C/Cpp / #define
一、概括
?1. 將一些文本替換成另外一些文本。
?2. 以“#”開始,第一個換行符為止。可以出現(xiàn)在源文件任何位置。
?3. 有效范圍:從指令出現(xiàn)的地方到該文件末尾或者該符號對應(yīng)的 #undef。
?4. ANSI 之后,允許預(yù)編譯指令的“#”前面添加空格和制表符,“#”和指令的其余部分之間亦可有空格。但是,之前是不允許的(K&R C)。
?5. 常用的預(yù)編譯指令:
?#define、#undef、#include、#ifdef、#else、#endif、#ifndef、#if、#elif、#line、#error和#pragma 。
?二、符號常量:#define
?#define ? ? ? ?PI ? ? ? ? 3.1415926#define ? ? Add(x,y) ? ? ?((x)+(y))//預(yù)編譯指令 ? ? ?宏 ? ? ? ?替換體(替換列表)//X和Y被成為宏參數(shù)。//注意:上述例子中每一個括號都是不可缺少的。1、作用:一旦預(yù)處理器在程序中找到該宏,就會用替換體替換該宏。
2、宏變成最終替換文本的過程被稱為宏展開。
3、宏可以表示任何字符串(數(shù)值、函數(shù)、字符串)和其他宏。
4、注意:宏如果在雙引號里面,預(yù)處理是不會進行文本替換的。
5、不帶參數(shù)的宏
(1)如上圖中定義的“PI”。
(2)有的編譯器將宏的替換體看作是記號型字符串,而不是傳統(tǒng)意義上的字符型字符串。C預(yù)處理器記號是宏定義的替換體中單獨的“詞”,用空格把這些詞分開。
例如:
上述的宏的替換體的記號為“1*2”,如果改成下例:
#define ?TWO ?1 * 2則記號就有三個,分別是“1”、“*”和“2”。
小結(jié):宏的替換體解釋為字符型字符串,則將空格作為替換體的一部分。解釋為記號型字符串,則把空格作為替換體中各記號的分隔符。
(3)重定義常量
同一文件中,同一符號被定義了兩次以上,這個過程被稱為重定義常量。例如:
#define ? PI ? 3.1415 #define ? PI ? 3.1415926這種情況下,有的編譯器報錯,有的編譯器警告,有的編譯器沒有任何提示信息(VS2010),以最后一個符號定義為準。
例如:
這里 iSum 中元素有 10 個。
6、帶參數(shù)的宏
(1)宏中使用參數(shù)的外形和函數(shù)很像的被稱為類函數(shù)宏。
(2)宏函數(shù)和函數(shù)調(diào)用完全不同,前者是在預(yù)編譯期,將參數(shù)記號傳給了程序,后者是在程序運行期將參數(shù)的值傳給了函數(shù),即不同的過程發(fā)生在了不同的時期。
應(yīng)用:
Z = Add(3,7);7、用宏參數(shù)創(chuàng)建字符串:#運算符
(1)一般的宏在字符串中都會被視為普通的文本,但是允許在宏替換中的字符串中包含宏參數(shù)。“#x”就可轉(zhuǎn)換為字符串“x”的形參名,這個過程被稱為字符串化(注意使用“”)。
(2)例如:
#include "stdafx.h" #include <stdio.h> #define POST(x) ?printf("I am "#x",%d\n",((x)*(x)))int _tmain(int argc, _TCHAR* argv[]) {POST(10);POST(2 + 3);getchar();return 0; }結(jié)果:
8、預(yù)處理器的粘合劑,“##”指令,將兩個記號組合成一個記號。
例如:
#include "stdafx.h" #include <stdio.h>#define XNAME(n) ? ? ? iX##n ? #define Print_Xn(n) ? ?printf("iX"#n" = %d\n",iX##n)?int _tmain(int argc, _TCHAR* argv[]) {int XNAME(1) = 2; ?//相當于:int iX1 = 2int XNAME(2) = 5; ?//相當于:int iX2 = 5Print_Xn(1);Print_Xn(2);getchar();return 0; }結(jié)果:
9、變參宏
(1)指令如下:
"..." 和 "__VA_ARGS__"這兩個指令組合可以讓用戶定義可變參數(shù)的類函數(shù)宏。
(2)例如:
結(jié)果:
10、宏函數(shù)和普通函數(shù)的對比
(1)宏定義只能寫在一行,雖然編譯器沒有硬性規(guī)定,但是請遵守這條約定。
(2)空間:使用宏函數(shù)20個地方,就會有20個副本,但是函數(shù)只有一個。
(3)時間:宏函數(shù)沒有函數(shù)跳轉(zhuǎn),節(jié)省時間。如果嵌套調(diào)用,效果很明顯。
(4)宏不用考慮形參的數(shù)據(jù)類型,因為在宏眼里,一切都是字符串或者記號。
三、#undef
1. 取消之前的 #define 定義。
2. 即使之前沒有被定義,直接使用此指令也是沒有問題的。所以在使用某個符號時,若不確定之前是否已使用,可以在前面加上#undef。
四、拓展
字符常量和符號常量的區(qū)別
(1)字符常量:直接在代碼中書寫的數(shù)值,例如:5.78、3.1415、7。
(2)符號常量:用一個標識符代替一個常量。先定義后使用,例如:#define ?PI ?3.1415926
?
?
(SAW:Game Over!)
總結(jié)
以上是生活随笔為你收集整理的C/Cpp / #define的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RS触发器
- 下一篇: Tiniux 3.0 / Memory.