前言
本文将全面分析const这一C++语法的所有相关用法,包括:
const、const指针、const引用、在函数当中的引用
const怎么理解?C和C++中const的区别?
最基本情况下:
1、C++中,const所修饰的量,必须初始化,初始化有两种方式:立即数、变量,立即数初始化得到的是常量,变量初始化得到的是常变量,且初始化完毕之后是不能被修改的,即const修饰的量不能作为左值。const int a=20;
这里的a将不能再被修改,也可以再这样描述:a=30;
这里是非法的。编译时,所有出现const常量名字的地方,都会被常量的初值替换,而const常变量则与下面C中的一致。
2、在C中,const修饰的量叫常变量,不叫常量。const 仅仅在语法层级限制a不能被写成赋值,即仅仅不能写成a=30
。const就只是当做一个变量来编译生成指令。此种区别举例如下:
#include <stdio.h>
int main()
{
const int a=20;
int *p=(int*)&a;
*p=30;
printf("%d %d %d",a,*p,*(&a));
return 0;
}
对于这个程序其在C中结果是30 30 30,而在C++中则是20 30 20。这就意味着在C里面,甚至可以通过汇编修改a的值。
Const与一级指针的结合
const修饰的常量出现必须注意的问题:
1、常量不能作为左值—>导致直接修改常量的值
2、不能把常量的地址泄漏给一个普通的指针或者普通的引用变量—>导致可以间接修改常量的值
举例:
const int a=20;//这里是非法的,上面的代码能通过是因为强制转换为了(int*)
int *p=&a; //这里右边是const int*类型,左边是int* 类型,出现了问题2
const与一级指针的结合情况(const修饰的是离它最近的类型):
1、const int *p;
cosnt 修饰的是int,修饰指针的指向,那么*p一经初始化,就不能再修改,但是p可以改动
举例:const int * p=&a;
*p=20 非法
p=&b 合法
总结:可以指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值。
2、int const* p
这种情况,const不可能修饰*,应该修饰int,同上
3、int *const p;
这种情况const修饰的是前面的int * 类型,修饰指针本身,这里指针p就是常量,不能指向其他内存,但是可以通过指针解引用修改指向的内存。
int* const =&a;
p=&b; 非法
*p=b; 合法
4、const int *const p;
这种非常严格,第一个const修饰int ,第二个const修饰p,这里指针的指向和指针本身都被限制
总结:const类型和指针的类型转换公式(const如果右边没有指针*,cont不参与类型):
int* <= const int* 错误
const int* <= int* 正确
const与二级指针的结合
有三种结合方式:
1、const int **q;
const修饰int,作用于**q
2、int *const* q;
const修饰int*,作用于*q
3、int **const q;
const修饰int * *,作用于q
转换公式为:
int ** <= const int **,错误,两边都要是const int **
const int** <= int**, 错误
int** <= int*const* ,错误
int* const * <= int** ,正确