【C++】C++入门2

引用

引用的语法表层就是给变量起别名

1.发明原因

引用是为了完善指针的一些缺点而创造出来的,在一些场景下可以替代指针,但和指针有很大区别.详细见3.

2.语法

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

3.引用在C语言的应用


在这里插入图片描述
在递归中,若传参是没到一层栈帧都需要改变的,那就需要能不受创立新栈帧的变量,指针就是其一
递归创建二叉树时,要创建多少节点需要int*pi记录,因为在栈帧中,*pi的改变是不可以逆转的,不受跳出递归影响
同样作为引用传入,只要递归中改变,作用域外的值也会改变,不受跳出递归影响


在这里插入图片描述

在数据结构中,我们在改变链表的头结点时需要使用二级指针,这使的很多人都头疼,套来套去的令人混乱。———函数传参要改变指针的指向,就需要使用指针的指针。 如图这难免有些饶
而一些数据结构的书中,在头插部分如图第三和第二定义
第一和第三其实都是用二级指针解决,而第二是传入了头结点的引用,那么更改其引用,也就是改变其本身。这就避免了使用二级指针的麻烦

4.引用作为返回值的使用

首先我们要知道函数返回值的过程
在这里插入图片描述
从Count栈帧返回的值并不会直接赋给ret,而是通过创建临时变量来传递
在这里插入图片描述
后者也一样
在这里插入图片描述
这样,我们就可以引入引用作返回值的用法
在这里插入图片描述
第二点,进行赋值操作,我们举一个例子
比如创建一个结构体数组

#define n 10
typedef struct array
{
	int a[n];
	int size;
}ay;

然后定义一个取数组数据的函数(引用)

int& PosAt(ay&ay, int i)
{
	assert(i < n);

	return ay.a[i];
}

然后我们给数组赋值并打印
在这里插入图片描述
因为PosAt返回的是数组数据的引用,所以是可以进行修改,即可赋值的左值

5.权限保持

指针和引用,赋值/初始化时,权限可以缩小,但不能放大
什么权限:可读可写的权限

权限平移

在这里插入图片描述
权限放大

在这里插入图片描述
权限缩小

在这里插入图片描述

6.小细节

临时变量有常量属性

int Count(int n)
{
	n++;
	return n;
}

int main()
{
    //函数返回值,是创建临时变量
	//临时变量有常量性,不能用变量作常量的别名
	
	int& ret = Count();//错误
	const int& ret = Count();//正确,改成const就可以
}

显示/隐式转换
在这里插入图片描述

auto自动推导类型

1.语法

在这里插入图片描述
auto可以自动推导新变量的数据类型

2.应用场景

我们在数据结构的学习中会发现,结构体名称可能较长,每次定义新变量的时候不是很方便,所以auto可以缓解这一不便

3.举例

在这里插入图片描述
PS:map和string都是以后要学得STL,在此只是举例有很长的类型名,auto可以做相应简化

4.auto遍历数组

int arr[] = { 1,2,3,4,5,6,6,4 };
	//原始版
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;

	//范围for -- 语法糖
	//自动依次获取数组中数据赋值给g对象,自动判断结束
	for (auto g : arr)
	{
		cout << g << " ";
	}
	cout << endl;
	//一样的
	for (int x : arr)
	{
		cout << x << " ";
	}
	cout << endl;

在这里插入图片描述

5.小细节

可以使auto指代更精确
在这里插入图片描述

内联函数

1.发明原因

C语言中,宏是一个重要工具。宏常量和宏函数的运用也较为重要
C++中,使用const和enum代替宏常量,而使用内联函数来代替宏函数

宏函数因为在预处理时进行替换,所以不用建立栈帧
同时,我们知道宏函数因其暴力替换的性质,可简化代码,提高复用性的同时也可能带来很多麻烦,或者使事情更复杂
比如 加法的宏函数

#define Add(x,y) ((x)+(y))

左边的多个括号让很多人一头雾水
因其暴力替换的属性,少任何括号都可能产生歧义
例如

#define Add(x,y) x+y
Add(1,2)*3  -->1+2*3
#define Add(x,y) (x+y)
Add(a||b,a&&b)  -->a||b+a&&b  //但是+比||和&&的优先级高

所以宏函数有时也会添麻烦

而内联函数同样也不需要建立栈帧而是直接在调用部分展开
在这里插入图片描述

2.小细节

内联函数是否展开
在这里插入图片描述
内联函数的分文件编写
在这里插入图片描述

在这里插入图片描述
类内成员函数定义

在类内定义的成员函数,编译器可能会将其定为内联函数(看其是否经常调用且短小)

所以一些经常调用的,短小的,非递归的成员函数,可以直接在类内进行定义

NULL和nullptr

在这里插入图片描述
二者都代表0
但是不知道为什么在C++中,NULL的定义时int
这导致NULL的很多功能失效,所以打了nullptr这个补丁,nullptr=(void)0;*

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值