国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言·預(yù)處理詳解

這篇具有很好參考價值的文章主要介紹了C語言·預(yù)處理詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 預(yù)定義符號

????????C語言設(shè)置了一些預(yù)定義符號,可以直接使用,預(yù)定義符號也是在預(yù)處理期間處理的

????????????????__FILE__ ?進行編譯的源文件

????????????????__LINE__ ?文件當(dāng)前的行號

????????????????__DATE__ ?文件被編譯的日期

????????????????__TIME__ ?文件被編譯的時間

????????????????__STDC__ ?如果編譯器遵循ANSI C,其值為1,否則未定義

? ? ? ? 舉個例子

C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

? ? ? ? 這行代碼的出現(xiàn)位置是在第16行,所以__LINE__的值就是16,注意這個詞是兩個下劃線+LINE+兩個下劃線,文件名,行號,日期,時間都是編譯當(dāng)前文件當(dāng)前位置當(dāng)前時間的信息,注意是編譯時的不是運行時的信息。

2. #define定義常量

????????基本語法:

????????????????#define name stuff

????????#define定義的stuff內(nèi)容可以是數(shù)值,參數(shù),甚至是語句,舉個例子:

C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????最后一段定義中我們定義了一個打印的語句,很明顯我是將一行代碼寫成了3行。這是因為寫成一行代碼的時候代碼量太長,因此我們可以借助續(xù)行符進行換行接著寫。前兩行結(jié)尾處的反斜杠就是續(xù)行符,我們可以理解成將反斜杠后面的回車轉(zhuǎn)義掉了,所以回車換行相當(dāng)于沒換,視覺上像是換了行,但實際上還是在這一行上書寫

????????現(xiàn)在我們思考一個問題:在使用#define定義標(biāo)識符的時候要不要在最后加上 ?; ?

????????我建議是不要加上的,因為#define是暴力替換掉常量名,如果不注意的話很容易出問題

C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

? ? ? ? 觀察num被替換之后的樣子我們可以發(fā)現(xiàn)加? ;? 的危害了

3. #define定義宏

????????于定義常量類似,定義宏也是將名暴力替換掉,只不過宏新增了一個參數(shù)的機制

????????下面是宏的聲明方式

????????????????#define name(parament-list) stuff

????????parament-list參數(shù)列表是一個由符號隔開的符號表,其中的符號可能出現(xiàn)在stuff中

????????注意:參數(shù)列表的左括號必須和name緊鄰,如果兩者間由任何空白的存在,參數(shù)列表就會被認(rèn)為是stuff的一部分

????????舉例如何使用定義宏

????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

? ? ? ? 我用宏實現(xiàn)了一個將參數(shù)變成其二倍的功能

????????但是這么寫宏是有問題的

???????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????我在宏的參數(shù)部分寫2+1,本意是計算DOUBLE(3),但是因為暴力替換的問題,表達(dá)式并沒有按照我預(yù)想的循序計算,而計算的是2*2+1

????????因此我們在定義宏的時候要將表達(dá)式中的元素用小括號括起來,保證它們的運算順序不會在暴力替換之后改變

????????但是問題還沒有解決

???????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????很明顯,這段代碼也因為暴力替換的問題本想計算5*4,但是實際上計算的是5*2+2

????????因此我們要將整體也用小括號固定計算順序

??????????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????這樣才算正確的定義宏

4. 帶有副作用的宏參數(shù)

????????當(dāng)宏參數(shù)在宏定義中出現(xiàn)超過一次的時候,如果參數(shù)帶有副作用,那么你在使用這個宏的時候就可能出現(xiàn)危險,導(dǎo)致不可預(yù)測的后果。副作用就是表達(dá)式求值的時候出現(xiàn)的永久性效果。

????????????????x+1 不帶有副作用

????????????????x++ 帶有副作用

????????舉一個副作用的例子

????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

???????很明顯結(jié)果和我們預(yù)期的不一樣,判斷3和5的大小最后答案竟然是6,而且a和b的值也被改變,這正是因為參數(shù)的副作用帶來的問題,簡單分析一下注釋掉的那條語句就可以知道到底是怎么回事了

5. 宏的替換

????????我們之前已經(jīng)提到過多次了,宏在使用時其實就是將名強行替換掉了,那么具體的替換方案涉及以下幾個步驟

????????1.在調(diào)用宏時,首先對參數(shù)進行檢查,看看是否包含任何由#define定義的符號。如果是,它們首先被替換

????????2.替換文本隨后被插入到程序中原來文本的位置。對于宏,參數(shù)名被它們的值替換。

????????3.最后,再對結(jié)果文件進行掃描,看看它是否包含任何由#define定義的符號。如果是,重復(fù)以上處理步驟

