预定义宏&与函数对比

宏介绍

假设我们正在用C语言开发一个应用程序,有一个值或一个对象或一段代码,我们在代码中需要多次使用,然后在宏的帮助下,我们可以定义它一次并多次使用它。宏在很多地方都非常有用,可以用宏的单个值替换代码段。宏有多种类型,还有一些预定义的宏。

C语言中的宏是一段可以被宏值替换的代码。宏是在#define 预处理指令的帮助下定义的,宏没有以分号(;)结束。宏只是给某些值或表达式的一个名称,它不指向任何内存位置。每当编译器遇到宏时,它就用宏值替换宏名称。两个宏不能有相同的名称。

宏的语法如下图所示。

#define -预处理器指令

MAX -宏名称

1000 -宏值

组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code);
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序;
链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人
的程序库,将其需要的函数也链接到程序中。

C语言中的预定义宏

在C语言中有一些预定义的宏,我们可以直接在程序中使用,它们是不可修改的。

为什么使用宏而不是函数呢?

1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹
2. 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以用于>来比较的类型。

使用宏需要注意的点:

1.宏不能被调试。当你有一个宏转换为一个数字或字符串时,源代码将有宏名称,许多调试器不能看到宏转换为什么。可以用enum const T;对于“类函数”宏,因为调试器工作在“你所在的每个源行”级别,所以宏像单个语句一样工作,无论它是一条语句还是一百条。

2.宏观扩张可能导致奇怪的副作用。例如:#define SQUARE(x) ((x) * (x))并使用x2 = SQUARE(x++)。这导致了x2 = (x++) * (x++);,即使它是有效的代码[1],也几乎肯定不是程序员想要的。如果它是一个函数,那么x++就可以了,x只会增加一次。

x+1;//不带副作用
x++;//带有副作用

3.宏没有“命名空间”,所以如果有一个宏与其他地方使用的名称冲突,程序会在一个意想不到的地方进行宏替换,这通常会导致错误消息,并且无法查找错误的位置。如果你在include之前包含了这个宏,程序将会完全出错;解决方法:在宏中只使用大写名称,函数名不要全部大写。

4. 宏可能会带来运算符优先级的问题,导致程容易出现错.

宏和函数的区别

条件编译
在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的。因为我们有条件编译指令。

#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__//当标识符已经被定义过(#define命令定义),则对程序段进行编译。
printf("%d\n", arr[i]);//为了观察数组是否赋值成功。
#endif //__DEBUG__//与#ifdef成对使用,头文件结尾。
}
return 0;
}

总结

宏是一段代码或值,在程序执行之前用宏名称替换。
预处理器对预处理器指令执行不同的操作,对于宏定义,我们使用#define 预定义指令。
#define的工作是在预处理时用宏值替换宏主体。
根据需求在代码中使用宏并利用不同类型的宏是个好主意。
预定义宏可以做很多普通C编程无法做到的事情。

猜你喜欢

转载自blog.csdn.net/m0_72000264/article/details/128960623