c++基础入门二

news/2024/9/18 17:13:46/ 标签: c++

C++基础入门(二)

一、函数重载

在自然语言中,一句话或者一个词有不同的意思。例如:国乒和别人比赛是“谁也赢不了”,而国足和别人比赛是“谁也赢不了”

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

类型

一、参数类型不同

//函数名相同,参数不同
void ADD(int a, int b) {cout << a + b << endl;
}void ADD(double a, double b) {cout << a + b << endl;
}int main() {ADD(1, 3);ADD(2.3, 4.5);return 0;
}

image-20240913165853887

二、参数个数不同

//参数个数不同
void Fun() {cout << "Fun()" << endl;
}
void Fun(int a) {cout << "Fun(int a)" << endl;
}

三、参数的类型顺序不同

//参数顺序不同
void Add(int a, char b) {cout <<a<<b<< endl;
}
void Add(char b, int a) {cout << a<<b<< endl;
}int main() {Add(1, 'a');Add('a', 1);return 0;
}

实现原理

为什么C++支持函数重载,C不支持呢?

C/C++运行一个程序,需要经历几个阶段:预处理编译汇编链接

image-20240913174643866

程序执行的过程

image-20240913175304401

程序处理过程

在处理程序的过程中,为了识别重载的函数,编译时会给函数修饰规则,在不同系统环境下,对应的修饰规则也不同,因为Windous下的修饰规则太过于复杂,这里就演示Linux下的规则。

Linux下修饰规则*

gcc命令把test.c编译成C语言文件

//test.c
int Add(int a,int b){return a+b;
}
Fun(double a,int x,int *p){
}
int main(){Add(1,3);Fun(3,4,0)
}

image-20240913182004228

image-20240913181931811

在反汇编状态下,C语言是不支持函数重载的,也没有对应的命名规则。

