c++入门语法—————引用,内联函数,auto关键字,基于范围的for循环,nullptr

文章目录

  • 一.引用
    • 1.引例
    • 2.注意事项
    • 3.应用场景
      • 1.做参数(a:输出型参数b:内容较大参数)
      • 2.做返回值(a:修改返回值,b:减少拷贝)
    • 4.引用和指针的区别
  • 二.内联函数
    • 1.为什么有内联函数
    • 2.用法和底层
    • 3.特性
  • 三.auto关键字
    • 1.基础示例
    • 2.弊端
  • 四.for循环
  • 五. nullptr

一.引用

1.引例

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

数据类型+&+别名=原数值

如以下例子:

int main()
{
	int a = 10;
	int& b = a;
	return 0;
}

vs调试结果:

在这里插入图片描述
显然在语法层面,a和b的地址和数值大小完全一致。

2.注意事项

  • 引用必须初始化,不能空定义一个引用,然后引用。
    在这里插入图片描述
    在这里插入图片描述
  • 引用不同于指针,一旦引用不能中途更换指向。
int main()
{
	int a = 10;
	int c = 20;
	int& b = a;
	b = c;
	return 0;
}

在这里插入图片描述
这里只是赋值而不是重引用

  • 一个变量可以有多个引用多个别名,也可以给引用在引用。
    在这里插入图片描述
  • 不可修改的常量不能被引用
    在这里插入图片描述

3.应用场景

值得注意的是引用和指针在许多场景功能是重复的,但又各自有独特的妙用

1.做参数(a:输出型参数b:内容较大参数)

  • a:
    输出型参数是一种函数参数,用于在函数调用结束后将结果传递出来。这种参数通常用于返回函数的计算结果或状态信息。
    如交换函数:
void Swap(int& x, int& y)
{
	int temp = x;
	x = y;
	y = temp;
}
int main()
{
	int a = 10,  b = 20;
	cout << a<< "  " << b << endl;
	Swap(a, b);
	cout << a <<"  "<<   b << endl;
	return 0;
}

在这里插入图片描述

  • b:

使用引用做参数,在语法层面就少去了函数传参,进行临时拷贝这一过程,所以增加了效率

2.做返回值(a:修改返回值,b:减少拷贝)

在讲用法之前,我需要细说一下函数返回值是如何传回主函数的。系统知识我会后续推出函数栈帧的创建与销毁。

int Func()
{
	int a = 10;
	return a;
}
int main()
{
	cout << Func() << endl;
}

在主函数内调用Func()函数,需要开辟一块内存称为Func()的函数栈帧。
在c/c++中,局部变量储存在栈中,随着函数生命周期结束,栈帧也随之销毁,在程序后期这片内存会清理分配给其他局部变量使用
在这里插入图片描述
由此可见,虽然是return ,但返回的也是一份拷贝,并不是a这个量

  • 错误写法:
int& Func()
{
	int a = 10;
	return a;
}

在这里插入图片描述

在代码量较少函数栈区未清理时,会存在正确情况,但一旦清理,将意味着引用将指向一个无效的内存地址。这将导致未定义的行为,可能会导致程序崩溃或产生不可预测的结果。

  • 所以引用返回值,在堆区使用更加合理,脱离了局部变量返回的束缚:
int& Func(int x)
{
	int* a = (int*)malloc(sizeof(int)*10);
	for (size_t i = 0; i < 10; i++)
	{
		a[i] = i;
	}
	return a[x];
}

在这里插入图片描述

4.引用和指针的区别

  • 语法:
    1.引用是别名不开空间,指针是地址需要开空间
    2.引用必须初始化,指针不要求
    3.引用不能改变指向,指针可以
    4.引用相对更安全没有空引用,指针有空指针,野指针。
    5.sizeof()内的意义,引用指指向的值,指针则指本身指针大小
    6.引用没有±数值的用法
  • 底层:
    在汇编代码角度二者实现方法是相同的,都是指针,都需要开空间

二.内联函数

1.为什么有内联函数

内联函数(inline function)是一种在调用处直接展开执行的函数。在C++中,使用关键字inline声明的函数就是内联函数。内联函数的目的是减少函数调用的开销,提高程序的执行效率。

内联函数通常适用于函数体较小且频繁调用的情况,可以减少函数调用时的开销,但也可能增加代码的大小。

内联函数的定义通常放在头文件中,以便在需要的地方直接展开执行。
在c语言中我们通常使用宏替换去写频繁调用的小函数,不建立函数栈帧。

宏的缺点:
1.语法复杂,不易控制
2.本质是替换,不能调试
3.没有类型安全检查

所以c++中引入了内联函数的概念

2.用法和底层

  • 在未使用内联
int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int ret = Add(1, 2);
	return 0;
}

在这里插入图片描述
call代表调用函数,证明此时建立了函数栈帧

  • 使用内联函数
inline int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int ret = Add(1, 2);
	return 0;
}

在需要展开的函数前加上inline
在这里插入图片描述
这里就没有call指令,即没有调用函数栈帧

3.特性

inline本质为空间换时间,但是一旦函数大小过大,编译器将自动忽略内联不在展开,防止代码膨胀。所以超过范围大小的,和递归类型的函数不适用于内联。

多文件项目函数实现的方法:
1.声明和定义分离
2.static静态实现函数
3.inline函数展开

前两种方法适用于大一些的函数,第三种适用于短小型函数。

三.auto关键字

auto关键字通常用于声明变量,它让编译器根据变量的初始化值自动推断出变量的类型。这样可以简化代码,减少重复输入类型名称的工作量。
在C++11及以后的标准中,auto关键字还可以用于迭代器的声明和lambda表达式的返回类型推断。

1.基础示例

void  func(int x, int y)
{
	return;
}

int main()
{
	void(*pf1)(int ,int) = func;//函数指针
	auto pf2 = func;//自动推导
	cout << typeid(pf1).name ()<< endl;
	cout << typeid(pf2).name() << endl;
	return 0;
}

在很长的函数指针定义时很复杂,所以可以使用auto自动推导
typeid是C++中的一个操作符,用于获取一个对象的类型信息。
在这里插入图片描述

2.弊端

过分使用auto,会误导程序员的判断,相当于一些关键信息会被省略,建议慎用。

四.for循环

C++11引入了范围for循环,它提供了一种简洁的方法来遍历容器、数组或其他可迭代对象的元素。范围for循环的语法如下:

for (auto element : container) {
    // 在这里使用 element
}

其中,auto关键字用于自动推断element的类型,container是要遍历的容器或可迭代对象。在循环的每次迭代中,element将依次代表container中的每个元素,直到遍历完所有元素为止。
日常使用中,这里容器可指数组,所以在c++中遍历数组又有了更简洁的使用方法。

int main()
{
	int arr[5] = { 1,2,3,4,5};
	
	for (auto e : arr)
	{
		//遍历数组
		cout << e << " ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述
注意的一点:这里的e是对数组元素的一份临时拷贝,修改e对数组无效
那么怎么修改呢我们可以尝试使用引用对数组元素取别名
在这里插入图片描述

五. nullptr

在c++98中有一个bug,将NULL直接宏定义为0,所以在函数重载上会有误判。
在这里插入图片描述
如图所示,输出皆为第一个函数,并没有达到重载效果。
所以c++11,引入关键字nullptr进行修正。
在这里插入图片描述
本期文章就分享到这里,感谢收看!
在这里插入图片描述

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

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

相关文章

计网Lesson11 - 虚拟机网络环境及socket概述

文章目录 虚拟机的简述socket概述 虚拟机的简述 放张图在这&#xff0c;根本没明白是啥对啥&#xff0c;以后学了Linux再来吧 &#x1f626; socket概述 s o c k e t socket socket 是一种用于应用层的用户态与应用层以下的内核态交互的工具&#xff0c;本意为“插座”。 也就是…

聚醚醚酮(Polyether Ether Ketone)PEEK在粘接使用时使用UV胶水的优势有哪些?要注意哪些事项?

使用UV胶水在聚醚醚酮&#xff08;Polyether Ether Ketone&#xff0c;PEEK&#xff09;上进行粘接可能具有一些优势&#xff0c;但同时也需要注意一些事项。以下是使用UV胶水的优势和需要考虑的事项&#xff1a; 优势&#xff1a; 1.快速固化&#xff1a; UV胶水通常具有快速…

来聊聊大厂面试题:求Java对象的大小

写在文章开头 日常使用Java进行业务开发时&#xff0c;我们基本不关心一个Java对象的大小&#xff0c;所以经常因为错误的估算导致大量的内存空间在无形之间被浪费了&#xff0c;所以今天笔者就基于这篇文章来聊聊一个Java对象的大小。 你好&#xff0c;我叫sharkchili&#x…

部分地级市收入泰尔指数数据,shp/excel格式,附数据可视化图及计算公式

泰尔指数的计算方式&#xff1a;分别计算城镇和农村收入份额与人口份额之比的自然对数&#xff0c;然后再以城乡收入份额作为权数&#xff0c;进行加权平均求和。 数据名称: 部分地级市收入泰尔指数数据 数据格式: Shp、excel 数据时间: 2010-2019年 数据几何类型: 面 数…

c++学习记录 多态—案例2—电脑组装

#include<iostream> using namespace std;//抽象不同的零件//抽象的cpu类 class Cpu { public://抽象的计算函数virtual void calculate() 0; };//抽象的显卡类 class VideoCard { public://抽象的显示函数virtual void display() 0; };//抽象的内存条类 class Memory …

【蓝桥杯日记】复盘篇二:分支结构

前言 本篇笔记主要进行复盘的内容是分支结构&#xff0c;通过学习分支结构从而更好巩固之前所学的内容。 目录 前言 目录 &#x1f34a;1.数的性质 分析&#xff1a; 知识点&#xff1a; &#x1f345;2.闰年判断 说明/提示 分析&#xff1a; 知识点&#xff1a; &am…

网络体系结构 和网络原理之UDP和TCP

目录 网络分层 一. 应用层 http协议 二. 传输层 1. 介绍 2.UDP协议 (1)组成 (2)细节 3.TCP协议 (1)特性如下链接&#xff1a; (2)组成 (3)特点 三. 网络层 四. 数据链路层 1.介绍 2.以太网协议 3.mac地址和ip地址 五. 物理层 DNS 网络分层 一. 应用层 应用程序 现成的…

dfs专题 P1255 数楼梯——洛谷(疑问)

题目描述 楼梯有 &#xfffd;N 阶&#xff0c;上楼可以一步上一阶&#xff0c;也可以一步上二阶。 编一个程序&#xff0c;计算共有多少种不同的走法。 输入格式 一个数字&#xff0c;楼梯数。 输出格式 输出走的方式总数。 输入输出样例 输入 #1复制 4 输出 #1复制…

【Python】Win11用GTK3实现多文档窗体弹出对话框

一、安装PyGObject PyGObject是GTK的Python绑定&#xff0c;用于Python中的GTK3程序。可以使用pacman命令来安装PyGObject、GTK3和其他必要的库。 1. 打开MSYS2终端&#xff1a; 可以直接通过MSYS2的快捷方式打开终端或者从开始菜单中找到MSYS2。 2. 更新MSYS2包管理器&…

回显服务器(基于UDP)

目录 基本概念 API学习 DatagramSocket DatagramPacket InetSocketAddress 回显服务器实现 服务端 思路分析 具体实现 完整代码 客户端 思路分析 具体实现 完整代码 运行测试 基本概念 发送端和接收端 在一次网络数据传输时&#xff1a; 发送端&#xff1a;…

Linux中的软链接与硬链接

Linux链接概念 Linux链接分两种&#xff0c;一种被称为硬链接&#xff08;Hard Link&#xff09;&#xff0c;另一种被称为符号链接&#xff08;Symbolic Link&#xff09;。默认情况下&#xff0c;使用 ln 命令不加参数创建硬链接&#xff0c;加 -s 参数则创建软链接 硬链接…

2024不可不会的StableDiffusion之扩散模型(四)

1. 引言 这是我关于StableDiffusion学习系列的第四篇文章&#xff0c;如果之前的文章你还没有阅读&#xff0c;强烈推荐大家翻看前篇内容。在本文中&#xff0c;我们将学习构成StableDiffusion的第三个基础组件基于Unet的扩散模型&#xff0c;并针该组件的功能进行详细的阐述。…

RK3568平台开发系列讲解(Linux系统篇)platform 设备的注册

🚀返回专栏总目录 文章目录 一、platform_device_register 注册函数二、platform_device_unregister 反注册函数三、platform_device 结构体四、resource 结构体沉淀、分享、成长,让自己和他人都能有所收获!😄 一、platform_device_register 注册函数 platform_device_re…

海外云手机运营Instagram攻略

Instagram是世界著名的社交媒体平台&#xff0c;有着10亿实时用户&#xff0c;是跨境电子商务的优质流量来源。平台以女性用户为主&#xff0c;购物倾向高&#xff0c;转化率好。它被公认为外贸行业的优质社交媒体流量池。那么&#xff0c;如何使用海外云手机吸引Instagram上的…

【论文阅读】Long-Tailed Recognition via Weight Balancing(CVPR2022)

目录 论文使用方法weight decayMaxNorm 如果使用原来的代码报错的可以看下面这个 论文 问题&#xff1a;真实世界中普遍存在长尾识别问题&#xff0c;朴素训练产生的模型在更高准确率方面偏向于普通类&#xff0c;导致稀有的类别准确率偏低。 key:解决LTR的关键是平衡各方面&a…

力扣题集(第一弹)

一日练,一日功;一日不练十日空。 学编程离不开刷题&#xff0c;接下来让我们来看几个力扣上的题目。 1. 242. 有效的字母异位词 题目描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数…

JS图片二维码识别

前言 js识别QR图片&#xff0c;基于jsQR.js 代码 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title>图片二维码识别</title><script src"https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">…

什么是消息队列?

消息用队列的模式发送&#xff0c; 把要传输的数据放在队列中&#xff0c; 产生消息的叫做生产者&#xff0c; 从队列里取出消息的叫做消费者。 一、组成 生产者&#xff1a;Producer 消息的产生者与调用端 主要负责消息所承载的业务信息的实例化 是一个队列的发起方 代理…

网站小程序分类目录网源码系统+会员注册登录功能 附带完整的搭建教程

随着互联网的发展&#xff0c;小程序分类目录网站已经成为了人们获取各类信息的重要渠道。而在这个领域中&#xff0c;罗峰给大家分享一款网站小程序分类目录网源码系统以其强大的功能和易用性&#xff0c;脱颖而出。本系统集成了会员注册登录功能&#xff0c;让用户能够更加便…

uniapp H5 实现上拉刷新 以及 下拉加载

uniapp H5 实现上拉刷新 以及 下拉加载 1. 先上图 下拉加载 2. 上代码 <script>import DragableList from "/components/dragable-list/dragable-list.vue";import {FridApi} from /api/warn.jsexport default {data() {return {tableList: [],loadingHi…