初始C++(二)

前言:

        C++相对于C语言还有很多区别,接下来我们继续介绍

函数重载:

        很好理解,就是Java中的函数重载。C++加了函数的修饰,通过函数修饰规则去找。C语言是直接通过函数名查找,C++是通过修饰后的函数名去查找。

引用:

        注意,这个知识点很重要。引用不是新定义一个变量,而是给已经存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量公用同一块内存空间。

        相当于给其他人取了别名。

int main()
{int a = 0;//引用:b是a的别名int& b = a;//地址都是一样的cout << &a << endl;cout << &b << endl;return 0;
}

        可以发现, 地址都是一样的。

        我们可以不用传地址,通过引用(取别名)的方式交换实参的值。

void Swap(int& a, int& b)
{//a是x的别名 b是y的别名//所以可以完成交换int tmp = a;a = b;b = tmp;
}int main()
{int x = 1, y = 0;Swap(x, y);cout << x << endl;cout << y << endl;return 0;
}

        这里可以看出,引用有点类似于指针;引用确实可以改变实参,其实引用本事就是为了方便我们的学习,但是我们如果想要学得更好,还是需要学好指针的。但是不能完全替代指针,比如一个链表,还是需要用到指针的。

typedef struct ListNode
{int val;struct ListNode* next;
}LTNode;//void LishPush(LTNode** phead, int x)
//这两者是等价的,我们可以通过引用改变指针指向
void LishPush(LTNode*& phead, int x)
{}

        之前我们使用链表,往里面插入数据需要传二级指针,现在有了引用就不需要传入二级指针,只需要传入指针的引用即可。

        引用在使用的时候必须先初始化;一个变量可以有多个引用。

        引用一旦引用一个实体,便不能引用其他实体。

int main()
{int x = 0, z = 0;int& y = x;//是y变成z的别名呢?//还是z赋值给y?//是z赋值给xy = z;return 0;
}

        注意这里y是x的别名,之后将z的值赋给x。

引用和指针的区别:

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

         语法上引用不开空间,我们通过反汇编来观察:

        可以发现底层都是指针,但是引用语法上不开空间。

        因为就是起了一个别名,所以本质大小还是类型本身的大小。 

注意事项:

        我们先来看一段代码:

int* p = NULL;
int& r = *p;
//这里我们不能只看语法层
//这里就要看底层,是一个指针存放了空指针

        一旦打印,就会崩溃,所以一定注意!

权限:

        我们必须将权限单独来讲,每个变量都会存在权限。

//权限的方法
//m只读
//n变成m的别名,n的权限是可读可写
//权限只能缩小,不能放大
const int m = 0;
int& n = m;

        因为取别名可以将权限放大。 权限只能缩小,不能放大。

int x = 0;
const int& y = x;
x++;//可以修改,只是不能够y去修改

        我们再来观察一个代码: 

int main()
{double d = 12.34;//类型转换会发生临时变量int i = d;int& y = d;//这句是错误的const int& r = d;return 0;
}

        因为临时变量具有常性,所以我们只能添加const语法才正确。 

 

内联函数:

        如果我们要频繁使用一个函数时,如果这个函数是一个小函数,但是需要频繁使用,C语言一般是使用宏,这样可以提高效率。

        但是宏是进行宏替换,很容易出现问题,一般是不建议使用宏去完成一个函数的,那么我们在C++该如何解决这个问题呢?

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

        在Debug版本下内联函数默认不展开,因为这样方便调试。

        此时可以看到call,就说明还是去建立了函数栈帧。此时我们就需要去更改一些配置才能看到具体内联函数是如何操作的。

        当内联函数比较大时,就不再会进行展开。

        inline是一种以空间换时间的做法,如果编译器将函数当成了内敛函数处理,在编译阶段,会用函数体替换函数调用。

        缺陷:可能会使目标文件变大 优势:少了调用开销,提高程序运行效率。

        inline对于编译器而言只是一个建议,不用编译器关于inline实现机制可能不同,一般建议:将函数规模较小(函数不长,取决于编译器内部实现)不是递归切频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

        也就是说,内联函数是否展开取决于编译器。

        这里我们不考虑函数的栈帧,如果展开,编译出来的可执行程序会变大。

        内联不能声明和定义分离!

        因为在链接时会符号汇总,回去找函数的地址,但是内联函数是没有地址的(因为没有call),直接被展开,所以会报链接错误。所以使用内联函数时不要声明和定义分离。

auto:

        auto可以替代写起来比较长的类型定义,简化代码。

int main()
{int a = 10;int b = a;auto c = 'a';cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;return 0;
}

        typeid可以帮助我们去看一个对象的类型。

int x = 10;
auto a = &x;
//指定必须是指针
auto* a1 = &x;

        我们可以用auto来接受指针,可以在后面加上*也可以不加上*,但是一旦加上*,就指定它一定是一个指针变量。 

        auto不能作为函数的形式参数。

        C++中有增强for循环,叫做范围for,我们可以利用auto来改善增强for循环。

int main()
{int arry[] = { 1,2,3,4,5 };for (auto x : arry) {cout << x << " ";}return 0;
}

        如果我们想利用增强for循环来改变数组内容,不能直接改变,因为临时变量是其拷贝,所以我们加上引用即可修改。 

int main()
{int arry[] = { 1,2,3,4,5 };for (auto& x : arry) {x += 1;}for (auto x : arry) {cout << x << " ";}return 0;
}

        在函数中,不能用增强for循环对数组进行遍历,因为传过去的时指针,其只能对数组使用。

void TestFor(int arry[]) 
{for (auto e : arry) {cout << e << endl;}
}int main()
{int arry[] = { 1,2,3,4,5 };TestFor(arry);//for (auto& x : arry) {//	x += 1;//}//for (auto x : arry) {//	cout << x << " ";//}return 0;
}

 

        因为C/C++追求效率,所以不支持传数组。

nullptr:

        我们先看一段代码:

void f(int i)
{cout << "f(int)" << endl;
}void f(int* p)
{cout << "f(int*)" << endl;
}int main()
{f(0);f(NULL);return 0;
}

        因为NULL宏定义为0,所以此时调用的是一个函数。这就是C语言的缺陷。

f((int*)NULL);

        此时只能这样修改。所以C++引入了nullptr关键字。

        使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。

        sizeof(nullptr)与sizeof((void*)0)所占字节数相同。为了提高代码健壮性,在后续表示指针空值是建议最好使用nullptr。

void f(int i)
{cout << "f(int)" << endl;
}void f(int* p)
{cout << "f(int*)" << endl;
}int main()
{f(0);f((int*)NULL);f(nullptr);return 0;
}

总结: 

        OK了老铁焖,我们已经基本上把所有C++基础语法学完了,当然你要有C语言基础,期待下一篇,就是类和对象!

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

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

相关文章

Java 运行的底层原理

Java是一种跨平台的编程语言&#xff0c;其底层原理涉及到了多个方面&#xff0c;包括Java虚拟机&#xff08;JVM&#xff09;、字节码、类加载机制、垃圾回收器等。让我们逐一深入了解Java运行的底层原理。 1. Java虚拟机&#xff08;JVM&#xff09; Java虚拟机是Java程序运…

Python进行excel处理-01

最近干采购&#xff0c;每个月要对供应商的对账单&#xff0c;对对应的采购订单号和物料编号的价格和数量&#xff0c;是不是和物料管控总表里面的价格数量是不是一致&#xff0c;于是写了一个代码。 从总表里面找到&#xff0c;对账单里对应采购订单和物料编码的数据&#xf…

5W 1.5KVDC 隔离 宽电压输入 DC/DC 电源模块——TP05DB 系列

TP05DB系列电源模块额定输出功率为5W&#xff0c;应用于2:1及4:1电压输入范围 4.5V-9V、9V-18V、18V-36V、36V-72V、9V-36V和18V-72V&#xff0c;40-160VDC的输入电压环境&#xff0c;输出电压精度可达1%&#xff0c;具有输出过流保护等功能。可广泛应用于通信、铁路、自动化以…

Java毕业设计 基于SpringBoot vue社区智慧养老监护管理平台

Java毕业设计 基于SpringBoot vue社区智慧养老监护管理平台 SpringBoot 社区智慧养老监护管理平台 功能介绍 登录注册 个人中心 修改密码 个人信息 房间信息管理 房间入住信息管理 反馈信息管理 留言管理 老人信息管理 公告管理 物资申请管理 管理员管理 护工管理 体检员管理…

[C++][数据结构]AVL树插入的模拟实现

前言 紧接着上一篇文章&#xff0c;我们来模拟实现一下set的底层结构 引入 对于BSTree&#xff0c;虽然可以缩短查找的效率&#xff0c;但如果数据有序它将退化为单支树 我们可以用AVL树来解决这个问题。 概念 AVL树&#xff1a; 它的每个结点的左右子树高度之差的绝对值…

Tuxera NTFS for Mac Mac用户无缝地读写NTFS格式的硬盘和U盘

在数字化时代&#xff0c;数据交换和共享变得日益重要。然而&#xff0c;对于Mac用户来说&#xff0c;与Windows系统之间的文件交换可能会遇到一些挑战。这是因为Mac OS默认不支持Windows常用的NTFS文件系统。幸运的是&#xff0c;Tuxera NTFS for Mac为我们提供了一个优雅的解…

一文盘点 Partisia Blockchain 生态 4 月市场进展

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

【微积分听课笔记】全微分,二元极值,Double Integral

6.6 二元函数的极值_哔哩哔哩_bilibili 此笔记为听课笔记&#xff0c;宋浩老师微积分~ 最近诸事缠身&#xff0c;会有种会不会只做一件事好些。实际上&#xff0c;关键在于动力&#xff0c;我不可能每次都准备充分。动力&#xff0c;分配&#xff0c;这是目前进入大学我正在学…

Jetpack Compose三:主题和基础控件的使用

设置主题 与Android View的主题定义方式不同&#xff0c;Jetpack Compose中的主题由许多较低级别的结构体和相关API组成&#xff0c;它们包括颜色、排版和形状属性。 Theme.kt控制工程的主题&#xff0c;它是一个可组合的Compose函数 最后主题函数ComposeStudyTheme的相关设置…

Spring中FactoryBean的作用和实现原理

Spring中FactoryBean的作用和实现原理 BeanFactory与FactoryBean&#xff0c;相信很多刚翻看Spring源码的同学跟我一样很好奇这俩货怎么长得这么像&#xff0c;分别都是干啥用的。 BeanFactory是Spring中Bean工厂的顶层接口&#xff0c;也是我们常说的SpringIOC容器&#xff…

Pytorch学习笔记——卷积操作

一、认识卷积操作 卷积操作是一种数学运算&#xff0c;它涉及两个函数&#xff1a;输入函数&#xff08;通常是图像&#xff09;和卷积核&#xff08;也称为滤波器或特征检测器&#xff09;。卷积核在输入函数上滑动&#xff0c;将核中的每个元素与其覆盖的输入函数区域中的对应…

Windows基于WSL2安装Kali-linux

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、kali-linux是什么&#xff1f;二、简单使用1.下载2.打开1.通过应用列表2.通过Terminal 三、安装图形界面1.下载2.打开 四、重头戏总结 前言 kali-linux大家…

什么牌子的洗地机质量最好?四款耐用高分产品推荐

洗地机具备了吸尘、擦拭、除菌等多种功能&#xff0c;可以一次完成多种清洁任务&#xff0c;帮助用户更高效地保持家居整洁&#xff0c;节省时间和精力&#xff0c;备受人们的喜爱。但是怎么挑选到优质的洗地机一直是大家关注的问题。今天&#xff0c;笔者将结合自己在家电行业…

EMAP的Root工程及其他工具

首先右击项目导航&#xff0c;新建EMAP系统配置 上方辅助工具功能&#xff1a; 1 2 3 4 5 6 7 8 9 10 查看重复数据模型:显示为放大镜标识&#xff0c;可以显示所有应用中相同…

图算法必备指南:《图算法:行业应用与实践》全面解读,解锁主流图算法奥秘!

《图算法&#xff1a;行业应用与实践》于近日正式与读者见面了&#xff01; 该书详解6大类20余种经典的图算法的原理、复杂度、参数及应用&#xff0c;旨在帮助读者在分析和处理各种复杂的数据关系时能更好地得其法、善其事、尽其能。 全书共分为10章&#xff1a; 第1~3章主要…

python笔记:dataclass

1 引子&#xff1a;其他类似实现方法的局限性 假设我们现在需要实现这样的内容&#xff1a; nameChinaarea960population140967 1.1 tuple/list country1_tuple(China,960,140967) country1_tuple[0] #China 缺点&#xff1a;需要记住各个属性是list/tuple第几位的属性&am…

[YOLOv8] 用YOLOv8实现指针式圆形仪表智能读数(二)

最近研究了一个项目&#xff0c;利用python代码实现指针式圆形仪表的自动读数&#xff0c;并将读数结果进行输出&#xff0c;若需要完整数据集和源代码可以私信。 目录 &#x1f353;&#x1f353;1.yolov8实现圆盘形仪表智能读数 &#x1f64b;&#x1f64b;2.表盘指针语义…

Flink DataSource介绍

介绍 Flink的Data Source&#xff08;数据源、源算子&#xff09;是Flink作业的起点&#xff0c;它定义了数据输入的来源。Flink可以从各种数据来源获取数据&#xff0c;例如文件系统、消息队列、数据库等。以下是对Flink Data Source的详细介绍&#xff1a; 概述&#xff1a…

YTM32的片内flash应用答疑 - 释疑efm_sts[accerr]寄存器位

YTM32的片内flash应用答疑 - 释疑efm_sts[accerr]寄存器位 文章目录 YTM32的片内flash应用答疑 - 释疑efm_sts[accerr]寄存器位IntroductionConceptConclusion Introduction 之前有客户在基于ytm32b1le05微控制器做ota方案&#xff0c;其中在擦写片内flash模块时&#xff0c;需…

SpringCloudAlibaba:4.2云原生网关higress的基本使用

概述 简介 Higress是基于阿里内部的Envoy Gateway实践沉淀、以开源Istio Envoy为核心构建的下一代云原生网关&#xff0c; 实现了流量网关 微服务网关 安全网关三合一的高集成能力&#xff0c;深度集成Dubbo、Nacos、Sentinel等微服务技术栈 定位 在虚拟化时期的微服务架构…