c語言巨集定義與函式的差別我覺得巨集定義和函式

2021-06-21 04:08:33 字數 5216 閱讀 5342

1樓:來自海印寺芳香襲人 的啄木鳥

首先巨集定義和函式是有差別的

巨集定義是在編譯之前處理的,不做語法檢查。 這個很危險另外我要說

#define a(b,c)

表示bc之合,在結果上和函式確實一樣

2樓:匿名使用者

但是當函式複雜的情況下,你就沒法代替了哦!

3樓:匿名使用者

#define a(x,y) x>y?x*y:x+y和int a(x,y)

a(x+y,x*y)這個表示式對於以上兩種定義的得到的結果是不一樣的而且,巨集有巨集的有點,函式有函式的優點

函式的優點就是佔用儲存空間少,缺點是每次呼叫函式都要呼叫中斷程式,影響執行效率

巨集的優點就是直接巨集,每次呼叫都要,所以比較佔儲存空間,但是相應的就不用呼叫中斷程式了,執行效率自然就高了

c語言巨集定義問題 巨集定義不是可以實現和函式相同功能 那為什麼還要分函式和巨集定義兩種功能?

4樓:物理公司的

我們以下面兩行**為例,描述:

函式式巨集定義:#define max(a,b) ((a)>(b)?(a):(b))

普通函式 :max(a,b)

(1)函式式巨集定義的引數沒有型別,前處理器只負責做形式上的替換,而不做引數型別檢查,所以傳參時要格外小心。

(2)呼叫真正函式的**和呼叫函式式巨集定義的**編譯生成的指令不同。

如果max是個普通函式,那麼它的函式體return a > b ? a : b; 要編譯生成指令,**中出現的每次呼叫也要編譯生成傳參指令和call指令。

而如果max是個函式式巨集定義,這個巨集定義本身倒不必編譯生成指令,但是**中出現的每次呼叫編譯生成的指令都相當於一個函式體,而不是簡單的幾條傳參指令和call指令。所以,使用函式式巨集定義編譯生成的目標檔案會比較大。

(3)函式式巨集定義要注意格式,尤其是括號。

如果上面的函式式巨集定義寫成 #define max(a, b) (a>b?a:b),省去內層括號,則巨集就成了k = (i&0x0f>j&0x0f?

i&0x0f:j&0x0f),運算的優先順序就錯了。同樣道理,這個巨集定義的外層括號也是不能省的。

若函式中是巨集替換為 ++max(a,b),則巨集就成了 ++(a)>(b)?(a):(b),運算優先順序也是錯了。

(4)若函式引數為表示式,則普通函式的呼叫與函式式巨集定義的替換過程是不一樣的。

普通函式呼叫時先求實參表示式的值再傳給形參,如果實參表示式有side effect,那麼這些sideeffect只發生一次。例如max(++a, ++b),如果max是普通函式,a和b只增加一次。但如果max函式式巨集定義,則要成k = ((++a)>(++b)?

(++a):(++b)),a和b就不一定是增加一次還是兩次了。所以若引數是表示式,替換函式式巨集定義時一定要仔細看好。

5)函式式巨集定義往往會導致較低的**執行效率。

看下面一段**:

複製****如下:

int a=;

int max(n)

int main()

若是普通函式,則通過遞迴,可取的最大值,時間複雜度為o(n)。但若是函式式巨集定義,則巨集為( a[n]>max(n-1)?a[n]:

max(n-1) ),其中max(n-1)被呼叫了兩遍,這樣依此遞迴下去,時間複雜度會很高。

儘管函式式巨集定義和普通函式相比有很多缺點,但只要小心使用還是會顯著提高**的執行效率,畢竟省去了分配和釋放棧幀、傳參、傳返回值等一系列工作,因此那些簡短並且被頻繁呼叫的函式經常用函式式巨集定義來代替實現。

5樓:龔煒林

現在的教科書啊, c語言的標準定義,是不包括巨集的。

