宏定義分為不帶參數(shù)的宏定義和帶參數(shù)的宏定義,不帶參數(shù)的宏定義就是普通的宏定義,帶參數(shù)的宏定義則稍稍復(fù)雜。下面將結(jié)合一些例子講解這些顯得比較高級(jí)的宏定義。
這個(gè)宏定義中有一個(gè)參數(shù),使用時(shí)傳入?yún)?shù)即可,
k=M(5); //宏調(diào)用
經(jīng)過(guò)替換,變?yōu)?/p>
k=5*5+3*5
2、#define MAX(X,Y) (((x)>(y))?(x):(y))機(jī)器很笨,為了防止機(jī)器理解錯(cuò)誤,需要將參數(shù)以及整個(gè)表達(dá)式都加上括號(hào)。
調(diào)用
MAX(5,3)
會(huì)被替換為:
(((5)>(3))?(5):(3))
3、用帶參數(shù)宏定義多個(gè)語(yǔ)句#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
看完整例子:
#include#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
int main(){int length = 3, width = 4, height = 5, sa, sb, sc, vv;
SSSV(sa, sb, sc, vv);
printf("sa=%d, sb=%d, sc=%d, vv=%d\n", sa, sb, sc, vv);
return 0;
}
sa=12, sb=15, sc=20, vv=60
替換為:
#include#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
int main(){int length = 3, width = 4, height = 5, sa, sb, sc, vv;
sa = length * width;
sb = length * height;
sc = width * height;
vv = width * length * height;
printf("sa=%d, sb=%d, sc=%d, vv=%d\n", sa, sb, sc, vv);
return 0;
}
sa=12, sb=15, sc=20, vv=60
4、宏定義嵌套下面的宏定義將天,小時(shí),分鐘,秒轉(zhuǎn)化為ms
#define SECOND 1000UL//ul為無(wú)符號(hào)長(zhǎng)整形,不加默認(rèn)為int,可存儲(chǔ)數(shù)據(jù)小
#define MINUTE (SECOND *60)
#define HOUR (MINUTE *60)
#define DAY (HOUR *24)
5、#define ABC “abc”用宏定義除了定義數(shù)字還可以定義字符串
6、用#將宏參數(shù)轉(zhuǎn)換為字符串#include#define STR(s) #s
int main() {printf("%s\n", STR(c.biancheng.net));
printf("%s\n", STR("c.biancheng.net"));
return 0;
}
會(huì)被替換為
#include#define STR(s) #s
int main() {printf("%s\n", "c.biancheng.net");
printf("%s\n", "\"c.biancheng.net\"");
return 0;
}
c.biancheng.net
"c.biancheng.net"
注意轉(zhuǎn)義字符"表示"
7、##用于在宏定義中進(jìn)行連接#include#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
int main() {printf("%f\n", CON1(8.5, 2));
printf("%d\n", CON2(12, 34));
return 0;
}
會(huì)被替換為
#include#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
int main() {printf("%f\n", 8.5e2);
printf("%d\n", 123400);
return 0;
}
850.000000
123400
8、復(fù)雜宏定義1#define osTimerStaticDef(name, function, control) \
const osTimerDef_t os_timer_def_##name = \
{(function), (control) }
該宏定義是用
osTimerStaticDef(name, function, control)
替換
const osTimerDef_t os_timer_def_##name = \
{(function), (control) }
osTimerDef_t 是一個(gè)結(jié)構(gòu)體別名,我們可以看一下它的定義
typedef struct os_timer_def
{os_ptimer ptimer; ///< start address of a timer function
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
osStaticTimerDef_t *controlblock; ///< control block to hold timer's data for static allocation; NULL for dynamic allocation
#endif
} osTimerDef_t;
用osTimerDef_t定義一個(gè)結(jié)構(gòu)體變量,變量名中包含參數(shù)name,用##與os_timer_def_連接,達(dá)到自動(dòng)修改結(jié)構(gòu)體變量名的目的。
結(jié)構(gòu)體包含兩個(gè)成員。
9、復(fù)雜宏定義2#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ) || ((FREQ) == HAL_TICK_FREQ_100HZ) || ((FREQ) == HAL_TICK_FREQ_1KHZ))
先看看HAL_TICK_FREQ_10HZ的定義
typedef enum
{HAL_TICK_FREQ_10HZ = 100U,
HAL_TICK_FREQ_100HZ = 10U,
HAL_TICK_FREQ_1KHZ = 1U,
HAL_TICK_FREQ_DEFAULT = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;
傳入FREQ,只要FREQ100U或FREQ10U或FREQ==1U,就返回true
二、答疑 1、宏定義占用內(nèi)存嗎?宏定義只是一個(gè)預(yù)處理命令,在程序編譯之前做一個(gè)簡(jiǎn)單的替換,不會(huì)占用內(nèi)存空間,因此宏定義中的參數(shù)不用指定數(shù)據(jù)類(lèi)型。
2、宏定義作用域從定義位置開(kāi)始到當(dāng)前文件末尾
3、define和typedef的區(qū)別宏定義只是簡(jiǎn)單的字符串替換,由預(yù)處理器來(lái)處理;
而 typedef 是在編譯階段由編譯器處理的,它并不是簡(jiǎn)單的字符串替換,而是給原有的數(shù)據(jù)類(lèi)型起別名,將它作為一種新的數(shù)據(jù)類(lèi)型。
這里給個(gè)例子體驗(yàn)一下:
typedef struct node
{int a;
char b;
}Node;
這里就是用typedef給結(jié)構(gòu)體node取一個(gè)別名Node,以后用它定義結(jié)構(gòu)體變量,就可以直接用Node
Node node1;
而不需要使用下面這種方式定義:
struct node node2;
完整代碼如下:
#includetypedef struct node
{int a;
char b;
}Node;
int main()
{Node node1;
node1.a=10;
node1.b='a' ;
printf("node1.a=%d,node1.b=%c\r\n",node1.a,node1.b);
struct node node2;
node2.a=20;
node2.b='b' ;
printf("node2.a=%d,node2.b=%c\r\n",node2.a,node2.b);
return 0;
}
node1.a=10,node1.b=a
node2.a=20,node2.b=b
可以看到,typedef就是給這個(gè)結(jié)構(gòu)體取一個(gè)別名,不是簡(jiǎn)單替換。
再看一個(gè)例子:
#define PIN1 int*
typedef int* PIN2;//注意;不要忘記
下面用PIN1定義兩個(gè)變量
PIN1 a,b;
經(jīng)過(guò)預(yù)處理器替換后,代碼變?yōu)椋?/p>
int* a,b;
其中a是一個(gè)指向整型的指針變量,b是一個(gè)整型變量。
同樣,用PIN2定義兩個(gè)變量
PIN2 a,b;
a,b均為指向整型的指針變量。
預(yù)處理命令包括:宏定義、文件包含、條件編譯
(1) 一般宏定義的格式為 #define 宏名 被替換字符串;
(2) C語(yǔ)言的文件包含,就是以 #Include開(kāi)頭之后,引用的文件;
(3) 條件編譯可以作為頭文件衛(wèi)士
#ifndef FILE_H // 判斷FILE_H宏是否正在,不存在則條件為真
#define FILE_H // 定義FILE_H宏,注意與普通宏定義的區(qū)別?。。?
#endif // FILE_H // #ifndef的結(jié)尾
這種固定寫(xiě)法,一般在頭文件中使用,它能防止頭文件被重復(fù)包含。
參考資料1、http://c.biancheng.net/view/1982.html
2、https://blog.csdn.net/m0_37689444/article/details/88852630
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
分享文章:【C語(yǔ)言】高級(jí)宏定義-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)地址:http://chinadenli.net/article28/pscjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、全網(wǎng)營(yíng)銷(xiāo)推廣、響應(yīng)式網(wǎng)站、微信公眾號(hào)、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、Google
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容