const
LaLaLaLaLaLaLaLaLaLa~~~~~~~~,zzg给我讲了一晚上。。。。。。。。。
一、C语言中的const
1.在c语言中 ,const关键字修饰的变量称为常变量(即就是不具有常量性)。
const int a = 10;
int arr[a] = { 0 }; //err
2.数据类型对const而言是透明的
int a = 10;
const int *p = &a;//1
int const *q = &a;//2
其中指针变量p和q均用const关键字来修饰,1和2效果都是一样的,因为数据类型与const修饰的内容无关,即const主要作用的是它所修饰的内容。
3.const修饰它的直接右边,不能做左值(即放在赋值运算符左边)
const int a = 10;
a = 20; //err
const int *p = &a;
*p = 20; //err
通俗来讲,c语言中用const修饰的变量的属性为只读,不允许修改,而赋值运算符的左值是可修改的。
4.权限可以同等或者缩小传递,但不能放大传递(因为放大权限将意味着会被修改,不安全)。注:不允许泄漏常量的地址给非常量的指针
int a = 10;
int *p1 = &a;
const int *p2 = &a;//const修饰的是*p2,p2指向可以改,但是指向的值不能改变
int *const p3 = &a;//const修饰的是p3,p3指向不可以改,但是指向的值可以改变
int *q1 = &a;
const int *q2 = &a;
int *const q3 = &a;
q1 = p1; //ok 权限相同
q1 = p2; //err const在修饰p2的时候强调不可进行解引用操作
//若将p2赋值给q1,q1本身没有任何限制,
//这就属于放大权限(放大了内存a的使用权限<本身是只读权限>),因而会出错
q1 = p3; //ok 互不干扰,因为没涉及到任何修改的操作
q2 = p1; //ok 缩小权限
q2 = p2; //ok 权限相同
q2 = p3; //ok 互不干扰,涉及到的修改操作彼此独立
q3 = p1; //error 与第3条不符
q3 = p2; //error 与第3条不符
q3 = p3; //error 与第3条不符
二、C++中的const
1.c++中const关键字修饰的变量是一个常量,值不允许改变;
const int a = 10;
int arr[a] = { 0 }; //ok
原因在于编译器在编译期的时候将使用该常量值的地方替换成了常量的值。既然是一个常量,就必须初始化,因为以后没机会对其进行赋值操作,或者说它不能作为左值。
const int a; //err 必须初始化
2.const修饰的数据产生的符号是local的,对外不可见。
fun.cpp
const int A = 10;
main.cpp
#include<iostream>
using namespace std;
extern const int A;
int main()
{
cout << A<< endl;
}
出现无法解析的外部命令的错误提示,存在以下两种可能:
(1)不存在
(2)存在没法用(local)
很显然,在这里是第二种情况。
3.c++中用const修饰的变量是一个常量,但在特殊情况(编译器无法确定其值的时候)下它会退化成常变量。
int a = 10;
const int b = a;
int arr[b] = { 0 }; //err 此处的b已经退化为常变量
如果数据类型本身并不是指针,则可以将const数据或非const数据的地址赋给指向const数据的指针(例:const int *p),但是只能将非const数据的地址赋给非const指针(例如:int * const p,因为C++规定不能泄露非常量地址给常量指针)
附上zzg考我的他所谓的测试用例,让我判断对错QAQ。。。。。。。。
const int a = 10;
int b = 20;
const int *p = &a;//ok 对应将const数据的地址赋给指向const数据的指针
//具体就是对于a它仅仅是只读的,p不能解引用,所以这两个互不影响
const int *p = &a;//ok 对应将非const数据的地址赋给指向const数据的指针
//具体就是对于a它可读可写,p不能解引用,这是缩小内存a的使用权限了
int * const m = &b;//err
int * const m = &b;//ok 对应将非const数据的地址赋给非const指针
上一篇: Python基础练习题(2)
下一篇: Arduino 中文转UTF-8