为何常规swap函数可通过指向指针的变量交换指针指向地址?
关于指针交换示例代码的原理解析
首先要明确:你贴的这段代码存在类型不匹配的问题,属于C语言里的未定义行为,但因为多数系统中所有指针类型的内存大小一致,所以才“碰巧”实现了交换指针指向地址的效果,这不是规范的写法。下面拆解它的运行逻辑,以及纠正你的猜想误区:
代码运行的实际逻辑
先看
main中的变量关系ptr_x是int*类型的变量,它本身存储的是x的内存地址;&ptr_x是int**类型(指向int*变量的指针),代表ptr_x这个变量自己的内存地址。- 调用
swap(&ptr_x, &ptr_y)时,你把int**类型的地址值传给了int*类型的参数a和b——这违反了C语言的类型规则,但编译器若允许隐式转换,a会存储&ptr_x的地址值,b存储&ptr_y的地址值。
进入
swap函数后的操作int temp = *a;:对int*类型的a解引用,本质是读取a所指向的内存内容。因为a里存的是ptr_x变量的地址,所以*a就是读取ptr_x变量的当前值(也就是x的地址),并存在temp里。*a = *b;:*b读取的是ptr_y变量的当前值(y的地址),然后将这个值写入a指向的内存(即ptr_x变量)——此时ptr_x就存储了y的地址,也就是指向y了。*b = temp;:把temp中保存的x的地址,写入b指向的内存(即ptr_y变量)——ptr_y就存储了x的地址,指向x了。
你的猜想误区纠正
- 局部变量
a的类型是int*,并非指向&ptr_x的int**类型,它只是存储了&ptr_x的地址值,类型不匹配是这段代码的隐患。 *a(你猜想里的*x)不等价于&x,而是等价于ptr_x变量的当前值(即它指向的地址)。temp存储的是ptr_x原来指向的地址,*a和*b直接操作的是ptr_x、ptr_y这两个变量本身的内容,这才是能改变它们指向地址的核心原因。
规范的写法
要避免类型不匹配的问题,应该把swap函数的参数改成int**类型,这样完全符合C语言的类型规则:
void swap(int **a, int **b) { int *temp = *a; *a = *b; *b = temp; }
此时调用swap(&ptr_x, &ptr_y)就没有任何问题,运行原理和上面一致,但不存在未定义行为。
内容的提问来源于stack exchange,提问作者MatanCode
相关产品推荐
相关产品推荐

