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; 
5
  • 2
    Because that just swaps the local pointers, not the data in the memory they point to. Commented Jan 25, 2021 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? Commented Jan 25, 2021 at 23:33
  • That's true, but not the point. Swapping pointers doesn't swap the contents of the variables they point to. Commented Jan 25, 2021 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. Commented Jan 25, 2021 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. Commented Jan 26, 2021 at 0:01

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

In "passed pointers but not deref" (2nd to last example),int t; --> int *t; [or something to allow t = b; to compile].
@CraigEstey Thanks.
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.

Comments

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) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.