g++命令把test.c`编译成**C++**文件

image-20240913193819167

可以看见,在Linux下函数修饰规则是

_Z+字符数+函数名+类型缩写

所以,C++就支持了函数重载。另外如果对Windous下的修饰规则感兴趣,可以查看微软官方的介绍修饰名 | Microsoft Learn

二、引用

引用不是定义一个新变量,而是给已经存在的变量别名,系统不会为引用开辟新的内存空间,而是和引用的变量公用一个内存空间。

如何理解引用呢。大家都知道,李逵在江湖上人称黑旋风,而在家被称为铁牛

用法:类型& 引用变量名(对象名)=对象

void Fun() {int a = 10;int& b = a;cout << a << endl;cout << b << endl;
}

image-20240913195150125

输出结果都是一样的

注意:引用的类型必须是实体的类型

特性

1、引用在定义时就必须初始化

2、一个变量可以有多个引用

3、该引用已经和实体绑定,就不能引用别的实体

int main() {int a = 10;//int& b;引用必须初始化int &b=a;int &bb=a;int &bbb=a;//可以有多个引用
}

image-20240913195935628

引用必须初始化

常引用

在引用常量const时,引用的变量也必须是const

就如一句话:权力只能向下兼容,不能以下犯上

int main() {const int a = 10;int& b = a;//会报错,因为a是常量类型const int& rb = a;//正确用法//向下兼容int b=100;const int& rb=b;
}

image-20240913201057784

使用场景

一、做参数

void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}

在以往我们用C语言写一个交换函数是这样的,还需要指针。很不方便,而有了引用之后,比指针方便多了。

void Swap(int* a, int* b) {int tmp = *a;*b = *a;*a = tmp;
}

二、做返回值

int& Count()
{static int n = 0;n++;// ...return n;
}

引用和指针的区别

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址

  2. 引用在定义时必须初始化,指针没有要求

  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体

  4. 没有NULL引用,但有NULL指针

  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)

  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

  7. 有多级指针,但是没有多级引用

  8. 访问实体方式不同,指针需要显式解引用引用编译器自己处理

  9. 引用比指针使用起来相对更安全

三、内联函数

概念:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率

int ADD(int a, int b) {return a + b;
}
int main() {ADD(1, 4);return 0;
}

转到反汇编

image-20240914102446365

call命令可以理解成建立栈帧

可以看见ADD函数是新建立一个栈帧(消耗内存空间)。

在ADD前面加上inline,再进入反汇编查看

inline int ADD(int a, int b) {return a + b;
}int main() {ADD(1, 4);return 0;
}

image-20240914102841763

发现怎么还有call命令

1、在debug模式下,进入反汇编模式,是查看不了内联函数的

2、在release模式下,进入反汇编才能查看内联函数的过程

这里给出VS2022查看内联函数的设置

在资源管理器右键当前cpp文件,查看属性

image-20240914103236760

选择优化,然后找到内联函数展开,模式调成以下

image-20240914103411424

在常规里面,找到调试信息格式,改成程序数据库

image-20240914103450084

最后,我们在重新进入反汇编

image-20240914103559671

发现call已经神奇的消失了。说明内联函数在底层还是需要开辟空间,而在语法上是不开辟空间,直接在当前函数展开的。

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性

image-20240914104605777

可以看见内联函数对编译器来说,只是一个申请,而且行数也不能超过太多,一般10行以内就好。


http://www.ppmy.cn/news/1525989.html

相关文章

【AI大模型】Kimi API大模型接口实现

一、Kimi大模型概述 Kimi&#xff0c;月之暗面旗下国产大模型。是北京月之暗面科技有限公司&#xff08;Moonshot AI&#xff09;于2023年10月9日推出的一款智能助手&#xff0c;主要应用场景为专业学术论文的翻译和理解、辅助分析法律问题、快速理解API开发文档等&#xff0c…

软件测试工程师面试整理-数据库与SQL

在软件测试过程中,数据库和SQL的知识是非常重要的,尤其是在涉及数据密集型应用或需要验证数据准确性的场景中。测试人员需要掌握SQL语句,以便查询、插入、更新和删除数据,并验证数据库操作的正确性。 1. 数据库基础知识 ● 关系型数据库:大多数应用使用关系型数据库(如My…

基于zabbix实现监控Jenkins过程---超详细

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

uniapp+uview-plus实现微信小程序自定义tabbar

参考文档 微信小程序相关开发文档链接&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 虽然是uniapp框架但是实现方式和原生小程序相似 实现思路 1、app.json里面tabBar添加配置 custom:true,其他和非自定义设置一样 2、在…

在Flask中实现跨域请求(CORS)

在Flask中实现跨域请求&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;主要涉及到对Flask应用的配置&#xff0c;以允许来自不同源的请求访问服务器上的资源。以下是在Flask中实现CORS的详细步骤和方法&#xff1a; 一、理解CORS CORS是一种机制&…

C++笔记20•数据结构:哈希(Hash)•

哈希 1.无序的关联式容器&#xff08;unordered_map&unordered_set&#xff09; unordered_map与unordered_set几乎与map与set是一样的&#xff0c;只是性能unordered_map与unordered_set比map与set更优一些。还有就是unordered_map与unordered_set是无序的&#xff0c;…

前端深拷贝

什么是 structuredClone()&#xff1f; structuredClone() 是 2022 年引入的全局函数&#xff0c;支持深度克隆 JavaScript 对象。与 JSON.stringify() 和 JSON.parse() 等传统方法不同&#xff0c;它们难以处理复杂的结构和循环引用&#xff0c;而 structuredClone() 可以毫不…

C到C++入门基础知识

一&#xff1a;命名空间&#xff1a;namespace &#xff08;一&#xff09;&#xff1a;命名空间的定义 注&#xff1a;命名空间只能定义在全局&#xff0c;不能定义在函数内部。 &#xff08;1&#xff09;类似于C语言的结构体&#xff0c;C语言的命名空间定义为&#xff1…

【React】React18.2.0核心源码解读

前言 本文使用 React18.2.0 的源码&#xff0c;如果想回退到某一版本执行git checkout tags/v18.2.0即可。如果打开源码发现js文件报ts类型错误请看本人另一篇文章&#xff1a;VsCode查看React源码全是类型报错如何解决。 阅读源码的过程&#xff1a; 下载源码 观察 package…

Docker 数据目录迁移:一篇详细的技术指南

在使用Docker进行容器化部署时,有时我们需要将Docker的数据目录(默认位于/var/lib/docker)迁移到新的位置。这可能是由于磁盘空间不足、存储优化或系统迁移等原因。本文将详细介绍如何将Docker数据目录迁移到新的目录下,包括所有必要的步骤和代码实现。 一、背景知识 Doc…

数据结构————二叉树基础知识(零基础包会的!)

今天带来数据结构二叉树的知识&#xff0c;保证大家不会离散数学或者没有数据结构基础&#xff0c;也能明明白白的。 一&#xff0c;树 1&#xff0c;树的结构 我们在了解什么是二叉树之前我们先了解下什么是树&#xff0c;树是一种非线性的数据结构&#xff0c;它是由n个节点…

Kafka 命令详解及使用示例

文章目录 Kafka 命令详解及使用示例Kafka 命令详解kafka-topics.sh&#xff1a;主题管理创建主题创建带副本的主题修改主题分区数了解分区分布列出主题查看主题详情删除主题 kafka-console-producer.sh&#xff1a;消息生产者发送消息到主题带键值对的消息消息生产性能优化带分…

node前端开发基本设置

加快下载源速度 要将 npm 切换到淘宝的源镜像&#xff0c;你可以按照以下步骤操作&#xff1a; 查看当前 npm 源&#xff1a; npm config get registry这个命令会显示当前使用的 npm 源地址&#xff0c;默认情况下它会是 https://registry.npmjs.org/。 切换到淘宝镜像&#…

基于SpringBoot的校园新闻网站设计与实现

需要项目源码请联系我&#xff0c;目前有各类成品 毕设 javaweb ssh ssm springboot等等项目框架&#xff0c;源码丰富。 专业团队&#xff0c;咨询就送开题报告&#xff0c;活动限时免费&#xff0c;有需要的朋友可以来留言咨询。 一、摘要 本论文主要论述了如何使用JAVA语言…

CISC 和 RISC 架构的对比

研究 RISC 架构优缺点的最简单方法是将其与其前身进行对比&#xff1a; CISC&#xff08;复杂指令集计算机&#xff09;架构。 内存中的两个数字相乘 右图表示一台普通计算机的存储方案。 主存储器被划分为编号从&#xff08;行&#xff09;1&#xff1a;&#xff08;列&…

计算机组成原理(第二次笔记)

各种码 真值 (书写用)&#xff1a; 将用“”、“-” 表示正负的二进制数称为真值 机器不能识别书写格式&#xff0c;故用“0/1”表示“/-”符号。 机器码 (机器内部使用)&#xff1a; 将符号和数值一起编码表示的二进制数称为机器码。 常用机器码&#xff1a;原码、 反码、 补…

Centos 执行yum安装 出现Failed connect to mirrors.163.com:80; 拒绝连接

错误如下: http://mirrors.163.com/centos/7/os/x86_64/repodata/repomd.xml: [Errno 14] curl#7 - "Failed connect to mirrors.163.com:80; 拒绝连接 解决办法&#xff1a; 换镜像源地址 添加阿里的源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.al…

OCR 通用端到端模型GOT

摘要 在人工智能领域&#xff0c;光学字符识别&#xff08;OCR&#xff09;技术已经取得了显著的进展。随着技术的不断进步&#xff0c;我们正迈向OCR 2.0时代。本文将介绍由Vary团队开发的通用端到端模型GOT&#xff0c;这一模型在OCR领域具有革命性的潜力。 论文概览 论文…

一. rpc基本学习

1. 什么是rpc&#xff0c;为什么有了http还要rpc 我们常说的http&#xff0c;应该是说的http1&#xff0c;http只是应用层的一个协议 Rpc是一种调用方式&#xff0c;全称叫远程过程调用&#xff0c;对应本地调用&#xff0c;rpc是一种调用方式&#xff0c;不是一种协议 更具体…

Qt与MQTT交互通信

MQTT全称是&#xff08;Message Queuing Telemetry Transport&#xff09;&#xff0c;即消息队列遥测传输协议 是一种基于发布/订阅&#xff08;Publish/Subscribe&#xff09;模式的轻量级通讯协议&#xff0c;并且该协议构建于TCP/IP协议之上&#xff0c;常用于互联网中&am…