【C++】 const补充

一、局部变量

 笔记主要记录对const的一些深入理解,C语言中的const只是让变量变为只读属性,其本质还是变量,不是真正意义上的常量(只有enum枚举定义的才是常量).
注意:语法来讲const变量不能被直接赋值,但是由于const局部变量会存在栈里,可以通过指针来修改const变量.这种操作被称为未定义的行为,即不同的编译器可能结果不一样,所以不太建议修改这样操作。

C中const
#include <stdio.h>
int main()
{
    const int c = 0; //const局部变量

    int* p = (int*)&c;
    *p = 5;          //通过指针修改const变量

    printf("c = %d  *p = %d\n", c,*p); //c = 5  *p = 5
    printf("&c = %p  p = %p\n", &c,p); // &c = 000000000061FE14  p = 000000000061FE14
    return 0;
}
  • 在C中,const局部变量是在栈中,所以通过地址去修改可以修改,并且再次读取读的也是栈中修改后的数据。
C++中const
#include <stdio.h>
int main()
{
    const int c = 0; //const局部变量

    int* p = (int*)&c;
    *p = 5;          //通过指针修改const变量

    printf("c = %d  *p = %d\n", c,*p); //c = 0  *p = 5
	printf("&c = %p  p = %p\n", &c,p); //&c = 000000000061FE14  *p = 000000000061FE14
    return 0;
}
  • 在C++中,多了一个符号表,const变量在预处理时处理,编译器只对其值读取一次 。当遇到&符号时,会将其在栈中重新分配空间,p所修改的地址是分配空间的值,但是符号表中c的值并未改变,但是如果加上volatile关键字修饰,则每次使用都重新读取(打破只读取一次的限定),不让编译器优化,此时c的值就是修改后的值,此时就退化成C语言中的情况。

二、全局变量

C/C++ 全局const
#include <stdio.h>
const int c = 0; //const全局变量
int main()
{
    int* p = (int*)&c;
    *p = 5; //修改const变量 段错误
    printf("c = %d\n", c);
    return 0;
}

全局变量而言没有不同,因为const修饰的全局变量在编译后会存储在只读区域,如果使用指针修改的话只读区域的数据时会发生段错误。

三、const与define

 上面提到C++中const会在预处理时处理,此时就容易想到和define功能类似。但是他两还有一定的区别。

  • const常量: 由编译器处理,它会对const常量进行类型检查和作用域检查
  • define宏定义: 由预处理器处理,直接进行文本替换,不会进行各种检查
作用域检查
#include <stdio.h>
void f()
{
#define a 3        //定义宏
	const int b = 4; //定义局部变量
}

int main()
{
	f();
	printf("a=%d", a); //文本直接替换不进行作用域检查

	//printf("b=%d",b); //b的作用域在f函数内
	return 0;
}
posted @ 2022-01-26 16:06  一半丶  阅读(28)  评论(0编辑  收藏  举报