当前位置: 首页 > news >正文

3.3 参数传递方式

在这里插入图片描述

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; // 仍然是5return 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,实际输出5return 0;
}

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

  • deposit:存款(修改余额)
  • withdraw:取款(修改余额)
  • transfer:转账(修改两个账户余额)
    所有金额修改都应使用引用传递实现
http://www.dtcms.com/a/287010.html

相关文章:

  • 写case杂记
  • Glary Utilities(系统优化工具) v6.20.0.24 专业便携版
  • JavaSE -- 数组详细讲解(数组介绍,Arrays常用方法,二维数组创建)
  • Redis学习其三(订阅发布,主从复制,哨兵模式)
  • 优迅股份IPO隐忧:毛利水平“两连降”,研发费用率不及行业均值
  • decltype是什么,什么作用?
  • 【c++】指针的另一大用途:限制实参必须是变量
  • Fish Speech:开源多语言语音合成的革命性突破
  • Nestjs框架: 基于TypeORM的多租户功能集成和优化
  • LeetCode1047删除字符串中的所有相邻重复项
  • wsl 安装 nvm
  • [QOI] qoi_desc | qoi_encode | qoi_decode
  • 高防IP能够防御CC攻击吗?它具备哪些显著优势?
  • 服务管理智能化:R²AIN SUITE 升级带来的两大功能更新哪些值得关注?
  • T5(Text-to-Text Transfer Transformer) 模型
  • 20250718-5-Kubernetes 调度-Pod对象:重启策略+健康检查_笔记
  • 【Spring WebFlux】什么是响应式编程
  • 前缀和 HASH
  • proxy_cache缓存系统
  • 期刊论文-图片格式要求
  • UNet改进(23):如何用SLCAM模块提升UNet的分割性能
  • Google Gemini CLI 配置简要指南
  • 大模型驱动的超短期功率预测算法封装方案
  • SymAgent(神经符号自学习Agent)
  • PowerBi实现Top N和Bottom N的简单示例
  • 番茄项目1:定了一个新的目标——做一个番茄工作法的web项目!
  • 光伏财务管理:在阳光与资本的精密计算中前行
  • VSCode - VSCode 快速跳转标签页
  • Web攻防-访问控制篇水平越权垂直越权未授权访问级别架构项目插件SRC复盘
  • pytest + requests 接口自动化测试框架