第二章補(bǔ)充C/C++預(yù)處理命令
預(yù)處理器是在程序源文件被編譯之前根據(jù)預(yù)處理指令對(duì)程序源文件進(jìn)行處理的程序。預(yù)處理器指令以#號(hào)開(kāi)頭標(biāo)識(shí),末尾不包含分號(hào)。預(yù)處理命令不是C/C++語(yǔ)言本身的組成部分,不能直接對(duì)它們進(jìn)行編譯和鏈接。C/C++語(yǔ)言的一個(gè)重要功能是可以使用預(yù)處理指令和具有預(yù)處理的功能。C/C++提供的預(yù)處理功能主要有文件包含、宏替換、條件編譯等。
1文件包含
預(yù)處理指令#include用于包含頭文件,有兩種形式:#include <xxx.h>,#include "xxx.h"。尖括號(hào)形式表示被包含的文件在系統(tǒng)目錄中。如果被包含的文件不一定在系統(tǒng)目錄中,應(yīng)該用雙引號(hào)形式。在雙引號(hào)形式中可以指出文件路徑和文件名。如果在雙引號(hào)中沒(méi)有給出絕對(duì)路徑,則默認(rèn)為用戶(hù)當(dāng)前目錄中的文件,此時(shí)系統(tǒng)首先在用戶(hù)當(dāng)前目錄中尋找要包含的文件,若找不到再在系統(tǒng)目錄中查找。對(duì)于用戶(hù)自己編寫(xiě)的頭文件,宜用雙引號(hào)形式。對(duì)于系統(tǒng)提供的頭文件,既可以用尖括號(hào)形式,也可以用雙引號(hào)形式,都能找到被包含的文件,但顯然用尖括號(hào)形式更直截了當(dāng),效率更高。
2宏替換
宏定義
宏定義的作用一般是用一個(gè)短的名字代表一個(gè)長(zhǎng)的代碼序列。宏定義包括無(wú)參數(shù)宏定義和帶參數(shù)宏定義兩類(lèi)。宏名和宏參數(shù)所代表的代碼序列可以是任何意義的內(nèi)容,如類(lèi)型、常量、變量、操作符、表達(dá)式、語(yǔ)句、函數(shù)、代碼塊等。但要尤其注意的是宏名和宏參數(shù)必須是合法的標(biāo)識(shí)符,其所代表的內(nèi)容及意義在宏展開(kāi)前后必須一直是獨(dú)立且保持不變的,不能分開(kāi)解釋和執(zhí)行。
如果希望宏定義代碼序列中標(biāo)識(shí)符內(nèi)出現(xiàn)的宏形參名能夠被替換,可以在宏形參名與標(biāo)識(shí)符之間添加連接符##,在宏替換過(guò)程中宏形參名和連接符##一起將被替換為宏實(shí)參名。##用于把宏參數(shù)名與宏定義代碼序列中的標(biāo)識(shí)符連接在一起,形成一個(gè)新的標(biāo)識(shí)符。例如:
#define BLOG(name) my_##name,BLOG(vrmozart)表示my_vrmozart
#define BLOG(name) name##_ blog,BLOG(vrmozart)表示vrmozart_ blog
#define BLOG(name) my_##name##_blog,BLOG(vrmozart)表示my_vrmozart_ blog
如果希望宏定義代碼序列中的宏形參名被替換為宏實(shí)參名的字符串形式(即在宏實(shí)參名兩端加雙引號(hào)"),而不是替換為宏實(shí)參名,可以在宏定義代碼序列中的宏形參名前面添加符號(hào)#。#用于把宏參數(shù)名變?yōu)橐粋€(gè)字符串形式。例如:
#define STR(name) #vrmozart,STR(vrmozart)表示"vrmozart"
__DATE__,字符串常量類(lèi)型,表示當(dāng)前所在源文件的編譯日期,輸出格式為Mmmddyyyy(如May 27 2006)。
__TIME__,字符串常量類(lèi)型,表示當(dāng)前所在源文件的編譯日期,輸出格式為hh:mm:ss(如09:11:10)。
__FILE__,字符串常量類(lèi)型,表示當(dāng)前所在源文件名,且包含文件路徑。
__LINE__,整數(shù)常量類(lèi)型,表示當(dāng)前所在源文件中的行號(hào)。
__FUNCTION__,字符串常量類(lèi)型,表示當(dāng)前所在函數(shù)名。
3條件編譯指令
一般情況下,在進(jìn)行編譯時(shí)對(duì)源程序中的每一行都要編譯,但是有時(shí)希望程序中某一部分內(nèi)容只在滿(mǎn)足一定條件時(shí)才進(jìn)行編譯,如果不滿(mǎn)足這個(gè)條件,就不編譯這部分內(nèi)容,這就是條件編譯。條件編譯主要是進(jìn)行編譯時(shí)進(jìn)行有選擇的挑選,注釋掉一些指定的代碼,以達(dá)到多個(gè)版本控制、防止對(duì)文件重復(fù)包含的功能。#if,#ifndef,#ifdef,#else,#elif,#endif是比較常見(jiàn)條件編譯預(yù)處理指令,可根據(jù)表達(dá)式的值或某個(gè)特定宏是否被定義來(lái)確定編譯條件。
4其它預(yù)處理指令
除了上面討論的常用預(yù)處理指令外,還有三個(gè)不太常見(jiàn)的預(yù)處理指令:#line、#error、#pragma,下面分別介紹。
① #line
#line指令用于重新設(shè)定當(dāng)前由__FILE__和__LINE__宏指定的源文件名字和行號(hào)。
#line一般形式為#line number "filename",其中行號(hào)number為任何正整數(shù),文件名filename可選。#line主要用于調(diào)試及其它特殊應(yīng)用,注意在#line后面指定的行號(hào)數(shù)字是表示從下一行開(kāi)始的行號(hào)。
② #error
#error指令使預(yù)處理器發(fā)出一條錯(cuò)誤消息,然后停止執(zhí)行預(yù)處理。
#error 一般形式為#error info,如#error MFC requires C++ compilation。
③ #pragma
#pragma指令可能是最復(fù)雜的預(yù)處理指令,它的作用是設(shè)定編譯器的狀態(tài)或指示編譯器完成一些特定的動(dòng)作。
#pragma一般形式為#pragma para,其中para為參數(shù),下面介紹一些常用的參數(shù)。
#pragma once,只要在頭文件的最開(kāi)始加入這條指令就能夠保證頭文件被編譯一次。
#pragma message("info"),在編譯信息輸出窗口中輸出相應(yīng)的信息,例如#pragma message("Hello")。
#pragma warning,設(shè)置編譯器處理編譯警告信息的方式,例如#pragma warning(disable:4507 34;once : 4385;error:164)等價(jià)于#pragma warning(disable:4507 34)(不顯示4507和34號(hào)警告信息)、#pragma warning(once:4385)(4385號(hào)警告信息僅報(bào)告一次)、#pragma warning(error:164)(把164號(hào)警告信息作為一個(gè)錯(cuò)誤)。
#pragma comment(…),設(shè)置一個(gè)注釋記錄到對(duì)象文件或者可執(zhí)行文件中。常用lib注釋類(lèi)型,用來(lái)將一個(gè)庫(kù)文件鏈接到目標(biāo)文件中,一般形式為#pragma comment(lib,"*.lib"),其作用與在項(xiàng)目屬性鏈接器“附加依賴(lài)項(xiàng)”中輸入庫(kù)文件的效果相同。
轉(zhuǎn)自http://www.cnblogs.com/lidabo/archive/2012/08/27/2658909.html