const分配内存、伪常量(C++)

只要const可以分配内存,则可以通过指针操作,绕过编译器检测,去修改这个const修饰的变量。
(const修饰的变量叫做常量,会不会觉得很疑惑?常量居然可以修改,其实这不是严格意思的常量,可以称为伪常量

情况1:
当初始化定义在函数内(不是全局)
const int a = 10; // extern const int a = 10 加上extren会分配内存!!!!注意区别
int *p = (int*)&a;
当初始化p指针用来取a的地址的时候才会执行一下操作:
这里的const初始化是没有给a分配内存的,是把a和10写进了符号表里(用key和value保存),并没有给他们分配真正属于他的内存
但是会通过一个临时变量,分配临时内存,内部实现相当于:
int tmp  = a;
int *p = tmp;
p指针指向的是临时内存tmp变量的地址,所以此时修改p指针所指的元素,只是修改的tmp,而不会改变a
换句话说:指针p指向的地址跟a的地址是不相同的,因此不管通过指针p做什么操作,都不会改变a的值,只会改变tmp的值
像这里的a是一个受到保护的常量(c语言中a是伪常量,c++做了增强),因此可以用来初始化数组: int arr[a];

只要是分配内存的变量都可以用指针修改它

情况2:用普通变量初始化const变量,会分配内存
	int a = 10;
	const int b = a;  会分配内存
	int*p = (int *)&b;
	此时可以通过操作p指针来修改b的值,p指向的地址就是b的地址。
	通过操作指针p可以改变b的值
	这样的b是虚伪的常量,因此不能初始化数组:int arr[b]会报错
情况3: 自定义数据类型,加const也会分配内存
class person {
	int m_age;
};
	比如这个自定义的类也算是自定义的数据类型
	void test() {
		 const person p1; //这里的p1会分配内存
不可以改:p1.m_age = 10;//不允许直接修改,这是错误的
可以改:  person *p = (person*)&p1;
	     p1->m-age = 20; //通过指针仍然可以修改const修饰的p1对象
	}

你可能感兴趣的:(const分配内存、伪常量(C++))