C语言通过函数正确交换两个整数的方法

清欢
清欢
发布时间:2026-10-15 | 5人浏览过
原创

在C语言开发中,通过自定义函数实现变量交换是基础且高频的操作。由于函数参数默认采用“值传递”机制,直接传入数值无法改变主调函数中的变量。要实现真正的交换效果,必须掌握指针传递与解引用的原理,避免常见的编译错误或运行时逻辑失败。

正确的实现方式

要成功交换两个整数变量的值,核心在于操作变量的地址而非副本。我们需要定义一个接收整型指针参数的函数,并在函数内部通过解引用符(*)访问指针指向的内存空间。

以下是标准的实现代码:

#include <stdio.h>

// 定义fun函数,通过指针接收变量的地址
void fun(int *x, int *y)
{
    // 定义临时变量保存状态
    int t;
    // 执行三步交换逻辑
    t = *x;       // 暂存 x 指向的值
    *x = *y;      // 将 y 指向的值赋给 x
    *y = t;       // 将暂存的值赋给 y
}

int main()
{
    int a, b;
    scanf("%d %d", &a, &b);
    
    // 将变量 a 和 b 的地址传给函数
    fun(&a, &b);
    
    printf("%d %d\n", a, b);
    return 0;
}

常见错误类型与原因分析

许多初学者在尝试编写此类函数时,容易陷入以下三种典型的逻辑或语法陷阱。理解这些错误有助于深入掌握C语言的内存管理模型。

第一种情况:值传递(传值调用)

现象:形参改变不影响实参。

如果函数定义为 void Swap_err01(int a, int b),传入的是变量的副本。函数内部对参数的任何修改都只作用于局部栈内存,原函数的变量不受影响。

代码如下:

void Swap_err01(int a, int b)
{
    int tmp;
    tmp = a;
    a = b;
    b = tmp;
}

该方式的编译与运行结果验证了其无效性:

原理解析:值传递过程中,数据被复制了一份。函数内部使用的形参与外部实参在内存中占据不同的地址,互不干扰。如图所示,这种机制下无法跨越函数边界改变外部变量:

第二种情况:仅修改指针本身(未解引用)

现象:代码无误但不生效。

若定义为 void Swap_err02(int *p1, int *p2),并在内部执行指针互换 p1 = p2;,这仅仅改变了局部指针变量所指向的地址,而没有触及指针指向的目标内存。

代码如下:

void Swap_err02(int *p1, int *p2)
{
    int *tmp = p1;
    p1 = p2;
    p2 = tmp;
}

其运行结果表现为变量并未真正交换:

这一失败的核心原因在于没有进行解引用操作。我们操作的是指针变量的地址映射,而非指针所指的实际内容:

第三种情况:悬挂指针(野指针)崩溃

现象:编译器报错或程序段错误(Segmentation Fault)。

在尝试使用局部指针变量作为中转站时,如果未对其进行初始化分配即使用解引用符(如 *tmp = ...),会导致访问非法内存区域。

代码如下:

void Swap_err03(int *p1, int *p2)
{
    int *tmp; // 未初始化,内容为随机垃圾值
    *tmp = *p1; // 危险操作!向未知地址写入数据
    *p1 = *p2;
    *p2 = *tmp;
}

在使用 Visual Studio 2012 等环境进行测试时,会捕获到相关异常:

原因:int *tmp 只是一个空悬的指针,它指向了一个没有权限也没有归属的随机地址。向此地址写入数据属于严重的内存违规行为,这就是所谓的“悬挂指针”或“野指针”错误。

成功的交换逻辑演示

排除上述错误后,使用正确规范的指针交换函数可以完美达成目标。关键在于:一是传递地址,二是对地址的内容进行操作(解引用)。

完整示例代码:

#include <stdio.h>

// 正确的 swap 函数
void Swap(int *p1, int *p2)
{
    int tmp;
    tmp = *p1;  // 取地址内的值存入临时变量
    *p1 = *p2;  // 将地址2的值写入地址1
    *p2 = tmp;  // 将临时变量值写入地址2
}

int main() {
    int a = 10;
    int b = 20;
    printf("a=%d, b=%d\n", a, b);
    
    // 调用时传入 a 和 b 的地址
    Swap(&a, &b);
    
    printf("a=%d, b=%d\n", a, b);
    return 0;
}

该函数执行后的预期输出:

过程图解:可以看到,解引用之后,实际是在内存层面对两个位置进行了数值置换。这个过程清晰地展示了内存数据流向:

总结判断标准:子函数的动作若要影响到父函数(Main函数),务必满足两个条件:
1. 必须传递变量的地址(指针);
2. 必须在子函数内部对指针进行解引用,以操作内存中的数据。
缺一不可。

调用结构示意

int main () // 父函数/调用者
{
    Fun(&a, &b); // 传递地址给子函数
}

总结

本文梳理了C语言中利用函数交换变量值的标准路径与避坑指南。牢记“传址+解引用”原则,不仅能解决本题,也能帮助应对更复杂的数组或结构体处理场景。

以上就是C语言用fun函数实现两个数的交换的详细内容,更多关于C语言函数指针教程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表