const —— 一旦赋值便不能被修改的只读变量
1:常量与const
const有数据类型,而常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查。常量的值在编译时已知,而且不需要分配存储;而const需要分配内存
2、const可修饰基本数据类型、指针、类、传递参数、函数
const修饰数据类型与指针
char* const a0; //指针是const类型
char const *a0; //指向的数据是const
const char *a0; //指向的数据是const
原则如下: const修饰的是它左侧的表示类型,如果const在最左侧,则修饰其右侧的表示类型
const修饰类
const对象的成员是不能修改的,const成员函数不可以修改对象的数据,不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。
const传递参数/返回值
将函数传入参数声明为const,禁止函数对其进行修改,在多线程的场景下这是必要的。const返回值可以阻止用户修改返回值,返回值也要相应的付给一个常量或常指针。
const函数
const成员函数不可以修改对象的数据,不管对象是否具有const性质,做到多对象成员的保护
const与常量的使用:
1)提醒编程者,某些值是常量,或该值在程序运行期间是不变的,防止程序员误修改。
2)在多人多模块开发中,头文件引用复杂,模块之间可能会冲突。#define可以重复定义,而const不可以重复定义。如下:
#define PI 3.14;
#define PI 3.1415926;
int const a1 = 10;
//int const a1 = 11;
3)#define宏不支持类型,无法进行类型检测
4)#define宏无法实现const的一些功能。如函数传递const参数,如c++类机制中的const成员的访问性控制。
const变量的存储
int main()
{
const int con_var1 = 3;
int * b = (int *)&con_var1;
*b = 5;
std::cout <<con_var1 << " "<<*b ; //c语言使用printf打印
return 0;
}
在c++编译器中,输出为3;在c编译器中,输出为5
这段代码只是为了分析const存储在哪里,对一个const定义的变量使用指针强制访问是非常无聊的。
在c中,const是存储在栈中的,他会随着内存访问改变而改变。在c++中,没有存储在栈中,而是存储在某一个特定表中,在使用时被装入内存区(栈中),因此即使使用*b = 5把栈区的存储改变,在cout输出时,仍然从特定表中取数据而不是从栈区存储中取数据。
再看一个例子
int v = 3;
const int *ptr_cvalue = &v;
cout << v;
cout << *ptr_cvalue;
v = 5;
cout << v;
cout << *ptr_cvalue;
输出为3,3,5,5 这个实验的目的是为了再次说明,const机制并没有在运行期有任何行为,只是编译期的行为。
假如把const定义为全局变量呢?
int const s1 = 10;
int main()
{
int *p2 = (int *)&s1;
*p2 = 100;
cout << s1 << endl;
}
编译OK,运行会报错。全局变量定义的const存储在数据区,且受保护,*p2 = 100这条语句的执行会引起错误
综上:
1、 在c语言中,const修饰的数据存储在栈区(全局的存储在数据区) ;c++中存储在特定表中,栈区的只是一个类似的copy,被const修饰的属性在表中不会被修改,且调用时从表中区而不是从数据存储区读取。
2、 使用const的目的是不被修改,因此在c语言中,不要使用指针强转去获取const修饰变量
3、 const是在编译的时候被实现的一种数据保护机制,在执行中遇到问题是正常的~~~