一、const与一级引用
①
const int a = 10;
int &b = a;
正确。
②
const int a = 10;
int &b = a;//error
因为可能通过b进而修改a的值,a被const修饰值不可改,所以编译器会报错。
③
const int a = 10;
int const &b = a;//取地址不参与类型,b的类型是int,const修饰的是&b
const int &b = 10;//常引用
这个编译可以通过,因为10的值存入临时变量,然后将临时变量的地址赋给b
④
int a = 10;
const int &b = a;//这句在底层相当于const int* b = &a;
正确。
二、引用一级指针
①
int a = 10;
int *p = &a;
int *&p = &a;<==>int *&q = &p;//底层:int **q = &p==>**q = a
正确。
②
const int a = 10;
const int *p=&a;
const int *&q=&p;
正确。
三、const和指针
①
const int a = 10;
int *p = &a;//errror
因为a是一个常量,*p有修改a值的迹象,编译器会杜绝这种情况出现,所以会报错。在第二句最前面加一个const即可。
②
const int a = 10;
int *const p = &a;//error
因为p指向a的内存块,不会改变指向,但是也可能通过*p改变a的值。
③
const int a = 10;
const int *p = &a;
int **q=&p;//error
因为对q解引用一次跳到p,*p就会出错。在第三局最前面加一个const即可。
④
int a = 10;
int *p = &a;
int *const *q = &p;
正确。*q被const修饰,所以p不能被间接被修改,但是它自身可以修改。
四、const与形参列表的结合
void func1(const int *a)
{
cout<<typeid(a),name()<<endl;//打印参数类型
}
void func2(int *a)
{
cout<<typeid(a),name()<<endl;
}
void func3(int *const a)
{
cout<<typeid(a),name()<<endl;
}
void main(){
int a=10;//调用第二个func函数,因为a的值可以修改
//const int a=10;//调用第一个func函数
func(&a);
}
func1,func2是函数重载,func1中的a不可变,func2中的a可变。
func2,func3不是函数重载,因为形参中的a都是可以改变的。
如果两个形参类型是:const int*和int*,那么就是两个不同形参。
如果两个形参类型是:const int和int,这是两个一样的形参。
注意:不能返回局部变量的指针和引用
五、const与返回值、指针、引用的结合
int sum()
{
int tmp = 10;
return tmp;
}
int *sum()
{
int tmp = 10;
return tmp;
}
int main()
{
int &b = sum();//有寄存器带回返回值,寄存器是没有地址的
int *const &p = sum();
int *&p = sum();//errror -->int **p = &sum();相当于给一个立即数取地址,所以出错,立即数是不能取地址的
}