C语言预处理命令
我們經(jīng)常使用#include命令。使用庫(kù)函數(shù)之前,應(yīng)該用#include引入對(duì)應(yīng)的頭文件。這種以#號(hào)開(kāi)頭的命令稱(chēng)為預(yù)處理命令。
C語(yǔ)言源文件要經(jīng)過(guò)編譯、鏈接才能生成可執(zhí)行程序:
1 . 編譯(Compile)會(huì)將源文件(.c文件)轉(zhuǎn)換為目標(biāo)文件。對(duì)于 VC/VS,目標(biāo)文件后綴為.obj;對(duì)于GCC,目標(biāo)文件后綴為.o。
2 . 鏈接(Link)是針對(duì)多個(gè)文件的,它會(huì)將編譯生成的多個(gè)目標(biāo)文件以及系統(tǒng)中的庫(kù)、組件等合并成一個(gè)可執(zhí)行程序。
在實(shí)際開(kāi)發(fā)中,有時(shí)候在編譯之前還需要對(duì)源文件進(jìn)行簡(jiǎn)單的處理。例如,我們希望自己的程序在 Windows 和 Linux 下都能夠運(yùn)行,那么就要在 Windows 下使用 VS 編譯一遍,然后在 Linux 下使用 GCC 編譯一遍。但是現(xiàn)在有個(gè)問(wèn)題,程序中要實(shí)現(xiàn)的某個(gè)功能在 VS 和 GCC 下使用的函數(shù)不同(假設(shè) VS 下使用 a(),GCC 下使用 b()),VS 下的函數(shù)在 GCC 下不能編譯通過(guò),GCC 下的函數(shù)在 VS 下也不能編譯通過(guò),怎么辦呢?
這就需要在編譯之前先對(duì)源文件進(jìn)行處理:如果檢測(cè)到是 VS,就保留 a() 刪除 b();如果檢測(cè)到是 GCC,就保留 b() 刪除 a()。
這些在編譯之前對(duì)源文件進(jìn)行簡(jiǎn)單加工的過(guò)程,就稱(chēng)為預(yù)處理(即預(yù)先處理、提前處理)。
預(yù)處理主要是處理以#開(kāi)頭的命令,例如#include <stdio.h>等。預(yù)處理命令要放在所有函數(shù)之外,而且一般都放在源文件的前面。
預(yù)處理是C語(yǔ)言的一個(gè)重要功能,由預(yù)處理程序完成。當(dāng)對(duì)一個(gè)源文件進(jìn)行編譯時(shí),系統(tǒng)將自動(dòng)調(diào)用預(yù)處理程序?qū)υ闯绦蛑械念A(yù)處理部分作處理,處理完畢自動(dòng)進(jìn)入對(duì)源程序的編譯。
編譯器會(huì)將預(yù)處理的結(jié)果保存到和源文件同名的.i文件中,例如 main.c 的預(yù)處理結(jié)果在 main.i 中。和.c一樣,.i也是文本文件,可以用編輯器打開(kāi)直接查看內(nèi)容。
示例
我們舉例來(lái)說(shuō)明預(yù)處理命令的實(shí)際用途。假如現(xiàn)在要開(kāi)發(fā)一個(gè)C語(yǔ)言程序,讓它暫停 5 秒以后再輸出內(nèi)容,并且要求跨平臺(tái),在 Windows 和 Linux 下都能運(yùn)行,怎么辦呢?
這個(gè)程序的難點(diǎn)在于,不同平臺(tái)下的暫停函數(shù)和頭文件都不一樣:
Windows 平臺(tái)下的暫停函數(shù)的原型是void Sleep(DWORD dwMilliseconds)(注意 S 是大寫(xiě)的),參數(shù)的單位是“毫秒”,位于 <windows.h> 頭文件。Linux 平臺(tái)下暫停函數(shù)的原型是unsigned int sleep (unsigned int seconds),參數(shù)的單位是“秒”,位于 <unistd.h> 頭文件。不同的平臺(tái)下必須調(diào)用不同的函數(shù),并引入不同的頭文件,否則就會(huì)導(dǎo)致編譯錯(cuò)誤,因?yàn)?Windows 平臺(tái)下沒(méi)有 sleep() 函數(shù),也沒(méi)有 <unistd.h> 頭文件,反之亦然。這就要求我們?cè)诰幾g之前,也就是預(yù)處理階段來(lái)解決這個(gè)問(wèn)題。
示例
#include <stdio.h>//不同的平臺(tái)下引入不同的頭文件 #if _WIN32 //識(shí)別windows平臺(tái) #include <windows.h> #elif __linux__ //識(shí)別linux平臺(tái) #include <unistd.h> #endifint main() {//不同的平臺(tái)下調(diào)用不同的函數(shù)#if _WIN32 //識(shí)別windows平臺(tái)Sleep(5000);#elif __linux__ //識(shí)別linux平臺(tái)sleep(5);#endifputs("http://www.baidu.com/");return 0; }#if、#elif、#endif 就是預(yù)處理命令,它們都是在編譯之前由預(yù)處理程序來(lái)執(zhí)行的。
對(duì)于 Windows 平臺(tái),預(yù)處理以后的代碼變成:
#include <stdio.h> #include <windows.h>int main() {Sleep(5000);puts("http://www.baidu.com/");return 0; }對(duì)于 Linux 平臺(tái),預(yù)處理以后的代碼變成:
#include <stdio.h> #include <unistd.h>int main() {sleep(5);puts("http://www.baidu.com/");return 0; }如上所示,在不同的平臺(tái)下,編譯之前(預(yù)處理之后)的源代碼都是不一樣的。這就是預(yù)處理階段的工作,它把代碼當(dāng)成普通文本,根據(jù)設(shè)定的條件進(jìn)行一些簡(jiǎn)單的文本替換,將替換以后的結(jié)果再交給編譯器處理。
如果感覺(jué)不錯(cuò)的話(huà)請(qǐng)點(diǎn)贊喲!!!
總結(jié)
- 上一篇: Spring Boot 后台验证 Hib
- 下一篇: Java this关键字详解