在c語言中,對同一個變量或者函數進行屢次聲明是不會報錯的。因此若是h文件裏只是進行了聲明工做,即便不使用# ifndef宏定義,多個c文件包含同一個h文件也不會報錯。c++
#ifndef x //先測試x是否被宏定義過 #define x 程序段1blabla~ //若是x沒有被宏定義過,定義x,並編譯程序段 1 #endif
程序段2blabla~ //若是x已經定義過了則編譯程序段2的語句,「忽視」程序段 1
條件指示符#ifndef 的最主要目的是防止頭文件的重複包含和編譯。瞭解:條件編譯固然也能夠用條件語句來實現。 可是用條件語句將會對整個源程序進行編譯,生成的目標程序程序很長,而採用條件編譯,則根據條件只編譯其中的程序段1或程序段2,生成的目標程序較短。若是條件選擇的程序段很長,採用條件編譯的方法是十分必要的。模塊化
#ifndef 和 #endif 要一塊兒使用,若是丟失#endif,可能會報錯。總結一下:在c語言中,對同一個變量或者函數進行屢次聲明是不會報錯的。因此若是h文件裏只是進行了聲明工做,即便不使用# ifndef宏定義,一個c文件屢次包含同一個h文件也不會報錯。 使用#ifndef能夠避免下面這種錯誤:若是在h文件中定義了全局變量,一個c文件包含同一個h文件屢次,若是不加#ifndef宏定義,會出現變量重複定義的錯誤;若是加了#ifndef,則不會出現這種錯.函數
#ifdef測試
與ifndef相似,ifdef顧名思義,就是if define,看例子spa
#ifdef x 程序1blabla~ #endif
翻譯:若是宏定義了x,則執行程序1.翻譯
此外,還有其餘形式,仍是看例子好些:code
#ifndef x #define x 程序段 1 #else 程序段 2 #endif
當x沒有由#define定義過,則編譯「程序段1」,不然編譯「程序段2」。htm
#if 表達式 程序段 1 #else 程序段 2 #endif
它的做用是 當「表達式」值爲真時。編譯程序段1。不然則編譯程序段2。當沒有程序段2時,直接是#if---#endifblog
#define作用域
在C或C++語言源程序中容許用一個標識符來表示一個字符串,稱爲「宏」。「define」爲宏定義命令。
被定義爲「宏」的標識符稱爲「宏名」。在編譯預處理時,對程序中全部出現的「宏名」,都用宏定義中的字符串去代換,這稱爲「宏代換」或「宏展開」。宏定義是由源程序中的宏定義命令完成的。宏代換是由預處理程序自動完成的。
優勢:
(1) 方便程序的修改。這個就很少說了。
(2) 提升程序的運行效率。使用帶參數的宏定義可完成函數調用的功能,又能減小系統開銷,提升運行效率。正如C語言中所講,函數的使用可使程序更加模塊化,便於組織,並且可重複利用,但在發生函數調用時,須要保留調用函數的現場,以便子函數執行結束後能返回繼續執行,一樣在子函數執行完後要恢復調用函數的現場,這都須要必定的時間,若是子函數執行的操做比較多,這種轉換時間開銷能夠忽略,但若是子函數完成的功能比較少,甚至於只完成一點操做,如一個乘法語句的操做,則這部分轉換開銷就相對較大了,但使用帶參數的宏定義就不會出現這個問 題,由於它是在預處理階段即進行了宏展開,在執行時不須要轉換,即在當地執行。宏定義可完成簡單的操做,但複雜的操做仍是要由函數調用來完成,並且宏定義所佔用的目標代碼空間相對較大。因此在使用時要依據具體狀況來決定是否使用宏定義。
在C或C++語言中,「宏」分爲有參數和無參數兩種。
1、無參宏定義
1. 無參宏定義的通常形式爲:#define 標識符 字符串
2. 其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均爲預處理命令。「define」爲宏定義命令。「標識符」爲所定義的宏名。「字符串」能夠是常數、表達式、格式串等。
1 #include <stdio.h> 2 #define M ( a+b ) 3 int main( int argc, char * argv[] ) 4 { 5 int s, a, b; 6 printf( "input number a& b: " ); 7 scanf( "%d%d", &a, &b ); 8 s = M*M; 9 printf( "s=%d\n" ,s ); 10 }
上例程序中首先進行宏定義,定義M來替代表達式(a+b),在 s= M * M 中做了宏調用。在預處理時經宏展開後該語句變爲: S=(a+b)*(a+b) 但要注意的是,在宏定義中表達式(a+b)兩邊的括號不能少。不然會發生錯誤。 如看成如下定義後:#define M (a)+(b) 在宏展開時將獲得下述語句:S= (a)+(b)*(a)+(b)
還要說明的是:
1.宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的代換,字符串中能夠含任何字符,能夠是常數,也能夠是表達式,預處理程序對它不做任何檢查。若有錯誤,只能在編譯已被宏展開後的源程序時發現。
2.宏定義不是說明或語句,在行末沒必要加分號,如加上分號則連分號也一塊兒置換。
3..宏定義必須寫在函數以外,其做用域爲宏定義命令起到源程序結束。如要終止其做用域可以使用#undef命令
2、帶參宏定義
c語言容許宏帶有參數。在宏定義中的參數稱爲形式參數,在宏調用中的參數稱爲實際參數。對帶參數的宏,在調用中,不只要宏展開,並且要用實參去代換形參。
帶參宏定義的通常形式爲: #define 宏名(形參表) 字符串
例:
#define M(y) ((y)*(y)+3*(y)) /*宏定義*/ k = M(5); /*宏調用*/
#include <stdio.h> #define MAX( a, b ) ((a>b)?(a):(b)) int main( int argc, char * argv[] ) { int x, y, max; printf( "input two numbers: " ); scanf( "%d%d", &x, &y ); max = MAX( x, y ); printf( "max=%d\n", max ); return 0; }
上例程序的第一行進行帶參宏定義,用宏名MAX表示條件表達式 (a>b)?a:b ,形參a,b均出如今條件表達式中。程序中 max=MAX(x,y) 爲宏調用,實參x,y,將代換形參a,b。宏展開後該語句爲: max=(x>y)?x:y; 用於計算x,y中的大數。