C語(yǔ)言宏定義函數(shù)指針
C語(yǔ)言只要宏定義寫(xiě)得好,誰(shuí)知道你代碼寫(xiě)的是什么,哈哈,開(kāi)句玩笑。宏定義對(duì)于C還是非常重要的,它可以幫助代碼可讀性更強(qiáng)( 對(duì)于自己 ),整理破碎的代碼,以及可以玩各種騷操作,據(jù)說(shuō)?Lisp 調(diào)用 C?就是使用 C 語(yǔ)言的宏定義來(lái)處理。
今天我們用一個(gè)例子來(lái)了解宏定義函數(shù)指針。但在此之前,需要知道什么是預(yù)處理。
預(yù)處理過(guò)程
預(yù)處理是 C 語(yǔ)言編譯過(guò)程中的一個(gè)階段,在 C 語(yǔ)言編譯過(guò)程中,大致經(jīng)歷了四個(gè)步驟:預(yù)處理、編譯、匯編、鏈接;今天我們只講預(yù)處理過(guò)程,預(yù)處理就是將帶有 # 號(hào)的指令、和注釋進(jìn)行處理,包括我們熟知的 #include、#define、#pragma 等等。
#define N 45????宏定義,本質(zhì)上是符號(hào)替換,假設(shè)有那么一條指令: int demo1 = N; 經(jīng)過(guò)預(yù)處理之后就變成了:?int demo1 = 45; 再假設(shè): #define CALCULATE?(34 * 9 + 12 / (2?-?55))? int demo2 = CALCULATE;?(注意,這是兩個(gè)語(yǔ)句,請(qǐng)將?#define CALCULATE?(34 * 9 + 12 / (2?-?55)) 單獨(dú)寫(xiě)作一行)預(yù)處理之后就變成了?int demo1 = (34 * 9 + 12 / (2 - 55)); 其結(jié)果不難看出,預(yù)處理就是將宏定義的內(nèi)容直接替換到使用宏的位置。
宏定義不能直接定義字符串或字符,因?yàn)樽址穷?lèi)型,字符串更不可能,當(dāng)你使用宏定義,定義了一個(gè)字符或者字符串,在預(yù)處理過(guò)程中,編譯器會(huì)報(bào)錯(cuò),并且提示你該符號(hào)未定義error: 'c' undeclared (first use in this function) ,要想使用宏定義字符串,只能使用帶參數(shù)的宏定義,即 #define NAME1(n) #n ,# 號(hào)會(huì)將傳遞進(jìn)來(lái)的 n 轉(zhuǎn)換為字符串,舉個(gè)例子,#define NAME1(n) #n printf("%s",NAME(hello)); (注意,這是兩個(gè)語(yǔ)句,請(qǐng)將?#define CALCULATE?(34 * 9 + 12 / (2?-?55)) 單獨(dú)寫(xiě)作一行)經(jīng)過(guò)NAME()處理后,hello的兩端將被 " 包裹--"hello"。
?了解了一些基礎(chǔ)知識(shí)后,我們準(zhǔn)備進(jìn)入主題
定義一些數(shù)據(jù)
假設(shè)我們需要執(zhí)行這樣一個(gè)函數(shù),將所有的傳入的結(jié)果進(jìn)行相乘
第一第二個(gè)參數(shù),使用 int 型,第三第四個(gè)參數(shù)傳遞 void * 指針,然后在函數(shù)內(nèi)進(jìn)行運(yùn)算,得到結(jié)果再進(jìn)行相乘。
我們先聲明與實(shí)現(xiàn)處理第三與第四個(gè)參數(shù)的函數(shù)。
然后再分別定義函數(shù)指針,這樣就可以通過(guò)函數(shù)指針調(diào)用函數(shù)了。
然后我們對(duì)指針使用宏定義進(jìn)行包裝,在預(yù)處理的時(shí)候就被替換為了 add 與 divi ,而這兩個(gè)符號(hào)都是函數(shù)指針
定義兩個(gè)宏來(lái)使用
最后是函數(shù)?int multiply(int a,int b,void *,void *);?實(shí)現(xiàn)
第二行將傳遞進(jìn)來(lái)的 pending 指針,轉(zhuǎn)換為函數(shù)指針,在函數(shù)內(nèi)可以使用 add 調(diào)用函數(shù)了。
第三行的 Div 是宏,如果定義在全局變量區(qū),那么預(yù)處理之后變成了 divi,而 dive 正是指向函數(shù) divide 的函數(shù)指針
第四行是空行
第五行 將所有的數(shù)據(jù)進(jìn)行相乘,包括現(xiàn)有的,以及調(diào)用函數(shù)后產(chǎn)生的返回值
調(diào)用函數(shù)
現(xiàn)在,我們調(diào)用函數(shù)
注意,第三個(gè)參數(shù)與第四個(gè)參數(shù)現(xiàn)在都是 void *指針
其中 (void *) 還可以使用宏定義一次---- #define ItsAHinstance (void *) ,使用的時(shí)候使用宏ItsAHinstance 代替??(void *) 即可,所以看起來(lái),有那么一點(diǎn)...不像 C 了
最后我們使用 printf()?函數(shù),將數(shù)據(jù)打印出來(lái)
結(jié)果
代碼全貌