tft每日頭條

 > 圖文

 > c語言入門知識點大全

c語言入門知識點大全

圖文 更新时间:2024-11-28 03:32:22

c語言入門知識點大全?第一部分 "C 語言基礎知識"知識點,我來為大家科普一下關于c語言入門知識點大全?下面希望有你要的答案,我們一起來看看吧!

c語言入門知識點大全(C語言知識點總結)1

c語言入門知識點大全

第一部分 "C 語言基礎知識"知識點

1、C 程序的基本結構 C程序是由函數構成的。每個程序由一個或多個函數組成,其中必須有且僅有一個主函數main( )。 main 函數是一個可執行 C 語言程序的入口和正常出口,而不論其在整個程序中書寫的位置如何。 在 C 語言中,大小寫字母是有區别的。(例如習慣使用小寫字母定義變量,用大寫字母定義常量)。 C 程序的注釋有兩種方法,一種是行注釋,使用"//";另外一種是塊注釋,使用"/* */",注意

"/*"與"*/"不能嵌套使用。 C 語言書寫較為靈活,但是提倡采用縮進格式進行程序書寫,以體現語句之間的層次感。 C 程序每條語句以"分号"作為結束标志。以下幾種情況不得使用分号:

(1) 所定義的函數名稱後不得使用分号; (2) if…else…語句是一個整體,中間不能使用分号将其分隔開; (3) 預編譯命令後不能使用分号。

2、C 程序開發步驟

C 語言在計算機上的開發過程主要由以下四個步驟組成: 第一步:編輯。生成後綴名為".c"的源文件 第二步:編譯。生成後綴名為".obj"的目标文件 第三步:連接。生成後綴名為".exe"的可執行文件 第四步:運行。

3、VC 6.0 開發工具的使用

按下功能鍵 Ctrl F7 編譯程序;按下功能鍵 F7 連接程序;按下功能鍵 Ctrl F5 運行程序;若程序在編譯和連接過程中有語法錯誤,則按下功能鍵 F4 定位錯誤所在行并根據錯誤提示信息改正錯誤(原則是先解決 error,再解決 warning)。

4、C 語言中标識符的命名規則

标識符由字母、數字、下劃線組成;規定第一個字符必須為字母或下劃線。 标識符定義的變量名、函數名、常量名等最好做到"見名知義";大小寫代表不同含義;不能使

用關鍵字;最好不要與 C 語言的庫函數同名。

5、C 語言的數據類型

C 語言的數據類型由基本類型和複雜類型構成。其中基本數據類型包括字符型(char)、整型(int,short,long)、實型(float,double);複雜數據類型包括指針類型、數組、結構體、聯合體。

char 型占 1 個字節、short 型占 2 個字節、long 型和 float 型占 4 個字節、double 型占 8 個字節。

6、常量

(1) 字符型常量(用單引号括起來的一個字符) 兩種形式——普通字符、轉義字符(掌握'\n'、'\0'、'\t'、'\\'、'\''、'\"'、'\ddd'、'\xhh') 不論普通字符,還是轉義字符,都等價于 0-127 之間的某個整數,即 ASCII 碼表。

(2) 整型常量 三種表示形式——十進制形式、八進制形式(加前導 0)、十六進制形式(加前導 0x) 注意:C 語言的整型常量沒有二進制表示形式。

(3) 實型常量 兩種表現形式——小數表示形式、指數表示形式(由"十進制小數"+"e 或 E"+"十進制整數"組成,注意:e 或 E 的兩側必須有數,其後必須為整數)

(4) 字符串常量(用雙引号括起來的零個或者若幹多個字符) 編譯系統會在字符串的最後添加'\0'作為字符串的結束符。比較'a'和"a"的不同。

(5) 符号常量:例如 #define PI 3.14159

7、變量

變量必須"先定義、後使用"。變量代表計算機内存中一定大小的存儲空間,具體代表多少字節的存

儲空間示變量的類型而定,該存儲空間中存放的數據就是變量的值。 注意:變量定義後如果未賦初值,則變量的初值是随機數。因此變量應該先賦值再使用才有意義。為

變量賦值的幾種方法:①初始化;②賦值語句;③調用标準輸入函數從鍵盤為變量賦值。 (1) 字符型變量

用"char"定義字符型變量,字符型變量存放 1 個字節的數值。對于無符号字符型變量,取值範圍是 0~255,對于有符号字符型變量,取值範圍是-128~ 127。

(2) 整型變量 用"int"、"short"、"long"定義整型變量,其中 int 型和 long 型占用 4 個字節的存儲空間,short型占用 2 個字節的存儲空間。

(3) 實型變量 用"float"、"double"定義實型變量,其中 float 型占用 4 個字節的存儲空間,double 型占用 8個字節的存儲空間。

8、表達式

表達式具有廣泛的含義,根據運算符不同,有賦值表達式、算術表達式、邏輯表達式、關系表達式等,甚至單獨的一個常量或一個變量也是一個表達式。

9、運算符

(1) 算術運算符( 、-、*、/、%) 除号(/)——當除數和被除數都為整數時,相除的結果自動取整。 求餘号(%)——要求"%"号的兩側必須是整數,不能是實數。

(2) 賦值運算符( = ) 格式"變量 = 表達式",表示将表達式的值賦值到變量對應的存儲空間裡。 注意:賦值号"="的左側必須是變量,不能是常量或者表達式。

(3) 複合賦值運算符( =、-=、*=、/=、%=) 由算術運算符和賦值運算符組成,是兩個運算符功能的組合。例如:a = a c;

★(4) 自增、自減運算符( 、- -)表達式 當自增、自減運算符單獨使用時放在變量前面或者後面沒有區别。

例如: i; 等價于 i ; 等價于 i=i 1; 自增、自減運算符與其它運算符共同存在于表達式中時,放在變量前和變量後有區别。

例如:若定義 int i = 3, j; 則 j = i; 語句執行後 i 的值為 4,j 的值為 4。 則 j = i ; 語句執行後 i 的值為 4,j 的值為 3。

(5) 關系運算符(>、<、>=、<=、==、!=) 注意:不能混淆賦值運算符(=)和關系運算符中的等于号(==)。前者是做賦值操作,

後者是判斷兩個數是否相等。

關系表達式的值隻有"邏輯真(用數值 1 表示)"和"邏輯假(用數值 0 表示)"兩種情況。

如果表達式的值為實型,不能使用"=="或者"!="判斷兩個值相等還是不相等。 (6) 邏輯運算符(!、&&、||)

運算邏輯表達式時,當參與運算的數"非 0 表示真"、"0 表示假";表達式的解"1 表示真"、"0 表示假"。

注意:"短路特性"的含義。如果邏輯與"&&"運算符左側表達式的值為 0(假),則該運算符右側的表達式被"短路",即運算過程被計算機省略掉;如果邏輯或"||"運算符左側表達式的值為 1(真),則該運算符右側的表達式被"短路"。

(7) 位運算符(~、^、&、|、<<、>>) 隻适用于字符型和整數型變量。是 C 語言具有低級語言能力的體現。 注意:不能混淆邏輯與運算符"&&"和按位與運算符"&";邏輯或運算符"||"和按位

或運算符"|";邏輯非運算符"!"和按位取反運算符"~"。 (8) 逗号運算符(,)

功能為從左至右依次計算由逗号隔開的各表達式的值,最後一個表達式的值即為整個逗号

表達式的值。是優先級最低的運算符。 (9) 條件運算符(? :)

這是 C 語言中唯一的一個三目運算符,其形式為:<表達式 1> ? <表達式 2> :<表達式 3> (10) 求字節運算符 sizeof

注意:不能混淆求字節運算符 sizeof 和字符串長度庫函數 strlen( )。前者是運算符,後者是函數。sizeof("Hello")的值為 6,而 strlen("Hello")的返回值為 5。

(11) 各種運算符混合運算時的優先級排隊口決 二、 二、 二、 與、 或、 二、 逗 ! * / % - > >= < <= == != && || = ,

(12) 數據類型的強制轉換 格式:(轉換類型名)表達式。 注意:類型名兩側的小括号不能省略,表達式示情況而定可以增加小括号。

第二部分 "C 程序的三種基本結構"知識點

1、語句 C 語言的語句分為四類:①簡單語句(分為表達式語句、函數調用語句);②空語句;③複合語句(由一對大括号括起來的一條或多條語句,複合語句在語法上視為一條語句);④控制語句(分為結構化語句,

如 if 語句、switch 語句、while 語句、do-while 語句、for 語句;非結構化語句,如 break 語句、continue語句、return 語句、goto 語句)。

2、程序的三種基本結構

順序結構、選擇結構、循環結構

3、順序結構

(1) printf()函數的使用 難點

一般形式為:printf("格式控制字符串",輸出項列表);

其中"格式控制字符串"包含三類字符——普通字符(即原模原樣輸出的字符,主要用于做

提示信息)、格式說明符(以"%"開頭)、轉義字符(以"/"開頭) 輸出項列表是可以省略的,當"格式控制字符串"中沒有"格式說明符"時,輸出項列表省

略;若是有"格式說明符"時,輸出項列表不能省略,并且有幾個格式說明符,輸出項列表

就必須有幾個對應數據類型的表達式,各表達式之間用逗号隔開。 需要掌握的格式說明符有:%c、%d、%f、%s、%u、%o、%x、%ld、%lf、%e、%%

(2) scanf()函數的使用 難點 一般形式為:scanf("格式控制字符串",地址列表); 其中"格式控制字符串"包含兩類字符——普通字符(需從鍵盤原模原樣輸入的字符,一般

起分隔和提示作用)、格式說明符(以"%"開頭) 地址列表通常是不省略的,根據"格式控制字符串"中包含多少個格式說明符,地址列表中就有幾個地址。對于普通變量,需在變量名前加上取地址符"&",數組名前不需加"&"。 注意 1:scanf()函數的"格式控制字符串"中不能包含"轉義字符",否則将引起輸入無效。如 scanf ("%d\n", &a);是錯誤的。 注意 2:scanf()的格式控制字符串中的普通字符不是用來顯示的, 而是輸入時要求照普通字符原模原樣輸入。 注意 3:scanf()中參數的第二部分一定是地址列表,不能是表達式。 注意 4:字符和數值混合輸入且二者中間沒有分隔符,需注意何時加空格。例如:已定義

char x; int y; scanf("%c%d", &x, &y); 此時從鍵盤輸入時,字符和整數之間需加空格; 而 scanf("%d%c", &y, &x); 此時從鍵盤輸入時,整數和字符之間不能加空格。