巨集是編譯器的一部分,我們通常寫**,為了**高可用等,一般離不開使用巨集。

巨集定義是編譯器的前處理器處理的,真正編譯的時候,才是解析具體的語言語法,

具體巨集定義的使用,還得看編譯器的支援了。

巨集只有一個特徵:就是字串替換。前處理器處理巨集的時候,就是把**中的巨集,替換為巨集代表的字串,至於加的一些#if #else的邏輯,也是可以理解為替換。

巨集定義不能實現和函式的相同功能,函式可以劃分域,會佔用棧,可以做介面,高複用**。

而巨集就不一樣了,純粹替換字串, 不能劃分域,那你只用巨集,就會整個檔案都在同一個作用域,定義一個變數,其它巨集還不能隨便重名... ...

再比如,我寫一個函式,編譯之後,只佔4k空間,然後,這個函式被10000處呼叫,但是仍然只需要4k空間來儲存函式**,如果你換成巨集,每一處呼叫都會佔用4k空間的(因為是字串替換),所以,會引起實際佔用4k * 10000 = ? ,拿作業系統不用執行了

就按照上邊的區別去想,自然解答了你這個問題。

c語言巨集定義函式如何呼叫(裡面含引數可以當函式用嗎)

6樓:魔方格的故事

使用巨集函式或者巨集函式時,注意如下幾點:

1.巨集函式的引數沒有型別,前處理器只負責做形式上的替換,而不做引數型別檢查,所以傳參時要格外小心。

2.巨集函式定義要注意格式,尤其是括號。

如果上面的巨集函式寫成 #define max(a, b) (a>b?a:b),省去內層括號,則巨集就成了k = (i&0x0f>j&0x0f?

i&0x0f:j&0x0f),運算的優先順序就錯了。同樣道理,這個巨集定義的外層括號也是不能省的。

若函式中是巨集替換為 ++max(a,b),則巨集就成了 ++(a)>(b)?(a):(b),運算優先順序也是錯了。

3.巨集函式往往會導致較低的**執行效率。

若是普通函式,則通過遞迴,可取的最大值,時間複雜度為o(n)。但若是巨集函式,則巨集為( a[n]>max(n-1)?a[n]:

max(n-1) ),其中max(n-1)被呼叫了兩遍,這樣依此遞迴下去,時間複雜度會很高。

7樓:匿名使用者

巨集定義,不能當函式使(函式中的return是返回到呼叫點,而巨集中的return卻是從呼叫點跑開了)

你的**,在編譯時會進行巨集替換,真正的**變成了如下:

#include

//#define a(b,c)

int main()

//本身這句也有問題,return後跟的printf()永遠不會執行!

return 0;}

8樓:橙心橙願

可以啊,

不過#define a(b,c)其中的return d;最好去掉,因為巨集是直接貼到用呼叫處的,相當於

int main()

還沒printf就return了,列印不出來了

9樓:匿名使用者

不可以吧,函式執行的時候,遇到return就返回了,這個定義是不成功的。而且這樣定義完全沒有必要,可以定義子函式來實現。

c語言巨集定義如何用?用巨集定義有什麼優點?

10樓:我愛流雨飛軒

巨集定義巨集定義是c提供的三種預處理功能的其中一種,這三種預處理包括:巨集定義、檔案包含、條件編譯

編輯本段1.不帶引數的巨集定義:

巨集定義又稱為巨集代換、巨集替換,簡稱「巨集」。

格式:#define 識別符號 字串

其中的識別符號就是所謂的符號常量,也稱為「巨集名」。

預處理(預編譯)工作也叫做巨集:將巨集名替換為字串。

掌握"巨集"概念的關鍵是「換」。一切以換為前提、做任何事情之前先要換,準確理解之前就要「換」。

即在對相關命令或語句的含義和功能作具體分析之前就要換:

例: #define pi 3.1415926

把程式中出現的pi全部換成3.1415926

說明:(1)巨集名一般用大寫

