1. 程式人生 > >巨集的本質以及巨集(包括函式式巨集) 沒有返回值概念

巨集的本質以及巨集(包括函式式巨集) 沒有返回值概念

巨集(包括函式式巨集)  沒有返回值的概念,函式才有返回值的概念

函式才有返回值的概念,因為呼叫函式時有一個切換並保護現場的過程,所以切換回來(到呼叫者)時就需要通過返回值將函式的結果傳送回來。

巨集(包括函式式巨集)  沒有返回值的概念,因為它只是在原始碼檔案(級別)上的文字替換(即修改些原始碼),沒有一個切換並保護現場的過程,所以不需要也不存在一個通過返回值將其的結果傳送回來的過程。還有,巨集所代表的表示式的計算結果是叫一個結果值,不叫(函式)返回值。

1、#define xxx() {} ,是標準C支援的
也是GCC新增的功能(微軟vS不支援),主要為了防止巨集展開出現問題,預設展開時是要加上一個;的(即{;}

),(否則)容易出問題。

2、表示式是操作符、變數、常量的任意組合。在C語言中,花括號{}和分號;(分號表示式語句(結束的)分隔符,不算運算子。)不是操作符,而圓括號()和逗號,(屬於順序點運算子)是操作符(即運算子)。而上述d={a=1;b+=1;c=3;a+b+c;}這個整體表達式(即一個賦值表示式)中{a=1;b+=1;c=3;a+b+c;}可以作為其子表示式,有點費解。上述語句裡,花括號{}和分號;相當於圓括號()和逗號,的作用。

3、整體表達式

<子表示式><子表示式>;<子表示式><子表示式>;<子表示式><

子表示式>;

表示式分隔符,比表示式分隔符;優先順序高

4、標頭檔案的內容除了函式原型和巨集定義外,還可以有結構體定義,全域性變數定義

-----------------------------------------------------我是分割線-----------------------------------------

1.函式體直接使用巨集定義不管有沒有返回值都不能作賦值執行的左右值 . 如下圖示:


錯誤提示:

 

2.通過使用小括號()把函式體括起來使用巨集定義可以得到該函式體最後一條語句運算結果,這裡還需要注意 ,不能漏了' ; ',

如下圖示:


列印結果如下:

 

3.一般情況下使用多語句巨集定義時 ,最好使用do{...}while(0)或者({})的形式

        因為在if() 結構裡做分支執行部分時,使用do{...}while(0)可以使呼叫時後面能正確的使用' ; ' ,一旦沒寫就會像普通語句那樣報錯 , 這樣符合我們的習慣 ,  如果只是使用{}的結構體形式 , 那麼在呼叫時後面不能使用' ; ' , 如果按照我們的習慣寫上 ' ; '  ,那麼就有可能引起錯誤 . 比如 : if()後面還有else語句的話, 就會出錯 , 因為 ' ; '被當作另外一條語句(空指令)的結束符插在else的上面 .

注意使用do{...}while(0)結構之後就不能把這個把這個巨集定義作為賦值操作的左右值了.

圖示如下:

 

列印結果對應如下:

 

4.需要得到函式式巨集定義的返回值的方法

         從上面我們已經可以知道當我們使用({})形式的巨集定義時 , 只要函式體最後一次運算出的結果是我們想要的那使用這個形式是可以正確取得返回值的 並且放在賦值操作的右端;  當我們使用do{...}while(0)形式的巨集定義時 , 我們是無法通過賦值操作來得到返回值的 , 但是我們可以通過多加一個引數 , do{}while(0)裡面把要放回的值賦給多加的這個引數 , 這樣我們就可以得到想要的返回值了.

演示圖示如下:

 

列印結果如下: