日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言——预编译

發(fā)布時(shí)間:2023/12/20 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言——预编译 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C語言——預(yù)編譯


宗旨:技術(shù)的學(xué)習(xí)是有限的,分享的精神是無限的。


? ? ? ? 在C 語言中,并沒有任何內(nèi)在的機(jī)制來完成如下一些功能:在編譯時(shí)包含其他源文件、定義宏、根據(jù)條件決定編譯時(shí)是否包含某些代碼。要完成這些工作,就需要使用預(yù)處理程序。盡管在目前絕大多數(shù)編譯器都包含了預(yù)處理程序,但通常認(rèn)為它們是獨(dú)立于編譯器的。預(yù)處理過程讀入源代碼,檢查包含預(yù)處理指令的語句和宏定義,并對(duì)源代碼進(jìn)行響應(yīng)的轉(zhuǎn)換。預(yù)處理過程還會(huì)刪除程序中的注釋和多余的空白字符。

?????? 預(yù)處理指令是以#號(hào)開頭的代碼行。#號(hào)必須是該行除了任何空白字符外的第一個(gè)字符。#后是指令關(guān)鍵字,在關(guān)鍵字和#號(hào)之間允許存在任意個(gè)數(shù)的空白字符。整行語句構(gòu)成了一條預(yù)處理指令,該指令將在編譯器進(jìn)行編譯之前對(duì)源代碼做某些轉(zhuǎn)換。下面是部分預(yù)處理指令:

??????????指令??????????????用途
??????????#??????????????????
空指令,無任何效果
?????????#include??????
包含一個(gè)源代碼文件
?????????#define????????
定義宏
?????????#undef?????????
取消已定義的宏
?????????#if???????????????
如果給定條件為真,則編譯下面代碼
?????????#ifdef??????????
如果宏已經(jīng)定義,則編譯下面代碼
?????????#ifndef????????
如果宏沒有定義,則編譯下面代碼
?????????#elif?????? ??
如果前面的#if給定條件不為真,當(dāng)前條件為真,則編譯下面代碼
?????????#endif?????????
結(jié)束一個(gè)#if……#else條件編譯塊
?????????#error????????
停止編譯并顯示錯(cuò)誤信息

??一、文件包含
????????#include預(yù)處理指令的作用是在指令處展開被包含的文件。包含可以是多重的,也就是說一個(gè)被包含的文件中還可以包含其他文件。標(biāo)準(zhǔn)C編譯器至少支持八重嵌套包含。
????????預(yù)處理過程不檢查在轉(zhuǎn)換單元中是否已經(jīng)包含了某個(gè)文件并阻止對(duì)它的多次包含。這樣就可以在多次包含同一個(gè)頭文件時(shí),通過給定編譯時(shí)的條件來達(dá)到不同的效果。例如:

????????#defineAAA
????????#include "t.c"
????????#undef AAA
????????#include "t.c"

????????為了避免那些只能包含一次的頭文件被多次包含,可以在頭文件中用編譯時(shí)條件來進(jìn)行控制。例如:???????
????????#ifndef_OS_H_
????????#define _OS_H_
??????????……
????????#endif /* _OS_H_ */

????????在程序中包含頭文件有兩種格式:
????????#include
????????#include "os.h"
?????????第一種方法是用尖括號(hào)把頭文件括起來。這種格式告訴預(yù)處理程序在編譯器自帶的或外部庫的頭文件中搜索被包含的頭文件。第二種方法是用雙引號(hào)把頭文件括起來。這種格式告訴預(yù)處理程序在當(dāng)前被編譯的應(yīng)用程序的源代碼文件中搜索被包含的頭文件,如果找不到,再搜索編譯器自帶的頭文件。

二、宏
????????宏定義了一個(gè)代表特定內(nèi)容的標(biāo)識(shí)符。預(yù)處理過程會(huì)把源代碼中出現(xiàn)的宏標(biāo)識(shí)符替換成宏定義時(shí)的值。宏最常見的用法是定義代表某個(gè)值的全局符號(hào)。宏的第二種用法是定義帶參數(shù)的宏,這樣的宏可以象函數(shù)一樣被調(diào)用,但它是在調(diào)用語句處展開宏,并用調(diào)用時(shí)的實(shí)際參數(shù)來代替定義中的形式參數(shù)。

?1.#define指令
????????#define預(yù)處理指令是用來定義宏的。該指令最簡(jiǎn)單的格式是:首先神明一個(gè)標(biāo)識(shí)符,然后給出這個(gè)標(biāo)識(shí)符代表的代碼。在后面的源代碼中,就用這些代碼來替代該標(biāo)識(shí)符。
宏表示的值可以是一個(gè)常量表達(dá)式,其中允許包括前面已經(jīng)定義的宏標(biāo)識(shí)符。例如:
???????#define ONE 1
???????#define TWO 2
???????#define THREE (ONE+TWO)
????????注意上面的宏定義使用了括號(hào)。盡管它們并不是必須的。但出于謹(jǐn)慎考慮,還是應(yīng)該加上括號(hào)的。