(3) getchar()函數的使用 函數原型為:char getchar(void); 例如:char a; a=getchar( ); 該函數使用時關注函數的返回值。

(4) putchar()函數的使用 函數原型為:char putchar(char); 例如:putchar('A'); 該函數使用時關注函數的參數。

(5) printf( )、scanf( )、getchar( )、putchar( )這四個函數都屬于标準輸入輸出庫函數,調用時需在程序中包含頭文件 stdio.h。

(6) 例如已定義:char a, b='A'; 則以下函數調用等價

4、選擇結構

scanf("%c", &a); 等價于 a = getchar( ); printf("%c", b); 等價于 putchar(b);

(1) if 語句 if 語句的三種形式——單分支選擇結構、雙分支選擇結構、多分支選擇結構。 單分支選擇結構: if(表達式)

注意:if 語句的表達式很多時候是關系表達式,不要将"=="号誤用成"="号。 說明 1:表達式兩側的小括号不能省略,此表達式可以是 C 語言中任意合法的表達式,隻

要表達式的值為非零(真),就執行其後的語句體;否則,結束 if 語句。 說明 2:由于"if(表達式)"和"語句體"是一個整體,在語法上看作一條語句,因此在"(表

達式)"後面不能加";",如果加了分号,則 if 語句的語句體就成了空語句。 說明 3:"if(表達式)"會自動結合一條語句,如果語句體有多于一條語句時,必須使用複

合語句,即用大括号将多條語句括起來。

語句體;

易錯點

易錯點

說明 4:為了表示語句體從屬于 if,書寫時,應使語句體與關鍵字 if 的位置有縮進。 雙分支選擇結構(二選一):

說明 1:表達式隻寫在關鍵字 if 的後面,不能寫在 else 的後面。 說明 2:"if"、"語句 1"、"else"、"語句 2"是一個整體,在語法上看作一條語句,因此在

"(表達式)"後面不能加分号,在關鍵字 else 後面也不能加分号。 說明 3:如果"語句體 1"、"語句體 2"有多于一條語句,則必須使用複合語句。 說明 4:書寫時,應使關鍵字 if 和 else 對齊,"語句體 1"和 if 之間有縮進,"語句體 2"

和 else 之間有縮進。 多分支選擇結構(多選一):

說明:表達式一定是跟在關鍵字"if"的後面,不能跟在關鍵字"else"的後面。

if(表達式) 語句體 1;

else 語句體 2;

if(表達式 1) 語句體 1; else if(表達式 2) 語句體 2; … else if(表達式 n) 語句體 n; else 語句體 n 1;

(2) switch 語句 switch(表達式) { case 常量表達式 1: 語句 1; <break;> case 常量表達式 2: 語句 2; <break;> ……

case 常量表達式 n: 語句 n; <break;> 說明 1:關鍵字 switch 後面表達式的值必須是整型或者字符型,不能是實型。 說明 2:關鍵字 case 後面是"常量表達式",隻能是常量或常量表達式,不能是變量或者變量

表達式。且表達式的值必須是整型或者字符型,不能是實型和字符串。書寫時注意

"case"與"常量表達式"之間必須有空格;"常量表達式"後面是冒号。 說明 3:每個 case 分支後面的常量表達式必須互不相同。 說明 4:每一個分支後面的"break"可以省略,如果省略,則程序繼續執行下一個 case 分支

的語句,否則執行完該 case 分支的語句就跳出 switch 語句。 說明 5:多個 case 分支可以共用一組語句,當某個 case 分支後面省略了語句,則意味着該分支

與它後面緊鄰的分支共用語句。 說明 6:default 可以省略。 說明 7:書寫時必須注意①switch 後面的表達式必須用小括号括起;②表達式的小括号後面不

能加分号;③case 和其後常量表達式之間必須加空格;④常量表達式以及 default 後面必須加冒号。

5、循環結構

循環結構程序編寫過程中的三要素——循環的初始條件、循環的終止條件、控制循環結束條件的變化。

<default : 語句 n 1;> }

while(表達式) 循環體;

重點

(1) while 語句

while 語句構成的循環稱為當型循環。當表達式的值為非零,則執行循環體,否則結束循環。 說明 1:表達式可以是 C 語言中任意合法的表達式,書寫時不能省略其兩側的小括

号。 說明 2:"while(表達式)"會自動結合一條語句,如果循環體有多于一條語句時,必須使用複合

語句。 說明 3:"while(表達式)"與"循環體"是一個整體,"(表達式)"後面不應加分号,否則循環

體就成了一條空語句。 (2) do-while 語句 do

循環體;

do-while 語句構成的循環稱為直到型循環。先執行循環體,再判斷表達式的值是否為非零,是則繼續下一次循環,否則結束循環。 說明 1:do 必須和 while 聯合使用。 說明 2:如果循環體有多于一條語句時,必須使用複合語句。 說明 3:表達式可以是 C 語言中任何合法的表達式,書寫時其兩側的小括号不能省略,"while(表

達式)"後面的分号也不能省略。 (3) for 語句

說明 1:小括号裡有三個表達式,每個表達式之間用分号隔開。這三個表達式都可以缺省,但是應該在其它相應的位置補齊。

說明 2:"表達式 1"也稱為初始表達式,在整個循環開始前執行一次;"表達式 2"也稱終止表達式,每輪循環進入前執行一次,如果該表達式的值為非零,則執行循環體,否則結

束循環;"表達式 3"也稱循環表達式,每次循環結束時執行一次,常用來控制循環的初始條件逐漸轉變到終止條件。

說明 3:"for(…)"會自動結合一條語句,當循環體有多于一條語句時,必須使用 複合語句。

(4) break 語句 break 語句出現在循環體中的作用是提前結束本層循環。 break 語句出現在 switch 語句中的作用是跳出本層 switch 語句。

(5) continue 語句 continue 語句隻能出現在循環體中,其作用是提前結束本輪循環,進入下一輪循環。即當

continue 語句被執行時,放置在該語句之後的其它語句将被略過。注意:continue 語句并沒有使整個循環結束。

6、常用算法、常用庫函數

(1) 交換兩個變量中存放的數值——使用首尾相接的三條語句。例如:已定義 int a=3, b=4, t; 若要交換 a 和 b 中的數值,使用如下三條語句 t = a; a = b; b = t;

(2) 數學函數(需包含頭文件 math.h)——sqrt( )、fabs( )、pow( )、exp( ) (3) 斐波拉契數列 (4) 素數問題 (5) N 項式求和問題 (6) 叠代法

while(表達式);

for(表達式 1; 表達式 2; 表達式 3)循環體;

重點, 難點

難點 重點, 難點

第三部分 "數組、字符串"知識點

1、一維數組 (1)一維數組的定義形式:類型說明符 數組名[常量表達式]; 注意:方括号中的"常量表達式"表示該數組的元素個數。隻能是常量,不能是變量或者變量表達式。 說明 1:數組一旦定義,就在内存空間中分配連續存放的若幹存儲單元,每一個存儲單元的大小由數

據類型決定。例如有如下定義:int a[10]; 則計算機為數組 a 連續分配 10 個存儲單元,每個 存儲單元占用 4 個字節,總共是 40 個字節的存儲空間。

說明 2:數組一旦定義,數組名就代表了一段連續存儲空間的首地址,數組名是常量,永遠指向該數 組第一個元素的内存單元地址。

(2)一維數組元素的引用:數組名[下标] 與一般變量一樣,數組必須先定義,後使用。數組元素的引用是指使用已定義數組中的某個指定元素,

通過"下标"來指定需要引用的元素。 注意 1:下标的下限一定是"0",上限由數組定義時的常量表達式值決定,為"常量表達式值-1"。

假設已經有如下定義:int a[10]; 則引用該數組元素的下标範圍是"0~9",若引用時下标超過此範圍,稱為數組越界,會導緻程序運行出錯。

注意 2:必須區分數組定義時方括号中的"常量表達式"和數組元素引用時方括号中的"下标",二者具有不同的含義和功能。前者是指明數組的大小,後者是指明要引用數組中的第幾個元素。

(3)一維數組的初始化 與一般變量一樣,數組定義後,如果沒有為其賦初值,則數組元素中的初值是随機數。為數組元素賦

值的方法通常有兩種:一種是進行初始化;一種是使用循環結構依次為每個數組元素賦值。 數組初始化的方法分為:①全部元素賦初值;②部分元素賦初值;③全部元素賦初值時可以不指定數

組長度。 (4)一維數組元素的輸入、輸出 由于數組中的元素是若幹個相同類型的數值,不能對其進行整體的輸入或者輸出,必須針對單個元素

進行輸入或者輸出,這時就要使用循環結構,對于一維數組來說,使用單層循環。

2、二維數組

(1)二維數組的定義形式:類型說明符 數組名[常量表達式 1][ 常量表達式 2]; 說明 1:"常量表達式 1"指明二維數組的行數,"常量表達式 2"指明二維數組的列數。 說明 2:二維數組可以看作特殊的一維數組,二維數組元素在内存中是"按行存放"。 (2)二維數組元素的引用:數組名[行下标][列下标]

說明:與一維數組一樣,二維數組元素引用時的行下标和列下标不能越界。假設已經有如下定義:int a[3][4]; 則引用該數組元素時,行下标的範圍是"0~2",列下标的範圍是"0~3"。

(3)二維數組的初始化 二維數組初始化有以下四種方式:①分行全部元素初始化(使用兩層花括号);②分行部分元素初始

化;③按照數值存放順序不分行初始化(使用一層花括号);④按照數值存放順序不分行初始化,當對全

部元素賦初值時,可以省略确定行數的常量值。 (4)二維數組元素的輸入、輸出 使用雙層循環嵌套對二維數組的所有元素進行輸入、輸出。

3、字符數組與字符串

(1)字符數組與字符串的關系 字符數組是字符型數據的集合。定義方式為:char 數組名[常量表達式]; 與其它類型的數組一樣,将

數組中的各個字符看作是獨立的個體。當這些字符中有'\0'時,可以将它們視為一個整體,即字符串。 字符串有常量,但是沒有字符串型的變量,字符串常量使用字符數組進行存放,前提是字符數組的大

小要能容納整個字符串,包括字符串的結束符'\0'。 (2)字符數組的初始化 當字符數組中存放的所有字符作為獨立個體時,其初始化方法與其它類型的數組一樣。當字符數組中

