简体   繁体   中英

I executed following code with macro

I executed following code

# define swap(a,b) temp=a; a=b; b=temp;
#include<stdio.h>
#include<conio.h>
main( )
{
  int i, j, temp;
  i=5;
  j=10;
  temp=0;
  if( i > j)
    swap( i, j );
  printf( "%d %d %d", i, j, temp);
}

It gave me output as 10 0 0

My question is why #define macro gets executed even after the if(i>j) statement is false ?

You need to wrap the macro into curly braces to make it work:

#define swap(a,b) {temp=a; a=b; b=temp;}

Your macro is expanded into the following

if( i > j)
  temp=a; 
a=b; 
b=temp;

And the proper solution is to use std::swap , which is a template function. You'll never run into this kind of problems with template functions

Rewrite your macro like this:

#define swap(a, b) do { int temp = (a); (a) = (b); (b) = temp; } while (0)

Note that here I declare temp inside the compound statement, if you have to deal with different (larger) types, you could declare the temp variable in another scope like you did.

You need a scope in that macro:

# define swap(a,b) do { temp=a; a=b; b=temp; } while(0)

Note: The do/while is avoiding pitfalls if it used as an expression.

But that macro is junk, anyway. It requires the variable temp declared outside, which is leading to the confusion in the first place.

In C++ just use std::swap.

Adding braces to your macro helps in scoping your code. When you write your macro without braces then it will get expand in this manner.

    if( i > j)
{
      temp=a; 
}
    a=b; 
    b=temp;

But when you add braces like this:-

#define swap(a,b) {temp=a; a=b; b=temp;}

Then your code will execute as per your expectation

Add braces for macro. It will work.

# define swap(a,b) { temp=a; a=b; b=temp;} 

If to insert the macro definition in the code then instead of

  if( i > j)
    swap( i, j );

you will get

  if( i > j)
    temp=i; i=j; j=temp;

It will look more clear if to format this code appropriately

  if( i > j) 
    temp=i; 

  i=j; 
  j=temp;

So in realty the if statement was not executed.

However the two statements that follow the if statement were executed.

So j was assigned to i and i becomes equal to 10 while temp was assigned to j and j becomes equal to 0,

This result you got.:)

If you do not want this result then you should enclose the macro definition in braces. For example

# define swap(a,b) { temp=a; a=b; b=temp; }

However it would be better to define variable temp as a local variable. For example

# define swap(a,b) { int temp=a; a=b; b=temp; }

In C++ you could use standard template function std::swap . The problem is that C has no references. Usually in C references are substituted for pointers. So the function could look as

void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
} 

And in main you could call this function as

swap( &i, &j );

In C99 you could define this function as inline

inline void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
} 

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