首先项乒,讓我們先從頭文件開始啰劲,在很多頭文件里,我們會看到這樣的語句
#ifndef _MYHEADFILE_H
#define _MYHEADFILE_H
// .......語句......
#endif // _MYHEADFILE_H
為了避免同一個文件被include
多次,我們常使用 #ifndef
進行判斷板丽,如果沒有包含_MYHEADFILE_H
, 則使用#define
來定義一個宏_MYHEADFILE_H
, #endif
與#ifndef
首尾呼應呈枉,表示結束。
說到這里埃碱,我們有必要提一個C語言中的預處理器猖辫,預處理器是一個小軟件,它可以在編譯前處理C程序砚殿,它的行為是由預處理指令控制的啃憎,預處理指令包含了以下內容:
- 宏定義
#define
- 文件包含
#include
- 條件編譯 #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
的區(qū)別炫贤,#ifndef
與#if !defined
的區(qū)別相類似溅固,都在于后者可以組成復雜的預編譯條件,前者只判斷單個宏是否定義,例如:
#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
更為合理