一、總結
1、預處理器直接對巨集進行文字替換
2、巨集使用時的引數不會進行求值和運算
3、預處理器不會對巨集定義進行語法檢查,巨集定義時出現的語法錯誤只能被編譯器檢測
4、巨集定義的效率高於函式呼叫(巨集不占用記憶體,函式占用記憶體)
5、巨集的使用會帶來一定的***
6、#define定義的巨集可以出現在程式的任意位置,#define定義之後的**都可以使用這個巨集
7、#define 表示式的使用類似函式呼叫,但是巨集比函式功能更強大,比函式更容易出錯
8、巨集表示式中不能出現遞迴定義
二、**測試(ubuntu 10 gcc平台)
1、**:
#include #define error -1
#define path1 "d:/test/test.c"
#define path2 d:/test/test.c
#define path3 d:/test/
//下面這個遞迴是不對的,巨集表示式中不能出現遞迴定義
#define sum(n) (n > 0 ? sum(n - 1) + n : 0)
#define _sum_(a,b) (a) + (b)
#define _min_(a,b) ((a) < (b) ? (a) : (b))
#define _dim_(a) sizeof(a)/sizeof(*a)
//記住用define定義的巨集,預處理之後全都消失
//所以下面這個函式實際是空的,預處理後函式內容都是空的
void def(void)
double area(double r)
int main()
; int s1 = _sum_(a,b);
int s2 = _sum_(a,b)*_sum_(a,b);//這裡預處理好後變成:int s2 = (a) + (b)*(a) + (b); 所以是1 + 2*1 + 2 = 5
int m = _min_(a++,b); //這裡預處理後變成這樣:int m = ((a++) < (b) ? (a++) : (b));所以a執行了兩次++,最後變成3
int d = _dim_(c);
int su = sum(5); //預處理通過,編譯不通過,因為巨集定義不能出現遞迴
printf("a = %d\n",a); //a = 3
printf("s1 = %d\n",s1); //s1 = 3
printf("s2 = %d\n",s2); //s2 = 5
printf("m = %d\n",m); //m = 2
printf("d = %d\n",d); //d = 4
printf("r = %lf\n",r); //r = 78.539815
return 0;
}
我們先看下預處理之後是什麼東西(預處理命令在終端輸入:gcc -e test.c -o test.i 然後找到這個檔案用gedit開啟就行了)
void def(void)
double area(double r)
int main()
; int s1 = (a) + (b);
int s2 = (a) + (b)*(a) + (b);
int m = ((a++) < (b) ? (a++) : (b));
int d = sizeof(c)/sizeof(*c);
int su = (5 > 0 ? sum(5 - 1) + 5 : 0);
printf("a = %d\n",a);
printf("s1 = %d\n",s1);
printf("s2 = %d\n",s2);
printf("m = %d\n",m);
printf("d = %d\n",d);
printf("r = %lf\n",r);
return 0;
}
再看下終端輸出
**裡面都有注釋,講的很清楚,所以不講了
2、**2 (注意:這個**裡面有bug,看看你們能不能發現)
#include #include #define malloc(type,l) (type *)malloc(sizeof(type) * l)
#define free(p) (free(p),p = null)
#define log(s) printf("[%s] %s \n",__date__,__file__,__line__,s)
#define foreach(i,m) for(i = 0;i < m;i++)
#define begin
int main()
這麼看是不是有點複雜,那我們預處理下,在終端輸入gcc -e test.c -o test.i 然後在當前資料夾下面找到這個新生成的test.i,然後雙擊在gedit裡面把它開啟
看出來沒!是不是第1個for後面有個冒號,這是第乙個bug,同樣下面for也是有個冒號,這是第二個bug
那這個bug會導致什麼問題麼?加了冒號,for迴圈什麼都不執行,for迴圈執行完x = 5,下面p[5] = 5 + 1;
但是我們申請內容只申請了5個int型別資料,但是現在賦值到第6個了,所以會導致錯誤,具體什麼現象,你們在終端裡面直接執行就知道了,所以我們把這個bug去掉,然後編譯執行下,看下終端輸出:
參考資料《狄泰軟體c語言高階教程》
巨集定義的注意事項
巨集定義不是函式,它只是不同形式的替換而已,不同於函式的引數巨集定義的引數 暫且稱之為引數 不是作為乙個整體參與計算的,如下例子所示 include using namespace std define fun1 x x x define fun2 x x x int fun3 int x int ...
C語言巨集定義用法注意事項與好處
1.乙個識別符號被巨集定義後,該識別符號便是乙個巨集名。這時,在程式中出現的是巨集名,在該程式被編譯前,先將巨集名用被定義的字串替換,這成為巨集替換,替換後才進行編譯,巨集替換是簡單的替換 2.include define n 2 int main int argc,char argv 這段程式執行...
c語言巨集定義的使用方法
在工程規模較小,不是很複雜,與硬體結合緊密,要求移植性的時候,可採用巨集定義簡化程式設計,增強程式可讀性。當巨集作為常量使用時,c程式設計師習慣在名字中只使用大寫字母。但是並沒有如何將用於其他目的的巨集大寫的統一做法。由於巨集 特別是帶引數的巨集 可能是程式中錯誤的 所以一些程式設計師更喜歡使用大寫...