C++ #if #endif #define #ifdef #ifndef #if defined #if !defined詳解
首先,讓我們先從頭文件開始,在很多頭文件裏,我們會看到這樣的語句
#ifndef _MYHEADFILE_H
#define _MYHEADFILE_H
// .......語句......
#endif // _MYHEADFILE_H
爲了避免同一個文件被include多次,我們常使用 #ifndef 進行判斷,如果沒有包含
_MYHEADFILE_H , 則使用#define 來定義一個宏 _MYHEADFILE_H , #endif 與#ifndef
首尾呼應,表示結束。
說到這裏,我們有必要提一個C語言中的預處理器,預處理器是一個小軟件,它可以在編譯前處理C程序,它的行爲是由預處理指令控制的,預處理指令包含了以下內容:
1,宏定義 #define
2,文件包含 #include
3,條件編譯 #if
#ifdef
#ifndef
#if defined
#if !defined
#elif
#else
#endif
#undef
指令都是以#開始的,我們來看一下簡單的宏定義(對象式宏)
#define 標準符 替換列表
#define PI 3.1415926
可以對類型重命名
#define BOOL int
宏可以帶參數,也是常說的宏函數
#define 標識符(x1,x2...) 替換列表
特別注意的是標識符和(之間不能有空格,圓括號是必須的。
我們來看一下例子:
#define MAX(x,y) ((x)>(y)?(x):(y))
#define IS_EVEN(n) ((n)%2==0)
#define TOUPPER(c) (‘a’<(c)&&(c)<’z’?(c)-’a’+’A’(c))
#define SWAP(T,x,y) {T t=x; x=y; y=t}
還可以寫得更復雜一點,比如我們來寫一個宏函數,用它來驗證一個日期是否合法
#define ISLEAP(y) ((y)%4==0&&(y)%100!=0||(y)%400==0)
#define ISSMALL(m) ((m)==4||(m)==6||(m)==9||(m)==11)
#define NORMAL(m) (ISSMALL(m)?30:31)
#define DAYS(y,m) ((m)==2?28+ISLEAP(y):NORMAL(m))
#define IN(x, from,to) ((x)>=(from)&&(x)<=(to))
#define VALID(y,m,d) ((y)>1600&&IN(m,1,12)&&IN(d,1,DAYS(y,m)))
下面我們來看看條件編譯
#if (comdition)
{//語句##;}
#endif
如果(comdition)爲真, 也就是邏輯1的話,編譯下面的語句,如果(comdition)爲假,即邏輯0,則不編譯下面的語句。例子如下:
#define DEBUG
#if DEBUG
Printf(“Value of i:%d\n”, i);
Printf(“Value of j:%d\n”, j);
#endif
格式:
#if 常量表達式
常量表達式爲0時,預處理器刪除#if 和#endif中間的代碼
#if 會把沒有定義過的標準符視做爲0, 如果沒有定義DEBUG, 則
測試#if DEBUG 會失敗,但#if !DEBUG會成功。
可以用宏來定義文件名:
#if define(IA32)
#define CPU_FILE “ia32.h”
#elif defined(IA64)
#deifine CPU_FILE “ia64.h”
#elif defined(AMD64)
#define CPU_FILE “amd64.h”
#endif
#include CPU_FILE
還可以取消已經定義的宏:
#if defined VALUE // 檢驗VALUE是否被定義 ,如果被定義
#undef VALUE // 解除語句定義
#define VALUE 1000 // 重新定義VALUE 爲1000
#endif
如果檢驗沒有定義,可以這樣寫:
#ifndef VALUE // 如果VALUE沒有被定義
#define VALUE 1000 // 定義VALUE 爲1000
#endif
以上所用的宏中:
#undef爲解除定義;
#ifndef是if not defined的縮寫,也可以寫成#if !defined 即如果沒有定義;
#ifdef是if defined的縮寫,也可以寫成#if defined 即檢查是否定義過;
#ifdef 和 #if defined 的區別,#ifndef 與#if !defined 的區別相類似,都在於後者可以組成複雜的預編譯條件,前者只判斷單個宏是否定義,例如:
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* v */ SIZE16,
#else
0,
#endif
#ifdef PERL_PACK_CAN_SHRIEKSIGN
/* v */ SIZE16,
#else
0,
#endif
#ifdef是種簡寫,但不支持更復雜的表達式。
#ifdef HAVE_MYHEADER
# if VERSION > 3
...
# endif
#endif
這種情況用
#if defined(HAVE_MYHEADER) && VERSION > 3
...
#endif
更爲合理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.