gpt4 book ai didi

三元运算符能否扩展为 C 宏中的 if–else 语句?

转载 作者:太空宇宙 更新时间:2023-11-04 05:14:48 24 4
gpt4 key购买 nike

Define a macro MAX3 that gives the maximum of three values.

这是我想出的:

#define MAX3(a,b,c) ( ((a) > (b)) && ((a) > (c)) ) ? (a) : ((b) > (c)) ? (b) : (c)

这很难读。有没有办法用 if–else 语句编写等效的宏?

最佳答案

在标准 C99 语言中不可能有一个内部有语句的类似表达式的宏(因为在 C99 中,语句和表达式在句法和语义上都有很大不同)。

然而,GCC(以及其他一些具有受 GCC 启发的扩展的编译器,例如 clang)为此提供了一个很好的扩展:statement expressions (文档提供了与您的问题相关的示例)。有了这个扩展,你可以编写类似的代码

 #define MAX3(A,B,C) ({ int a=(A); int b=(B); int c=(C); int m; \
if (a>b) m=a; else m=b; \
if (c>m) m=c; \
m; }) /* bad macro */

但是,如果您使用该宏,例如

 int badex(int x, int y) { 
int a= x+y; int m= x*y; int d=x-y;
return MAX3(a,m,d);
}

我希望你明白为什么它不起作用(名称冲突,例如 badex 中的 a 中的 a MAX3 宏)。因此,您需要一种在每次调用宏时都具有唯一名称的方法。同样,GCC 为此提供了一个很好的扩展,即 __COUNTER__。与 concatenation 一起使用的宏(扩展为唯一数字,计数)在预处理器中。

然后你将编写如下代码

 #define MAX3(A,B,C) MAX3_COUNTED((A),(B),(C),__COUNTER__)
#define MAX3_COUNTED(A,B,C,N) ({ \
int a_##N=(A); int b_##N=(B); int c_##N=(C); \
int m_##N; \
if (a_##N>b_##N) m_##N = a_##N; else m_#N = b_##N; \
if (c_##N>m_##N) m_##N=c_##N; \
m_##N; }) /* better example */

然后第一次调用我们的宏,例如MAX3(i++,j++,k++) 可能扩展为 MAX3_COUNTED((i++),(j++),(k++),1) 使用 扩展为某些内容a_1 b_1 ...和第二次调用,例如MAX3(a,m,d) 扩展为 MAX3_COUNTED((a),(m),(d),2) 将使用 a_2 b_2 等这样更好。

当然,定义一个 static inline max3(int a, int b, int c) 函数更简洁(特别是因为副作用:您的 MAX3 宏通过像 MAX3(i++,j++,k++) etc)

这样的调用给出顽皮的效果和结果

关于这一点的一般教训是,您应该尽可能避免使用宏(首选内联函数),而当您绝对需要宏时,请注意名称冲突和扩展。

使用作为 gcc -C -E 调用的 GCC 向您显示程序的预处理形式。

关于三元运算符能否扩展为 C 宏中的 if–else 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8776547/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com