C 語(yǔ)言學(xué)習(xí)(2) ---- C/C++ 語(yǔ)言中的預(yù)處理

C語(yǔ)言預(yù)處理功能概要

功能 說明
宏定義 #define均唉,#undef
文件包含 #include
條件編譯 #ifdef钧大,#ifndef朽褪,#if辱挥,#elif犁嗅,#if definedxxx,#else般贼,#endif
編譯信息和警告 #pragma message("message")愧哟,#pragma warning,#error
文件名和行信息 #line
標(biāo)識(shí)符連接 x##8哼蛆,將變量轉(zhuǎn)換為字符串
ANSI_C定義的C語(yǔ)言預(yù)處理指令

預(yù)處理名稱以及對(duì)應(yīng)的含義

功能 說明
#define蕊梧,#undef 宏定義,撤銷已經(jīng)定義的宏名稱
#include 使編譯程序的另一源文件嵌入到帶有#include 的源代碼中
#if #else #endif 如果#if 后面的常量表達(dá)式為true,則編譯它與#endif之間的代碼腮介,否則跳過這些代碼
#if #elif else #endif 表示如果有定義和如果沒有定義肥矢,是條件編譯的另一種方法
#ifdef #endif 同上
#error 編譯程序的時(shí)候,遇到#error 就會(huì)產(chǎn)生一個(gè)編譯錯(cuò)誤信息叠洗,并且停止編譯
#pragma 可以設(shè)定編譯程序完成一系列的動(dòng)作
#/## 字符串轉(zhuǎn)換和標(biāo)志符連接
宏定義

宏(Macro)甘改,是一種批量處理的稱謂,計(jì)算機(jī)科學(xué)里的宏是一種抽象灭抑,它根據(jù)一系列預(yù)定義的規(guī)則替換一定的文本模式
宏定義又稱為宏代換十艾、宏替換,簡(jiǎn)稱“宏”腾节,宏定義是在編譯預(yù)處理階段展開進(jìn)行替換的忘嫉。
編譯器預(yù)定義宏

_LINE_  編譯文件的行號(hào)字符串
_DATE_  編譯時(shí)刻日期字符串
_FILE_   編譯文件名稱
_TIME_ 編譯文件時(shí)間字符串
_STDC_ 判斷文件是不是定義成標(biāo)準(zhǔn)C
注意點(diǎn):宏定義字符串不需要雙引號(hào)

#define PATH "C:\English\demo" 錯(cuò)誤
#define PATH C:\English\demo 正確

注意點(diǎn):宏定義中要添加括號(hào)

NA

注意點(diǎn):. 宏定義常量的時(shí)候注意后綴

#defien SEC_A_YEAR (60*60*24*365) 錯(cuò)誤
#defien SEC_A_YEAR (60*60*24*365)UL 正確

注意點(diǎn): 宏定義函數(shù)每行必須加上連接符
#define swap(x, y)\
x = x + y;\
y = x - y;\
x = x - y;
或者
#define MALLOC(n, type) \
  ( (type *) malloc((n)* sizeof(type)))
條件編譯

條件編譯的功能是使得我們可以按照不同的條件去編譯不同的程序部分案腺,因而產(chǎn)生不同的目標(biāo)代碼文件庆冕,對(duì)程序的移植和調(diào)試都很有用

  • 形式一
    #ifdef 標(biāo)識(shí)符
    #endif

  • 形式二
    #ifdef 標(biāo)識(shí)符
    #else
    #endif

  • 形式三
    #ifndef 標(biāo)識(shí)符
    #else
    #endif

  • 形式四
    #if 常量表達(dá)式
    程序段1
    #else
    程序段
    #endif
    如果常量表達(dá)式的值為真,則進(jìn)行程序段1的編譯劈榨,否則進(jìn)行程序段2 的編譯

實(shí)例:

    #if (demo_a == true)
    //#if (demo_a)
        MI_PRINT("demoa == true \n");
    #else
        MI_PRINT("demoa != true \n");
    #endif
    #if (demo_c == 1)
        MI_PRINT("demo_C = 1 \n");
    #elif (demo_c == 2)
        MI_PRINT("demo_C = 2 \n");
    #elif (demo_c == 3)
        MI_PRINT("demo_C = 3\n");
        #error this is my error
    #elif (demo_c == 4)
        MI_PRINT("demo_C = 4\n");
        #error this is my error
    #endif
  • 形式五
    #if defined XXX_XXX
    #endif 是條件編譯访递,是根據(jù)你是否定義了XXX_XXX這個(gè)宏,而使用不同的代碼同辣。

#if !defined XXX_XXX
#define XXX_XXX
#endif 是為了避免.h頭文件被重復(fù)include拷姿。

文件包含

文件包含是預(yù)處理的一個(gè)重要功能惭载,它將多個(gè)源文件鏈接成一個(gè)源文件進(jìn)行編譯,結(jié)果生成一個(gè)目標(biāo)文件跌前,C語(yǔ)言提供#include命令來(lái)實(shí)現(xiàn)文件包含的操作棕兼,它實(shí)際是宏替換的延伸。

  • 格式1
    #include <filename>
    預(yù)處理到系統(tǒng)規(guī)定的路徑去獲取這個(gè)文件抵乓,找到文件后伴挚,用文件內(nèi)容替換該語(yǔ)句。
  • 格式2
    #include “filename”
    標(biāo)識(shí)在當(dāng)前目錄中查找文件名為filename 的文件灾炭,如果沒有找到茎芋,則安裝系統(tǒng)指定的路徑去搜索其他目錄,找到文件后蜈出,用文件內(nèi)容替換該語(yǔ)句田弥。

