3.3 参数传递方式

发布于:2025-07-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

在这里插入图片描述

1 值传递

值传递的原理

值传递就像复印文件:你把原件拿去复印,函数拿到的是复印件,对复印件的任何修改都不会影响原件。

内存原理

  1. 调用函数时,参数的值会被复制一份
  2. 函数内操作的是这个副本
  3. 函数返回后,副本被丢弃,原变量不受影响

示例程序演示

#include <iostream>
using namespace std;

// 值传递函数
void incrementByValue(int num) {
    num++;
    cout << "函数内num的值: " << num << endl;
}

int main() {
    int a = 5;
    incrementByValue(a);
    cout << "main函数中a的值: " << a << endl; // 仍然是5
    
    return 0;
}

输出结果:

函数内num的值: 6
main函数中a的值: 5

值传递的局限性

  1. 无法修改原变量:函数内的修改不会影响调用处的变量
  2. 效率问题:对于大型结构体或类对象,复制开销大
  3. 内存消耗:每次调用都会创建新的副本

适用场景

  • 基本数据类型(int, double等)
  • 不需要修改原变量的情况
  • 需要保护原数据不被意外修改

2 引用传递

引用符号(&)的使用

引用就像给变量起别名,使用&符号声明:

void incrementByRef(int &num) { // 注意&符号
    num++;
}

修改原变量的示例

#include <iostream>
using namespace std;

void swapByRef(int &x, int &y) {
    int temp = x;
    x = y;
    y = temp;
}

int main() {
    int a = 3, b = 5;
    cout << "交换前: a=" << a << ", b=" << b << endl;
    
    swapByRef(a, b);
    
    cout << "交换后: a=" << a << ", b=" << b << endl;
    return 0;
}

输出结果:

交换前: a=3, b=5
交换后: a=5, b=3

趣味练习:交换变量值

#include <iostream>
using namespace std;

// 你的任务:实现这个交换函数
void mySwap(int &first, int &second) {
    // 在这里写下你的代码
    int temp = first;
    first = second;
    second = temp;
}

int main() {
    int x = 10, y = 20;
    cout << "交换前: x=" << x << ", y=" << y << endl;
    
    mySwap(x, y);
    
    cout << "交换后: x=" << x << ", y=" << y << endl;
    
    // 测试用例
    if(x == 20 && y == 10) {
        cout << "恭喜!交换成功!" << endl;
    } else {
        cout << "再检查一下你的代码哦~" << endl;
    }
    
    return 0;
}

扩展挑战

  1. 尝试用引用实现三个变量的轮换(a→b→c→a)
  2. 编写一个函数同时返回多个计算结果(如圆的面积和周长)

3 两种方式的比较

内存角度分析

值传递 引用传递
内存使用 创建参数副本 直接使用原变量
修改影响 不影响原变量 直接影响原变量
调用开销 需要复制数据 仅传递地址,效率高
安全性 高(保护原数据) 低(可能意外修改原数据)

使用场景建议

使用值传递当

  • 参数是基本数据类型(int, double等)
  • 不需要修改原变量
  • 希望保护原始数据不被修改

使用引用传递当

  • 需要修改原变量
  • 参数是大型结构体或对象(避免复制开销)
  • 需要实现多返回值(通过引用参数返回结果)

常见错误提醒

  1. 忘记加&符号
void func(int x) {...} // 本想用引用但忘记&
  1. 传递字面量给非常量引用
void print(int &x) {...}
print(5); // 错误!不能绑定临时值到非const引用
  1. 返回局部变量的引用
int& badFunc() {
    int x = 10;
    return x; // 错误!x将很快被销毁
}
  1. 混淆指针和引用
void func1(int &x) {...} // 引用
void func2(int *x) {...} // 指针

本章实验项目

成绩修改器

#include <iostream>
using namespace std;

// 值传递版本(不会修改原成绩)
void adjustGradeByValue(int grade, int bonus) {
    grade += bonus;
    if(grade > 100) grade = 100;
    cout << "调整后成绩(函数内): " << grade << endl;
}

// 引用传递版本(会修改原成绩)
void adjustGradeByRef(int &grade, int bonus) {
    grade += bonus;
    if(grade > 100) grade = 100;
    cout << "调整后成绩(函数内): " << grade << endl;
}

int main() {
    int myGrade = 75;
    int bonusPoints = 10;
    
    cout << "原始成绩: " << myGrade << endl;
    
    // 测试值传递
    adjustGradeByValue(myGrade, bonusPoints);
    cout << "值传递后实际成绩: " << myGrade << endl;
    
    // 测试引用传递
    adjustGradeByRef(myGrade, bonusPoints);
    cout << "引用传递后实际成绩: " << myGrade << endl;
    
    return 0;
}

思考问题

  1. 为什么值传递版本没有改变main函数中的myGrade?
  2. 如果bonusPoints也用引用传递会有什么影响?
  3. 什么情况下应该使用const引用?

本章总结表

特性 值传递 引用传递
语法 void func(int x) void func(int &x)
修改原变量 不能
内存开销 需要复制 仅传递引用(地址)
典型用途 保护原始数据、基本类型 修改参数、大型对象传递
安全性 需谨慎使用

课后综合练习

  1. 基础题:编写一个函数createFullName,通过引用参数返回"姓氏+名字"的组合
  2. 提高题:实现一个计算器,使用引用参数同时返回加减乘除四个结果
  3. 挑战题:设计一个学生成绩处理器,使用引用修改学生成绩并返回是否及格
  4. 思考题:分析以下代码的问题并修复:
void increase(int x) {
    x++;
}

int main() {
    int a = 5;
    increase(a);
    cout << a; // 期望输出6,实际输出5
    return 0;
}

编程小项目:创建一个简单的银行账户系统,包含以下功能:

  • deposit:存款(修改余额)
  • withdraw:取款(修改余额)
  • transfer:转账(修改两个账户余额)
    所有金额修改都应使用引用传递实现

网站公告

今日签到

点亮在社区的每一天
去签到