預(yù)處理器

2018-08-12 22:03 更新

預(yù)處理器

預(yù)處理器是指令,在實際編譯開始之前,預(yù)處理器會給編譯器指令來預(yù)處理需要編譯的信息。

所有的預(yù)處理指令以開頭,可能在預(yù)處理指令行之前出現(xiàn)的只有空白字符。預(yù)處理指令是不是 C++ 語句,所以它們不會以分號(;)結(jié)束。

你已經(jīng)在所有的例子中都看到了 #include 指令。這個宏用于將頭文件包含到源文件。

還有許多 C++ 支持的預(yù)處理指令,如#include,#define#if, #else#line 等等。下面我們來看一些重要的指令:

define 處理器

#define 處理指令用來創(chuàng)建符號常量。這個符號常量被稱為。指令的一般形式是:

    #define macro-name replacement-text 

當(dāng)這一行出現(xiàn)在一個文件中時,在程序被編譯之前,該文件中的所有后續(xù)出現(xiàn)的 macro-name 將會被 replacement-text 替換掉。 例如:

    #include <iostream>
    using namespace std;

    #define PI 3.14159

    int main ()
    {

    cout << "Value of PI :" << PI << endl; 

    return 0;
    }

現(xiàn)在,讓我們對這個代碼進(jìn)行預(yù)處理來看一看結(jié)果。假設(shè)我們有源代碼文件,那么我們用 -E 選項編譯它并重定向結(jié)果到 test.p?,F(xiàn)在,如果你查看 test.p,會發(fā)現(xiàn)里面有大量的信息,并且你會在底部發(fā)現(xiàn)值已經(jīng)被替換了,如下所示:

    $gcc -E test.cpp > test.p

    ...
    int main ()
    {

    cout << "Value of PI :" << 3.14159 << endl; 

    return 0;
    }

函數(shù)宏

你可以用#define定義一個帶有如下參數(shù)的宏:

    #include <iostream>
    using namespace std;

    #define MIN(a,b) (((a)<(b)) ? a : b)

    int main ()
    {
       int i, j;
       i = 100;
       j = 30;
       cout <<"The minimum is " << MIN(i, j) << endl;

    return 0;
    }

如果我們編譯并運(yùn)行上述代碼,將會產(chǎn)生以下結(jié)果:

    The minimum is 30

條件編譯

有幾種不同的指令,其可用于有選擇的編譯程序源代碼的一部分。這個過程被稱為條件編譯。

條件預(yù)處理器結(jié)構(gòu)很像 if 選擇結(jié)構(gòu)。思考下面的預(yù)處理代碼:

    #ifndef NULL
       #define NULL 0
    #endif

你可以編譯一個用于調(diào)試的程序,并且可以用單個宏打開或關(guān)閉調(diào)試開關(guān),如下所示:

    #ifdef DEBUG
       cerr <<"Variable x = " << x << endl;
    #endif

如果符號常量 DEBUG 定義在#ifdef DEBUG指令之前,那么程序中的 cerr 語句會被編譯。你可以使用#if 0語句注釋掉程序的一部分,如下所示:

    #if 0
       code prevented from compiling
    #endif

我們來用下面的例子試一下:

    #include <iostream>
    using namespace std;
    #define DEBUG

    #define MIN(a,b) (((a)<(b)) ? a : b)

    int main ()
    {
       int i, j;
       i = 100;
       j = 30;
    #ifdef DEBUG
       cerr <<"Trace: Inside main function" << endl;
    #endif

    #if 0
       /* This is commented part */
       cout << MKSTR(HELLO C++) << endl;
    #endif

       cout <<"The minimum is " << MIN(i, j) << endl;

    #ifdef DEBUG
       cerr <<"Trace: Coming out of main function" << endl;
    #endif
    return 0;
    }

如果我們編譯并運(yùn)行上述代碼,將會產(chǎn)生以下結(jié)果:

    Trace: Inside main function
    The minimum is 30
    Trace: Coming out of main function

和 ## 操作符

在 C++ 和 ANSI/ISO C 中###預(yù)處理器操作符是可用的。

操作符會將要替代的文本符號轉(zhuǎn)換成用雙引號引起來的字符串。

思考下面的宏定義:

    #include <iostream>
    using namespace std;

    #define MKSTR( x ) #x

    int main ()
    {
    cout << MKSTR(HELLO C++) << endl;

    return 0;
    }

如果我們編譯并運(yùn)行上述代碼,將會產(chǎn)生以下結(jié)果:

    HELLO C++

讓我們來看看它是如何工作的。

這很容易理解,C++ 預(yù)處理器將下面一行代碼:

    cout << MKSTR(HELLO C++) << endl;

轉(zhuǎn)變成了下面這一行的代碼:

    cout << "HELLO C++" << endl;

##操作符是用來連接兩個符號的。

例子如下所示:

    #define CONCAT( x, y )  x ## y

當(dāng) CONCAT 出現(xiàn)在程序中時,它的參數(shù)會被連接起來,并用其來取代宏。例如,CONCAT(HELLO,C++),在程序中會 “HELLO C++” 替代。例子如下所示。

    #include <iostream>
    using namespace std;

    #define concat(a, b) a ## b
    int main()
    {
       int xy = 100;

       cout << concat(x, y);
       return 0;
    }

如果我們編譯并運(yùn)行上述代碼,將會產(chǎn)生以下結(jié)果:

    100

讓我們來看看它是如何工作的。

這很容易理解,C++ 預(yù)處理器將下面一行代碼:

    cout << concat(x, y);

轉(zhuǎn)換成了下面這一行的代碼:

     cout << xy;

C++ 預(yù)定義的宏

C++ 提供了許多預(yù)定義的宏,如下所示:

描述
__LINE__ 編譯過后,其包含了當(dāng)前程序行在程序內(nèi)的行號
__FILE__ 編譯過后,其包含了當(dāng)前程序的程序名
__DATE__ 其包含了由源文件轉(zhuǎn)換為目標(biāo)代碼的日期,該日期是格式為 月/日/年 的字符串文本
__TIME__ 其包含了源文件編譯的時間,該時間是 時:分:秒 形式的字符串文本

我們來看一個展示上面宏的例子:

    #include <iostream>
    using namespace std;

    int main ()
    {
    cout << "Value of __LINE__ : " << __LINE__ << endl;
    cout << "Value of __FILE__ : " << __FILE__ << endl;
    cout << "Value of __DATE__ : " << __DATE__ << endl;
    cout << "Value of __TIME__ : " << __TIME__ << endl;

    return 0;
    }

如果我們編譯并運(yùn)行上述代碼,將會產(chǎn)生以下結(jié)果:

    Value of __LINE__ : 6
    Value of __FILE__ : test.cpp
    Value of __DATE__ : Feb 28 2011
    Value of __TIME__ : 18:52:48
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號