当前位置: 首页 > news >正文

【C++】入门基础(引用、inline、nullptr)

目录

一.引用

1.引用的定义

2.引用的特性

3.引用的使用场景

4.const引用

5.引用和指针的区别

二.inline

 三.nullptr


一.引用

1.引用的定义

引用不是新定义一个变量,而是给已经存在的变量取一个别名,编译器不会给引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。简单来说,引用就是起别名,例如水浒传中林冲又名豹子头,这就是取别名,同时,林冲死了也就意味着豹子头死了,两者指向的都是同一个人。

用法:类型&引用别名 = 应用对象;

int main()
{//对a起别名b和cint a = 0;int& b = a;int& c = a;cout << a << endl;cout << b << endl;cout << c << endl;cout << &a << endl;cout << &b << endl;cout << &c << endl;return 0;
}

2.引用的特性

  1. 引用在定义的时候必须初始化。因为引用是一个别名,它的存在建立在主体存在的基础上,也就是说必须引用一个已经存在的对象,否则会引起编译报错。

  2. 一个变量可以有多个引用。正如一个人可以有多个外号,但这些引用都指向同一个对象。

  3. 引用一旦引用另一个实体,就不能再引用其他实体。引用一旦建立,就不能更改为其他实体的引用,这种“偷外号”的行为是不允许发生的。

  4. 允许引用其他引用。例如:int& b = a,int &c = b;此时就是c引用了b,但b也是引用的a,此时,b,c都是a的别名。

int a = 0;
int& b = a;
int c = 20;
//b已经引用a的情况下,不能更改为引用c
//以下直接看作赋值
b = c;
cout << a << endl;
cout << b << endl;
cout << c << endl;

3.引用的使用场景

引用在实践中主要是用于引用传参和做返回值,能够减少拷贝提高效率,同时能够改变引用对象和被引用对象。

引用传参跟指针传参的功能是类似的,但引用传参看着更简洁也更方便。例如,对于Swap函数的实现而言,引用传参可以这样实现:

void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}

引用返回值就要看使用场景了,例如在栈(Stack)的实现中,有一个函数叫STTop用于得到栈顶元素,返回值是int,只是一个数值的拷贝,具有常性,无法做左值,即无法进行修改。

但若返回值改为int&,那么此时就是对返回的栈顶元素取别名,那么就可以进行修改了。如下所示

typedef int STDatatype;
typedef struct Stack
{int* a;int capacity;int top;
}ST;//直接引用传参
void STInit(ST& rs, int n = 4)
{rs.a = (STDatatype*)malloc(sizeof(STDatatype) * n);rs.capacity = n;rs.top = 0;
}void STPush(ST& rs, STDatatype x)
{rs.a[rs.top] = x;rs.top++;
}//int STTop(ST& rs)
//{
//	return rs.a[rs.top - 1];
//}int& STTop(ST& rs)
{return rs.a[rs.top - 1];
}
int main()
{ST s;STInit(s,4);STPush(s, 1);STPush(s, 2);STTop(s) = 4;return 0;
}

4.const引用

const引用可以用来引用普通对象,普通对象是能读能写,但const引用后,引用是只读不写,注意:对象本体还是可以写的,只是引用(别名)用const修饰了不能写,这叫权限缩小

const引用也可以用来引用const对象,此时就叫权限平移,因为引用和本体的权限是相同的,都被const修饰,只能读不能写。

普通引用不能用来引用const对象,这是权限放大。原本本体就不能被修改,但引用后反而能被修改了,这合理吗?这种写法是禁止的,也会进行如下报错。

 引用临时对象需要使用const引用。什么是临时对象?临时对象出现在以下这几种情况:

类型转化:如下double类型转化为int引用

double a = 1.1;

const int& b = a;

表达式结果:如下a*3就是一个表达式,需要临时对象储存结果

int a = 1;

const int& b = a*3;

