【C++奇遇记】函数探幽(上)

🎬 博客主页:博主链接
🎥 本文由 M malloc 原创,首发于 CSDN🙉
🎄 学习专栏推荐:LeetCode刷题集 数据库专栏 初阶数据结构
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述
在这里插入图片描述

文章目录

  • 😇内联函数的前情介绍
    • 📝任何时候我们都要用内联函数吗?
    • 😇内联与宏
  • 😇引用变量
    • 📝创建引用变量
    • ✉将引用用作函数参数
    • 📋利用引用和指针来实现swap()函数
  • 📃如何巩固学习
  • 📃本文小结

😇内联函数的前情介绍

😁内联函数是c++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要区别不在于编写方式,而在于c++编译器如何将它们组合到程序中。要了解内联函数与常规函数之间的区别,必须深入到程序内部。


编译过程的最终产品是可执行程序

它们由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。


📝任何时候我们都要用内联函数吗?

我们应该选择地使用内联函数。如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分。如果代码执行时间很短,则内联调用就可以节省非内联调用使用的大部分时间。另一方面,由于这个过程相当快美因茨尽管节省了该过程的大部分时间,但节省的时间绝对值并不大,除非该函数经常被调用。


使用内联函数特性

  1. 在函数声明前加上关键字inline;
  2. 在函数定义前加上关键字inline。

通常的做法时省略原型,将整个定义(即函数头和所有函数代码)放在本应提供原型的地方。

📝程序员请求将函数作为内联函数时,编译器并不一定会满足这种要求。他可能认为该函数过大或注意到函数调用了自己(内联函数不能递归),因此不将其作为内联函数;而有些编译器没有启用或实现这种特性。


实例

通过内联函数square()演示了内联技术。注意到整个函数定义都放在一行中,但并不一定非得这样做。然而,如果函数定义占用多行(假定没有使用冗长的标识符),则将其作为内联函数就不太合适。

#include<iostream>
using namespace std;

inline double square(double x)
{
	return x * x;
}

int main()
{
	double a, b;
	double c = 13.0;
	a = square(5.0);
	b = square(4.5 + 7.5);
	cout << "a = " << a << ", b = " << b << "\n";
	cout << "c = " << c; 
	cout << ", c squared = " << square(c++) << "\n";
	cout << "Now c = " << c << "\n";
	return 0;
}

输出
在这里插入图片描述

📋输出表明,内联函数和常规函数一样,也是按值来传递参数的。如果参数为表达式,如4.5+7.5,则函数将传递表达式的值(这里为12)。这使得c++的内联功能远远胜过c语言的宏定义。

😇内联与宏

🐤宏的优缺点:

优点:

  1. 增强代码的复用性
  2. 提高性能
    缺点:
  3. 不方便调试宏。(因为预编译阶段进行了替换)
  4. 导致代码可读性差,可维护性差,容易误用。
  5. 没有类型安全的检查

c++中那些技术替换宏?

1、常量定义换用const enum
2、短小函数定义 换用内联函数

😇引用变量

c++新增了一种复合类型—引用变量

引用是已定义的变量的别名(另一个名称)。

📝创建引用变量

前言

在c和c++使用&符号来指示变量的地址。c++给&符号赋予了另一个含义,将其用来声明引用。例如,要将rodents作为rats变量的别名,可以这样做:

int rats;
int& rodents = rats;

其中,&不是地址运算符,而是类型标识符的一部分。就像声明中的char* 指的是指向char的指针一样,int&指的是指向int的引用


C语言的用户

📝首次接触到引用时可能也会有些疑惑,因为这些用户很自然地会想到指针,但它们之间还是有区别的。例如,可以创建指向rats的引用和指针:

int rats = 101;
int& rodents = rats;
int* prats = &rats;

引用的特点

必须在引用时将其初始化,而不能像指针那样,先声明,再赋值:我们来看下述代码

int main()
{
	int rat;
	int& rodents;
	rodents = rat;
	return 0;
}

报错信息
在这里插入图片描述
注意

必须在声明引用变量时进行初始化。


C++关于全局变量和局部变量的规定定义了一种名称空间层次。每个声明区域都可以声明名称,这些名称独立于在其他声明区域中声明的名称。在一个函数中声明的局部变量不会与在另一个函数中声明的局部变量发生冲突。

#include<iostream>
using namespace std;
int add(int left, int right)
{
	return left + right;
}
double add(double left, double right)
{
	return left + right;
}
void Swap(int* p1, int* p2)
{}
void Swap(double* p1, double* p2)
{}

int main()
{
	cout << add(1, 1) << endl;
	cout << add(1.1, 1.1) << endl;

	return 0;
}

在上述代码中从#include 到最后一个有括号为止都属于声明区(全局名称空间)

✉将引用用作函数参数

