C++ 之const 与指针
首先const 修饰的变量不能在作为左值,初始化之后不能在修改
- 在C语言中 :const int a = 20 这个a 只能叫做常变量,不能作为数组的大小开辟内存 ,并且通过指针就可以修改 (可以不初始化)
const int a = 20; int *p = (int *) &a; *p = 30
printf("%d ,%d ,%d",a, *p,*(&a)) // 30 30 30
C语言上也只是在语言层面不能在作为左值,通过修改内存,或者汇编,都可以改变其值。
- C++ 中const 必须初始化,叫做常量 可以作为数组大小,开辟内存
const int a = 20; int *p = (int *) &a; *p = 30 printf("%d ,%d ,%d",a, *p,*(&a)) // 20 30 20
原因是 C 与 C++ 编译方式不一样,在C中const 就是当作一个变量来生成指令的, 在C++ 中将 凡是出现常量名字的地方,都被常量初始化值替换了
- 还有一种情况 : int b =20; const int c = b; 此时c 为常变量,退化成C语言中的情况。
const 与 指针
const 与一级指针 :
1 , 不能将一个常量的地址泄漏给一个普通的指针和引用
const 修饰离它最近的类型
例如 : const int *p 离const 最近的是int 那么 const 修饰了 *p 表示 不能解引用 ,但是 p 可以指向其他地址
int const *p 这个和上面一样
int* const p 离const 最近的是int* 那么const 限定了 p 表示可以解引用,但是不能在指向其他地方
const int * const p 这个既不能解引用,也不能指向其他内存
const int a =10 // 此时 a 为常量 const int *p = &a ;// 这样才能接收
//int* const p = &a ;// 错误
总结:
- int * <== const int * (错误)
- const int * <== int * (可以的)
- int* const <== int* (等同于 int* <=== int *)
注意点:
int * p1 =nullptr; int * const p2 = nullptr; cout<<typeid(p1)<<endl; // int * cout<<typeid(p2)<<endl; // int *
int * p3 =p2;(正确的)
如果const 右边没有* 那么const 是不参与类型的,因此两个都是int*
const 与二级指针结合 :
int a =10; int *q = &a; int **p = &q;
const int **p : 离const 最近的是int 那么const 修饰**p 表示 **p 不能被赋值
int * const *p : 离const 最近的是int* 那么const 修饰了*p ,表示* p不能被赋值
int** const p : 离const 最急的是int ** ,那么const 修饰了p 表示p 不能被赋值
结论 :
- int ** <=== const int ** (错误的)
- const int ** < ==== int ** (错误的)
- int ** <=== int* const * (错误的)
- int* const* <=== int ** (正确的)