【我的C++入门之旅】(下)

news2024/9/20 23:17:48

前言

  • 参考前章内容【我的C++入门之旅】(上)

目录

  • 前言
  • 1.引用
    • 常引用
    • 传值、传引用效率比较
    • 引用和指针的区别
  • 2.auto关键字
    • 使用场景
  • 3.范围for 语法糖
  • 4.inline函数
  • 5.指针空值nullptr

1.引用

取别名,一块空间有多个名字或者说是一个变量有多个名字
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

我们可以看到下面a的地址和b的地址是一样的
也就是说a就是b,b就是a

#include <iostream>
using namespace std;
int main()
{
	int a = 1;
	int& b = a;//&跟类型在一起的适合叫引用符
	cout << &a << endl << &b << endl;
	return 0;
}

结果:
在这里插入图片描述
引用在定义时必须初始化
在这里插入图片描述

引用一旦引用实体,再不能引用其他实体

int main()
{
	int a = 1;
	int& b = a;
	int c = 10;
	b = c;//这行代码是给c取了个名字叫b吗?还是把c的值赋给b
	cout << a << endl << b << endl;
	return 0;
}

显而易见b = c的意思是把c的值赋给b
在这里插入图片描述

引用做参数(输出型参数)
引用做参数(提高效率)(大对象/深拷贝类对象)
引用作为返回值
但如果返回的那个别名的值空间归还给操作系统了,就会越界访问,相当于野指针。

平常写的交换两个数,使用指针,还要解引用

void Swap(int* left, int *right)
{
	int tmp = *left;
	*left = *right;
	*right = tmp;
}

用引用作为参数

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

引用作为返回值:

没有被static修饰的n:
我们知道每个函数都有自己的函数栈帧,出了栈帧,就会把使用权还给操作系统,我们返回的是n的别名,那我们再去访问的时候,n的那块空间的使用权以及不归我们使用了,可能结果是对的。
被static修饰的n:
出了函数栈帧也不会销毁,因为n是在静态区创建的。

看看下面两段代码有什么区别

被static修饰的n

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

没被static修饰的

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

总结:
基本任何场景都可以用引用传参
谨慎使用引用做返回值,除了函数作用域,对象不在了,就不能用引用返回,对象还在,就可以用引用返回

常引用

不同类型会产生临时变量(临时变量具有常性)
在这里插入图片描述

传值、传引用效率比较

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

在这里插入图片描述
返回值类型的性能比较

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

引用和指针的区别

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

2.auto关键字

auto自动推导类型
autu不能在同一行定义多个不同类型变量
auto不能作为函数参数
auto不能直接用来声明数组

在这里插入图片描述

使用场景

  1. 类型难于拼写
    2.含义不明确导致容易出错

当类型很长的时候,可以使用auto
在这里插入图片描述
auto与指针和引用结合起来使用
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

int main()
{
	int x = 10;
	auto a = &x;//把x的地址交给指针
	auto* b = &x;//
	auto& c = x;
	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	*a = 20;
	*b = 30;
	 c = 40;
	return 0;
}

在同一行不能定义多个不同的变量

void TestAuto()
{
 	auto a = 1, b = 2; 
 	auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

3.范围for 语法糖

以前我们C语言要遍历数组是这样的:
在这里插入图片描述

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号 ,“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围

  • 依次取arr数组中值赋给e
  • 自动迭代,自动判断结束
  • 适用于数组
void TestFor()
{
	int array[] = { 1, 2, 3, 4, 5 };
	for (auto& e : array)//如果要改变数组中的值,auto后面加&
		e *= 2;//每次对数组的值*=2

	for (auto e : array)
		cout << e << " ";//打印
}

4.inline函数

C语法:宏函数 Add(x, y) ((x)+(y))
优点:不需要建立栈帧,提高效率
缺点:复杂,容易出错,代码可读性变差

在这里插入图片描述

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率

在函数前面加个inline就是内联函数

在这里插入图片描述

inline适用于短小的且频繁调用的函数,否则会造成代码膨胀,代码膨胀的后果就是可执行程序变大
inline对于编译器仅仅只是一个建议,最终是否成为inline,取决于编译器
类似下面的函数加了inline,也会被编译器否决掉
1.比较长的函数不行
2.递归函数也不能搞inline
默认debug模式下,inline不会起作用,否则就无法调试

5.指针空值nullptr

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0

在这里插入图片描述

正常情况下,打印的应该是f(int)和f(int*),但是情况并不是这样:
在这里插入图片描述

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
  2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。

在这里插入图片描述

所以在C++中,推荐使用nullptr

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

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

相关文章

【LeetCode: 44. 通配符匹配 | 暴力递归=>记忆化搜索=>动态规划 】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【Linux】线程详解之线程概念

前言 在我们的教材中&#xff0c;对线程给出以下的概念&#xff1a; 是进程内部的一个执行分支&#xff0c;在进程的内部运行&#xff0c;属于进程的一部分&#xff0c;比进程更加轻量化。 可能有的人看完之后都是懵的&#xff0c;什么叫在进程的内部运行&#xff0c;什么又是…

【正点原子STM32连载】 第十二章 SYSTEM文件夹介绍 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十二…

文件夹路径保存不同,什么批量修改名称

在日常工作中不知道大家有没有遇到过&#xff0c;需要批量修改文件夹名称&#xff0c;并且文件夹保存路径不同呢&#xff0c;像这种情况到底不能批量修改呢。我也问了很多身边的朋友&#xff0c;他们有的说&#xff0c;他一般都修改保存路径是同一个&#xff0c;还很少遇到像我…

【C++ STL】 趣学stackqueuepriority_queue【对话情景版】

文章目录 &#x1f4cd;前言C STL 之 stack&queue基础知识及其模拟实现&#x1f4cd;容器适配器&#x1f388;什么是适配器&#xff1f;&#x1f388;STL标准库中stack和queue的底层结构&#x1f388;deque的简单介绍(了解)&#x1f4cc;deque的原理介绍&#x1f4cc;deque…

强化学习:基本概念

以 grid-world 为例&#xff0c;进行强化学习基础概念的介绍。如图&#xff0c;机械人处于一个网格世界中&#xff0c;不同的网格代表不同的功能&#xff0c;白色代表机械人可以自由的进入&#xff0c;黄色代表陷阱&#xff08;机械人一旦进入就会被强制返回起点&#xff09;&a…

《Reinforcement Learning: An Introduction》第1章笔记

文章目录 1.1 强化学习1.2 强化学习的例子1.3 强化学习的要素1.4 局限和范围1.5 拓展例子&#xff1a;井字游戏1.6 总结1.7 强化学习的早期历史参考资料 1.1 强化学习 强化学习是学习做什么—如何将情景映射到动作—以便最大化数字奖励信号。学习者不会被告知该采取什么动作&a…

MySQL基础(三十九)MySQL常用命令

1 MySQL常用命令 1.1 mysql 该mysql不是指mysql服务&#xff0c;而是指mysql的客户端工具。 语法 &#xff1a; mysql [options] [database]1.1. 连接选项 #参数 &#xff1a; -u, --username 指定用户名 -p, --password[name] 指定密码 -h, --hostname 指定服务器IP或域名…

计算机组成原理实验报告二-认识汇编语言

实验资料&#xff1a; https://wwpv.lanzoue.com/b05drqjef 密码:d19t 使用txt文档编写下面C源码&#xff0c;文档命名为【学号_hello.c】并使用Mingw工具&#xff08;是 Minimalist GNU for Windows的缩写&#xff09;的bin文件夹下gcc.exe带选项编译&#xff08;&#xff09…

JUC之线程池的标准创建方式

文章目录 JUC之线程池的标准创建方式核心和最大线程数量空闲时长(keepAliveTime)线程工厂(ThreadFactory)任务阻塞队列线程池的拒绝策略线程池的任务调度流程 JUC之线程池的标准创建方式 ​ 因为使用Executors快捷创建线程池在使用时会有严重的潜在问题&#xff0c;因此在实战…

数据结构——队列的实现(细就完事了)

1.队列 1.1队列的概念和结构 今天我们要是实现的队列是完全相反的&#xff0c;队列是数据先进先出。而在栈中我们使用的顺序表(数组)来实现的。而队列却用单链表来实现是更加合适的。 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行数据操作的特殊线…

【王道·计算机网络】第六章 应用层【未完】

一、基本概念 1.1 应用层概述 应用层对应用程序的通信提供服务应用层协议定义&#xff1a; 应用进程交换的报文类型&#xff0c;请求还是响应?各种报文类型的语法&#xff0c;如报文中的各个字段及其详细描述字段的语义&#xff0c;即包含在字段中的信息的含义进程何时、如何…

这是关于“树先生“的故事

《数据结构专栏》 文章目录 《数据结构专栏》一、认识树结构如何遍历树如何创建一个树&#xff1f;如何判断一颗树是否是完全二叉树&#xff1f; 二、树的简单算法——递归1.相同树2.镜像树3.单值二叉树 总结 一、认识树结构 树的定义&#xff1a;树是指由N&#xff08;N>0…

高效研发团队都在看!一套方法论带你找到适合自己的效能提升路径

近日&#xff0c;ONES 受邀参加 2023 QECon 全球软件质量&效能大会&#xff08;深圳站&#xff09;。在会上&#xff0c;ONES 研发效能改进咨询顾问陈仪&#xff0c;发表了主题为《如何为研发团队打造专属的效能提升路径》的演讲。 陈仪有着丰富的咨询经验&#xff0c;曾带…

Netty核心技术二--BIO编程

1. I/O模型 I/O 模型简单的理解&#xff1a;就是用什么样的通道进行数据的发送和接收&#xff0c;很大程度上决定了程序通信的性能 Java共支持3种网络编程模型/IO模式&#xff1a;BIO、NIO、AIO Java BIO &#xff1a;同步并阻塞(传统阻塞型)&#xff0c;服务器实现模式为一个…

C++每日一练:饿龙咆哮-逃离城堡(避坑指南)非负整数求和

文章目录 前言一、题目二、解题代码及思路1、思路2、代码 三、非负整数求和总结 前言 饿龙这一题要说难度嘛&#xff0c;还真是挺简单的&#xff0c;但要满分也是有坑的&#xff01;本文就记录了笔者解题过程&#xff0c;希望能对读者使用C编程有所启发。至于非负整数求和代码…

RocketMQ集群环境部署

文章目录 1. 准备环境2. 修改主机名3. 免密登录配置4. 配置RocketMQ集群5. 搭建RocketMQ集群6. 启动集群 1. 准备环境 准备好三台虚拟机&#xff0c;下面是我的虚拟机的一些基本信息 名称ip地址worker010.117.33.135worker110.117.39.202worker210.117.9.52 三台虚拟机都已经…

Windows下nginx的配置与启动

一&#xff0c;下载 http://nginx.org/&#xff0c;打开官网&#xff0c;点击download 选择下载稳定版 二&#xff0c;解压 1&#xff0c;解压到硬盘某个目录 2&#xff0c;由于80端口被占用&#xff0c;于是我要修改conf目录下的nginx.conf文件 查看端口是否被占用 net…

路径规划算法:基于蝴蝶算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于蝴蝶优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于蝴蝶优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法蝴蝶…

【C++】类和对象(上):带你速度了解什么是类,如何定义类!!

前言&#xff1a; 前面我们学习C一些基础的内容&#xff0c;也可以说C针对C语言的缺陷进行改进。而今天我们要学的是C的内容也就是类和对象。 一、初识类&#xff1a; 我们先来看看C语言解决一个问题的过程&#xff1a; 假设有以下这个场景&#xff1a;你需要手洗一件衣服&am…