C++基础:第七章 函数

2023-05-16

第七章 函数

第1节 函数基础

栈帧结构
在这里插入图片描述

在这里插入图片描述

函数的外部链接

第2节 函数详解

传值、传址、传引用

传参数时的类型退化,传数组时函数形参退化成指针,所以形参不要写数组个数

多维数组作为函数参数时

void fun(int (*par)[4])

int a[3][4] = {0};
fun(a);

避免退化的写法

void fun(int (&par)[3])
    
int a[3];
fun(a);

变长参数

  • initializer_list ,变量类型必须相同

    #include <initializer_list>
    void fun(std::initializer_list<int> par)
        
    fun({1,2,3,4,5});
    
  • 可变长度模板参数 (不限制类型相同,复杂一些)

  • 使用省略号表示形参(不建议使用)

函数缺省实参

void fun (int x = 0){} fun();

缺省实参右侧的参数都必须有缺省实参

传入实参时从左到右与形参匹配

在一个翻译单元中,每个参数的缺省实参只能定义一次

缺省实参为对象时,实参的缺省值会随对象的值变化而变化 (不建议,阅读困难)

推荐方法:源文件中定义函数,头文件中声明函数同时定义缺省实参,main函数中调用函数,最安全。

main函数的两个版本

  • 无形参 int main(){}
  • 带两个形参的 int main(int argc,char* argv[]){}

argc 为非负数,程序运行环境传递给程序的实参个数

argv为指针,指针指向argc+1个指针的数组

函数体

函数体形成域

  • 其中包含自动对象
  • 可包含局部静态对象

函数体的返回值

  • 隐式返回 void
  • 显式返回 return

返回值优化(RVO)

返回类型

表示函数计算结果类型,可以为void

返回类型的几种书写方式

  • 经典:位于函数头前部

  • 11引入新方法:位于函数头的后部

    auto fun(int a,int b) -> int
    {
        return a + b;
    }
    
  • 14引入方式:返回类型自动推导

17引入返回类型的结构化绑定

第3节 函数重载与重载解析

(重载的函数,参数类型不相同)

int fun(int x){
    return x+1;
}
double fun(double x){
    return x+1;
}
fun(3);
fun(3.5);

使用相同的函数名定义多个函数,每个函数具有不同的参数列表

  • 不能基于不同的返回类型进行重载
  • 函数重载与mangling

编译器如何选择正确的版本完成调用

名称查找

限定查找(限定查找域)与非限定查找

非限定查找会进行逐级域查找——名称隐藏(同一域的函数在域内会隐藏其他域的同名函数)

查找通常会在已声明集合中进行

实参依赖查找

namespace MyNS{
    struct Str{};
    void g(Str s){
        
    }
}
MyNS::Str obj;
g(obj);

重载解析

在名称查找基础上进一步选择合适的调用函数

  • 过滤不能被调用的版本

    • 参数个数不对
    • 实参无法转换为形参
    • 实参不满足形参的限制条件
  • 在剩余版本中查找最匹配的版本,匹配级别越低越好(同一匹配级别视为重定义)

    1. 完美匹配,平凡转换(加const)

    2. promotion或加平凡转换

    3. 标准转换或标准平凡转换

    4. *自定义转换

    5. *调用形参为省略号的版本

  • 函数包含多个形参时,所选函数的所有形参的匹配级别都要优于或等于其他函数

第4节 函数相关的其他内容

递归函数

在函数体内调用其自身的函数

通常用于描述复杂的迭代过程(注意避免无线递归)

内联函数

调用函数时,函数体运算较简单,则较多资源用于构建和释放栈帧,针对这一问题编译期可以展开函数,避免构建栈帧。

inline内联标识符,向编译器发出请求,将函数编译时展开

inline内联标识符,将程序级的一次定义原则改为翻译单元级别的一次定义原则

向编译器发出请求,将函数编译时展开

constexpr函数与consteval函数

为了让**某些函数在编译期计算**,引入constexpr函数

(内联函数和constexpr函数都应该定义在头文件中,翻译单元级不重复)

constexpr int fun(int x){
    return x + 1;
}

constexpr int y = 3;
int z = fun(y);

实参也需要是字面值或常量编译表达式

函数指针

函数类型与函数指针类型

int fun(int x){} 函数类型为int(int)

using K = int(int);
K fun;           //相当于函数声明,不可用于定义

或者配合std::function使用

(函数指针多数跟高阶函数配合使用)

函数指针与重载

函数指针作为参数

using K = int(int);
void pla(K* input) {  
	std::cout << (*input)(2) << std::endl;
}

int inc(int x) {
	return x + 1;
}

int main(int argc, char *argv[]) {
	pla(inc);
}

函数指针作为返回值

int inc(int x){
    return x+1;
}
int dec(int x){
    renturn x-1;
}
auto fun(bool input){
    if(input)
        return inc;        //返回函数指针
    else
        return dec;
}

std::cout<<(*fun(true))(100)<<std::endl;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++基础:第七章 函数 的相关文章

  • 【Python】@cache装饰器使用 (依赖cachetools)

    介绍 cachetools 是一个 Python 缓存库 xff0c 可以用于缓存函数的计算结果 xff0c 以提高程序的性能和响应速度 使用 cachetools 可以避免重复计算 减少网络请求 降低数据库负载等问题 xff0c 从而提高
  • Python常见装饰器使用(实用向)

    目录 1 96 64 staticmethod 96 2 96 64 classmethod 96 3 96 64 classmethod 96 与 96 64 staticmethod 96 比较4 96 64 property 96 5
  • 【C++】std::transform、std::back_inserter使用

    std transform函数可以用于对一个序列中的每个元素进行转换 xff0c 并将结果存储到另一个序列中 们需要传递三个参数 xff1a 源序列的起始迭代器 源序列的结束迭代器和目标序列的起始迭代器 此外 xff0c 我们还需要传递一个
  • std::inner_product与std::accumulate初始值设置踩坑

    std inner product函数可以用于计算两个序列的内积 在这个函数中 xff0c 我们需要传递四个参数 xff1a 两个源序列的起始迭代器 一个初始值和一个二元函数对象 std inner product函数将对两个源序列中的每个
  • 树莓派无法连接vnc,树莓派 vnc viewer 显示 cannot currently show the desktop 的解决方法

    最近新买了一块树莓派4B xff0c 正常启动ssh xff0c vnc服务 但vnc viewer上却显示黑屏 cannot currently show the desktop 在网上查找了许多解决方法 xff0c 都不能用 但后来调整
  • 'gbk' codec can't encode character '\xa0' XXX解决方法

    在运行py文件时 xff0c 出现 UnicodeEncodeError gbk codec can t encode character xa0 in position XXX 让人摸不着头脑 注意这三个方面 xff0c 一般都能解决 1
  • 基于stm32cubeIDE学习can通信

    can通信 TO DO 1 CAN FilterTypeDef 中的SlaveStartFilterBank 为从过滤器配置 xff0c 用来选择从过滤器的寄存器号 当选择双CAN模式的时候 xff0c 这个参数要跟CAN2的filtern
  • jetson nano 的GPIO使用

    依次输入以下指令 python span class token comment 进入python编程界面 span span class token operator gt gt span span class token operato
  • 多态的基础语法

    1 向上转型和向下转型的概念 向上转型 自动转型 xff1a 子类 gt 父类 当我们是用父类引用指向子类对象的时候 xff0c 系统会自动向上转型 向下转型 强制转型 xff1a 父类 gt 子类 当父类引用指向子类对象时 xff0c 父
  • qt画个灰度直方图

    步骤 导入图表库在ui界面新建一个wight窗口并提升为那个图表库的类型写函数 输入参数是 xff08 图表 xff0c 待处理图片 xff09 图表的横轴是像素值 从0 255 纵轴是此灰度的像素点数量或者占比所以要挨个判断图像里的每一个
  • 找特征点的算法 SIFT和SURF算法

    SIFT 特征点算法 SIFT算法是记录每个极值点附近的梯度方向 xff0c 并以一个主要梯度方向为基准来兼顾特征旋转的情况 它通过不同模糊程度的灰度图相减找极值 xff0c 筛选确定出真实关键点后按梯度和权重求出关键点的主方向 xff0c
  • nano的CAN通信

    我买的是微雪的树莓派用的SPI转CAN 现在用在jetson nano上 我看了一下俩模块的芯片用的都是一样的 xff0c 引脚也都对得上 xff0c 所以我就打算拿这个模块给nano做can通信 具备CAN功能 xff0c 使用SPI接口
  • 驱动开发基础知识——设备树

    BSP开发工程师 原来BSP就是那些被指臃肿的文件啊 BSP的出生 Linux经过不断的发展 原先嵌入式系统的三层结构逐步演化成为一种四层结构 这个新增加的中间层次位于操作系统和硬件之间 包含了系统中与硬件相关的大部分功能 通过特定的上层接
  • 分布式系统 中间件

    我只是想知道中间件是什么而已 xff0c 结果 中间件 61 平台 43 通信 xff0c 这也就限定了只有用于分布式系统中才能叫中间件 xff0c 同时也把它与支撑软件和实用软件区分开来 中间件技术能屏蔽底层操作系统的复杂性 xff0c
  • 伺服电机控制

    前言 xff1a 感谢各位大佬愿意将知识开源并作出详细的说明 我只是依据自己的学习轨迹稍作整理 xff0c 加以自己的理解并记录于此 本文几乎所有的参考内容都附上了原文链接 xff0c 本文的文字内容有一些是我的 xff0c 有一些是从链接
  • 永磁同步电机的MATLAB建模

    建模是为了能够确定我们输入怎样的电压能得到怎样的转矩 xff0c 以获得怎样的转速 电机这个东西 xff0c 输出的不是位移也不是速度 xff0c 我们要看的输出是力矩 xff0c 力矩够大才有位移才有速度 xff0c 没有位移没有速度的时
  • SVPWM的MATLAB建模

    异步电机矢量控制20讲 xff1a SVPWM的simulink仿真 xff08 总第38讲 xff09 扇区判断 注意 xff0c 这个N是二进制转来的十进制数 波形对应出来的扇区是 5 6 1 2 3 4 如果改变三相电压输入的相位 x
  • Java要素察觉

    简介 xff1a 主要内容来源于b站刘二大人Java课程 xff0c 旨在记录课程中的重要内容 Java课程记录 xff08 课程号作为标题 xff09 02 数据类型03 数组与字符串05 类与对象07 继承08 方法重载 方法重写和多态
  • vscode配置gitee(码云)实现步骤

    第一步 1 百度搜索Git xff0c 出现的第一个网站 xff08 如下图 xff09 Git xff09 2 下载 3 下载之后 双击安装 xff08 安装过程中只需要默认下一步 不需要多余操作 放心大胆的点击下一步 xff09 第二步
  • ROS读取MPU6050数据

    上一篇讲到使用I2C连接Jetson Nano和MPU6050并使用python读取 xff0c 本次基于roscpp连接读取IMU数据 RTIMULib RTIMULib是本次使用的IMU库 xff0c 支持多种常见的IMU模块 xff0

