C 为什么要三次调用下面的函数
我曾尝试过调试,但没有成功,我不明白为什么第二个printf()调用增量()三次,而第一个调用两次C 为什么要三次调用下面的函数,c,C,我曾尝试过调试,但没有成功,我不明白为什么第二个printf()调用增量()三次,而第一个调用两次 #include <stdio.h> #define MAX(a, b) ( (a) > (b) ? (a) : (b) ) int increment(){ static int i = 42; i += 5; printf("increment returns %d\n", i); // 47, 52, 57 return i; } in
#include <stdio.h>
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
int increment(){
static int i = 42;
i += 5;
printf("increment returns %d\n", i); // 47, 52, 57
return i;
}
int main( int argc, char ** argv ) {
int x = 50;
// parameters compute from right to left side
printf("max of %d and %d is %d\n",
x, //3rd: 50
increment(), //2nd: 52
MAX(x, increment()) //1st: 50,47 -> 50
);
printf("max of %d and %d is %d\n",
x, //3rd: 50
increment(), //2nd: 62
MAX(x, increment()) //1st: 50,57 -> 57
);
return 0;
}
因为你这么说:
MAX(x, increment())
评估为
( (x) > (increment()) ? (x) : (increment()) )
如果条件未满足,则计算:
之后的部分,从而再次调用函数。因为宏:MAX(x,increment())
展开为:
( (x) > (increment()) ? (x) : (increment()) )
类似地,宏的下一个调用将展开
变量i
是静态的,因此初始初始化时使用i=42
,其递增值在不同的函数调用中保持不变
下面是一个函数调用序列,显示了由increment()
函数返回的i
值
increment(); i = 47, First call
x 52 x i
( (50) > (52) ? (50) : (52) )
Second // ^ not called because condition is True 50 > 52
第二次:
increment(); i = 57, Third call
x i x i
( (50) > (62) ? (50) : (67) )
Forth Fifth // called because condition is False 50 > 62
这个顺序是根据你的输出
重要注意事项:由于函数参数的求值顺序未定义,因此使用不同的编译器可能会有不同的输出
使用宏非常“危险”:各种奇怪的事情都可能发生。例如,在您的例子中,如果调用MAX(f(),g())
将两次调用产生最大结果的函数,另一个函数只调用一次。由于您使用的是MAX(x,f())
,f
被调用两次,当且仅当它给出的结果大于x
特别是,宏将按如下方式展开:
( (x) > (increment())? (x):(increment()) )
因此,如果条件(需要对
increment()
进行一次求值的测试),则执行increment()
以产生结果。这是因为宏将展开为((x)>(increment())?(x):(increment())
但是,这不是唯一的问题,您的代码包含未定义的行为。。参数不会按指定的顺序进行计算。这是宏中副作用的经典示例。您的
max
宏示例如下:
x > increment() ? x : increment()
一旦增量()的返回值大于x
时,三元运算符将调用increment()
两次,一次用于评估条件,一次用于评估错误部分(这是第二个increment()
)
在这种情况下,最好使用maxmax\u int
函数:
int max_int(int a, int b)
{
return a > b ? a : b;
}
调用此函数而不是MAX
将确保您的参数只计算一次。((a)>(b)?(a):(b))
在这个语句中,如果b代表一个函数,如果(a>b)为true,则只调用一次,如果(a>b)为false,则调用两次:一个用于给出比较参数(b在“(a)>(b)”中),另一个用于返回整个语句的值(b在宏的后半部分)
在您的例子中,有一个额外的调用“b”(increment),用于在每个测试中提供第二个整数参数
总共是两次和三次。如果将最大增量值放在不同的变量中,会发生什么情况?请注意,您的代码包含未定义的行为。请尝试修复它,因为它可能导致恶性错误。恐怕没有参数传入此变量program@StefanoFalasca嗯,我可能错了,瓦拉格人的评价和其他人不一样吗参数?varargs在哪里?@StefanoFalasca调用
printf()
maybe?@StefanoFalasca哈哈,没问题:)“宏的使用非常不推荐”据我所知不是这样。虽然可能会发生一些你应该注意的奇怪的事情,但它们被广泛用于各种各样的事情。
int max_int(int a, int b)
{
return a > b ? a : b;
}