C C 關於預編譯的一些理解

2021-10-04 14:35:25 字數 3159 閱讀 8982

自己的一些理解:

條件編譯的乙個重大作用就是防止標頭檔案的重複定義,

#ifndef   abc_h

#define    abc_h

#endif

假如檔案abc_h之前沒有被#define過,在這裡就會#define,,從而保證了乙個檔案只可能被執行一次,

甚至可以把#define    abc_h看成該檔案是否被執行過的一種標誌

abc_h的名字是可以隨便取的,只要保證不同檔案裡#define 後的abc_h對應就行,這樣在邏輯上才能行得通.

一般為了方便人類觀察,習慣寫成某個標頭檔案abc.h的大寫形式abc_h

條件編譯是c語言中預處理部分的內容,它是編譯器編譯**時最先處理的部分,

之所以能夠實現條件編譯是因為預編譯指令是在編譯之前進行處理的,通過預編譯進行巨集替換、條件選擇**段,然後生成最後的待編譯**,最後進行編譯。

#if的一般含義是,如果#if後面的常量表示式為true,則編譯它所控制的**,如條件1成立時就**段1,條件1不成立再看條件2是否成立,如果條件2成立則編譯**段2,否則再依次類推判斷其它條件,如果條件1-n都不成力則會編譯最後的**段n+1.

條件編譯裡面有判斷語句,比如 #if 、#else 、#elif 及 #endif

它的意思是如果巨集條件符合,編譯器就編譯(預處理)這段**,否則,編譯器就忽略這段**而不編譯,如

#define a 0 //把a定義為0

#if (a > 1)

printf("a > 1"); //編譯器沒有編譯該語句,該語句不生成彙編**

#elif (a == 1)

printf("a == 1"); //編譯器沒有編譯該語句,該語句不生成彙編**

#else

printf("a < 1"); //編譯器編譯了這段**,且生成了彙編**,執行該語句

#endif

而 if 語句則不然,if 是 c 語言中的關鍵字,它根據表示式的計算結果來決定執行(執行可不是條件編譯預處理,)那個語句,但是它裡面的每個分支都編譯(都進行了預處理和編譯)了的, 如

#define a 0

if (a > 1)

printf("a > 1"); //編譯器編譯該語句,但因為a == 0 未執行

else if(a == 1)

printf("a == 1"); //編譯器編譯該語句,但因為a == 0 未執行

else

printf("a < 1"); //編譯器編譯該語句,因為a == 0 故執行

#if條件編譯作為乙個編譯「開關」(常用來注釋**),比如:

#if(條件滿足)

執行**1

#else

執行**2

#endif

假如編譯時,確實滿足條件(結果非0時),則生成的程式檔案(.exe檔案)中不會有執行**2的。如果用普通if語句,生成的程式檔案就會有執行**2,這個區別看看生成檔案大小就可以知道。如果你的條件在程式編譯前就已經確定了,那就用#if;如果條件需要在程式執行過程中才能判斷,則用if。

所以 簡單地講,條件編譯是根據 巨集條件 選擇性地編譯語句,它是編譯器在編譯**時完成的;條件語句是根據條件表示式選擇性地執行語句,它是在程式執行時進行的。

#if的後面接的是表示式

#if (max==10)||(max==20)

code...

#endif

它的作用是:如果(max10) || (max20)成立,那麼編譯器就會把其中的#if 與 #endif之間的**編譯進去(注意:是編譯進去,不是執行!!)

#if後面接的是乙個巨集。

#if defined (x)

...code...

#endif

這個#if defined它不管裡面的「x」的邏輯是「真」還是「假」它只管這個程式的前面的巨集定義裡面有沒有定義「x」這個巨集,如果定義了x這個巨集,那麼,編譯器會編譯中間的…code…否則直接忽視中間的…code…**。

另外 #if defined(x)也可以取反,也就用 #if !defined(x)

#include #define config_debug 

int main()

#ifdef config_debug

printf("open test.txt ok");

#endif

return 0;

}

#ifdef的使用和#if defined()的用法一致 

#ifndef又和#if !defined()的用法一致。

最後強調兩點:

第一:這幾個巨集定義只是決定**塊是否被編譯!

第二:別忘了#endif

#ifdef _***x

...程式段1...

#else

...程式段2...

#endif

這表明如果識別符號_***x已被#define命令定義過則對程式段1進行編譯;否則對程式段2進行編譯。

3:情況3:

#if 常量

...程式段1...

#else

...程式段2...

#endif

這裡表示,如果常量為真(非0,隨便什麼數字,只要不是0),就執行程式段1,否則執行程式段2。

//巢狀情況

#if 常量a

...程式段1...

#else

#if 常量b

...程式段2...

#else

...程式段3...

#endif

#endif

這裡表示,如果常量a為真(非0,隨便什麼數字,只要不是0),就執行程式段1。當常量a為0,常量b為真時,執行程式段2;當常量a為0,常量b為0時,執行程式段3;

關於預編譯標頭檔案的一些知識

許多初學 vc 的朋友也許都為那麼乙個問題困擾過 為什麼所有的 cpp 都必須 include stdafx.h 也許請教了別的高手之後,他們會告訴你,這是預編譯標頭檔案,必須包含。可是,這到底是為什麼呢?預編譯頭有什麼用呢?這得從頭檔案的編譯原理講起。其實標頭檔案並不神秘,它的全部作用,就是把自己...

C 中的一些預編譯指令

1 define和 undef 用法 define debug undef debug define告訴編譯器,我定義了乙個debug的乙個符號,他類似乙個變數,但是它沒有具體的值,可以將它看為乙個符號而已。undef就是刪除這個符號的定義。如果符號debug沒定義過,則 undef不起作用,否則 ...

關於編譯opencv contrib的一些總結

首先說下我的程式設計環境 win10 64 位 vs2017 opencv3.3.1dubug opencv2.4.9 提到opencv2.4.9的原因 opencv2.4.9為十分經典的版本,如果在多次編譯opencv contrib未果的情況下,不妨可以退回到opencv2.4.9,實測在上述環...