Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 可以交换两个变量的地址吗?_C_Pointers_Swap - Fatal编程技术网

C 可以交换两个变量的地址吗?

C 可以交换两个变量的地址吗?,c,pointers,swap,C,Pointers,Swap,我知道可以像这样交换两个变量的值 #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; *

我知道可以像这样交换两个变量的值

#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;
}
#包括
无效交换(int*x,int*y);
int main(){
int x=5,y=10;
互换(x&y);
printf(“x:%d,y:%d\n”,x,y);
返回0;
}
无效交换(int*x,int*y){
内部温度;
温度=*x;
*x=*y;
*y=温度;
}
但是有可能交换这两个变量的地址吗?我并不是说只做一个指向它们的指针,然后交换指针所持有的值,我的意思是实际交换这两个值,这样在交换函数之后,x的地址现在是y的地址,在交换函数之前,反之亦然


如果这是一个愚蠢的问题,我很抱歉,但我很好奇这样的事情是否可能发生。如果这种行为不可能,为什么?

不,那是不可能的。你不能选择变量的地址,也不能修改它们。

在运行时,你不再有
x
y
。您有两个内存地址,每个地址保留
sizeof int
字节,这两个地址都假定存储一个整数

您可以交换这些内存区域的内容,您可以使用指针变量及其地址,并且可以交换它们,正如您所说的。这里真的并没有任何其他有意义的方式来交换任何东西,所以答案是“不”,因为这种交换的概念并不存在

我想,如果您有虚拟内存页而不仅仅是整数,那么您可以交换它们,但就应用程序代码而言,即使这样也只是交换内存内容的一种有效方式


如果您不使用高级语言,那么您可以使用自修改代码,将程序的汇编代码更改为访问
y
,而不是
x
,反之亦然。但从概念上讲,这与将许多指针嵌入到程序集中并更改指针是一样的。而且,这是一种非常理论化的方法,需要可写的代码段,因此在现代操作系统中甚至不可能实现。

如果不向指针传递指针,这是不可能的。C中的所有函数调用都是按值调用的。参数调用是指针类型的函数调用通常被称为“引用调用”(顺便说一下,与引用调用的C++概念不同),但是它实际上也是按值调用的。参见下面的示例

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
}
很容易看出
foo()
是如何通过值调用的。将
x
y
的副本传递给它(因此按值调用)。它所做的任何更改都是对其自己的副本(在其范围内命名为
a
b
x
y
不受影响,并且在该函数返回后不会在
main()
中更改

虽然对于初学者来说有点难理解,
bar()
也是按值调用的。将
xp
yp
的副本传递给它。它所做的任何更改都是对自己的副本(在其范围内命名为
ap
bp
xp
yp
不受影响,并且在该函数返回后,
main()
中不会更改

(注意上面段落中的最后三行与前一行几乎相同。唯一的区别是
x
y
的类型是
int
,而
xp
yp
的类型是
int*

qux()
也按值调用,因为它接收
xp
yp
的副本(在其范围内称为
ap
bp
)。但是,它可以取消引用
ap
bp
,它们是
xp
yp
的副本,指向相同的内存位置。通过名称
x
y
main()
的作用域中已知的内存位置。如果
qux()
对这些 内存位置,它将更改
main()
x
y
的“视图”


因此,通过被调用函数更改这些指针的值的唯一方法是将这些指针的地址发送到该函数,然后该函数可以取消引用并可能更改这些地址。然而,你的问题已经排除了这个选项,所以不,这是不可能的

为什么要这样做?如果变量写在内存中(而不是驻留在CPU寄存器中),那么它们的“名称”是一个与它们的内存地址相等的人工构造。而且你不能到处移动地址。(将“名称”从一个地址移动到另一个地址需要一个指针,而不是一个文本int。)@BasileStarynkevitch没有真正的原因,只是好奇而已。谢谢Jongware,谢谢你!这是因为地址实际上是物理的东西,还是我在这里偏离了基准?@Jarod重要的是,C语言没有改变变量地址的方法。更改一个变量的地址也是一个基本上没有用的功能,而且有点难以实现,因此它不可用。即使使用第三个变量也不可用?(仅更改其值)