0

I'm fairly new to C programming and I don't get why swapping values of two variables when using a function shouldn't be the same as the normal way without using pointers.

#include <stdio.h>
void swap(int*, int*); //Swap function declaration

int main()
{
   int x, y;

   printf("Enter the value of x and y\n");
   scanf("%d%d",&x,&y);

   printf("Before Swapping\nx = %d\ny = %d\n", x, y);

   swap(&x, &y);

   printf("After Swapping\nx = %d\ny = %d\n", x, y);

   return 0;
}
//Swap function definition
void swap(int *a, int *b)
{
   int t;

   t  = *b;
   *b = *a;
   *a = t;
}

Why shouldn't it just be:

t = b;
b = a;
a = t;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
EL02
  • 282
  • 2
  • 9
  • 2
    Because that just swaps the local pointers, not the data in the memory they point to. – Barmar Jan 25 '21 at 23:26
  • @Barmar So what you're saying is that those swapped variables are only accessible within the function and not in the global scope? – EL02 Jan 25 '21 at 23:33
  • That's true, but not the point. Swapping pointers doesn't swap the contents of the variables they point to. – Barmar Jan 25 '21 at 23:36
  • Here's an analogy: Suppose you have a blue box in your left hand, and a red box in your right hand, and you want to swap their contents. Switching the hands they're in won't do that. The hands are like pointers. – Barmar Jan 25 '21 at 23:37
  • Because with pointers, you always have to remember the distinction between *the pointer* versus *what it points to*. `b = a` copies the pointers. (But that's not what you want.) `*b = *a` copies the pointed-to value: that's what you want. – Steve Summit Jan 26 '21 at 00:01

3 Answers3

2

b = a copies the value of a to b.

*b = *a copies the value in the memory pointed to by a to the memory pointed to by b.

When a and b are int * they contain the memory address of an integer, a pointer. In this case b = a will simply make b point at the same memory as a. *b says to "dereference" b and use the value it is pointing at. So *b = *a says to copy the value that a is pointing at to the memory b is pointing at.

This is all necessary because you are working inside a function isolated from the rest of the code. That function wants to change the value of two variables outside its scope, so it must do that by manipulating their memory.

int *a, int *b is like having two buckets named a and b. b = a makes buckets a and b the same. *b = *a copies what's in bucket a to bucket b. swap wants to swap what's in x and y's buckets.


Had you passed by value like so...

swap(x, y);

void swap(int a, int b)
{
   int t;

   t = b;
   b = a;
   a = t;
}

The values of x and y would be copied to a and b. The values of a and b would be swapped to no effect on x and y.

Had you passed pointers, but not dereferenced, like so...

swap(&x, &y);

void swap(int *a, int *b)
{
   int *t;

   t = b;
   b = a;
   a = t;
}

Now the memory address of x and y are copied to a and b. a points to the same memory as x, b points to the same memory as y. But b = a swaps these addresses between a and b to no effect on x and y.

swap(&x, &y);

void swap(int *a, int *b)
{
   int t;

   t = *b;
   *b = *a;
   *a = t;
}

The memory address of x and y is still copied to a and b. a has the address of x, b has the address of y. *b = *a changes the value of the memory they point to, the same as y and x. It is effectively y = x. x and y see the change.

Schwern
  • 153,029
  • 25
  • 195
  • 336
0

Consider the following program

#include <stdio.h>

void f( int x )
{
    x = 20;
    
    printf( "Within f( int ) x = %d\n", x );
}

int main(void) 
{
    int x = 10;
    
    printf( "Before call of f( int ) x = %d\n", x );
    
    f( x );
    
    printf( "After  call of f( int ) x = %d\n", x );
    
    return 0;
}

The program output is

Before call of f( int ) x = 10
Within f( int ) x = 20
After  call of f( int ) x = 10

As you can see the variable x declared in main was not changed by calling the function.

The variable x was passed to the function f by value. That is the function parameter x (another variable that has the function block scope) was initialized by the value of the variable x declared in main.

So the function changed its local variable (parameter) x. The variable x declared in main stays unchanged.

You can imagine the function definition and its call the following way

f( x );

//...

void f( /*int parameter_x*/ )
{
    int parameter_x = x;

    patameter_x = 20;
    
    printf( "Within f( int ) patameter_x = %d\n", patameter_x );
}

To change the variable x declared in main you have to pass it by reference. In C passing by reference means passing an object indirectly through a pointer to it.

Here is a demonstrative program.

#include <stdio.h>

void f( int *px )
{
    *px = 20;
    
    printf( "Within f( int ) x = %d\n", *px );
}

int main(void) 
{
    int x = 10;
    
    printf( "Before call of f( int ) x = %d\n", x );
    
    f( &x );
    
    printf( "After  call of f( int ) x = %d\n", x );
    
    return 0;
}

The program output is

Before call of f( int ) x = 10
Within f( int ) x = 20
After  call of f( int ) x = 20

Dereferencing the pointer px

    *px = 20;

the function gets a direct access to the pointed object that is to the object x declared in main.

So if you want to exchange values of two variables declared in main within a function like swap you need to pass the corresponding objects by reference to the function. Otherwise the function will deal with copies of values of the variables declared in main.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Abstracting from dupe this swap has minimal sense. Use macro:

#define SWAP(a,b,type) do{type c__c__c; c__c__c = (a); (a) = (b); (b) = c__c__c;}while(0)
0___________
  • 60,014
  • 4
  • 34
  • 74