存放的是字符串時,其初始化方法有如下幾種: ① char a[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; ② char a[6] = {"Hello"}; ③ char a[6] = "Hello"; ④ char a[] = "Hello"; (3)向字符數組中存放字符串的方法 定義了字符數組後,如果要向數組中存放字符串,除了以上提到的初始化方法,還有以下方法,注意

不能使用賦值語句的方法。假設已經有定義:char a[50]; 方法 1:scanf("%s", a); 注意:a 已經代表數組的首地址,前面不再有取地址符&。 方法 2:gets("%s", a); 方法 3: int i=0;

while((a[i] = getchar()) != '\n') i ; a[i] = '\0';

重點 注意:不能用賦值語句的方法向字符數組中存放字符串。以下寫法是錯誤的,原因是數組名是常量, 永遠指向數組的首地址,字符串常量書寫時,系統給出其在内存中占用的一段無名存儲區的首 地址,不允許将數組名這個常量重新賦值指向另一個地址空間。

char a[50]; a = "Hello"; (錯誤) (4)'\0'何時系統自動添加、何時需手動添加 字符串常量的結束标志是'\0',缺少了'\0',則不能稱為字符串常量。以下列出何時由系統自動添加'\0',

何時需要編程者自己手動添加'\0'的幾種情況。 系統自動添加的情況:(假設已有定義: char a[50];) 調用 scanf 函數從鍵盤輸入字符串時。例如:scanf("%s", a); 調用 gets 函數從鍵盤輸入字符串時。例如:gets(a); 以字符串常量形式對字符數組進行初始化時。例如:char a[50] = "Hello"; 調用 strcpy 函數将字符串拷貝到字符數組中時。例如:strcpy(a, "Hello");

需手動添加'\0'的情況: 以字符形式對字符數組進行初始化時。例如:char a[ ] = {'H', 'e', 'l', 'l', 'o', '\0'}; 先定義字符數組,再将單個字符賦值到各個數組元素中時。例如:char a[50];

a[0]='H'; a[1]='e'; a[2]='l'; a[3]='l'; a[4]='l'; a[5]='\0'; 對字符數組中原來存放的字符串進行處理,破壞了原字符串的'\0',對新處理後的字符串需手動添加'\0'

(5)字符串輸入、輸出 第一種方法:調用 scanf、printf 函數實現,格式說明符使用"%s"。例如:

char a[50]; scanf("%s", a); //當遇到空格或者回車時系統認為字符串輸入結束 printf("%s", a); //字符串輸出

第二種方法:調用 gets、puts 函數實現。例如: char a[50]; gets(a); //當遇到回車時系統認為字符串輸入結束

puts(a); 說明:scanf 和 gets 輸入字符串時的區别是——scanf 不接收空格,該函數認為空格是字符串輸入結束

标志。而 gets 接收空格作為字符串中的有效字符,該函數隻認為回車是字符串輸入結束标志。 (6)字符串處理函數 求字符串長度函數:strlen(s)

例如:char s[50]; int len; len = strlen(s); 說明 1:使用 strlen 求字符串長度時,計算的是第一個'\0'之前的有效字符個數,函數返回值不包

括'\0'占用的字節數。 說明 2:注意區分 strlen 和 sizeof。首先,strlen 是庫函數,而 sizeof 是運算符;其次,strlen 計

算的是字符串有效字符占用的字節數,不包括'\0'占用的空間,而 sizeof 計算的是字符 數組或者字符串占用内存的字節數,包括'\0'占用的空間。例如:

char s[20]="Hello"; int x, y, m, n; x = strlen(s); y = sizeof(s); m = strlen("Hello"); n = sizeof("Hello"); 以上舉例中,變量 x 和 m 的值都是 5,因為 strlen 函數僅僅統計字符串中有效字符的占 用的字節數。變量 y 的值是 20,因為 sizeof(s)計算的是數組 a 在内存中占用的字節數。 變量 n 的值是 6,因為 sizeof("Hello")計算的是字符串"Hello"在内存中占用的字節數, 包括'\0'占用的空間。

字符串連接函數:strcat(s1, s2) 例如:char s1[50] = "Hello", s2[50] = " every one";

strcat(s1, s2); //表示把字符串" every one"粘貼到字符串"Hello"的後面 strcpy(s1, "every one");

字符串比較函數:strcmp(s1, s2) 說明:該函數是從左至右依次将兩個字符串的對應字符取出做比較,比的是對應字符 ASCII 碼

值的大小。當字符串 s1 大于字符串 s2 時,函數返回 1;當字符串 s1 等于 s2 時,函數返 回 0;當字符串 s1 小于 s2 時,函數返回-1。

字符串拷貝函數:strcpy(s1, s2) 說明:該函數将 s2 指向的字符串拷貝到 s1 指向的存儲空間裡,要求 s1 指向的存儲空間必須足夠

大,能夠容納即将拷貝的字符串。 例如: char s1[50], s2[50] = "Hello";

strcpy(s1, s2); //表示把字符數組 s2 中存放的字符串拷貝到字符數組 s1 中 strcpy(a, "China"); //表示把字符串"China"拷貝到字符數組 a 中

4、常用算法

(1)冒泡法排序 (2)選擇法排序

重點

重點

第四部分 "函數"知識點

1、庫函數與自定義函數

(1) 庫函數:目前已學習過的庫函數有标準輸入輸出類庫函數、數學類庫函數,當程序中調用庫函數時,必須包含對應的頭文件。例如标準輸入輸出類庫函數對應的頭文件是<stdio.h>,數學類庫

函數對應的頭文件是<math.h>。 (2) 用戶自定義函數:用戶自己編寫的完成特定功能的函數,也稱子函數。 (3) 一個 C 程序由一個 main 函數和若幹多個子函數組成。

2、函數定義、函數調用、函數聲明的概念

(1) 函數定義——即定義函數的功能。未經定義的函數不能使用。 (2) 函數調用——即執行一個函數,調用函數時,程序跳轉到被調用函數的第一句開始執行,執行

至被調用函數的最後一句,然後程序返回調用該函數處。 (3) 函數說明——即通知編譯系統該函數已經定義過了。

3、函數定義的格式

<函數類型> 函數名 (<參數表>) {

重點 函數首部

<函數體語句> } 函數由函數首部和函數體構成,其中函數首部由函數類型、函數名、參數表組成。 關于函數類型的說明 說明 1:函數類型分為"空類型(關鍵字是 void)"和"非空類型(需指定具體的返回類型,如 int、

float、double、char、指針類型、結構體類型等)"。 說明 2:當缺省"函數類型"時,默認函數返回類型為 int 型。 說明 3:當函數類型是"非空類型"時,函數體内必須有 return 語句,寫成"return(表達式);",

表達式值的類型必須與函數類型一緻,否則編譯系統會給出警告提示。 說明 4:當函數類型是"void"時,函數體内不需要 return 語句,或者直接寫"return ;"即可。 說明 5:函數類型是 C 語言中的關鍵字,在 VC 6.0 編譯環境中是藍色字體。 關于函數名的說明 說明 1:函數名命名必須符合 C 語言标識符的命名規則。命名函數名最好是見名知意。 說明 2:同一段程序中的各自定義函數不允許函數名同名。 關于參數表的說明

說明 1:此時參數表中的參數稱為形式參數,簡稱"形參"。形參必須用一對小括号括起來。 說明 2:如果參數表中沒有參數,稱為無參函數,此時小括号中可以寫關鍵字 void,或者什麼都

不寫。 說明 3:如果參數表中有參數,稱為有參函數,此時小括号中必須明确申明各個參數的數據類型。

注意:每個參數都必須有各自的類型說明符,如 int fun(int a, int b, char c) 關于函數體的說明

說明 1:函數體必須用一對大括号括起來,函數體前面是說明部分,後面是執行語句部分。 說明 2:函數首部與函數體是一個整體,不能被分離開。例如,在括起參數表的小括号與括起函數

體的大括号之間加上分号是錯誤的。

4、函數調用

一個已經定義的函數,隻有在發生函數調用時才能被執行。函數調用的過程即是程序跳轉到被調用函

數的第一句開始執行,執行至被調用函數的最後一句,然後程序返回函數調用語句處。 函數調用的一般形式: (1)有參數函數的調用形式: 函數名(參數) (2)無參數函數的調用形式: 函數名( )

函數的傳值調用 函數調用時的參數稱為實際參數,簡稱"實參"。當發生函數調用時,實參将數值傳遞給形參,

實現函數調用時的數值傳遞。 為保證函數調用時正确的數值傳遞,"實參"與"形參"應有嚴格的對應關系,可以歸納為"3

個一緻和 1 個不一緻"——規定:實參的個數、類型、順序必須與被調用函數形參的個數、類型、順序保持一緻。而實參與形參的參數名稱可以不相同。 C 語言中函數調用的三種方式

(1)作為獨立的語句。例如:printf("Hello world!"); (2)作為表達式中的一部分。例如:y = sqrt(9); (3)作為其它函數的實參。例如:printf("y = %lf\n", sqrt(9));

5、函數聲明

編輯 C 程序時,如果函數定義寫在函數調用之後,則需要進行函數聲明,否則可以省略函數聲明。函數聲明的一般形式為:

類型名 函數名(類型 1,類型 2,… ,類型 n); 說明:函數聲明、函數定義、函數調用三者必須有嚴格的對應關系,三者的函數類型需一緻,函數名

需相同,參數的個數、類型、順序需一緻。

6、函數的嵌套調用

C語言中不允許作嵌套的函數定義。因此各函數之

間是平行的,不存在上一級函數和下一級函數的問題。 但是C語言允許在一個函數的定義中出現對另一個函

數的調用。這樣就出現了函數的嵌套調用。即在被調函

數中又調用其它函數。 其關系如圖所示:在執行 main 函數的過程中調用

f1 函數,于是轉去執行 f1 函數,在執行 f1 函數過程中又調用 f2 函數,于是轉去執行 f2 函數,f2 函數執行完畢後返回 f1 函數的斷點繼續執行,f1 函數執行完畢後返回 main 函數的斷點繼續執行。

7、變量的作用域和存儲類别(教材 12.1~12.3 節)

變量的作用域是指從空間上對變量的作用範圍進行分類,分為全局變量和局部變量。其中全局變量的

作用範圍寬,局部變量的作用範圍窄。 變量的存儲類别是指從時間上對變量的存在時間長短進行分類,分為動态變量、靜态變量。其中動态

變量的存在時間短,靜态變量的存在時間長。

(1)變量的作用域 變量的作用域是指變量的作用範圍,分為全局變量和局部變量,局部變量又分為函數體的局部變量以

及複合語句的局部變量。

