【C++专栏】C++入门 | 函数重载、引用、内联函数


  • 博客主页:Duck Bro 博客主页
  • 系列专栏:C++专栏
  • 关注博主,后期持续更新系列文章
  • 如果有错误感谢请大家批评指出,及时修改
  • 感谢大家点赞👍收藏⭐评论✍

C++入门 | 函数重载、引用、内联函数

文章编号:C++入门 / 02

文章目录

  • C++入门 | 函数重载、引用、内联函数
    • 一、函数重载
      • 1. 函数重载概念
      • 2. 函数重载的使用
    • 二、引用
      • 1. 引用概念
      • 2. 引用特性
      • 3. 常引用
      • 4. 引用的使用场景
        • 4.1 参数
        • 4.2 返回值
      • 5. 传值&传引用效率对比
      • 6. 引用&指针区别
    • 三、内联函数
      • 1. 内联函数概念
      • 2. 内联函数特性
      • 3. 内联函数的使用


一、函数重载

结论:函数名相同 参数不同(类型相同、个数相同、顺序不同)返回值可同可不同。

1. 函数重载概念

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

2. 函数重载的使用

#include<iostream>
using namespace std;
//1.参数类型不同
int Add(int a, int b)
{
	cout << "int Add(int a, int b)" << endl;
	return a + b;
}
double Add(double a, double b)
{
	cout << "double Add(int a, int b)" << endl;
	return a + b;
}
//2.参数个数不同
void func()
{
	cout << "func()" << endl;

}
void func(int a)
{
	cout << "func(int a)" << endl;
}
//3.参数类型顺序不同
void func(int a, char b)
{
	cout << "f(int a, char b)" << endl;
}
void func(char a, int b)
{
	cout << "f(char a, int b)" << endl;
}
int main()
{
	Add(3,4);
	Add(3.5, 3.7);

	func();
	func(10);

	func(20, 'a');
	func('a', 20);

	return 0;
}

二、引用

结论:引用就是给已经存在的变量取别名,不是重新定义一个变量。

1. 引用概念

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

void Test1()
{
	int a = 10;
	int& b = a;// 定义引用类型
	printf("a的地址:%p\n", &a);
	printf("b的地址:%p\n", &b);

}

int main()
{

	Test1();
	return 0;
}

输出结果:
在这里插入图片描述

2. 引用特性

结论:引用必须初始化。不可以直接定义int& s;

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体,再不能引用其他实体
void Test2()
{
	int s = 10;
	//int& s;  编译出错
	int& rs = s;
	int& rrs = s;
	printf("s的地址:%p\nrs的地址:%p\nrrs的地址:%p\n", &s, &rs, &rrs);
}

3. 常引用

结论:const可以使变量变为常量

在C++中,const是用于指定一个变量为常量(constant)的关键字。使用const关键字声明的变量不能被修改。它可以用于声明常量值、函数参数、函数返回值和成员函数。

void Test3()
{
	const int a = 10;
	//int& ra = a; //编译时出错,a是常量
	const int& ra = a;
	
	
	//int& b = 10; //编译时出错,b是常量
	const int& rb = 10;
	
	
	double d = 10.15;
	//int& rd = d;//编译时出错,类型(double)不同
	const double& rd = d;
	
}

4. 引用的使用场景

4.1 参数

引用做参数传值

void Swap(int& left, int& right)
{
	int temp = left;
	left = right;
	right = temp;
}
void Swap(int*left, int* right)
{
	int temp = *left;
	*left = *right;
	*right = temp;
}
int main()
{
	int a = 2;
	int b = 3;
	//引用传值交换
	Swap(a, b);
	cout << a << " " << b << endl;
	//指针传值交换
	Swap(&a, &b);
	cout << a << " " << b << endl;
	return 0;
}
4.2 返回值

使用引用做返回值

int& Count()
{
   static int n = 0;
   n++;
   // ...
   return n;
}
int main()
{
	int ret=Count();
	cout << ret << endl;
	return 0;
}

5. 传值&传引用效率对比

结论:传引用比传值效率高

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

测验代码:

#include<iostream>
#include <time.h>
using namespace std;
struct A { int a[10000]; };
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{
	A a;
	// 以值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分别计算两个函数运行结束后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
	TestRefAndValue();
	return 0;
}

输出结果:
在这里插入图片描述

6. 引用&指针区别

结论:从语法概念上引用只是取别名,没有独立的空间,但从底层实现上是有空间产生的,因为引用是按照指针方式来实现的。

#include<iostream>
using namespace std;
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. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

三、内联函数

结论:内联函数是一种用于提高函数调用效率的优化手段,适用于函数体简单且执行时间短的函数。但是在使用时需要根据具体情况进行权衡和选择。

1. 内联函数概念

C++内联函数是一种特殊的函数,它在编译时会被直接插入到调用它的地方,而不是通过跳转到函数的地址来进行调用。内联函数的主要目的是提高函数调用的效率,避免因函数调用带来的额外开销,例如压栈、跳转等操作。

使用内联函数可以有效地减少函数调用的开销,因为内联函数的代码会直接插入到调用它的地方,而不需要通过函数调用来执行。这就意味着在执行过程中不需要额外地保存和恢复函数的上下文信息,也不需要进行函数调用和返回的跳转。

要定义一个内联函数,需要在函数定义前加上关键字inline。内联函数的定义通常写在头文件中,以便在多个cpp文件中进行共享。

2. 内联函数特性

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
    用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
    行效率。
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
    议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
    是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
    了,链接就会找不到。

3. 内联函数的使用

#include<iostream>
using namespace std;
//内联函数
inline int Add1(int a,int b)
{
	return a + b;
}

int main()
{
	int ret = Add1(3, 5);
	cout << ret << endl;
	return 0;
}


在这里插入图片描述

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

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

相关文章

【机器学习】在Python中进行K-Means聚类和层次聚类

Python中聚类算法API的使用指南 聚类分析是数据分析中一种常见的无监督学习方法&#xff0c;通过将相似的对象分组在一起&#xff0c;我们能够识别出数据集中的自然分群。本文将介绍如何使用Python中的聚类算法接口&#xff0c;KMeans和层次聚类方法。 K-Means 聚类 K-Means…

利用 Redis 和 Lua 实现高效的限流功能

简介 在现代系统中&#xff0c;限流是一种重要的机制&#xff0c;用于控制服务端的流量并保护系统免受恶意攻击或请求泛滥的影响。本文将介绍如何利用 Redis 和 Lua 结合实现高效的限流功能。 一、什么是限流 限流指的是对系统中的请求进行控制和调节&#xff0c;确保系统在…

动手学深度学习PyTorch版

基本的数据操作 import torch # 创建一个行向量&#xff0c;默认为从0开始的12个整数 # n维数组也称为张量 x torch.arange(12) x # 张量的形状 x.shape# 张量的大小,张量所有元素的个数 x.numel()#修改张量的形状 x x.reshape(3,4)#生成形状为3*4的两个向量&#xff0c;向…

离散数学——(4)

目录 1.主析取范式 2.大项 3.主合区范式 4.范式的求法 真值表法 5.推理理论 直接证法 1.主析取范式 2.大项 3.主合区范式 4.范式的求法 真值表法 5.推理理论 直接证法

验证码安全

目录 验证码识别&复用&调用&找回密码重定向&状态值 res 修改-找回密码修改返回状态值判定验证通过 验证码爆破-知道验证码规矩进行无次数限制爆破 短信轰炸原理 验证码识别&复用&调用&找回密码重定向&状态值 res 修改-找回密码修改返回状态…

GraalVM 虚拟机-概述

GraalVM 虚拟机 Graal 编译器以及由此诞生的GraalVM&#xff0c;虽然目前还处在实验阶段&#xff0c;但是也是 Java 程序员们必须要了解的&#xff0c;因为他未来极有可能替代 HotSpot&#xff0c;成为 Java生态的下一代技术基础。 1 、关于 Graal Graal编译器最早是作为 Ho…

kamailio转发电话到目的地,目的返回失败时再转给其他IP

按图中这样测试&#xff1a; A---->kamailio------->B B返回480等失败错误码&#xff08;非200 OK&#xff09;&#xff0c;能进入failure_route[TOVOICEMAIL]&#xff0c;但是t_relay_to_udp执行失败。 好吧&#xff0c;说是&#xff1a;在 failure_route 中处理的是…

【嵌入式高级C语言】11:C语言Makefile

文章目录 1 makefile的概述【只针对Linux有效】1.1 make1.2 makefile1.3 采用makefile的好处 2 Makefile的语法规则3 makefile变量3.1 自定义变量3.2 系统环境变量3.3 预定义变量 4 伪目标5 最终版本Makefile 1 makefile的概述【只针对Linux有效】 1.1 make make是个命令&…

这是谁的女儿?其母亲早已红过头了,现在小小年纪的她也爆红网络,没想到吧?

这是谁的女儿&#xff1f;其母亲早已红过头了&#xff0c;现在小小年纪的她也爆红网络&#xff0c;没想到吧&#xff1f; 原来&#xff0c;作母亲的她在红极一时后似乎沉寂了下来&#xff0c;没想到她11岁的女儿近年来也在社交媒体上走红&#xff0c;她为何也成了小网红呢&…

【蓝牙协议栈】【经典蓝牙】【BLE蓝牙】蓝牙协议规范(HCI、L2CAP、SDP、RFOCMM)

目录 1. 蓝牙协议规范&#xff08;HCI、L2CAP、SDP、RFOCMM&#xff09; 1.1 主机控制接口协议 HCI 1.2 逻辑链路控制与适配协议 L2CAP 1.3 服务发现协议SDP 1.4 串口仿真协议 RFCOMM 1. 蓝牙协议规范&#xff08;HCI、L2CAP、SDP、RFOCMM&#xff09; 1.1 主机控制接口协…

寒假作业Day 08

寒假作业Day 08 一、选择题 1、下列关于 const 和 #define 定义常量的区别&#xff0c;说法不正确的有&#xff08; &#xff09; A: define宏是在预处理阶段展开。const常量是编译运行阶段使用 B: 宏没有类型&#xff0c;不做任何类型检查&#xff0c;仅仅是展开。const常量…

计算机找不到api-ms-win-core-path-l1-1-0的5种解决方法

在计算机使用过程中&#xff0c;我们可能会遇到各种问题&#xff0c;其中之一就是找不到某些系统文件。最近&#xff0c;许多用户反映他们在使用电脑时遇到了“找不到api-ms-win-core-path-l1-1-0文件”的问题。这个问题通常出现在Windows操作系统中&#xff0c;可能会影响到一…

【Linux】编译器-gcc/g++使用

个人主页 &#xff1a; zxctscl 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 文章目录 1. 前言2. 初见gcc和g3. 程序的翻译过程3.1 预处理3.1.1 宏替换 去注释 头文件展开3.1.2 条件编译 3.2 编译3.3 汇编3.4 链接 4. 链接4.1 动态链接4.2 静态链接 1. 前言 在之…

DRC:扩散模型的推荐系统应用

1 Title Diffusion Recommender Model&#xff08;Wenjie Wang、Yiyan Xu、Fuli Feng、Xinyu Lin、Xiangnan He、Tat-Seng Chua&#xff09;【SIGIR 23】 2 Conclusion . In light of the impressive advantages of Diffusion Models (DMs) over traditional generative model…

万字完整版【C语言】指针详解~

一、前言 初始指针&#xff08;0&#xff09;&#xff1a;着重于讲解指针的概念、基本用法、注意事项、以及最后如何规范使用指针深入指针&#xff08;1&#xff09;&#xff1a;讲解指针变量常见的类型&#xff0c;如何去理解这些类型、最后就是如何正确的使用深入指针&#…

【语法基础练习】1.变量、输入输出、表达式与顺序语句

&#x1f338;博主主页&#xff1a;釉色清风&#x1f338;文章专栏&#xff1a;算法练习&#x1f338;今日语录&#xff1a;You don’t know until you try. 文章简介&#xff1a;下面的题目是AcWing网站语法基础练习篇的第一小节&#xff0c;内容基础&#xff0c;难度&#xf…

如何进入Windows 11的安全模式?这里提供详细步骤

序言 如果你在启动Windows 11 PC时遇到问题,则重新启动到安全模式可能会有所帮助,该模式会暂时禁用驱动程序和功能,以使你的PC更稳定。下面是如何做到这一点。 在Windows 7和更早版本中,通常可以在打开电脑后按功能键(如F8)启动安全模式。Microsoft从Windows 8中删除了…

MybatisPlus知识点总结(基于黑马2023MybatisPlus课程)

MybatisPlus知识点总结 配套资料 黑马微服务框架笔记&#xff0c;内含mpMybatisPlus.pptxMyBatis-Plus &#xff08;mp中文官网&#xff09; 快速入门 入门案例 使用MybatisPlus的基本步骤&#xff1a;1.引入MybatisPlus依赖&#xff0c;代替Mybatis依赖2.定义Mapper接口并继…

C++_可变参数模板

目录 1、可变参数模板的用法 2、参数包展开 2.1 递归方式展开 2.2 逗号表达式形式展开 3、参数包的大小 结语 前言&#xff1a; C11引入了可变参数模板&#xff0c;他的作用是可以让创建的函数模板或者类模板的模板参数可以接收任意数量参数&#xff0c;在C11前&#x…

16. C++标准库

C标准库兼容C语言标准函数库&#xff0c;可以在C标准库中直接使用C语言标准函数库文件&#xff0c;同时C标准库增加了自己的源代码文件&#xff0c;新增文件使用C编写&#xff0c;多数代码放在std命名空间中&#xff0c;所以连接C标准库文件后还需要 using namespace std;。 【…