本篇文章專注於解答在《c++預處理器》一文中提出的問題,並進一步提公升對c++條件編譯的認識。
通常,原始檔中所有內容都要參加編譯,但是在某些時候,可能希望原始檔中某些部分在滿足某些條件的情況下才進行編譯,這就是所謂的條件編譯。
有趣的是,對於c++的初學者來說,沒有條件編譯照樣可以寫出可以良好執行的程式,所以條件編譯的知識常常會被忽視。
但事實上,條件編譯非常有用。要注意,對於一些小型的程式,條件編譯的作用可能常常被掩蓋,但是當程式的規模變大後條件編譯的作用和優勢就會顯現出來了。因此把握它還是非常重要的。
條件編譯有以下三種形式:
形式一
#ifdef 識別符號
程式片段1
#else
程式片段2
#endif
上述語句的意思就是如果識別符號已被#define
命令定義過,則對程式片段1進行編譯;否則對程式片段2進行編譯。其中,程式片段2可以為乙個空的程式段,那麼#else
就沒有什麼實際的意義了,這時可以將其省略。
請看下面看這段示例**。
#include #define debug
using namespace std;
void main()
}
形式二#ifndef 識別符號
程式片段1
#else
程式片段2
#endif
形式2和形式1的區別在於#ifdef關鍵字換成了#ifndef關鍵字,其功能是如果識別符號未被
功能正好相反。
形式三
#if 識別符號
程式片段1
#else
程式片段2
#endif
該形式完成的功能是如果表示式的值為真,則對程式片段1進行編譯;否則對程式片段2
進行編譯。因此可以使程式在不同條件下完成不同的功能。
在c或c++中,標頭檔案重複包含問題是程式設計師必須避免的問題,也是很多新手容易犯錯的問題。
請讀者先先思考這樣一段**:(方便起見將三個檔案的**寫在一起)
#includeint a=1;
#include "a.h"
void f()
#include#include"a.h"
#include"b.h"
void main()
編譯執行此程式會報錯,提示你int a 被重複定義。
為什麼會出現這樣的問題呢,我們要從頭檔案的編譯預處理說起。
我們知道在編譯c或c++程式時候,編譯器首先要對程式進行預處理,預處理其中一項工作便是將你源程式中#include
的標頭檔案完整的展開
於是乎,當出現標頭檔案重複包含時,就會帶來兩種不利影響:
1、編譯器編譯步驟多次編譯該標頭檔案,工程**量小還好,工程量一大會使整個專案編譯速度變的緩慢,後期的維護修改變得困難。
2、標頭檔案裡對變數的多次定義會使程式在編譯鏈結的時候崩潰。
解決:標頭檔案重複包含和變數重複定義可以藉由條件編譯解決,**如下:
#ifndef _a_h
#define _a_h
int a = 1;
#endif;
通過條件編譯,實現了a.h只編譯一次。
此外,微軟的vs和vscode還提供了#pragma one
預編譯指令,其作用與條件編譯相同。
#pragma once
#includeint a = 1;
一些客戶需要你這個產品裡的功能a而另外一些客戶不需要a,那麼你就可以使用條件編譯把實現a的所有**包起來,這樣你就可以#define和#undef來enable或者disable你的功能a了
在形式一的樣例**中展現過這樣的思路,即將除錯過程中的附加**用#ifdef debug
包起來,在預編譯指令中通過加入與刪除#define debug
來實現除錯過程與最終**之間的切換。
C 條件編譯詳解
一般情況下,在進行編譯時對源程式中的每一行都要編譯。但是有時希望程式中某一部分內容只在滿足一定條件時才進行編譯,也就是指定對程式中的一部分內容進行編譯的條件。如果不滿足這個條件,就不編譯這部分內容。這就是 條件編譯 其實這跟事物具有多樣性一樣。我們需要對不同的狀況下採取不同的操作。例如程式的執行平台...
C語言條件編譯詳解
預處理程式提供了條件編譯的功能。可以按不同的條件去編譯不同的程式部分,因而產生不同的目標 檔案。這對於程式的移植和除錯是很有用的。條件編譯有三種形式,下面分別介紹 ifdef 識別符號 程式段1 else 程式段2 endif 它的功能是,如果識別符號已被 define命令定義過則對程式段1進行編譯...
c語言條件編譯詳解
指令 用途 空指令,無任何效果 include 包含乙個源 檔案 define 定義巨集 undef 取消已定義的巨集 if 如果給定條件為真,則編譯下面 ifdef 如果巨集已經定義,則編譯下面 ifndef 如果巨集沒有定義,則編譯下面 elif 如果前面的 if給定條件不為真,當前條件為真,則...