全局變量 函數體内的局部變量 複合語句内的局部變量 定義位置 定義在函數體外面 定義在函數體内部 定義在複合語句内部

作用域 從定義位置開始到整個.c 文件結束有效

本函數體内有效 本複合語句内有效

注意事項 (1)同一個.c 文件内的全局變量不能重名

(1)必須寫在執行語句之前(2)同一函數體内的局部變

(1)必須寫在執行語句之前(2)同一個複合語句内的局

重點

(2)全局變量允許與局部變量重名,重名時,局部變量

屏蔽全局變量

量不能重名 (3)當與全局變量重名時,局部變量屏蔽全局變量

部變量不能重名 (3)與前兩種變量相比,這是作用範圍最小的一種變量

說明 1:從此表格可以看出,作用範圍最寬的是全局變量,其次為函數體内的局部變量,範圍最窄的是複合語句内的局部變量。

說明 2:當全局變量、局部變量有重名時,範圍較窄的變量會自動屏蔽範圍較寬的變量。 說明 3:定義在函數體内的變量以及形參都屬于局部變量。 (2)變量的存儲類别 變量的存儲類别分為 auto(動态型)、static(靜态型)、register(寄存器型)、extern(外部型)。 動态變量—— 隻在某一個時間段内存在。例如函數的形參、函數體内的局部動态變量,這類變

量在發生函數調用時,系統臨時為它們分配存儲空間,但是随着函數調用結束, 這些變量的存儲空間被釋放掉,變量的值也随之消失。 動态變量分為全局動态變量、局部動态變量。

靜态變量—— 生存期為程序的整個執行過程,直到程序運行結束。這類變量一旦定義,系統就 為之分配存儲空間,靜态變量在整個程序運行過程中固定的占用這些存儲空間, 因此也稱永久存儲。

靜态變量分為全局靜态變量、局部靜态變量。 注意:靜态變量定義後如果沒有賦初值,則初值為零。這一點與動态變量不同, 動态變量定義後如果沒有賦初值,則初值是随機數。

寄存器變量—— 可以将使用頻率較高的變量定義為 register 型,以提高程序的運行速度。寄存 器變量屬動态變量,存儲空間到特定時候就自動釋放。 注意:寄存器變量隻限整型、字符型、指針型。

外部變量—— 如果在某個源文件(例如 a.c)中定義了一個全局動态變量 int x,在另外一個源

auto

static

register

extern

重點

重點

文件(例如 b.c)中需要引用這個全局變量 x,則在"b.c"中對變量 x 進行如下說 明"extern int a;"後,即可引用"a.c"中定義的變量 x。 注意:全局變量的定義隻能有一次,但是使用 extern 對其進行說明可以有多次。 這一點與函數類似,函數定義也是隻能有一次,而函數說明可以有多次。

8、函數的存儲分類(教材 12.4 節)

(1)用 static 說明函數 一個函數定義後,除了被所在的源文件調用,不允許被其它的源文件調用,則在函數首部的返回值

類型前面加上 static 關鍵字即可達到以上目的。這樣做的好處是避免不同的.c 文件定義了同名的函數而引起混亂。

(2)用 extern 說明函數 一個函數定義後,如果除了被所在的源文件調用,還能被其它源文件調用,則其它源文件在調用該函

數前,需先使用 extern 關鍵字進行說明,之後便可調用。

9、編譯預處理(教材 13.1 節)

在 C 語言中,凡是以"#"開頭的行都稱為編譯預處理命令行,要求掌握"#define"和"#include"。注意:每行的末尾不能加";"号。

(1) 宏替換 —— #define 不帶參數的宏定義

#define 宏名 替換文本 使用說明:替換文本中可以包含已經定義過的宏名 書寫說明:當宏定義分多行書寫時,在行末加一個反斜線"\";宏名習慣用大寫字母;宏定義一般寫在程序的開頭。 帶參數的宏定義

#define 宏名(參數表) 替換文本 使用說明 1:參數表中隻有參數名稱,沒有類型說明。 使用說明 2:如果替換文本中有括号,則進行宏替換時必須有括号;反之,如果替換

文件中本身沒有括号,則宏替換時不能随便加括号。 書寫說明:宏名和小括号必須緊挨着;小括号不能省略;

重點

(2)文件包含 —— #include 所謂文件包含是指在一個文件中去包含另一個文件的全部内容,#include 命令行的形式如下: #include "文件名" 或者 #include <文件名> 如果文件名用雙引号括起來,是指系統先在源程序所在的目錄查找指定的包含文件,如果找不到,再

按照系統指定的标準方式到有關目錄中去找。 如果文件名用尖括号括起來,系統将直接按照系統指定的标準方式到有關目錄中去尋找。

第五部分 "指針"知識點

1、指針的基本概念(教材 8.1 節) (1)計算機的内存空間是由許多存儲單元構成的,每個存儲單元代表一個字節的容量,每個存儲單

元都有一個唯一的編号,即地址。程序運行過程中使用變量等就存放在這些存儲單元中。對變量的取值有

兩種方法,一種是使用變量名對其内容進行存取,稱為"直接法",另一種是借助變量的地址對其内容進

行存取,稱為"間接法"。 (2)指針──即地址。一個變量的地址稱為該變量的指針,通過變量的指針能夠找到該變量。 指針變量──專門用于存儲其它變量地址的變量。指針與指針變量的區别,就是變量值與變量名的區

别。注意:指針變量存放的是地址值,而不是通常意義上的數值。

2、指針變量的定義、賦值(教材 8.2 節)

(1)指針變量的定義: 類型标識符 *指針變量名; 說明 1:此處的類型标識符稱為指針變量的"基類型",即表示該指針變量應存放何種類型的變量地

址,指針變量的基類型必須與其指向的普通變量同類型,否則會引起程序運行錯誤。 說明 2:與普通變量的定義相比,除變量名前多了一個星号"*"外,其餘一樣。注意:此時的星号

僅僅是一個标識符,标識其後的變量是指針變量,而非普通變量。 說明 3:例如有定義"int *p;"表示定義了一個 int 類型的指針變量 p,此時該指針變量并未指向某個

具體的變量(稱指針是懸空的)。使用懸空指針很容易破壞系統,導緻系統癱瘓。 重點

重點及難點

說明 4:不論是什麼類型的指針變量,在 VC 6.0 編譯環境中已定義的指針變量都占用 4 個字節的存儲空間,用來存放地址。這點與普通變量不一樣,普通變量根據不同的數據類型,它所占用

的存儲空間字節數是有差别的。 (2)指針變量的賦值 與普通變量相同,指針變量可以在定義時為其賦值,稱為初始化;也可以先定義,再使用賦值語句為

其賦值,賦值方式為:指針變量名=某一地址; 通常有以下幾種方法為指針變量賦值:

方法一:指針變量名 = &普通變量名 方法二:指針變量名 = 另外一個同類型并已賦值的指針變量 方法三:第三種是調用庫函數 malloc 或者 calloc,當指針使用完畢後再調用 free 将其釋放。例如: int *p; //以下兩種寫法均能實現為指針變量 p 動态分配 40 個字節存儲空間的功能 p = (int *)malloc(10 * sizeof(int)); 等價于 p = (int *)calloc(10, sizeof(int));

3、指針運算(教材 8.4.2、8.4.3 節)

(1)指針運算中兩個重要的運算符 * (取内容符): 取出其後内存單元中的内容。 &(取地址符): 取出其後變量的内存單元地址。 說明:此處的取内容符也是星号,外形上與指針變量定義時的标識符一樣,但是二者的含義完

全不相同,前者是運算符,後者隻是一個标識符。 (2)移動指針

重點

重點

移動指針就是對指針變量加上或減去一個整數,或通過賦值運算,使指針變量指向相鄰的存儲單元。

隻有當指針指向一串連續的存儲單元(例如數組、字符串)時,指針的移動才有意義。 指針移動通過算術運算(加、減)來實現,指針移動的字節數與指針的基礎類型密不可分。例如已定

義:char *p1; int *p2;進行如下運算"p1 ; p2 ;"後,指針 p1 中存放的地址值自增一個單元,指針 p2 中存放的地址值自增 4 個單元。

(3)比較運算 比較運算是比兩個指針變量中存放的地址值的大小關系。 (4)指針的混合運算 例如有定義:int a, *p; 則以下一些舉例的混合運算需要仔細推敲其含義。

難點

①"&*p"的含意是什麼?②"*&a"的含義是什麼?③"(*p) "的含義是什麼?④"*p "的含義是什麼?⑤"* p"的含義是什麼?⑥ " *p"的含義是什麼?

4、函數之間地址值的傳遞(教材 8.5 節)

(1)實參向形參傳送地址值 如果函數的形參為指針變量,對應的實參必須是基類型相同的地址值或者是已指向某個存儲單元的指

針變量。 教材 7.5 節的内容是"函數之間數值的傳遞",這種方式下完成的是實參向形參的數值單向傳遞,即

當發生函數調用時,實參将其數值傳遞給形參,函數調用完畢後,形參的改變并不能影響對應實參的值,

因此把這種數值傳遞稱為是"單向"的。 而本節的内容是"函數之間地址值的傳遞",其特點是實參為主調用函數中某内存單元的地址,在被

調用函數中可以通過形參對主調函數中該内存單元的值進行修改,這也就使得通過形參改變對應的實參值

有了可能,因此通過地址值的傳遞方式,主調函數與被調函數之間數據傳遞可以實現"雙向"的傳遞。 "傳地址"方式的體現的另外一個優越之處在于:可以将多個數據從被調函數返回到主調函數中。這

一點也是"傳值"方式做不到的,傳值方式中被調函數隻能利用 return 語句向主調函數返回一個數據。 同學需仔細區分函數之間"傳值"與"傳地址"這兩種方式各自的特點,做題時注意分析何時為傳值

方式,何時為傳地址方式。 (2)通過 return 語句返回地址值 當函數返回值的類型是指針類型,而非普通數據類型時,表明被調函數調用完畢後向主調函數返回的

是一個地址值,而不是一個普通的數值。此時應注意 return 語句的表達式值應是指針類型(地址值)。

重點

重點

5、一維數組和指針(教材 9.2 節)

(1)數組名是一個地址常量 (2)使用指針對數組元素進行訪問是基于數組元素順序存放的特性。

方式一:利用數組的首地址(數組名)訪問數組元素。注意:由于數組名是常量,因此對數 組名不能使用自增運算,必須借助一個變量 i 來實現對數組元素的順序訪問。

