新闻详情

新闻详情

首页 / 资讯中心 / 详情

C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?

发布时间:2026/10/2 2:33:13来源:尧图网络
C++ 第 13 课:值传递 —— 为什么函数里改了,外面却没变?
上一课标准答案不能。因为a是test()里的局部变量只能在test()的作用域里使用。输出6 6因为每次调用test()都会重新创建一个新的a 5然后a变成 6。3.可以。因为a定义在外层main()里内层if可以访问外层变量。4.b定义在if的{}里面离开这对花括号后它的作用域就结束了所以外面不能直接使用。第 13 课值传递 —— 为什么函数里改了外面却没变这一课非常重要因为它直接通向后面的引用 指针 * 函数参数 数组 对象 机器人状态修改先看一个很奇怪的例子。#include iostream void change(int a) { a 100; } int main() { int x 5; change(x); std::cout x std::endl; return 0; }你可能会直觉地觉得change(x)里面把a改成了 100那x应该也变成 100。但实际输出是5为什么1. 关键a和x不是同一个变量看调用change(x);假设x 5;调用函数时C 会把x的值5复制一份交给函数参数int a所以可以想象成main 里面 x ┌─────┐ │ 5 │ └─────┘ 调用 change(x) 复制一个 5 ↓ change 里面 a ┌─────┐ │ 5 │ └─────┘注意x和a是两个不同的盒子。只是开始时里面都放着 5。2. 函数里面改的是a执行a 100;于是变成main x ┌─────┐ │ 5 │ └─────┘ change a ┌─────┐ │ 100 │ └─────┘所以改的是a不是x函数结束以后a消失。而x从头到尾还是53. 这就叫“值传递”专业名字pass by value值传递意思是把变量里的“值”复制一份传进去。不是把原变量本身交进去。4. 再看一个更明显的例子void addOne(int number) { number; }然后int main() { int count 10; addOne(count); std::cout count std::endl; }调用时count 10复制给number 10然后函数里number;变成number 11但是count依然10所以最后输出105. 用“复印件”理解最简单你可以把值传递理解成你把文件复印一份给别人。原文件x 5复印件a 5别人把复印件改成a 100你的原文件x 5不会自动变化。这就是值传递最好的直觉。6. 那为什么之前calculateError没问题之前我们写double calculateError(double target, double current) { return target - current; }调用double result calculateError(50.0, 20.0);这里我们根本不需要修改外部变量。函数只是拿到两个值 ↓ 计算 ↓ 返回结果所以值传递非常合适。7. 值传递什么时候特别常见例如double square(double x) { return x * x; }调用double result square(3.0);我们只是想让函数计算3 × 3并不希望外面的变量被改掉。所以值传递非常安全。8. 一个机器人例子double limitAngle(double angle) { if (angle 90.0) { angle 90.0; } return angle; }调用double joint_angle 120.0; double safe_angle limitAngle(joint_angle);函数收到angle 120然后改成angle 90返回90所以safe_angle 90但原来的joint_angle仍然是120因为传进去的是副本。9. 这其实有好处值传递的一个优点就是函数内部乱改参数不会影响外面的原变量。例如void test(int x) { x 999; }你在外面int motor_id 2; test(motor_id);motor_id不会突然变成 999。这能减少很多意外修改。10. 但是有时候我们就是想改外面的变量比如int speed 10;我写一个函数void setSpeed(int speed) { speed 100; }然后setSpeed(speed);你可能希望外面的speed变成 100。但值传递下它不会变。这时候就需要下一阶段的重要概念引用 reference也就是不过我们这一课先把“值传递”彻底吃透。11. 再看一遍完整程序#include iostream void change(int a) { a 100; std::cout Inside: a std::endl; } int main() { int x 5; change(x); std::cout Outside: x std::endl; return 0; }执行过程x 5 ↓ 调用 change(x) ↓ 把 5 复制给 a ↓ a 5 ↓ a 改成 100 ↓ 输出 Inside: 100 ↓ 函数结束 ↓ a 消失 ↓ 回到 main ↓ x 还是 5 ↓ 输出 Outside: 5所以Inside: 100 Outside: 512. 参数名不需要和外面一样例如void printValue(int number) { std::cout number std::endl; }外面int age 20; printValue(age);调用时age 的值 20 ↓ 复制给 number所以number 20变量名字不需要一样。13. 就算名字一样也还是两个变量看void change(int x) { x 100; } int main() { int x 5; change(x); std::cout x std::endl; }这里函数参数也叫x外面也叫x但是它们仍然不是同一个变量。可以想象成main 房间里的 x 5 change 房间里的 x 5名字相同不代表同一个东西。最终还是输出514. 参数本质上也是函数内部的局部变量这和上一课正好接上。void change(int a)这里a就是change()内部的一个局部变量。只不过它的初始值由调用者传进来。例如change(20);相当于函数开始时a 20函数结束后这个a的生命周期结束。15. 一个容易误解的机器人例子假设void stopMotor(double speed) { speed 0.0; }然后int main() { double motor_speed 100.0; stopMotor(motor_speed); std::cout motor_speed std::endl; }你可能觉得stopMotor()不是把速度改成 0 了吗但这里只改了函数里的speed所以输出还是100这就是为什么理解值传递非常重要。以后你看到真实机器人代码时如果一个函数“明明改了参数但外面没变”首先就要检查是不是值传递16. 值传递的核心图把这个牢牢记住外部变量 x 5 │ │ 复制值 ▼ 函数参数 a 5 │ │ 修改 ▼ a 100 外面的 x 仍然 5不是x 和 a 指向同一个盒子这个“同一个盒子”的效果下一课的引用才会出现。本课小练习第 1 题void change(int a) { a 20; } int main() { int x 5; change(x); std::cout x std::endl; }最后输出什么第 2 题void addTen(int number) { number 10; std::cout number std::endl; } int main() { int x 3; addTen(x); std::cout x std::endl; }依次输出什么第 3 题为什么void change(int a) { a 100; }不能直接改变外面的int x 5;第 4 题一句话解释什么是值传递
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Android直读U盘底层实现:绕过libaums解析USB与文件系统 2026/10/2 13:27:17

