为什么常规交换与指针到指针变量一起使用?

Mat*_*ode 1 c swap pointers pointer-to-pointer function-definition

我知道这两个函数之间的区别:Swap(int *x, int *y)vs Swap(int **x, int **y)

但是,我不确定这种代码是如何工作的。如何将指针指向的地址与常规swap()类型交换?

例如,我相信a创建了一个本地指针变量并且它指向&ptr_x,因此当我取消引用时*x它等于&x

那么,temp(并且*a也可以用作整数)可以保存/*b的实际地址,这就是它起作用的原因?xy

void swap(int *a, int *b)
{
   int temp = *a;
   *a = *b;
   *b = temp;
}


int main()
{
   printf("in main:\n");

    int x = 2;
    int y = 8;

    int *ptr_x = &x;
    int *ptr_y = &y;

    printf("ptr_x points to = %p\n", ptr_x);
    printf("ptr_y points to = %p\n\n", ptr_y);

    swap(&ptr_x, &ptr_y);

    printf("ptr_x points to = %p\n", ptr_x);
    printf("ptr_y points to = %p\n", ptr_y);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 5

该代码无效。至少编译器应该发出一条消息,表明存在不同类型的指针的赋值(初始化)而无需强制转换。

int *也就是说,指针类型、参数类型和int **参数表达式类型之间没有隐式转换。

一般来说,该函数会调用未定义的行为,因为该类型的对象不必int足够大以能够存储指针值。

看来您的程序可以工作,因为sizeof( int * )等于sizeof( int ) 或地址值不大并且可以存储在类型的对象中int。或者仅交换大小相等的指针的低有效部分,sizeof( int )而两个指针的最高有效部分相同。

要表明代码无效,只需使用一个指向具有自动存储持续时间的变量的指针和另一个指向动态分配的内存的指针。

这是一个演示程序。

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

void swap(int *a, int *b)
{
   int temp = *a;
   *a = *b;
   *b = temp;
}

int main( void ) 
{
    int x;

    int *ptr_x = &x;
    int *ptr_y = malloc( sizeof( int ) );

    printf( "ptr_x = %p\n", ( void * )ptr_x );
    printf( "ptr_y = %p\n", ( void * )ptr_y );

    swap( ( int * )&ptr_x, ( int * )&ptr_y);

    printf( "ptr_x = %p\n", ( void * )ptr_x );
    printf( "ptr_y = %p\n", ( void * )ptr_y );

    // This can produce a run-time error 
    //free( ptr_x );  
}
Run Code Online (Sandbox Code Playgroud)

程序输出可能类似于

ptr_x = 0x7ffdcf002d98
ptr_y = 0x564608597eb0
ptr_x = 0x7ffd08597eb0
ptr_y = 0x5646cf002d98
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,仅交换了适合类型对象的指针的不太重要的部分int

也就是说,函数内的表达式*a和不会产生指针的完整值,因为它们具有类型。*bswapint

作为一个技巧,您可以通过以下方式声明和定义该函数:)

#include <stdint.h>

void swap(intptr_t *a, intptr_t *b)
{
   intptr_t temp = *a;
   *a = *b;
   *b = temp;
}

//...

swap( ( intptr_t * )&ptr_x, ( intptr_t * )&ptr_y);
Run Code Online (Sandbox Code Playgroud)