iOS 7:漫談#define 宏定義
阿新 • • 發佈:2018-01-05
們的 知識 深入 最簡 連接符 都是 inline 疑惑 處理
如果您完全不知道宏是什麽的話,可以先來熱個身。很多人在介紹宏的時候會說,宏嘛很簡單,就是簡單的查找替換嘛。嗯,只說對了的一半。C中的宏分為兩類,對象宏(object-like macro)和函數宏(function-like macro)。對於對象宏來說確實相對簡單,但卻也不是那麽簡單的查找替換。對象宏一般用來定義一些常數,舉個例子:
#define宏定義在C系開發中可以說占有舉足輕重的作用。底層框架自不必說,為了編譯優化和方便,以及跨平臺能力,宏被大量使用,可以說底層開發離開define將寸步難行。而在更高層級進行開發時,我們會將更多的重心放在業務邏輯上,似乎對宏的使用和依賴並不多。但是使用宏定義的好處是不言自明的,在節省工作量的同時,代碼可讀性大大增加。 如果想成為一個能寫出漂亮優雅代碼的開發者,宏定義絕對是必不可少的技能(雖然宏本身可能並不漂亮優雅XD)。但是因為宏定義對於很多人來說,並不像業務邏輯那樣是每天會接觸的東西。即使是能偶爾使用到一些宏,也更多的僅僅只停留在使用的層級,卻並不會去探尋背後發生的事情。 有一些開發者確實也有探尋的動力和意願,但卻在點開一個定義之後發現還有宏定義中還有其他無數定義,再加上滿屏幕都是不同於平時的代碼,既看不懂又不變色,於是乎心生煩惱,怒而回退。本文希望通過循序漸進的方式,通過幾個例子來表述C系語言宏定義世界中的一些基本規則和技巧,從0開始,希望最後能讓大家至少能看懂和還原一些相對復雜的宏。考慮到我自己現在objc使用的比較多,這個站點的讀者應該也大多是使用objc的,所以有部分例子是選自objc,但是本文的大部分內容將是C系語言通用。 入門
- //This defines PI
- #define M_PI 3.14159265358979323846264338327950288
- #define M_PI 3.14159265358979323846264338327950288
- double r = 10.0;
- double circlePerimeter = 2 * M_PI * r;
- // => double circlePerimeter = 2 * 3.14159265358979323846264338327950288 * r;
- printf("Pi is %0.7f",M_PI);
- //Pi is 3.1415927
- //A simple function-like macro
- #define SELF(x) x
- NSString *name = @"Macro Rookie";
- NSLog(@"Hello %@",SELF(name));
- // => NSLog(@"Hello %@",name);
- // => Hello Macro Rookie
- #define PLUS(x,y) x + y
- printf("%d",PLUS(3,2));
- // => printf("%d",3 + 2);
- // => 5
- //Version 1.0
- #define MIN(A,B) A < B ? A : B
- int a = MIN(1,2);
- // => int a = 1 < 2 ? 1 : 2;
- printf("%d",a);
- // => 1
- int a = 2 * MIN(3, 4);
- printf("%d",a);
- // => 4
- int a = 2 * MIN(3, 4);
- // => int a = 2 * 3 < 4 ? 3 : 4;
- // => int a = 6 < 4 ? 3 : 4;
- // => int a = 4;
- //Version 2.0
- #define MIN(A,B) (A < B ? A : B)
- int a = MIN(3, 4 < 5 ? 4 : 5);
- printf("%d",a);
- // => 4
- int a = MIN(3, 4 < 5 ? 4 : 5);
- // => int a = (3 < 4 < 5 ? 4 : 5 ? 3 : 4 < 5 ? 4 : 5); //希望你還記得運算符優先級
- // => int a = ((3 < (4 < 5 ? 4 : 5) ? 3 : 4) < 5 ? 4 : 5); //為了您不太糾結,我給這個式子加上了括號
- // => int a = ((3 < 4 ? 3 : 4) < 5 ? 4 : 5)
- // => int a = (3 < 5 ? 4 : 5)
- // => int a = 4
- //Version 3.0
- #define MIN(A,B) ((A) < (B) ? (A) : (B))
- float a = 1.0f;
- float b = MIN(a++, 1.5f);
- printf("a=%f, b=%f",a,b);
- // => a=3.000000, b=2.000000
- float a = 1.0f;
- float b = MIN(a++, 1.5f);
- // => float b = ((a++) < (1.5f) ? (a++) : (1.5f))
- int a = ({
- int b = 1;
- int c = 2;
- b + c;
- });
- // => a is 3
- //GNUC MIN
- #define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
- //CLANG MIN
- #define __NSX_PASTE__(A,B) A##B
- #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
- #define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); })
- #define __NSX_PASTE__(A,B) A##B
- #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
- #define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); \
- __typeof__(B) __NSX_PASTE__(__b,L) = (B); \
- (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); \
- })
iOS 7:漫談#define 宏定義