????????注意:

????????1.宏參數(shù)和#define定義中可以出現(xiàn)其他#define定義的符號。但是對于宏,不能出現(xiàn)遞歸

????????2.當(dāng)預(yù)處理器搜索#define定義的符號的時候,字符串常量的內(nèi)容不被搜索
?

????????

6. 宏和函數(shù)的對比

????????宏通常被應(yīng)用于執(zhí)行簡單的運算,函數(shù)用于解決復(fù)雜的功能

????????比如在執(zhí)行上面那個比較兩個數(shù)大小的功能的時候,寫成宏更有優(yōu)勢

????????宏的優(yōu)勢:

? ? ? ? 1. 進行簡單計算的時候需要的計算量比函數(shù)更小,宏沒有像函數(shù)的調(diào)用和返回那樣復(fù)雜的匯編語句需要,因此速度也會比函數(shù)快

? ? ? ? 2. 宏是與類型無關(guān)的,所以參數(shù)想傳什么就傳什么,具體產(chǎn)生什么效果等替換完了再看。甚至宏可以傳遞類型名,這是函數(shù)絕對做不到的

????????宏的劣勢:

? ? ? ? 1. 每次使用宏的時候,一份宏定義的代碼將插到程序當(dāng)中去。除非宏比較短,否則可能大幅增加宏的長度

? ? ? ? 2. 宏是沒法調(diào)試的

? ? ? ? 3. 宏由于類型無關(guān),因此不夠嚴(yán)謹(jǐn)

? ? ? ? 4. 宏可能會帶來運算符優(yōu)先級的問題,導(dǎo)致容易出錯
?

7. #和##

7.1 #運算符

????????#運算符將宏的一個參數(shù)轉(zhuǎn)換成字符串字面量。它僅允許出現(xiàn)在帶參數(shù)的宏的替換宏的替換列表中

????????#執(zhí)行的操作可以理解為字符串化

????????舉個例子:

C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????這段代碼中#n在替換時發(fā)生字符串化,將 a 變成了 "a"

????????當(dāng)然在觀察注釋的時候可以注意到printf中包含了3段字符串,這種寫法是允許的,它和第二行注釋是等價的

????????

7.2 ##運算符

????????##可以把位于它兩邊的符號合成一個符號,它允許宏定義從分離的文本片段創(chuàng)建標(biāo)識符。##被稱為記號粘合

????????這樣的連接必須是產(chǎn)生一個合法的標(biāo)識符,否則結(jié)果是未定義的

????????下面我們舉個例子:

????????當(dāng)我們想比較兩個數(shù)的大小的時候不同的類型int、float、double都要寫一個不同名函數(shù)來運算,但其實它們的運算內(nèi)容方法是一樣的,所以能不能有一種方法把它們整合一下

C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????##在這段代碼中就起到了粘貼 type 和 _max 的作用,使得type會被替換之后還能與_max形成新的函數(shù)名,用這種方法通過一段代碼生成了3個功能相似,函數(shù)名不同的函數(shù)

8. 命名約定

????????一般來講,函數(shù)和宏的使用語法很相似,所以為了區(qū)分二者,我們有這樣的書寫習(xí)慣

????????????????把宏全部大寫

????????????????函數(shù)名不要全部大寫

9. #undef

????????這條指令用于移除一個宏定義

????????舉個例子

???????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????在宏定義移除之后MAX就不能用了,但是我們可以用#define重新啟用他,起到一個修改宏的作用

10. 命令行定義

????????許多C的編譯器提供了一種能力,允許在命令行中定義符號,用于啟動編譯的過程

????????舉個例子,如果我在編寫代碼的時候不能確定一個數(shù)組要分配多大的空間,只能在運行前的時候確定,可以這樣先把程序?qū)懗鰜?/p>

??????????????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????這樣在程序中并不指定SIZE的具體大小,在啟動程序的時候用命令行

????????????????gcc -D SIZE=10 programme.c

????????這樣程序就能正常跑起來,并且開辟一個10個元素的數(shù)組

????????這個功能vs中不好演示,感興趣可以用Linux嘗試一下

11. 條件編譯

????????在編譯一個程序的時候我們可以使用條件編譯指令來控制要不要編譯這條語句

????????比如說那些調(diào)試性的代碼,刪除可惜,保留又礙事,所以我們可以選擇性編譯

????????常見的條件編譯指令

????????1.#if #endif

????????????????#if 常量表達(dá)式(為真編譯,為假不編譯)

????????????????······

????????????????#endif

????????注意#if后面跟的是常量表達(dá)式

????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????這么寫就是有錯誤的。第一,#if 后邊要求跟常量表達(dá)式,a是變量。第二,#if 是在預(yù)處理階段進行處理的,這時候a還沒有定義呢,那a算什么?

????????2. 多分支的條件編譯

????????????????#if 常量表達(dá)式

????????????????······

????????????????#elif 常量表達(dá)式

????????????????······

????????????????#else

????????????????······

????????????????#endif

????????3. 判斷是否被定義

????????????????#if defined(symbol)

????????????????#ifdef symbol

????????這兩條語句都是說如果這個symbol被定義了就編譯下面的代碼

????????????????#if !defined(symbol)

????????????????#ifndef symbol

????????這兩條語句是說如果沒定義symbol就編譯下面的代碼

????????當(dāng)然不要忘記 #endif 結(jié)束條件編譯,#endif和距它最近的?#if 或 #if··· 匹配,不管是 #if 還是 #if··· 都要記得用 #endif 結(jié)束

????????4.條件編譯指令是可以嵌套的

12. 頭文件的包含

12.1 頭文件被包含的方式

12.1.1 本地文件包含

????????????????#include "filename.h"

????????查找策略:現(xiàn)在源文件目錄下查找,如果該頭文件未找到,編譯器就像查找?guī)旌瘮?shù)頭文件一樣在標(biāo)準(zhǔn)位置查找頭文件,如果還是找不到就報錯

12.1.2 庫文件包含

????????????????#include <filename.h>

????????查找這種類型的頭文件就直接去標(biāo)準(zhǔn)路徑下查找(所以庫函數(shù)所在位置),如果找不到就報錯

????????這樣是不是可以說,對于庫函數(shù)包含的時候可不可以用 ?" " ?的形式?

????????確實是可以的,但是這樣做效率就會低一點,同時這樣也不容易區(qū)分我包含的是庫文件還是本地文件

12.2 嵌套文件包含

????????我們之前已經(jīng)學(xué)到過#include就是把另一個文件復(fù)制到這條語句所在位置,并替換掉這條語句。

????????那么在一個大型的項目中,在所難免的會出現(xiàn)頭文件被重復(fù)包含的現(xiàn)象,這會導(dǎo)致多次把頭文件中的內(nèi)容粘過來,如果頭文件過大,這很影響編譯的速度

????????所以我們可以用條件編譯解決這個問題,在頭文件開頭寫:

??????????????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????這樣就可以通過判斷__TEST_H__是否被定義來確定這個頭文件有沒有使用過,從而確定要不要把頭文件的內(nèi)容粘過去

????????還有一種方法,在頭文件開頭加上:

??????????????????????????????????????C語言·預(yù)處理詳解,C語言學(xué)習(xí)之旅,c語言,開發(fā)語言

????????就可以避免頭文件的重復(fù)引用,這個方法是比較常見的

13. 其他預(yù)處理指令

????????????????#error

????????????????#pragma

????????????????#line

????????????????#pragma pack()?? ?修改默認(rèn)對齊數(shù),在結(jié)構(gòu)體中有講

????????????????······

????????更多內(nèi)容可以參考《C語言深度解剖》中預(yù)處理一章文章來源地址http://www.zghlxwxcb.cn/news/detail-811053.html

