黑馬程式設計師 12 C語言之預處理指令

2021-06-28 18:46:45 字數 4314 閱讀 1499

 1

、所有的預處理指令都是以

#開頭,且結尾沒有分號

2、預處理指令在**翻譯成0和

1之前執行

3、預處理指令可以出現在程式的任何位置,它的作用範圍是從它出現的位置到檔案尾。習慣上我們盡可能將預處理指令寫在源程式開頭,這種情況下,它的作用範圍就是整個源程式檔案4、

c語言提供的預處理指令主要有:巨集定義、檔案包含、條件編譯 (

1)定義格式:

#define 巨集名值

(2)作用

它的作用是在編譯預處理時,將源程式中所有"巨集名

"替換成右邊的"值

",常用來定義常量。對程式中用雙引號擴起來的字串內的字元,不進行巨集的替換操作。

#define count 5

#define kcount 5

會將count

替換為5

,雙引號內的不會替換,如:

char *name=」count」

;#undef count //

此行開始

count

這個巨集失效(3

)在編譯預處理用字串替換巨集名時,不作語法檢查,只是簡單的字串替換。只有在編譯的時候才對已經展開巨集名的源程式進行語法檢查(4

)定義乙個巨集時可以引用已經定義的巨集名

#define r 3.0

#define pi 3.14

#define l 2*pi*r

一般形式:

#define 巨集名(

引數列表

) 字串

作用:在編譯預處理時,將源程式中所有巨集名替換成字串,並且將字串中的引數用巨集名右邊引數列表中的引數替換

#define sum(v1, v2) v1+v2

int c=sum(10,11); //

將sum(10,11)

轉換為10+11,即c

值為21

int d=sum(2,3)*sum(4,5);//d

的值為19

,不是預想的

45分析:帶引數的巨集在展開時,只作簡單的字元和引數的替換,不進行任何計算操作,所以

sum(2,3)*sum(4,5)

會轉換為

2+3*4+5

,即19

,並不會先計算出

sum(2,3)

,再去乘

sum(4,5)

的值。所以定義時結果值要加小括號,引數也要加小括號。

#define sum(v1, v2) ((v1)+(v2))

#define pingfang(a) ((a)*(a))

帶引數的巨集定義,在源程式中出現的形式與函式很像。但是兩者是有本質區別的:(1

)巨集定義不涉及儲存空間的分配、引數型別匹配、引數傳遞、返回值問題(2

)函式呼叫在程式執行時執行,而巨集的替換只在編譯預處理階段進行。所以帶引數的巨集比函式具有更高的執行效率,簡單函式可以使用巨集代替。

有時我們希望程式的某一部分**只有在滿足一定條件時才進行編譯,否則不參與編譯(只有參與編譯的**最終才會被執行),這就是條件編譯。簡單的說條件編譯就是有條件的編譯某段**,

#if 條件1

//...code1...

#elif 條件2

//...code2...

#else

//...code3...

#endif

1)如果條件

1成立,那麼編譯器就會把

#if與

#elif

之間的code1

**編譯進去(注意:是編譯進去,不是執行),其他**不會參與編譯。而

if-else

會編譯所以語句(2

)如果條件

1不成立、條件

2成立,那麼編譯器會把

code2

**編譯進去(3

)如果條件1、

2都不成立,那麼編譯器就會把

#else

與#endif

之間的code3

編譯進去(4

)條件編譯結束後,必須在最後麵加乙個

#endif(5

)#if

和#elif

後面的條件一般是判斷巨集定義而不是判斷變數,因為條件編譯是在編譯之前做的判斷,巨集定義也是編譯之前定義的,而變數是在執行時才產生的、才有使用的意義

#if

和#elif

後面的條件不僅僅可以用來判斷巨集的值,還可以判斷是否定義過某個巨集。比如:

#if defined(max)

// ...code...

#endif

如果前面已經定義過

max這個巨集,就將

code

編譯進去。它不會管

max的值是多少,只要定義過

max,條件就成立。

條件也可以取反:

#if !defined(max)

//...code...

#endif

如果前面沒有定義過

max這個巨集,就將

code

編譯進去。4、

#ifdef

和#ifndef

的使用#ifdef

的使用和

#if defined()

的用法基本一致

#ifdef max

//...code...

#endif

如果前面已經定義過

max這個巨集,就將

code

編譯進去。

#ifndef

又和#if !defined()

的用法基本一致

#ifndef max

//...code...

#endif

如果前面沒有定義過

max這個巨集,就將

code

編譯進去。

#include #define max 10

int main ()

在第

2行定義了乙個巨集

max,注意第5到第

11行的條件編譯語句。由於

max為

10,所以

#elif

的條件成立,第

8行**將會被編譯進去,其實編譯預處理後的**是這樣的:

int main ()

常見的#include

就是檔案包含,它是拷貝

<>或」」

內的檔案到

#include

處#include

<

檔名》

用於系統自帶的檔案,直接在

c語言庫函式的標頭檔案所在的目錄中尋找檔案

#include

"檔名

"用於自定義的檔案,系統會先在源程式當前目錄下尋找,若找不到,再到作業系統的

path

路徑中查詢,最後才到

c語言庫函式標頭檔案所在目錄中查詢(1

)#include

指令允許巢狀包含,比如

a.h包含

b.h,

b.h包含

c.h,但是不允許迴圈包含,比如

a.h

包含b.h

,b.h

包含a.h。(

2)使用

#include

指令可能導致多次包含同乙個標頭檔案,這樣編譯效率會降低,利用條件編譯可防止標頭檔案重複包含

#dendef

檔名_h

#define

檔名_h//

定義乙個空的巨集

//函式宣告

#endif

兩個.h

檔案內的巨集名不可以相同,否則可能導致另乙個標頭檔案不被編譯,所以巨集名以檔名

_h命名

例如:#dendef one_h

#define one_h

void one();

#endif

當我們第一次

#include "one.h"

時,因為沒有定義

one_h

,所以條件成立,所以會拷貝

one.h

檔案,會定義

one_h

這個巨集,宣告

one函式。當第二次

#include"one.h"

,因為已經定義過

one_h

這個巨集,所以條件不成立,直接跳到

#endif

,結束條件編譯。所以防止了

one.h

的內容被重複包含。

黑馬程式設計師 C語言之預處理命令

asp.net unity開發 net培訓 期待與您交流!1.所有的預處理指令都是以 開頭 2.預處理指令分3種 1 巨集定義 2 條件編譯 3 檔案包含 3.預處理指令在 翻譯成0和1之前執行 4.預處理的位置是隨便寫的 5.預處理指令的作用域 從編寫指令的那一行開始,一直到檔案結尾,可以用 un...

黑馬程式設計師 C語言預處理指令

asp.net unity開發 net培訓 期待與您交流!1.預處理指令,預處理指令分3種 1.1 巨集定義 1.2 條件編譯 1.3 檔案包含 2.預處理指令不會被編譯,它只會在程式被編譯之前給替換掉 2.1 不帶引數的巨集 define pi 3 一般巨集定義都是全部大寫 int a pi 在程...

黑馬程式設計師 C語言之迴圈結構

asp.net unity開發 net培訓 期待與您交流!今天看的是c語言的迴圈結構,c語言中乙個很重要的部分也就是迴圈結構。他分為幾個部分,乙個是for迴圈,while迴圈,do while迴圈。下面就乙個乙個講解下迴圈結構。for迴圈 for 語句1 條件 語句2 語句1 初始化語句 語句2 增...