引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量名的别名。这种传递参数的方法成为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。


按值传递

void test(int x)
{

}

int main()
{
	int rat;
	test(rat);
	return 0;
}

两个变量,两个名称

按引用传递

void test(int& x)
{

}

int main()
{
	int rat;
	test(rat);
	return 0;
}

一个变量。两个名称

📋利用引用和指针来实现swap()函数

💐在常见的日常刷题的过程中,我们经常要交换两个变量的值,这里我们对使用引用和使用指针做一下比较。

引用实现swap()函数

#include<iostream>
using namespace std;
void swapy(int& x, int& y)
{
	int temp = x;
	x = y;
	y = temp;
}
int main()
{
	int x = 1, y = 0;
	cout << "x = " << x << "y = " << y << endl;
	swapy(x, y);
	cout << "x = " << x << "y = " << y << endl;

	return 0;
}

在这里插入图片描述

注意

为什么我们用引用可以实现呢?我们来分析一下,因为在这里我们用了引用作为函数的参数,他就相当于我们传递上来参数的别名,也就是换了个名字而已,所以我们修改的时候自然而然的也能进行交换


指针实现swap()函数

#include<iostream>
using namespace std;

void swapp(int* x, int* y)
{
	int temp = *x;
	*x = *y;
	*y = temp;
}
int main()
{
	int x = 1, y = 0;
	cout << "x = " << x << "y = " << y << endl;
	swapp(&x, &y);
	cout << "x = " << x << "y = " << y << endl;

	return 0;
}

📃如何巩固学习

提示:在学习的过程中,我们需要先自行进行思考,并且多去阅读一些大佬的书籍,俗话说的好,书籍是人类进步的阶梯!

📃本文小结

  1. C++鼓励程序员在开发程序时使用多个文件。一种有效的组织策略是,使用头文件来定义,为操纵用户类型的函数提供函数原型;并将函数定义放在一个独立的源代码文件中。头文件和源代码文件一起定义和实现了用户定义的类型及其使用方式。最后,将main()和其他使用这些函数的函数放在第三个文件中。

好啦今日的分享到这里就结束啦,我是爱你们的M malloc希望可以帮助到你们噢,最后别忘记三连啦!!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

誉天程序员-瀑布模型-敏捷开发模型-DevOps模型比较

文章目录 2. 项目开发-开发方式2.1. 瀑布开发模型2.2. 敏捷开发模型2.3. DevOps开发模型2.4. 区别 自增主键策略1、数据库支持主键自增自增和uuid方案优缺点 2. 项目开发-开发方式 由传统的瀑布开发模型、敏捷开发模型&#xff0c;一跃升级到DevOps开发运维一体化开发模型。 …

swagger相关问题

swagger相关问题 swagger版本为&#xff1a; <dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>1.9.6</version> </dependency> <dependency><groupId&…

Grafana集成prometheus(4.Grafana添加预警)

上文已经完成了grafana对prometheus的集成及数据导入&#xff0c;本文主要记录grafana的预警功能&#xff08;以内存为例&#xff09; 添加预警 添加入口&#xff08;2个&#xff09; databorard面板点击edit&#xff0c;下方有个Alert的tab&#xff0c;创建Alert rules依赖…

IDEA偶尔编译的时候不识别lombok

偶尔IDEA启动项目的时候会识别不到lombok,识别不到get()跟set()方法 方案 在settings添加下面代码 -Djps.track.ap.dependenciesfalse

自然语言处理学习笔记(二)————语料库与开源工具

目录 1.语料库 2.语料库建设 &#xff08;1&#xff09;规范制定 &#xff08;2&#xff09;人员培训 &#xff08;3&#xff09;人工标注 3.中文处理中的常见语料库 &#xff08;1&#xff09;中文分词语料库 &#xff08;2&#xff09;词性标注语料库 &#xff08;3…

我理解的音响设备音频放大器地线环路共地回路造成交流声干扰哼声的分析,信号接地,工业仪表接地的问题

我理解的音响设备音频放大器地线环路共地回路造成交流声干扰哼声的分析&#xff0c;信号接地&#xff0c;工业仪表接地的问题 wxleasyland 2023.8 一、地线环路造成交流声哼声 家里插座中有一个的PE地线&#xff0c;相当于大地。 设备1的“信号地”接到家里三脚插座的PE地线…

【雕爷学编程】MicroPython动手做(39)——机器视觉之图像基础2

MixPY——让爱(AI)触手可及 MixPY布局 主控芯片&#xff1a;K210&#xff08;64位双核带硬件FPU和卷积加速器的 RISC-V CPU&#xff09; 显示屏&#xff1a;LCD_2.8寸 320*240分辨率&#xff0c;支持电阻触摸 摄像头&#xff1a;OV2640&#xff0c;200W像素 扬声器&#…

unity TextMeshPro 富文本

<b>粗体标签</b> <i>斜体标签</i> <u>下划线标签</u> <s>删除线标签</s> <sup>上标标签</sup>前面后边上标签 5<sup>。</sup>C <sub>下标标签&#xff0c;如&#xff1a;</sub>H<sub&…

【练】要求定义一个全局变量 char buf[] = “1234567“,创建两个线程,不考虑退出条件,打印buf

要求定义一个全局变量 char buf[] "1234567"&#xff0c;创建两个线程&#xff0c;不考虑退出条件&#xff0c;另&#xff1a; A线程循环打印buf字符串&#xff0c;B线程循环倒置buf字符串&#xff0c;即buf中本来存储1234567&#xff0c;倒置后buf中存储7654321. 不…

动手学深度学习—卷积神经网络(原理解释+代码详解)

目录 1. 从全连接层到卷积层2. 图像卷积2.1 互相关运算2.2 卷积层2.3 图像中目标的边缘检测2.4 学习卷积核2.5 特征映射和感受野 3. 填充和步幅3.1 填充3.2 步幅 4. 多输入多输出通道4.1 多输入通道4.2 多输出通道4.3 11卷积核 5. 汇聚层5.1 最大汇聚层和平均汇聚层5.2 填充和步…

c 语言解析 时间字符串

#include <iostream> #include <ctime>int main(int argc, char *argv[]) {struct tm timeinfo;char cur_time[] "current time: 2021-09-06 23:50:13";// 解析时间到timeinfo中strptime(cur_time, "current time: %Y-%m-%d %H:%M:%S", &…

【快应用】adbutton如何直接下载广告而不跳落地页再下载

【关键词】 原生广告、adbutton、下载 【问题背景】 快应用中的原生广告推出了adbutton组件来直接下载广告app&#xff0c;在使用的时候&#xff0c;点击adbutton按钮的安装文案&#xff0c;不是直接下载广告app&#xff0c;而是跳转到落地页后直接下载&#xff0c;这种情形该…

Redis主从复制、哨兵机制、集群分片

目录 一.主从复制 1.概述 2.主从架构相比于单点架构的优势 3.主从复制原理和工作流程 第一次同步 第一阶段&#xff1a;建立链接、协商同步 第二阶段&#xff1a;主服务器同步数据给从服务器 第三阶段&#xff1a;主服务器发送新写操作命令给从服务器 基于长连接的命…

vscode 通过mongoose 连接mongodb atlas

了解mongodb 的项目结构 1.代表集群名称 > 2.代表数据库名称>3.代表每个 collection名称 三者范围为从大到小的关系 &#xff08;一对多&#xff09;。每个集群有不同的连接地址、用户信息&#xff08;Database Access&#xff09;、ip配置信息&#xff08;Network Acce…

Modbus TCP转Profinet网关modbus tcp转以太网

大家好&#xff0c;今天我们来聊一聊如何使用捷米特的Profinet转modbusTCP协议转换网关在博图上进行非透传型配置。 1, 首先&#xff0c;我们需要安装捷米特JM-TCP-PN的GSD文件&#xff0c;并根据现场设备情况配置modbusTCP地址。然后&#xff0c;在博图中添加该GSD文件&#x…

应用在测温仪中的数字温度传感芯片

测温仪&#xff08;thermometric indicator&#xff09;&#xff0c;是温度计的一种&#xff0c;用红外线传输数字的原理来感应物体表面温度&#xff0c;操作比较方便&#xff0c;特别是高温物体的测量。应用广泛&#xff0c;如钢铸造、炉温、机器零件、玻璃及室温、体温等各种…

一零六六、线程池、锁

线程池&#xff1a; 管理线程创建&#xff0c;销毁的一系列池子 如何创建线程池&#xff1f; ExecutorService executor Executors.newFixedThreadPool(n); 创建线程有多种方法&#xff0c;为何要用线程池&#xff1f; 减少性能开销,每次执行任务都新建线程造成cpu资源浪费…

Shell脚本学习-MySQL单实例和多实例启动脚本

已知MySQL多实例启动命令为&#xff1a; mysqld_safe --defaults-file/data/3306/my.cnf & 停止命令为&#xff1a; mysqladmin -uroot -pchang123 -S /data/3306/mysql.sock shutdown 请完成mysql多实例的启动脚本的编写&#xff1a; 问题分析&#xff1a; 要想写出脚…

MINIO安装(centos7)

步骤1&#xff1a;安装wget 在开始安装MinIO之前&#xff0c;需要安装wget命令行工具。可以使用以下命令在CentOS系统中安装wget&#xff1a; sudo yum install wget 步骤2&#xff1a;下载MinIO wget https://dl.minio.org.cn/server/minio/release/linux-amd64/minio 将下…