條件編譯中使用的預編譯指令
條件編譯是根據實際定義宏(某類條件)進行代碼靜態編譯的手段。可根據表達式的值或某個特定宏是否被定義來確定編譯條件。
#define 定義一個預處理宏
#undef 取消宏的定義
#if 編譯預處理中的條件命令,相當於C語法中的if語句
#ifdef 判斷某個宏是否被定義,若已定義,執行隨后的語句
#ifndef 與#ifdef相反,判斷某個宏是否未被定義
#elif 若#if, #ifdef, #ifndef或前面的#elif條件不滿足,則執行#elif之后的語句,相當於C語法中的else-if
#else 與#if, #ifdef, #ifndef對應, 若這些條件不滿足,則執行#else之后的語句,相當於C語法中的else
#endif #if, #ifdef, #ifndef這些條件命令的結束標志.
defined 與#if, #elif配合使用,判斷某個宏是否被定義
預編譯指令應用舉例
1. #define、#undef
#define命令定義一個宏:
宏定義,按照是否帶參數通常分為對象宏、函數宏兩種。
對象宏: 不帶參數的宏被稱為"對象宏(objectlike macro)"。對象宏多用於定義常量、通用標識。例如:
// 常量定義 #define MAX_LENGTH 100 // 通用標識,即 printf 函數的調用可代替名稱 #define SLog printf
函數宏:帶參數的宏。利用宏可以提高代碼的運行效率: 子程序的調用需要壓棧出棧, 這一過程如果過於頻繁會耗費掉大量的CPU運算資源。 所以一些代碼量小但運行頻繁的代碼如果采用帶參數宏來實現會提高代碼的運行效率。但多數c++程序不推薦使用函數宏,調試上有一定難度,可考慮使用c++的inline代替之。例如:
// 最小值函數 #define MIN(a,b) ((a)>(b)? (a):(b)) // 安全釋放內存函數 #define SAFE_DELETE(p) {if(NULL!=p){delete p; p = NULL;}}
#undef可以取消宏定義,與#define對應。
2. defined
defined用來測試某個宏是否被定義。defined(name): 若宏被定義,則返回1,否則返回0。
它與#if、#elif、#else結合使用來判斷宏是否被定義,乍一看好像它顯得多余, 因為已經有了#ifdef和#ifndef。defined可用於在一條判斷語句中聲明多個判別條件;#ifdef和#ifndef則僅支持判斷一個宏是否定義。此外和#if、#elif、#else不同,#ifdef、#ifndef 不同的,defined測試的宏可以是對象宏,也可以是函數宏。
#if defined(VAX) && defined(UNIX) && !defined(DEBUG)
3. #ifdef、#ifndef、#else、#endif
防止頭文件重復包含
最常見的條件編譯是防止重復包含頭文件的宏,也就是達到 #pragma once 的目的,如下面的代碼:
1 #ifndef A_H 2 #define A_H 3 4 //... 5 6 #endif
在實際使用中,比較常用:
1 #ifdef _ONLINE 2 3 // ... 做一些操作 4 5 #endif 6 7 #ifdef _LOCAL 8 9 // ... 做一些其它操作 10 11 #endif
想執行哪一段代碼,就在前面#define _ONLINE或者_LOCAL
_DEBUG宏
有些代碼,想要使得在debug的時候執行,release的時候不不執行,就可以這么做。
#ifdef _DEBUG #endif
對於_DEBUG,當你用生成時,VS的開發環境則自動的加上這個宏定義;release時,沒有這個宏。