
- C++ 基礎
- C++ 首頁
- C++ 概述
- C++ 環境設定
- C++ 基本語法
- C++ 註釋
- C++ Hello World
- C++ 省略名稱空間
- C++ 常量/字面量
- C++ 關鍵字
- C++ 識別符號
- C++ 資料型別
- C++ 數值資料型別
- C++ 字元資料型別
- C++ 布林資料型別
- C++ 變數型別
- C++ 變數作用域
- C++ 多個變數
- C++ 基本輸入/輸出
- C++ 修飾符型別
- C++ 儲存類
- C++ 運算子
- C++ 數字
- C++ 列舉
- C++ 引用
- C++ 日期與時間
- C++ 控制語句
- C++ 決策
- C++ if 語句
- C++ if else 語句
- C++ 巢狀 if 語句
- C++ switch 語句
- C++ 巢狀 switch 語句
- C++ 迴圈型別
- C++ while 迴圈
- C++ for 迴圈
- C++ do while 迴圈
- C++ foreach 迴圈
- C++ 巢狀迴圈
- C++ break 語句
- C++ continue 語句
- C++ goto 語句
- C++ 建構函式
- C++ 建構函式與解構函式
- C++ 複製建構函式
- C++ 檔案處理
- C++ 檔案和流
- C++ 從檔案中讀取
C++ 預處理器
預處理器是指令,它們指示編譯器在實際編譯開始之前預處理資訊。
所有預處理器指令都以 # 開頭,一行預處理器指令之前只能出現空格字元。預處理器指令不是 C++ 語句,因此它們不以分號 (;) 結尾。
您已經在所有示例中看到了 #include 指令。此宏用於將標頭檔案包含到原始檔中。
C++ 支援許多預處理器指令,例如 #include、#define、#if、#else、#line 等。讓我們看看重要的指令:
#define 預處理器
#define 預處理器指令建立符號常量。符號常量稱為宏,指令的一般形式為:
#define macro-name replacement-text
當此行出現在檔案中時,該檔案中宏的所有後續出現都將在程式編譯之前替換為 replacement-text。例如:
#include <iostream> using namespace std; #define PI 3.14159 int main () { cout << "Value of PI :" << PI << endl; return 0; }
現在,讓我們對這段程式碼進行預處理以檢視結果,假設我們有原始碼檔案。因此,讓我們使用 -E 選項進行編譯並將結果重定向到 test.p。現在,如果您檢查 test.p,它將包含大量資訊,並且在底部,您會發現值替換如下:
$gcc -E test.cpp > test.p ... int main () { cout << "Value of PI :" << 3.14159 << endl; return 0; }
類函式宏
您可以使用 #define 來定義一個宏,它將採用如下引數:
#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; }
如果我們編譯並執行上面的程式碼,這將產生以下結果:
The minimum is 30
條件編譯
有幾個指令可以用來編譯程式原始碼的選擇部分。此過程稱為條件編譯。
條件預處理器構造很像“if”選擇結構。考慮以下預處理器程式碼:
#ifndef NULL #define NULL 0 #endif
您可以編譯程式以進行除錯。您還可以使用單個宏開啟或關閉除錯,如下所示:
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
如果在 #ifdef DEBUG 指令之前已定義符號常量 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; }
如果我們編譯並執行上面的程式碼,這將產生以下結果:
The minimum is 30 Trace: Inside main function Trace: Coming out of main function
# 和 ## 運算子
# 和 ## 預處理器運算子在 C++ 和 ANSI/ISO C 中可用。 # 運算子導致將 replacement-text 令牌轉換為用引號括起來的字串。
考慮以下宏定義:
#include <iostream> using namespace std; #define MKSTR( x ) #x int main () { cout << MKSTR(HELLO C++) << endl; return 0; }
如果我們編譯並執行上面的程式碼,這將產生以下結果:
HELLO C++
讓我們看看它是如何工作的。很容易理解 C++ 預處理器如何將以下行:
cout << MKSTR(HELLO C++) << endl;
上面的行將轉換為以下行:
cout << "HELLO C++" << endl;
## 運算子用於連線兩個令牌。這是一個示例:
#define CONCAT( x, y ) x ## y
當 CONCAT 出現在程式中時,它的引數將被連線起來並用於替換宏。例如,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; }
如果我們編譯並執行上面的程式碼,這將產生以下結果:
100
讓我們看看它是如何工作的。很容易理解 C++ 預處理器如何轉換以下行:
cout << concat(x, y);
上面的行將轉換為以下行:
cout << xy;
預定義的 C++ 宏
C++ 提供了許多下面提到的預定義宏:
序號 | 宏和描述 |
---|---|
1 | __LINE__ 這包含程式在編譯時的當前行號。 |
2 | __FILE__ 這包含程式在編譯時的當前檔名。 |
3 | __DATE__ 這包含一個“月/日/年”形式的字串,即原始檔轉換為目的碼的日期。 |
4 | __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; }
如果我們編譯並執行上面的程式碼,這將產生以下結果:
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48