C++:参数传递方法(Parameter Passing Methods)

news2025/7/22 22:34:07

目录

 1. 值传递(Pass by Value)

2. 地址传递(Pass by Address) 

 3. 引用传递(Pass by Reference)

 数组作为函数参数(Array as Parameter)

数组作为函数返回值


什么是函数(Function)?

定义:函数是一段封装了特定功能的代码块(Code Block),接受输入(参数,Parameters),执行操作,并可选返回结果。函数提高代码的模块化(Modularity)和可复用性(Reusability)。

为什么需要函数?

  • 核心需求:程序需要重复执行某些逻辑(如计算、数据处理),而不希望重复写代码。函数将逻辑封装,调用时只需提供输入。

什么是结构体(Structure)?

定义:结构体是一种用户定义的数据类型(User-Defined Data Type),将多个相关变量(成员,Members)组织成一个整体,方便管理和操作数据。

为什么需要结构体?

  • 核心需求:程序需要处理一组相关数据(如学生的姓名、学号、成绩),单独定义变量会很零散,结构体将它们组合成一个逻辑单元。

 1. 值传递(Pass by Value)

void swap(int a, int b) { // 值传递,a和b是x和y的副本
    int temp = a;
    a = b;
    b = temp;
}
int main() {
    int x = 10, y = 20;
    swap(x, y); // 传递x和y的副本
    std::cout << "x: " << x << ", y: " << y << std::endl; // 输出:x: 10, y: 20
    return 0;
}

原理:

  • 函数接收到的是ab 的拷贝副本。

  • 这些副本在函数的栈区 stack里存在。

  • 修改这些副本不会影响原始变量。

 

工作原理:a和b是x和y的副本,函数修改a和b,但x和y不变。

优点:

  • 安全:函数无法修改原始数据,适合不需要改变输入的场景。

  • 简单:代码直观,适合小数据(如int)。

缺点:

  • 无法实现swap目标:原始变量x和y未交换。

  • 效率低:对于大对象(如结构体、数组),复制副本耗时耗空间。

适用场景:只读操作或小数据传递。 

2. 地址传递(Pass by Address) 

指针传递将变量的内存地址(Memory Address)传递给函数,函数通过指针(Pointer)操作原始数据。 

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

原理:

  • 传入的是变量的地址(内存位置)。

  • 函数通过指针 *a*b 解引用,直接修改了内存中的值。

  • 实际修改的是原始变量。

 

工作原理:a和b存储x和y的地址,通过*(解引用,Dereference)访问和修改原始数据。 

  • 优点:

    • 可修改原始数据:成功实现swap目标,x和y值交换。

    • 高效:只传递地址(通常4或8字节),适合大对象(如结构体、数组)。

    • 支持空指针检查:可用nullptr表示无效数据。

缺点:

  • 复杂性增加:需要使用*和&,容易出错(如忘记解引用)。

  • 需检查空指针:否则可能导致崩溃(未定义行为,Undefined Behavior)

 3. 引用传递(Pass by Reference)

引用传递将变量的**引用(Reference)**传递给函数,函数直接操作原始数据。引用是C++特有的机制,像是变量的“别名”(Alias)。

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

原理:

  • & 并不是取地址,而是声明a 和 b 是引用(Reference)。

  • 它们是原始变量的别名。

  • 编译器在底层偷偷用指针处理,但你写的代码不需要 *&

 

 工作原理:a和b是x和y的引用,操作a和b直接修改x和y。

优点:

  • 可修改原始数据:成功实现swap目标。

  • 语法简洁:无需*或&,代码像值传递一样直观。

  • 高效:传递引用(底层是地址),不复制数据。

缺点:

  • 可能意外修改:调用者可能不希望数据被改变,需明确意图。

  • 无空值检查:引用必须绑定有效变量,无法像指针用nullptr。

 数组作为函数参数(Array as Parameter)

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
}

在 C++ 中,数组作为函数参数传递时,实际上传递的是数组的首地址(指针)! 

🔬 C++ 中数组作为参数时,会退化为指针

void printArray(int arr[], int size);
// 实际等价于:
void printArray(int* arr, int size);

原因:

在函数参数中,数组类型会退化(decay)为指向其首元素的指针。这是 C/C++ 语言设计的一部分,背后原因:

  • 函数参数不能接收整个数组的“值”,因为数组不能整体赋值(不能复制整个内存块)。

  • 所以只能传递一个地址,也就是数组第一个元素的地址 &arr[0]

  • 这也是为什么你必须单独传一个 size 参数 —— 因为函数内无法知道数组长度。

数组作为函数返回值

C++中,函数不能直接返回局部数组(栈上分配,函数结束即销毁),需要通过指针(堆内存或外部数组)或现代C++容器(如std::vector)实现。 

int[] getArray() {  // ❌ 错误:不能返回数组类型
    int arr[5] = {1, 2, 3, 4, 5};
    return arr;     // ❌ 错误:返回局部数组
}
  • 它是一个在栈区(Stack)上分配的内存块。

  • 函数执行完毕后,这块内存就会被自动销毁。

  • 返回这个地址 → 悬空指针(Dangling Pointer) → 引发未定义行为。

✅ 正确的做法:用“能长期存在”的内存来返回数组

我们有几种安全的替代方案,分别基于不同内存管理方式:

 方法 1:返回堆上数组

int* getArray() {
    int* arr = new int[5]{1, 2, 3, 4, 5};  // 分配在堆上
    return arr;  // 返回地址
}

特点:

  • 返回的是堆内存地址,函数执行完也不会释放。

  • 必须手动 delete[] 来释放内存,否则内存泄漏。

 

方法 2:用 static 关键字返回静态数组 

int* getArray() {
    static int arr[5] = {1, 2, 3, 4, 5};
    return arr;  // 返回的是静态变量地址
}

特点:

  • static 数组会在程序整个生命周期中都存在。

  • 不在栈上,不会被销毁。

  • 不需要 delete,但多次调用会共享同一个数组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大语言模型的推理能力

2025年&#xff0c;各种会推理的AI模型如雨后春笋般涌现&#xff0c;比如ChatGPT o1/o3/o4、DeepSeek r1、Gemini 2 Flash Thinking、Claude 3.7 Sonnet (Extended Thinking)。 对于工程上一些问题比如复杂的自然语言转sql&#xff0c;我们可能忍受模型的得到正确答案需要更多…

Redis的安装与使用

网址&#xff1a;Spring Data Redis 安装包&#xff1a;Releases tporadowski/redis GitHub 解压后 在安装目录中打开cmd 打开服务&#xff08;注意&#xff1a;每次客户端连接都有先打开服务&#xff01;&#xff01;&#xff01;&#xff09; 按ctrlC退出服务 客户端连接…

2024年数维杯国际大学生数学建模挑战赛C题时间信号脉冲定时噪声抑制与大气时延抑制模型解题全过程论文及程序

2024年数维杯国际大学生数学建模挑战赛 C题 时间信号脉冲定时噪声抑制与大气时延抑制模型 原题再现&#xff1a; 脉冲星是一种快速旋转的中子星&#xff0c;具有连续稳定的旋转&#xff0c;因此被称为“宇宙灯塔”。脉冲星的空间观测在深空航天器导航和时间标准维护中发挥着至…

C# 控制台程序获取用户输入数据验证 不合规返回重新提示输入

在 C# 控制台程序中实现输入验证并循环重试&#xff0c;可以通过以下方式实现高效且用户友好的交互。以下是包含多种验证场景的完整解决方案&#xff1a; 一、通用输入验证框架 public static T GetValidInput<T>(string prompt, Func<string, (bool IsValid, T Val…

TDengine 运维——巡检工具(安装前检查)

简介 本文档旨在介绍 TDengine 安装部署前后配套的巡检工具。 相关工具的功能简介&#xff1a; 工具名称功能简介安装前检查部署前对 TDengine 安装部署的依赖要素进行安装前检查安装前预配置部署前对 TDengine 安装部署的依赖要素进行安装前预配置安装部署指定环境安装部署…

【Linux】权限chmod命令+Linux终端常用快捷键

目录 linux中权限表示形式 解析标识符 权限的数字序号 添加权限命令chmod 使用数字表示法设置权限 使用符号表示法设置权限 linux终端常用快捷键 &#x1f525;个人主页 &#x1f525; &#x1f608;所属专栏&#x1f608; 在 Linux 系统里&#xff0c;权限管理是保障系…

Java八股文智能体——Agent提示词(Prompt)

这个智能体能够为正在学习Java八股文的同学提供切实帮助&#xff1a;不仅可以帮你优化答案表述&#xff0c;还能直接解答八股文相关问题——它会以面试者的视角&#xff0c;给出贴合求职场景的专业回答。 将以下内容发送给任何一个LLM&#xff0c;他会按照你提示词的内容&…

Go语言的context

Golang context 实现原理 本篇文章是基于小徐先生的文章的修改和个人注解&#xff0c;要查看原文可以点击上述的链接查看 目前我这篇文章的go语言版本是1.24.1 context上下文 context被当作第一个参数&#xff08;官方建议&#xff09;&#xff0c;并且不断的传递下去&…

数据库原理 试卷

