C++语言学习(二)——⭐缺省参数、函数重载、引用

news/2024/7/26 10:29:29/文章来源:https://blog.csdn.net/m0_63596031/article/details/137284068

1.⭐缺省参数

(1)缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

void Func(int a = 0)
{cout<<a<<endl;
}
int main()
{Func();     // 没有传参时,使用参数的默认值Func(10);   // 传参时,使用指定的实参return 0;
}

(2)缺省参数分类

①全缺省参数

void Func(int a = 10, int b = 20, int c = 30)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

②半缺省参数

void Func(int a, int b = 10, int c = 20)
{cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl;
}

1. 半缺省参数必须从右往左依次来给出,不能间隔着给

2. 缺省参数不能在函数声明和定义中同时出现如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该 用那个缺省值。

3. 缺省值必须是常量或者全局变量

4. C语言不支持(编译器不支持)

2. ⭐函数重载

(1)函数重载概念

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

三种形式:

  • 参数类型不同
  • 参数个数不同
  • 参数类型顺序不同
#include<iostream>
using namespace std;
// 1、参数类型不同
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;
}int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

(2)为什么C++支持函数重载,而C语言不支持呢?

在C/C++中,一个程序要运行起来,要经历以下几个阶段:预处理、编译、汇编、链接

  1. 项目通常是由多个头文件和多个源文件构成,【当前a.cpp中调用了b.cpp中定义的Add函数时】,编译后链接前,a.o的目标 文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。
  2. 所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就 会到b.o的符号表中找Add的地址,然后链接到一起。
  3. 那么链接时,面对Add函数,链接接器会使用哪个名字去找呢?这里每个编译器都有自己的函数名修饰规则。
  4. 在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。
  5. 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
  6. 如果两个函数函数名和参数是一样的,返回值不同是不构成重载的,因为调用时编译器没办法区分。

3. ⭐引用

(1)引用概念

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

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

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

void TestRef()
{int a = 10;int& ra = a;//<====定义引用类型printf("%p\n", &a);printf("%p\n", &ra);
}

(2)引用特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
void TestRef()
{int a = 10;// int& ra;   // 该条语句编译时会出错int& ra = a;int& rra = a;printf("%p %p %p\n", &a, &ra, &rra);  
}

(3)常引用

常引用是指使用 const 关键字修饰的引用。常引用用于指示在函数中不会修改引用所绑定的对象。这样做的好处是可以确保在函数内部不会意外地修改传递给函数的参数,同时还能够允许函数接受常量作为参数。

void TestConstRef()
{const int a = 10;//int& ra = a;   // 该语句编译时会出错,a为常量const int& ra = a;// int& b = 10; // 该语句编译时会出错,b为常量const int& b = 10;double d = 12.34;//int& rd = d; // 该语句编译时会出错,类型不同const int& rd = d;
}

(4)使用场景

①做参数

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

②做返回值

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

下面代码输出什么结果?

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

int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);cout << "ret is :" << ret << endl;Add(3, 4);cout << "ret is :" << ret << endl;return 0;
}

(5)传值、传引用效率比较

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

#include <time.h>
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void main()
{A a; // 创建一个结构体A的实例a// 1.以值作为函数参数的情况size_t begin1 = clock(); // 获取执行函数调用前的时间for (size_t i = 0; i < 10000; ++i) // 传值调用10000次,这种情况每调用一次就会产生一次拷贝TestFunc1(a);size_t end1 = clock();// 获取执行函数调用结束的时间// 2.以引用作为函数参数size_t begin2 = clock();// 获取执行函数调用前的时间for (size_t i = 0; i < 10000; ++i) // 传引用调用10000次,这种情况每次调用都直接用的引用TestFunc2(a);size_t end2 = clock();// 获取执行函数调用结束的时间// 分别计算两个函数运行结束后的时间cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;// 结果// TestFuncl(A) - time:9// TestFunc2(A&) - time : 0
}

(6)引用和指针的区别

语法:

  1. 引用是别名,语法上不开空间,指针是地址,需要开空间存地址
  2. 引用必须初始化,指针可以初始化也可以不初始化
  3. 引用不能改变指向,指针可以
  4. 引用相对更安全,没有空引用,但有空指针,容易出现野指针,但是不容易出现野引用
  5. sizeof、++、解引用访问等方面的区别

底层:

  • 汇编层面上,没有引用,都是指针,引用在编译后也转换成指针了

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

keepalived+LVS高可用部署

目录 一.两台设备&#xff08;2.130和2.133&#xff09;作为调度器&#xff0c;前主后备 1.部署keepalived 2.修改配置文件准备启动 3.配置keepalived的系统日志并启动 二.模拟调度器掉点和web服务进程丢失 1.调度器掉点 2.当类似于httpd这种网站服务掉点 三.以三种健康…

简单了解观察者模式(发布 - 订阅模式)

什么是观察者模式&#xff1f; 观察者根据主题类的内部状态变化来改变自身状态&#xff0c;简单来说就是观察者订阅了主题类&#xff0c;当主题类发布一些消息&#xff0c;观察者就会收到消息&#xff0c;然后做出反应。 Spring的观察者模式 Spring用了监听器&#xff08;观察…

时序数据库IoTDB:功能详解与行业应用

一文读懂时序数据库 IoTDB。 01 为什么需要时序数据库 解释时序数据库前&#xff0c;先了解一下何谓时序数据。 时序数据&#xff0c;也称为时间序列数据&#xff0c;是指按时间顺序记录的同一统计指标的数据集合。这类数据的来源主要是能源、工程、交通等工业物联网强关联行业…

数据可视化高级技术(Echarts)

目录 &#xff08;一&#xff09;数据可视化概念及Echarts基础知识 数据可视化的好处&#xff1a; 数据可视化的目标 数据可视化的基本流程 &#xff08;二&#xff09;数据图表 类别比较图表&#xff1a; 数据关系图表&#xff1a; 数据分布图表&#xff1a; 时间序列…

ETL中如何自定义规则

一、ETL中的规则 在使用规则之前我们先来了解一下什么是规则&#xff0c;ETL中规则在很多组件中都能看见&#xff0c;可以理解为按照事前约定好的逻辑去执行&#xff0c;规则可以使得数据更加的规范统一&#xff0c;同时也不需要去纵向的修改底层代码&#xff0c;只需要动态编…

机器学习模型及其使用方法——《机器学习图解》

本书教你两件事——机器学习模型及其使用方法 机器学习模型有不同的类型&#xff0c;有些返回确定性的答案&#xff0c;例如是或否&#xff0c;而另一些返回概率性的答案。有些以问题的形式呈现&#xff1b;其他则使用假设性表达。这些类型的一个共同点是它们都返回一个答案或…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

docker 共享网络的方式实现容器互联

docker 共享网络的方式实现容器互联 本文以nacos连接mysql为例 前提已经在mysql容器中初始化好nacos数据库&#xff0c;库名nacos 创建一个共享网络 docker network create --driver bridge \ --subnt 192.168.0.0/24 \ --gateway 192.168.0.1 mynet此处可以不指定网络模式、…

软件接口安全设计规范及审计要点

1.token授权安全设计 2.https传输加密 3.接口调用安全设计 4.日志审计里监控 5.开发测试环境隔离&#xff0c;脱敏处理 6.数据库运维监控审计 项目管理全套资料获取&#xff1a;软件开发全套资料_数字中台建设指南-CSDN博客

未来购物新篇章:臻奶惠无人新零售

未来购物新篇章&#xff1a;臻奶惠无人新零售 随着科技的不断进步和消费者购物习惯的变化&#xff0c;无人新零售已经成为零售行业的一大趋势&#xff0c;它不仅重新定义了购物体验&#xff0c;也为零售行业带来了前所未有的变革。无人新零售&#xff0c;一种融合了AI技术、物…

民航电子数据库:在有分组统计的语句中,输出表达式含有非分组统计项

目录 一、场景二、报错信息三、排查四、原因五、解决 一、场景 1、对接民航电子数据库 2、执行SQL语句报错 二、报错信息 三、排查 查看数据库def_group_by_mode配置 show def_group_by_mode四、原因 def_group_by_mode设置为0导致&#xff0c;相当于mysql的sql_modeonly_…

SAP Fiori开发中的JavaScript基础知识9 - 代码注释,严格模式,JSON

1 背景 本文将介绍JavaScript编程中的三个小知识点&#xff1a;也即代码注释&#xff0c;严格模式&#xff0c;JSON文件。 2 代码注释 JavaScript的代码注释方式如下&#xff1a; // Single line comment/* Multi line comment */3 严格模式 JavaScript的"strict mod…

Go语言爬虫实战(线程池)

Go语言爬虫实战 目标 利用go语言爬取指定网站的图片。实现爬取网站任意页面所有所需的图片。实现使用go语言线程池开启多个线程爬取图片内容。最后实现创建多个文件夹存储图片。 爬取网站图片 步骤 对指定URL发去GET请求&#xff0c;获取对应的响应。 resp, err : http.Get(…

记一道文件上传

林深时遇见鹿&#xff0c;海蓝时遇见鲸。 首先先随便上传一个文件&#xff0c; 经测试php相关后缀都不能上传&#xff0c;且<?被过滤。 而且.user.ini里的file也被过滤了 所以只能使用.htaccess了 但是<?被过滤了&#xff0c;所以我们可以使用php伪协议来用base64加…

多维数组和交错数组笔记

1.) 关于数据的几个概念&#xff1a; Rank&#xff0c;即数组的维数&#xff0c;其值是数组类型的方括号之间逗号个数加上1。 Demo&#xff1a;利用一维数组显示斐波那契数列F(n) F(n-1) F(n-2) (n >2 ),每行显示5项,20项. static void Main(string[] args){int[] F n…

FANUC机器人故障诊断—报警代码更新(三)

FANUC机器人故障诊断中&#xff0c;有些报警代码&#xff0c;继续更新如下。 一、报警代码&#xff08;SRVO-348&#xff09; SRVO-348DCS MCC关闭报警a&#xff0c;b [原因]向电磁接触器发出了关闭指令&#xff0c;而电磁接触器尚未关闭。 [对策] 1.当急停单元上连接了CRMA…

openldap(一):简介和安装

目录 1 OpenLDAP简介1.1 LDAP介绍1、什么LDAP2、为什么要使用LDAP3、LDAP 的特点4、LDAP常用关键字5、LDAP的objectClass6、LADP使用场景 1.2 OpenLDAP介绍1、什么OpenLDAP2、OpenLDAP特点3、OpenLDAP的组件 2 OpenLDAP安装3 简单使用3.1 创建用户1、创建ou2、创建Group 3、创建…

CrossOver软件2024免费 最新版本详细介绍 CrossOver软件好用吗 Mac电脑玩Windows游戏

CrossOver是一款由CodeWeavers公司开发的软件&#xff0c;它可以在Mac和Linux等操作系统上运行Windows软件&#xff0c;而无需在计算机上安装Windows操作系统。这款软件的核心技术是Wine&#xff0c;它是一种在Linux和macOS等操作系统上运行Windows应用程序的开源软件。 Cross…

SpringBoot整合腾讯云邮件发送服务非STMP

SpringBoot整合腾讯云邮箱服务 1、pom配置 <!-- 腾讯云邮箱服务--><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java</artifactId><!-- go to https://search.maven.org/search?qtencen…

Gmail多账号防封攻略,看这一篇就够了

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…