到了這里,關(guān)于C語言·預(yù)處理詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【C語言】預(yù)處理詳解

    【C語言】預(yù)處理詳解

    ???????? 本文目錄 1 預(yù)定義符號 2 #define 2.1 #define 定義標(biāo)識符 2.2 #define 定義宏 2.3 #define 替換規(guī)則 2.4 #和## 2.5 帶副作用的宏參數(shù) 2.6 宏和函數(shù)對比 2.7 命名約定 3 #undef 4 命令行定義 5 條件編譯 6 文件包含 6.1 頭文件被包含的方式 6.2 嵌套文件包含 這些預(yù)定義符號都是語言內(nèi)置

    2024年02月14日
    瀏覽(35)
  • 詳解C語言—預(yù)處理

    詳解C語言—預(yù)處理

    目錄 一、預(yù)處理 1、預(yù)定義符號介紹 2、預(yù)處理指令 #define #define 定義標(biāo)識符:? #define 定義宏: #define 替換規(guī)則 3、預(yù)處理操作符# 4、預(yù)處理操作符## 5、帶副作用的宏參數(shù) 6、宏和函數(shù)對比 二、命名約定 三、預(yù)處理指令 #undef 四、命令行定義 五、條件編譯? 1、單分支#if:

    2024年02月08日
    瀏覽(28)
  • C語言預(yù)處理詳解

    C語言預(yù)處理詳解

    上一篇博客中我們講了C語言的編譯與鏈接,在編譯過程中有三個小階段:預(yù)處理、編譯、匯編。 本篇博客將詳細(xì)講述預(yù)處理部分的有關(guān)知識點 。 在C語言中,C語言本身設(shè)置了?些預(yù)定義符號,可以直接使? ,預(yù)定義符號的處理也是在預(yù)處理期間進行的。 在這里介紹幾個常

    2024年04月15日
    瀏覽(39)
  • C語言·預(yù)處理詳解

    C語言·預(yù)處理詳解

    ????????C語言設(shè)置了一些預(yù)定義符號,可以直接使用,預(yù)定義符號也是在預(yù)處理期間處理的 ????????????????__FILE__ ?進行編譯的源文件 ????????????????__LINE__ ?文件當(dāng)前的行號 ????????????????__DATE__ ?文件被編譯的日期 ????????????????_

    2024年01月21日
    瀏覽(33)
  • 【C語言進階】預(yù)處理詳解

    【C語言進階】預(yù)處理詳解

    對預(yù)處理的相關(guān)知識進行詳細(xì)的介紹 ? ? ? ? ? ? ? ? ??? 豬巴戒 :個人主頁? ??????????????? 所屬專欄 :《C語言進階》 ? ? ? ? ?? 跟著豬巴戒 ,一起學(xué)習(xí)C語言?? 目錄 引言 預(yù)定義符號 #define定義常量 #define定義宏 帶有副作用的宏參數(shù) 宏替換的規(guī)則 宏函數(shù)的

    2024年01月23日
    瀏覽(26)
  • 【C語言:編譯、預(yù)處理詳解】

    【C語言:編譯、預(yù)處理詳解】

    我們都知道,一個程序如果想運行起來要經(jīng)過編譯、鏈接然后才能生成.exe的文件。 編譯?可以分解為三個過程: 預(yù)處理(有些書也叫預(yù)編譯)、 編譯 匯編 預(yù)處理階段 主要處理那些源文件中以#開始的預(yù)編譯指令。比如:#include,#define,處理的規(guī)則如下: 刪除所有的注釋

    2024年02月03日
    瀏覽(24)
  • 【C語言基礎(chǔ)】:預(yù)處理詳解(一)

    【C語言基礎(chǔ)】:預(yù)處理詳解(一)

    一、預(yù)定義符號 在C語言中設(shè)置了許多的預(yù)定義符號,這些預(yù)定義符號是可以直接使用的,預(yù)定義符號也是在預(yù)處理階段進行處理的。 常見的預(yù)定義符號 : 【示例】 : 我們在VS上使用 _ _ STDC _ _ 會發(fā)現(xiàn)顯示未定義,這也就說明VS的編譯器是不完全遵循 ANSI C 的,為了展示效果

    2024年04月22日
    瀏覽(31)
  • 【c語言】詳解c語言#預(yù)處理期過程 | 宏定義前言

    【c語言】詳解c語言#預(yù)處理期過程 | 宏定義前言

    c語言系列專欄:?c語言之路重點知識整合?? 創(chuàng)作不易,本篇文章如果幫助到了你,還請點贊支持一下???)!!? 主頁專欄有更多知識,如有疑問歡迎大家指正討論,共同進步! 給大家跳段街舞感謝支持!? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 代碼編譯到執(zhí)

    2024年02月01日
    瀏覽(28)
  • 初始C語言最后一章《編譯、鏈接與預(yù)處理詳解》

    初始C語言最后一章《編譯、鏈接與預(yù)處理詳解》

    感謝老鐵們的陪伴和支持,初始C語言專欄在本章內(nèi)容也是要結(jié)束了,這創(chuàng)作一路下來也是很不容易,如果大家對 Java 后端開發(fā)感興趣,歡迎各位老鐵來我的Java專欄!當(dāng)然了,我也會更新幾章C語言實現(xiàn)簡單的數(shù)據(jù)結(jié)構(gòu)!不過由于我是Java 技術(shù)棧的,所以如果以后有機會學(xué)習(xí)C

    2024年04月16日
    瀏覽(22)
  • 【C語言】預(yù)處理詳解:#define的各種使用方法

    【C語言】預(yù)處理詳解:#define的各種使用方法

    目錄 1.#define定義標(biāo)識符 1.1賦值 1.2? ?定義 1.3用更形象的符號來替換一種實現(xiàn) 1.4? ?加續(xù)行符換行 1.5#define定義宏 1.6? #define替換的規(guī)則 注意事項 2.#和## 3.帶有副作用的宏參數(shù) 4.函數(shù)和宏的對比 #define定義標(biāo)識符的用法非常簡單 name可以由自己來命名,盡量取一些有意義

    2024年02月15日
    瀏覽(32)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包