例如: int a[10], i = 0; while(i < 10) scanf("%d", &a[i ]); 或者 while(i < 10) scanf("%d", a i ); 方式二:利用指針變量訪問數組元素。 例如: int a[10], i = 0, *p = a; while(i < 10) scanf("%d", p );

(3)引用一維數組元素的二種等價方法——下标法、指針法 假設有如下定義:int a[3], *p = a; 從上表可總結出,下标法取數組元素數值的表達式為"a[i]"或"p[i]",指針法取數組元素數值

的方法為"*(a i)"或"*(p i)"。下标法取數組元素地址的表達式為"&a[i]"或"&p[i]",指針法取數組元素地址的方法為"a i"或"p i"。

(4)假設有以下定義:int a[10], *p = a; 則 p 和 a 的相同點是:都是指針,存放數組的首地址。 不同點是:a 是地址常量,p 是指針變量。a 永遠指向該數組的首地址,直到該數組

的存儲空間被系統收回;p 是變量,可以重新賦值指向其它的存儲空間。

6、一維數組與函數參數(教材 9.3 節)

(1)數組元素作為函數實參 由于數組元素相當于一個個獨立的普通變量,當數組元素作為函數實參時,實現的是"傳值"方式,即單向傳遞。在被調函數中隻能使用數組元素的數值,不能改變數組元素的初值。 (2)數組元素的地址作為函數實參

當某數組元素的地址作為函數實參時,實現的是"傳地址"方式,能夠達到雙向數據傳遞的功能。即在被調用函數中,不但可以利用形參使用該數組元素的初值,還可以達到修改該數組元素初值

的目的。 (3)數組名作為函數實參

當數組名作為函數實參時,由于數組名本身就是一個地址值,因此實現的是"傳地址"方式,能夠達到雙向數據傳遞的功能,對應的形參必須是一個與數組類型一樣的指針變量。在被調用函數中,

可以通過形參(指針變量)使用數組中的所有元素,還能夠修改這些元素的初值。 說明 1:數組名作為函數實參時,對應的形參有如下幾種寫法,都代表一個與數組類型一緻的指

針變量。 void fun(int a[10]) 或者 void fun(int a[ ]) 或者 void fun(int *a) { … } { … } { … }

說明 2:數組名作為實參時,對應的形參是一個與數組同類型的指針變量,發生函數調用時,系 統隻是為該指針變量(形參)分配 4 個字節的存儲空間,并不是分配等同于整個數組需要 占用的存儲容量。 例如:

a[0] a[1] a[2] 下标法

p[0] p[1] p[2] *a *(a 1) *(a 2)

取數

組元

素的

數值 指針法

*p *(p 1) *(p 2)

&a[0] &a[1] &a[2]

下标法 &p[0] &p[1] &p[2]

a a 1 a 2

取數

組元

素的

地址指針法

p p 1 p 2

重點

重點

void main(void) void fun(int a[10]){ { int a[10]; … … printf("%d", sizeof(a)); printf("%d", sizeof(a)); …

fun(a); } …

注:fun 函數中的打印結果是"4",因為形參是一個指針變量,不論何種類型的指針變量,系統都為它分配 4 個字節的存儲空間。

}

注:主函數中的打印結果是"40",因為 a 數組定義後,系統為它分配 40 個字節的存儲空間。

7、二維數組和指針(教材 9.6 節) 難點

(1)二維數組"基類型"的理解 假設有定義:int a[3][4], *p;

與一維數組一樣,二維數組名也是一個地址常量。 二維數組可以看作由多個一維數組組成,由以上定義可知,二維數組 a 由三個一維數組組成,每

一個一維數組中有四個元素,a[0]、a[1]、a[2]分别是這三個一維數組的數組名,它們各自代表了這三個一維數組的首地址,同樣也是不可改變的常量地址。

基于以上分析,可以這樣理解:①二維數組名 a 的基類型是 4 個 int 型;②一維數組名 a[0]、a[1]、a[2]的基類型是 1 個 int 型(即數組元素的類型)。 假設有定義:int a[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9 10, 11, 12};以下示意圖表示了二維數組名、一維數組名、二維數組中各元素之間的對應關系。

以上示意圖的右側是二維數組的 12 個元素,每個元素占用一個 int 型的存儲空間(4 個字節),

假設第一行第一個元素 a[0][0]的地址為 0x1000,分析可知第二行第一個元素 a[1][0]的地址為 0x1010,第三行第一個元素 a[2][0]的地址為 0x1020,這三行元素的首地址分别由 a[0]、a[1]、a[2]來存放。示意圖的中部就是 a[0]、a[1]、a[2]構成的一個一維數組,這三個元素是一級指針,存放的是地址值(分别是 0x1000、0x1010、0x1020)。示意圖的左側是二維數組名 a,它是一個二級指針,存放由 a[0]、a[1]、a[2]三個元素構成的一維數組的首地址(假設是 0x1030)。

通過以上分析可知,"a[i]"是一級指針,基類型為 1 個 int 型。"a"是二級指針,基類型是 4 個int 型。例如:"a[0]"指向元素 a[0][0],則"a[0] 1"表示地址向後移動,指向元素 a[0][1],即一級指針加 1 表示地址向後移動 1 個 int 型。"a"指向元素 a[0],則"a 1"表示地址向後移動,指向元素a[1],即二級指針加 1 表示地址向後移動 4 個 int 型。

(2)二維數組每行元素的首地址 a(或者 a[0])代表二維數組中第一行元素的首地址;a 1(或者 a[1])代表第二行元素的首地址;

a 2(或者 a[2])代表第三行元素的首地址。

1030 a

1000

1010

1020

a[0]

a[1]

a[2]

該行首地址為 1000 1 2 3 4

5 6 7 8

9 10 11 12

a[0][0] a[0][1] a[0][2] a[0][3]

a[2][0] a[2][1] a[2][2] a[2][3]

該行首地址為 1010

該行首地址為 1020

該一維數組首地址為 1030

二維數組名 a (二級指針)

一維數組名 a[i](一級指針)

二維數組元素 a[i][j] (内容)

(3)二維數組每個元素的地址 二維數組中第 i 行第 j 列的某個元素 a[i][j]的地址可以由以下幾種表達式求得: ①&a[i][j] ②a[i] j ③*(a i) j ④&(*(a i)[j]) ⑤a[0] 4*i j ⑥&a[0][0] 4*i j

(4)通過地址引用二維數組的元素 引用二維數組第 i 行第 j 列的元素的幾種表達式如下所示: ①a[i][j] ②*(a[i] j) ③*(*(a i) j) ④*(a i)[j] ⑤*(a[0] 4*i j) ⑥*(&a[0][0] 4*i j)

(5)通過建立一個指針數組引用二維數組元素 假設有定義:int *p[3]; 則将 p 稱為指針數組。 由于"[ ]"的優先級高于"*"的優先級,因此 p 首先與"[ ]"結合,構成 p[3],說明是一個數 組,"p[3]"再與"int *"結合,表示該數組中每個元素的數據類型是"整型指針"類型,于是我們将 "int *p[3]"稱為指針數組——即它首先是一個數組,數組中的每個元素是指針類型。 下面我們來分析"指針數組"與"二維數組"的對應關系,假設有定義:int *p[3], a[3][2]; (注 意以上定義中,必須保證指針數組的元素個數與二維數組的行号常量一緻,即 p[3]中的"3"與 a[3][2] 中的"3"要保持一緻)。則以下寫法表示将 p 數組中的每個元素(指針變量)指向 a 數組中的每一 行。(參看教材 P128 圖 9.6) 第一種方法:p = a; 第二種方法:for(i = 0; i < 3; i ) p[i] = a[i]; 這時,可以通過指針數組 p 來引用二維數組 a 中的元素。

① p[i][j] 等價 a[i][j] ② *(p[i] j) 等價 *(a[i] j) ③ *(*(p i) j) 等價 *(*(a i) j) ④ *(p i)[j] 等價 *(a i)[j]

(6)通過建立一個行指針引用二維數組元素 假設有定義:int (*q)[2]; 則将 q 稱為行指針。同學需仔細區分行指針與指針數組的區别。 由于定義時加了小括号,因此 q 首先與"*"結合,說明 q 是一個指針變量,然後再與"[3]"結 合,說明指針變量 q 的基類型是一個包含兩個整型元素的數組。 下面我們來分析"行"與"二維數組"的對應關系,假設有定義:int (*q)[2], a[3][2]; (注意以 上定義中,必須保證行指針的元素個數與二維數組的列号常量一緻,即(*q)[2]中的"2"與 a[3][2] 中的"2"要保持一緻)。則指針變量 q 的基類型與 a 的基類型相同,q = a; 是合法的賦值語句,表示 指針 q 指向了二維數組 a 的首地址,這時可以通過行指針 q 來引用二維數組 a 中的元素。

① q[i][j] 等價 a[i][j] ② *(q[i] j) 等價 *(a[i] j) ③ *(*(q i) j) 等價 *(*(a i) j) ④ *(*(q i)[j]) 等價 *(*(a i)[j])

(7)二維數組、指針數組、行指針之間的對應關系 假設有定義:int a[3][2], *p1[3], (*p2)[2]; 則 a 是二維數組名、p1 是指針數組名,p2 是行指針名,由于二維數組的行數與指針數組的維數相同,二維數組的列數與行指針的維數相同,因此它們三

者可以産生對應關系。以下語句合法 p1 = a; p2 = a; 可以将 a、p1、p2 都視為二級指針。

難點 8、二維數組名和指針數組名作為函數實參(教材 9.7 節)

(1)二維數組名作為函數實參 首先回憶一維數組名作為函數實參的時候,對應的形參是與數組元素同類型的指針變量,形參有如下幾種寫法:

main() { int a[3]; … fun(a); //一維數組名作為函數實參 … }

則 fun 函數首部可以有如下幾種寫法:(1)void fun(int

p[3])

p[ ]) *p)

