「C/C++ 01」volatile关键字 和 修改const修饰的变量

目录

一、修改const修饰的局部变量

二、无法修改const修饰的全局变量

三、volatile关键字

面试题】



一、修改const修饰的局部变量

可以通过指针和强转来修改const修饰的局部变量。

#include <iostream>
using namespace std;

int main(void)
{
    const int a = 1;
    int* pa = (int*)&a;
    *pa = 2;

    cout << a << endl;
    return 0;
}

        以上面的案例来讲const修饰的局部变量a会在编译时进行类似宏替换的预处理(编译器把代码中的局部变量a全都替换为常量1)。但局部变量a仍然存在栈上,a也仍然是一个变量,我们通过强制类型转换把a空间的访问权限扩大后让指针变量pa指向这个空间,此时我们就能通过pa来修改a指向的空间了。

        但是上面代码的结果仍然是1,原因开头就说了:const修饰的局部变量a会在编译时进行类似宏替换的预处理,在运行前代码中的a就被宏替换为了1,所以即使a中的内容已经被修改,答应结果还是为1 。

通过反汇编可观测到这一现象:

二、无法修改const修饰的全局变量

        const修饰的全局变量则更为特殊:它在全局(静态)区中的常量区中。这是一块不允许修改的空间,我们通过指针和强转,让指针变量p指向了这块空间,我们能访问到它,但是不能修改它。


        const 修饰的全局变量是常量,放在常量区中,这是一块不能被修改的区域。而非const修饰的全局变量在全局区中,该区域允许被修改。

三、volatile关键字

        volatile 是 C 和 C++ 中的一个关键字,它告诉编译器不要对该变量的访问进行优化,并且每次对该变量的读写都应该直接从其内存地址中进行。


举个例子:volatile可以阻止编译器在编译时对const修饰的局部变量进行类似宏替换的预处理。所以下面的代码结果和一中代码的结果不一样:

int main()
{
	volatile const int a = 1;
	int* pa = (int*)&a;
	*pa = 2;

	cout << a << endl;
	return 0;
}

通过反汇编也能观察到,a未进行类似宏替换的预处理:

面试题】

以下代码的运行结果是?

#include <iostream>
using namespace std;

int main(void)
{
	const int a = 100;
	int* p = (int*)(&a);
	*p = 200;
	cout << "a = " << a << ", *p = " << *p << endl;
	cout << "&a:" <<   (int*)& a << endl;
	cout << "p:" << p << endl;
	return 0;
}
  • A. 编译或者运行阶段报错
  • B. a = 100, *p = 100
  • C. a = 200, *p = 200
  • D. a = 100, *p = 200
  • E. a = 200, *p = 100

        答案是D,因为代码中的变量a在编译阶段进行类似宏替换的预处理,被替换为1 。而p通过指针+强转强制访问并修改了a所在的空间的内容。


------------------------END-------------------------

才疏学浅,谬误难免,欢迎各位批评指正。 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烛火萤辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值