5.引用和指针的区别

  1. 引用必须初始化,指针建议初始化,但语法上不是必须的
  2. 引用不开辟空间,但指针是储存一个变量地址,需要开空间
  3. 初始化后引用不可修改指向对象,而指针可以修改指向对象
  4. 引用直接访问指向对象,指针需要解引用才能访问
  5. sizeof时,引用是引用对象类型的大小,而指针始终是地址空间所占的字节个数(32位下是4字节,64位下是8字节)
  6. 引用更加安全,指针容易出现空指针和野指针的问题

二.inline

使用inline修饰的函数就是内联函数,编译时编译器会将其在调用的地方展开,这样调用内联函数就需要建立栈帧了,可以提高效率。inline就是为了替代C语言中宏函数而实现的,宏函数实现很复杂而且容易出错,不方便调试,inline才运营而生。

当然inline对于编译器而言只是一个建议,是否展开取决于编译器本身,一般来说,inline适用于频繁调用的短小函数,对于递归函数,代码较多的函数,就算加上inline编译器也会选择忽略。

line不建议声明和定义分离到两个文件,分离会导致链接错误。但可以在同一个项目的不同源文件内定义函数名相同但实现不同的inline函数。

注:class类中的函数默认是inline

 三.nullptr

在C语言中,NULL其实是一个宏,它的定义是:

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

 那么在使用时就会产生歧义,例如在调用空值的指针时,就有可能调用到int类型的重载函数,例如:

void f(int x)
{cout << "f(int x)" << endl;
}
void f(int* x)
{cout << "f(int* x)" << endl;
}
int main()
{f(0);f(NULL);return 0;
}//结果是两次都是调用的f(int x)

因此在C++11中引入了nullptr,这是一个特殊的关键字,它可以转化为任意类型的其他指针类型,但不能转化为整数类型,这就避免上图的出错。 

看到这里,就能对有了一定的C++基础知识,但还不算入门,接下里我会持续更新类和对象的内容,那才是面向对象编程的精髓。感谢观看,欢迎关注。 

http://www.lryc.cn/news/399476.html

相关文章:

  • 24/07/10数据结构(5.1213)链表OJ
  • C++ 入门基础:开启编程之旅
  • 据传 OpenAI秘密研发“Strawberry”项目
  • 简单的SQL字符型注入
  • HttpClient调用SpringBoot项目的文件上传接口实现文件上传
  • [leetcode]kth-smallest-element-in-a-sorted-matrix 有序矩阵中第k小元素
  • 【经典面试题】是否形成有环链表
  • Flask 用 Redis 缓存键值对-实例
  • 我的世界1.21多种服务端开服教程,原版/Forge/Fabric/Paper/Mohist...,Minecraft开服教程
  • docker安装nginx并配置https
  • 永磁同步电机控制算法--基于 SVM 的无磁链环 DTC
  • 如何避免在 Docker 容器中遇到 MAC 地址冲突和 IP 地址冲突的问题
  • arm64架构下源码编译安装kafka —— 筑梦之路
  • LabVIEW前面板占满整个屏幕(转)
  • Promise.all、any、race和allSettled的相同点与不同点与应用场景
  • Ubuntu下如何设置程序include搜索路径及链接路径
  • FLinkCDC引起的生产事故(二)
  • 【产品经理】WMS多仓调拨转移说明
  • 每日一练:奇怪的TTL字段(python实现图片操作实战)
  • 【Java开发实训】day03——方法的注意事项
  • HarmonyOS NEXT:一次开发,多端部署
  • Bilibili Android一二面凉经(2024)
  • 数据库内核研发学习之路(一)
  • LSTM:深度学习中的时间序列处理大师
  • T113-i系统启动速度优化方案
  • ArcGis将同一图层的多个面要素合并为一个面要素
  • 微软Win11 24H2七月更新补丁KB5040435发布!附下载
  • iOS 开发中不常见的专业术语
  • 【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构④ | 4.7
  • Time to say GoodBye