目录
一、#define定义宏
#include<stdio.h>
#define MAX(a,b) a>b?a:b
#define DS 1024
int main()
{
int a = 2;
int b = 4;
printf("%d\n",DS);
printf("%d\n",MAX(a,b));
return 0;
}
这个代码是一个#define宏定义的一个应用,咋一看MAX(a,b),很多人肯定会认为是一个函数但是它不是,它是一个宏。对于宏,我的理解是给一个操作或变量换了个名字,对于那些很长很长的数字或字母会是一个很棒的东西,它让我们方便了很多。
运用方式还是很简单的,只要在代码开始时加上#define然后像上面的代码中的DS一样就可以了,当然如果你要传参,那就得加括号了,如MAX(a,b)。
二、#define替换规则
1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
注意:
1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
三、宏和函数 的对比
宏的一些优点:
1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。
2. 函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏则可以适用于整形、长整型、浮点型等。宏是类型无关的。
宏的缺点:
当然和函数相比宏也有劣势的地方:
1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
2. 宏是没法调试的。
3. 宏由于类型无关,也就不够严谨。
4. 宏可能会带来运算符优先级的问题,导致程容易出现错。
四、#undef
如果你定义了一个宏,然后你又想删除这个宏,怎么办呢?
这个#undef就可以解决这个问题。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define MAX(a,b) a>b?a:b
#define DS 1024
int main()
{
int a = 5;
int b = 4;
printf("%d\n", DS);
printf("%d\n", MAX(a, b));
#undef DS
printf("%d\n", DS);
return 0;
}
上面这个代码就运用了一下,只需在#undef后加宏就可以了,如上代码的DS就会报错了
五、文件包含
1、本地文件包含
#include "file",像这样在#include的后面加双引号就是本地文件包含。
查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件,如果找不到就提示编译错误。
2、库文件包含
#include<stdio.h>,像这样我们基本每次开始就打的就是库文件包含。
查找策略:查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。
你们可能会问那库文件包含是不是也可以用本地文件包含的方式写呢?
答案是当然可以,只不过那样明显就会降低我们的效率,而且那样我们也不好分辨哪个是本地文件包含哪个是库文件包含了,这种吃力不讨好的事当然是不干为好啦!
感谢支持!