C語言的預處理命令


前言

C程序的源代碼中可以包含各種編譯指令,也被稱為預處理命令
他們實際上不是C語言的一部分,但卻擴展C程序的設計環境。
ANSI標准定義的C語言預處理程序包括下列命令:#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明顯,所有預處理命令均以符號#開頭,下面分別加以介紹。

#define

#define定義了一個標識符及一個串。在源程序中遇到該標識符時,都以相應的串代替。ANSI標准將標識符定義為宏名,將替換過程稱為宏替換。格式一般為:

#define identifier string

注意

  1. 該語句沒有分號。在在標識符與串之間可以有任意多個空格,串一旦開始,僅由一新行結束。
  2. 宏名定義后,即可成為其他宏名定義中的一部分。
  3. 宏替換僅僅是以文本串代替宏標識符,前提是宏標識符必須獨立的識別出來,否則不進行替換。例如:#define XYZ this is a test使用宏printf(“XYZ”)。該段不打印“this is a test”而打印“XYZ”。因為預編譯器識別出的是“XYZ”
  4. 如果串長於一行,在該行末尾加上\
#define LONG_STRING "this is a very long\
string that is used as an example"
  1. 普遍使用大寫字母定義標識符。
  2. 用宏代換代替實在的函數的一大好處是宏替換增加了代碼的速度,因為不存在函數調用的開銷。但增加速度也有代價:由於重復編碼而增加了程序長度。

#error

#error強迫編譯程序停止編譯,主要用於程序調試。
#error指令使預處理器發出一條錯誤消息,該指令的作用就是在程序崩潰之前給出一定的信息。

#include

#include使編譯程序將另一源文件嵌入帶#include的源文件,被讀入的源文件必須用雙引號尖括號括起來。例如:#include"stdio.h"或#include<stdio.h>這兩行代碼均使用C編譯程序讀入並編譯用於處理磁盤文件庫的子程序。
將文件嵌入帶有#include命令中的文件內是可行的,這種方式稱為嵌套的嵌入文件,嵌套層次依賴於具體實現。
如果 顯式路徑名文件標識符 的一部分,則僅在 那些 子目錄 中搜索 被嵌入文件。否則,如果文件名用雙引號括起來,則首先檢索當前工作目錄。如果未發現文件,則在命令行中說明的所有目錄中搜索。如果仍未發現文件,則搜索實現時定義的標准目錄
如果沒有顯式路徑名且文件名被尖括號括起來,則首先在編譯命令行中的目錄內檢索。如果文件沒找到,則檢索標准目錄,不檢索當前工作目錄

條件編譯命令

條件編譯命令有幾個命令可對程序源代碼的各部分有選擇地進行編譯,該過程稱為條件編譯。商業軟件公司廣泛應用條件編譯來提供和維護某一程序的許多顧客版本。

#if、#elif、#else、#endif

#if的一般含義是如果#if后面的常量表達式為true,則編譯它與#endif之間的代碼,否則跳過這些代碼。命令#endif標識一個#if塊的結束。

點擊查看代碼
#include<iostream>
#include<cstdlib>
using namespace std;
#define MAX 91
int main(){
    #if MAX>99
        cout<<"MAX is bigger than 99"<<endl;
    #elif MAX>90
        cout<<"MAX is bigger than 90"<<endl;
    #else cout<<"MAX is smaller than 90"<<endl;
    #endif return 0;
    system("pause");
}

跟在#if后面的表達式在編譯時求值,因此它必須僅含常量及已定義過的標識符,不可使用變量。表達式不許含有操作符sizeof(sizeof也是編譯時求值)。
#else命令的功能有點象C語言中的else;#else建立另一選擇(在#if失敗的情況下)。注意,#else屬於#if塊。
#elif命令意義與else if 相同,它形成一個if else if階梯狀語句,可進行多種編譯選擇。#elif 后跟一個常量表達式。如果表達式為true,則編譯其后的代碼塊,不對其它#elif表達式進行測試。否則,順序測試下一塊。

#ifdef、#ifndef

條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示“如果有定義”及“如果無定義”。
#ifdef與#ifndef可以用於#if、#else,#elif語句中,但必須與一個#endif。

點擊查看代碼
#include<iostream>
#include<cstdlib>
using namespace std;
#define MAX 91
int main(){
    #ifdef MAX
        cout<<"Hello! MAX"<<endl;
    #else
        cout<<"Where is MAX?"<<endl;
    #endif
    #ifndef LEO
        cout<<"LEO is not defined."<<endl;
    #endif return 0;
    system("pause");
}

#undef

取消其后那個前面已定義過有宏名定義。一般形式為:#undef macroname

#line

  1. #line 用於強制指定新的行號和編譯文件名,並對源程序的代碼重新編號。
  2. 用法:#line number [newFilename] //newFilename可選
  3. #line 編譯指示字的本質是重定義__LINE__和__FILE__
點擊查看代碼
#include <stdio.h>
#include<cstdlib>
//作者 A 寫的代碼
//--------------------------開始--------------------------
//把 line 的下一行定義為第 1 行,文件名為“a.c”
#line 1 "a.c"
//--------------------------結束--------------------------
//作者 B 寫的代碼
//--------------------------開始--------------------------
//把 line 的下一行定義為第 1 行,文件名為“b.c”
#line 1 "b.c"
//--------------------------結束--------------------------
//作者 C 寫的代碼
//--------------------------開始--------------------------
#line 1 "MyCode.c"
int main(){
    printf("%s:%d\n",__FILE__,__LINE__);
    #line 1 "Test.c"
    printf("%s:%d\n",__FILE__,__LINE__);
    system("pause");
    return 0;
}

運行結果:

MyCode.c:2
Test.c:1

#pragma

(1)#pragma 用於指示編譯器完成一些特定的動作
(2)#pragma 所定義的很多指示字是編譯器特有的,在不同的編譯器間是不可移植的
①預處理器將忽略它不認識的#pragma 指令

②不同編譯器可能以不同的方式解釋同一條#pragma 指令

(3)一般用法:#pragma parameter //注意,不同的 parameter 參數語法和意義不同


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM