0

I'm having a problem trying to interchange the values of two variables using a function that executes two different approaches.

The first approach is show below:

void interchange_values(int *first_number_pointer, int *second_number_pointer) {
   
    int temporal_variable;

    temporal_variable = *first_number_pointer;
    *first_number_pointer = *second_number_pointer;
    *second_number_pointer = temporal_variable;

};

And this works as expected.

But the second approach doesn't interchange the values of the two variables.

void interchange_values(int *first_number_pointer, int *second_number_pointer) {
     
    int *temporal_ptr = first_number_pointer;
    first_number_pointer = second_number_pointer;
    second_number_pointer = temporal_ptr;
};

Can someone explain me why I'm not interchanging the values of the original variables in the second approach?

5
  • You're only changing the addresses of first_number_pointer and second_number_pointer in interchange_values, not the addresses of the calling function. For that you'd need a pointer to pointer (e.g. int **). How are you calling interchange_values? It won't work if the caller isn't using pointers. Commented Jul 31, 2023 at 19:49
  • 5
    It doesn't work for the same reason that it wouldn't work if you just passed integers instead of pointers -- you're just changing the local variables, not the caller's variables. Commented Jul 31, 2023 at 19:53
  • See stackoverflow.com/questions/40163283/… for example. Commented Jul 31, 2023 at 19:55
  • As a warmup, consider the following code: void f(int x) { x = 5; } int main(void) { int y = 6; f(y); printf("%d\n", y);. Do you understand why the value printed is 6 and not 5? Commented Jul 31, 2023 at 20:23
  • 1
    you are just juggling pointers in the second one Commented Jul 31, 2023 at 21:27

2 Answers 2

0

For the second approach, you need to pass the pointer to pointer to an integer. You will also need to define pointers to your integer variables (as you will exchange the references and you need objects which will hold the references) It will not exchange values of your integers.

To modify the object passes to the function you need pass the reference to it (pointer).

void interchange_values(int **first_number_pointer, int **second_number_pointer) {
   
    int *temporal_variable;

    temporal_variable = *first_number_pointer;
    *first_number_pointer = *second_number_pointer;
    *second_number_pointer = temporal_variable;

};
int main(void)
{
    int a = 5; int b = 10;
    int *pa = &a; int *pb = &b;

    printf("Before: a = %d b = %d\n", a , b);
    printf("Before: *pa = %d *pb = %d\n", *pa , *pb);
    interchange_values(&pa, &pb);
    printf("After:a = %d b = %d\n", a , b);
    printf("After: *pa = %d *pb = %d\n", *pa , *pb);
}

Result:

Before: a = 5 b = 10
Before: *pa = 5 *pb = 10
After:a = 5 b = 10
After: *pa = 10 *pb = 5

https://godbolt.org/z/vfrfzK1r9

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

Comments

0

In the first example you are passing the variables for the desired change by reference (via pointer).

The pointers themselves are passed by value which, as others have mentioned, means that their scope is local to that function.

This is why in the C standard library you see functions that accept pointer pointers when there is a need to potentially change not only the base data but also potentially the pointer itself. An example of such a function would be the root of trees included in search.h. Any function that could reallocate memory and physically relocate the root in memory accepts a pointer pointer, because you pass the pointer by reference. tsearch might need to move the root, so it accepts a pointer by reference, while twalk wouldn't ever modify the root so it accepts the pointer by value. Link to man page for the described tree functions

Edit: Simple Example

#include <stdio.h>
#include <stdlib.h>

void interchange_pointers_by_reference(int ** first, int ** second)
{
    int * tmp_ptr = *first;
    *first = *second;
    *second = tmp_ptr;
}

int main()
{
    int * foo = malloc(sizeof(*foo));
    int * bar = malloc(sizeof(*bar));
    *foo = 1;
    *bar = 2;
    printf("foo = %d, bar = %d\n", *foo, *bar);
    printf("running function\n");
    interchange_pointers_by_reference(&foo, &bar);
    printf("foo = %d, bar = %d\n", *foo, *bar);
    return 0;
}
scott@scott-G3:~/tmp$ gcc -o example example.c
scott@scott-G3:~/tmp$ ./example 
foo = 1, bar = 2
running function
foo = 2, bar = 1

1 Comment

good feedback, I'll update

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.