(2)使用巨集可提高程式的通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。例如:陣列大小常用巨集定義

(3)預處理是在編譯之前的處理,而編譯工作的任務之一就是語法檢查,預處理不做語法檢查。

(4)巨集定義末尾不加分號;

(5)巨集定義寫在函式的花括號外邊,作用域為其後的程式,通常在檔案的最開頭。

(6)可以用#undef命令終止巨集定義的作用域

(7)巨集定義可以巢狀

(8)字串" "中永遠不包含巨集

(9)巨集定義不分配記憶體,變數定義分配記憶體。

編輯本段2.帶引數的巨集定義:

除了一般的字串替換,還要做引數代換

格式:#define 巨集名(參數列) 字串

例如:#define s(a,b) a*b

area=s(3,2);第一步被換為area=a*b; ,第二步被換為area=3*2;

類似於函式呼叫,有一個啞實結合的過程:

(1)實參如果是表示式容易出問題

#define s(r) r*r

area=s(a+b);第一步換為area=r*r;,第二步被換為area=a+b*a+b;

正確的巨集定義是#define s(r) ((r)*(r))

(2)巨集名和引數的括號間不能有空格

(3)巨集替換隻作替換,不做計算,不做表示式求解

(4)函式呼叫在編譯後程式執行時進行,並且分配記憶體。巨集替換在編譯前進行,不分配記憶體

(5)巨集的啞實結合不存在型別,也沒有型別轉換。

(6)函式只有一個返回值,利用巨集則可以設法得到多個值

(7)巨集使源程式變長,函式呼叫不會

(8)巨集不佔執行時間,只佔編譯時間,函式呼叫佔執行時間(分配記憶體、保留現場、值傳遞、返回值

c語言巨集定義技巧(常用巨集定義)

寫好c語言,漂亮的巨集定義很重要,使用巨集定義可以防止出錯,提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟體中常用得巨集定義。。。。。。

11樓:匿名使用者

主要用於函式重定義,通用性,可以用一個變數符號替代另一個變數符號格式:#define m(x,y) x+y在主程式裡寫入z=m(6,9);等價於z=6+9;而寫成z=(6-8,9);等價於z=6-8+9 ;直接代入

還有就是 :#define uint unsigned int 即用 uint 代替unsigned int 便於書寫,還有就是不同作業系統的通用變數識別

12樓:匿名使用者

用#define 來定義,如#define max 100

優點:在以後的程式中 要修改max的大小 不用跑到程式中找 直接修改

#define max 的大小即可。很方便。

13樓:匿名使用者

自己去**找呀!!!!

c語言的巨集定義問題

c語言函式的定義問題,C語言函式的定義問題

void就是沒有返回值,不需要return 是否需要返回值是由你的需求決定的。陳恩點在此為你解答如有錯誤請見諒 不是沒有返回值 是void 不能有返回值 include int f int i int main 第一個void表示沒有該函式沒有需要帶回的資料 當你的函式當中需要呼叫了某個函式,但是你...

C語言的巨集定義是什麼,在C語言中巨集定義是什麼?

巨集定義又稱為巨集代換 巨集替換,簡稱 巨集 是c提供的三種預處理功能的其中一種。1 巨集名一般用大寫。2 使用巨集可提高程式的通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。例如 陣列大小常用巨集定義。3 預處理是在編譯之前的處理,而編譯工作的任務之一就是語法檢查,預處理不做語法檢查。4 巨...

c語言中什麼是原型定義,C語言中函式的定義格式是什麼,函式原型宣告的語法格式?

我還直是不知道呢,我說說自己的理解吧,一個函式,可能在別外被引用或是在本檔案中但是要先引用了而後面才有函式定義,此時編譯器需要先行知道這個函式返回型別和引數類形,才可以正確的幫著做嚴格的資料型別和引數個數的檢查 如不提前申明就會當做是返回int 型,引數都當int型且不能檢查引數個數 這個函式在定義...