我知道这两个函数之间的区别:
Swap(int *x, int *y)
vs 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;
}
代码无效。至少编译器应该发出一条消息,指出有不同类型的指针的赋值(初始化)而没有强制转换。
即指针类型
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 );
free( ptr_y );
}
程序输出可能看起来像例如
ptr_x = 0x7ffdcf002d98
ptr_y = 0x564608597eb0
ptr_x = 0x7ffd08597eb0
ptr_y = 0x5646cf002d98
如您所见,仅交换了适合类型
int
.的指针的不太重要的部分
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);