1. 資料類型
2. 轉義字元
3. 變量
資料類型名 變量名清單
① 辨別符是以字母或下劃線開頭,由字母、數字和下劃線組成的字元序列。② 辨別符是區分大小寫的。③ 不能使用C語言的關鍵字定義其他的辨別符。④ 變量在聲明的同時可以給其指派,稱為變量的初始化。
⑤ 如果任何時候都不希望改變某個變量的值,可以将該變量聲明為固定變量。在定義并初始化該變量時,為其聲明加上保留字const。
4.資料類型轉換
強制類型轉換:(資料類型名) (表達式) 将表達式的資料類型轉化
5.資料的輸出函數
①putchar(整型表達式)
字元輸出函數,在标準輸出裝置上輸出單個字元。
②printf(“格式控制”,輸出表列);
如b=1:printf(“a=%d”,b)
a為普通字元,d為格式字元,%d為格式說明,a=%d為格式控制,b為輸出表列;
輸出為:a=1
還可以表示:printf(參數1,參數2........參數n);
如:printf(“%d%f%c”,a,b,c);的執行結果為:a按%d的格式輸出,b按%f的格式輸出,c按%c的格式輸出。隻有第一個參數“參數1”是必要的,其他參數可以省略。當隻有一個參數時,“參數1”中不能包含“格式說明”字元,隻能有“普通字元”。
ptintf函數的格式字元:
在格式說明中,在引導符“%”和格式字元之間還可以插入附加格式說明字元,以便更精确地控制輸出格式;
6. 資料的輸入函數
①getchar();
從鍵盤上輸入一個字元。通常把輸入的字元賦予一個字元變量。
②scanf(格式控制,位址表列)
其中,“格式控制”的含義同printf函數,“位址表列”是由若幹個記憶體位址組成的表列,可以是變量的位址,也可以是字元串的首位址。對于一般變量,出現在scanf函數參數中時,通常需要加位址運算符“&”。但有些參數本身就是位址,也就不需要加位址運算符了,比如用指針變量作為參數。
7.運算符的優先級
7. if語句
if(表達式)語句;
先計算條件“表達式”的值,若結果為“真”則執行“語句”,然後執行if語句後面的語句。如果結果為假,則不執行“語句”,而直接執行if語句之後的語句。
if(表達式)語句1;
else語句2;
先計算條件“表達式”的值,如果結果為真則執行“語句1”,否則執行“語句2”,然後跳到整個if語句之外繼續執行程式。
if(表達式1)語句1;else if(表達式2)語句2;……else if(表達式n)語句n;
else語句n+1;先計算“表達式1”,如果為“真”,則執行“語句1”,然後跳出if語句,轉到if語句後的語句(位于“語句n+1”之後)繼續執行程式;若“表達式1”為“假”,則跳過“語句1”,計算“表達式2”;若“表達式2”為“真”,則執行“語句2”,然後跳出if語句,否則再計算“表達式3”,……,以此類推。當“表達式n”為“假”(意味着,所有表達式的值都為“假”)時,執行“語句n+1”。
8. 條件運算和條件運算表達式
表達式e1?表達式e2:表達式e3其中,表達式e1是一個關系表達式或邏輯表達式,結果是邏輯值“真”或“假”。表達式e2、e3可以是任意表達式。先求解表達式e1;若e1為真(非0),則計算表達式e2,并将e2的結果作為整個條件表達式的結果;若e1為假(0),則計算表達式e3,并将e3的結果作為整個條件表達式的結果。
9. switch語句
switch(表達式){case常量表達式1:語句1;case常量表達式2:語句2;……case常量表達式n:語句n;default:語句n+1;}先計算“表達式”的值,并逐個與其後的“常量表達式i”(即常量表達式1、常量表達式2、……、常量表達式n)的值相比較,當“表達式”的值與“常量表達式i”的值相等時,即開始執行該“常量表達式i”後的“語句i”,如果沒有遇到break語句,則繼續執行後面所有的case後(跳過case部分)的語句,直到遇到break語句或者switch語句最後的“}”。如果“表達式”的值與所有的“常量表達式”均不相同,則執行default後的語句。在switch語句中,常使用break語句來結束switch語句。break語句的格式為:break;
10. While語句
while語句的一般格式為:while(表達式)語句do-while語句的一般格式為:
do語句while(表達式);
① 計算“表達式”的值;② 若“表達式”的值不是0,則為“真”,繼續執行③,否則,結束循環,轉到while語句後面的語句繼續執行程式;③ 執行“語句”部分,即執行循環體;④ 傳回①繼續執行。
11. for語句
for(表達式1;表達式2;表達式3)語句“表達式1”用于循環的初始化;“表達式2”是for語句的循環控制條件,可以是任何形式的表達式;“表達式3”用于修改循環控制變量的值,目的是使“表達式2”的值變為0,以結束循環;
① 計算“表達式1”;② 計算“表達式2”,如果“表達式2”的值為0(表示“假”),則轉到⑤,否則轉到③;③ 執行“語句”部分;④ 計算“表達式3”後,轉到②;⑤ for語句結束。
12. goto語句
goto語句标号;
13. 數組
一維數組的定義:
類型說明 數組名稱[數組長度]
二維數組的定義:
類型說明 數組名稱[行數][列數]
三維數組的定義:
類型說明 數組名稱[行數][列數][層數]
數組的初始化出:
類型說明 數組名稱[數組長度]={數值清單}
不允許定義可變長度數組;不允許直接引用數組本身進行某種運算,隻能通過應用數組的元素間接引用數組,數組元素的數值以前必須先給數組元素指派;數組元素指派可以使用指派語句,也可以通過調用scanf等函數從鍵盤輸入;花括号中的數值清單是用逗号分割的若幹個數值的集合;如果在數值清單中給出了所有元素的初值,數組長度說明是可以省略的,但不要省略方括号。
14. 指針
把一個資料所占據的若幹存儲單元中第一個單元的位址稱為該資料的位址。
指針變量的值是一個位址,指針變量的類型不是該位址的類型,而是存放在該位址存儲單元中的資料的類型。
定義指針變量:
類型說明*指針變量名
類型說明 *指針變量名1,*指針變量名2,.....
指針變量可以與其他變量一起定義。
變量x位址可以用&x表示,&為取位址運算符:&變量名
取位址運算表達式的傳回值是一個位址。
指針變量的指派:
要為指針變量指派,可以用已定義的相同類型的普通變量的位址,也可以用已經指派的另一個相同類型的指針變量的值。
程式中永遠不要讓指針包含一個位置的位址。
如果程式中暫時還不能确定指針的方向,或者不需要指向某個特定的存儲位址。則可以用空指針NULL(或0)為指針指派。
可以用空指針為任何類型的指針指派,甚至為空類型(用void聲明)的指針指派,void類型的指針可以指向任何類型的變量,常作為通用的指針。
指針變量的引用:
*指針變量名其運算結果是該指針變量所指向的變量的值。當指針指向某個确定的位址時,可以通過指針運算符“*”引用所指向的資料。
一般不能将指針運算符“*”直接應用于void類型的指針,比如對于“int x; void *p=&x;”直接寫*p=3是非法的,因為無法确定*p的資料類型。為此必須使用強制類型轉換,即在引用p所指向的變量前,先強行變更為該變量的類型,可将*p=3改為*((int *)p)=3,其中“(int *)”為強制類型轉換。
15. 一維數組與指針
可以定義指針指向數組的某個元素。進而通過該指針間接的通路該數組元素。
一維數組的位址:
取位址運算同樣适用于數組元素,是以數組元素a[i]的位址是&a[i]。第一個數組元素的位址稱為數組的首位址,用數組名表示,是以數組名a被定義為&a[0]。
指針的運算:
C語言中,與指針相關的運算除了指派運算“=”、取位址運算“&”和指針運算“*”,還有以下幾種。(1)指針與整數的加、減法文法:指針±整數若指針p指向數組a第i個元素a[i],則p+1指向下一個元素,即a[i+1],而p-1指向前一個元素,即a[i-1]
(2)左移指針“--”和右移指針“++”文法:指針++或 ++指針指針--或 --指針若指針p指向數組a的第i個元素a[i],則p++使指針右移一位,指向a[i+1],而p--則使指針左移一位,指向a[i-1]。
16. sizeof()運算符的用法
sizeof(運算對象)
表達式的值是運算對象所占記憶體的存儲單元個數。sizeof的運算對象可以是常量變量。也可以是類型說明符。
17. malloc函數
指針=(類型說明*)malloc(資料長度)其中,“(類型說明 *)”是強制類型轉換,以保證與指針的類型一緻。“資料長度”是一個正整數,表示資料所占記憶體單元個數——位元組數,常用sizeof()運算符來擷取。malloc函數的函數值是成功配置設定的記憶體單元的位址,若配置設定記憶體失敗則傳回空指針NULL。
18. calloc函數
指針=(類型說明*)calloc(資料個數,資料長度)與malloc函數不同的是,calloc函數可配置設定若幹個資料所占據的連續空間,是以可以将calloc函數配置設定的空間與等長度的數組對應,而malloc函數隻能配置設定一個變量位址。
19. free函數
使用malloc函數或calloc函數成功配置設定記憶體空間後,這些存儲單元将被占用,如果不釋放,就不能被其他變量使用。為了有效地使用記憶體資源,程式中動态配置設定的記憶體空間必須在使用結束後立即釋放,方法是調用free函數。free函數的使用方法是:
free(指針);作用是釋放“指針”所指向的動态配置設定的記憶體。
20. 二維數組與指針。
指向數組的指針:如何定義與二維數組對應的指針,指針類型必須與數組元素一緻,是以與二維數組對應的指針是指向一個一維數組的指針,定義格式為:類型說明(*指針名稱)[整型常數]其中,圓括号不能省略。例:int a[行數][列數],(*p)[列數];若指針p指向二維數組a的第i行,即p=a+i,則p++使p指向下一行,p--使p指向上一行。
指向指針的指針:
如果指針的值是另一指針的位址,則該指針是指針的指針,定義為類型說明**指針變量名
指針數組:
如果數組的每個元素都是指針,則該數組為指針數組,定義為
類型說明*數組名[數組長度]
21. 字元串
字元串的存儲方法:
C語言中,程式中的字元串使用雙引号作為定界符,字元串以字元 '\0' 為結束辨別,字元 '\0' 并不顯式地出現在字元串中。
字元數組是類型為字元的數組,其定義格式為:char數組名[數組長度]
字元串的輸入和輸出:
使用scanf函數輸入字元串的一般格式為:scanf("%s",字元數組)其中,%s為字元串描述符,與之對應的輸入項是字元數組的首位址。
其功能是從鍵盤緩沖區中讀取一個字元串,并存入數組x中。不同于輸入其他類型的資料,作為輸入參數的數組名x的前面不能再有取位址運算符“&”。值得注意的是,我們已經知道scanf函數使用空白(空格、制表符、回車符等)作為輸入資料的分隔符,是以用scanf函數隻能輸入“單詞”字元串:例如:char a[10],b[10],c[10];scanf("%s%s%s",a,b,c);運作程式時,如果輸入的是(“_”表示空格)。
printf函數的用法與scanf函數類似,但輸出參數可以是字元串常量。使用printf函數輸出字元串的一般格式為:printf("%s",字元數組名或字元串常量)這裡特别強調數組中存放的是字元串,也就是必有一個元素為 '\0'。
不同于scanf函數,使用gets函數可輸入一句話(包含空格、制表符),其文法為:gets(字元數組)存入字元數組的是一個字元串(以 '\0' 結束),但不包括回車符。
與printf函數不同,使用puts函數輸出字元串,會在結束時自動換行,其文法為:puts(字元數組或字元串常量)
C語言提供了另一個類似于printf的函數—sprintf函數,可将要輸出到終端的内容先以字元串方式存放在字元數組中,以備以後輸出到終端。sprintf函數的用法與printf函數基本相同,隻是多了一個存放結果的字元數組,其一般格式如下:sprintf(字元數組名,格式控制字元串,輸出表列)
字元指針是指向字元串的指針,定義為:char *指針;可以用字元數組為指針指派,例如:char a[]="Welcome to Beijing.";char *p=a;也可以用字元串常量的位址為指針指派,例如:char *p="Hello";
字元串數組是存放了若幹字元串的字元數組,字元串數組是一個二維數組。通常每個字元串占據一行,字元串的個數對應數組的行數,最長的字元串的長度對應數組的列數。是以,字元串數組的定義為:char 數組名[字元串個數][字元串長度]要引用字元串數組中的字元串,可使用行位址。第i個字元串的位址為:數組名[i],也可寫為:*(數組名+i)。
指向字元串數組的指針:char(*指針)[字元串長度]其中,“字元串長度”必須與字元串數組相同。
如果數組元素是字元指針,每個指針指向一個字元串,則該數組為字元指針的數組,定義為:char *指針[數組長度]
22. 字元串處理函數
字元串處理函數的原型定義在頭檔案string.h中,是以,使用這些函數的時候,程式的開始位置需要書寫:#include<string.h>
複制已連接配接:
1. Strcpy函數和strncpy函數兩個函數的一般形式是:strcpy(字元數組1,字元串2)strncpy(字元數組1,字元串2,整數n)strcpy函數的功能是将“字元串2”對應的字元串全部複制到“字元數組1”中,結果兩個字元串相同。strncpy函數最多将“字元串2”的前n個字元複制到“字元數組1”中。
2. Strcat函數和strncat函數兩個函數的一般形式為:strcat(字元數組1,字元串2)strncat(字元數組1,字元串2,整數n)strcat函數将“字元串2”附加在“字元數組1”中的字元串的後邊,也就是把兩個字元串連接配接起來再存入“字元數組1”,是以,strcat函數的功能是連接配接兩個字元串。而strncat函數僅把“字元串2”的前n個(不足n個,則為實際個數)字元連接配接到“字元數組1”的字元串後邊。
比較大小:
1. strcmp函數、strncmp函數和stricmp函數這些函數的一般形式是:strcmp(字元串1,字元串2)strncmp(字元串1,字元串2,整數n)stricmp(字元串1,字元串2)這些函數的函數值都是整型的,如果函數值為0,表示兩個字元串相等;如果函數值大于0,則“字元串1”大于“字元串2”;如果函數值小于0,則“字元串1”小于“字元串2”。strcmp函數是最常用的函數之一,比較時要從左到右逐一比較每個字元,直到遇到不同的字元或遇到字元串結束符為止。strncmp函數隻比較兩個字元串的前n個字元,是以strncmp("ABC", "AB", 2)的傳回值為0,表示"ABC"和"AB"相等。用stricmp函數比較兩個字元串時,将忽略字母符号的大小寫,是以"ABC"與"AbC"相等。
2. strstr函數strstr函數的一般形式為:strstr(字元串1,字元串2)strstr函數的功能是在“字元串1”中查找“字元串2”,如果找不到,則函數傳回空指針NULL,若找到了,則傳回與“字元串1”中所包含的“字元串2”的首字元對應的指針。如果“字元串1”中包含“字元串2”,那麼“字元串2”常被稱做“字元串1”的子串。求子串是實作查詢(檢索)的基礎。
變換:
1. strlwr函數和strupr函數兩個函數的一般用法是:strlwr(字元數組)strupr(字元數組)strlwr函數将存放在“字元數組”中的字元串裡的所有大寫字母轉化為小寫字母,而strupr函數則相反,将小寫字母轉化為大寫字母。轉換後得到的字元串仍存放在“字元數組”中。
2. atoi函數和atof函數這兩個函數的原型在stdlib.h中,一般用法是:變量=atoi(字元串)變量=atof(字元串)atoi函數将“字元串”轉化成整數,并作為函數值傳回,而atof函數則轉化為實數。
其他:
用strlen函數可計算字元串的長度,用法是:變量=strlen(字元串)strlen函數的函數值是一個整數,表示“字元串”的長度,即結束符 '\0' 前的字元的個數。與sizeof(字元串)不同,用strlen函數求得的并不是數組長度(所占記憶體的位元組數)
23. 函數
函數的定義形式如下:資料類型 函數名(參數聲明清單){說明與語句}其中有些部分是可以省略的。最簡略的函數是下面的形式:函數名(){}這樣的函數不做任何事情,稱為空函數。
函數是通過return語句傳回給其調用者數值的。return後面可以跟任何形式的表達式:return表達式;
調用者稱為主調函數,而把被調用者稱為被調函數。函數還可以自己調用自己,稱為遞歸調用。main函數是主函數,它可以調用其他函數,而不允許被其他函數調用。是以,C語言程式的執行總是從main函數開始,完成對其他函數的調用後再傳回到main函數,最後由main函數結束整個程式。一個C語言源程式必須有也隻能有一個主函數main。
函數的參數:函數的參數分為形式參數(簡稱形參)和實際參數(簡稱實參)兩種。形參出現在函數定義中,在整個函數體内都可以使用,離開該函數則不能使用。實參出現在主調函數中,進入被調函數後,實參變量也不能使用。形參和實參的功能是做資料傳送。發生函數調用時,主調函數把實參的值傳送給被調函數的形參進而實作主調函數向被調函數的資料傳送。① 實參可以是常量、變量、表達式等。無論實參是何種類型的量,在進行函數調用時,它們都必須具有确定的值,以便把這些值傳送給形參。是以,應預先用指派、輸入等方法使實參獲得确定值。② 形參變量隻有在被調用時才配置設定記憶體單元,在調用結束時,即刻釋放所配置設定的記憶體單元。是以,形參隻有在函數内部有效。函數調用結束傳回主調函數後則不能再使用該形參變量。③ 實參和形參在數量、類型、順序上應嚴格一緻,否則會發生“類型不比對”的錯誤。④ 函數調用中發生的資料傳送是單向的,即隻能把實參的值傳送給形參,而不能把形參的值反向地傳送給實參。是以,在函數調用過程中,形參的值發生改變,而實參中的值不會變化。
函數的傳回值:
将函數實作的結果傳回給調用者,要從函數傳出一個數值,必須用到關鍵字return,而且資料類型必須和函數的傳回類型相比對。實際上,所有的函數都有一個傳回值。對于void類型的函數,函數不用寫return語句或者return語句後面不帶任何表達式。對于int類型的函數,不寫return語句時,相當于執行了“rerun 0;”語句。其實,主函數main也是有傳回類型的。有時将其定義void main(),表明其傳回值為void。有時将主函數定義為int main(),或者省略類型直接定義為main(),都表示函數的傳回類型為int。main函數的傳回值是直接給作業系統的。
庫函數的原型:
一般來說,庫函數的原型在系統提供的頭檔案中。
這種思想也可以借鑒來定義我們自己的函數原型。即将定義好的函數的原型放入一個“.h”的頭檔案中,然後在使用這些函數的子產品裡使用#include預編譯指令包含這個頭檔案,進而給出函數的原型。
函數的遞歸調用:一個函數在它的函數體内調用他自身稱為遞歸調用。這種函數稱為遞歸函數。
24. 變量的作用域
C語言中的變量按作用域範圍可分為兩種。局部變量和全局變量。
25. 變量的存儲類型
所謂存儲類型是指變量占用記憶體空間的方式,也稱為存儲方式。變量的存儲方式可分為“靜态存儲”和“動态存儲”兩種。靜态存儲變量通常是在變量定義時就分定存儲單元并一直保持不變,直至整個程式結束。動态存儲變量是在程式執行過程中,使用它時才配置設定存儲單元,使用完畢立即釋放。典型的例子是函數的形式參數,在函數定義時并不給形參配置設定存儲單元,隻是在函數被調用時,才予以配置設定,調用函數完畢立即釋放。如果一個函數被多次調用,則反複地配置設定、釋放形參變量的存儲單元。
在C語言中,對變量的存儲類型說明有以下4種:● auto:自動變量。● register:寄存器變量。● extern:外部變量。● static:靜态變量。自動變量和寄存器變量屬于動态存儲方式,外部變量和靜态變量屬于靜态存儲方式。
變量說明的完整形式應為:存儲類型說明符 資料類型說明符 變量名,變量名……;
auto變量:這種存儲類型是C語言程式中使用最廣泛的一種類型。C語言規定,函數内凡未加存儲類型說明的變量均視為自動變量,也就是說自動變量可以省去說明符auto。在前面各章的程式中所定義的變量凡未加存儲類型說明符的都是自動變量。自動變量具有以下特點。① 自動變量的作用域僅限于定義該變量的個體内。在函數中定義的自動變量,隻在該函數内有效。在複合語句中定義的自動變量隻在該複合語句中有效。② 自動變量屬于動态存儲方式,隻有在使用它,即定義該變量的函數被調用時,才給它配置設定存儲單元,開始它的生存期。函數調用結束時,釋放存儲單元,結束生存期。是以,函數調用結束之後,自動變量的值不能保留。在複合語句中定義的自動變量,在退出複合語句後也不能再使用,否則将引起錯誤。③ 由于自動變量的作用域和生存期都局限于定義它的個體内(函數或複合語句内),是以不同的個體中允許使用同名的變量而不會混淆。即使在函數内定義的自動變量也可以與該函數内部的複合語句中定義的自動變量同名。
extern變量:在前面介紹全局變量時已介紹過外部變量。下面再補充說明外部變量的幾個特點。① 外部變量和全局變量是對同一類變量的兩種不同角度的提法。全局變量是從它的作用域提出的,外部變量是從它的存儲方式提出的,表示了它的生存期。② 當一個源程式由若幹個源檔案組成時,在一個源檔案中定義的外部變量在其他的源檔案中也有效。
static變量:将保留字static加在一個函數體定義的變量前,那麼這個變量就成為靜态局部變量,它在這個函數的每次調用時都占用同一塊記憶體區域。是以,當多次調用一個函數且要求在調用之間保留某些變量的值時,可以考慮采用靜态局部變量,有時這種定義方式很有用。将保留字static加在一個外部變量前,則将會使這個外部變量“私有化”,就是說将會使這個外部變量隻能在本檔案之内使用,在其他檔案内即使使用extern說明了這個變量,它仍然不可以被通路。靜态局部變量屬于靜态存儲方式,它具有以下特點。① 靜态局部變量在函數内定義,但不像自動變量那樣,當調用時就存在,退出函數時就消失。靜态局部變量始終存在着,也就是說它的生存期為整個源程式。② 靜态局部變量的生存期雖然為整個源程式,但是其作用域仍與自動變量相同,即隻能在定義該變量的函數内使用該變量。退出該函數後,盡管該變量還繼續存在,但不能使用它。③ 允許對構造類靜态局部變量賦初值。在第6章中介紹數組初始化時已做過說明。若未賦初值,則由系統自動賦0值。④ 對基本類型的靜态局部變量若在說明時未賦初值,則系統自動賦0值。而對自動變量不賦初值,則其值是不定的。根據靜态局部變量的特點,可以看出它是一種生存期為整個源程式的量。雖然離開定義它的函數後不能使用,但再次調用定義它的函數時,它又可繼續使用,而且儲存了前次被調用後留下的值。雖然用全局變量也可以達到上述目的,但全局變量有時會造成意外的副作用,是以仍以采用局部靜态變量為宜。
register變量:通常,變量都存放在存儲器内,是以當對一個變量頻繁讀寫時,必須要反複通路記憶體儲器,進而花費大量的存取時間。為此,C語言提供了另一種變量,即寄存器變量。這種變量存放在CPU的寄存器中,使用時,不需要通路記憶體,而直接從寄存器中讀寫,這樣變量的存取效率可大大提高。寄存器變量的說明符是register。由于寄存器的特點,隻有整型或者字元型變量可以聲明為寄存器變量。其他類似的類型如unsigned、long或short也可以聲明為寄存器變量。實際上,任何編譯器都隻允許使用有限個寄存器變量,而且一旦沒有寄存器可以使用,編譯器将忽略寄存器變量,而隻把它當成普通的變量。是以,通過使用寄存器變量獲得的速度提高是有限的。
26. 自定義資料類型
結構體:
結構體定義的一般形式如下:struct 結構體類型名{資料類型 成員1;資料類型 成員2;……資料類型 成員n;};struct關鍵字後面是結構體類型名,接着是一對大括号“{}”,它們表示結構體類型定義的開始和結束。括号後面要有分号“;”,表示整個定義結束。在括号中,與聲明程式變量一樣聲明結構體的資料成員。在結構體中的成員還可以使用使用者自定義的類型,包括結構體類型。
通過結構體指針變量通路結構體成員的兩種方法如下。(1)使用點操作符:(*結構體指針變量名).成員名(2)使用箭頭操作符:結構體指針變量名->成員名
共用體(union):是将不同的資料類型組合在一起,共同占用同一段記憶體的使用者自定義資料類型。共用體的聲明方法與結構體類似,隻是将關鍵字struct改為了union。
對比結構體和共用體,可以發現:① 結構體和共用體都是由多個不同的資料類型成員組成的,但在任何同一時刻,共用體中隻存放了一個被選中的成員,而結構體的所有成員都存在;② 對于共用體的不同成員指派,将會對其他成員重寫,原來成員的值就不存在了,而對于結構體的不同成員指派是互不影響的。
除了使用C語言提供的标準類型名(如int、char、float、double等)、結構體和共用體之外,還可以用typedef聲明新的類型名來代替已有的類型名。一般來說,typedef新定義的類型用大寫字母表示,以差別于原有的資料類型。
枚舉類型定義的一般形式如下:enum枚舉名{枚舉值表};在“枚舉值表”中應羅列出所有可用值。這些值也稱為枚舉元素。例如:enum weekday{sun,mou,tue,wed,thu,fri,sat};該枚舉名為weekday,枚舉值共有7個,即一周中的7天。凡被說明為weekday類型變量的取值隻能是7天中的某一天。如同結構體和共用體一樣,枚舉變量也可以用不同的方式說明,即先定義後說明、同時定義說明或者直接說明。
① 枚舉值是常量,不是變量,不能在程式中用指派語句再對它指派
② 枚舉元素本身由系統定義了一個表示序号的數值,從0開始順序定義為0, 1, 2,…。③ 隻能把枚舉值賦予枚舉變量,不能把元素的數值直接賦予枚舉變量。④ 枚舉類型也可以使用typedef重新定義。
27. 預處理指令
C語言提供了多種預處理功能,如宏定義、檔案包含、條件編譯等。
#define指令定義了一個辨別符及一個串,可以用來建立命名常量和宏。在源程式中每次遇到該辨別符時,均以定義的串代換它。在C語言源程式中允許用一個辨別符來表示一個字元串,稱為宏。
#undef用來取消宏定義,它與#define對立:#undef 辨別符如果被取消的宏實際上沒有被#define所定義,針對它的#undef并不會産生錯誤。當一個宏定義被取消後,可以再度定義它。
預定義宏:
提供目前編譯的資訊。
#include包含
預處理器發現#include指令後,就會尋找後面跟着的檔案名并把這個檔案的内容包含到目前檔案中。目前,我們的程式大多都使用了#include指令,此指令用于檔案包含。這些檔案包含了編譯器所需的資訊。很多情況下,頭檔案中的内容是編譯器産生最終代碼所需的資訊。#include的格式如下:#include"檔案名"#include#include預處理标記注意,所在的行不能含有除注釋和空白符之外的其他任何内容。用尖括号“<”和“>”括起來表明這個檔案是一個工程或标準頭檔案。查找過程會檢查預定義的目錄。可以通過設定搜尋路徑環境變量或指令行選項來修改這些目錄。如果檔案名用一對引号括起來則表明該檔案是使用者提供的頭檔案,查找該檔案時将從目前檔案目錄(或檔案名指定的其他目錄)中尋找檔案,然後再在标準位置尋找檔案。
條件編譯:
編譯指令#if、#elif、#else、#endif用于條件編譯,基本格式如下:#if常量表達式1語句……#elif常量表達式2語句……#elif常量表達式3語句……#else語句……#endif#if和#else分别相當于C語言語句中的if和else,它們根據常量表達式的值來判别是否編譯後面的語句。#elif相當于C語言中的else if,#else之後不帶常量表達式。常量表達式可以是包含宏、算術運算、邏輯運算等的合法C常量表達式。如果常量表達式為一個未定義的宏,那麼它的值被視為0。
28. 檔案操作
檔案系統中,檔案句柄是一個重要的概念。每個被使用的檔案,都在記憶體中開辟一個區域,用來存放檔案的有關資訊,例如,檔案的狀态以及目前位置等。這些資訊儲存在一個結構體變量中,結構體的類型是由系統定義的。在C語言中,該結構體取名為FILE要處理檔案,程式必須建立檔案句柄指針變量并打開檔案,然後用輸入函數從檔案中讀取資料,用輸出函數向檔案中寫入資料。
不論對哪種類型的檔案,程式都調用fopen函數打開檔案。fopen函數的一般格式為:檔案句柄指針=fopen(檔案名字元串,檔案打開方式字元串)fopen函數的第1個參數是包含檔案名的字元串,第2個參數是包含一個或多個檔案說明符的字元串
不論對哪種類型的檔案,程式都調用fclose函數關閉檔案。fclose函數的一般格式為:fclose(檔案句柄指針);
文本檔案的操作:
二進制檔案的操作:
标準檔案:
文本檔案和二進制檔案都是指存儲在磁盤或錄音帶上的資訊流。實際上,針對每個程式,系統還打開了3個标準檔案,它們是stdin、stdout、stderr,分别是standard input(标準輸入)、standard output(标準輸出)、standard error(标準出錯)的縮寫。檔案stdin是程式可以讀取其輸入的位置,預設情況下,從鍵盤讀取。stdout是程式寫入其輸出的位置,除非将其定向到其他地方,否則标準輸出通常出現在顯示器上。stderr是程式發出錯誤和特殊消息的地方,除非将其定向到其他地方,否則标準錯誤通常出現在顯示器上。實際上,不論在标準檔案系統還是非标準檔案系統中,檔案結構隻需要用檔案句柄或檔案代号代替,前面介紹的檔案操作函數也均适用。
其他檔案操作函數:
29. 位操作
移位運算:移位包括左移和右移。1.<<左移位左移位就是将一個數的各二進制位左移指定位數,右邊補0,高位左移溢出後,舍棄不用。把一個數左移1位,相當于用該數乘以2,當然也存在溢出的問題。2.>>右移位右移位就是将一個數的各二進制位右移指定位數,左邊補該數的符号位,低位右移溢出後,舍棄不用。把一個數右移1位,相當于用該數除以2,當然也存在舍棄小數的問題。需要說明的是,對于無符号數,高位不再代表符号,是以在右移時,高位會補0。
30. ASCLL碼表