下面介紹一些 C/C++ 中幾個不常見卻有用的預編譯和宏定義。
error
語法格式如下:
#error token-sequence
其主要的作用是在編譯的時候輸出編譯錯誤信息token-sequence,從方便程序員檢查程序中出現(xiàn)的錯誤。
例:
#include "stdio.h"
int main(int argc, char* argv[])
{
#define CONST_NAME1 "CONST_NAME1"
printf("%s\n",CONST_NAME1);
#undef CONST_NAME1
#ifndef CONST_NAME1
#error No defined Constant Symbol CONST_NAME1
#endif
{
#define CONST_NAME2 "CONST_NAME2"
printf("%s\n",CONST_NAME2);
}
printf("%s\n",CONST_NAME2);
return 0;
}
在編譯的時候輸出如編譯信息
fatal error C1189: #error : No definedConstant Symbol CONST_NAME1
pragma
其語法格式如下:
# pragma token-sequence
此指令的作用是觸發(fā)所定義的動作。如果token-sequence存在,則觸發(fā)相應的動作,否則忽略。此指令一般為編譯系統(tǒng)所使用。例如在Visual C++.Net 中利用# pragma once 防止同一代碼被包含多次。
line
此命令主要是為強制編譯器按指定的行號,開始對源程序的代碼重新編號,在調(diào)試的時候,可以按此規(guī)定輸出錯誤代碼的準確位置。
例:
#include "stdio.h"
void Test();
#line 10 "Hello.c"
int main(int argc, char* argv[])
{
#define CONST_NAME1 "CONST_NAME1"
printf("%s\n",CONST_NAME1);
#undef CONST_NAME1
printf("%s\n",CONST_NAME1);
{
#define CONST_NAME2 "CONST_NAME2"
printf("%s\n",CONST_NAME2);
}
printf("%s\n",CONST_NAME2);
return 0;
}
void Test()
{
printf("%s\n",CONST_NAME2);
}
提示如下的編譯信息:
Hello.c(15) : error C2065: 'CONST_NAME1' :undeclared identifier
表示當前文件的名稱被認為是Hello.c, #line 10 "Hello.c"所在的行被認為是第10行,因此提示第15行出錯。
運算符#和##
在ANSI C中為預編譯指令定義了兩個運算符——#和##。
# 的作用是實現(xiàn)文本替換(字符串化)
例:
#define HI(x) printf("Hi,"#x"\n");
void main()
{
HI(John);
}
程序的運行結(jié)果:
Hi,John
在預編譯處理的時候, #x的作用是將x替換為所代表的字符序列。(即把x宏變量字符串化)在本程序中x為John,所以構(gòu)建新串“Hi,John”。
##的作用是串連接
例:
#define CONNECT(x,y) x##y
void main()
{
int a1,a2,a3;
CONNECT(a,1)=0;
CONNECT(a,2)=12;
a3=4;
printf("a1=%d\ta2=%d\ta3=%d",a1,a2,a3);
}
程序的運行結(jié)果為:
a1=0 a2=12 a3=4
在編譯之前, CONNECT(a,1)被翻譯為a1, CONNECT(a,2)被翻譯為a2。
標準C的預處理器定義了一些宏,這些宏的名稱都是以兩個下劃線字符開始
和結(jié)束的。程序員不能取消這些預定義宏的定義或?qū)λ鼈冞M行重新定義。
幾個常用的預定義宏:
__LINE__ 當前源程序行的行號,用十進制整數(shù)常量表示
__FILE__ 當前源文件的名稱,用字符串常量表示
__DATA__ 編譯時的日期,用“Mmm dd yyyy”形式的字符串常量表示
__TIME__ 編譯時的時間,用“hh:mm:ss”形式的字符串常量表示。
(注意,前后是各兩個下劃線)
更多建議: