預處理指令用法詳解(C語言)-天天快播報
前言
使編譯器執行預處理操作的代碼被稱為預處理指令,本文介紹常見的預處理指令的實際用法。
(資料圖片)
一、預處理符號
預處理符號是C語言內置的符號,是可以直接使用的。
其中,若遵頊ANSI C,則__STDC__
為1,否則未定義。
二、#define
1)定義標識符
#define可以用來定義標識符,其語法為:#define name stuff
,經過預處理后,stuff
會被直接替換為·name
。
若stuff
的內若過長,可在句末加上\
續行符號,像這樣:
#include#define Piccaso "Pablo,Diego,José\Francisco,de,Paula,Juan,Nepomuceno\,María,de,los,Remedios,Cipriano,de\,la,Santísima,Trinidad,Ruiz,y,Picasso"int main(){printf("%s", Piccaso);return 0;}
示例1:數值替換
int main(){int a = 100;return 0;}
示例2:循環替換
#includeint main(){while(1){printf("A");}return 0;}
運行代碼,將會在屏幕上死循環地打印A
。
示例3:分支替換
int main(){int input = 0;switch (input){case 1:break; case 2:break; case 3:}return 0;}
2)宏定義
#define允許有參數的文本替換,這種操作通常稱為宏,其語法為:#define name(list) stuff
,其中,list
是由逗號隔開的符號表,符號有可能出現在stuff
中。
示例1:
int main(){printf("%d", 5+5);return 0;}
示例2:
int main(){printf("%d", 10*double(5+1));return 0;}
因為#define
的功能只是替換,若要利用宏定義實現快捷的函數操作,最好的方法是在宏定義時多加括號,以便于達到整體求值的效果,像這樣:#define double(x) (x)+(x)
。
注意:由于宏是直接替換,因此傳參時嚴禁使用自增,自減,傳參時使用,替換后依然會再次執行,會導致不可預測的后果。
3)字符串轉換符
字符串有自動連接的特點,例如運行以下這段代碼:
#includeint main(){printf("123" "456");return 0;}
效果圖:
字符串轉換符#就是利用這個特性,它可以將宏定義中傳入的參數,替換為字符串格式。
#include#define sum(x) printf("the val of "#x" is %d",x)int main(){int a = 10;sum(a);return 0;}
在上述代碼中,#號
將a
直接轉化為字符串,隨后三個字符串拼接在一起。
效果圖:
利用該方法可以只傳參一次實現值和名
同時打印。
4)片段鏈接符
在宏定義時,片段連接符##
可以實現將兩個符號連接在一起,使其成為一個符號,前提是這個合成的符號必須已經被定義。
#include#define double(x) sum##x*=2int main(){int sum1 = 1;int sum2 = 1;int sum3 = 1;double(1);printf("%d %d %d", sum1, sum2, sum3);return 0;}
在上述代碼中,##
會把sum和參數x連接在一起,當我們傳入1經過預處理后,等效于:sum1*=2
。
效果圖:
5)宏定義VS函數
宏定義的優勢:
宏定義的執行速度遠遠超過函數,當執行簡單的計算時,更適合使用宏定義。宏定義傳參時沒有類型檢測,可以將任意的數據傳入。宏定義是直接替換,可以傳入各種各樣的符號,實現許許多多函數做不到的功能。(可以傳入類型、傳入函數、傳入語句等等)宏定義的劣勢:
宏定義不能調試、不能遞歸,因此宏定義只適合做簡單的計算。宏定義是直接替換,因此相鄰操作符的優先級很有可能產生不期望的順序,因此要盡可能帶括號。宏定義傳參沒有類型檢測,因此不夠嚴謹。6)命名公約
以下幾條公約,必須遵守
宏定義的名必須全部大寫。函數名不可以全部大寫。三、#undef#undef
宏定義刪除,可以在函數內部使用!被刪除后的標識就不能再使用了。
四、命令行編譯
指在VScode
或Linux
等用命令行執行編譯的環境下,可以在編譯時對變量進行賦值。
五、條件編譯
在寫程序時,有些代碼是為了查看某個部分是否正確而寫的的調試代碼。
刪除很可惜,但又不想讓其編譯,此時就可以使用選擇性編譯
。
但實質上使用if
語句或直接注釋
會更加方便,但在C語言內置的頭文件中,為了節約時間經常使用條件編譯。
1)常量表達式判斷
#if 常量表達式//...#endif
常量表達式為真,則中間的語句編譯;
常量表達式為假,則中間的語句不編譯。
此外,也可以寫成多分支的表達式條件編譯。
int main(){#if 0printf("111");#elif 1printf("222");#else 0printf("333");#endifreturn 0;}
效果圖:
2)是否定義判斷
判斷某個符號是否被定義,只要被定義,就編譯中間的語句,無論其被定義為什么。
#include#define MAXint main(){#if defined(MAX)//或#ifdef MAXprintf("111");#endifreturn 0;}
或判斷某個符號是否沒定義,沒定義則編譯。
#include#define MAXint main(){#if !defined(MAX)//或#ifndef MAXprintf("111");#endifreturn 0;}
3)嵌套判斷
條件編譯是可以互相嵌套的。
#include#define DEBUG int main(){#ifdef DEBUG#if 1printf("111");#elif 0printf("222");#endif#endif return 0;}
如上述代碼是在是否定義判斷中嵌套常量表達式判斷。
效果圖:
六、頭文件的包含
1)雙引號與尖括號
對于#include
來說,后面的文件有兩種引用方法:
所有的頭文件在包含時都可以使用雙引號,但為了速度和區別位置,建議自己寫的頭文件用雙引號,標準庫中的用尖括號。
2)頭文件的嵌套包含
可以將許許多多的頭文件都包含在一個自己創建的頭文件中,最后只需要在其他的源文件中包含該自己創建的頭文件即可,像這樣:
3)頭文件重復包含解決方法
在寫多人合作的大型項目時,每個程序員可能都要包含一次公用的頭文件,當他們寫的代碼匯總時,這個頭文件可能會被包含多次。
因此,我們使用條件編譯來解決這個問題。
#if !defined(TIME)#define TIME //...//... //在這里實現各種函數//...#endif
假設上述代碼為head.h
,當我們第一次包含head.h
時,由于TIME沒有被定義,因此會定義一個TIME,同時編譯里面的函數。
當我們第二次包含head.h
時,因為TIME被定義過了,即使head.h
里面的內容被拷貝到源文件中,也不會進行編譯,從而加快了速度。
注意:在頭文件開頭加入#pragma once
即可一鍵實現上述效果,不必冗雜的代碼,但僅限于自己寫的頭文件,標準庫的頭文件已經幫你加完了。
感謝您的閱讀與耐心~
標簽: 編程算法
- 預處理指令用法詳解(C語言)-天天快播報
- 環比和同比的區別是什么?與上一年對比叫環比嗎?
- Meta“效率之年”并不高效:裁員傳聞導致規劃和目標混亂-當前聚焦
- 報告:超8成受訪者認為游戲促進AI發展
- 2023年2月13日上期所部分品種“倉單日報”-熱點在線
- 被《王國之淚》致敬?有游戲表示早就做出了組裝載具-世界看點
- 為抵制《霍格沃茨》 LGBTQ+創作者發布游戲捆綁包-當前熱聞
- 信用卡和儲蓄卡的區別是什么?公務卡可以個人消費嗎?
- 信用卡可以取現金嗎?信用卡能轉賬到微信嗎?
- 優雅女人的衣櫥中怎能少了一席長裙,保暖時髦一手抓,明星都愛了-天天新動態
- 三歲以下嬰幼兒照護費用專項扣除什么意思?怎么選扣除方式?
- 定期存款三大忌有哪些?老人存錢最好的方法有哪些?
- 個人養老金賬戶是什么意思?養老金個人賬戶余額能取出來嗎?
- 老鳳祥黃金價格今天多少錢一克?老鳳祥金鐲子價格表
- 南京部分取餐柜試水向騎手收費 你怎么看呢?
- 2023年麒麟電池概念股有哪些?麒麟電池龍頭股有哪些?
- 國內首個百兆瓦級液冷儲能項目,科華數能液冷儲能系統應用標桿!-每日時訊
- 最近為什么市場上時長4小時的電池儲能電站越來越多?-天天信息
- 儲能產業鏈五大趨勢研判-全球熱頭條
- 走進虛擬電廠——技術篇
- 灰氫之后是綠氫-世界速讀
- Horizon Investments首席投資官Scott Ladner稱,美國1月及未來幾個月的通脹數據...
- 科技企業競跑ChatGPT賽道 多領域智慧應用可期
- 開普云:公司數字人已與OpenAI的GPT3-003接口完成對接-全球最資訊
- 社區團購末路:團長累了,經銷商跑了
- 大作難產、項目被砍,育碧怕不是快寄了?-每日看點
- 不買房、不買股推升居民存款大增?中金:關于“超額存款”存在三個誤區
- 北約網站遭黑客攻擊 包括“北約特種作戰司令部”網站
- 《塞爾達傳說王國之淚》林克和大師劍設定圖公開-世界今日訊
- 2000多個網點關閉、公司要倒閉?韻達快遞緊急回應:假的!春節期間人手不足,已采...
- 預處理指令用法詳解(C語言)-天天快播報
- 環比和同比的區別是什么?與上一年對比叫環
- Meta“效率之年”并不高效:裁員傳聞導致規
- 報告:超8成受訪者認為游戲促進AI發展
- 2023年2月13日上期所部分品種“倉單日報”-
- 被《王國之淚》致敬?有游戲表示早就做出了
- 為抵制《霍格沃茨》 LGBTQ+創作者發布游戲
- 信用卡和儲蓄卡的區別是什么?公務卡可以個
- 信用卡可以取現金嗎?信用卡能轉賬到微信嗎
- 優雅女人的衣櫥中怎能少了一席長裙,保暖時
- 三歲以下嬰幼兒照護費用專項扣除什么意思?
- 定期存款三大忌有哪些?老人存錢最好的方法
- 個人養老金賬戶是什么意思?養老金個人賬戶
- 老鳳祥黃金價格今天多少錢一克?老鳳祥金鐲
- 南京部分取餐柜試水向騎手收費 你怎么看呢
- 2023年麒麟電池概念股有哪些?麒麟電池龍頭
- 國內首個百兆瓦級液冷儲能項目,科華數能液
- 最近為什么市場上時長4小時的電池儲能電站
- 儲能產業鏈五大趨勢研判-全球熱頭條
- 走進虛擬電廠——技術篇
- 灰氫之后是綠氫-世界速讀
- Horizon Investments首席投資官Scott Lad
- 科技企業競跑ChatGPT賽道 多領域智慧應用可期
- 開普云:公司數字人已與OpenAI的GPT3-003接
- 社區團購末路:團長累了,經銷商跑了
- 大作難產、項目被砍,育碧怕不是快寄了?-
- 不買房、不買股推升居民存款大增?中金:關
- 北約網站遭黑客攻擊 包括“北約特種作戰司
- 《塞爾達傳說王國之淚》林克和大師劍設定圖
- 2000多個網點關閉、公司要倒閉?韻達快遞緊