C++----------函数的调用机制

news2024/12/24 12:55:02
  1. 栈帧的创建与销毁

    • 栈帧创建过程
      • 当一个函数被调用时,系统会在程序的栈空间中为该函数创建一个栈帧。首先,会将函数的返回地址(即调用该函数的下一条指令的地址)压入栈中,这确保函数执行完后能回到正确的位置继续执行后续代码。然后,根据函数参数的类型和数量,将参数的值(如果是值传递)或引用(如果是引用传递)或指针(如果是指针传递)依次压入栈中。最后,为函数内部定义的局部变量分配内存空间。
      • 例如,有函数void func(int a, int b),当调用func(3, 4)时,系统会先将返回地址压入栈,然后将34压入栈作为参数ab的值,接着为func函数内部可能定义的局部变量预留空间。
    • 栈帧销毁过程
      • 当函数执行结束(遇到return语句或者函数体的最后一个花括号)时,栈帧会被销毁。首先,会释放函数内部局部变量所占用的内存空间。然后,根据函数的返回值类型(如果有返回值),将返回值复制到一个临时存储位置(如果是基本数据类型)或者通过移动语义(如果是对象)将返回值传递给调用者。最后,将栈顶指针恢复到调用该函数之前的位置,这样就相当于销毁了这个栈帧,同时将返回地址从栈中弹出,程序继续从返回地址处执行。
  2. 参数传递方式的细节

    • 值传递深入理解
      • 复制过程:在值传递中,实际参数的值会被完整地复制到函数的形式参数中。对于基本数据类型,这是一个简单的字节复制过程。例如,传递一个int类型的参数,会将该int值的字节序列复制到函数参数对应的内存位置。对于自定义结构体等复杂类型,会递归地复制每个成员变量的值。
      • 对原始参数的影响:由于是复制了一份新的值给函数参数,所以在函数内部对参数的修改不会影响到原始的实际参数。例如,对于函数void modify(int num),在函数内部num = 10,但如果在函数外部有int original_num = 5; modify(original_num);original_num的值依然是5
    • 引用传递深入理解
      • 引用的本质:引用在底层实现上可以看作是一个指针常量,它总是指向被引用的对象。当进行引用传递时,实际上传递的是对象的地址,但是在语法上使用起来就像使用原始对象一样。例如,int& ref = original_num;reforiginal_num在内存中指向同一个位置。
      • 对原始参数的影响:因为引用和原始对象共享同一块内存空间,所以在函数内部通过引用对参数进行操作,实际上就是对原始对象进行操作。例如,函数void modifyByReference(int& num),在函数内部num = 10,如果在函数外部有int original_num = 5; modifyByReference(original_num);original_num的值会变为10
    • 指针传递深入理解
      • 指针的操作方式:指针传递是把变量的地址传递给函数。在函数内部,通过解引用指针(使用*操作符)来访问和修改指针所指向的变量的值。例如,函数void modifyByPointer(int* ptr),当传递&original_num作为参数时,在函数内部通过*ptr = 10来修改original_num的值。
      • 与引用传递的区别:虽然指针传递和引用传递都可以在函数内部修改原始变量的值,但指针传递需要显式地解引用指针来访问变量,而引用传递在语法上更简洁,直接使用引用变量就可以访问和修改原始变量。另外,指针可以在函数内部重新赋值指向其他对象,而引用一旦初始化就不能再引用其他对象。
  3. 函数返回值传递机制的细节

    • 基本数据类型返回值传递
      • 复制返回值:当函数返回一个基本数据类型(如intdouble等)的值时,函数会将返回值复制到一个临时存储位置。这个临时存储位置可能是一个寄存器或者栈中的某个位置,具体取决于编译器和硬件架构。例如,对于函数int add(int a, int b) { return a + b; },当调用add函数时,计算a + b的结果会被复制到这个临时位置,然后这个值再被赋值给接收返回值的变量(如int result = add(3, 5);中的result)。
    • 对象返回值传递
      • 返回值优化(RVO):当函数返回一个对象时,C++编译器可能会应用返回值优化。在没有返回值优化的情况下,函数会先创建一个临时对象,将函数内部的对象复制到这个临时对象中(通过调用复制构造函数),然后返回这个临时对象。但是,通过返回值优化,编译器可以直接将函数内部的对象构造到接收返回值的对象的内存空间中,避免了不必要的复制操作。例如,对于函数MyClass createObject(),如果MyClass是一个自定义类,在合适的条件下,编译器会直接将createObject函数内部构造的MyClass对象构造到接收返回值的MyClass对象中,而不是先复制到一个临时对象再进行赋值。
      • 移动语义(Move Semantics):如果编译器没有进行返回值优化,除了复制构造函数外,C++还提供了移动构造函数来更高效地处理对象返回值。移动构造函数允许将一个对象的资源(如动态分配的内存)“移动”到另一个对象中,而不是进行复制。例如,对于一个包含动态分配数组的类,移动构造函数可以将数组的指针从一个对象转移到另一个对象,避免了重新分配内存和复制数组元素的开销。当函数返回对象时,编译器可能会优先调用移动构造函数(如果定义了)来提高效率。
        在这里插入图片描述
        下面是一些代码示例,用来展示 C++ 函数的调用机制,包括栈帧、参数传递以及返回值传递相关内容:
#include <iostream>

// 用于展示栈帧中的局部变量
void localVarDemo() {
    int localVar = 10;
    std::cout << "局部变量 localVar 的值: " << localVar << std::endl;
}

// 值传递示例
void valuePassing(int num) {
    num = 20;
    std::cout << "值传递中函数内 num 的值: " << num << std::endl;
}

// 引用传递示例
void referencePassing(int& num) {
    num = 30;
    std::cout << "引用传递中函数内 num 的值: " << num << std::endl;
}

// 指针传递示例
void pointerPassing(int* num) {
    *num = 40;
    std::cout << "指针传递中函数内 *num 的值: " << *num << std::endl;
}

// 返回基本数据类型示例
int returnBasicType() {
    return 50;
}

// 简单类定义,用于展示对象返回
class MyClass {
public:
    int data;
    MyClass(int value) : data(value) {}
};

// 返回对象示例
MyClass returnObject() {
    MyClass obj(60);
    return obj;
}

int main() {
    // 栈帧中的局部变量演示
    localVarDemo();

    int value = 15;
    // 值传递
    valuePassing(value);
    std::cout << "值传递后 value 的值: " << value << std::endl;

    // 引用传递
    referencePassing(value);
    std::cout << "引用传递后 value 的值: " << value << std::endl;

    // 指针传递
    pointerPassing(&value);
    std::cout << "指针传递后 value 的值: " << value << std::endl;

    // 返回基本数据类型
    int basicResult = returnBasicType();
    std::cout << "返回基本数据类型的结果: " << basicResult << std::endl;

    // 返回对象
    MyClass objResult = returnObject();
    std::cout << "返回对象的 data 值: " << objResult.data << std::endl;

    return 0;
}

代码解释:

  • localVarDemo 函数展示了在栈帧中定义和使用局部变量,函数执行时会创建栈帧来存放 localVar
  • valuePassing 是值传递示例,函数接收参数的副本,所以内部修改不影响外部变量。
  • referencePassing 利用引用传递,函数形参是实参的别名,内部修改会同步到外部变量。
  • pointerPassing 通过指针传递,传递变量地址,函数可通过解引用修改外部变量的值。
  • returnBasicType 返回基本数据类型,返回值被复制给 basicResult
  • returnObject 返回自定义类对象,编译器可能会进行返回值优化,高效地把对象传递给 objResult
    在这里插入图片描述

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

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

相关文章

【Leetcode】855. 考场就座

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 在考场里&#xff0c;有 n n n 个座位排成一行&#xff0c;编号为 0 0 0 到 n − 1 n - 1 n−1。 当学生进入考场后&#xff0c;他必须坐在离最近的人最远的座位上。如果有多个…

Unity引擎学习总结------动画控件

左侧窗格可以在参数视图和图层视图之间切换。参数视图允许您创建、查看和编辑动画控制器参数。这些是您定义的变量&#xff0c;用作状态机的输入。要添加参数&#xff0c;请单击加号图标并从弹出菜单中选择参数类型。要删除参数&#xff0c;请在列表中选择该参数并按删除键&…

UE4_用户控件_1_滑块控制图像颜色的变化

祝愿大美兰陵越来越好&#xff0c;祝愿祖国繁荣昌盛&#xff0c;祝愿人民幸福安康&#xff01; 一、样式展示&#xff1a; 效果&#xff0c;当角色靠近物体&#xff08;只有一个胶囊碰撞体&#xff09;时显示用户控件&#xff0c;调整控件中的滑块值&#xff0c;可以改变UE4lo…

网络编程 02:IP 地址,IP 地址的作用、分类,通过 Java 实现 IP 地址的信息获取

一、概述 记录时间 [2024-12-18] 前置文章&#xff1a;网络编程 01&#xff1a;计算机网络概述&#xff0c;网络的作用&#xff0c;网络通信的要素&#xff0c;以及网络通信协议与分层模型 本文讲述网络编程相关知识——IP 地址&#xff0c;包括 IP 地址的作用、分类&#xff…

【pycharm】远程服务器之后如何打开终端

【pycharm】远程服务器之后如何打开终端 在pycharm中&#xff0c;我们通过远程连接服务器&#xff0c;此时如果我们需要在终端运行的话&#xff0c;并不能直接在本地终端运行&#xff0c;而是需要连接到服务器终端才能运行命令 设置如下&#xff1a; 输入服务器的ip、端口、…

C#+OpenCv深度学习开发(常用模型汇总)

在使用 OpenCvSharp 结合深度学习进行机器视觉开发时&#xff0c;有许多现成的模型可以使用。以下是一些常用的深度学习模型&#xff0c;适用于不同的机器视觉任务&#xff0c;包括物体检测、图像分类和分割等。 使用示例 在 OpenCvSharp 中加载和使用这些模型的基本示例&…

dolphinscheduler服务注册中心源码解析(三)RPC提供者服务整合注册中心注册服务实现源码

RPC提供者服务整合注册中心注册服务实现源码 1.概述2.源码解读思路3.实现2.1.应用服务的RPC服务接口定义2.1.1.MasterServer应用中提供的RPC接口服务2.1.2.WorkerServer应用中提供的RPC接口服务2.2.应用服务的RPC服务接口实现2.2.1.MasterServer应用中提供的RPC接口服务实现类2…

重生之我在异世界学编程之C语言:数据在内存中的存储篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 引言正文一、数据类型介绍1.内置类型2.自定义…

线程的概念及基本应用

目录 线程的概念 Java中多线程应用 继承Thread类 实现Runnable接口 实现Callable接口 线程的生命周期 线程的基本操作及原理 Thread.join的使用及原理 Thread.sleep的作用 问题 Thread.sleep的工作流程 wait和notify的使用 wait notify 例子 生产者消费者模式 Th…

联通软研院:基于OceanBase落地检索增强生成 (RAG) 的应用实践

本文作者&#xff1a;邱永刚&#xff0c;联通软件研究院OceanBase研发负责人&#xff0c;主要负责中国联通自研关系型数据库分布式CUDB研发、支撑、运维工作。 近年来&#xff0c;生成式人工智能技术取得了飞速进步&#xff0c;很多大模型在自然语言处理及对话系统领域的运用吸…

【更新】LLM Interview

课程链接&#xff1a;BV1o217YeELo 文章目录 LLM基础相关1. LLMs概述2. 大语言模型尺寸3. LLMs的优势与劣势4. 常见的大模型分类5. 目前主流的LLMs开源模型体系有哪些&#xff08;Prefix Decoder&#xff0c;Causal Decoder&#xff0c;Encoder-Decoder的区别是什么&#xff09…

模型 课题分离

系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。明确自我与他人责任。 1 课题分离的应用 1.1课题分离在心理治疗中的应用案例&#xff1a;李晓的故事 李晓&#xff0c;一位28岁的软件工程师&#xff0c;在北京打拼。他面临着工作、家庭和感情的多重…

sqlite 自定以脚本解释器

应用程序使用 libfdt 解析设备树,获取兼容性配置 内核源码支持libfdt 标准设备树语法,不用自己再创造 非常的爽,因为设备树支持预编译 一些可以跑类 BSD 系统的设备也可以使用这样的方法,不仅仅是在linux 系统上跑 有pylibfdt 支持解析设备树&#xff0c;校验设备树是否是正确的…

某医院vsan部署技术手册

环境配置 服务器4900G5五台 配置信息&#xff1a;cpu 8368*2颗 &#xff0c;内存256GB ,双口万兆网卡两个&#xff0c;四口千兆&#xff0c;RAID卡LSI9361-8i12G SAS RAID &#xff0c;两块固态盘480SSD &#xff0c;2*1.92TB NVME盘&#xff0c;5*8T盘。 万兆交换机两台H3C…

【编辑器扩展】打开持久化路径/缓存路径/DataPath/StreamingAssetsPath文件夹

代码 [MenuItem("Assets/Open Explorer/PersistentDataPath")]public static void OpenPersistentDataPath(){Application.OpenURL(Application.persistentDataPath);}[MenuItem("Assets/Open Explorer/DataPath")]public static void OpenDataPath(){Appl…

【day14】异常处理与Object类深入解析

【day13】回顾 在深入探讨异常处理与Object类之前&#xff0c;让我们回顾一下【day13】中的关键内容&#xff1a; 权限修饰符&#xff1a; public&#xff1a;最广的访问范围&#xff0c;任何地方都可以访问。protected&#xff1a;在同包和子类中可以访问。默认&#xff08;无…

【NLP 17、NLP的基础——分词】

我始终相信&#xff0c;世间所有的安排都有它的道理&#xff1b;失之东隅&#xff0c;收之桑榆 —— 24.12.20 一、中文分词的介绍 1.为什么讲分词&#xff1f; ① 分词是一个被长期研究的任务&#xff0c;通过了解分词算法的发展&#xff0c;可以看到NLP的研究历程 ② 分词…

11.vector的介绍及模拟实现

1.vector的介绍 记得之前我们用C语言实现过顺序表&#xff0c;vector本质上也是顺序表&#xff0c;一个能够动态增长的数组。 vector 的底层实现机制 - 动态数组&#xff1a;vector 的底层实现是动态数组。它在内存中连续存储元素&#xff0c;就像一个可以自动调整大小的数…

# 起步专用 - 哔哩哔哩全模块超还原设计!(内含接口文档、数据库设计)

↑ 上方下载文档 (大小374KB) 接口文档预览 (超过50个接口) 一、数据库25张表er-关系清晰构图&#xff01;(tip: 鼠标右键图片 > 放大图像) 二、难点/经验 详细说明 热门评论排序评论点赞列表|DTO封装经验分享|精华接口文档说明 组员都说喜欢分档对应枚举码 如果这篇文章…

android RecyclerView 垂直显示示例(java)

RecyclerView垂直列表显示示例&#xff0c;显示图片加文字。 1、RecyclerView.Adapter适配器 public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {private Context mContext;private List<TitleBean> titleBeans;public ListAdapt…