#include也是支持相對(duì)路徑的,格式如下
. 代表當(dāng)前路徑
.. 代表上一級(jí)目錄

預(yù)處理
  • #error message
    編譯程序的時(shí)候铡原,只要遇到#error 就會(huì)生成一個(gè)編譯錯(cuò)誤提示消息偷厦,并且停止編譯
    #error 編譯器錯(cuò)誤 (不需要加引號(hào))
  • #pragma 消息文本
    比如:
    #pragma message("now we run into this \n")
    在編譯就會(huì)在編譯log 中打印上面的文本
    這個(gè)命令可以幫助我們判斷編譯的流程
    #ifndef BIONIC
    #pragma message("not define bionic \n")
    #endif

  • #pragma once
    頭文件中加入這條指令就可以保證頭文件被編譯一次,防止重復(fù)包含燕刻。

#pragma resource
#pragma resource “*.dfm” 表示把*.dfm 的資源都加入工程只泼。

  • #pragma comment
    #pragma comment(…) 用于將一個(gè)注釋記錄放入對(duì)象文件或者可執(zhí)行文件中。

  • #pragma comment(lib, “user32.lib”)
    上面的指令用于將 user32.lib 放入工程中卵洗。

  • #pragma warning
    常用:
    #pragma warning(disable:4507 34) 不顯示4507 和34 號(hào)警告
    #pragma warning(once:4385) 4385號(hào)警告信息僅僅報(bào)告一次
    #pragma warning(error:164) 將164 號(hào)警告作為一個(gè)錯(cuò)誤

  • #pragma code_seg
    #pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )

例如:
//默認(rèn)情況下,函數(shù)被存放在.text節(jié)中
void func1() { // stored in .text
}
//將函數(shù)存放在.my_data1節(jié)中
#pragma code_seg(".my_data1")
void func2() { // stored in my_data1
}

  • #與##
    # 可以將語(yǔ)言符號(hào)轉(zhuǎn)換為字符串
    #define STRING(x) #x STRING(1+1) 相當(dāng)于變成了 “1+1” 字符串

## 用于將前后的字符串連接起來(lái)
比如定義:
#define XNAME(n) x##n
XNAME(8) 等同于 x8

示例代碼

//標(biāo)記前使用“#”特殊符號(hào)將其轉(zhuǎn)換為字符串的標(biāo)記
#define GET_STRING(n) #n
//## 用于將兩個(gè)標(biāo)志符用字符串的方式連接
#define CONNECT(a, b) a##b
//多行的宏要用連接符連接 最后一行不需要使用
#define MACRO(n, limit) while (n < limit) \
{ \
    printf("minger "); \
    n++; \
}

//...表示所有剩下的參數(shù)请唱,__VA_ARGS__被宏定義中的...參數(shù)所替換。
//這在c語(yǔ)言的GNU擴(kuò)展語(yǔ)法里是一個(gè)特殊規(guī)則:當(dāng)__VA_ARGS__為空時(shí)过蹂,會(huì)消除前面這個(gè)逗號(hào)
#ifndef debugPrintf
#define debugPrintf(...) printf("DEBUG: " __VA_ARGS__);
#else
#define debugPrintf(...)
#endif

cdefineDemo::cdefineDemo() {
    auto printDemo = [](string& s)->void {
        cout << " printDemo " << s << endl;
    };


    cout << "cdefineDemo start..." << endl;
    cout << "GET_STRING:" << GET_STRING(this is my string) << endl;;
    cout << "COONECT A B: " << CONNECT(12,34) << endl;

    string p = "stringA";
    CONNECT(print, Demo)(p); // using connect as function name 

    debugPrintf("demo printf %s",p.c_str());
}
Review History
日期 說明
2022/10/31 修改部分格式
NA NA
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末十绑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子酷勺,更是在濱河造成了極大的恐慌本橙,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脆诉,死亡現(xiàn)場(chǎng)離奇詭異勋功,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)库说,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)片择,“玉大人潜的,你說我怎么就攤上這事∽止埽” “怎么了啰挪?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵信不,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我亡呵,道長(zhǎng)抽活,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任锰什,我火速辦了婚禮下硕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘汁胆。我一直安慰自己梭姓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布嫩码。 她就那樣靜靜地躺著誉尖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铸题。 梳的紋絲不亂的頭發(fā)上铡恕,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音丢间,去河邊找鬼探熔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛千劈,可吹牛的內(nèi)容都是我干的祭刚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼墙牌,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涡驮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起喜滨,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捉捅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后虽风,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棒口,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年辜膝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了无牵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厂抖,死狀恐怖茎毁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤七蜘,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布谭溉,位于F島的核電站,受9級(jí)特大地震影響橡卤,放射性物質(zhì)發(fā)生泄漏扮念。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一碧库、第九天 我趴在偏房一處隱蔽的房頂上張望柜与。 院中可真熱鬧,春花似錦谈为、人聲如沸旅挤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粘茄。三九已至,卻和暖如春秕脓,著一層夾襖步出監(jiān)牢的瞬間柒瓣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工吠架, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芙贫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓傍药,卻偏偏與公主長(zhǎng)得像磺平,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拐辽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容