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 |