简体   繁体   中英

Why can't I swap the memory address of two variables?

I want to swap the memory address of two variables, like this:

#include<stdlib.h>
#include<stdio.h>
void main() {
int a = 5;
int b = 10;
int temp;
temp = &a;
&a = &b;
&b = temp;
}

But the compiler doesn't allow it. Is there any good reason why this is not allowed?

I know that variables are just names representing memory locations. When you access a variable you're just accessing a memory location, so why can't you just swap the names for memory locations? In C# you can swap object names in this way so why can't you do that in C?

Is there something in the C standard that prohibits two variable names from pointing to the same address?

In C, you would do this with pointers:

int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int));
int *temp;

*a = 5;
*b = 10;
temp = a;
a = b;
b = temp;

This is similar to what is actually happening when you do the same thing in C#, except C# doesn't expose the pointer syntax like C does.

In the C language, names disappear at translation time. (In typical C implementations, names are only ever retained at run time for features like symbolic debugging, or possibly dynamic linkage of shared libraries.)

Names are not run-time entities that can be manipulated by the program. Even if you somehow have access to a symbol table at run time (via some compiler or library extension), which allows you not only to access a symbol like b , but also change the entry to make it have a different value, such a change will not propagate back to the compiled program, in which b no longer exists, because it has been replaced by machine language instructions which access that memory location numerically, rather than symbolically. Symbolic changes in a C program generally require the program source code to be recompiled.

Lastly, your program is simply not valid C because in the expression:

temp = &a;

the left hand side of the assignment, temp , has type int , whereas &a has type int * . You're assigning a pointer value to an integer.

The syntax you're trying to use to denote name manipulation simply does not denote name manipulation; it denotes something else: the conversion of a pointer to an integer.

Without a cast operator, that conversion requires a diagnostic. With a cast operator, it produces an implementation-defined integer value.

Programming languages are not like human languages; the machine has no intuition about what you really mean. Your program isn't being rejected on the grounds that the machine understands what you really mean, but on a completely different interpretation of your intent according to the real rules of the language.

In other words, your program does not show that C doesn't support symbolic manipulation at run time, because your program does not in any way encode the request for such a thing.

What shows that C doesn't support symbolic manipulation at run time that is the lack of any description in the ISO C standard of such a feature. This means that if such a feature exists, it's only as a local extension of the particular C dialect that your compiler understands. In that case, you can find it documented in the manual for your compiler, and that documentation will show you the proper syntax.

The code:

&a = &b; 

Is attempting to change the address of the variable a. This simply not allowed in C. The same goes for:

&b = temp;

Rather, to swap the values, do the following:

 temp=a;
 a=b;
 b=temp;

Another approach would be to declare a and b as pointers. Then you could swap where each points:

int a = 5;
int b = 10;

int *ap = &a;
int *bp = &b;
int *temp;

temp = ap;
ap = bp;
bp = temp;

printf("*ap[%d]\n", *ap);   // output: '*ap[10]'
printf("*bp[%d]\n", *bp);   // output: '*bp[5]'

You will probably want to read section 6.2.4 of the latest C language standard .

Note that you can have multiple pointers that resolve to the same address:

int a;
int *p = &a;
int *q = &a;
int *r = p;

Under this scenario, the expressions a , *p , *q , and *r all resolve to the same memory location, so

a = 1;

has the same effect as

*p = 1;

which has the same effect as

*q = 1;

which has the same effect as

*r = 1;

You can't update the result of &a because the operation is nonsensical (it's equivalent to writing something like 1 = 2 ).

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