- 一、预处理器
- 二、语法
- 三、原理
- 三、参数宏
- 四、类型宏
- 五、#和##运算符
- #运算符
- ##运算符
- 六、预定义宏
一、预处理器
预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理。
所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前。预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾。
#define 预处理指令用于创建符号常量。该符号常量通常称为宏,指令的一般形式是:
#define marco-name replace-text三、原理
考虑以下代码:
#includeusing namespace std; #define PI 3.1415926 int main(){ cout< 及
#includeusing namespace std; const double PI=3.1415926; int main(){ cout< 它们的运行结果都是3.1415926,有什么不同呢?
对于第一段代码,如果我们对其编译(GCC),使用 -E 选项进行编译,并把结果重定向到 test.p。打开test.p,将会看到它已经包含大量的信息,而且在文件底部的值被改为如下:$ gcc -E test.cpp > test.p ... int main (){ cout<<3.1415926; return 0; }而第二段代码编译后却与源代码一样。
三、参数宏
可以看出,#define的原理是将define以后的全部marco-name替换成replace-text。您可以使用 #define 来定义一个带有参数的宏(类似于函数):
#includeusing namespace std; #define MIN(a,b) (a 程序输出51,需要注意,参数宏不需要return语句,因为define的本质是替换,所有上述代码编译后实际是:
... int main(){ cout<<(5<10)?5:10; }在宏中没有;,但有时可能需要:
#includeusing namespace std; #define OUTPUT(s) cout< 在这里,分号是必要的。
四、类型宏如下:
#includeusing namespace std; #define int long long int a,b,c; .... 这里的#define对于许多oier应该不陌生,作用即将以下所有int换为long long,防止有时手残写错,需要注意,此时main()必须声明为signed main(),signed即有符号整形,因为main()不能是int_64。
五、#和##运算符# 和 ## 预处理运算符在 C++ 和 ANSI/ISO C 中都是可用的。
注意:#和##运算符不可重载六、预定义宏
- #运算符
# 运算符(前置一元运算符)会把 replacement-text 令牌转换为用引号引起来的字符串。
#includeusing namespace std; #define ToSTR(x) #x int main(){ cout< 结果:
Hello World!看看它是如何工作的,编译这句:
cout<成了:
cout<<"Hello World!";- ##运算符
##运算符(二元运算符)用于连接两个令牌。
#includeusing namespace std; #define CONNECT(a,b) a##b int main(){ int xy=114514; int x=123,y=456; cout< 结果:
114514看看它是如何工作的,同理,编译器将:
cout<转换成了:
cout<C++提供了以下预定义宏2:
宏 作用 __LINE__3 返回当前行号 __FILE__ 返回当前文件名 __DATE__ 返回一个形同month/day/year的字符串,表示日期 __TIME__ 返回一个形同hour:minute:second的字符串,表示时间 例:
#includeusing namespace std; int main(){ cout << "__LINE__:" << __LINE__ << endl << "__FILE__:" << __FILE__ << endl << "__DATE__:" << __DATE__ << endl << "__TIME__:" << __TIME__ << endl; return 0; } 结果:
__LINE__:4 __FILE__:D:VSprojecttestmain.cpp __DATE__:Nov 26 2021 __TIME__:12:24:23
@HaohaoCppDebuger|寻兰
2021/11/26-----THE END-----
THANK YOU !
参数宏不需要说明参数类型,因此即使你调用MIN("Hello","World"),程序也不会报错,只是结果因编译器而异。这也是参数宏和函数的区别——有无类型检查。 ↩︎
如果使用VSC++查看这些宏的定义,编译器会显示找不到。 ↩︎
下划线_是必须的,下同。 ↩︎



