一起來看看C語言的預(yù)處理注意點(diǎn)
C 預(yù)處理器
C 預(yù)處理器不是編譯器的組成部分,但是它是編譯過程中一個單獨(dú)的步驟。簡言之,C 預(yù)處理器只不過是一個文本替換工具而已,它們會指示編譯器在實(shí)際編譯之前完成所需的預(yù)處理。
指令 | 描述 |
---|---|
#define | 定義宏 |
#include | 包含一個源代碼文件 |
#undef | 取消已定義的宏 |
#ifdef | 如果宏已經(jīng)定義,則返回真 |
#ifndef | 如果宏沒有定義,則返回真 |
#if | 如果給定條件為真,則編譯下面代碼 |
#else | #if 的替代方案 |
#elif | 如果前面的 #if 給定條件不為真,當(dāng)前條件為真,則編譯下面代碼 |
#endif | 結(jié)束一個 #if……#else 條件編譯塊 |
#error | 當(dāng)遇到標(biāo)準(zhǔn)錯誤時,輸出錯誤消息 |
#pragma | 使用標(biāo)準(zhǔn)化方法,向編譯器發(fā)布特殊的命令到編譯器中 |
1.取消已定義宏
demo.h文件代碼如下
#ifndef __DEMO_H_ #define __DEMO_H_ #define PAI 3.14 #endif // __DEMO_H_
#include <stdio.h> #include "demo.h" /* 在 #include 與 main 函數(shù)中間區(qū)域使用#undef來取消以定義的宏,然后重新定義宏 */ #undef PAI #define PAI 33.14 int main() { printf("PAI = %G\n", PAI); } /* 輸出結(jié)果 PAI = 33.14 */
2.使用#ifdef來調(diào)試
#ifdef DEBUG /* 你的調(diào)試代碼 */ #endif // DEBUG
如果定義了 DEBUG,則執(zhí)行處理語句。在編譯時,如果您向 gcc 編譯器傳遞了 -DDEBUG 開關(guān)量,這個指令就非常有用。它定義了 DEBUG,您可以在編譯期間隨時開啟或關(guān)閉調(diào)試。
常用預(yù)定義宏
宏 | 描述 |
---|---|
__DATE__ | 當(dāng)前日期,一個以 “MMM DD YYYY” 格式表示的字符常量。 |
__TIME__ | 當(dāng)前時間,一個以 “HH:MM:SS” 格式表示的字符常量。 |
__FILE__ | 這會包含當(dāng)前文件名,一個字符串常量。 |
__LINE__ | 這會包含當(dāng)前行號,一個十進(jìn)制常量。 |
預(yù)處理器運(yùn)算符
1.宏延續(xù)運(yùn)算符
\
一個宏通常寫在一個單行上。但是如果宏太長,一個單行容納不下,則使用宏延續(xù)運(yùn)算符\
#include <stdio.h> #define PAI \ 3.1415926 int main() { printf("%.8f\n", PAI); }
2.字符串常量化運(yùn)算符#
在宏定義中,當(dāng)需要把一個宏的參數(shù)轉(zhuǎn)換為字符串常量時,則使用字符串常量化運(yùn)算符#
。在宏中使用的該運(yùn)算符有一個特定的參數(shù)或參數(shù)列表。就是把宏的參數(shù)變成字符串。
#include <stdio.h> #define PAI 3.1415926 //字符串常量化 #define CONVERT_TO_STR1(arg) "字符串常量化:" #arg //字符串常量化 #define CONVERT_TO_STR2(arg) CONVERT_TO_STR1(arg) int main() { printf("%s\n", CONVERT_TO_STR1(ABC)); printf("%s\n", CONVERT_TO_STR1(PAI)); printf("%s\n", CONVERT_TO_STR2(PAI)); } /* 輸出結(jié)果 字符串常量化:ABC 字符串常量化:PAI 字符串常量化:3.1415926 */
這里有幾點(diǎn)需要提一下。
1.宏定義中,當(dāng)有多個字符串需要連接時,以空格來隔開每一個字符串即可。
2.當(dāng)需要把一個宏字符串常量化時,需要按照先定義一個宏函數(shù)1,然后再定義一個宏函數(shù)2,然后宏函數(shù)2調(diào)用宏函數(shù)1即可,例如CONVERT_TO_STR2
調(diào)用CONVERT_TO_STR1
3.標(biāo)記粘貼運(yùn)算符##
宏定義內(nèi)的標(biāo)記粘貼運(yùn)算符(##)會合并兩個參數(shù)。它允許在宏定義中兩個獨(dú)立的標(biāo)記被合并為一個標(biāo)記。
#include <stdio.h> #define PRINTF1(arg) printf("var" #arg " = %d\n" , var##arg) int main() { int var1 = 20; PRINTF1(1); }
/*
輸出結(jié)果
var1 = 20
*/
參數(shù)化的宏
使用注意點(diǎn)
用宏定義時,含參數(shù)時,參數(shù)本身要加(),此外,對參數(shù)的操作整體也要加()。
#define MAX(a,b) ((a)>(b)?(a):(b))
使用宏函數(shù)的時候不要使用++
/--
運(yùn)算符
#include <stdio.h> #define MIN(A,B) ((A)<(B)?(A):(B)) int main() { char *p="ghi"; char a; a=MIN(*p++,'f');//不要使用自增/自減運(yùn)算符 printf("%c\n",a); }
/*
輸出結(jié)果
f
*/
另,宏定義實(shí)現(xiàn)指定大小的交換:
#define SWAP(a, b, size) \ unsigned int __size = (size); \ char *__a = (a), *__b = (b); \ do \ { \ char __tmp = *__a; \ *__a++ = *__b; \ *__b++ = __tmp; \ } while (--__size > 0);
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Qt數(shù)據(jù)庫應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)生成器
有兩種應(yīng)用場景需要用到數(shù)據(jù)生成器,一種是需要測試數(shù)據(jù)庫性能,一種是隨機(jī)模擬生成一堆數(shù)據(jù),用來測試程序的性能。本文將利用Qt實(shí)現(xiàn)通用數(shù)據(jù)生成器,需要的可以參考一下2022-02-02C++實(shí)現(xiàn)LeetCode(67.二進(jìn)制數(shù)相加)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(67.二進(jìn)制數(shù)相加),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例
今天小編就為大家分享一篇關(guān)于C++11并發(fā)編程關(guān)于原子操作atomic的代碼示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12C語言實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07undefined reference to `SetPduPowerConsumptionCnt''錯誤的解決方法
編譯時出現(xiàn)undefined reference to `SetPduPowerConsumptionCnt'錯誤要如何解決呢?有沒有什么好的解決方法?下面小編就為大家解答吧,如果你也遇到了這種情況,可以過來參考下2013-07-07C++動態(tài)內(nèi)存分配(new/new[]和delete/delete[])詳解
這篇文章主要介紹了C++動態(tài)內(nèi)存分配(new/new[]和delete/delete[])詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05