(2)void fun(int (3)void fun(int

當二維數組名作為函數實參時,對應的形參必須是一個行指針變量,形參的寫法有以下幾種形式:

main() 則 fun 函數首部可以有如下幾種寫法: { int a[2][3]; (1)void fun(int p[2][3])

(2)void fun(int p[ ][3])

… fun(a); //一維數組名作為函數實參

… (3)void fun(int (*p)[3]) } 注意以上寫法,列下标不可缺省。無論是哪種方式,系統都把 p 處理成一個行指針。

(2)指針數組名作為函數實參 當指針數組作為函數實參時,對應的形參應當是一個指向指針的指針。形參的寫法有以下幾種形式:

main() 則 fun 函數首部可以有如下幾種寫法:{

(1)void fun(int *p[3]) (2)void fun(int *p[ ])

int a[2][3], *p[3] = a; … fun( p ); //指針數組名作為函數實參 … }

與一維數組名作實參時形參的寫法相似(一維數組名作實參時對應的形參有三種寫法),當指針數組

作為函數實參時,傳送的仍然是一個一維數組名,對應的形參也有三種寫法,隻不過形參的類型是指針類

型而已。

9、字符串與指針(教材 10.2 節)

(3)void fun(int **p)

重點

(1)使指針指向一個字符串 由于字符串中的每一個字符在内存空間裡是順序存放的,因此使用指針操作字符串是比較便利的。以

下是幾種将字符型指針變量指向字符串的正确方法: 方法一:在定義字符型指針變量時為其賦初值一個字符串(初始化)。例如: char *p = "Hello"; 方法二:先定義字符型指針變量,然後通過賦值語句讓指針變量指向字符串。例如: char *p; p = "Hello"; 示例中的字符串常量"Hello"在程序中給出的是它在内存空間的首地址,因此可以通過賦值

語句将這段無名存儲區的首地址賦值給指針變量,使得指針指向該字符串。 方法三:先定義字符型指針變量,然後将指針變量賦一個有效的地址值(可以将指針賦值為一個字符

數組的首地址,或者調用 malloc 函數為指針變量動态分配一段存儲空間),最後調用 strcpy 函數将字符串複制到指針所指向的這段存儲空間裡。例如:

char *p; p = (char *)malloc(6 * sizeof(char));

strcpy(p, "Hello");

char a[6], *p; p = a; strcpy(p, "Hello");

或者

注意:在調用 strcpy 函數之前,指針 p 必須已經指向一個有效的存儲空間,然後才能向這個

存儲空間裡存放字符串常量。如果指針隻是定義,沒有為其賦有效的地址值,這樣的 指針是不能拿來用的。

(2)一些容易範錯誤的用法 錯誤一:使用賦值語句企圖為字符數組賦一個字符串。例如: char a[6]; a = "Hello"; (錯誤原因是數組名是常量,不能指向另外的存儲空間) 錯誤二:指針變量定義後就調用 strcpy 函數企圖将一個字符串複制到指針所指的存儲空間裡。例如: char *p; strcpy(p, "Hello");

(錯誤原因是指針 p 中此時存放的是一個随機的地址值,即它還未指向一段有效的存儲空 間,向一個随機的存儲空間裡賦值字符串常量是毫無意義的。)

(3)"字符數組存放字符串"與"指向字符串的指針"的比較 對于字符串的操作,既可以使用字符數組,還可以使用字符型指針變量,二者使用上有一些異同: 相同點:都可以利用初始化的方法為其賦一個字符串常量。例如: char a[6] = "Hello"; (正确) char *p = "Hello"; (正确) 不同點 1:字符數組不能使用賦值語句為其賦字符串常量;而字符型指針變量可以通過賦值語句使之

指向字符串常量;例如: char a[6]; a = "Hello"; (錯誤) char *p; p = "Hello"; (正确) 不同點 2:字符數組定義之後可以調用 strcpy 函數為其賦字符串常量;而字符型指針變量定義之後不

能立即調用 strcpy 函數為其賦字符串常量。例如: char a[6]; strcpy(a, "Hello"); (正确) char *p; strcpy(p, "Hello"); (錯誤) 不同點 3:字符數組裝載字符串後,系統為數組開辟的是一段連續的存儲空間(大于或等于字符串長

度),數組名代表了這段存儲空間的首地址。字符型指針變量指向字符串後,系統為字符型 指針變量開辟的僅僅是 4 個字節,用來存放字符串無名存儲區的首地址。例如:÷ char a[ ] = "Hello"; (系統為數組開辟了 6 個字節的存儲空間用來存放字符串) char *p = "Hello"; (系統為指針變量 p 開辟了 4 個字節用來存放字符串常量的首地址) 因此 sizeof(a) 的運算結果是 6;而 sizef(p) 的運算結果是 4。

(4)字符串數組 難點

多個字符串放在一起就構成了字符串數組。可以使用一個二維數組(字符型的)來構造字符串數組,

也可以定義一個指針數組(字符型的)來構造一個類似的字符串數組。以下分别叙述: 方法一:使用二維數組來構造字符串數組。例如: char name[ ][10] = {"China", "America", "English", "France"}; 定義二維數組時,可以缺省第一維的長度,該例中,系統為二維數組 name 總共開辟了 40

個字節的存儲空間,用來存放四個字符串,雖然有一些單元被浪費,示意圖如下所示:

name name[0]

name[1]

name[2]

name[3]

C h i n a \0

A m e r i c a \0

E n g l i s h \0

F r a n c e \0

方法二:定義一個指針數組來構造字符串數組。例如: char *pname[4] = {"China", "America", "English", "France"};

pname pname[0]

pname[1]

pname[2]

pname[3]

C h i n a \0

A m e r i c a \0

E n g l i s h \0

F r a n c e \0

由以上示意圖可以看出,指針數組 pname 中有四個元素,都是字符型的指針變量,每個指針指 向的存儲空間不等長。因此用指針數組構造的字符串數組能夠有效利用存儲空間,根據不同的字符串 長度系統為之分配不同的存儲容量,因此不會造成存儲空間的浪費,這一點與二維數組構造的字符串 數組不一樣。

第六部分 "函數的進一步讨論"知識點

1、main 函數的參數(教材 11.1 節) main 函數的參數通常有兩個,函數首部可以寫成以下形式: 第一個參數:類型必須是 int 型,參數名通常是 argc,也可以由用戶自己來命名。該參數記錄用戶從命令行輸入的字符串的個數。 第二個參數:類型必須是字符型的指針數組,參數名通常是 argv,也可以由用戶自己來命名。該參數記錄用戶從命令行輸入的各個字符串,由于多個字符串構成字符串數組,此時的形參為一個指針數組,數

組中的每一個指針指向各個字符串的首地址。 說明:從命令行輸入的多個字符串中,第一個字符串必須是可執行文件的文件名。

參看教材"P158 例 11.1"對參數 argc 和 argv 的使用。

2、指向函數的指針(函數指針)(教材 11.2 節)

(1)指向函數的指針變量的定義、賦值

指向函數的指針也稱"函數指針",由于 C 語言中函數名代表該函數的入口地址,因此可以定義一種指向函數的指針來存放該入口地址,将這種指針稱為指向函數的指針。

void main(int argc, char **argv){ … }

難點

重點

double fun(int a, char *p){ … }

該 fun 函數定義為返回類型是 double 型,有兩參數,第一個是 int 型,第二個是 char *型。

{ … } void main(int argc, char *argv[ ])

或者

void main(void){ double (*pfun)(int, char *); //定義指向函數的指針變量

char x=2, double y; pfun = fun; //将 fun 函數的入口地址賦值給指針變量 pfun …

y = (*pfun)(10, &x); //等價于 y = fun(10, &x); }

以上示意圖中,在主函數内部首先定義了一個指向函數的指針變量 pfun,明确指出該指針所指向的函數返回值是 double 型,函數有兩個參數,第一個參數是 int 型,第二個參數是 char *型。然後為指針變

量 pfun 賦值,通過語句"pfun = fun;"将 fun 函數的入口地址賦值給指針變量 pfun,于是對函數的調用即可通過該指針來完成。最後利用 pfun 實現對 fun 函數的調用,通過語句"y = (*pfun)(10, &x);"來完成,該語句等價于傳統用法"y = fun(10, &x)"。

注意 1:定義指向函數的指針變量 pfun 時,"* pfun"的兩側必須加小括号,寫成 (* pfun)。 注意 2:為指向函數的指針變量賦值時,賦值号的左側隻寫指向函數的指針變量名,賦值号的右側隻

寫函數名。 注意 3:利用指向函數的指針變量調用函數時,等價于使用函數名調用函數。

(2)指向函數的指針變量作為實參 函數名作實參時,對應的形參應該是函數指針。 函數指針也可以作函數實參,對應的形參應當是類型相同的指針變量。參看教材"P159 例 11.2"。

3、函數的遞歸調用(教材 11.3 節) 重點

一個函數如果自己調用自己,則稱為直接遞歸調用;如果是兩個函數相互調用對方,則稱為間接遞歸

調用。 一個函數在它的函數體内調用它自身稱為遞歸調用。這種函數稱為遞歸函數。在

遞歸調用中,主調函數又是被調函數。執行遞歸函數将反複調用其自身。例如有函數

fun 如下圖所示:

int fun (int x) {

int y; z=fun(y);return z;

}

這個函數是一個遞歸函數。但是運行該函數将無休止地調用其自身,這當然是不正确

的。為了防止遞歸調用無終止地進行,必須在函數内有終止遞歸調用的手段。常用的

辦法是加條件判斷,滿足某種條件後就不再作遞歸調用,然後逐層返回。

第七部分 "結構體、共用體" 知識點 重點

1、結構體類型的說明

"結構體"是一種構造類型,是由數目固定,類型相同或不同的若幹有序變量組成的集合。組成結構體的每個數據都稱為結構體的"成員",或稱"分量"。 結構體類型說明的形式如下: struct 結構體标識名

例如:以下定義了一個日期型的結構體類型 { struct data { int year; int month; int day; };

類型名 1 結構體成員名列表 1; 類型名 2 結構體成員名列表 2; … 類型名 n 結構體成員名列表 n;

} ; 說明 1:結構體類型的說明可以嵌套。 說明 2:struct 是關鍵字。"結構體标識名"可以省略。 說明 3:右側花括号後面的分号 ; 不能省略。 說明 4:結構體類型的說明隻是列出了該結構的組成情況,标志這種類型的結構模式已存在,編譯程

序并沒有因此而分配任何存儲空間。就類似于列出"int",标志系統認可這種數據類型,但 "int"本身并不占用内存空間,隻有定義了 int 型的變量後,系統才為變量分配内存空間。

2、用 typedef 定義類型

typedef 是一個關鍵字,利用它可以将已存在的數據類型命一個新的名稱,可以理解為給已有的數據類型取一個别名。

例如:typedef int INT; INT x, y; //等價于 int x, y; 以上寫法表示使用 typedef 給已有的數據類型"int"取了一個新名字"INT",于是"INT"等價于"int",

可以使用這個新類型名定義變量 x 和 y。 注意:typedef 的使用并不是定義了一種新的類型,而僅僅是将已有的數據類型取了一個新名稱。 用戶自己定義的結構體類型一般都比較複雜,使用 typedef 可以為結構體類型取一個較為簡單的名稱。 以下三種方式是使用 typedef 為結構體類型取一個别名的方法。别名為"DATE"。

方法一:先定義結構體類型,再使用 typedef 為之取一個别名。 struct date { int year; int month; int day; }; typedef struct data

方法二:定義結構體類型 方法三:定義結構體類型的同時使用 typedef 的同時使用 typedef為之 為之取一個别名,并且不省略 取一個别名,并且省略了結構體标識名。 typedef struct date { int year; int month; int day; }DATE; DATE;

結構體标識名。 typedef struct { int year; int month; int day; }

圖 1 圖 2 圖 3

DATE;

3、定義結構體變量

以上提到結構體類型定義後,系統隻是認可有這樣一種用戶自己構造的複雜數據類型,但并沒有為之 分配存儲空間,隻有定義了該結構體類型的變量之後,系統才為變量分配相應的存儲空間,結構體變量占

用的存儲容量由結構體類型決定。以下幾種是定義結構體變量的方法: 方法四:先定義結構體類

方法一:先定義結構體類型,再定義該結構體類型的變量。 struct date { int year; int month; int day; }; struct data

方法三:先使用 typedef 型,然後使用 typedef方法二:在定義結 為之構體類型的同時, 定義結構體類型的别名, 取一個别名,最後使用别

名定義結構體變量。 struct date { int year; int month; int day; }; typedef stuct date DATE;DATE x, y;

圖 7

定義結構體變量。 再使用結構體類型的别struct date { int year; int month; int day; }

圖 5

名定義變量。 typedef struct date { int year; int month; int day; }DATE; DATE

圖 6

x, y;

x, y; x, y;

圖 4 同學仔細比較"圖 1"和"圖 4",如果結構體類型名"struct date"前面有關鍵字 typedef,則 struct date

後面的是結構體類型的别名,反之如果沒有關鍵字 typedef,則 struct date 後面的是結構體變量。 同學再仔細比較"圖 2"和"圖 5",同樣道理,如果"struct date"前面有關鍵字 typedef,則右側花

括号後面的是結構體類型的别名,反之如果沒有關鍵字 typedef,則右側花括号後面的是結構體變量。 以上圖 4~圖 7 三種方法都定義了兩個結構體類型的變量 x 和 y,這兩個變量各自占用 12 個字節的存

儲容量,該存儲容量的大小由結構體類型決定。

4、定義結構體類型的指針變量

結構體類型的指針變量定義方法與結構體類型普通變量的定義方法相同,均可使用圖 4~圖 7 所示的

三種方法,例如:

typedef struct student { char num[20]; char name[30]; char sex; int age; double score; }STU; STU x, *p = &x;

右圖所示定義了一個 STU 結構體類型的普通變量 x,以及指針變量 p。由于該結構體類型各成員一共占用 20 30 1 4 8=63 字節的存儲容量,因此系統為變量 x 分配 63 字節的存儲空間,指針 p 的基類型為STU 結構體類型,即指針 p 所指向的一則段存儲空間是 63 字節。

定義結構體指針變量 p的同時對它進行初始化,為之賦值為"&x",這一賦值過程很有必要,因為這使得指針變量 p 指向了一個有效的存儲空間,沒有指向有效存儲空間的指針不能随便使用。

5、通過結構體變量或結構體指針引用成員

例如上圖中定義的 STU 類型的結構體變量 x 或者結構體指針 p,它們有五個成員,如果要把某一個成員取出進行操作,不能直接使用,例如"age = 20;"這樣的語句是錯誤的,原因是 age 現在不是一個獨立的變量,它是變量 x 的一個成員,或者稱之為一個屬性,要取出 age 并将它賦值為 20,必須通過變量 x或者指針 p 才能将它取出。有以下三種方法,用到"."運算符或者"->"運算符。

(1)結構體變量名. 成員名 (2)結構體指針變量名->成員名

重點

(3)(*結構體指針變量名). 成員名 例如: strcpy(x.name, "LiWei"); 或者 strcpy(p->name, "LiWei"); 或者 strcpy((*p)->name, "LiWei"); x.age = 20; 或者 p->age = 20; 或者 (*p).age = 20;

6、給結構體變量賦值

方法一:初始化 定義結構體變量的同時為它的各個成員賦初值,稱為初始化,例如:

typedef struct student { char num[20]; char name[30]; char sex; int age; double score; }STU; STU

右圖所示在定義結構體變量 x 的同時為它的五個成員賦初值。所有初值必須要

用一對花括号括起來,各數值之間用逗号

隔開,數值的類型以及書寫順序與各成員

的類型和書寫順序保持一緻。

x={"20070102001", "ZhangHua", 'M', 18, 80.0};

方法二:結構體變量的整體賦值。如果兩個結構體變量類型相同,則可以對兩個結構體變量進行整體

賦值。例如:

typedef struct student { char num[20]; char name[30]; char sex; int age; double score; }STU; STU x, y={"20070102001", "ZhangHua", 'M', 18, 80.0};x = y; //結構體變量的整體賦值

右圖所示定義了兩個結構體變量 x 和y。其中變量 y 使用初始化的方法已經為它的五個成員賦了初值,而變量 x 定義的時候各成員還沒有初值。由于 x 和 y 是同類型的變量,因此可以通過賦值語句"x = y;"将變量 y 的值整體賦值給變量 x。這樣做相當于将變量 y 各個成員的初值對應地賦值給變量 x 的各個成員。

方法三:結構體變量的各成員分開賦值。兩個結構體變量對應成員之間可以相互賦值,例如: strcpy(x.num, y.num); strcpy(x.name, y.name); x.sex = y.sex; x.age = y.age; x.score = y.score; 注意:以上各成員分開賦值時,對于字符串類型,不能寫成"x.num = y.num;"、"x.name = y.name;",

雖然此時賦值号的兩側類型相同,都是數組名(是地址),但由于數組名本身是地址常量,不能将其賦值

為另一個存儲空間的首地址,因此對于字符數組類型的成員之間進行賦值,應選用 strcpy 庫函數。其它基本數據類型的成員之間可以直接使用賦值語句進行賦值。

方法四:從鍵盤為各成員輸入數值。例如: scanf("%s", x.num); //注意:成員"x.num"本身是數組名,代表地址,因此前面不加取地址符 scanf("%s", x.name); //成員"x.name"本身是數組名,代表地址,因此前面不加取地址符 scanf("%c", &x.sex); //成員"x.sex"、"x.age"、"x.score"是基本數據類型的變量,前面要加取地址符 scanf("%d", &x.age); scanf("%lf", &x.score);

7、結構體變量或成員做實參

"傳值"方式——與基本數據類型一樣,當結構體變量或者結構體變量的成員做實參時,實現的是"傳

值"方式,隻能單向傳遞數據。對應的形參必須與實參保持同類型。 "傳地址"方式——當結構體變量的地址或者結構體變量成員的地址做實參時,實現的是"傳地址"

方式。對應的形參必須是同類型的指針變量。 難點 8、利用結構體變量構成鍊表

當結構體類型定義時有一個自身結構體類型的指針變量作為成員,則可以利用該結構體類型的變量構

成鍊表。構成鍊表有靜态方式和動态方式兩種,動态方式是難點,也是考查的重點。 構成單向鍊表時,通常有一個頭結點,若幹個數據結點,以及一個末尾結點。一般來說,頭結點的數

據域為空,頭結點的指針域指向第一個數據結點,依次類推,每一個數據結點的指針域指向後一個數據結

點,最後一個數據結點稱為末尾結點,末尾結點的指針域為空(NULL)。 有關單向鍊表的基本算法(參考教材 P198~P201)有:鍊表的建立、順序訪問鍊表中各結點的數據

域、在單向鍊表中插入結點、删除單向鍊表中的結點。對鍊表的各種操作必須考慮各個指針變量的用途。

9、共用體

共用體類型的說明以及共用體變量的定義方式與結構體相似。共用體與結構體不同的是,結構體變量

的各個成員各自占用自己的存儲空間,而共用體變量的各個成員占用同一個存儲空間。 說明 1:共用體變量的存儲空間大小由占用字節數最多的那個成員決定。 說明 2:共用體變量初始化時隻能對它的第一個成員進行初始化。 說明 3:由于共用體變量所有成員占用同一個存儲空間,因此它們的首地址相同,并且與該變量的地

址相同。 共用體變量中每個成員的引用方式與結構體完全相同,可以使用如下三種方式: (1)共用體變量名.成員名 (2)共用體指針變量名->成員名 (3)(*共用體指針變量名).成員名

第八部分 "文件"知識點

1、基本概念

(1)記錄在外部介質上的數據的集合稱為"文件"。數據可以按文本形式或二進制形式存放在介質上,因此文件可以按數據的存放形式分為文本文件和二進制文件。二進制文件的輸入輸出速度較快一些。

(2)對文件的輸入輸出方式稱為存取方式,在 C 語言中,有兩種存取方式——順序存取、直接存取。 順序存取的特點是:每當打開這類文件進行讀或寫操作時,總是從文件的開頭開始進行讀或寫。 直接存取的特點是:可以通過調用庫函數指定讀或寫的起始位置,然後直接從此位置開始進行讀或寫。 (3)文件指針:是一個指向結構體類型名為 FILE 的指針。對文件的打開、關閉、讀、寫等操作都

必須借助于文件指針來完成。例如:FILE *fp; 即表示定義了一個 FILE 結構體類型的文件指針。 (4)文件位置指針:隻是一個形象化的概念,用來表示當前讀或寫的數據在文件中的位置。讀或寫

操作總是從文件位置指針所指的位置開始。

2、文件操作類庫函數

文件操作類庫函數都定義在 stdio.h 頭文件裡。 (1) fopen 和 fclose 函數——打開、關閉文件

函數調用形式:文件指針 = fopen(文件名, 文件使用方式); fclose(文件指針); 說明 1:fopen 函數的參數文件名和文件使用方式都是字符串。該函數調用成功後即返回一個

FILE 類型的指針。常用的文件使用方式及其含義如下表所示: 文件使用方式 含義

"r"、"w" 為隻讀、隻寫而打開文本文件。總是從文件開頭進行讀寫操作。 "r "、"w " 為讀和寫而打開文本文件。 "a" 為在文件後面添加内容而打開文本文件。文件中原有内容保持不變。

文本 文件

"a " 在文件末尾添加内容後,可以從頭開始讀。

"rb"、"wb" 以隻讀、隻寫而打開二進制文件。總是從文件開頭進行讀寫操作。 "rb "、"wb " 為讀和寫而打開二進制文件。 "ab" 為在文件後面添加内容而打開二進制文件。文件中原有内容保持不變。

二進制 文件

"ab " 同"a ", 在文件末尾添加内容後,可以從指定位置讀。 說明 2:當對文件的讀、寫操作完成之後,必須調用 fclose 函數關閉文件。 (2) fscanf 和 fprintf 函數——格式化輸入輸出。

函數調用形式:fscanf(文件指針, 格式控制字符串, 輸入項列表); fprintf(文件指針, 格式控制字符串, 輸出項列表); 功能:fscanf 函數是從文件讀入格式化數據,fprintf 函數是将格式化數據寫到文件中。 說明:這兩個函數與 scanf、printf 函數的功能相似,表一比較這四個函數的區别。 函數名 功能及數據流向 函數名 功能及數據流向 scanf 鍵盤 内存 printf 内存 顯示屏 fscanf 文件 内存

輸入 格式化數據 fprintf 内存 文件

輸出 格式化數據

表一

(3) fgetc 和 fputc 函數——也可寫成 getc、putc。功能是輸入、輸出一個字符。 函數調用形式:ch = fgetc(文件指針); //ch 是一個字符型變量 fputc(ch, 文件指針); 功能:fgetc(或 getc)函數是從文件讀入一個字符,fputc(或 putc)函數是将一個字符輸出

到文件。

說明:這兩個函數與 getchar、putchar 函數的功能相似,表二比較這四個函數的區别。 函數名 功能及數據流向 函數名 功能及數據流向 getchar 鍵盤 内存 putchar 内存 顯示屏

fgetc 文件 内存 輸入

一個字符 fputc 内存 文件 輸出

一個字符 表二

(4) fgets 和 fputs 函數——輸入、輸出一個字符串。 函數調用形式:fgets(str, n, 文件指針); //str 是字符串的起始地址,n 表示讀入字符串的長度 fputs(str, 文件指針); 功能:fgets 函數是從文件讀入字符串,fputs 函數是将字符串輸出到文件。 說明 1:fgets 函數最多隻能從文件中讀 n-1 個字符,讀入結束後,系統将自動添加'\0'。 說明 2:這兩個函數與 gets、puts 函數的功能相似,表三比較這四個函數的區别。 函數名 功能及數據流向 函數名 功能及數據流向

gets 鍵盤 内存 puts 内存 顯示屏 fgets 文件 内存

輸入 字符串 fputs 内存 文件

輸出 字符串

表三

(5) fread 和 fwrite 函數——讀、寫二進制文件。 函數調用形式:fread(buffer, size, count, 文件指針); fwrite(buffer, size, count, 文件指針); 參數說明:以上函數中的參數 buffer 是數據塊的指針,輸入或者準備輸出的數據存放在此内

存塊中;size 表示每個數據塊的字節數;count 用來指定每次讀、寫的數據塊個數。 說明:fread 和 fwrite 這兩個函數隻能針對二進制文件進行讀寫,不能操作文本文件。

(6) feof 函數——用來判斷二進制文件是否結束,如果是則返回 1,否則返回 0。 函數調用形式:foef(文件指針); 說明:文本文件是以 EOF(相當于-1)作為文件的結束标志。二進制文件沒有明顯的結束

标志,判斷二進制文件是否結束必須調用 feof 函數。 (7) fseek 函數——用來移動文件位置指針到指定的位置上,接着的讀或寫操作就從此位置開始。

函數調用形式:fseek(文件指針, offset, origin); 參數說明:以上函數中的參數 offset 是以字節為單位的位移量,為長整型;origin 是起始點,

用以指定位移量是以哪個位置為基準,起始點既可以用标識符(表四)來表示, 也可以用數字來表示。

位置指針起始點的标識符 代表的起始點 數字 SEEK_SET 文件開始 0 SEEK_END 文件末尾 2 SEEK_CUR 文件當前位置 1

表四

說明 1:對于文本文件來說,位移量 offset 必須是 0。例如:fseek(pf, 0L, SEEK_SET); 表示 将文件位置指針移到文件開頭;fseek(pf, 0L, SEEK_END); 表示将文件位置指針移 到文件末尾;

說明 2:對于二進制文件來說,如果位移量是正整數,表示位置指針從指定的起始點處向後移 動;如果位移量是負整數,表示位置指針從指定的起始點處向前移動。

(8) ftell 函數——用來獲得當前文件位置指針的位置,該函數返回值是一個長整型的數,表示當前位置指針相對于文件開頭的字節數。 函數調用形式:t = ftell(文件指針); //t 是一個長整型的變量

(9) rewind 函數——又稱"反繞"函數,功能是使文件的位置指針回到文件開頭處。 函數調用形式:rewind(文件指針);

常用庫函數

1、标準輸入輸出函數(頭文件 stdio.h) 函數名 函數原型 功能

scanf scanf(格式控制, 地址項列表) 從鍵盤輸入格式化數據 printf scanf(格式控制, 輸出項列表) 将格式化數據輸出到顯示屏 getchar char getchar(void) 讀取鍵盤輸入的一個字符 putchar putchar(char ch) 将一個字符輸出到顯示屏 gets gets(char *s) 讀取鍵盤輸入的一個字符串,可以包含空格 puts puts(char *s) 将一個字符串輸出到顯示屏

2、數學函數(頭文件 math.h) 函數名 函數原型 功能

sqrt double sqrt(double x) 計算并返回參數 x 的平方根值 pow double pow(double x, double y) 計算并返回參數 x 的 y 次方的值 fabs double fabs(double x) 計算并返回參數 x 的絕對值 log double log(double x) 計算并返回參數 x 的對數值,即求 ln(x)的值

3、字符串處理函數(頭文件 string.h) 函數名 函數原型 功能

strlen int strlen(char *str) 計算 str 所指字符串的長度,不包括'\0' strcpy strcpy(char *dest, char *sour) 将 sour 所指字符串複制到 dest 所指的存儲空間裡 strcat strcat(char *dest, char *sour) 将 sour 所指字符串粘貼到 dest 所指字符串的末尾

strcmp int strcmp(char *str1, char *str2) 比較 str1 和 str2 所指的兩個字符串,并返回比較的結果。如果前者>後者,返回 1;如果前者<後者,返回-1;如果前者==後者,返回 0。

4、動态存儲分配函數(頭文件 stdlib.h) 函數名 函數原型 功能

malloc void *malloc(unsigned n) 按照形參給定的大小動态分配内存空間,并返回指向該内存塊的指針。(形參 n 即代表 n 個字節)

calloc void *calloc(unsigned n, unsigned size) 按照形參給定的大小動态分配内存空間,并返回指向該内存塊的指針。(形參 n 即代表有 n 個數據塊,形參 size 代表每個數據塊的字節數)

free void free(void *p) 釋放之前調用 malloc 或 calloc 分配的内存空間。形參指針 p 指向即将被釋放的内存空間的首地址。

5、文件函數(頭文件 stdio.h) 函數名 函數原型 功能

fopen FILE *fopen(文件名, 文件使用方式) 按照使用方式打開文件,返回文件指針 fclose fclose(FILE *fp) 關閉由 fp 指向的已打開的文件 fscanf fscanf(FILE *fp, 格式控制, 地址列表) 從 fp 指向文件讀入格式化數據 fprintf fprintf(FILE *fp, 格式控制,輸出項列表) 将格式化數據寫到 fp 指向文件中 fgetc/getc char fgetc(FILE *fp) 從 fp 指向文件讀入一個字符 fputc/putc fputc(char ch, FILE *fp) 将一個字符寫到 fp 指向文件中 fgets fgets(char *s, int n, FILE *fp) 從 fp所指文件的指定位置讀入一個字符串(含 n-1

個字符),将此字符串存放到 s 所指的内存空間裡。fputs fputs(char *s, FILE *fp) 将 s 所指字符串寫到 fp 指向的文件中。

fread fread(void *p, int s, int n, FILE *fp) 從 fp 指向的二進制文件讀出 n 個數據塊,每個數據塊有 s 個字節大小,将讀出的數據塊存放到 p所指的内存空間裡。

fwrite fwrite(void *p, int s, int n, FILE *fp)從 p 所指的内存空間裡讀取信息寫到 fp 指向的二進制文件裡,讀取的信息由 n 個數據塊組成,每個數據塊有 s 個字節大小。

feof int feof(FILE *fp) 判斷 fp 指向的二進制文件是否結束,如果是返回1,否則返回 0。

fseek fseek(FILE *fp, long n, int origin) 移動 fp 指向的文件的位置指針,使之移動到距離origin 起始點 n 個字節的位置。

ftell long ftell(FILE *fp) 獲得并返回 fp 指向的文件當前位置指針相當于文件開頭的字節數。

rewind rewind(FILE *fp) 反繞函數,使文件位置指針回到文件開頭。

其 它

1、C 語言中的常用關鍵字

(1) 與數據類型有關的:char、int、float、double、short、long、signed、unsigned、void、struct、union、typedef、enum、sizeof

(2) 與存儲類别有關的:auto、static、register、extern (3) 與程序控制結構有關的:if、else、switch、case、default、while、do、for、break、continue、return、

goto

2、容易用錯的運算符

(1)= 是賦值号,功能是将其右側表達式的值賦值給左側的變量,注意它的左側隻能是變量名。 == 是關系運算符中的等于号,功能是比較其左右兩側表達式的值是否相等。

(2)* 當把它放在兩個表達式中間時作乘号使用(雙目運算符);當變量定義時把它放在變量名前時它

是一個标志,标志此時定義的變量時指針變量;當把它放在變量名前作為表達式中的一部分,則

它是取内容符(單目運算符)。

(3)&& 是邏輯與運算符 對比 & 是按位與運算符(雙目) 對比 & 是取地址符(單目)

|| 是邏輯或運算符 對比 | 是按位或運算符 ! 是邏輯非運算符 對比 ~ 是按位取反運算符

(4)^ 是按位異或運算符,注意它不是計算次方的運算符,計算次方需調用 pow 庫函數完成。

(5)sizeof 是求字節數運算符,注意它不是庫函數,而是運算符。注意它與 strlen 庫函數的區别。

(6)! 邏輯非運算符(單目) != 是關系運算符中的不等于号(雙目)

(7), 是逗号運算符,是逗号 C 語言中比較特殊的一個運算符,其優先級最低。 (8)? : 是條件運算符,是指 C 語言中唯一的三目運算符。

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved