預(yù)處理
C語言的預(yù)處理(預(yù)編譯)主要有三個方面的內(nèi)容: 1.宏定義; 2.文件包含究孕; 3.條件編譯比搭」邗危“#”是編譯器預(yù)處理的標(biāo)志。
預(yù)處理(預(yù)編譯)工作也叫做宏展開:將宏名替換為文本(這個文本可以是字符串敢辩、可以是代碼等)蔽莱。
掌握"宏"概念的關(guān)鍵是“換”。
1.宏定義
:預(yù)處理階段會將程序中所有用到宏定義的地方替換成原內(nèi)容戚长。因此盗冷,使用宏定義可以減少代碼量,保持一致性同廉,使開發(fā)過程更輕松仪糖。
2.文件包含
:指的是頭文件的引入,在預(yù)編譯階段會把引入頭文件的內(nèi)容拷貝至當(dāng)前文件中。
#import "ClassA.h"
#import <Foundation/Foundation.h>
3.條件編譯
:預(yù)編譯時可以根據(jù)條件來決定編譯哪塊代碼迫肖,可以減少編譯的代碼量
條件編譯指令 | 釋義 |
---|---|
#undef | 取消已定義的宏 |
#if | 判斷表達(dá)式真假 |
#ifdef | 如果宏已經(jīng)定義 |
#ifndef | 如果宏沒有定義 |
#elif | 上邊表達(dá)式不成立時锅劝,判斷當(dāng)前表達(dá)式是否成立 |
#endif | 結(jié)束一個#if……#else條件編譯塊 |
宏定義
上邊簡單的提了一下宏定義,這里重點記錄下宏定義一些語法和用法蟆湖。
- 無參宏(直接帶過)
#define NUMBER 100
#define NOTIFICATION_CENTER [NSNotificationCenter defaultCenter]
- 帶參宏
- 固定參數(shù)
如果讓你實現(xiàn)一個取最小值的宏函數(shù)故爵,你一定覺的很簡單,然后胸有成竹的就寫出了這行代碼
#define MIN(A,B) A < B ? A : B
看著邏輯上也沒有什么毛病隅津,嚯嚯嚯诬垂,小伙子,入坑了吧伦仍!我們知道預(yù)處理會在預(yù)編譯階段將預(yù)定義標(biāo)識替換成原內(nèi)容结窘,如果有宏嵌套,宏展開后充蓝,原先的邏輯可能會因為運算符的優(yōu)先級導(dǎo)致輸出錯誤隧枫。具體詳解請看大神之作《宏定義的黑魔法 - 宏菜鳥起飛手冊》喉磁。
正確寫法:(這真的不是一般的麻煩啊。官脓。协怒。)
#define MIN(A,B) ({ __typeof__(A)__a = (A); __typeof__(B) __b = (B); __a < __b ? __a :__b; })
- 可變參數(shù)及特殊語法
特殊標(biāo)識 | 釋義 | 示例 |
---|---|---|
# | 單個”#“號的作用是字符串化 | #define A(x) #x 調(diào)用 A(123) 將得到c字符串 "123" |
@ | @是objc的編譯符號,不屬于宏操作的對象 | #define A(x) @#x 將得到OC字符串 @"123" |
\ | 連接換行符 | 放在行尾 然后換行 用來連接代碼塊 |
## | 雙井號是連接符 | #define A(x,y) x##y 調(diào)用 A(123,456) ==> 123456 |
__ | 雙下滑線表示預(yù)定義确买,即已經(jīng)定義過的 | __TIME__, __FUNCTION__, __LINE__ 等 |
... | 任意個數(shù)的參數(shù),但是宏定義中只有... ,那么起碼有1個參數(shù) | #define NSLog(...) {(NSLog)((format),__VAR_VACHS__);} |
__VA_ARHS__ | 配合...使用,表示的是宏定義中的...中的所有剩余參數(shù)斤讥,至少一個 | 同上 |
##__VA_ARHS__ | 參數(shù)個數(shù)不限制纱皆,可為0 | #define NSLog(format, ...) {(NSLog)((format),##__VAR_VACHS__);} |
宏定義示例
單例
#define RF_SINGLETION(__clazz) \
+ (__clazz *)sharedInstance;
#define RF_DEF_SINGLETION(__clazz) \
static __clazz * __singletion;\
+ (__clazz *)sharedInstance \
{\
static dispatch_once_t once; \
dispatch_once(&once,^{__singletion = [[__clazz alloc] init];});\
return __singletion;\
}\
+ (id)allocWithZone:(struct _NSZone *)zone {\
\
if (!__singletion) {\
\
return [super allocWithZone: zone];\
\
}\
\
return nil;\
\
}\
\
- (id)copy {\
\
return __singletion;\
\
}\
初始化方法
#define INIT_CELL(_CLASS_NAME) \
\
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier \
{ \
NSLog(@"-------------- %@ init ----------", self.class); \
[_CLASS_NAME description]; \
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { \
[self _CLASS_NAME##_internalInit]; \
} \
\
return self; \
} \
\
- (void)awakeFromNib \
{ \
[super awakeFromNib]; \
\
[self _CLASS_NAME##_internalInit]; \
} \
\
- (void)_CLASS_NAME##_internalInit
結(jié)語
本篇為知識總結(jié)湾趾,幫助自己查閱資料,后續(xù)會不斷更新派草。搀缠。。祝大家學(xué)習(xí)愉快近迁!^_^