简体   繁体   中英

i don't understand why this program prints these results

this program prints out -8 -4 but i wanna know why and why isn't the compiler showing an error about which function to use? why are the results different. i don't know much about defining a function like this can someone explain this too

#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;
}

If you preprocess the call to the macro foo , you get:

i + j / 3 + i + j

With your values, that's

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

Which evaluates to -8 .

When you undefine the macro foo , you get the function foo instead, where the line return x + y / x is executed.

With i = -6 and j = 3 , you get:

(-3) / 3 + -3

Which is -4 .

Further reading:

These two functions are not equivalent due to operator precedence rules.

Remember a #define macro does inline substitution and the arguments themselves are replaced as-is:

#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));
}

What this ends up doing is evaluating:

i + j / 3 + i + j

Due to order of operations, this evaluates as:

i + (j / 3) + i + j

That's not what you want, instead you want:

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

Which means you need the macro:

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

That's how macros are written normally to avoid ambiguity and inconsistency like this.

Your #define is not at all like the function. It evaluates as

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

which will naturally generate a different result to the function as the parameters passed the function are evaluated so it sees x as -3 and y as 3.

when you define

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

and then do

 foo( i + j , 3));

you get

 i + j / 3 + i + j

which is

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

when you call the function foo the i+j is evaluated first

if you want the correct define behavior then do

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

You have just discovered why define d functions are a bad idea

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM