C++对C的扩展2:C/C++中的const
const基础知识(用法、含义、好处)
const单词字面意思为常数,不变的。它是c/c++中的一个关键字,是一个限定符,它用来限定一个变量不允许改变,它将一个对象转换成一个常量。
const int a = 10;
A = 100; //编译错误,const是一个常量,不可修改
初级理解:const是定义常量 >>> const意味着只读
含义:
int main()
{
const int a; //代表一个常整形数
int const b; //代表一个常整形数
const int *c; // c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
int * const d; //d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
const int * const e ; //e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)
return 0;
}
Int func1(const )
const好处:
- 指针做函数参数,可以有效的提高代码可读性,减少bug;
- 清楚的分清参数的输入和输出特性
int setTeacher_err( const Teacher *p )
const修改形参的时候,在利用形参不能修改指针所向的内存空间
C/C++中const的区别
C中的const
c中的const理解为”一个不能改变的普通变量”,也就是认为const应该是一个只读变量,既然是变量那么就会给const分配内存,并且在c中const是一个全局只读变量,c语言中const修饰的只读变量是外部连接的。
const int arrSize = 10;
int arr[arrSize];
看似是一件合理的编码,但是这将得出一个错误。 因为arrSize占用某块内存,所以C编译器不知道它在编译时的值是多少?
C++中的const
在c++中,一个const不必创建内存空间,而在c中,一个const总是需要一块内存空间。 在c++中,是否为const常量分配内存空间依赖于如何使用。
如果存储空间没有分配内存的话,在进行完数据类型检查后,为了代码更加有效,值也许会折叠到代码中。
不过,当取一个const地址, 或者把它定义为extern,则会为该const创建内存空间。
在c++中,出现在所有函数之外的const作用于整个文件(也就是说它在该文件外不可见),默认为内部连接,c++中其他的标识符一般默认为外部连接。
int main()
{
const int a = 10; //C++编译器将const变量变成符号表,以键值对的形式存在
int *p = (int*)&a; //C++中会新开辟一个空间,而原空间的a则始终没有改变
printf("a===>%d\n", a);
*p = 11;
printf("a===>%d\n", a);
printf("Hello......\n");
return 0;
}
编译过程中若发现使用常量则直接以符号表中的值替换
编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)
注意:
C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值
const和#define
C++中的const修饰的,是一个真正的常量,而不是C中变量(只读)。在const修饰的常量编译期间,就已经确定下来了。
对比加深:
- C++中的const常量类似于宏定义
- const int c = 5; ≈ #define c 5
- C++中的const常量与宏定义不同
- const常量是由编译器处理的,提供类型检查和作用域检查
- 宏定义由预处理器处理,单纯的文本替换
结论:
C语言中的const变量:
- C语言中const变量是只读变量,有自己的存储空间
C++中的const常量:
- 可能分配存储空间,也可能不分配存储空间
- 当const常量为全局,并且需要在其它文件中使用,会分配存储空间
- 当使用&操作符,取const常量的地址时,会分配存储空间
- 当const int &a = 10; const修饰引用时,也会分配存储空间
C/C++中const异同总结
C语言全局const会被存储到只读数据段。C++中全局const当声明extern或者对变量取地址时,编译器会分配存储地址,变量存储在只读数据段。两个都受到了只读数据段的保护,不可修改。
const int constA = 10;
int main(){
int* p = (int*)&constA;
*p = 200;
}
以上代码在C/C++中编译通过,在运行期,修改constA的值时,发生写入错误。原因是修改只读数据段的数据。
C语言中局部const存储在堆栈区,只是不能通过变量直接修改const只读变量的值,但是可以跳过编译器的检查,通过指针间接修改const值:
const int constA = 10;
int* p = (int*)&constA;
*p = 300;
printf("constA:%d\n",constA);
printf("*p:%d\n", *p);
运行结果:
C语言中,通过指针间接赋值修改了constA的值。
C++中对于局部的const变量要区别对待:
- 对于基础数据类型,也就是const int a = 10这种,编译器会进行优化,将值替换到访问的位置。
const int constA = 10;
int* p = (int*)&constA;
*p = 300;
cout << "constA:" << constA << endl;
cout << "*p:" << *p << endl;
运行结果:
- 对于基础数据类型,如果用一个变量初始化const变量,如果const int a = b,那么也是会给a分配内存。
int b = 10;
const int constA = b;
int* p = (int*)&constA;
*p = 300;
cout << "constA:" << constA << endl;
cout << "*p:" << *p << endl;
运行结果:
constA 分配了内存,所以我们可以修改constA内存中的值。
- 对于自定数据类型,比如类对象,那么也会分配内存。
const Person person; //未初始化age
//person.age = 50; //不可修改
Person* pPerson = (Person*)&person;
//指针间接修改
pPerson->age = 100;
cout << "pPerson->age:" << pPerson->age << endl;
pPerson->age = 200;
cout << "pPerson->age:" << pPerson->age << endl;
运行结果:
为person分配了内存,所以我们可以通过指针的间接赋值修改person对象。
1. C中const默认为外部连接,C++中const默认为内部连接
2. 当C语言两个文件中都有const int a的时候,编译器会报重定义的错误。
3. 而在c++中,则不会,因为C++中的const默认是内部连接的。
4. 如果想让C++中的const具有外部连接,必须显示声明为: extern const int a = 10;