1. C語言的特點
①語言簡潔、緊湊,使用方便、靈活。共有32個關鍵字(也稱保留字),9種控制語句。
②運算符豐富,共有34種運算符。
③數據結構豐富,數據類型有:整型、實型、字符型、數組、指針、結構體、共用體等。
④具有結構化的控制語句(如if…else、while、do…while、switch、for)
⑤語法限制不太嚴格,程序設計自由度大。
⑥允許直接訪問物理地址,能進行位(bit)操作,可以直接對硬件操作。
⑦生成目標代碼質量高,程序執行效率高。
⑧可移植性好。
2. C語言的用途
C雖不擅長科學計算和管理領域,但對操作系統和系統實用程序以及對硬件進行操作方面,C有明顯的優勢。現在很多大型應用軟件也用C編寫。
3. 二進制數的表示
① (十進制轉換二進制)將十進制除以2 後的余數 寫出來 再自上而下地依次將余數加以匯集 如:10 10÷2=5 余0 5÷2=4 余1 4÷2=2 余0 2÷2=1 余1 10的二進制表示:1010
②(二進制轉換十進制) 從最後一位開始 每位乘2的相對位數的幾次方 結果相加 如:1010=0×2的0次方+ 1×2的1次方+0×2的2次方+1×2的3次方
③(二進制轉換八進制) 從右向左 每三位進行一次十進制的轉換
④(二進制轉換十六進制) 從右向左 每四位進行一次十進制的轉換
⑤ 原碼:最高位作為符號位(0表示正,1表示負),其他數字位代表數值本身的絕對值的數字表示方式。
例如 數字6在計算機中原碼表示:0000 0110 數字-6的原碼表示:1000 0110
⑥ 反碼:正數的反碼、補碼就是原碼,不改變;負數則保留符號位1,然後將這個數字的原碼按照每位取反
例如 數字6在計算機中的反碼和原碼一樣:0000 0110 數字-6的反碼表示:1111 1001
補碼:正數不變,負數的補碼就是對反碼加一 例如:1111 1001 的補碼 1111 1011
1. C的數據類型
C的數據類型包括:整型、字符型、實型或浮點型(單精度和雙精度)、枚舉類型、數組類型、結構體類型、共用體類型、指針類型和空類型。
2. 常量與變量
常量其值不可改變,變量其值可以改變,變量名只能由字母、數字和下劃線組成,且第一個字符必須為字母或下劃線。否則為不合法的變量名。變量在編譯時為其分配相應存儲單元。
符號常量:用一個標識符代表一個常量,定義符號常量又稱為“宏定義”,一般寫在程序的函數之外。如:#define PI 3.14159 以後凡遇到PI即用3.14159代替。它的值在其作用域內不能改變,也不能再被賦值,其作用域在文件結束或遇#undef 處結束。
常量名常為大寫,變量名常為小寫。
3. 整型數據
整型常量的表示方法:十進制不用說了,八進制以0開頭,如0123,十六進制以0x開頭,如0x1e。
整型變量分為:基本型(int)、短整型(short int)、長整型(long int)和無符號型(unsigned int)。不同機器上各類數據所占內存字節數不同,一般int型為2個字節,long型為4個字節。
4. 實型數據
實型常量表示形式:十進制形式由數字和小數點組成(必須有小數點),如:0.12、.123、1230.0等。指數形式如123e3代表123×10的三次方。
實型變量分為單精度(float)和雙精度(double)兩類。在一般系統中float型占4字節(32位)內存空間,其數值范圍為3.4E-38~3.4E38,7位有效數字。double型占8字節(64位)內存空間,其數值范圍為1.7E-308~1.7E308,15~16位有效數字。
5. 字符型數據
字符常量用單引號括起來,如'a','b'等。還有一些是特殊的字符常量,如'\n','\t',' '等。分別代表換行、橫向跳格和空格。
字符變量以char 來定義,一個變量只能存放一個字符常量,一個字符常量占1個字節內存空間。
字符串常量是由雙引號括起來的字符序列。這裡一定要注意'a'和"a"的不同,前者為字符常量,後者為字符串常量,c規定:每個字符串的結尾加一個結束標志'',實際上"a"包含兩個字符:'a'和''。
6. 數值型數據間的混合運算
整型、字符型、實型數據間可以混合運算,運算時不同類型數據要轉換成同一類型再運算,轉換規則:
char,short -> int -> unsigned -> long -> double <- float
7. 運算符和表達式
c運算符包括:
算數運算符( + - * / % )
關系運算符( > < == >= <= != )
邏輯運算符( ! && || )
位運算符( << >> ~ | ^ & )
賦值運算符( = )
條件運算符( ? : )
逗號運算符( , )
指針運算符( * & )
求字節數( sizeof )
強制類型轉換(類型)
分量運算符( . -> )
下標運算符( [ ] )
其它運算符( 如函數調用運算符( ) )
自增自減運算符( ++ -- )注意:++i和i++的不同之處,++i使用i之前先使i加1,i++使用i之後,使i加1。
逗號表達式的求解過程:先求解表達式1,再求解表達式2,整個表達式的值是表達式2的值。
1.c的9種控制語句:
if() ~ else~
for()~
while()~
do~while()
continue
break
switch
goto
return
程序的三種基本結構:順序結構,選擇結構,循環結構
2.數據輸出
c語言不提供輸入輸出語句,輸入輸出操作是由c的庫函數完成。但要包含頭文件stdio.h。
putchar( ) 向終端輸出一個字符
strlen() 函數 針對字符串,用來計算字符串的實際長度,不包括‘\0’
sizeof() 操作符,用來計算任意數據類型的內存占用大小。
strcat() 把第二個字符串接到第一個字符串的後面,第一個字符串後面的‘\0’結束符被取消。
printf( )的格式字符:
① d格式符 用來輸出十進制整數
%d 按整型數據的實際長度輸出
%md 使輸出長度為m,如果數據長度小於m,則左補空格,如果大於m,則輸出實際長度
%-md 使輸出長度為m,如果數據長度小於m,則右補空格,如果大於m,則輸出實際長度
%ld 輸出長整型數據
② o格式符 以八進制形式輸出整數
③ x格式符 以十六進制形式輸出整數
④ u格式符 用來輸出unsigned型數據,以十進制形式輸出
⑤ c格式符 用來輸出一個字符
⑥ s格式符 輸出一個字符串
%s 輸出實際長度字符串
%ms 輸出的串占m列,如果串長度小於m,左補空格,如果大於m,實際輸出
%-ms輸出的串占m列,如果串長度小於m,右補空格
%m.ns 輸出占m列,但只取字符串中左端n個字符並靠右對齊
%-m.ns m、n含義同上,靠左對齊,如果n>m,則m自動取n值
⑦ f格式符 以小數形式輸出實數
%f 整數部分全部輸出,小數部分輸出6位
%m.nf 輸出數據共占m列,其中有n位小數。如果數值長度小於m,左補空格
%-m.nf 同上,右補空格
⑧ e格式符 以指數形式輸出實數
%e 系統指定6位小數,5位指數(e+002 )
⑨ g格式符 輸出實數,根據數值大小,自動選f格式或e格式
3.數據輸入
getchar( ) 從終端輸入一個字符
scanf( 格式控制,地址列表) 標准C scanf中不使用%u,對於unsigned型數據,以%d或%o或%x輸入。%後的*,用來跳過它相應的數據。
輸入數據時不能規定精度如scanf( "%7.2f", &a );是不合法的。
scanf_s 是對%c和%s有特殊要求的,需要對字符或字符串指定寬度,如:scanf_s(“%c,%s”,&c,1,&s,10);
需注意scanf和scanf_s在使用時的區別。
1. 關系運算符:
c提供6種關系運算符(> < <= >= == != )前四種優先級高於後兩種。
2. If語句
C提供了三種形式的if語句
If(表達式) 語句
If(表達式) 語句1 else 語句2
If(表達式1) 語句1
else if(表達式2) 語句2
…
else 語句n
3. 條件運算符
(a>b)?a:b 條件為真,表達式取值a,否則取值b
4. Switch語句
Switch(表達式)
{
case 常量表達式1:語句1; break;
case 常量表達式2:語句2; break;
…
case 常量表達式n:語句n; break;
default :語句n+1;
}
1. 幾種循環語句
goto語句(現已很少使用)
while語句 先判斷表達式後執行語句
do-while語句 先執行語句後判斷表達式
for語句
2. Break語句和continue語句
Break語句用於跳出循環,continue用於結束continue以下的循環語句。
當型循環:先判斷表達式的值,再執行循環體的內容
直到型循環:先運行一次循環體,再判斷表達式的值
1. 一維數組
C規定不能對數組作動態定義,只能靜態對數組初始化,方括號內可以是符號常量(宏定義),但不能是變量。給數組初始化時可以不指定數組長度,編譯器根據數組中被初始化元素的數量,自動確定數組長度。
當初始化元素的數量小於數組長度時,前n個元素被初始化,剩下的為0
如果不給數組初始化,數組的每個元素為默認值。
數組的最小下標是0 最大上標是數組長度-1
2. 二維數組
一個二維數組可以分解為多個一維數組
二維數組是按行排列的
求一個二維數組所占空間字節數公式:行數*列數*類型字節數=總字節數
若只對部分元素賦值,未賦值的元素自動取0值。
多維數組靠近數組名的第一個下標可以省略不定義,但其他的都必須定義其大小
3. 字符數組
字符型數據:字符型數據包括字符常量、轉義字符常量、字符串常量、字符變量、符合常量。
字符常量:由單引號括起來的單個字符
轉義字符常量:以反斜槓開頭的特殊字符序列,意思是把反斜槓後面的字符轉換成特定的含義
字符串常量:用雙引號括起來的字符序列
c語言有字符常量和字符變量,有字符串常量,但沒有專門存放字符串的變量,c語言用字符數組存放字符串。每個字符串以‘\0’結束。在字符數組中,第一個\0前面的所有字符和\0一起構成了字符串,\0之後的其他數組元素與該字符串無關。
定義字符數組時,數組長度>=有效字符個數+1 最後一個存放‘\0’,如果初值個數大於數組長度,則按照語法錯誤處理,初值個數小於數組長度,則只將花括號中的字符分別賦給數組中前面的元素,其余的元素自動定為空字符。
c允許用字符串的方式對數組作初始化賦值,列如:char ch[]=”china”;
用字符串方式賦值比用字符逐個賦值要多占一個字節,用於存放字符串結束標志’\0’
Scanf(“%s”);函數輸入時以回車和空格作為分隔符,gets()只以回車作為分隔符。
部分字符串處理函數 (需要包含頭文件“string.h”)
puts(字符數組) 將一個字符串輸出到終端。
gets(字符數組) 從終端輸入一個字符串到字符數組,並且得到一個函數值,為該字符數組的首地址 (vs裡需要寫成gets_s)
strcat(字符數組1,字符數組2) 連接兩個字符數組中的字符串,數組1必須足夠大。
(vs裡需要寫成strcat_s)
Strcpy(字符數組1,字符串2) 將字符串2拷貝到字符數組1中。 (vs裡需要寫成strcpy_s)
Strcmp(字符串1,字符串2) 比較字符串,相等返回0,字符串1>字符串2,返回正數,小於返回負數。
Strlen(字符數組) 求字符串長度。
Strlwr( 字符串) 將字符串中的大寫字母轉換成小寫 (vs裡需要寫成 _strlwr_s)
Strupr( 字符串) 將字符串中的小寫字母轉換成大寫 (vs裡需要寫成 _strupr_s)
以上是一些比較常用的字符串處理函數。
1. 關於形參和實參的說明
① 在函數被調用之前,形參不占內存
② 實參可以是常量、變量或表達式
③ 必須指定形參的類型
④ 實參與形參類型應一致
⑤ 實參對形參的數據傳遞是"值傳遞",即單向傳遞
2. 函數返回值
如果想讓函數返回一個值,在函數中就要用return語句來獲得,在定義函數時也要對函數值指定類型,如果不指定,默認返回整型。
3. 函數調用
1 注意在函數調用時實參和形參的個數、類型應一一對應。對實參表求值的順序是不確定的,有的系統按自左至右,有的系統則按自右至左的順序。這一點要注意。
2 函數調用的方式:函數語句,函數表達式,函數參數
3 如果主調函數和被調函數在同一文件中,並且主調函數在前,那麼一般要在主調函數中對被調函數進行說明。除非: 被調函數的返回值類型為整型或字符型 被調函數出現在主調函數之前。
4 對函數的說明和定義是不同的,定義是指對函數功能的確立,包括指定函數名,函數值類型,形參及其類型、函數體等。說明則只是對已定義的函數返回值類型進行說明,只包括函數名、函數類型以及一個空的括弧,不包括形參和函數體。
5 c語言允許函數的遞歸調用(在調用一個函數的過程中又出現直接或間接的調用該函數本身)。
4. 數組作為函數參數
1 數組元素作為函數參數 和一般變量相同
2 數組名作參數應該在主調和被調函數分別定義數組,形參數組的大小可以不定義。注意:數組名作參數,不是單向傳遞。
3多維數組作參數,在被調函數中對形參數組定義時可以省略第一維的大小說明,但不能省略第二維或更高維的說明。
5. 局部變量和全局變量
從變量作用域角度分,變量可分為局部變量和全局變量。
1)內部變量(局部變量)
在一個函數內定義,只在函數范圍內有效的變量。
2)外部變量(全局變量)
在函數外定義,可以為本文件其它函數所共用,有效范圍從定義變量的位置開始
到本文件結束。建議盡量少使用全局變量,因為它在程序全部執行過程中都占用
資源,而且使函數的通用性降低了。如果在定義外部變量之前的函數要想使用該
外部變量,則應在該函數中用extern作外部變量說明。
2、當全局變量與局部變量同名時,局部變量將在自己作用域內有效,它將屏蔽同名的全局變量。
6. 動態存儲變量與靜態存儲變量
從變量值存在的時間(生存期)角度來分,可分為靜態存儲變量和動態存儲變量。靜態存儲指在程序運行期間給變量分配固定的存儲空間,動態存儲指程序運行期間根據需要動態的給變量分配存儲空間。
C語言中,變量的存儲方法分為兩大類:靜態存儲類和動態存儲類,具體包括:自動的(auto),靜態的(static),寄存器的(register),外部的(extern)。
1、局部變量的存儲方式
函數中的局部變量如不作專門說明,都之auto的,即動態存儲的,auto可以省略。局部變量也可以定義為static的,這時它在函數內值是不變的。靜態局部變量如不賦初值,編譯時系統自動賦值為0,動態局部變量如不賦初值,則它的值是個不確定的值。C規定,只有在定義全局變量和局部靜態變量時才能對數組賦初值。為提高執行效率,c允許將局部變量值放在寄存器中,這種變量叫register變量,要用register說明。但只有局部動態變量和形式參數可以作為register變量,其它不行。
2、全局變量的存儲方式
全局變量在函數外部定義,編譯時分配在靜態存儲區,可以在程序中各個函數所引用。多個文件的情況如何引用全局變量呢?假如在一個文件定義全局變量,在別的文件引用,就要在此文件中用extern對全局變量說明,但如果全局變量定義時用static的話,此全局變量就只能在本文件中引用了,而不能被其它文件引用。
3、存儲類別小結
從作用域角度分,有局部變量和全局變量
局部變量:自動變量,即動態局部變量(離開函數,值就消失)
靜態局部變量(離開函數,值仍保留)
寄存器變量(離開函數,值就消失)
(形參可定義為自動變量和寄存器變量)
全局變量:靜態全局變量(只限本文件引用)
全局變量(允許其它文件引用)
從存在的時間分,有靜態存儲和動態存儲
動態存儲:自動變量(本函數內有效)
寄存器變量(本函數內有效)
形參
靜態存儲:靜態局部變量(函數內有效)
靜態全局變量(本文件內有效)
全局變量(其它文件可引用)
從變量值存放的位置分
靜態存儲區:靜態局部變量
靜態全局變量
全局變量
動態存儲區:自動變量和形參
寄存器內:寄存器變量
7. 內部函數和外部函數
內部函數:只能被本文件中的其它函數調用,定義時前加static,內部函數又稱靜態函數。
外部函數:可以被其它文件調用,定義時前加extern,如果省略,則隱含為外部函數,在需要調用此函數的文件中,一般要用extern說明。
指針:就是變量的地址。
指針變量:用來存放指針(地址)的變量。
& 取地址運算符
“*”指針運算符
1、指針變量的定義
類型標識符 *指針變量名 如:int *pointer; 該指針變量的類型是 int *,int代表該指針變量指向的變量的類型,”*”代表這是一個指針變量。
1、給指針變量賦值
Int a=3;
int *pointer=&a;
意思是 把變量a的地址賦給指針變量。
Int *p=NULL; 給指針變量初始化,NULL是特殊字符,代表這是一個空指針。
2、指針變量的引用概念
int *p; int a=3; p=&a;
*p:代表指針變量指向的存儲單元裡面的內容
p等價 &a,*p等價 a,&*p等價 &a。
3、指針變量的++--
*p++ 指:指向的存儲單元裡面的值++。
p++ 代表 指針變量存儲的地址++。
如果指向的變量是整型,則p++ 等價於 p+1*4
如果是實型,則p++ 等價於 p+1*4
如果是字符型,則p++ 等價於 p+1*1
4、數組與指針
數組指針:數組的起始地址。
數組元素指針:數組元素的地址。
① 數組名代表數組首元素的地址,相當於指向數組第一個元素的指針。
② 我們通常引用數組元素的形式是a[i],如果用指針可以這樣引用,*(a+i),或定義一個指針變量p,將數組a的首地址賦給p,p=a;然後用*(p+i)引用。
注意:指針變量p指向數組a首地址,則p++指向數組a的下一元素地址,即a[1]的地址。
5、字符串與指針
字符串可以直接賦值給指針,不用定義字符數組,當賦值後,指針指向該字符串的首字符,指針指向字符串後,只能訪問字符串的內容,不能通過指針對字符串做修改,因為該字符串是常量。但是這樣做會產生內存垃圾,因為這個字符串不知道被分配到哪個地方了。
char *p=”hello”;
在c++裡可以用函數new 動態分配一個內存空間,用完還可以釋放:
int n; cin>>n; char *p=new char a [n];
釋放指針指向的存儲空間:delete[] p;
在c++裡,cout語句對數組名和指針有特殊處理,如果輸出數組名,則輸出的是字符串,輸出指針也一樣,就像c的printf(“%s”);一樣。想輸出字符數組的起始地址需要這樣寫
cout<<static_cast<void*>(數組名)<<;
c++標准庫中聲明了一個string類型,是字符串類型,可以定義字符串變量,可以直接讀入,輸出,賦值字符串,可以使用關系運算符。
string string1,string2;
string1=”hello”; cin>>string1; string2=string1; if(string1>string2)
6、二維數組與指針
① 數組名是指向數組第一行的指針
② “*a”等價於a[0],相當於讓a下降了一級
③ “&a”表示指向整個二維數組的指針,相當於a上調了一級
④ 幾個有用的結論
a、a[0]、&a[0][0]有相同的值
a+1表示第1行的地址
*(a+1)表示第1行第0列的地址
*a+1表示第0行第1列的地址
a[0]+1表示第0行第1列的地址
⑤ 二維數組指針的定義: int (*p)[列數值];
錯誤:int *p=a 正確:int (*p)[4]=a 正確:int *p=&a[0][0]
因為int *p是指向一個整型元素的指針,不能指向多個元素
⑥ 指針數組的定義:int *pointer[10] 定義包含10個基類型為整型的指針數組。
1、結構體定義
struct 結構體名字
{
變量名
}; //注意後面的冒號
組合型數據類型 結構體,將一組變量集合在一起,組成一個事物。
2、結構體變量的定義
① 結構體名+變量名 等於定義了新的相同的結構體,也可以在結構體”;”後面直接新定義名字
3、結構體與指針
① 定義:struct + 結構體名 + *指針名
② 調用:p -> name
③ -> 是指向運算符,優先級僅次於 () []。
③ 對指針 p++; 將躍過整個結構體
④ 對變量輸入時,加 ”&”取地址符 scanf_s(“%d”, &p->name);
4、結構體與函數
① 結構體可以作函數形參,也可以作函數實參
② 結構體名作參數,是值傳遞,結構體指針作參數,是地址傳遞
1、鏈表將分散的內存數據集合起來,定義與結構體相同
2、結構體內有一個指針,該指針代表指向下一片相同的內存空間
1、枚舉的定義
enum 枚舉類型 {元素1,元素...};
2、枚舉變量的定義: enum 枚舉類型 枚舉變量名
3、枚舉結構與數組相同,每個元素都有特定的含義,是常量,不可賦值,每個元素都有下標
4、不能給枚舉變量賦其他值,枚舉變量只能接收 枚舉元素。給枚舉變量賦值整數,應先強制類型轉換 變量=(enum 枚舉類型)1;
原意是把枚舉下標為1的元素賦給變量。
5、輸出變量時,會輸出元素的下標
6、枚舉型可以比較