C語言和C++語言程序中廣泛存在着#ifdef或#ifndef等條件編譯語句,本篇就系統介紹下他們的用法。 這幾個宏是為了進行條件編譯。一般情況下,源程序中所有的行都參加編譯。但是有時希望對其中一部分內容只在滿足一定條件才進行編譯,也就是對一部分內容指定編譯的條件,這就是“條件編譯”。有時,希望當滿足某條件時對一組語句進行編譯,而當條件不滿足時則編譯另一組語句。
#ifdef
條件編譯命令最常見的形式為:
1
2
3
4
5
|
#ifdef 標識符
// 程序段1
#else
// 程序段2
#endif
|
其中#else部分也可以沒有,即:
1
2
3
|
#ifdef 標識符
// 程序段1
#endif
|
例1 不同計算機系統的條件編譯
這里的“程序段”可以是語句組,也可以是命令行。這種條件編譯可以提高C源程序的通用性。如果一個C源程序在不同計算機系統上運行,而不同的計算機又有一定的差異。例如,我們有一個數據類型,在Windows平台中,應該使用long類型表示,而在其他平台應該使用float表示,這樣往往需要對源程序作必要的修改,這就降低了程序的通用性。可以用以下的條件編譯:
1
2
3
4
5
|
#ifdef WINDOWS
# define MYTYPE long
#else
# define MYTYPE float
#endif
|
如果在Windows上
編譯程序,則可以在程序的開始加上
1
|
#define WINDOWS
|
這樣則
編譯下面的命令行:
1
|
#define MYTYPE long
|
如果在這組
條件編譯命令之前曾出現以下命令行:
1
|
#define WINDOWS 0
|
例2 調試程序的條件編譯
1
2
3
|
#ifdef DEBUG
print (
"device_open(%p)\n"
, file);
#endif
|
如果在它的前面有以下命令行:
1
|
#define DEBUG
|
則在程序運行時輸出file
指針的值,以便調試分析。調試完成后只需將這個define命令行刪除即可。有人可能覺得不用
條件編譯也可達此目的,即在調試時加一批printf語句,調試后一一將printf語句刪除去。的確,這是可以的。但是,當調試時加的printf語句比較多時,修改的工作量是很大的。用
條件編譯,則不必一一刪改printf語句,只需刪除前面的一條“#define DEBUG”命令即可,這時所有的用DEBUG作
標識符的條件編譯段都使其中的printf語句不起作用,即起統一控制的作用,如同一個“開關”一樣。
代碼舉例:新建define.cpp文件
1
2
3
4
5
6
7
8
9
|
#include <iostream>
using
namespace
std;
int
main(
int
argc,
char
* argv[] )
{
#ifdef DEBUG
cout <<
"Beginning execution of main()"
<< endl;
#endif
return
0;
}
|
運行結果為:
1
|
Press any key to continue
|
改寫
代碼如下:
1
2
3
4
5
6
7
8
9
10
|
#include <iostream>
using
namespace
std;
#define DEBUG
int
main(
int
argc,
char
* argv[] )
{
#ifdef DEBUG
cout <<
"Beginning execution of main()"
<< endl;
#endif
return
0;
}
|
運行結果為:
1
2
|
Beginning execution of main()
Press any key to continue
|
1
2
3
|
#define DEBUG
#ifdef DEBUG
#endif
|
而在define.cpp源文件中,代碼修改如下:
1
2
3
4
5
6
7
8
9
|
#include <iostream>
#include "head.h"
int
main(
int
argc,
char
* argv[] )
{
#ifdef DEBUG
cout<<
"Beginning execution of main()"
<< endl;
#endif
return
0;
}
|
運行結果如下:
1
2
|
Beginning execution of main()
Press any key to continue
|
結論: |
#ifndef
有時也采用下面的形式:
1
2
3
4
5
|
#ifndef 標識符
// 程序段1
#else
// 程序段2
#endif
|
以上兩種形式用法差不多,根據需要任選一種,視方便而定。
#undef
#undef 是在后面取消以前定義的
宏定義
該指令的形式為
#undef
標識符
在此程序中,我們將取消在先前程序中對
預處理器的定義。
1
2
3
4
5
6
7
8
9
10
11
|
#include <iostream.h>
#include<string.h>
#define MAX 5
#undef MAX
void
main()
{
char
name[MAX]=
"abcde"
;
//只能用abcd,否則會提示說超出長度,原因大概是"\0"字符
cout<<
"MAX = "
<<MAX<<endl;
for
(
int
i=0;i<MAX;i++)
cout<<name<<
" "
<<endl;
}
|
得到如下錯誤消息:
未定義符號 'MAX'
初始值設定項太多
1
2
3
4
5
|
#define TEST_A 1
#define TEST_CLASS_A clase T1
#include "TEST.h"
#undef TEST_A
#undef TEST_CLASS_A
|
在這一個文件中使用宏定義:
1
2
|
#undef TEST_A 1
#undef TEST_CLASS_A clase T1
|
1
|
#define TEST_A 1
|
::
在TEST.h(或TEST.cpp)中1就是TEST_A,clase T1就是TEST_CLASS_A clase;只在TEST中有效。
程序示例:
修改已經宏定義的
符號常量的值:
1
2
3
4
5
6
7
8
9
10
|
#include <stdio.h>
int
main(
void
)
{
#define MAX 200
printf
(
"MAX= %d\n"
,MAX);
#undef MAX
#define MAX 300
printf
(
"MAX= %d\n"
,MAX);
return
0;
}
|
#if
1
2
3
4
5
|
#if 表達式
// 程序段1
#else
// 程序段2
#endif
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#define LETTER 1
int
main(
int
argc,
char
* argv[] )
{
char
str[20] =
"C Language"
;
char
c;
int
i=0;
while
( (c=str[i])!=
'\0'
)
{
i++;
#if LETTER
if
(c>=
'a'
&&c<=
'z'
) c=c-32;
#else
if
(c>=
'A'
&&c<=
'Z'
) c=c+32;
#endif
printf
(
"%c"
,c);
}
return
0;
}
|
運行結果為:
1
|
C LANGUAGE
|
現在先定義LETTER為1,這樣在預處理
條件編譯命令時,由於LETTER為真(非零),則對第一個if語句進行編譯,運行時使小寫字母變大寫。如果將程序第一行改為:
1
|
#define LETTER 0
|
1
|
c language
|