C语言两数交换Swap函数:指针警告与临时变量替换问题
C语言Swap函数问题排查与原理说明
问题涉及的原代码如下:
void Swap(int *x, int *y) { int *pTemp; pTemp = x; x = y; y = pTemp; }
为什么编译会弹出"使用了未初始化的指针"警告
- 警告触发的直接原因是代码中
int *pTemp;声明局部指针变量时没有做显式初始化。此时pTemp是一个值随机的野指针,虽然下一行立刻执行pTemp = x;给它赋予了合法地址值,但在严格编译检查规则下(比如GCC开启-Wmaybe-uninitialized、VS开启SDL安全检查、MISRA C合规检查),指针类型变量声明时必须显式赋初始值(哪怕是NULL),不允许声明后留空再赋值,因此会触发警告。 - 这个警告属于规范类提示,不是说代码真的发生了解引用未初始化野指针的行为——代码中第一次操作pTemp是给它赋值x,属于写操作,没有读取pTemp的随机值。这类检查的目的是避免后续代码迭代时出现分支路径漏赋值,导致野指针访问问题。
- 需要明确:这段代码的核心逻辑本身就是错误的,和警告无关。C语言函数参数是值传递,形参x、y是函数内部的局部变量,存储的是外部传入地址的副本。原代码只是交换了两个局部指针变量的指向,全程没有通过指针修改外部内存的值,函数执行结束后形参随栈帧销毁,完全无法实现两数交换的功能。
将pTemp改为普通int类型能否实现交换
分两种情况判断:
- 仅修改pTemp类型为int,其余代码逻辑不变
- 首先会直接触发编译错误:x、y是
int*指针类型,直接赋值给int类型变量会发生类型不匹配,64位环境下指针占8字节、int通常占4字节,地址赋值给int会发生高位截断,属于非法类型转换。 - 就算强行忽略编译错误,逻辑上依然只是修改函数内部的局部形参,不会影响外部实参的值,完全无法实现交换。
- 首先会直接触发编译错误:x、y是
- 修改pTemp为int类型,同时调整逻辑为解引用操作指针指向的内存
此时代码可以正常实现两数交换,正确实现代码如下:
实现原理:void Swap(int *x, int *y) { int pTemp; pTemp = *x; *x = *y; *y = pTemp; }- 这里的int类型pTemp用来暂存整数值,不是存地址。代码通过解引用符
*访问x、y存储的地址对应的外部实参内存,直接修改内存中存储的整数值。 - 这种修改是直接操作函数外的变量内存,不会随函数栈帧销毁而丢失,因此可以真正实现两个外部变量的值交换。
- 这里的int类型pTemp用来暂存整数值,不是存地址。代码通过解引用符
内容的提问来源于stack exchange,提问作者Skyechen
相关产品推荐
相关产品推荐

