- 相關推薦
C語言條件編譯分析實例
引導語;一般情況下,源程序中所有的行都參加編譯。但有時希望對其中一部分內容只在滿足一定條件下才進行編譯,即對一部分內容指定編譯條件,這就是“條件編譯”(conditional compile)。以下是百分網小編分享給大家的C語言條件編譯分析實例,歡迎閱讀!
條件編譯
參看:條件編譯#ifdef的妙用詳解_透徹
#if:表示如果...
#ifdef: 表示如果定義...
#ifndef:表示如果沒有定義...
#else: 表示否則...與#ifdef/#ifndef搭配使用 //筆試題 注意,沒有#elseif
#elif: 表示否則如果...與#if/#ifdef/#ifndef搭配使用
#endif: 表示結束判斷,與#if/#ifdef/#ifndef搭配使用
注意:#if 和 if 區別
#if=>主要用于編譯期間的檢查和判斷
if =>主要用于程序運行期間的檢查和判斷Z
最常見的形式:
#ifdef 標識符
程序段1
#else
程序段2
#endif
作用:當標識符已經被定義過(一般用#define命令定義),則對程序段1進行編譯,否則編譯程序段2。其中#else部分也可以沒有,即:
#ifdef 標識符
程序段1
#endif
這里的“程序段”可以是語句組,也可以是命令行。這種條件編譯可以提高C源程序的通用性。如果一個C源程序在不同計算機系統上運行,而不同的計算機又有一定的差異。例如,我們有一個數據類型,在Windows平臺中,應該使用long類型表示,而在其他平臺應該使用float表示,這樣往往需要對源程序做必要的修改,這就降低了程序的通用性。可以用以下的條件編譯:
#ifdef WINDOWS
#define MYTYPE long
#else
#define MYTYPE float
#endif
如果在Windows上編譯程序,則可以在程序的開始加上
#define WINDOWS
這樣則編譯下面的命令行:
#define MYTYPE long
如果在這組條件編譯命令之前曾出現以下命令行:
#define WINDOWS 0
則預編譯后程序中的MYTYPE都用float代替。這樣,源程序可以不必任何修改就可以用于不同類型的計算機系統。當然以上介紹的只是一種簡單的情況,可以根據此思路設計出其他的條件編譯。
例如,在調試程序時,常常希望輸出一些所需的信息,而在調試完成后不再輸出這些信息。可以在源程序中插入以下的條件編譯段:
#ifdef DEBUG
print ("device_open(%p)\n", file);
#endif
如果在它的前面有以下命令行:
#define DEBUG
則在程序運行時輸出file指針的值,以便調試分析。調試完成后只需將這個define命令行刪除即可。有人可能覺得不用條件編譯也可以達到此目的,即在調試時加一批printf語句,調試后一一將prntf語句刪除。的確,這是可以的。但是,當調試時加的printf語句比較多時,修改的工作量是很大的。用條件編譯,則不必一一刪除printf語句。只需刪除前面的一條#define DEBUG 命令即可,這時所有的用DEBUG 作標識符的條件編譯段都使其中的printf語句不起作用,起到統一控制的作用,如同一個“開關”一樣。
有時也采用下面的形式:
#ifndef 標識符
程序段1
#else
程序段2
#endif
只是第一行與第一種形式不同:將“#ifdef”改為“#ifndef”。它的作用是,若標識符未被定義則編譯程序段1,否則編譯程序段2。這種形式與第一種形式的作用相反。
一般地,當某文件包含幾個頭文件,而且每個頭文件都可能定義了相同的宏,使用#ifndef可以防止該宏重復定義。
/*test.h*/
#ifndef SIZE
#define SIZE 100
#endif
#ifndef 指令通常用于防止多次包含同一文件,也就是說,頭文件可采用類似下面幾行的設置:
//頭文件衛士
#ifndef THINGS_H_
#define THINGS_H_
#endif
還有一種形式,就是#if 后面跟一個表達式,而不是一個簡單的標識符:
#if 表達式
程序段1
#else
程序段2
#endif
它的作用是:當指定的表達式為真(非零)時就編譯程序段1,否則編譯程序段2.可以事先給定一定條件,使程序在不同的條件下執行不同的功能。例如:
#include
#define LETTER 1
int main (void)
{
#if LETTER
printf ("111\n");
#else
printf ("222\n");
#endif
return 0;
}
輸出結果:
111
這種形式也可以用作注釋用:#if 1 和 #if 0
#include
int main (void)
{
#if 0
printf ("111\n");
#endif
printf ("222\n");
return 0;
}
輸出結果:
222
最后一種形式
#if 標識符
#elif
程序段1
#elfi
程序段2
。。。
#else
程序段n
#endif
#if...#elif(任意多次)...#else...#endif,以上結構可以從任意邏輯表達式選擇一組編譯,這種結構可以根據任意邏輯表達式進行選擇。
/*
條件編譯演示
*/
#include
#define SAN
int main()
{
#if defined(YI) //布爾值
printf("1\n");
#elif defined(ER) //布爾值
printf("2\n");
#elif defined(SAN)
printf("3\n");
#else
printf("4\n");
#endif
return 0;
}
輸出結果:
3
這里,define是一個預處理運算符。如果 define 的參數已用#define定義過,那么define返回1,否則返回 0 。這種方法的優點在于它可以和#elif一起使用。
應用示例:
我們主要使用以下幾種方法,假設我們已在程序首部定義:
#define DEBUG
#define TEST
1、利用#ifdef / #endif 將程序功能模塊包括進去,以向某用戶提供該功能.
在程序首部定義#define HNLD:
#ifdef HNLD
include"n166_hn.c"
#endif
如果不許向別的用戶提供該功能,則在編譯之前將首部的HNLD加下劃線即可。
2、在每一個子程序前加上標記,以便追蹤程序的運行。
#ifdef DEBUG
printf(" Now is in hunan !");
#endif
3、避開硬件的限制。有時一些具體應用環境的硬件不一樣,但限于條件,本地缺乏這種設備,于是繞過硬件,直接寫出預期結果。具體做法是:
#ifndef TEST
i=dial();
//程序調試運行時繞過此語句
#else
i=0;
#endif
調試通過后,再屏蔽TEST的定義并重新編譯,即可發給用戶使用了。
有一個問題,如何確保使用的標識符在其他任何地方都沒有定義過?
通常編譯器提供商采用下述方法解決這個問題:用文件名做標識符,并在文件名中使用大寫字母、用下劃線代替文件名中的句點字符、用下劃線(可能使用兩條下劃線)做前綴和后綴。例如,檢查頭文件read.h,可以發現許多類似的語句:
#ifndef __READ_H__ //作為開頭的預處理指令則當它后面的宏名稱被定義過則編譯后一組否則編譯前一組
#define __READ_H__ //防止被重復定義
extern int num=0;
#endif __READ_H__
參看:C語言再學習 -- 標識符
擴展:extern "C"
通過 extern "C" 可以要求 C++ 編譯器按照 C方式處理函數接口,即不做換名,當然也就無法重載。
1) C 調 C++,在 C++ 的頭文件如下設置:
extern "C" int add (int x, int y);
extern "C" {
int add (int x, int y);
int sub (int x, int y);
}
//示例 add.h
#ifndef _ADD_H
#define _ADD_H
#ifdef __cplusplus
extern "C" {
#endif
int add (int ,int );
#ifdef __cplusplus
}
#endif
#endif
2)C++ 調 C,在C++ 的主函數如下設置:
extern "C" {
#include "chead.h"
}
//示例 main.cpp
#include
using namespace std;
extern "C" {
#include "05sub.h"
}
int main (void) {
int x=456,y=123;
cout << x << "+" << y << "="
<< sub(x, y) << endl;
return 0;
}
【C語言條件編譯分析實例】相關文章:
C語言的結構與聯合的實例分析03-30
C語言的編碼編譯12-04
C語言編譯過程總結詳解12-04
最新C語言編譯過程總結詳解12-11
C語言數組實例解析03-28
C語言快速排序實例代碼06-04
Swift與C語言指針結合使用實例03-29
C語言插入排序算法及實例代碼12-05
C語言選擇排序算法及實例代碼11-25