【C++】C++入门(下)

news2024/11/27 12:29:49

引用

  1. 什么是引用?
      引用是给一个已经存在的变量取一个别名,在语法上并不会给这个别名开一个空间,它和她引用的变量共用一个空间。但是实际上引用也是开了一块空间的,用来存放引用名。引用是按照指针的方式来实现的。
  2. 引用语法:
      类型& 引用变量名(对象名/别称) = 引用实体;注意引用类型必须和被引用类型相同。
int main()
{
	int a = 10;
	int& b = a;

	printf("%p\n", &a);
	printf("%p\n", &b);

	return 0;
}

在这里插入图片描述

  1. 引用特性:
      引用在定义时必须初始化,引用必然是有被引用对象的,不可能说先取个别名,但是不知道这个别名是谁;
      一个变量可以有多个引用,相当于一个人可以有很多个外号一样;
      引用一旦引用一个实体,就不能再引用其他实体了。
int main()
{
	int a = 10;
	//int& b;这个会直接报错
	int& c = a;
	int& d = a;

	int e = 20;
	c = e;

	printf("%p\n%p\n%p\n%p\n", &a, &c, &d, &e);

	return 0;
}

在这里插入图片描述

  如果被引用对象是一个常数,则需要添加const修饰。

int main()
{
	const int a = 10;
	const int& b = a;

	const int& c = 20;

	return 0;
}
  1. 使用场景:
      做参数
void swap(int* a, int* b)
{
	int x = *a;
	*a = *b;
	*b = x;
}
void swap(int& a, int& b)
{
	int x = a;
	a = b;
	b = x;
}
int main()
{
	int a = 1;
	int b = 2;

	swap(&a, &b);
	cout << a << " " << b << endl;

	swap(a, b);
	cout << a << " " << b << endl;
	
	return 0;
}

在这里插入图片描述

  做返回值,可以减少拷贝;调用者可以修改返回值。
  需要提前知道一个点,一个函数的返回值实际上是这个值的拷贝,而不是这个值本身。
  如果函数返回时,出了函数作用域,如果返回对象还没有还给系统,则可以使用引用返回,如果已经还给系统了,则不能使用引用返回,如果使用结果是返回值是未定义的。

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

	return n;
}
int main()
{
	int ret = Count();

	return 0;
}

在这里插入图片描述

  1. 权限问题:
      指针和引用可以进行权限平移和缩小,但是不能进行权限放大。
int main()
{
	int a = 1;
	const int b = 2;
	//权限平移
	int& ra = a;
	const int& rb = b;
	//权限缩小
	const int& c = a;
	//权限放大
	int& d = b;

	return 0;
}

在这里插入图片描述

  1. 与指针的区别
      引用在概念上是一个变量的别名,指针存储一个变量地址;
      引用必须初始化,指针没有规定;
      引用在初始化后就不能改变了,指针可以在任何时候改变指向;
      在sizeof中含义不同,引用的结果是引用类型的大小,但是指针始终是地址空间所占用的字节个数;
      引用自加是被引用的实体加一,指针自加是指针向后偏移一个类型的大小;
      指针可以有多级,但引用没有;
      访问实体时,指针需要显式的解引用,引用是编译器自己处理;
      引用比指针更加安全。

内联函数:

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

int Add(int left, int right)
{
	return left + right;
}
inline int Sub(int left, int right)
{
	return left - right;
}
int main()
{
	int ret = 0;
	ret = Add(1, 2);

	int tmp = 0;
	tmp = Sub(4, 3);

	return 0;
}

  有call说明进行了跳转,是开辟了栈帧空间的。
在这里插入图片描述

  我们默认的调试模式是在Debug模式,Debug是不会进行代码优化的,如果我们想要看到内联函数的展开就需要修改一些配置。Release又对代码优化的太厉害了,我们不太容易看懂。
在这里插入图片描述

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

特性:
  内联函数是一种空间换时间的做法,如果编译器将函数当做内联函数处理,在编译阶段,会用函数体替换函数调用。这是就会出现一个问题,如果内联函数太大,就会使目标文件变大,所以内联函数常被用来写一些短小的函数。实际上,如果内联函数过长,编译器也会忽视这个内联,把它当做普通函数处理;
  内联函数对于编译器只是一个建议,不同的编译器关于内联函数的实现机制可能存在不同。在《C++ prime》中明确指出,内联说明只是想编译器发出一个请求,编译器可以选择忽略这个请求;
  内联函数的声明和定义一般情况下是不分离的,因为分离之后可能会导致链接错误,内联函数是会被展开的,展开之后就不存在函数地址了,那这个时候去链接地址就会找不到。
  
使用场景:
  内联函数常被用来替代宏函数。这时候就有个问题,既然有宏函数,为什么又要搞出内联函数这个东西?因为宏是较大缺陷的。
  宏的优缺点:
    优点:增强代码的复用性;提高性能。
    缺点:不方便调试(因为在预编译阶段就进行了宏替换);导致代码可读性差,可维护性差,容易误用;没有类型安全检查。
    所以在C++中,常使用const enum代替宏的常量定义,用内联函数代替宏函数。

auto关键字(C++11):

  在写代码的时候,可能会遇到一个类型名非常长的情况,这种类型名写一两个还行,但是如果多了就非常容易写错。有些人会用typedef来解决这一问题,但是typedef有一个缺陷。
在这里插入图片描述

  早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,但是并没有人使用它。之后在C++11中,auto就具有新的含义了,auto不再是一个存储类型的指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
  auto定义变量时必须初始化,auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器编译时会将auto替换为变量实际的类型。
  用autto声明指针类型时,用auto和auto*没有任何区别,但是用auto声明引用类型时必须要加&。

int main()
{
	int x = 10;
	auto a = &x;
	auto* b = &x;
	auto& c = x;
	auto d = x;
	//typeid().name()可以返回变量的类型名
	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	
	printf("%p\n", &x);
	printf("%p\n", &c);
	printf("%p\n", &d);

	return 0;
}

在这里插入图片描述

  当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
在这里插入图片描述

  auto不能作为函数参数;
  auto不能直接用来声明数组;
  为了避免与C++98中的auto发生混淆,C++11值保留了auto作为类型指示符的用法;

基于范围的for循环(C++):

  C++11中引入了基于范围的for循环。for循环后的括号由冒号":"分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

int main()
{
	int a[] = { 1,2,3,4,5 };
	//自动依次取数组中的数据赋值给e(e只是个名字,可以改变),自动判断结束
	for (auto e : a)
		e *= 2;

	for (auto e : a)
		cout << e << " ";
	cout << endl;
	//这里相当于e是a[0]、a[1]等的别名,就可以达到改变数组的效果
	for (auto& e : a)
		e *= 2;

	for (auto e : a)
		cout << e << " ";
	cout << endl;

	return 0;
}

在这里插入图片描述

  与普通循环类似,也可以使用continue和break;
  范围for的循环范围必须是确定的;

指针空值nullptr(C++11):

  NULL实际是一个宏定义的,NULL可能被定义为字面常量0,或者被定义为无类型指针(void *)的常量。也不知道出于什么原因被定义成了字面常量0,这样在程序中就会造成一些不可预料的问题。
在这里插入图片描述

  于是C++11就打了一个补丁,引入nullptr作为关键字,代表指针空值。在C++11中,sizeof(nullptr)与sizeof((void*)0)所占用的字节数相同。

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

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

相关文章

电子技术——B类输出阶

电子技术——B类输出阶 下图展示了一个B类输出阶的原理图&#xff0c;B类输出阶由两个互补的BJT组成&#xff0c;不同时导通。 原理 当输入电压 vI0v_I 0vI​0 的时候&#xff0c;两个晶体管都截止输出电压为零。当 vIv_IvI​ 上升至超过0.5V的时候&#xff0c;此时 QNQ_NQN…

MVVM 架构进阶:MVI 架构详解

前言Android开发发展到今天已经相当成熟了&#xff0c;各种架构大家也都耳熟能详&#xff0c;如MVC,MVP,MVVM等&#xff0c;其中MVVM更是被官方推荐&#xff0c;成为Android开发中的显学。不过软件开发中没有银弹&#xff0c;MVVM架构也不是尽善尽美的&#xff0c;在使用过程中…

【软件测试】从功能到自动化测试,测试人的进阶之路细节,这些必不可少......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试流程&#xff0…

SQL语法2

SQL语法视图view常用函数三张重要的表接SQL语法第一篇文章&#xff0c;接下来所有的操作都基于safe这张表进行。视图view 语法&#xff1a;create view 视图名称 as select 原表中的列名 from 原表名&#xff1b; 删除视图&#xff1a; 语法&#xff1a;drop view 视图名&…

【Python】Numpy数组的切片、索引详解:取数组的特定行列

【Python】Numpy数组的切片、索引详解&#xff1a;取数组的特定行列 文章目录【Python】Numpy数组的切片、索引详解&#xff1a;取数组的特定行列1. 介绍2. 切片索引2.1 切片索引先验知识2.1 一维数组的切片索引2.3 多维数组的切片索引3. 数组索引&#xff08;副本&#xff09;…

Linux解压压缩

打包tar首先我们得提一下专门用于打包文件的命令——tartar用于备份文件&#xff0c;打包多个文件或者目录&#xff0c;也可以用于还原被打包的文件假设打包目录test下的文件 tar -cvf test.tar ./test 假设打包目录test下的文件,并用gzip命令将包压缩 tar -zcvf test.tar ./te…

华为OD机试题,用 Java 解【蛇形矩阵】问题

最近更新的博客 华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】华为OD机试 - 分糖果(Java) | 机试题算法思路 【2023】华为OD机试 - 非严格递增连续数字序列 | 机试题算法思路 【2023】华为OD机试 - 消消乐游戏(Java) | 机试题算法思路 【2023】华为OD机试 - 组成最大数…

22河北省赛 F

Problem - F - Codeforces 思维构造题 题意: 一个长为n的直线洞窟中, 每一个1~n的整数位置都有一个洞口可以容纳一只兔子 有一只兔子在这个洞窟里四处躲藏, 每一回合都必须向左或者向右移动, 不能待在原地 你每一次都可以在兔子移动之前检查任何一个洞口 要求在最坏的情况…

银行数字化转型导师坚鹏:平安银行数字化转型—橙E网战略研究

平安银行对公业务数字化转型案例—橙E网战略研究课程背景&#xff1a; 很多银行存在以下问题&#xff1a; 不清楚银行对公业务数字化转型能否成功&#xff1f; 不知道其它银行对公业务数字化转型的实际做法&#xff1f; 课程特色&#xff1a; 用实战案例解读平安银行对公业务…

python网络数据获取

文章目录1网络爬虫2网络爬虫的类型2.1通用网络爬虫2.1.12.1.22.2聚焦网络爬虫2.2.1 基于内容评价的爬行策略2.2.2 基于链接结构的爬行策略2.2.3基于增强学习的爬行策略2.2.4基于语境图的爬行策略2.3增量式网络爬虫深层网页爬虫3网络爬虫基本架构3.1URL管理模块3.2网页下载模块3…

算法进阶-动态规划

经典例题 大家肯定想用递归做 思路大概就是这样 递归到最后一行就是对应的D(i,j) 然后往上推 但是这样会超时&#xff0c;因为存在大量的重复计算 比如调用第一行MasSum(7)需要调用MaxSum(3)和MaxSum(8) 但是调用第二行MaxSum(3)还要调用3行的MaxSum(8)和3行的MaxSum(1) 第二行…

English Learning - L2-2 英音地道语音语调 2023.02.23 周四

English Learning - L2-2 英音地道语音语调 2023.02.23 周四查音标的工具怎么练习效果好准备工作大小声练习大元音开口度的对比舌位对比复习后元音 /ɑː/ /ɔː/ /uː//ɑː//ɔː//uː/前元音 /iː/发音技巧对应单词的发音对应句子的发音常见的字母组合中元音 /ɜː/发音技巧…

作业2.25----通过操作Cortex-A7核,串口输入相应的命令,控制LED灯进行工作

1.通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输入led…

golangの并发编程(GMP模型)

GMP模型 && channel1. 前言2. GMP模型2.1. 基本概念2.2. 调度器策略2.3. go指令的调度流程2.4. go启动周期的M0和G02.5. GMP可视化2.6. GMP的几种调度场景3. channel3.1. channel的基本使用3.2. 同步器1. 前言 Go中的并发是函数相互独立运行的体现&#xff0c;Gorouti…

RabbitMQ学习(十一):RabbitMQ 集群

一、集群1.1 为什么要使用集群前面我们介绍了如何安装及运行 RabbitMQ 服务&#xff0c;不过这些是单机版的&#xff0c;无法满足目前真实应用的 要求。如果 RabbitMQ 服务器遇到内存崩溃、机器掉电或者主板故障等情况&#xff0c;该怎么办&#xff1f;单台 RabbitMQ 服务器可以…

西北工业大学大学物理(II)期末试题选填解析2021-2022

2 金属薄片&#xff0c;就暗示了载流子是电子了。3 熟练掌握左右手即可。4 又是位移电流。6 感应电场。随时间变化着的磁场能在其周围空间激发一种电场&#xff0c;它能对处于其中的带电粒子施以力的作用&#xff0c;这就是涡旋电场&#xff0c;又叫感生电场。涡旋电场是非保守…

使用file-selector-button美化原生文件上传

前言 你平时见到的上传文件是下面这样的? 还是下面这种美化过的button样式 还是下面这种复杂的上传组件。 <input type="file" >:只要指定的是type类型的input,打开浏览器就是上面第一种原生的浏览器默认的很丑的样式。 下面的两种是我从ElementUI截的图,…

Flume简介

Flume是一个高可用&#xff0c;高可靠&#xff0c;分布式的海量日志采集、聚合和传输的系统&#xff0c;能够有效的收集、聚合、移动大量的日志数据。 优点&#xff1a; 使用Flume采集数据不需要写一行代码&#xff0c;注意是一行代码都不需要&#xff0c;只需要在配置文件中…

切记:别手欠升级手机系统!

今天手欠升级了手机系统&#xff0c;相机直接不能用了......过年手机坏了&#xff0c;买的报修险申请了售后&#xff0c;换了主板换主板还没保存数据&#xff0c;结果大家都懂&#xff0c;手机里那么多照片视频全没了&#xff0c;这个怪自己平时没做数据备份&#xff0c;手机坏…

【fly-iot飞凡物联】(2):如何从0打造自己的物联网平台,使用开源的技术栈搭建一个高性能的物联网平台,目前在设计阶段。

目录前言1&#xff0c;fly-iot 飞凡物联2&#xff0c;mqtt-broker 服务3, 管理后台产品/设备设计4,数据存储目前使用mysql&#xff0c;消息存储到influxdb中5,规则引擎使用 ekuiper6, 总结和其他的想法前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/detail…