简体   繁体   中英

Why can't I swap memory address of two variables using a function? C

static void swapAddr(int *numOne, int *numTwo)
{
    int *tmp;

    tmp = numOne;
    numOne = numTwo;
    numTwo = tmp;
}

int main(void)
{
    int a = 15;
    int b = 10;

    printf("a is: %d\n", a);
    printf("Address of a: %p\n", &a);
    printf("b is: %d\n", b);
    printf("Address of b: %p\n", &b);

    swapAddr(&a, &b);
    printf("\n");

    printf("a is: %d\n", a);
    printf("Address of a: %p\n", &a);
    printf("b is: %d\n", b);
    printf("Address of b: %p\n", &b);

    return 0;
}

When I compile and run this piece of code, the output is

a is: 15
Address of a: 0x7fff57f39b98
b is: 10
Address of b: 0x7fff57f39b94

a is: 15
Address of a: 0x7fff57f39b98
b is: 10
Address of b: 0x7fff57f39b94

Clearly the result is not what I intended, since the address does not seem to have been swapped at all.

You generally can't change the address of a variable.

Your 'swapAddr' function changes its parameter values, but these are local to the function - you're not changing anything outside the function. Perhaps the best way of understanding it is that a function parameter always receives a copy of the value that was passed to the function. In this case, you get a copy of the address of a and a copy of the address of b . You can and do change the values of the variables holding those copies ( numOne and numTwo ), and seeing as they are pointers you could (but don't) change the values that they point at (the values of variables a and b ) - but you can't change the addresses of the original variables.

To break it down:

static void swapAddr(int *numOne, int *numTwo)
{
    int *tmp;

    tmp = numOne;

At this point, tmp and numOne both point to the value of the a variable...

    numOne = numTwo;

Now, numOne points instead to the value of the b variable...

    numTwo = tmp;
}

And finally, numTwo now points to the value of the a variable. The function returns and numOne and numTwo no longer exist after that point. The addresses of the variables a and b did not change at any stage.

You could however write a function which exchanges the addresses in two pointer variables:

static void swapAddr(int **ptrOne, int **ptrTwo)
{
    int *tmp;

    tmp = *ptrOne;
    *ptrOne = *ptrTwo;
    *ptrTwo = tmp;
}

This would allow you to pass the address of two pointer variables, and on return the pointers would be swapped - each one pointing at what the other did previously. But again, this would not change the address of any variable that those pointers happened to point to.

The pointers are passed to the function by value, so changing what they point to isn't going to change the value of the passed parameters in the calling function.

When the function is called, a copy of each pointer is made and saved to the stack. Then the function reads each pointer value off the stack and manipulates them. It never changes the value of the original pointer that was copied onto the stack.

static void swapAddr(int *numOne, int *numTwo)

In this function you are passing 2 pointers by value . This allows you to modify the int pointed to by the pointers but not the pointers themselves.

Use this function definition instead that passes pointers to pointers and allows modifying the pointers themselves

static void swapAddr(int **numOne, int **numTwo) {
    int *tmp = *numOne;
    numOne = *numTwo;
    numTwo = tmp;
}

You could use it like this for example:

int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
*a = 15;
*b = 10;
swapAddr(&a, &b);

Remember that in C values are passed by value to functions, meaning that the values are copied. When you modify an argument in a function you only modify the local copy inside the function, not the original value that was passed to the function. This goes for pointers as well.

To solve your problem you must pass the arguments by reference , but unfortunately C doesn't have that, it only have pass by value. However, pass by reference can be emulated by passing pointers to the data, just like you do in the function. You must however dereference the pointer to get the values from where the pointers point to, and use those values to do the actual swapping:

int temp = *numOne;  // Note: temp is a value not a pointer
*numOne = *numTwo;
*numTwo = temp;

You canlt change the addresses. The adderss of a is the address of a and that will remain the same until the end of days.

You can do:

static void swapAddr(int **numOne, int **numTwo)
{
    int *tmp;

    tmp = *numOne;
    *numOne = *numTwo;
    *numTwo = tmp;
}

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

What you want to achieve is something like

int *c = &a;
&a = &b;
&b = &a;

This is not possible (you can check: it will not compile). A variable that is created is placed at one place in memory and stays there. So when you create a variable a it will stay variable a and it will not be able to change its identity to that of another variable b .

What you can do is use two pointers int *p1, *p2 to int. These pointers can change their value and point to other objects during lifetime:

p1 = a;
p2 = b;
p1 = b;
p2 = a;

a and b will stay the same, but p1 and p2 can point to different objects over time.

So a thing that would be possible:

static void swapaddr(int **pp1, int **pp2)
{
    int *pp;
    pp = *pp1;
    *pp1 = *pp2;
    *pp2 = pp;
}

int main(void)
{
    int a = 15, b = 10;
    int *pA = &a, *pB = &b;
    swapAddr(&pA, &pB);
}

In this example a and b would keep their identity and address, but pA and pB would change their value and pA would point to b and pB would point to pA .

You cannot change the addresses of the variables.however you can change values of pointers,which store addresses as their value,here is an example :

#include <stdio.h>

void swapAddr(int **numOne, int **numTwo)
{
    int *tmp;
    tmp = *numOne;
    *numOne = *numTwo;
    *numTwo = tmp;
}

int main(void)
{
    int a = 15;
    int b = 10;

    int *p_a = &a;
    int *p_b = &b;

    printf("Address of a: %p\n", p_a);
    printf("Address of b: %p\n", p_b);

    swapAddr(&p_a,&p_b);
    printf("\n");

    printf("p_a : %p\n",p_a);
    printf("p_b : %p\n",p_b);

    return 0;
}

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