#ifndef, #define, #endif 做用

#ifndef
  它是if not define 的簡寫,是宏定義的一種,實際上確切的說,這應該是預處理功能三種(宏定義、文件包含、條件編譯)中的一種----條件編譯。

  在c語言中,對同一個變量或者函數進行屢次聲明是不會報錯的。因此若是h文件裏只是進行了聲明工做,即便不使用# ifndef宏定義,多個c文件包含同一個h文件也不會報錯。c++

  可是在c++語言中,#ifdef的做用域只是在單個文件中。因此若是h文件裏定義了全局變量,即便採用#ifdef宏定義,多個c文件包含同一個h文件仍是會出現全局變量重定義的錯誤。
使用#ifndef能夠避免下面這種錯誤:若是在h文件中定義了全局變量,一個c文件包含同一個h文件屢次,若是不加#ifndef宏定義,會出現變量重複定義的錯誤;若是加了#ifndef,則不會出現這種錯誤。
示例:
   
#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中的大數。

相關文章
相關標籤/搜索