您現在的位置:首頁 > 資訊 > 特別關注 > 正文

        焦點快報!預處理指令用法詳解(C語言)

        時間:2023-02-15 12:11:04    來源:騰訊云    

        前言

        使編譯器執行預處理操作的代碼被稱為預處理指令,本文介紹常見的預處理指令的實際用法。

        一、預處理符號

        預處理符號是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宏定義刪除,可以在函數內部使用!
        #

        被刪除后的標識就不能再使用了。

        四、命令行編譯

        指在VScodeLinux等用命令行執行編譯的環境下,可以在編譯時對變量進行賦值。

        五、條件編譯

        在寫程序時,有些代碼是為了查看某個部分是否正確而寫的的調試代碼。

        刪除很可惜,但又不想讓其編譯,此時就可以使用選擇性編譯

        但實質上使用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即可一鍵實現上述效果,不必冗雜的代碼,但僅限于自己寫的頭文件,標準庫的頭文件已經幫你加完了。

        感謝您的閱讀與耐心~

        關鍵詞: 編程算法

        上一篇:
        下一篇:

        相關新聞

        最近更新

        凡本網注明“XXX(非汪清新聞網)提供”的作品,均轉載自其它媒體,轉載目的在于傳遞更多信息,并不代表本網贊同其觀點和其真實性負責。

        特別關注

        • 省委召開常委會議

          今天,在中央第一環境保護督察組向吉林省反饋督察情況后,省委書記巴音朝魯立即主持召開省委常委會議,聽取關于中央環保督察反饋問題整改工

          2017-12-29 14:30

        • 2017年全球十大航天新聞和中國十大航天新聞評選揭曉。

          新浪科技訊 12月28日消息,由空間瞭望智庫、《國際太空》和《衛星應用》雜志,以及中國太空網聯合組織的2017年全球十大航天新聞和中國十大

          2017-12-28 21:47

        • 五星級酒店馬桶刷洗茶杯,酒店以后還能住嗎?

          保潔人員先用馬桶刷子刷茶杯,隨后用同一把馬桶刷子刷馬桶。緊接著,她用浴巾擦杯子,再蘸了馬桶水擦地,最后將浴巾放在地上整理。馬桶刷刷

          2017-12-28 21:12

        • 這些政策將影響你明年錢袋子

          近日,國家發改委、住建部、商務部、工信部、交通部等部委密集召開年度工作會議,貫徹落實中央經濟工作會議精神,部署2018年的重點工作,在

          2017-12-27 21:40

        • 生態文明建設年度評價結果公布:吉林排名靠前

          根據中共中央辦公廳、國務院辦公廳印發的《生態文明建設目標評價考核辦法》和國家發展改革委、國家統計局、環境保護部、中央組織部印發的《

          2017-12-26 16:34

        • 長春市公安局寬城區分局“一號追逃目標”嫌疑人喜歡二人轉“露出馬腳”

          21年前的12月25日,這一天是圣誕節,雖然是西方的節日,但隨著夜幕降臨,歡樂的節日氣氛也隨之而來。當晚,八點多鐘,長春市寬城區的一家藥

          2017-12-15 22:18

        • “第一動力”正加力

          十九大報告再次明確創新的地位:創新是引領發展的第一動力,是建設現代化經濟體系的戰略支撐。2017年,我省創新成果豐碩,形成了跟跑、齊跑

          2017-12-12 10:34

        • 中紀委機關談反腐

          每到關鍵節點,人們總是根據一些重要信號來判斷一項工作的走勢。十九大閉幕后的首月,人們熟悉的打虎節奏和信息如約而至,中央紀委監察部網

          2017-12-08 12:32

        • 撐起“半壁江山” 釋放更強動力

          長春、通化、白山、遼源入選東北地區民營經濟發展改革示范城市,在政策環境、金融環境、創新環境、促進民營經濟轉型升級及人才隊伍建設等方

          2017-12-08 12:21

        • 300城市土地市場量跌價漲 成交均價上漲

          11月,全國300城市土地市場供求回落,但各線城市土地成交均價環同比繼續上漲。綜合前11個月來看,年度土地出讓收入整體保持同比上漲勢態。6

          2017-12-07 18:43