C語言學習總結

2021-07-27 15:54:12 字數 3673 閱讀 7370

無參巨集定義:(即巨集名後不帶引數。)

其定義的一般形式為:

#define 識別符號 字串
其中各個名稱的含義如下:

1>其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均為預處理命令。

2>「define」為巨集定義命令。

3>「識別符號」為所定義的巨集名。

4>「字串」可以是常數、表示式、格式串等。

例如:

#define m (a+b)
它的作用是指定識別符號m來代替表示式(a+b)。在編寫源程式時,所有的(a+b)都可由m代替,而對源程式作編譯時,將先由預處理程式進行巨集代換,即用(a+b)表示式去置換所有的巨集名m,然後再進行編譯。

程式1:

#define m (a+b)

main()

上例程式中首先進行巨集定義,定義m來替代表示式(a+b),在 s= m * m 中作了巨集呼叫。在預處理時經巨集展開後該語句變為:

s=(a+b)*(a+b)
但要注意的是,在巨集定義中表示式(a+b)兩邊的括號不能少。否則會發生錯誤。

如當作以下定義後:

#difine m (a)+(b)
在巨集展開時將得到下述語句:

s= (a)+(b)*(a)+(b)
1>巨集定義是用巨集名來表示乙個字串,在巨集展開時又以該字串取代巨集名,這只是一種簡單的代換,字串中可以含任何字元,可以是常數,也可以是表示式,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。

2>巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。

3>巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。

4>如要終止其作用域可使用:

#undef命令
帶參巨集定義:(即允許巨集帶有引數)

a.在巨集定義中的引數稱為形式引數,在巨集呼叫中的引數稱為實際引數。

b.對帶引數的巨集,在呼叫中,不僅要巨集展開,而且要用實參去代換形參。

帶參巨集定義的一般形式為:

#define 巨集名(形參表) 字串(在字串中含有各個形參)
例如:

#define m(y) ((y)*(y)+

3*(y)) /*巨集定義*/

....

k=m(5); /*巨集呼叫*/

....

在巨集呼叫時,用實參5去代替形參y,經預處理巨集展開後的語句為:

k=5

*5+3

*5

程式2:

#define max(a,b) (a>b)?a:b    

main()

上例程式的第一行進行帶參巨集定義,用巨集名max表示條件表示式:

(a>b)?a

:b

形參a,b均出現在條件表示式中。

程式第七行

max

=max(x,y)

為巨集呼叫,實參x,y,將代換形參a,b。

巨集展開後該語句為:

max=(x>y)?x

:y;

用於計算x,y中的大數。

注:

a.防止重複定義#define條件編譯

b.標頭檔案(.h)可以被標頭檔案或c檔案包含;

c.重複包含(重複定義)

d.由於標頭檔案包含可以巢狀,那麼c檔案就有可能包含多次同乙個標頭檔案,就可能出現重複定義的問題的。 通過條件編譯開關來避免重複包含(重複定義)

例如:

#ifndef __headerfile***__  

#define __headerfile***__

„ 檔案內容

#endif

在簡單巨集定義的使用中,當替換文字所表示的字串為乙個表示式時,容易引起誤解和誤用。

例如:

#define n 2+2

void main()

(1) 出現問題:

在此程式中存在著巨集定義命令,巨集n代表的字串是2+2,在程式中有對巨集n的使用,一般同學在讀該程式時,容易產生的問題是先求解n為2+2=4,然後在程式中計算a時使用乘法,即n*n=4*4=16,其實該題的結果為8,為什麼結果有這麼大的偏差?

(2) 問題解析:

如1節所述,巨集展開是在預處理階段完成的,這個階段把替換文字只是看作乙個字串,並不會有任何的計算發生,在展開時是在巨集n出現的地方 只是簡單地使用串2+2來代替n,並不會增添任何的符號,所以對該程式展開後的結果是a=2+2*2+2,計算後=8,這就是巨集替換的實質,如何寫程式才能完成結果為16的運算呢?

(3)解決辦法:

/*將巨集定義寫成如下形式*/

#define n (2+2)

/*這樣就可替換成(2+2)*(2+2)=16*/

在帶引數的巨集定義的使用中,極易引起誤解。例如我們需要做個巨集替換能求任何數的平方,這就需要使用引數,以便在程式中用實際引數來替換巨集定義中的引數。

一般學生容易寫成如下形式:

#define area(x) x*x

/*這在使用中是很容易出現問題的,看如下的程式*/

void main()

(1) 問題解析:

按理說給的引數是2+2,所得的結果應該為4*4=16,但是錯了,因為該程式的實際結果為8,仍然是沒能遵循純粹的簡單替換的規則,又是先計算再替換 了,在這道程式裡,2+2即為area巨集中的引數,應該由它來替換巨集定義中的x,即替換成2+2*2+2=8了。

那如果遵循(1)中的解決辦法,把2+2 括起來,即把巨集體中的x括起來,是否可以呢?#define area(x) (x)(x),對於area(2+2),替換為(2+2)(2+2)=16,可以解決,但是對於area(2+2)/area(2+2)又會怎麼樣呢,有的學生一看到這道題馬上給出結果,因為分子分母一樣,又錯了,還是忘了遵循先替換再計算的規則了,這道題替換後會變為 (2+2)(2+2)/(2+2)(2+2)即4*4/4*4按照乘除運算規則,結果為16/4*4=4*4=16,那應該怎麼呢?

(2)解決方法:

在整個巨集體上再加乙個括號,即#define area(x) ((x)*(x)),不要覺得這沒必要,沒有它,是不行的。

要想能夠真正使用好巨集定義,一定要先將程式中對巨集的使用全部替換成它所代表的字串,完全展開後再進行相應的計算,就不會寫錯執行結果。如果是自己程式設計使用巨集替換,則在使用簡單巨集定義時,當字串中不只乙個符號時,加上括號表現出優先順序,如果是帶引數的巨集定義,則要給巨集體中的每個引數加上括號,並在整個巨集體上再加乙個括號。看到這裡,不禁要問,用巨集定義這麼麻煩,這麼容易出錯,可不可以摒棄它, 那讓我們來看一下在c語言中用巨集定義的好處吧。

例如:

#include 

#define product(x) x*x

int main()

依次輸出結果:

j=9;i=5;k=49;i=7

C語言學習總結

1 c語言中有乙個賦值表示式,是其他多數高階語言中沒有的。2 c 語言的輸入與輸出操作是由函式來完成的,它不提供輸入輸出語句。3 c語言中有乙個共用體,其變數所點記憶體長度是其最長 成員變數的長度。4 static char a language char p a 8 5 void main int...

C語言學習總結

看了李明杰老師的c 語言課程,感覺老師講得很細 很透。收穫了很多新的知識,對cc 語言課程的學習總結。1.執行c 語言程式的步驟 1 編寫 c原始檔 2 編譯 c原始檔為 o目標檔案 3 鏈結 o目標檔案為可執行檔案 4 執行可執行檔案 2.常用格式符 1 d i 整數 int 2 f 小數 flo...

C語言學習總結

while語句 當條件為真時,進行迴圈。for迴圈,第二個條件為真時,執行迴圈體 對於單鏈表應該設定的變數l的型別為結構指標型別,初始化時就是把l變成頭指標,並且還為其分配了記憶體空間 巨集定義 define long string it represent a long string that i...