?

2.#運(yùn)算符
????????出現(xiàn)在宏定義中的#運(yùn)算符把跟在其后的參數(shù)轉(zhuǎn)換成一個(gè)字符串。有時(shí)把這種用法的#稱為字符串化運(yùn)算符。例如:

#definePASTE(n) "adhfkj"#nint main(void) {printf("%s\n", PASTE(15));return 0; }

? ? ? ? 宏定義中的#運(yùn)算符告訴預(yù)處理程序,把源代碼中任何傳遞給該宏的參數(shù)轉(zhuǎn)換成一個(gè)字符串。所以輸出應(yīng)該是adhfkj15。


3.##運(yùn)算符
????????##運(yùn)算符用于把參數(shù)連接到一起。預(yù)處理程序把出現(xiàn)在##兩側(cè)的參數(shù)合并成一個(gè)符號(hào)。看下面的例子:

#defineNUM(a,b,c) a##b##c #defineSTR(a,b,c) a##b##cint main(void) {printf("%d\n", NUM(1, 2, 3));printf("%s\n", STR("aa", "bb", "cc"));return 0; } //最后程序的輸出為: 123 aabbcc

?

三、條件編譯指令
????條件編譯指令將決定那些代碼被編譯,而哪些是不被編譯的。可以根據(jù)表達(dá)式的值或者某個(gè)特定的宏是否被定義來確定編譯條件。
1.#if指令
????????#if指令檢測(cè)跟在制造另關(guān)鍵字后的常量表達(dá)式。如果表達(dá)式為真,則編譯后面的代碼,知道出現(xiàn)#else、#elif或#endif為止;否則就不編譯。

????????如果要屏蔽一段代碼,建議使用 [ #if 0?... ?#endif ]

2.#endif指令
????????#endif用于終止#if預(yù)處理指令。

#define DEBUG 0 int main(void) { #if DEBUGprintf("Debugging\n"); #endifprintf("Running\n");return 0; }

? ? ? ? 由于程序定義DEBUG宏代表0,所以#if條件為假,不編譯后面的代碼直到#endif,所以程序直接輸出Running。
????????如果去掉#define語句,效果是一樣的。

?

3.#ifdef#ifndef

#define DEBUGint main(void) { #ifdef DEBUGprintf("yes\n"); #endif #ifndef DEBUGprintf("no\n"); #endifreturn 0; }

? ? ? ? #if defined等價(jià)于#ifdef; #if !defined等價(jià)于#ifndef


4.#else指令
????????#else指令用于某個(gè)#if指令之后,當(dāng)前面的#if指令的條件不為真時(shí),就編譯#else后面的代碼。#endif指令將中指上面的條件塊。

#define DEBUGint main(void) { #ifdef DEBUGprintf("Debugging\n"); #elseprintf("Notdebugging\n"); #endifprintf("Running\n");return 0; }


5.#elif指令
????????#elif預(yù)處理指令綜合了#else和#if指令的作用。

#define TWOint main(void) { #ifdef ONEprintf("1\n"); #elif defined TWOprintf("2\n"); #elseprintf("3\n"); #endifreturn 0; }

? ? ? ? 程序很好理解,最后輸出結(jié)果是2。

?6.其他一些標(biāo)準(zhǔn)指令
????????#error指令將使編譯器顯示一條錯(cuò)誤信息,然后停止編譯。
????????#line指令可以改變編譯器用來指出警告和錯(cuò)誤信息的文件號(hào)和行號(hào)。
????????#pragma指令沒有正式的定義。編譯器可以自定義其用途。典型的用法是禁止或允許某些煩人的警告信息。

#ifndef _OPTION_H_ #define _OPTION_H_typedef enum {OPTION_DEV_ID = 0,OPTION_SERVER_IP = 1,OPTION_SMALL_IMAGE_PORT = 2,OPTION_LARGE_IMAGE_PORT = 3,OPTION_GPS_PORT = 4,OPTION_SERVER_NAME = 5, } option_id_t;typedef __packed union {uint8_tdev_id[SETTING_DEV_ID_MAX_LENGTH]; //設(shè)備號(hào)char server_name[SETTING_SERVER_NAME_MAX_LENGTH]; } option_data_t;typedef __packed struct {uint8_t id;uint8_t length;option_data_t data; } option_item_t;void OptionInit(void);#endif /* _OPTION_H_ */

總結(jié)

以上是生活随笔為你收集整理的C语言——预编译的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。