C语言预处理、宏定义等
对于源程序编译得到可执行文件的过程:
- 预处理:
1.1替换头文件
1.2删除注释
1.3替换#define 符号
1.4 得到.i文件
-
编译: 将.i文件转化为汇编语言文件.0 。
-
汇编:汇编语言文件转化为二进制指令文件 .obj;形成符号表(函数,文件位置)
-
链接:符号表的重定位和合并,合并段表。
define c语言初始标识符号
- FILE :源文件所在路径;
- TIME :文件运行时刻,可以用来做日志。
```#include <stdio.h>
int main()
{
printf("%s\n",__FILE__);
printf("%s\n",__TIME__);
printf("%d",__STDC__);
return 0;
}
#undef ;移除一个宏定义
#define 自定义标识符
```#include <stdio.h>
#define max 10
#define ll long long int //简化代码长度
#define do_for() for(; ;) //相当于只是缺少for语句内部语句
#define CASE break;case //case 语句后面自动跟上一个break
#define定义宏
宏定义中若是参数是表达式,为了防止错误请加上括号。
```#include <stdio.h>
#define max 10
#define ll long long int //简化代码长度
#define do_for() for(; ;) //相当于只是缺少for语句内部语句
#define CASE break;case //case 语句后面自动跟上一个break
#define Sqrt(x) x*x
int main() {
ll a = max;
ll b = 5;
printf("%d %d\n", Sqrt(b), Sqrt(5 + 1));
//Sqrt(5+1) 在宏中是参数替换不是传参,所以是5+1*5+1=11;
printf("%s\n", __FILE__);
printf("%s\n", __TIME__);
printf("%d", __STDC__);
return 0;
}
注意:
宏定义中可以出现其他#define 的标识符号,但是不能出现递归
字符串常量中的#define 定义的表示符号,不会被替换。
预编译指令:
```#include <stdio.h>
#define JUDAGE(a,b,c){\
if(a>b) b=a; \
if(b>c) c=b;\
printf("%.3f",c);\
}
#define DEBUG1
int main()
{
float a,b,c;
scanf("%f %f %f",&a,&b,&c);
if(a>b) b=a;
if(b>c) c=b;
#ifdef DEBUG //若表标识符已经被定义则编译指令为1,执行编译否则不编译
//ifndef 标识符//标识标识符没有定义才执行语句编译
printf("%.3f\n",c);
#endif
#if 0
JUDAGE(a,b,c);
#endif
return 0;
}
技巧一:使用#把宏参数变成字符串
```#include <stdio.h>
#define max 10
#define ll long long int //简化代码长度
#define do_for() for(; ;) //相当于只是缺少for语句内部语句
#define CASE break;case //case 语句后面自动跟上一个break
#define Sqrt(x) x*x
#define printf1(a) printf("the value "#a" is %d\n",a)
//#a 变成参数对应的参数符号字符串
int main() {
ll a = max;
ll b = 5;
printf("%d %d %d\n", Sqrt(b), Sqrt(5 + 1),Sqrt(5+1));
//Sqrt(5+1) 在宏中是参数替换不是传参,所以是5+1*5+1=11;
printf1(a);
printf1(b);
return 0;
}
技巧二:##可以连接两个符号合并为一个符号,宏定义支持两个分开的符号连接起来作为一个标识符。
```#include <stdio.h>
#define max 10
#define ll long long int //简化代码长度
#define Sqrt(x) x*x
#define printf1(a) printf("the value "#a" is %d\n",a)
//#a 变成参数对应的参数符号字符串
#define CAT(X,Y) X##Y
int main() {
ll a = max;
ll b = 5;
ll inta=456;
printf("%d\n",CAT(int,a));
return 0;
}
宏与函数的不同:
1、宏没有调用和返回的时间开销,
2、宏支持多种类型参数(类似函数模板)
3、宏无法调试
4、宏参数可能有副作用
```int x;
x++//副作用