C++中const、引用、指针之间的要点与难点总结
一、const
1、C的const修饰的变量称为伪常量,可以通过指针修改其值,所以C中也不能用const常量作为数组的维度。 C++修饰的变量为真常量,不可以通过指针修改其值,C++中可以用const常量作为数组的维度。
const int a=10;
int *p=(int*)&a;//*p的值是10,(int*)的作用是类型强转
*p=20;
//C中输出:a=20,*p=20。通过指针把const int a的值改变了
//C++中输出a=10,*p=20。*p的值被改变了,但是const int a的值没有变
cout<<"a="<<a<<" , "<<"*p="<<*p<<endl;
//C中会报错,因为const为伪常量,会被修改;C++中编译通过。
int b[a];
2、const在C与C++中的实质
- C中,编译器会给const变量分配内存空间,所以可以通过取址的方式修改值。
- C++中,编译器不会给const变量分配内存空间,而是将const变量专门存在符号表里,变量对应变量值。
在C++中int p=(int)&a为什么可以取a的地址呢? 这是因为编译器会临时开辟一块内存空间temp来存储a的值,即int temp=a;int p=(int) &temp。
3、C++中const对象默认只在文件内有效。
这样做的原因是为了防止重定义。其他文件想用const对象,加extern关键字就可以了。
4、C++中的const在某些情况下也会分配内存
-
取地址的时候会分配临时内存
-
加extern关键字会分配临时内存
-
用普通变量初始化const变量时会分配内存
int c=10 ; const int d=c;//d会分配内存 int *p1=(int*)&d;//*p的值是10,(int*)的作用是类型强转。 *p1=20; //C++中输出d=20,*p1=20 cout<<"d="<<d<<" , "<<"*p1="<<*p1<<endl;
-
自定义的数据类型
5、尽量用const代替#define(无类型,无作用域)来定义常量
6、const对象必须初始化,const只在要改变对象的操作才会发挥作用。
二、引用
引用就是起别名,不分配内存,与被引用的变量有相同的地址。
1、引用的注意事项
(1)引用必须初始化,初始化后所引用的对象不能修改,但是可以赋值
int e=5,f=2;
int &g=e;//初始化
g=f;//这不是修改引用,这是赋值
(2)引用必须引用一块合法的内存空间,但是加入const可以直接赋值
const int &i=10;//正确
(3)引用类型与原类型保持一致
(4)不要返回局部变量的引用
(5)可对引用,再次引用。多次引用的结果,是某一变量具有多个别名
(6)引用加入const后,编译器会分配临时内存,将可以通过取地址修改const引用值
const int &j=10;
int *p2=(int*)&j;//*p的值是10,(int*)的作用是类型强转。
*p2=20;
//C++中输出j=20,*p2=20
cout<<"j="<<j<<" , "<<"*p2="<<*p2<<endl;
2、数组的引用:给数组起别名
int arr[10];
int(&parr)[10]=arr;//parr是arr的别名
3、指针的引用
int i=10;
int *P;
int *&r=p;//这是指针的引用,不存在引用的指针
4、引用的本质 :指针常量
int h=10;
int &rh=h;//内部会自动转化为int *const rh=&h;
rh=20;//内部会自动转换为*rh=20;
5、初始化常量引用允许用任意可转化为引用的类型的表达式作为初始值
//以下式子都可以编译成功,原因是编译器会创建一个临时变量接受右值,而左值便会绑定这个临时变量
//这样也导致了当const引用一个非const对象时,可以修改这个非const对象来修改const引用值
int a=10;
double b=20;
const int &ra=a;
const int &rb=b;
const int &r=10;
三、指向常量的指针与常量指针
1、指向常量的指针
int const *p
(底层const)助记:const后面是*p,代表所指对象不能变。
(1)要想存常量对象的地址,一定要有指向常量的指针
const int a=10;
int *p=&a;//报错,不能用非常量指针储存常量对象的地址
const int *p1=&a;//正确
(2)指向常量的指针不能用于修改其指向的对象的值
const int a=10;
const int *p=&a;//正确
*p1=10;//错误,所指对象的值不能修改
(3)指向常量的指针坚持自己指向的是常量,不管自己指的是不是常量,坚持不更改指向对象的值。但是指向的对象如果不是常量,对象是可以通过被赋值等操作更改的。
int a=10;
const int *p=&a;//正确
a=10;//虽然不能通过*p来修改a,但是可以通过给a赋值来修改a
2、常量指针
int *const p
(顶层const)助记:const后面是p
,代表地址不能变。
(1)常量指针意思是指针是一个常量,指针本身所存的地址不变,一直指向那个地址
int a=10;
int b=20;
int *const p=&a;
p=b;//报错,p一直存着a的地址,不能更改
(2)常量指针指向的如果不是常量的话,是可以通过常量指针修改所指对象的值
int a=10;
int *const p=&a;
*p=20;//正确
(3)如果指向的是一个常量,那就成了const int *const p类型,不能修改所指对象的值
const int a=10;
int *const p=&a;//报错
const int *const p=&a;//正确·