C/C++中的const

一、C中的const

  • 一、局部const变量存放在堆栈区中,会分配内存(也就是说能够经过地址间接修改变量的值)。测试代码以下:
void main() {
 const int a = 10;
 printf("initial a = %d\n", a);
 int *ptr = &a;
 *ptr = 100;
 printf("modify a = %d\n", a);
}
复制代码

运行结果:c++

  • 二、全局const变量存放在只读数据段(不能经过地址修改,会发生写入错误), 默认为外部联编,能够给其余源文件使用(须要用extern关键字修饰)
const int a = 10;
//不能用变量初始化全局const变量,编译器不经过:表达式必须含有常量值
//const int b = a; 
void main() {
	printf("first a = %d\n", a);
	int *ptr = &a;
	//编译器经过,但运行阶段发生写入错误
	*ptr = 100;
	printf("second a = %d\n", a);
}
复制代码

运行结果:express

因为分文件编写,很差呈现,因此在这里不为你们提供c语言全局const变量默认为外部联编的案例。若是各读者有兴趣,可自行尝试。具体步骤以下,可新建一个源文件,而且提供a变量的声明,如:extern const int a。

二、C++中的const

  • 一、普通局部const变量

对于基本类型,以符号表中的数据进行初始化的普通局部const变量,此时不会分配内存,将其放入符号表中,若是对它取地址,则会开辟一个新的空间,也就是说会建立一个临时变量,若是经过地址间接进行修改值不会影响到其自己。测试代码以下:bash

const int a = 10;
	int *ptr = const_cast<int*>(&a);
	*ptr = 100;
	cout <<"a = "<<a << endl;
	cout <<"*ptr = "<<*ptr << endl;
复制代码

运行结果:函数

在这里解释一下上述代码:第二行代码,使用了const(expression),显示转换,这是因为c++比c类型转换更严格。因此须要将 const int * 转换为 int * 才可以进行赋值,而且第二行代码将被隐式转换为以下代码:

int temp=a;
    int *ptr=&temp;
    //因此对指针 ptr 指向的内存空间进行操做,并不会影响到 a。
复制代码

对于基本类型,用变量初始化的普通局部const变量,此时会在堆栈区开辟内存,能够经过地址间接修改值。测试代码以下:测试

int b = 10;
	const int a = b;
	int *ptr = const_cast<int*>(&a);
	*ptr = 100;
	cout << "a = " << a << endl;
	cout << "b = " << a << endl;
	cout << "*ptr = " << *ptr << endl;
复制代码

运行结果:ui

(3)对于自定义类型,都会分配内存,能够经过地址间接修改值this

class Person
{
public:
	Person(int age) { this->age = age; };
	~Person() {};
	int age;
private:
};
int main()
{
	const Person personA(20);
	Person* personPtr = const_cast<Person *>(&personA);
	personPtr->age = 100;
	cout <<"personPtr->age = "<<personPtr->age << endl;
}
复制代码

运行结果:spa

  • 二、普通全局const变量3d

    • 与局部const变量基本相同,只是内存开辟在全局/堆区,对于c++而言,全局const变量默认为内部联编,能够在定义时加extern关键字声明为外部联编。 因为分文件编写很差展现,请读者自行尝试。
  • 三、const 成员变量/成员函数指针

    • const成员变量只能被const成员函数访问

    • const成员函数,可以访问全部成员变量,可是在函数体内不能直接修改变量的值(包括普通成员变量),若是须要在函数体内修改普通成员变量的值,须要在变量定义的前面添加mutable关键字,或者经过地址间接修改。注意:const成员函数只能被该类的const对象访问。测试代码以下:

class Person
{
public:
	Person() {};
	~Person() {};
	void test()const
	{
		//没有加mutable修饰的变量在const成员函数内不能直接修改
		//b = 20;
		//能够经过地址间接修改
		int* Bptr = const_cast<int*>(&b);
		*Bptr = 1000;
		//使用mutable修饰的变量能够经过
		c = 30;
		cout << b << endl;
		cout << c << endl;
	}
private:
	const int a=10;
	int b = 100;
	mutable int c = 20;
};
int main()
{
	Person p;
	p.test();
	return 0;
}
复制代码

运行结果:

三、C/C++中const异同总结

  • c语言全局const会被存储到只读数据段。c++中全局const当声明extern或者对变量取地址时,编译器会分配存储地址,变量存储在只读数据段。两个都受到了只读数据段的保护,不可修改。

  • c语言中局部const存储在堆栈区,只是不能经过变量直接修改const只读变量的值,可是能够跳过编译器的检查,经过指针间接修改const值。

  • c++中对于局部的const变量要区别对待:

    • (1)对于基础数据类型,也就是const int a = 10这种,编译器会把它放到符号表中,不分配内存,当对其取地址时,会分配内存。 a在符号表中,当咱们对a取地址,这个时候为a分配了新的空间,*p操做的是分配的空间,而a是 从符号表得到的值。

    • (2)对于基础数据类型,若是用一个变量初始化const变量,若是const int a = b,那么也是会给a分配内存。

    • (3)对于自定数据类型,好比类对象,也会分配内存。

  • c中const默认为外部链接,c++中const默认为内部链接.当c语言两个文件中都有const int a的时候,编译器会报重定义的错误。而在c++中,则不会,由于c++中的const默认是内部链接的。若是想让c++中的const具备外部链接,必须显示声明为: extern const int a = 10;

以上内容若有错误请联系我进行改正,谢谢!!!

相关文章
相关标签/搜索