轉載至C語言中文網-跨平臺條件編譯
阿新 • • 發佈:2019-02-07
假如現在要開發一個C語言程式,讓它輸出紅色的文字,並且要求跨平臺,在 Windows 和 Linux 下都能執行,怎麼辦呢?
這個程式的難點在於,不同平臺下控制文字顏色的程式碼不一樣,我們必須要能夠識別出不同的平臺。
Windows 有專有的巨集
這些操作都是在預處理階段完成的,多餘的程式碼以及所有的巨集都不會參與編譯,不僅保證了程式碼的正確性,還減小了編譯後文件的體積。
這種能夠根據不同情況編譯不同程式碼、產生不同目標檔案的機制,稱為條件編譯。條件編譯是預處理程式的功能,不是編譯器的功能。
條件編譯有多種形式,下面一一講解。
需要注意的是,#if 命令要求判斷條件為“整型常量表達式”,也就是說,表示式中不能包含變數,而且結果必須是整數;而 if 後面的表示式沒有限制,只要符合語法就行。這是 #if 和 if 的一個重要區別。
#elif 和 #else 也可以省略,如下所示:
也可以省略 #else:
VS/VC 有兩種編譯模式,Debug 和 Release。在學習過程中,我們通常使用 Debug 模式,這樣便於程式的除錯;而最終釋出的程式,要使用 Release 模式,這樣編譯器會進行很多優化,提高程式執行效率,刪除冗餘資訊。
為了能夠清楚地看到當前程式的編譯模式,我們不妨在程式中增加提示,請看下面的程式碼:
例如,下面的形式只能用於 #if:
NUM: 10
再如,兩個巨集都存在時編譯程式碼A,否則編譯程式碼B:
NUM1: 10, NUM2: 20
這個程式的難點在於,不同平臺下控制文字顏色的程式碼不一樣,我們必須要能夠識別出不同的平臺。
Windows 有專有的巨集
_WIN32
,Linux
有專有的巨集__linux__
,以現有的知識,我們很容易就想到了
if else,請看下面的程式碼:
- #include <stdio.h>
- int main(){
- if(_WIN32){
- system("color 0c");
- printf("http://c.biancheng.net
- }else if(__linux__){
- printf("\033[22;31mhttp://c.biancheng.net\n\033[22;30m");
- }else{
- printf("http://c.biancheng.net\n");
- }
- return 0;
- }
- #include <stdio.h>
- int main(){
- #if _WIN32
- system
- printf("http://c.biancheng.net\n");
- #elif __linux__
- printf("\033[22;31mhttp://c.biancheng.net\n\033[22;30m");
- #else
- printf("http://c.biancheng.net\n");
- #endif
- return 0;
- }
這些操作都是在預處理階段完成的,多餘的程式碼以及所有的巨集都不會參與編譯,不僅保證了程式碼的正確性,還減小了編譯後文件的體積。
這種能夠根據不同情況編譯不同程式碼、產生不同目標檔案的機制,稱為條件編譯。條件編譯是預處理程式的功能,不是編譯器的功能。
條件編譯有多種形式,下面一一講解。
#if 命令
#if 命令的完整格式為:
#if 整型常量表達式1
程式段1
#elif 整型常量表達式2
程式段2
#elif 整型常量表達式3
程式段3
#else
程式段4
#endif
需要注意的是,#if 命令要求判斷條件為“整型常量表達式”,也就是說,表示式中不能包含變數,而且結果必須是整數;而 if 後面的表示式沒有限制,只要符合語法就行。這是 #if 和 if 的一個重要區別。
#elif 和 #else 也可以省略,如下所示:
- #include <stdio.h>
- int main(){
- #if _WIN32
- printf("This is Windows!\n");
- #else
- printf("Unknown platform!\n");
- #endif
- #if __linux__
- printf("This is Linux!\n");
- #endif
- return 0;
- }
#ifdef 命令
#ifdef 命令的格式為:
#ifdef 巨集名
程式段1
#else
程式段2
#endif
也可以省略 #else:
#ifdef 巨集名
程式段
#endif
VS/VC 有兩種編譯模式,Debug 和 Release。在學習過程中,我們通常使用 Debug 模式,這樣便於程式的除錯;而最終釋出的程式,要使用 Release 模式,這樣編譯器會進行很多優化,提高程式執行效率,刪除冗餘資訊。
為了能夠清楚地看到當前程式的編譯模式,我們不妨在程式中增加提示,請看下面的程式碼:
- #include <stdio.h>
- #include <stdlib.h>
- int main(){
- #ifdef _DEBUG
- printf("正在使用 Debug 模式編譯程式...\n");
- #else
- printf("正在使用 Release 模式編譯程式...\n");
- #endif
- system("pause");
- return 0;
- }
#ifndef 命令
#ifndef 命令的格式為:
#ifndef 巨集名
程式段1
#else
程式段2
#endif
區別
最後需要注意的是,#if 後面跟的是“整型常量表達式”,而 #ifdef 和 #ifndef 後面跟的只能是一個巨集名,不能是其他的。例如,下面的形式只能用於 #if:
- #include <stdio.h>
- #define NUM 10
- int main(){
- #if NUM == 10 || NUM == 20
- printf("NUM: %d\n", NUM);
- #else
- printf("NUM Error\n");
- #endif
- return 0;
- }
NUM: 10
再如,兩個巨集都存在時編譯程式碼A,否則編譯程式碼B:
- #include <stdio.h>
- #define NUM1 10
- #define NUM2 20
- int main(){
- #if (definedNUM1 && definedNUM2)
- //程式碼A
- printf("NUM1: %d, NUM2: %d\n", NUM1, NUM2);
- #else
- //程式碼B
- printf("Error\n");
- #endif
- return 0;
- }
NUM1: 10, NUM2: 20
#ifdef 可以認為是 #if defined 的縮寫。
部分預處理語句
指令 |
說明 |
# |
空指令,無任何效果 |
#include |
包含一個原始碼檔案 |
#define |
定義巨集 |
#undef |
取消已定義的巨集 |
#if |
如果給定條件為真,則編譯下面程式碼 |
#ifdef |
如果巨集已經定義,則編譯下面程式碼 |
#ifndef |
如果巨集沒有定義,則編譯下面程式碼 |
#elif |
如果前面的#if給定條件不為真,當前條件為真,則編譯下面程式碼 |
#endif |
結束一個#if……#else條件編譯塊部分預處理語句 |