C++入门基础篇(2)

欢迎大家的来到小鸥的博客,今天我们继续C++基础的第二篇吧! 

这也是入门基础篇的最后一篇wo~

目录

1.引用

引用的概念

引用的特性及使用

const常引用

指针和引用的关系

2.inline内联函数

定义

相关特性及使用​

3.nullptr

>>后记<<


1.引用

引用的概念

引用不是新定义⼀个变量,而是给已存在变量取了⼀个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同⼀块内存空间。
就像你同时拥有名字和外号一样,他们都代表了你这个个体;变量名和这个变量的引用,都同样代表了这个变量本身。

在类型名的后面加上&符号,就是一个这种类型的引用,在C语言中&加在变量名前面,意思为取地址;而在类型名后面加上&,则代表引用。

定义方式:  类型& 引用别名 = 引用对象;

引用的特性及使用

特性:

  1.  C++中引用在定义时必须初始化,且引用一但指向一个实体,不能改变指向;
  2. 一个变量可以有多个引用,且引用不会另开空间;

  3. 引用不能代替指针,比如在链表中,就不能用引用代替指针(因为引用无法改变指向);

  4. 由于不可以改变指向,所以有以下情况:

    int a = 10;
    int b = 20;
    int& d = a;//别名d指向a,且不可改变
    d = b;//此时表示的就是一个赋值语句,将b的值赋值给d,d的指向仍然为变量a,即a=d=20,而不是将别名d的指向改为变量b

使用:

1.引用多用于传参和返回值:

  • 当做参数时,形参就是一个别名,就相当于直接将实参本身给了函数,这样即使不进行传址调用,也同样可以影响到实参本身。
  • 当作返回值时,返回的就是一个引用,可以对其进行修改,而正常情况下的返回值是存放在一个临时变量中的,临时变量具有常性,不可以修改。

2.当引用做返回值时,若返回一个局部变量,将导致出错,如:

int& Fun()
{int a = 0;return a;
}//变量a为局部变量,出函数后将会销毁

3.java 中的引用可以不初始化,且可以改变指向,更像 C/C++ 中的指针

const常引用

const引用即常引用,其所取的别名,将使当前别名的权限为只读不写,const引用也可以对常量以及带有常性的数据(临时变量)进行取别名

  • 临时对象:编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象,C++中把这个未命名对象叫做临时对象

  • const引用的使用牵扯到了权限的放大和缩小,只有指针和引用才会牵扯到权限的放大和缩小,在引用时,只能缩小权限,不能放大权限。代码演示(详细解释见注释处):

    int main()
    {int a = 1;const int b = 2;double c = 1.1;const double d = 2.2;const int& ra = a;//权限的缩小//int& rb = b;    //权限的放大,错误的//b本身就是一个const修饰的常变量,权限为只读不写,而int&的权限为可读可写,引用不可以放大权限//int& rc = c;    //c为double类型的变量,需要隐式类型转换为int类型,//但隐式类型转换的结果会先存储到一个临时对象中,临时对象具有常性const int& rc = c;//所以加上const修饰使其成为常引用,就可以指向c了return 0;
    }
  • const修饰的引用还可以指向常量和表达式

    	int a = 1;//int& c = 30;     //(错误使用)   const int& ra = 30;//常量只能用具有常性的const常引用;//int& rc = (a + 1);//(错误使用)   const int& rb = (a + 1);//表达式的计算结果会先存储到一个临时对象中,临时对象用const常引用

指针和引用的关系

在实际运用中,指针和引用相辅相成,虽然功能有部分重叠,但又各有特点,互相不可替代。

  1. 在语法概念上引用是给一个变量取别名,不需要开辟空降;而指针则是一个新的变量用于存储地址,需要开辟空间
  2. 引用必须初始化指向,而指针虽然建议初始化,但是非必须的;
  3. 引用不能后续改变指向,而指针可以;
  4. 引用可以直接访问变量,而指针要通过解引用来间接访问;
  5. 在sizeof操作符中,引用的大小为其引用的类型大小(如 sizeof(int),sizeof(char) 等),而sizeof(指针)的大小为地址空间所占的字节个数32位4字节,64位8字节);
  6. 引用的使用更加安全,不易出错,而指针容易出现空指针和野指针的情况。

