我們在寫C語言程序時經(jīng)常使用庫函數(shù)之前,應(yīng)該用#include
引入對應(yīng)的頭文件。這種以#
號開頭的命令稱為預(yù)處理命令。但是你對C語言的預(yù)處理了解多少呢?快來跟著斌哥一起學(xué)習(xí)一下C語言中的預(yù)處理吧!
一、預(yù)處理是什么?
預(yù)處理指令是以#
號開頭的代碼行。#
號必須是該行除了任何空白字符外的第一個字符。#
后是指令關(guān)鍵字,在關(guān)鍵字和#
號之間允許存在任意個數(shù)的空白字符。整行語句構(gòu)成了一條預(yù)處理指令,該指令將在編譯器進(jìn)行編譯之前對源代碼做某些轉(zhuǎn)換。下面是部分預(yù)處理指令:
還有下列幾種預(yù)處理宏(是雙下劃線)
__LINE__ 表示正在編譯的文件的行號
__FILE__表示正在編譯的文件的名字__DATE__表示編譯時刻的日期字符串
__TIME__ 表示編譯時刻的時間字符串
__STDC__ 判斷該文件是不是定義成標(biāo)準(zhǔn) C 程序
二、預(yù)處理有什么用?
在集成開發(fā)環(huán)境中,編譯,鏈接是同時完成的。其實(shí),C語言編譯器在對源代碼編譯之前,還需要進(jìn)一步的處理:預(yù)編譯。
所以,完整的步驟是:預(yù)編譯 -> 編譯 -> 鏈接
預(yù)編譯的主要作用如下:
1.將源文件中以”include”格式包含的文件復(fù)制到編譯的源文件中。
2.用實(shí)際值替換用“#define”定義的字符串。
3.根據(jù)“#if”后面的條件決定需要編譯的代碼。
預(yù)處理是C語言的一個重要功能,由預(yù)處理程序完成。當(dāng)對一個源文件進(jìn)行編譯時,系統(tǒng)將自動調(diào)用預(yù)處理程序?qū)υ闯绦蛑械念A(yù)處理部分作處理,處理完畢自動進(jìn)入對源程序的編譯。
預(yù)處理的行為是由指令控制的。這些指令是由#字符開頭的一些命令。
#define指令定義了一個宏---用來代表其他東西的一個命令,通常是某一個類型的常量。預(yù)處理會通過將宏的名字和它的定義存儲在一起來響應(yīng)#define指令。當(dāng)這個宏在后面的程序中使用到時,預(yù)處理器”擴(kuò)展”了宏,將宏替換為它所定義的值。例如:下面這行命令:
#include指令告訴預(yù)處理器打開一個特定的文件,將它的內(nèi)容作為正在編譯的文件的一部分“包含”進(jìn)來。例如:下面這行命令:
指示預(yù)處理器打開一個名字為stdio.h的文件,并將它的內(nèi)容加到當(dāng)前的程序中。
預(yù)處理器的輸入是一個C語言程序,程序可能包含指令。預(yù)處理器會執(zhí)行這些指令,并在處理過程中刪除這些指令。預(yù)處理器的輸出是另外一個程序:原程序的一個編輯后的版本,不再包含指令。預(yù)處理器的輸出被直接交給編譯器,編譯器檢查程序是否有錯誤,并經(jīng)程序翻譯為目標(biāo)代碼。
三、3種預(yù)處理詳解
1、宏定義指令
宏定義了一個代表特定內(nèi)容的標(biāo)識符。預(yù)處理過程會把源代碼中出現(xiàn)的宏標(biāo)識符替換成宏定義時的值。宏最常見的用法是定義代表某個值的全局符號。宏的第二種用 法是定義帶參數(shù)的宏(宏函數(shù)),這樣的宏可以象函數(shù)一樣被調(diào)用,但它是在調(diào)用語句處展開宏,并用調(diào)用時的實(shí)際參數(shù)來代替定義中的形式參數(shù)。
1.1 #define指令
1.1.1 #define預(yù)處理指令用來定義宏。該指令最簡單的格式是:聲明一個標(biāo)識符,給出這個標(biāo)識符代表的代碼(比如像圓周率這樣的數(shù))。在后面的源代碼中,我們就可以使用定義的宏取代要使用的代碼,代碼舉例:
#define PI 3.141592654
1.1.2 使用宏的好處有兩點(diǎn)
一是使用方便。如下:
#define PI 3.1415926
PI顯然比3.1415926寫著方便。
二是定義的宏有了意義,可讀性強(qiáng)。如例1,MAX_NUM,望文生意便知是最大數(shù)量的意思,比單純使用10這個數(shù)字可讀性要強(qiáng)的多。
三是容易修改。如例1,如果在程序中有幾十次會使用到MAX_NUM,修改只需要在宏定義里面修改一次就可以,否則你會修改到崩潰。
2、條件編譯指令
程序員可以通過定義不同的宏來決定編譯程序?qū)δ男┐a進(jìn)行處理。條件編譯指令將決定哪些代碼被編譯,而哪些是不被編譯的??梢愿鶕?jù)表達(dá)式的值或者某個特定的宏是否被定義來確定編譯條件。
2.1 #if/#endif/#else/#elif指令
#if指令檢測跟在制造另關(guān)鍵字后的常量表達(dá)式。如果表達(dá)式為真,則編譯后面的代碼,直到出現(xiàn)#else、#elif或#endif為止;否則就不編譯。
#endif用于終止#if預(yù)處理指令。
#else指令用于某個#if指令之后,當(dāng)前面的
#if指令的條件不為真時,就編譯
#else后面的代碼。
代碼舉例
#define DEBUG //此時#ifdef DEBUG為真
//#define DEBUG 0 //此時為假
int main()
{
#ifdef DEBUG
printf("Debugging\\n");
#else
printf("Not debugging\\n");
#endif
printf("Running\\n");
return 0;
}
這樣我們就可以實(shí)現(xiàn)debug功能,每次要輸出調(diào)試信息前,只需要#ifdef DEBUG判斷一次。不需要了就在文件開始定義#define DEBUG 0
#elif預(yù)處理指令綜合了#else和#if指令的作用。
3、頭文件包含指令
采用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因?yàn)樵谛枰玫竭@些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復(fù)一遍。預(yù)編譯程序?qū)杨^文件中的定義統(tǒng)統(tǒng)都加入到它所產(chǎn)生的輸出文件中,以供編譯程序?qū)χM(jìn)行處理。
#include預(yù)處理指令的作用是在指令處展開被包含的文件。包含可以是多重的,也就是說一個被包含的文件中還可以包含其他文件。標(biāo)準(zhǔn)C編譯器至少支持八重嵌套包含。預(yù)處理過程不檢查在轉(zhuǎn)換單元中是否已經(jīng)包含了某個文件并阻止對它的多次包含,這個的處理辦法上面已經(jīng)給出。
在程序中包含頭文件有兩種格式:
#include
#include "my.h"
第一種方法是用尖括號把頭文件括起來。這種格式告訴預(yù)處理程序在編譯器自帶的或外部庫的頭文件中搜索被包含的頭文件。第二種方法是用雙引號把頭文件括起 來。這種格式告訴預(yù)處理程序在當(dāng)前被編譯的應(yīng)用程序的源代碼文件中搜索被包含的頭文件,如果找不到,再搜索編譯器自帶的頭文件。
采用兩種不同包含格式的理由在于,編譯器是安裝在公共子目錄下的,而被編譯的應(yīng)用程序是在它們自己的私有子目錄下的。一個應(yīng)用程序既包含編譯器提供的公共 頭文件,也包含自定義的私有頭文件。采用兩種不同的包含格式使得編譯器能夠在很多頭文件中區(qū)別出一組公共的頭文件。
四、小結(jié)
預(yù)編譯程序所完成的基本上是對源程序的“替代”工作。經(jīng)過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經(jīng)過預(yù)處理的源文件是相同的,但內(nèi)容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機(jī)器指令。
-
C語言
+關(guān)注
關(guān)注
180文章
7631瀏覽量
141117 -
命令
+關(guān)注
關(guān)注
5文章
736瀏覽量
22807 -
庫函數(shù)
+關(guān)注
關(guān)注
0文章
177瀏覽量
34358
發(fā)布評論請先 登錄
c語言預(yù)處理命令以什么開頭
LED流水燈C語言常用預(yù)處理命令
基于51單片機(jī)--C語言之預(yù)處理總結(jié)
C語言常用的預(yù)處理命令和循環(huán)左移右移函數(shù)的詳細(xì)資料概述
LED流水燈開發(fā)教程之C語言常用預(yù)處理命令和循環(huán)左移右移函數(shù)資料概述

C語言程序設(shè)計(jì)教程之預(yù)處理命令的詳細(xì)資料說明

8051單片機(jī)的預(yù)處理命令的詳細(xì)資料說明

宏和函數(shù)到底有什么區(qū)別
C語言預(yù)處理命令的分類和工作原理詳細(xì)說明

評論