利用指针,交换两个变量的值

#include <stdio.h>
void f1(int *p1,int *p2)
{
    int t;
    t = *p1;
    *p1 = *p2;
    *p2 = t;
}

int main()
{
    int a,b;
    printf("请输入两个数:\n");
    scanf("%d %d",&a,&b);
    printf("交换前:a = %d,b = %d\n",a,b);
    f1(&a,&b);
    printf("交换后:a = %d,b = %d\n",a,b);
    
    return 0;
}

这段代码是 C 语言学习中指针(Pointer)最经典、最核心的入门案例。它不仅仅是一个“交换两个数”的程序,更是理解“值传递”与“地址传递”区别的钥匙。

函数定义:void f1(int *p1, int *p2)

  • 参数类型 int *:这里声明 p1  p2 不是普通的整数,而是指向整数的指针。这意味着调用该函数时,必须传入变量的内存地址,而不是变量的值。
  • 解引用操作符 *
    • 在参数声明中(如 int *p1),* 表示“这是一个指针变量”。
    • 在函数体中(如 *p1),* 是解引用运算符(Dereference Operator)。它的意思是:“去 p1 存储的那个地址里,把里面的值取出来”或者“修改那个地址里的值”。
  • 交换逻辑
    1. t = *p1;:取出 p1 指向地址中的值(即变量 a 的值),存入临时变量 t
    2. *p1 = *p2;:取出 p2 指向地址中的值(即变量 b 的值),写入到 p1 指向的地址中。此时,外部变量 a 的值已经被修改了。
    3. *p2 = t;:将暂存的 t(原 a 的值)写入到 p2 指向的地址中。此时,外部变量 b 的值也被修改了。

主函数:main

  • & 取地址运算符scanf 需要知道把用户输入的数据存到哪里,所以必须提供变量的地址。&a 获取变量 a 在内存中的首地址。
  • 关键调用f1(&a, &b);
    • 这里没有传 a 和 b 的值(如 10, 20),而是传的它们的地址(如 0x7fff...)。
    • 这使得 f1 函数内部的 p1 和 p2 直接“指向”了 main 函数中的 a 和 b

核心原理:为什么必须用指针?

这是 C 语言初学者最大的痛点:为什么不能直接传 a 和 b

场景 A:值传递(错误示范)

如果函数写成 void f1_wrong(int x, int y)

  1. C 语言默认是按值传递(Pass by Value)。
  2. 调用时,系统会创建 x 和 y 作为 a 和 b 副本(拷贝)。
  3. 函数内部交换的是 x 和 y 这两个副本。
  4. 函数结束,x 和 y 被销毁。
  5. 结果main 函数里的 a 和 b 毫发无损,交换失败。
场景 B:地址传递(当前代码,正确)

使用 void f1(int *p1, int *p2) 并传入 &a, &b

  1. 传递的是地址(门牌号)。
  2. p1 拿着 a 的地址,p2 拿着 b 的地址。
  3. 通过 *p1 和 *p2 操作,相当于直接拿着钥匙打开了 main 函数栈帧里的房间,修改了里面的家具(数据)。
  4. 结果main 函数里的 a 和 b 被永久修改。

结论若要在函数内部修改外部变量的值,必须传递该变量的地址(使用指针)。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