2.inline内联函数

定义

使用inline修饰的函数叫做内联函数,在编译时,C++编译器就会在调用内联函数的地方展开内联函数(效果类似宏函数),省去了建立栈帧的消耗,可以一定程度提高效率

相关特性及使用

1.inline内联函数在Debug模式下默认是不展开的,这样方便调试,想要展开时,需要更改设置:

解决方案资源管理器窗口下,右击项目文件打开属性,根据图示进行修改:

2.nline内联函数对于编译器而言,是可选择执行的,当inline修饰的函数较为简单时,编译器才会展开,当函数较为复杂,展开消耗更大时,编译器就可以选择忽略inline,不对其进行展开;这是由编译器所决定的,不同的编译器标准不同。

inline int Fun()
{int ret = 10;return ret;
}//较为简短,inline生效int main()
{int a = Fun();cout << a << endl;return 0;
}

inline int Fun()
{int ret = 10;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;return ret;
}//函数较为复杂,inline不生效int main()
{int a = Fun();cout << a << endl;return 0;
}

此处的汇编call语句相当于一个跳转语句,意思为跳转到函数Fun,括号中为函数的地址

3.inline的意义就是用于替代C语言中的宏函数,因为宏函数使用时较为复杂且容易出现错误;

以宏函数实现相加为例:

#define ADD(x,y) ((x)+(y))
//为什么要表达式外面要加括号
// 为什么x,y分别要加括号
// 为什么不加分号//错误示范
/*
#define ADD(x,y) x + y
#define ADD(x,y) (x + y);
#define ADD(x,y) (x)+(y)
...
*/

而如果使用inline内联函数就可以实现替换需求的同时,实现函数一样的简单定义方式。

4.一般函数我们都是定义和声明分开的,但inline修饰的内联函数不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。

3.nullptr

在C语言中我们知道NULL,而NULL实际上就是一个宏,在传统的C头文件(stddef.h)中,我们可以看到如下代码:

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

由此可以看出在C++中NULL可能被定义为了字符常量0,而在C语言中则定义为了⽆类型指针(void*)的常量,但这两种定义在我们想使用空指针时都会出现一些麻烦和问题,如下代码:

void Fun(int x)
{cout << "Fun(int x)" << endl;
}
void Fun(int* ptr)
{cout << "Fun(int* ptr)" << endl;
}
int main()
{Fun(0);Fun(NULL);//由于C++定义NULL为整型的0,所以和相当于Fun(0)Fun((int*)NULL);//Fun((void*)0);//在C语言中允许(void*)类型隐式转换为任意类型指针,但C++不行//C++void* ptr = NULL;   //C++的类型转换更加严格int* pa = (int*)ptr;//C++中必须进行显示转换,将void*类型强转为int*类型//C/*void* ptr = NULL;int* pa = ptr;//C语言允许void*类型隐式转换为其他类型*/return 0;
}

结果如下:

这样Fun(NULL)语句就和我们本来想要达到的目的相悖了。

所以在C++中就定义了一个nullptr,nullptr是一个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换成任意其他类型的指针类型,这样可以防止想要使用NULL时被转换为整型0的问题,因为nullptr可以被隐式转换为任意类型的指针,而不是整型

使用nullptr代替NULL即可使Fun(nullptr)正确的指向第二个函数。


>>后记<<

本篇讲解了引用,inline内联函数,nullptr关键字的相关定义和作用,有不足的地方大家可以在评论区或私信指出,大家互相学习wa

个人主页:海盗猫鸥-CSDN博客

本篇专栏:C++_海盗猫鸥的博客-CSDN博客

再次欢迎大家的到访,那么本篇就到这里,我们下篇再见——

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

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

相关文章

摩尔投票算法

文章目录 什么是摩尔投票算法算法思想 相关例题摩尔投票法的扩展题目解题思路代码奉上 什么是摩尔投票算法 摩尔投票法&#xff08;Boyer-Moore Majority Vote Algorithm&#xff09;是一种时间复杂度 为O(n),空间复杂度为O(1)的方法&#xff0c;它多数被用来寻找众数&#xf…

深入理解Symfony框架中的数据验证机制

Symfony是一个高度灵活的PHP Web应用框架&#xff0c;它提供了一整套工具和实践来帮助开发者构建复杂的Web应用。数据验证是确保应用数据完整性和安全性的关键环节。在Symfony中&#xff0c;数据验证是通过一系列的组件和方法来实现的&#xff0c;这些组件和方法遵循DRY&#x…

Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用

Dot&#xff1a;指代点对象或者表示点的符号。Arrow&#xff1a;指代箭头对象&#xff0c;包括直线上的箭头或者向量箭头等。NumberPlane&#xff1a;指代数轴平面对象&#xff0c;在Manim中用来创建包含坐标轴的数学坐标系平面。Text&#xff1a;指代文本对象&#xff0c;用来…

Linux系列--命令详解

目录 一、Linux资源管理方式 二、查询类型命令详解 三、文件管理类型命令详解 四、文件压缩与解压 五、文件编辑 六、系统命令 七、文件内容查看命令 一、Linux资源管理方式 linux操作系统采用一个文档树来组织所有的资源。这棵树的根目录的名字叫做&#xff1a;//…

使用 HttpServlet 接收网页的 post/get 请求

前期工作&#xff1a;部署好 idea 和 一个 web 项目 idea(2021),tomcat(9) ->创建一个空的项目 -> 新建一个空的模块 -> 右键单击模块 选择 Add..Fra.. Sup.. -> 勾选Web App...后点击OK -> 点击 file - Project Struc... -> 选择刚刚的模块 -> 点…

Web 性能入门指南-2.0 核心网络性能指标LCP、INP、CLS

Largest Contentful Paint、Interaction to Next Paint 和 Cumulative Layout Shift 是前端性能优化和用户体验评估中的重要指标&#xff0c;以下是它们的英文缩写及中文含义&#xff1a; 最大内容绘制 (LCP) 英文缩写&#xff1a;Largest Contentful Paint&#xff0c;LCP …

Linux - 基础开发工具(yum、vim、gcc、g++、make/Makefile、git)

目录 Linux软件包管理器 - yum Linux下安装软件的方式 认识yum 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式各命令汇总 vim底行模式各命令汇总 vim的简单配置 Linux编译器 - gc…

IOSUI自动化之mobiledevice

mobiledevice 要求 MAC OS X 10.6 以上版本 通过USB连接你的iPhone设备 需要安装mobiledevice 安装app需要提前安装开发者证书 安装 brew update brew install mobiledevice 支持的能力 安装卸载app 连接电脑的iphone设备列表 mobiledevice list_devices 获取设备属性 mobiled…

C 语言指针进阶

1.0 指针的定义 指针是内存中一个最小单元的编号&#xff08;内存单元的编号称之为地址【地址就是指针指针就是地址】&#xff09;指针通常是用来存放内存地址的一个变量。本质上指针就是地址&#xff1a;口语上说的指针起始是指针变量&#xff0c;指针变量就是一个变量&#…

MySQL覆盖索引和索引跳跃扫描

最近在深入学习MySQL&#xff0c;在学习最左匹配原则的时候&#xff0c;遇到了一个有意思的事情。请听我细细道来。 我的MySQL版本为8.0.32 可以通过 show variables like version; 查看使用的版本。 准备工作&#xff1a; 先建表&#xff0c;SQL语句如下&#xff1a; c…

golang基础用法

