【c++】——关于const的那些事儿

在c++的基础知识里面,有一个我们经常使用的const,那么我们要了解const在c和c++中的区别,const和一二级指针的结合等~


首先,我们要来明确一下,什么是const,在我们通常的观念里面,我们会认为下面这个代码是错误的。

	const int b = 20;
	b = 30;

因为const修饰的变量不能作为左值。初始化完成后值不能被修改。

一、const在c和c++中的区别

1、在.c中const 的用法

1.1const修饰的量,可以不用初始化
例如以下的程序是错误的:

const int a;
a = 20;

因为const的值虽然可以不用初始化,但是以后就不能作为左值来进行修改了。
所以一般情况下还是对其进行初始化。

1.2const修饰的量不叫常量,叫常变量
他和变量的唯一区别就是不能够把她作为左值修改。比如下列程序就是错误的。

const int a = 20;
int array[a] = {};

1.3练习
下列.c程序,打印结果是多少?

int main()
{
	const int a = 20;
	int* p = (int*)&a;
	*p = 30;
	printf("%d %d %d\n", a, *p, *(&a));
	return 0;
}

指针指向的是a的内存。结果是30,30,30.因为a这块内存已经被改了。a一直都是一个变量

2、在.cpp中const 的用法

2.1const修饰的量,必须初始化,常量
所以以下代码则是正确的:

const int a = 20;
int array[a] = {};

2.2const修饰的量叫常量
还是上述.c里面练习的代码。打印结果则为20 30 20
因为:const的编译方式不同,c中,const就是当做一个变量来编译生成指令的
c++中所有出现const常量名字的地方,都被常量的初始值替换了

2.3const修饰的量叫常变量的情况。初始值不是立即数,是一个变量

int b = 20;
const int a = b;

这种情况和.c文件里面的运行相同。

二、const和指针的结合

1、const 和一级指针的结合

1.1三种情况
在c++ 的语言规范里面,我们都知道const修饰的是离他最近的类型。

情况一:
const int *p;
表示的是可以任意指向不同int 类型的内存,但是不能通过指针间接修改指向的内存的值
所以,*p = 20错误的 p = &b正确的

情况二:
int const* p;
表示的是这个指针p现在是常量,不能在指向其他内存,但是可以通过指针解引用修改指向的内存的值
所以, p = &b正确的 *p = 20错误的

情况三:
const int *const p; 都不可以

1.2总结const的指针的类型转换公式
int <= const int 是错误的
const int * <= int* 是可以的**
解释如下:

int a = 10;
int *p1 = *a;
const int *p2 = &a;  //const int * <= int *
int *const p3 = &a;  //int*  <= int*

1.3const如果右边没有指针*的话,const是不参与类型的
解释如下:

int *q1 = nullptr;  //类型int*
int *const q2 = nullptr;  //类型int*
int *const p3 = &a;  //int*  <= int*
int *p4 = p3;//没有任何问题

1.4习题练习

错误的
int a = 10;
const int *p = &a;//const int * <= int*
int *q = p;//int * <= const int *

正确的
int a = 10;
int *const p = &a;//int * <= int*
int *q = p;//int * <= int *

正确的(因为const不参与类型)
int a = 10;
int *const p = &a;//int * <= int*
int *const q = p;//int * <= int *

正确的
int a = 10;
int *const p = &a;//int * <= int*
const int *q = p;//const int * <= int *

2、const 和二级指针的结合

2.1三种情况
const int **q; **q不能被赋值
int const q; *q不能被赋值
int **const q; q不能被赋值

2.2总结const的指针的类型转换公式
const int** <= int** 是错误的
int** <= intconst(const修饰的是一级指针)是错误的
int* const* <= int** 是可以的

2.3习题练习

错误的
int a = 10;
int *p = &a;
const int **q = &p;

正确的
int a = 10;
int *p = &a;
int *const*q = &p;

正确的
int a = 10;
int *p = &a;
int **const q = &p;//int** <= int**

错误的
int a = 10;
int * const p = &a;// int* <= int*
int ** q = &p;//int ** <= int *const*

错误的
int a = 10;
const int *p = &a;
int *const* q = &p;//int * <= const int**

三、const 和引用的结合

实质上引用是一种更安全的指针,下列代码是引用的一些实例:

int main()
{
	int a = 10;
	int* p = &a;
	int& b = a;
	*p = 20;
	cout << a << " " << *p << " " << b << endl;
	b = 30;
	cout << a << " " << *p << " " << b << endl;
	return 0;
}

最后的结果为20,20,20;30,30,30。说明三个都指向同一块内存
**1.引用是必须初始化的,指针可以不初始化
**
我们来看看以下语句的汇编

int* p = &a;
int& b = a;
在这里插入图片描述
*p = 20;
在这里插入图片描述
b = 30;
在这里插入图片描述
我们从上述汇编可以发现,指针和引用在底层的实现实质上是相同的。
注意!
要初始化的值一定要取地址,因为它在指令生成的时候,是把右边它所引用的值的地址拿出来放到右边底层的指针内存里,然后通过
引用变量赋值的时候,又从底层的指针拿出来地址,再做地址解引用赋值
所以int &c = 20是错误的,const int& a = 20;可因为其指令根本无法生成
**2、引用只有一级引用,没有多级引用,指针可以有一级指针,也可以有多级指针
**
例如,让写一句代码,在内存的0x0018ff44处写一个4字节的整数10

(1)p是一个左值引用
int &p = (int)0x0018ff44;错的
应该改正为int const &p = (int)0x0018ff44;
(2)p是一个右值引用变量

int &&p = (int)0x0018ff44;正确的

具体的引用和指针的区别,请参考博文指针和引用的区别

发布了62 篇原创文章 · 获赞 7 · 访问量 2549

猜你喜欢

转载自blog.csdn.net/qq_43412060/article/details/105045951