当前位置: 首页 > 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.xdnf.cn/news/1145953.html

相关文章:

  • 应用集成体系深度解析:从数据互通到流程协同
  • 20250718【顺着234回文链表做两题反转】Leetcodehot100之20692【直接过12明天吧】今天计划
  • Machine Learning HW2 report:语音辨识(Hongyi Lee)
  • 操作系统-处理机调度和死锁进程同步
  • 全球天气预报5天(经纬度版)免费API接口教程
  • HarmonyOS-ArkUI Web控件基础铺垫4--TCP协议- 断联-四次挥手解析
  • 70 gdb attach $pid, process 2021 is already traced by process 2019
  • postman接口测试,1个参数有好几个值的时候如何测试比较简单快速?
  • PPIO × Lemon AI:一键解锁全流程自动化开发能力
  • 【DataWhale】快乐学习大模型 | 202507,Task03笔记
  • 机械材料计算软件,快速核算重量
  • Python暑期学习笔记5
  • Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南
  • Nestjs框架: 基于TypeORM的多租户功能集成和优化
  • 多线程-4-线程池
  • 锁步核,为什么叫锁步核?
  • Android性能优化之启动优化
  • leetcode15.三数之和题解:逻辑清晰带你分析
  • RPG60.生成可拾取物品
  • camera2 outputbuffer的流转过程
  • 2025外卖江湖:巨头争霸,谁主沉浮?
  • python网络爬虫(第三章/共三章:驱动浏览器窗口界面,网页元素定位,模拟用户交互(输入操作、点击操作、文件上传),浏览器窗口切换,循环爬取存储)
  • 某邮生活旋转验证码逆向
  • nastools继任者?极空间部署影视自动化订阅系统『MediaMaster』
  • Linux下使用原始socket收发数据包
  • LatentSync: 一键自动生成对嘴型的视频
  • 域名WHOIS信息查询免费API使用指南
  • 笔试——Day12
  • Java Map 集合详解:从基础语法到实战应用,彻底掌握键值对数据结构
  • 爬虫小知识(二)网页进行交互