C語(yǔ)言中#define定義的標(biāo)識(shí)符和宏實(shí)例代碼
??1.#define定義標(biāo)識(shí)符
在C語(yǔ)言程序中,有時(shí)候會(huì)包含#define
#define可以定義標(biāo)識(shí)符
也就是說(shuō)可以對(duì)字符重新定義,實(shí)現(xiàn)代替的作用
??語(yǔ)法
#define name stuff
就比如說(shuō):
#define MAX 1000(用MAX代替1000)
#define reg register (用reg代替register)
??舉個(gè)栗子
#include<stdio.h> #define MAX 100 int main() { printf("%d", MAX); return 0; }
當(dāng)代碼運(yùn)行的時(shí)候
在代碼編譯的預(yù)處理階段 就會(huì)把宏替換為文本程序代碼
代替的結(jié)果如下:
#include<stdio.h> int main() { printf("%d", 100); return 0; }
??注意:#define定義標(biāo)識(shí)符后面盡量不加上分號(hào),因?yàn)槿绻由系脑?,在替換的過程中,分號(hào)也會(huì)別替換到文本程序中,有時(shí)候會(huì)導(dǎo)致出現(xiàn)邏輯錯(cuò)誤。
??2.#define定義宏
#define規(guī)定允許將參數(shù)替換到文本中,這樣包含參數(shù)叫做#define定義宏
宏在程序中,執(zhí)行的速度更快,因?yàn)橄鄬?duì)于函數(shù),宏沒有函數(shù)的調(diào)用和返回的開銷
語(yǔ)法:
#define SQUARE(x) x*x
這與#define定義宏一樣,都是完成替換的,不過#define定義宏后面有一個(gè)括號(hào),包含參數(shù)
??下面用#define定義宏來(lái)實(shí)現(xiàn)兩個(gè)數(shù)求最大值
#include<stdio.h> #define MAX(x,y) ((x)>(y)?(x):(y)) int main() { int a = 20; int b = 10; int c = MAX(a,b); printf("%d", c); return 0; }
替換后的結(jié)果為:
#include<stdio.h> int main() { int a = 20; int b = 10; int c = a>b?a:b; printf("%d", c); return 0; }
在#define定義宏的時(shí)候,后面的參數(shù)盡量帶上括號(hào),使每一個(gè)參數(shù)相對(duì)獨(dú)立
這樣可以避免由于操作符的優(yōu)先級(jí)不同,導(dǎo)致最終的邏輯就錯(cuò)了
舉個(gè)栗子:
#include<stdio.h> #define sum(x) x*x int main() { int ret = sum(3 + 3); printf("%d", ret); }
如果不仔細(xì)觀察的話,可能你認(rèn)為的結(jié)果就是36
這個(gè)代碼的計(jì)算過程為:3+3*3+3,并不是(3+3)*(3+3)
??#define替換的規(guī)則
#define定義標(biāo)識(shí)符和宏時(shí),程序會(huì)繼續(xù)如下步驟
1.在定義宏時(shí),先對(duì)參數(shù)進(jìn)行檢查,如果參數(shù)里包含有#define定義的標(biāo)識(shí)符時(shí),首先完成相應(yīng)的替換
2.替換文本會(huì)隨后插入到原來(lái)文本文件中,對(duì)于宏來(lái)說(shuō),參數(shù)名被他們的值所替換
3.最后進(jìn)行檢查,果然還有#define定義的符號(hào),將重復(fù)上述的操作
注意:
1.#define參數(shù)中可以包含其他由#define定義的標(biāo)識(shí)符,但是#define不能遞歸
2.如果#define的參數(shù)名存在在字符串中,將不會(huì)完成替換
??#與## #的用法:
在不確定參數(shù)的情況下,可以使用 “#n” ,可以實(shí)現(xiàn)不同字符串的插入
效果如下:
#include<stdio.h> #define PRINT(n) printf("the value of "#n" is %d\n",n); int main() { int a = 10; PRINT(a); int b = 20; PRINT(b); int c= 30; PRINT(c); return 0; }
??替換后的效果為:
#include<stdio.h> int main() { int a = 10; printf("the value of" "a" " is %d\n",a); PRINT(a); int b = 20; PRINT(b); printf("the value of " "b" " is %d\n",b); int c= 30; PRINT(c); printf("the value of " "c" " is %d\n",c); return 0; }
##的用法:
#include<stdio.h> #define CAT(Max,num) Max##nu int main() { int Maxnum = 100; printf("%d", Maxnum); return 0; }
雙##的用法可以拼接兩個(gè)字符串
當(dāng)然這個(gè)前提是拼接后的字符串必須產(chǎn)生一個(gè)合法的標(biāo)識(shí)符,否則結(jié)果就是未定義的
??宏的缺點(diǎn)
1.如果使用宏過多,宏定義的代碼插入到程序中,會(huì)大幅度增加程序的長(zhǎng)度
2.宏是沒法調(diào)試的
3.宏與類型無(wú)關(guān),導(dǎo)致程序不夠嚴(yán)謹(jǐn)
4.宏會(huì)帶來(lái)優(yōu)先級(jí)的問題,容易導(dǎo)致程序的錯(cuò)誤
??宏和函數(shù)的優(yōu)缺點(diǎn)
1).在代碼長(zhǎng)度角度上,因?yàn)楹晔侵苯犹鎿Q所以若宏較長(zhǎng)會(huì)增加代碼長(zhǎng)度
2).在執(zhí)行速度上,宏較函數(shù)快,因?yàn)楹瘮?shù)存在調(diào)用/返回時(shí)的額外開銷
3).在參數(shù)求值方面,define定義的宏可能會(huì)具有副作用會(huì)導(dǎo)致修改變量最后的值,而函數(shù)即使調(diào)用多次也不會(huì)修改變量原來(lái)的值
4).在參數(shù)類型方面,宏與類型無(wú)關(guān),所以宏是可以傳參數(shù)的而函數(shù)不行在C中函數(shù)是不可以傳類型的
5).在是否可調(diào)試方面,宏不可調(diào)試,函數(shù)可調(diào)試宏可以傳類型的檢測(cè),實(shí)現(xiàn)malloc(動(dòng)態(tài)開辟內(nèi)存的函數(shù))
#include<stdio.h> #include<stdlib.h> #define MALLOC(COUNT,TYPE)\ (TYPE *)alloc(COUNT*sizeof(TYPE)) void *alloc(int sz) //宏可以傳類型,函數(shù)不可以傳類型 { void *p=malloc(sz); if(p == NULL) { printf("out of memory\n"); exit(EXIT_FAILURE); } return p; } int main() { int i=0; int *p=MALLOC(10,int); for(i=0;i<10;i++) { *(p+i)=i; } for(i=0;i<10;i++) { printf("%d ",*(p+i)); } free(p); system("pause"); return 0; }
總結(jié)
到此這篇關(guān)于C語(yǔ)言中#define定義的標(biāo)識(shí)符和宏的文章就介紹到這了,更多相關(guān)C語(yǔ)言#define定義標(biāo)識(shí)符和宏內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)計(jì)算雙色球的中獎(jiǎng)率
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)計(jì)算雙色球的中獎(jiǎng)率,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-12-12使用C++實(shí)現(xiàn)給PDF文檔添加文字水印
這篇文章主要為大家詳細(xì)介紹了如何通過第三方國(guó)產(chǎn)庫(kù)Spire.PDF?for?C++來(lái)實(shí)現(xiàn)給PDF文檔添加文字水印,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11淺析棧區(qū)和堆區(qū)內(nèi)存分配的區(qū)別
以下是對(duì)棧區(qū)和堆區(qū)內(nèi)存分配的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來(lái)參考下2013-08-08C++如何實(shí)現(xiàn)BCD碼和ASCII碼的相互轉(zhuǎn)換
這篇文章主要介紹了C++實(shí)現(xiàn)BCD碼和ASCII碼互轉(zhuǎn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06C++編譯報(bào)錯(cuò):||error: ld returned 1 exit 
這篇文章主要介紹了C++編譯報(bào)錯(cuò):||error: ld returned 1 exit status|的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01C++ std::make_unique和std::make_shared用法小結(jié)
本文主要介紹了C++ std::make_unique和std::make_shared用法,使用std::make_unique和std::make_shared能夠簡(jiǎn)化動(dòng)態(tài)分配內(nèi)存和構(gòu)造對(duì)象的過程,提高代碼的安全性和可讀性,感興趣的可以了解一下2023-11-11C++前綴樹字典樹的學(xué)習(xí)與模擬實(shí)現(xiàn)代碼示例
這篇文章主要介紹了C++前綴樹字典樹的學(xué)習(xí)與模擬實(shí)現(xiàn)代碼示例,Trie又被稱為前綴樹、字典樹,所以當(dāng)然是一棵樹,上面這棵Trie樹包含的字符串集合是{in,inn,int,tea,ten,to},每個(gè)節(jié)點(diǎn)的編號(hào)是我們?yōu)榱嗣枋龇奖慵由先サ?需要的朋友可以參考下2023-07-07