以下是某高校教学管理系统的毕业论文指导ER图&#xff0c;数据信息&#xff1a;一名教师指导多名学生&#xff0c;一名学生只能选择一名教师&#xff0c;试分析完成以下各题&#xff0c;如用SQL命令完成的&#xff0c;在SQL Server2008验证后把答案写在题目的下方。 图1 毕业论…

【Qt开发】对话框

目录 1&#xff0c;对话框的介绍 2&#xff0c;Qt内置对话框 2-1&#xff0c;消息对话框QMessageBox 2-2&#xff0c;颜色对话框QColorDialog 2-3&#xff0c;文件对话框QFileDialog 2-4&#xff0c;字体对话框QFontDialog 2-5&#xff0c;输入对话框QInputDialog 1&…

2025年渗透测试面试题总结-匿名[校招]攻防研究员(应用安全)(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 匿名[校招]攻防研究员(应用安全) 基础部分 1. HTTP状态码 2. HTTP请求方法及作用 3. 网络分层及协议 OW…

碰一碰发视频系统--基于H5场景开发

#碰一碰发视频# 旨在构建一个基于移动网页&#xff08;H5&#xff09;的视频“碰传”交互系统&#xff0c;提供类似华为/苹果设备 NFC 轻碰分享的便捷体验。其核心技术依赖于移动端可用的近场通信&#xff08;NFC 或 H5 相关 API&#xff09;和可靠的媒体数据传输方案。实现细节…

MagicAnimate 论文解读:引入时间一致性的视频人物动画生成方法

1. 前言/动机 问题&#xff1a;现有动画生成方法缺乏对时间信息的建模&#xff0c;常常出现时间一致性差的问题 描述&#xff1a; 现有的动画生成方法通常采用帧变形&#xff08;frame-warping&#xff09;技术&#xff0c;将参考图像变形以匹配目标动作。尽管这类方法能生成较…

数据结构:递归(Recursion)

目录 示例1&#xff1a;先打印&#xff0c;再递归 示例2&#xff1a;先递归&#xff0c;再打印 递归的两个阶段 递归是如何使用栈内存 复杂度分析 递归中的静态变量 内存结构图解 递归&#xff1a;函数调用自己 必须有判断条件来使递归继续或停止 我们现在通过这两个示…

Cesium快速入门到精通系列教程一:打造第一个Cesium应用

一、打造第一个Cesium应用 1、官方渠道下载Cesium&#xff08;可选择历史版本&#xff09; ​​GitHub Releases页面​​&#xff1a;https://github.com/CesiumGS/cesium/releases 访问 Cesium GitHub Releases&#xff0c;此处列出了所有正式发布的版本。 通过标签&#…

力扣题解106:从中序与后序遍历序列构造二叉树

一、题目内容 题目要求根据二叉树的中序遍历序列和后序遍历序列来重建二叉树。具体来说&#xff0c;我们需要利用中序遍历序列和后序遍历序列的特点&#xff0c;通过递归的方法逐步构建出完整的二叉树。 中序遍历序列的特点是&#xff1a;左子树 -> 根节点 -> 右子树。后…

学习STC51单片机25(芯片为STC89C52RCRC)

每日一言 生活就像弹簧&#xff0c;你弱它就强&#xff0c;你强它就弱&#xff0c;别轻易认输。 ESP8266作为路由器模式&#xff08;AP模式&#xff09;也就是在局域网内可以有服务器的作用 那么我们需要将pc作为设备进行连接ESP的发射出来的WIFE 叫做这个AI啥的 也有可能叫做…

宁夏农业科技:创新引领,赋能现代农业新篇章

在广袤的宁夏大地上&#xff0c;农业科技如同一股强劲的春风&#xff0c;吹拂着每一寸土地&#xff0c;为宁夏的农业发展注入了新的活力与希望。近年来&#xff0c;宁夏农业科技以其独特的创新力和实践力&#xff0c;不断推动着现代农业的转型升级&#xff0c;让这片古老的土地…

Accelerate 2025北亚巡展正式启航!AI智御全球·引领安全新时代

近日&#xff0c;网络安全行业年度盛会Accelerate 2025北亚巡展正式在深圳启航&#xff01;智库专家、产业领袖及Fortinet高管、产品技术团队和300余位行业客户齐聚一堂&#xff0c;围绕“AI智御全球引领安全新时代”主题&#xff0c;共同探讨AI时代网络安全新范式。大会聚焦三…

005学生心理咨询评估系统技术解析:搭建科学心理评估平台

学生心理咨询评估系统技术解析&#xff1a;搭建科学心理评估平台 在心理健康教育日益受重视的当下&#xff0c;学生心理咨询评估系统成为了解学生心理状态的重要工具。该系统涵盖试卷管理、试题管理等核心模块&#xff0c;面向管理员和用户两类角色&#xff0c;通过前台展示与…