随机推荐

  • 关于navicat报错:Server unexpectedly closed network connection

    破解navicat后 使用navicat连接本地虚拟机 发现出现以下错误 在百度以及谷歌上面查找很多博客 发现我这里的报错信息跟他们不一样 解决方法 1 打开本地虚拟机 进入mysql mysql span class token oper
  • 学会查看官方文档

    曾经经历过的误区 从刚开始接触编程开始 xff0c 基本上接触新事物 xff0c 第一件事情就是去找博客 xff0c 或者买书 往往只需要使用的一个很小的知识点 xff0c 却购买了好几本不同的书籍 事后证明 xff0c 并没有什么太大的用
  • QGroundControl如何进行二次开发

    QGroundControl如何进行二次开发 QGroundControl是一个开源的地面站软件 xff0c 你可以通过以下步骤进行二次开发 xff1a 1 下载并安装QGroundControl 首先需要从QGroundControl的官
  • C 结构体指针malloc分配问题

    C语言中关于结构体指针的内存分配问题 话不多说先上一段代码 span class token keyword typedef span span class token keyword struct span span class toke
  • 这是一个用于记录学习经验的博客

    写在前面 本科时期科研经历较少 xff0c 硕士期间越来越多地开始接触计算机相关的软件 算法 项目等 从2020年入学至今 xff0c 也学习到了一些相关的知识与经验 过去都是通过word的方式记录进展与经验 从今天起我也想尝试通过博客的方
  • ARM64架构的Linux系统中编译C++程序报错fatal error: sys/io.h: No such file or directory

    原因是不同的Linux平台的 io h 放置的位置不同 Windows下的io h直接包含即可 xff1b Linux平台下在sys文件夹下 xff1b ARM架构的系统中在sys文件夹下 xff0c 而且名字也不一样 xff0c 变成了u
  • 矩阵的QR分解

    Gram Schmidt正交化 在提到矩阵的QR分解前 xff0c 必须要提到Gram Schmidt方法 xff0c 理论上QR分解是由Gram Schmidt正交化推出来的 那么Gram Schmidt正交化究竟是什么 在三维空间存在直
  • 常见数学符号及其读法

    大写 小写 英文注音 国际音标注音 中文注音 alpha alfa 阿耳法 beta beta 贝塔 gamma gamma 伽马 deta del
  • cartographer环境配置及运行

    文章目录 1 首先安装ROS2 安装eigen33 安装ceres4 安装cartographer5 试运行总结 xff1a 系统 xff1a Ubuntu 18 04 1 首先安装ROS 在无网络限制的情况下参考官网安装 ref xff1
  • SLAM会议笔记(一)LOAM

    LOAM Lidar Odometry and Mapping in Real time ABSTRACT 将复杂的SLAM问题分离为两个算法 xff0c 一个高频低精度的运动估计 xff0c 另一个低一个数量级的点云匹配和配准算法 REL
  • 相机&IMU内参及外参标定

    1 使用工具 xff1a https github com ethz asl kalibr git 2 特点支持多个相机的内参外参标定 xff0c 即使视域没有重叠 xff1b 支持相机 amp IMU之间标定 xff1b 支持IMU与IM
  • SLAM会议笔记(二)Real-time DEMO

    Real time Depth Enhanced Monocular Odometry Abstract 利用图像和稀疏的深度图做运动估计 xff0c 同时利用三角量测和运动估计得到位置深度的突出图像特征点的深度 xff0c 使用光束平差法
  • SLAM会议笔记(三)V-LOAM

    Visual lidar Odometry and Mapping Low drift Robust and Fast Abstract 提出了一种新的使用激光雷达里程计和视觉里程计的框架 xff0c 提升了表现 xff0c 特别是在剧烈运
  • SLAM会议笔记(四)Lego-LOAM

    LeGO LOAM Lightweight and Ground Optimized Lidar Odometry and Mapping on Variable Terrain Abstract 提出一种轻量级的ground optimi
  • SLAM会议笔记(五)LLOAM

    LLOAM LiDAR Odometry and Mapping with Loop closure Detection Based Correction Abstract 在LOAM的基础上加入了回环检测 xff0c 实现了雷达SLAM的
  • C++基础:第三章 对象与基本类型

    文章目录 第3章 对象与基本类型第1节 初始化 赋值语句第2节 类型详述类型描述类型种类划分与类型相关的标准未定义部分变量 第3节 复合类型 xff1a 从指针到引用指针指针特点相关操作符指针的定义 96 void 96 指针指针的指针指针
  • C++基础:第四章 数组、vector和字符串

    文章目录 第4章 数组 vector和字符串第1节 数组注意事项数组的复杂声明数组中元素的访问数组到指针的隐式转换获得s指向数组开头和结尾的指针数组的其他操作C字符串多维数组 第2节 vector构造和初始化元素的索引和遍历迭代器itera
  • C++基础:第五章 表达式基础与详述

    第五章 表达式基础与详述 第1节 基础 xff1a 引入 表达式由一到多个操作数组成 xff0c 可以求值并 xff08 通常会 xff09 返回求值结果 xff08 函数的调用是一种表达式 xff0c 有时函数不会返回求值结果 xff09
  • C++基础:第六章 语句

    第六章 语句 第1节 语句基础 常见类别 xff1a 表达式语句 xff0c 求值后丢弃 2 43 3 空语句复合语句 xff0c 用大括号 xff0c 形成独立的域 顺序语句 按先后顺序执行实际执行顺序可能产生变换 xff08 编译器优化
  • C++基础:第七章 函数

    第七章 函数 第1节 函数基础 栈帧结构 函数的外部链接 第2节 函数详解 传值 传址 传引用 传参数时的类型退化 xff0c 传数组时函数形参退化成指针 xff0c 所以形参不要写数组个数 多维数组作为函数参数时 void fun int