一、基础用法 基础定义 // 变量 var int i i 5 i :5 i, j : 3,"dsafd"// 常量const ( i "adfa" b 5 )// 特殊常量itoa itoa重新出现表示规0 后面会自动1 const (Monday iota // 0Tuesday // 1Wednesday // 2Thursday // 3Friday…

Element Plus 与 Vue 3:构建现代化 Web 应用的完美搭档

引言 Element Plus是基于Vue 3的组件库&#xff0c;它继承了Element UI的优秀基因&#xff0c;为Vue 3应用提供了丰富的界面组件。Element Plus不仅拥有与Element UI相同的高质量组件&#xff0c;还针对Vue 3进行了优化和更新&#xff0c;确保了与Vue 3的无缝集成。 环境准备…

Vue3单文件jsx输出多组件示例遇到的坑

感谢博主减肥吧Evan提供的SFC实现多组件的思路和实现&#xff0c;小卷在大佬的基础上再完善下实现。 我们从tsx的API使用上得到启发&#xff0c;可以在vue的单文件组件&#xff08;sfc&#xff09;中使用defineComponent来定义和导出多个独立的小组件。此时sfc中的<templat…

SSM框架学习笔记(仅供参考)

&#xff08;当前笔记简陋&#xff0c;仅供参考&#xff09; 第一节课&#xff1a; &#xff08;1&#xff09;讲述了Spring框架&#xff0c;常用jar包&#xff0c;以及框架中各个文件的作用 &#xff08;2&#xff09;演示了一个入门程序 &#xff08;3&#xff09;解释了…

Redis 实现的延时队列组件

最近看开源看到一个好用的延时队列组件&#xff0c;已经上生产。代码量很少&#xff0c;主要就是利用Redis监听过期键实现的。然后搞点策略模式柔和柔和。利用Spring Start 封装了一下&#xff0c;全是俺掌握的知识&#xff0c;稍微研究了下就搞懂了。觉得挺有用的&#xff0c;…

006-三台交换机堆叠

三台交换机堆叠 链形连接和环形连接 链形配置IRF与环形配置IRF的区别 三个交换机链形配置IRF与三个交换机环形配置IRF的主要区别体现在以下几个方面&#xff1a; 物理位置要求&#xff1a; 链形连接&#xff1a;对成员设备的物理位置要求相对较低&#xff0c;主要适用于成员…

计算机课程名,汇总

MP-ZHI, CS-DOG, R, NBA ! 助记词&#xff1a;媒婆知道&#xff0c;CS-DOG&#xff0c;认识NBA明星&#xff01; M&#xff0c;密&#xff0c;《网络安全》P&#xff0c;Performance&#xff0c;性能卓越的&#xff0c;指的是超算Z&#xff0c;组&#xff0c;《计算机组成原理…

Linux下如何解压rar文件

在windows下我们压缩解压文件通常后缀为rar&#xff0c;在linux下我们压缩解压文件通常后缀为tar 默认在linux下我们不能解压压缩rar文件&#xff0c;那我们如何使用呢&#xff1f; 我们可以下载rarlinux安装包实现解压压缩后缀为rar的包 下载地址&#xff1a;https://www.r…

HybridCLR + Addressable 热更新篇(一)

目录 前言一、HybridCLR 和 Addressable 是什么&#xff1f;1. HybridCLR2. Addressable 二、使用步骤1.HybridCLR导入2.HybridCLR配置3.Addressable导入4.Addressable配置 前言 随着移动互联网和游戏行业的快速发展&#xff0c;热更新技术变得越来越重要。热更新能够在不重新…

图——定义和基本术语

图是数据结构中非常重要的一章&#xff0c;这篇文章就先介绍一下图的定义和基本术语。 一&#xff0c;图的构成 图&#xff1a;Graph(V,E) V&#xff1a;顶点(数据元素)的有穷非空集合&#xff1b; E&#xff1a;边的有穷集合。 如下面这个图&#xff0c;由点集和边集可以确定…