12. 预处理指令
一、vs2019添加新的配置,
vs2019里搜索/p可找到选项“预处理到文件”,选择是,可以查看生成的预处理文件。
二、宏
预处理指令用于程序员和编译器之前的交互。
宏的处理机制:文本的查找替换。
宏的作用:
1.符号化常量,让数值或其他类型的常量更有说明性意义:
#define PI 3.14
2.符号化公式:
#define AREA(r) ((PI) * (r) * (r))
调用时double area = AREA(10);
3.代码块宏:
#define OUTPUT(x) printf(x);printf("\n")
调用时OUTPUT("Hello");
如果源代码中写为:
for (int i = 0; i < 5; ++i)
OUTPUT("Hello");
则预处理结果是:
for (int i = 0; i < 5; ++i)
printf("Hello");printf("Hello");
如果源代码中for循环加上括号,则预处理结果是:
for (int i = 0; i < 5; ++i) {
printf("Hello");printf("Hello");
}
因此推荐for,while,if等都加上花括号,即使子语句只有一行。
4.说明性宏:
#define IN
#define OUT
void foo(IN int i, OUT int array[]) {
}
5.兼容性宏:
#define INT long int
#define near
#define far
#define for if(1)for
VC6的for中,循环变量n是函数作用域,此宏将for变成if的子语句,n变为块作用域。
调用时:
for (int i = 0; i < 5; ++i) {
}
for (int i = 0; i < 5; ++i) {
}
预处理结果:
if(1)for (int i = 0; i < 5; ++i) {
}
if(1)for (int i = 0; i < 5; ++i) {
}
6.编译器预定义宏
__cplusplus
__LINE__ //当前代码所在行数
__FILE__ //当前的源文件名
_MSC_VER //编译器版本
7. # 字符串化,把记号转换为字符串
#define MYSTRING(x) #x
auto i = MYSTRING(nCount); //i是字符串”nCount”
8. ##宏参数连接,把2个记号组合成1个记号
#define DEF_INT(X) int int_##X
#define DEF_DOUBLE(X) double double_##X
#define GET_INT(X) int_##X
DEF_INT(count) = 0;
DEF_DOUBLE(count) = 0.0;
GET_INT(count) = 3;
以上3句的预处理结果:
int int_count = 0;
double double_count = 0.0;
int_count = 3;
二、Unicode
如果想在控制台打印宽字符串,要先设置locale
setlocale(LC_ALL, "zh-CN");
wprintf(L"你好Hello");
以下可以控制是否用Unicode版本
//#undef UNICODE
#ifdef UNICODE
#define TCHAR wchar_t
#define _tprintf wprintf
#define _T(X) L##X
#else
#define TCHAR char
#define _tprintf printf
#define _T(X) X
#endif // Unicode