Android直读U盘底层实现:绕过libaums解析USB与文件系统

1. 不靠 libaums,Android 直读 U 盘到底难在哪先别急着搜库、抄代码。这事儿得从根上讲清楚:Android 上读 U 盘,系统明明自带“OTG 文件管理”功能,插上去偶尔也能弹出提示,可一旦你想在自己的 App 里直接读取 U 盘里的…

阅读更多 →
基于DRV8818与STM32F042K6的工业步进电机控制系统设计 2026/10/2 13:27:11

基于DRV8818与STM32F042K6的工业步进电机控制系统设计

1. 为什么选 DRV8818 和 STM32F042K6 这套组合先聊一个很多人问我的问题:做步进电机控制,市面上驱动芯片一大堆,A4988、DRV8825、TB6600这些都烂大街了,为什么还要折腾 DRV8818PWPR 和 STM32F042K6 这种相对冷门的搭配&#xff1f…

阅读更多 →
Java环境监测系统源码毕业设计:Spring Boot+MyBatis实现数据采集与告警 2026/10/2 13:27:04

Java环境监测系统源码毕业设计:Spring Boot+MyBatis实现数据采集与告警

简介:这份资源是面向计算机专业学生与Java初学者的一套环境监测系统完整源码,可直接用于毕业设计、课程设计或项目练手。系统围绕空气质量、温湿度、二氧化碳浓度等环境数据的采集、处理与展示展开,采用Java语言配合MVC分层架构,后…

阅读更多 →
Zvec 向量数据库贡献指南:从源码编译、测试到提交 PR 的完整开发者流程 2026/10/2 13:27:04

Zvec 向量数据库贡献指南:从源码编译、测试到提交 PR 的完整开发者流程

向量数据库数据库嵌入式数据库 【免费下载链接】zvec A lightweight, lightning-fast, in-process vector database 项目地址: https://gitcode.com/GitHub_Trending/zve/zvec 点击查看 免费下载 Zvec 是一个内嵌式(in-process)向量数据库&a…

阅读更多 →
AI编程助手能力扩展实战:superpowers技能包机制与工程化集成指南 2026/10/2 13:26:58

AI编程助手能力扩展实战:superpowers技能包机制与工程化集成指南

1. 从“superpowers”这个标题说起:它到底是什么第一次看到“superpowers”这个词,很多人脑子里蹦出来的可能是超级英雄电影,或者是某个游戏里的技能系统。但如果你是在技术社区、代码仓库或者开发者聊天群里反复刷到这个关键词,那…

阅读更多 →
Pixelle-Video 完整教程:输入一个主题,AI视频生成只要3分钟 2026/10/2 13:26:52

Pixelle-Video 完整教程:输入一个主题,AI视频生成只要3分钟

Pixelle-Video 完整教程:输入一个主题,AI视频生成只要3分钟 【免费下载链接】Pixelle-Video 🚀 AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video Pixe…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