【c++学习】入门c++(中)

news2024/9/23 3:21:07

目录

  • 一. 前言
  • 二. 函数重载
    • 1. 概念
    • 2.函数名修饰规则
    • 三 .引用(&)
      • 1. 概念
      • 2. 引用特性
      • 3.应用
        • 1.做参数
        • 2. 做返回值
        • 3. 传值、传引用效率比较
        • 4.引用和指针的区别
    • 四 . 结语

一. 前言

小伙伴们大家好,今天我们继续学习c++入门知识,今天的内容主要是

二. 函数重载

1. 概念

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

可以理解为一词多义,比如一句话**“谁也赢不了”**,分别用在国乒乓队和国足的身上,就是两种截然不同的意思,大家细品。

int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}

double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}

然而c语言不支持函数重载,上述代码运行会直接报错。
三种重载方式:

1· 参数类型不同
2、参数个数不同
3、参数类型顺序不同

//参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}


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

// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}

2.函数名修饰规则

由之前的知识我们知道,函数调用需要建立栈帧,那么编译器是如何精确找到这些同名函数的地址呢?

c语言是根据函数名寻找函数,如果函数名相同,就会起冲突。
而c++通过函数名重载对函数的地址进行修饰

在这里插入图片描述
windows下的函数修饰名规则太复杂,所以我们转到Linux上对其讲解

Linux下修饰规则:格式:_ Z + 函数名称长度 + 函数名 + 类型首字母

代码段:

    1 #include<stdio.h>
    2                                                                                                                                                                                      
    3 void  add(int a,int b)
    4 {                        
    5 } 
    6  
    7 int main(){
    8            
    9   return 0;
   10 }          
  

进行编译形成可执行文件后,还需借助objdump -S exeName 查看修饰规则

在这里插入图片描述
结果为
在这里插入图片描述
我们发现c语言是直接根据函数名查找对应函数

改图为c++编译后的代码段
在这里插入图片描述

所以说:

对于相同名字的函数,函数重载就根据参数的类型,顺序,个数,以这些为基准,来区别不同的函数

但是不同返回值的函数不能构造函数重载

对于返回值不同的其他都相同的函数来说,在函数调用时,无法进行区分返回值,分不清调用哪个函数,不仅仅是因为函数返回值不在修饰规则内。

三 .引用(&)

1. 概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间

通俗来说就是取外号:
你很瘦,他人给你取了个外号叫“竹竿”,他的意思就是”竹竿“也代表了你

定义:

类型& 引用变量名(对象名) = 引用实体

实现如下:

int a = 10;
int& b = a;

b = 20;
cout << a << endl;

在这里插入图片描述
可以看出,a和b共用一个地址,且b为(int &)类。

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

2. 引用特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体

前俩条很好理解,最后一个是指当引用初始化之后,就不能改变引用的指向了

在这里插入图片描述

可以看出,b的值变成了20,a的值也改变成为了20,但b的地址没有改变,说明了
引用一旦引用一个实体,再不能引用其他实体

3.应用

1.做参数

还记得c语言中的交换函数怎么实现的吗

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

是不是感觉十分别扭,既要传指针,又要进行解引用,
现在我们可以用引用来进行简化

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

传递过来的都是实参的别名,可以直接修改,无需解引用

2. 做返回值

看如下代码:

int add(int a, int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int ret = add(1, 2);
	cout << ret << endl;

	return 0;
}

我们在调用函数时,会建立函数栈帧,对于传值返回,如上述代码的add()函数,在函数调用完成后,函数栈帧销毁,c变量也会销毁,所以传会的并不是变量c,而是c的一份拷贝,是一个临时变量。
但是临时变量在哪?

如果 c 比较小(4/8 byte),一般是寄存器充当临时变量。
如果 c 比较大,临时变量放在调用 add 函数的栈帧中。

如果定义一个静态的变量呢,static修饰的变量储存于静态区,不受函数栈帧的影响,那么返回他会不会进行拷贝呢,答案是会的。
那么就会产生浪费,如何进行规s避呢

我们试一试传引用返回

int& add(int a, int b)
{
	int c = a + b;
	return c;
}

int main() {
	int& ret = add(1, 2);
	cout << ret << endl;

	add(10, 20);
	cout << ret << endl;
	return 0;
}

运行结果:
在这里插入图片描述
可知,ret为int&类,在第一次调用add()函数栈帧销毁后,ret任可以访问当初函数c的地址,所以在第二此调用add()后,ret的值被改为30;
也就是非法访问

引用返回有一个原则:

如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

3. 传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低

在这里插入图片描述
通过上述代码的比较,发现传值和指针在作为传参以及返回值类型上效率相差很大。

4.引用和指针的区别

int main()
{
//引用
int a = 10;
int& ra = a;
ra = 20;
//指针
int* pa = &a;
*pa = 20;
return 0;
}

我们看看反汇编码
在这里插入图片描述
发现,指针和引用的底层逻辑是一样的。
所以:
从语法概念上来说,引用是没有开辟空间的,而指针是开辟了空间的
但是:
从反汇编代码上来看,引用其实是开空间的,并且实现方式和指针一样,引用其实也是用指针实现的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  8. 引用比指针使用起来相对更安全

四 . 结语

大家好,我是展轩,
本次博客学习就到这里,如果觉得有帮助的话,记得
一键三连哦ヾ(≧▽≦*)o。
在这里插入图片描述

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

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

相关文章

SQL性能优化的47个小技巧,你了解多少?

收录于热门专栏Java基础教程系列&#xff08;进阶篇&#xff09; 1、先了解MySQL的执行过程 了解了MySQL的执行过程&#xff0c;我们才知道如何进行sql优化。 客户端发送一条查询语句到服务器&#xff1b;服务器先查询缓存&#xff0c;如果命中缓存&#xff0c;则立即返回存…

platform 总线

驱动的分离与分层思想 分离&#xff1a;硬件信息分离&#xff1b; 在编写硬件驱动的时候&#xff0c;需要操作许多硬件寄存器。比如gpio 驱动&#xff0c;你需要知道gpio控制器 寄存器的地址&#xff0c;你想要哪个gpio输出&#xff1f;或是输入? 这些操作最终都是靠设置寄存…

19 pandas 分层索引与计算

