99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

c語言宏和宏函數的區別 宏定義是c語言語句嗎

我想知道c語言里面怎么區分函數與宏

在C及C++語言中允許用一個標識符來表示一個字符串,稱為宏,該字符串可以是常數、表達式、格式串等。在編譯預處理時,對程序中所有出現的“宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。宏定義是由源程序中的宏定義命令完成的。宏代換是由預處理程序自動完成的。若字符串是表達式,我們稱之為函數式宏定義,那函數式宏定義與普通函數有什么區別呢?我們以下面兩行代碼為例,展開描述:

創新互聯服務項目包括金堂縣網站建設、金堂縣網站制作、金堂縣網頁制作以及金堂縣網絡營銷策劃等。多年來,我們專注于互聯網行業,利用自身積累的技術優勢、行業經驗、深度合作伙伴關系等,向廣大中小型企業、政府機構等提供互聯網行業的解決方案,金堂縣網站推廣取得了明顯的社會效益與經濟效益。目前,我們服務的客戶以成都為中心已經輻射到金堂縣省份的部分城市,未來相信會繼續擴大服務區域并繼續獲得客戶的支持與信任!

函數式宏定義:#define MAX(a,b) ((a)(b)?(a):(b))

普通函數 : MAX(a,b) { return ab?a:b;}

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

(2)調用真正函數的代碼和調用函數式宏定義的代碼編譯生成的指令不同。

如果MAX是個普通函數,那么它的函數體return a b ? a : b; 要編譯生成指令,代碼中出現的每次調用也要編譯生成傳參指令和call指令。而如果MAX是個函數式宏定義,這個宏定義本身倒不必編譯生成指令,但是代碼中出現的每次調用編譯生成的指令都相當于一個函數體,而不是簡單的幾條傳參指令和call指令。所以,使用函數式宏定義編譯生成的目標文件會比較大。

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

如果上面的函數式宏定義寫成 #define MAX(a, b) (ab?a:b),省去內層括號,則宏展開就成了k = (i0x0fj0x0f?i0x0f:j0x0f),運算的優先級就錯了。同樣道理,這個宏定義的外層括號也是不能省的。若函數中是宏替換為 ++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[]={9,3,5,2,1,0,8,7,6,4};

int max(n)

{

return n==0?a[0]:MAX(a[n],max(n-1));

}

int main()

{

max(9);

return 0;

}

若是普通函數,則通過遞歸,可取的最大值,時間復雜度為O(n)。但若是函數式宏定義,則宏展開為( a[n]max(n-1)?a[n]:max(n-1) ),其中max(n-1)被調用了兩遍,這樣依此遞歸下去,時間復雜度會很高。

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

宏和函數的區別以及C語言的編譯鏈接過程

宏在編譯之前,需要進行預處理,將宏直接提換成宏定義的代碼,是直接替換,也就是說,在預處理之后,你再看代碼,發現宏定義已經被替換過來了,你看到是你定義之后的那一串代碼。

而函數,在編譯之后,有一系列調用函數的過程,比如,傳參,壓棧等,這部分是編譯器所做的。

C 語言編譯鏈接過程:

test.c(原始代碼) -- 預處理 -- test.i(經過預處理的)-- 編譯 -- test.s(匯編代碼)-- 匯編 -- test.o(目標文件,其實這部分已經是單個文件的完整二進制文件了,只是還不能執行,如果不懂這句話,可以再問我,其實這部分知識,平時也很少遇到) -- 鏈接 -- test (可執行文件,比如一個程序由3個代碼文件共同生成,那么就會有3個.o格式目標文件,鏈接是把多個目標文件真正的聯系在一起,比如a.o 中使用了 b.o中的一個函數,那么它們兩個之間的地址是如何確定的(同理,可引申到使用函數庫的問題,使用printf函數,也是需要鏈接器進行確定printf函數地址,才能知道如何調用。)這個就是鏈接器的作用)

請問C語言中帶參數的宏和函數的比較

宏是用于編譯器處理的,他在程序編譯時,會在對應位置展開成代碼。。,這就相當于你在告訴編譯器,我想在這個位置加一些代碼,代碼的內容已在宏中定義,請編譯器自己支找。。。,也就是說程序在運行時,早已變成了對應位置上的代碼,此時已沒有宏的概念了。。。。

而函數則是運行時,調用。他不會在編譯時,在對應位置上加上函數代碼,只是加上一個函數入口指針。。。從這個入口去運行一段代碼。。。運行完了之后回到當前位置繼續執行。。。。

可以簡單的認為,宏是在編譯時上起作用,而函數是運行時起作用。。。

C語言中帶參數的宏定義與函數的區別(試舉例)

宏只是字符的替換,在預處理階段就給替換到代碼中去了比如下面的代碼

#include

#define

MAX(x,

y)

((x)(y)?(x):y())

int

main()

{

int

a

=

2,

b

=

4;

int

m;

m

=

MAX(2,

4);

printf("%d\n",

m);

return

0;

}

如果你用的是gcc編譯器,執行

gcc

-E

main.c

-o

main.i,打開main.i文件就可以看到他是如何替換進去的,直接拖到最后,前面的都是stdio.h中的內容。

int

main()

{

int

a

=

2,

b

=

4;

int

m;

m

=

((2)(4)?(2):4());

printf("%d\n",

m);

return

0;

}

函數就不同了,函數還需要分配??臻g,在執行函數時都要進行入棧和出棧操作,有的還需要分配堆空間。

宏所實現的功能有限,而且長代碼不易讀,但是對于邏輯簡單、代碼不長、經常使用的功能由宏來實現是個不錯的選擇

網站題目:c語言宏和宏函數的區別 宏定義是c語言語句嗎
文章路徑:http://www.yijiale78.com/article40/docjgeo.html

成都網站建設公司_創新互聯,為您提供網站設計公司網站改版、移動網站建設外貿網站建設、品牌網站建設、品牌網站設計

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都定制網站建設