I know that it is possible to swap the value of two variables like so
#include <stdio.h>
void swap(int *x, int *y);
int main(){
int x=5,y=10;
swap(&x, &y);
printf("x: %d, y: %d\n", x, y);
return 0;
}
void swap(int *x, int *y){
int temp;
temp=*x;
*x=*y;
*y=temp;
}
But is it possible to swap the addresses of those two variables? And I don't mean just making a pointer to them and then swapping the values held by the pointers, I mean actually swapping the two, so that after the swap function the address of x is now the address of y before the swap function and vice versa.
I apologise if this is a silly question but I'm curious to see if such a thing is even possible. If this behaviour is not possible, why?
No, that's not possible. You don't get to choose the addresses of variables and you can't modify them either.
At runtime, you do not have x
or y
any more. You have two memory addresses with sizeof int
bytes reserved at each, which both are assumed to store an integer.
You can swap the contents of these memory areas, and you can have pointer variables with their addresses, and can swap them, as you say. There really isn't any other meaningful way to swap anything here, so answer is "no", because concept of such swapping does not exist.
I suppose, if you had virtual memory pages instead of just integers, then you could swap those, but even that would just be an efficient way to swap memory contents, as far application code is concerned.
If you step outside of high level languages, then you could have self modifying code, where you would change the assembly code of the program to access y
instead of x
and vice versa. But conceptually this is same as having many pointers embedded into assembly, and changing the pointers. Also, very theoretical way, which requires writable code segment so not even possible in a modern OS without extra tricks.
Without passing pointers to pointers, it is not possible. All function calls in C are call by value. Function calls where parameters are of pointer type are often called as "call by reference" (which, by the way, is different from the C++ notion of call by reference) for convenience, but it too is actually call by value. See below example.
void foo(int a, int b) {
a = 0;
b = 0;
}
void bar(int* ap, int* bp) {
ap = NULL;
bp = NULL;
}
void qux(int* ap, int* bp) {
*ap = 0;
*bp = 0;
ap = NULL;
bp = NULL;
}
int main() {
int x = 2;
int y = 3;
int* xp = &x;
int* yp = &y;
foo(x, y);
// x and y don't change here
bar(xp, yp);
// xp and yp don't change here
qux(xp, yp);
// xp and yp don't change here, but x and y do
}
It is easy to see how foo()
is called by value. Copies of x
and y
are passed to it (hence call by value). Any changes it makes are to its own copy (which are named a
and b
within its scope). x
and y
are unaffected, and will not change in main()
after this function returns.
Although somewhat hard to understand for a beginner, bar()
too is call by value. Copies of xp
and yp
are passed to it. Any changes it makes are to its own copy (which are named ap
and bp
within its scope). xp
and yp
are unaffected, and will not change in main()
after this function returns.
(Notice how the last 3 lines in above paragraph are nearly the same as the previous one. The only difference being that type of x
and y
are int
, while that of xp
and yp
are int*
.)
qux()
too is called by value, as it receives copies of xp
and yp
(known in its scope as ap
and bp
). However, it can dereference ap
and bp
, which being copies of xp
and yp
, point to the same memory location. The memory locations being known in main()
's scope by the names x
and y
. If qux()
makes changes to the value in those
memory locations, it will change main()
's "view" of x
and y
.
The only way to change the values of those pointers through a called function, therefore, is to send addresses of those pointers to the function, which it can then dereference and potentially change. However, your question already rules out that option, so no, this is not possible.