程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ "#"的作用和用法

C++ "#"的作用和用法

編輯:C++入門知識

C++ "#"的作用和用法


1 ###的作用和用法

C/C++ 的宏中,#的功能是將其後面的宏參數進行字符串化操作,簡單說就是在對它所引用的宏變量通過替換後在其左右各加上一個雙引號。##連接符號由兩個井號組成,其功能是在帶參數的宏定義中將兩個子串聯接起來,從而形成一個新的子串。但它不可以是第一個或者最後一個子串。

#include 
using namespace std;

#define WARN_IF(EXP) if(EXP) cerr << #EXP << endl;
#define paster( n ) cout << "token" << #n << " = " << n << endl;
#define _CONS(a, b) int(a##+##b)
#define _STRI(s) #s

void main()
{
    int div = 0;
    WARN_IF(div == 0);           // prints : div == 0
    paster(9);                   // prints : token9 = 9
    cout << _CONS(1, 2) << endl;     // prints : 3
    cout << _STRI(INT_MAX) << endl;  // prints : INT_MAX
}

凡是宏定義裡有用###的地方宏參數是不會再展開,例如_STRI(INT_MAX)中的INT_MAX就不會被展開為2147483647。如果想要使其中的宏參數展開,則需要多加一層中間轉換宏:

#define STRI(s) _STRI(s)

cout << STRI(INT_MAX) << endl; // prints : 2147483647

加這層宏的用意是把所有宏的參數在這層裡全部展開,那麼在轉換宏裡的宏就能得到對應的宏參數。

接下來,我們來了解通過預處理指令創建條件編譯參數控制代碼編譯的一些用法。

2 #include的用法

包含頭文件的操作,通常有兩種格式:

#include 
#include "header-file"

<>""表示編譯器在搜索頭文件時的順序不同:

<>表示從系統目錄下開始搜索,然後再搜索PATH環境變量所列出的目錄,不搜索當前目錄 ""是表示從當前目錄開始搜索,然後是系統目錄和PATH環境變量所列出的目錄。

所以,系統頭文件一般用<>,用戶自己定義的則可以使用"",加快搜索速度。除此外,寫代碼多了就會發現,有些頭文件之間的相互包含是有隱藏依賴關系的,一定要加以注意。Google C++ Style Guide中也強調使用標准的頭文件包含順序可增強可讀性, 避免隱藏依賴:

1 相關文件(優先位置,如dir2/foo2.h
2 C系統文件
3 C++ 系統文件
4 其他庫的.h文件
5 本項目內.h文件

3 #if,#elif,#else,#endif用法

// structure 1
#if constant_expression
#else
#endif

// structure 2
#if constant_expression
#elif constant_expression
#endif

這裡的結構跟常見的if...elseif...else if...else語句類似,當#if後的條件為非零(true)時,編譯#if#else#elif之間的代碼,否則編譯#else#endif之間的代碼(或者判斷#elif後的條件是否非零(true),決定是否編譯#elif#endif之間的代碼)。

#if 1
    cout << "Hello world!" << endl;
#else
    cout << "Nice to meet you!" << endl;
#endif

// prints : Hello world!
#if 1
    cout << "Hello world!" << endl;
#elif 1
    cout << "Nice to meet you!" << endl;
#endif

// prints: Hello world!
//         Nice to meet you!

4 #define,#undef,#ifdef,#ifndef用法

#define是大家都常見的宏定義方法,用法結構為:

// #define identifier replacement-code
#define PI 3.1415926
#define ADD(x,y) (x + y)

#undef顧名思義,就是從該處取消前面已經定義的宏,如果標識符當前沒有被定義稱為一個宏名稱,就會忽略該指令:

// #undef identifier
#undef PI

#ifdef#ifndef 含義相反,前者含義為如果定義了該宏,則編譯相應代碼;後者則為如果沒有定義該宏,則編譯相應代碼。通用結構為:

/*
 * #ifdef identifier
 * #else or #elif
 * #endif
**/ 
#define DEBUG
#ifdef DEBUG
  cout << "This is a debug message." << endl;
#endif
// prints : This is a debug message.

/*
 * #ifndef identifier
 * #else or #elif
 * #endif
**/
 #ifndef DEBUG
  cout << "This is a debug message." << endl;
#endif
// prints nothing

在編程時,為了避免頭文件重定義,經常使用的就是#define配合條件編譯解決:

#ifndef MY_HEADER_FILE_H
#define MY_HEADER_FILE_H

// ...
class MyHeaderFile
{
    // ....
};

#endif // MY_HEADER_FILE_H

除此以外,還有#pragma once的用法,只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次。(在所有的預處理指令中,#pragma指令可能是最復雜的了,它的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作,本文不多講述。)

5 #line用法

#line命令是用於更改__LINE____FILE__變量的值。__FILE____LINE__描述被讀取的當前文件和所在行數。

// #line line-number filename
int main()
{
#line 10 "main.cpp"
    cout << __FILE__ << " " << __LINE__ << endl;
}
// prints : main.cpp 10

6 #error用法

#error會直接導致程序停止編譯並輸出指定的錯誤信息:

// #error message
#ifndef VERSION
#error Version number not specified.
#endif

// The compiler will halt compiling and return with the specified error message: 
// fatal error C1189: #error :  Version number not specified.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved