一.预定义符号

cpp
"add.c"
#include <stdio.h>
void test()
{
printf("test():%s\n", __FILE__);
}
cpp
extern void test();
int main()
{
printf("%s\n", __FILE__);
printf("%s\n", __DATE__);
printf("%s\n", __TIME__);
printf("%d\n", __LINE__);
//printf("%d\n", __STDC__);//说明VS不支持ANSIC
test();
return 0;
}

当前被定义的文件的路径


二.#define定义常量


这里不进行任何计算,只进行替换






三.#define定义宏



cpp
#define SQUARE(X) X*X
int main()
{
int a = 5;
printf("%d\n", SQUARE(a));
return 0;
}
这样看着没啥问题
cpp
#define SQUARE(X) X*X
int main()
{
int a = 5;
printf("%d\n", SQUARE(a+1));
return 0;
}

替换成这样就肯定算不对了

cpp
#define SQUARE(X) (X)*(X)
int main()
{
int a = 5;
printf("%d\n", SQUARE(a+1));
return 0;
}

我们可以尝试写一个宏,是参数的2倍



四.带有副作用的宏参数



cpp
//写一个宏,求2个整数的较大值
#define MAX(x,y) ((x)>(y)?(x):(y))
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);// 3 5
int m = MAX(a++, b++);
printf("m = %d\n", m);
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}

五.宏替换的规则

六.宏函数的对比





cpp
#define MALLOC(n, type) (type*)malloc(n*sizeof(type))
int main()
{
int *p = (int*)malloc(10*sizeof(int));
int* p = MALLOC(10, int);
return 0;
}

七.# 和
1.#运算符

cpp
int main()
{
printf("hello world\n");
printf("hello ""world\n");
return 0;
}
这两个字符串打印都是一样的
cpp
#define PRINT(val, format) printf("the value of "#val" is " format"\n", val)
int main()
{
int a = 10;
//printf("the value of a is %d\n", a);
PRINT(a, "%d");
printf("the value of ""a"" is ""%d""\n", a);
int b = 20;
//printf("the value of b is %d\n", b);
PRINT(b, "%d");
float f = 3.5f;
//printf("the value of f is %f\n", f);
PRINT(f, "%f");
return 0;
}

#val的意思就是不要解析成值,而是将其转化成为字符串
2.##运算符







八.命名约定

九.#undef

cpp
#define MAX 100
int main()
{
printf("%d\n", MAX);
#undef MAX
//printf("%d\n", MAX);
#define MAX 1000
printf("%d\n", MAX);
return 0;
}
十.命令行定义

cpp
int main()
{
int arr[SZ];
int i = 0;
for(i=0; i<SZ; i++)
{
arr[i] = i;
}
for(i=0; i<SZ; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

这样就能进行编译了
十一.条件编译

cpp
#include <stdio.h>
#define __DEBUG__
int main()
{
int i = 0;
int arr[10] = {0};
for(i=0; i<10; i++)
{
arr[i] = i;
#ifdef __DEBUG__
printf("%d\n", arr[i]);//为了观察数组是否赋值成功。
#endif //__DEBUG__
}
return 0;
}
放开__DEBUG__,就能进行printf













十二.头文件的包含
1.本地文件包含

先去库里面找,找不到再到自己的安装路径下找
2.库文件包含


" "是兼容<>的,但是" "效率会变低
3.嵌套文件包含



再.h文件中加上这个,那么我们就能定义__TEST_H__,这样就只拿到一次了

十三. 其他预处理指令

