C语言 为什么普通的swap使用指针到指针变量?

gmol1639  于 2023-04-29  发布在  其他
关注(0)|答案(2)|浏览(133)

我知道这两个函数的区别:Swap(int *x, int *y)Swap(int **x, int **y)
但是,我不知道这种代码是如何工作的。如何将指针指向的地址与常规的swap()类型交换?
例如,我相信创建了一个局部指针变量a,它指向&ptr_x,所以当我解引用*x时,它等于&x
所以,temp(以及*a*b,它们也可以作为整数)可以保存x/y的实际地址,这就是为什么它工作?

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;
}
ssgvzors

ssgvzors1#

代码无效。编译器至少应该发出一条消息,表明存在不同类型的指针的赋值(初始化),而不需要强制转换。
也就是说,在指针类型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 );  
}

程序输出可能如下所示

ptr_x = 0x7ffdcf002d98
ptr_y = 0x564608597eb0
ptr_x = 0x7ffd08597eb0
ptr_y = 0x5646cf002d98

正如你所看到的,只交换了适合int类型对象的指针的较低有效部分。
也就是说,函数swap中的表达式*a*b不会产生完整的指针值,因为它们的类型为int
作为一个技巧,你可以用下面的方式声明和定义函数:)

#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);
7cjasjjr

7cjasjjr2#

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

当你传递int**类型的指针变量的地址时,这个交换函数会有2个指针。由于类型不匹配,您将获得未定义的行为。首先,你需要更新:
swap(&ptr_x, &ptr_y);

swap(ptr_x, ptr_y);
剩下的我建议你通过这个链接来理解指针是如何通过引用方法来交换值的:https://www.studymite.com/blog/swapping-values-using-pointer-in-c

相关问题