2016 - 2024

感恩一路有你

关于c语言宏定义的问题呢(c语言宏定义时要注意什么?)

浏览量:3834 时间:2023-02-20 19:34:35 作者:采采

关于c语言宏定义的问题呢(c语言宏定义时要注意什么?)

c语言宏定义时要注意什么?

定义的宏需要注意以下八点:

1.预处理器直接用文本替换宏。

2.宏中使用的参数将不会被评估和计算。

3.预处理器不会检查宏定义的语法,宏定义中的语法错误只能由编译器检测。

4.宏定义的效率高于函数调用(宏不占内存,函数占内存)。

5、宏的使用会带来一些副作用。

6.#define定义的宏可以出现在程序的任何地方,而#define定义的代码可以使用这个宏。

7.#define表达式的使用类似于函数调用,但宏比函数更强大,也更容易出错。

8.递归定义不能出现在宏表达式中。

二、代码测试(ubuntu10 gcc平台)

C语言的宏定义用起来有什么要注意的?为什么很多宏用do{}while(0)包围?

谢谢你。

C语言中的宏定义可以像函数一样接收参数(这个宏定义通常被称为 "函数式宏定义和),但它可以 不要像函数一样提供参数的类型检查,这对一些程序员来说是不安全的。

"函数式宏定义和在C语言中

然而,函数式宏定义并不。;t不在乎参数类型,有时候用来写一些适用性更广的C语言代码,比如:

上面C语言的宏定义代码实现了一个max()方法,该方法接收两个参数并返回较大的一个。max()方法不支持。;t不关心参数的类型,所以__a和__b可以是int、char、double等数据类型。

如果max()方法提供的函数是用C语言函数的形式写的,会有点麻烦,程序员要为每种数据类型实现一个max()函数。更糟糕的是,C语言不支持函数重载,所以一旦使用了函数名max(),其他函数就不能再使用了,所以相关的C语言代码可能如下:

相比之下,使用define宏来定义max()方法显然更方便。但C语言中的宏定义不提供参数类型检查也是一个缺点,可能会导致程序不安全,读者不要忽略这一点。因此,如果你不 不一定要用define宏定义来解决问题,应该尽可能使用函数,如果想得到更高效的代码,可以使用inline function。

我在上一篇文章中详细讨论了inline函数。

C语言中使用宏定义的注意事项

虽然 "函数式宏定义和在C语言中非常类似于函数,它实际上不是函数。读者一定不能忽视这一点,否则可能会写出一个存在隐患甚至严重错误的C语言程序。请看下面的例子:

超过这段C语言代码编译执行后会输出什么?

在main()函数中,变量A和B被初始化为2。然后调用max()宏,传递的参数分别是a和b。粗略来说,此时执行max( a,b)相当于执行max(3,2),那么上面的C语言程序会输出3,2,3?获得答案的最简单、最粗暴的方法是编译并执行这段代码。请看:

没有经验的读者看到实际的产量估计会感到惊讶。为什么A和M不是3而是4?没有第二个地方给a加一?如前所述,编译器会将C语言中的宏定义扩展到被调用的地方,而不是像函数一样编译后再通过call指令调用。使用gcc -E命令检查编译器为上述C语言代码预处理的代码,得到如下结果。请看:

很明显,这是 "函数式宏定义和在C语言中。传递给max()的参数A会展开到宏定义中的所有__a处,这就解释了为什么A和M最后等于4而不是3。

amp之间还有其他不同之处函数式宏定义和和实函数,例如 "函数式宏定义和不适合递归。

使用do{}while(0)打包代码。

虽然 "函数式宏定义和在C语言中与实函数相比有一些缺点,只要小心使用,会明显提高代码执行的效率。毕竟省去了分配释放堆栈帧、传递参数、返回值等一系列工作。正因为如此,Linux内核中有相当多的方法是通过使用define宏定义来实现的,而在内核C语言代码中, "函数式宏定义和通常是通过do { while }来实现的,例如:

为什么用do{}while(0)包装C代码?什么?;不使用do{}while(0)包装有什么问题?请看下面几行C代码:

宏定义被编译器展开后,会生成下面的C代码:

这可能与程序员 的意图,在这种情况下_ _ release(lock);不在if(cond)范围内。也许读者会说,那 这就像一个函数,can 你不就用{}包码吗?请看下面几行C代码:

问题出在spin_unlock(锁);后面的分号 " "如果你不 不要写它,它 这不像函数调用。如果写出来,会造成语法错误。——if语句将由这个 " "早点结束,否则就完了。;不要和它搭配。这样,用do{}while(0)把C语言的代码包装在 "函数式宏定义和C语言的显然是不行的。错误的。

总结

"函数式宏定义和不是实函数,它与实函数不同,如果我们不 我不明白这个。最后,我们分析了do{}while(0)常用于包装宏定义的代码的原因。读者也可以在以后的C语言程序开发中使用这种技术。

欢迎在评论区一起讨论提问。这些文章都是手工原创的。每天都有最简单的C语言、linux等嵌入式开发介绍。如果你喜欢我的文章,请关注一波。你可以看到最新的更新和以前的文章。

函数 代码 语言 参数

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。