C語言中#define定義的標(biāo)識符和宏實例代碼
??1.#define定義標(biāo)識符
在C語言程序中,有時候會包含#define
#define可以定義標(biāo)識符
也就是說可以對字符重新定義,實現(xiàn)代替的作用
??語法
#define name stuff
就比如說:
#define MAX 1000(用MAX代替1000)
#define reg register (用reg代替register)
??舉個栗子
#include<stdio.h>
#define MAX 100
int main()
{
printf("%d", MAX);
return 0;
}當(dāng)代碼運行的時候
在代碼編譯的預(yù)處理階段 就會把宏替換為文本程序代碼
代替的結(jié)果如下:
#include<stdio.h>
int main()
{
printf("%d", 100);
return 0;
}??注意:#define定義標(biāo)識符后面盡量不加上分號,因為如果加上的話,在替換的過程中,分號也會別替換到文本程序中,有時候會導(dǎo)致出現(xiàn)邏輯錯誤。
??2.#define定義宏
#define規(guī)定允許將參數(shù)替換到文本中,這樣包含參數(shù)叫做#define定義宏
宏在程序中,執(zhí)行的速度更快,因為相對于函數(shù),宏沒有函數(shù)的調(diào)用和返回的開銷
語法:
#define SQUARE(x) x*x
這與#define定義宏一樣,都是完成替換的,不過#define定義宏后面有一個括號,包含參數(shù)
??下面用#define定義宏來實現(xiàn)兩個數(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ù)相對獨立
這樣可以避免由于操作符的優(yōu)先級不同,導(dǎo)致最終的邏輯就錯了
舉個栗子:
#include<stdio.h>
#define sum(x) x*x
int main()
{
int ret = sum(3 + 3);
printf("%d", ret);
}
如果不仔細(xì)觀察的話,可能你認(rèn)為的結(jié)果就是36
這個代碼的計算過程為:3+3*3+3,并不是(3+3)*(3+3)
??#define替換的規(guī)則
#define定義標(biāo)識符和宏時,程序會繼續(xù)如下步驟
1.在定義宏時,先對參數(shù)進(jìn)行檢查,如果參數(shù)里包含有#define定義的標(biāo)識符時,首先完成相應(yīng)的替換
2.替換文本會隨后插入到原來文本文件中,對于宏來說,參數(shù)名被他們的值所替換
3.最后進(jìn)行檢查,果然還有#define定義的符號,將重復(fù)上述的操作
注意:
1.#define參數(shù)中可以包含其他由#define定義的標(biāo)識符,但是#define不能遞歸
2.如果#define的參數(shù)名存在在字符串中,將不會完成替換
??#與## #的用法:
在不確定參數(shù)的情況下,可以使用 “#n” ,可以實現(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;
}
雙##的用法可以拼接兩個字符串
當(dāng)然這個前提是拼接后的字符串必須產(chǎn)生一個合法的標(biāo)識符,否則結(jié)果就是未定義的
??宏的缺點
1.如果使用宏過多,宏定義的代碼插入到程序中,會大幅度增加程序的長度
2.宏是沒法調(diào)試的
3.宏與類型無關(guān),導(dǎo)致程序不夠嚴(yán)謹(jǐn)
4.宏會帶來優(yōu)先級的問題,容易導(dǎo)致程序的錯誤
??宏和函數(shù)的優(yōu)缺點
1).在代碼長度角度上,因為宏是直接替換所以若宏較長會增加代碼長度
2).在執(zhí)行速度上,宏較函數(shù)快,因為函數(shù)存在調(diào)用/返回時的額外開銷
3).在參數(shù)求值方面,define定義的宏可能會具有副作用會導(dǎo)致修改變量最后的值,而函數(shù)即使調(diào)用多次也不會修改變量原來的值
4).在參數(shù)類型方面,宏與類型無關(guān),所以宏是可以傳參數(shù)的而函數(shù)不行在C中函數(shù)是不可以傳類型的
5).在是否可調(diào)試方面,宏不可調(diào)試,函數(shù)可調(diào)試宏可以傳類型的檢測,實現(xiàn)malloc(動態(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語言中#define定義的標(biāo)識符和宏的文章就介紹到這了,更多相關(guān)C語言#define定義標(biāo)識符和宏內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于C++中push_back()函數(shù)的用法及代碼實例
push_back是vector的一個方法,表示將一個元素存儲到容器的末尾,下面這篇文章主要給大家介紹了關(guān)于C++中push_back()函數(shù)用法的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
C語言詳細(xì)分析講解內(nèi)存管理malloc realloc free calloc函數(shù)的使用
C語言內(nèi)存管理相關(guān)的函數(shù)主要有realloc、calloc、malloc、free等,下面這篇文章主要給大家介紹了關(guān)于C語言內(nèi)存管理realloc、calloc、malloc、free函數(shù)的相關(guān)資料,需要的朋友可以參考下2022-05-05
C語言實現(xiàn)學(xué)生學(xué)籍管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生學(xué)籍管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
C++中關(guān)鍵字Struct和Class的區(qū)別
這篇文章主要介紹了C++中關(guān)鍵字Struct和Class的區(qū)別,本文用大量實例講解了Struct和Class的區(qū)別,需要的朋友可以參考下2014-09-09