文章目录分层设置与查询数据index 为有序index 为无序(中文&#xff09;查看数据示例多层索引的创建方式&#xff08;行&#xff09;1、from_arrays 方法2、from_tuples 方法3、from_product 方法多层索引的创建方式&#xff08;列&#xff09;分层索引计算MultiIndex 参数表分…

Mybatis笔记整理

1. 相关文档地址 中文文档 https://mybatis.org/mybatis-3/zh/index.htmlMybatis可以配置成适应多种环境&#xff0c;不过每个SqlSessionFactory实例只能选择一种环境。Mybatis默认事务管理器是JDBC&#xff0c;连接池&#xff1a;POOLEDMaven仓库:下载地址<dependency>…

KVM-1、Linux 操作系统及虚拟化

1. 前言 一台计算机是由一堆硬件设备组合而成,在硬件之上是操作系统,操作系统与计算机硬件密不可分,操作系统用来管理所有的硬件资源提供服务,各个硬件设备是通过 总线 进行连接起来的: 在操作系统之上,需要一个人机交互接口,我们才能使用计算机对其发送指令,这个人机…

C语言【动态内存管理 后篇】

动态内存管理 后篇&#x1fac5;经典例题&#x1f926;‍♂️题目1&#x1f926;‍♂️题目2&#x1f926;‍♂️题目3&#x1f926;‍♂️题目4&#x1fac5;C/C程序的内存开辟前面的一篇文章动态内存管理 前篇&#xff0c;我们已经了解过了动态内存管理的相关信息&#xff0c…

数据库管理-第五十七期 多灾多难(20230218)

数据库管理 2023-02-18第五十七期 多灾多难1 网络震荡2 挂一大片3 恢复虚拟机总结第五十七期 多灾多难 2月第三周&#xff0c;怎么说呢&#xff0c;多灾多难的一周&#xff0c;一周两次严重故障&#xff0c;而且事情还都发生在24小时之内&#xff0c; 1 网络震荡 本周四一大…

不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向

不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向 最近&#xff0c;多所美国高校以及香港大学等都明确禁止在校使用ChatGPT等智能文本生成工具。GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一种自然语言处理技术&#x…

04 C++提高编程

文件基本上是黑马程序员的文档&#xff0c;部分添加自己需要的内容&#xff0c;仅用于自己学习&#xff01;链接&#xff1a;黑马程序视频课程GitHub:源代码 C提高编程 本阶段主要针对C泛型编程和STL技术做详细讲解&#xff0c;探讨C更深层的使用 1 模板 1.1 模板的概念 模…

spring的注解

Spring的常用注解常用注解EnableWebMvcConfigurationBeanSpringBootApplication && MapperScanControllerResponseBodyRestControllerRequestMapping("robot")ResourceRequestMappingService常用注解 EnableWebMvc 在配置类中开启Web MVC的配置支持。 Con…

力扣62.不同路径

文章目录力扣62.不同路径题目描述方法1&#xff1a;暴力深搜(超时未通过)方法2&#xff1a;动态规划力扣62.不同路径 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器…

[安装] Dell电脑安装系统时看不到固态硬盘的解决方案

前言如图&#xff0c;配备NVME固态硬盘的机器在重新安装时候没有看到固态硬盘。这其实是由于安装镜像缺少IRST驱动导致的。1.硬盘模式设置为AHCI大多数戴尔机器出厂BIOS默认硬盘模式为Raid On而非AHCI&#xff0c;WIN10纯净版镜像中自带NVME驱动&#xff0c;可以识别AHCI模式下…

台积电后悔莫及,美国没有将它当成自己人,大陆市场重要性凸显

台积电对于赴美设厂可谓变了再变&#xff0c;日前台积电创始人张忠谋就发声指美国“美国认为他可以通钱来快速进入芯片市场&#xff0c;这太天真了”&#xff0c;这是在台积电获得美国的补贴少得可怜之后的表态&#xff0c;凸显出对美国的不满。台积电对于赴美设厂一开始出现截…

postman教程

一、前言 1、postman 是什么 postman 是一款 HTTP 客户端工具&#xff0c;它可以用来调试和测试接口。通过 HTTP 协议&#xff0c;将请求数据发送到服务端&#xff0c;并从服务端获取响应数据。 2、为什么要使用 postman 后端开发者写的代码在大多数情况下是要给到前端开发…

day46【代码随想录】动态规划之打家劫舍 III、买卖股票的最佳时机、买卖股票的最佳时机II

文章目录前言一、打家劫舍 III&#xff08;力扣337&#xff09;【较难】二、买卖股票的最佳时机&#xff08;力扣121&#xff09;三、买卖股票的最佳时机II&#xff08;力扣122&#xff09;前言 1、打家劫舍 III 2、买卖股票的最佳时机 3、买卖股票的最佳时机II 一、打家劫舍 …

C++——二叉树进阶oj题

目录二叉树创建字符串二叉树的分层遍历1二叉树的分层遍历2给定一个二叉树, 找到该树中两个指定节点的最近公共祖先二叉树搜索树转换成排序双向链表。根据一棵树的中序遍历与后序遍历构造二叉树根据一棵树的前序遍历与中序遍历构造二叉树二叉树创建字符串 题目链接 思路&#x…

Python 之 Matplotlib 散点图、箱线图和词云图

文章目录一、散点图1. scatter() 函数2. 设置图标大小3. 自定义点的颜色和透明度4. 可以选择不同的颜色条&#xff0c;配合 cmap 参数5. cmap 的分类5.1 Sequential colormaps&#xff1a;连续化色图5.2 Diverging colormaps&#xff1a;两端发散的色图 .5.3 Qualitative color…

Python获取zabbix问题触发器

背景&#xff1a;阿里云的ECS服务器因为阿里云升级插件&#xff0c;导致安全防护程序重启&#xff0c;产生不同的端口。导致低自动发现注册的端口 大量报警。 解决&#xff1a;杀掉关于因为非业务 变更的端口检测的触发器。 相关文档&#xff1a; Zabbix监控之主机端口监控自…

3. 投票 案例项目(合集)

3.投票-1创建项目和子应用 创建项目 命令$ python django-admin startproject mysite 目录结构mysite/ # 项目容器、可任意命名manage.py # 命令行工具mysite/ # 纯 Python 包 # 你引用任何东西都要用到它__init__.py # 空文件 告诉Python这…

面试官让你说说react状态管理?

hooks 为什么不能放在条件判断里 以 setState 为例&#xff0c;在 react 内部&#xff0c;每个组件(Fiber)的 hooks 都是以链表的形式存在 memoizeState 属性中 update 阶段&#xff0c;每次调用 setState&#xff0c;链表就会执行 next 向后移动一步。如果将 setState 写在条…