编译预处理指令
#开头的是编译预处理指令
它们不是C语言的成分,但是C语言程序离不开它们
#include 用来引入头文件
#define 用来定义宏
宏定义
#define PI 3.14159
宏定义格式:
#define 名字 <值>
- 注意没有;结尾,因为不是C的语句
- 名字必须是单词,值可以是各种东西,比如:123,“abc”,"%d"等。
- C语言编译器开始编译之前,预处理程序会把指令换成值(在编译选项参数中加–save-temps参数可以保留.i预处理文件)
C语言中预定义的宏
宏 | 说明 |
---|---|
__DATE__ | 当前源文件的编译日期 |
__FILE__ | 当前源文件的名称 |
__func__ | 以 char 数组形式返回封闭函数的未限定和未修饰名称。 |
__LINE__ | 当前源文件中的行号。 行号是一个十进制整数文本。 它可以随 #line 指令改变。 |
__STDC__ | 指示符合 ANSI/ISO C99 标准。 只有提供了 /Za 编译器选项但未编译 C++ 代码时才定义为整数型常数 1;否则是不确定的。 |
__TIME__ | 当前源文件的最新编译时间。 该时间是 hh:mm:ss 形式的字符串文本。 |
__TIMESTAMP__ | 当前源文件的最近一次的修改日期和时间 |
#include <stdio.h>
#define PI 3.14
#define PI2 PI*2
#define FORMAT "%.2f\n"
int main(int argc,char const *argv[])
{
printf(FORMAT,PI2);
printf("%s\n",__DATE__);
printf("%s\n",__FILE__);
printf("%s\n",__func__);
f();
printf("%d\n",__LINE__);
printf("%d\n",__STDC__);
printf("%s\n",__TIME__);
printf("%s\n",__TIMESTAMP__);
return 0;
}
int f(void){
printf("%s\n",__func__);
}
带参数的宏
宏可以像函数一样带参数,参数不带类型
#define square(x) ((x)*(x))
#include <stdio.h>
#define square(x) ((x)*(x))
int main(int argc,char const *argv[])
{
int i = 2;
printf("%d\n",square(i+0));
double j = 3.14;
printf("%.4f\n",square(j));
return 0;
}
常见错误
#define square(x) (x*x)
参数之间没有带(),像上述(i+0)计算的结果就有问题
基本原则
1、每个参数都要括号
- 整个值要括号
- 每个参数出现的地方都要括号
2、宏的结尾不需要分号
部分宏被inline函数替代,inline函数资料参考
https://blog.youkuaiyun.com/Sudley/article/details/94996841