简体   繁体   中英

Why macros and functions work differently about same code in c

I am new to programing, and I found one interesting but difficult to find reason problem, so I am writing this post.

I was trying to write swap function:

When I write swap function in traditional way,

void swap(int *x,int *y){int t=*x;*x=*y;*y=t;}

this function works and of course,

void swap(int x,int y){int t=x;x=y;x=t;}

does not work. but when I write swap as macro,

#define swap(x,y){int t=x;x=y;y=t;} works...

why the macro can swap value though they don't use pointer?

As you've already guessed, the first one works but the second one doesn't is because in the first one, you're passing pointers to the variables that you want to swap and then use the pointers that you had passed in to swap them, effectively changing the value stored in the location that the pointers point to. But in the second one, you're just passing copies of the variables, since everything in C is passed by value.

The third one works, however, is because macros are simple text substitutions work by preprocessor token substitution (thanks to Eric Postpischil for pointing out that macros aren't just simple text substitutions). So consider this piece of code:

#define swap(x,y){int t=x;x=y;y=t;}
int main(void){
    int a=10;
    int b=20;
    swap(a,b);
}

This will be equivalent to:

int main(void){
 int a=10;
 int b=20;
 {int t=a;a=b;b=t;};
}

So there is no passing going on here. swap(a,b) is simply substituted by {int t=a;a=b;b=t;} . You can verify it by invoking cpp <file-name> .

why the macro can swap value though they don't use pointer?

Because macros and functions work differently. Functions in C use "call by value" semantics: when you pass a variable as a parameter to a function, only the value of that variable gets sent to the function -- the function can't change the variable itself. We simulate "call by reference" semantics by passing a pointer to the variable that you want to change instead of the variable itself. It's still call by value in the sense that the function still can't change the thing that was passed in, ie the address, but it can change the value stored at that address, which is what we want.

A macro, on the other hand, is just a simple text substitution; there's no function call at all. When you use the swap(x,y) macro, the preprocessor inserts the macro's definition right there into that spot. It's as if you had written {int t=x;x=y;y=t;} instead of swap(x,y) . When that code runs, it can change the values of the variables.

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