聊一聊const和static限定符

const 是常量限定符,被const修改的变量,为其分配内存时,且同时必须为其值进行初始化。其后不能再被修改。
例如:
const int a;
当a定义在函数外时,即为全局变量时,那么 a为自动被初始化为0。
当a定义在函数内,即为局部变量时,那么const int a = 右值;//这样显示初始化才行。否则编译不过。

void func_1() {
    
    
	const int d = 10;
	int* j = (int*)&d;
	*j = 1;
	cout << __func__ << ": " << " d = " << d << ", *j = " << *j << endl;//func_1:  d = 10, *j = 1
}

代码分析:
const int d = 10;//这种定义的常变量,会在编译期被优化为,作用域范围内使用到变量d的地方,都替换为整型字面值10,但是对于对变量d取地址的地方不会被替换。
int* j = (int*)&d;//强制将常变量的地址类型,转为非常量类型指针。指针j指向常变量d。这是一种危险的做法,不建议。编译对上一句代码的优化,也是为防止会出现强制的情况。
*j = 1; //修改常变量d的值。
输出语句中的变量d,在编译阶段已被替换为了10。这就是为啥即使修改d中的值为1,打印出来的还是10.
在这里插入图片描述

void func_2() {
    
    
	int b = 10;
	const int d = b;
	int* j = (int*)&d;
	*j = 1;
	cout << __func__ << ": " << " d = " << d << ", *j = " << *j << endl;//func_2:  d = 1, *j = 1
}

const int d = b;//这种情况下d的值只有执行func_2()时才能确定,所以这里在编译期不会对其作用域范围内其他地方使用到变量d的地方进行替换。
所以最后,输出语句中打印的d是修改之后的。
在这里插入图片描述
注意:const修饰符,一般拥有修饰函数的形参,还有定义全局常量时用到。一般不会在函数内部来修饰变量使用。
在函数内部一个变量 虽然被const修饰符修饰,那他仍然是一个在栈上的局部变量。函数执行完毕后,它的内存也就是被释放了。

void func_3() {
    
    
	int a = 6;
	static int c = 7;
	const int d = 10;
	printf("地址a: %p\n",&a);
	printf("地址c: %p\n",&c);
	printf("地址d: %p\n",&d);
}
int main()
{
    
    
	func_3();//第一次调用
	func_3();//第二次调用
}

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/adminstate/article/details/134922727
今日推荐