我不明白为什么这个程序会打印这些结果

时间:2018-12-04 17:08:02

标签: c

该程序输出-8 -4,但是我想知道为什么,为什么编译器没有显示关于使用哪个函数的错误?为什么结果不同。 我对定义这样的功能了解不多,有人也可以解释吗

#include <stdio.h>
#include <stdlib.h>

int foo(int x, int y);

#define foo(x, y) x/y + x

int main() {
    int i = -6, j = 3;
    printf("%d ", foo(i + j, 3));
#undef foo
    printf("%d\n", foo(i + j, 3));
}

int foo(int x, int y) {
    return x/y + x;
}

4 个答案:

答案 0 :(得分:5)

如果您预处理对宏foo的调用,则会得到:

i + j / 3 + i + j

使用您的值,那就是

(-6) + 3 / 3 + (-6) + 3

哪个值为-8

当您取消定义宏foo时,您将获得函数foo,在其中执行行return x + y / x

使用i = -6j = 3,您将得到:

(-3) / 3 + -3

哪个是-4

进一步阅读:

答案 1 :(得分:3)

由于运算符优先级规则,这两个功能不相同。

记住一个#define宏会进行内嵌替换,并且参数本身会按原样替换:

#include <stdio.h>
#include <stdlib.h>

int oper_fn(int x, int y) {
    return x/y + x;
}

#define oper_def(x, y) x / y + x

int main() {
    int i = -6, j = 3;
    printf ("oper_fn=%d ",oper_fn( i + j , 3));
    printf ("oper_def=%d\n",oper_def( i + j , 3));
}

这最终是在评估:

i + j / 3 + i + j

由于操作顺序,其计算结果为:

i + (j / 3) + i + j

这不是您想要的,而是您想要的:

(i + j) / 3 + (i + j)

这意味着您需要宏:

#define oper_def(x, y) ((x) / (y) + (x))

这是正常编写宏的方法,以避免像这样的歧义和不一致。

答案 2 :(得分:0)

您的#define与函数完全不同。评估为

printf ("%d ",i + j / 3 + i + j);

在评估传递给函数的参数时,自然会产生与函数不同的结果,因此将x视为-3,将y视为3。

答案 3 :(得分:0)

定义时

 #define foo(x, y) x / y + x

然后做

 foo( i + j , 3));

你得到

 i + j / 3 + i + j

 -6 + 3/ 3 + 3 -6 = -6 + 1 + 3 - 6 = -8

当您调用函数foo时,首先会评估i + j

如果您想要正确的定义行为,请执行

#define foo(x, y) ((x / y) + x)

您刚刚发现了为什么define d个函数不是一个好主意