IOS中巨集的高階使用

2021-07-03 06:43:32 字數 2875 閱讀 4803

先說一下本文中會提到的內容:##,__va_args__, __file__, __line__ , __function__等

巨集變數:

先舉乙個例子,會用到上面這些巨集:

[cpp]view plain

copy

#define myprintf(...) printk("[lch]:file:%s, line:%d, function:%s," \

__va_args__, __file__, __line__ ,__function__);  

此處的 #define 的作用是將 myprintf( )換成後面那一大串的內容,而括號內 ... 的內容原樣抄寫在 __va_args__ 的位置。最終輸出如下:

[lch]:file:arch/arm/mach-omap2/board-omap3wscec-camera.c, line:163, function:beagle_cam_init,camera init!

解析:

1)__va_args__:總體來說就是將左邊巨集中 ... 的內容原樣抄寫在右邊 __va_args__ 所在的位置。它是乙個可變引數的巨集,是新的c99規範中新增的,目前似乎只有gcc支援(vc從vc2005開始支援)。要注意的是,printf 的輸出格式是括號內左邊是字串,右邊是變數,而且右變數與左輸出格式是一一對應的。所以在上面那個例子中, __va_args__只能是一些不含任何變數的字串常量。因為上面的例子中若__va_args__含有變數,整個printf的輸出與變數便不能一一對應,輸出會出錯。

如果僅僅是替換函式名,可用如下方式,此時對__va_args__無任何特殊要求:#define myprintf(...) printk( __va_args__),在除錯程式時可以這樣用:

[cpp]view plain

copy

#ifndef log_ndebug_function

#define logfunc(...) ((void)0)

#else

#define logfunc(...) (printk(__va_args__))

#endif

2) __file__ :巨集在預編譯時會替換成當前的源檔名

3) __line__:巨集在預編譯時會替換成當前的行號

4) __function__:巨集在預編譯時會替換成當前的函式名稱

5)類似的巨集還有 __time__,__stdc__, __timestamp__等,就完全當乙個變數來使用即可。

巨集連線符##:

舉個例子:巨集定義為#define xname(n) x##n,**為:xname(4),則在預編譯時,巨集發現xname(4)與xname(n)匹配,則令 n 為 4,然後將右邊的n的內容也變為4,然後將整個xname(4)替換為 x##n,亦即 x4,故 最終結果為 xname(4) 變為 x4.

**如下:

[cpp]view plain

copy

#include 

#define xname(n) x ## n

#define print_xn(n) printf("x" #n " = %d/n", x ## n);

intmain(

void

)    

輸出為:x1 = 14, x2 = 20

ps:編譯過程:

1,掃瞄解析檔案

2,預處理(巨集在此時處理,該替換的文字會被替換)

3,對處理過的源**進行彙編,輸出組合語言的**(c語言的控制流程被處理)

4,編譯為二進位制目標檔案

5,與程式庫進行鏈結,輸出最終的程式檔案

(巨集 和 c語言在不同的階段處理執行)

簡單介紹以下幾個巨集:

1) __va_args__ 是乙個可變引數的巨集,這個可變引數的巨集是新的c99規範中新增的,目前似乎只有gcc支援(vc6.0的編譯器不支援)。巨集前面加上##的作用在於,當可變引數的個數為0時,這裡的##起到把前面多餘的","去掉,否則會編譯出錯。

2) __file__ 巨集在預編譯時會替換成當前的源檔名

3) __line__巨集在預編譯時會替換成當前的行號

4) __function__巨集在預編譯時會替換成當前的函式名稱

1.重新定義系統的nslog,__optimize__ 是release 缺省會加的巨集

#ifndef __optimize__

#define nslog(...) nslog(__va_args__)

#else

#define nslog(...){}

#endif

2.直接自己寫#define,當release版本的時候把#define 注釋掉即可

#define ios_debug

#ifdef ios_debug

#define nslog(...) nslog(__va_args__)

#endif

3.

#ifdef debug  

# define dlog(format, ...) nslog((@"[檔名:%s]" "[函式名:%s]" "[行號:%d]" format), __file__, __function__, __line__, ##__va_args__);

#else

# define dlog(...);

#endif

這種方式需要修改專案的配置,使得在debug編譯的時候,編譯dlog的巨集,產生詳細的日誌資訊,而release的時候,不產生任何控制台輸出

相比而言,還是第一種比較方便

iOS 巨集的使用

由於平時在開發過程中,經常有遇到使用巨集 常量的時候。但是一直對這兩者的使用有些疑惑。尤其是對const的使用更加模糊,只知道該修飾符有很多種用法,位置不同含義不同。所以特意查詢了一下,為了以後方便自己查閱特此記錄一下。巨集就相當於是文字替換操作,是編譯期語法,並不會占用到記憶體,因為實質上它根本就...

ios 靈活使用巨集

繼承於c語言和c 中的巨集定義,oc中也可以方便有效的支援巨集定義使用,簡單的巨集定義誰都知道,比如定義乙個int型常量,string型別的字串都可以。如果複雜一些呢,比如用巨集定義實現單例,實現類的歸檔操作,其實都是可以的。就以類的歸檔操作為例,說明一下 現有巨集定義 sscodingimplem...

C C 巨集的高階使用1 0

單個 引例1.include define p x printf s d n x,x int main 引例2 include define printfun x printf s x void gogogo 在函式裡面列印函式名 int main 2.兩個 引例1 include h define...