如何修改const常量值
总结:这个跟计算机语言类别和编译器有关,本文是在linux环境下说明的.
分两种情况:
1. C语言:
2. C++语言:
/*! * \Description:
* \author scictor <scictor@gmail.com> * \date 3 */ #include <stdio.h> ;// 常量数据区,只读,指针修改导致程序Segmentation fault.conststring myglobal("global"); //const_cast方式修改,不会引起崩溃.
int main(int argc, char *argv[])
{
int *pg_i = (int *)&g_i;
*pg_i = ;
printf("%p %d %p %d\n", &g_i, g_i, &pg_i, *pg_i); string* p=const_cast<string*>(&myglobal); *p="local";//这里强行改变了值 printf("%s\n",myglobal.c_str());
;
int *pa = (int *)&a;
*pa = ;
printf("%p %d %p %d\n", &a, a, pa, *pa);
;
int *pi = (int *)(&i);
*pi = ;
printf("%p %d %p %d\n", &i, i ,pi, *pi);
;
}
/*
1.对于C语言:
先看结果:
$ gcc -g -Wall const.c -o xmain
$ ./xmain
0x7fff0146a9f8 3 0x7fff0146a9f8 3
0x7fff0146a9fc 32 0x7fff0146a9fc 32
解释:
const数据放在常量数据区(constant segment),应用程序结束后,由操作系统释放.
C标准规定,对于修改const变量属于未定义行为.
2.对于C++语言而言:
先看结果:
$ g++ -g -std=c++11 -Wall const.cpp -o xmain
$ ./xmain
0x7fffed0c89c8 10 0x7fffed0c89c8 3
0x7fffed0c89cc 32 0x7fffed0c89cc 32
解释:
根据C++标准,对于修改const变量,属于:未定义行为(指行为不可预测的计算机代码),这样一来此行为取决于各种编译器的具体实现(即不同编译器可能表现不同)。
没有加volatile修饰符,即此处编译器进行了优化,没有从内存中读,直接从符号表中取出的.
结果表现为:指针 pa 和 &a(a的地址)值却是一样的,但输出结果不同.
这就是C++中的常量折叠:指const变量(即常量)值放在编译器的符号表中,计算时编译器直接从表中取值,省去了访问内存的时间,从而达到了优化。
而在此基础上加上volatile修改符,即告诉编译器该变量属于易变的,不要对此句进行优化,每次计算时要去内存中取数.
总结:
修改const常量值受到以下因素影响:
实质原因:
C和C++语言标准规定不同(存储位置不同,不同限定关键字和读取规则不同):
在C语言中,用const定义的常量其实是值不能修改的变量,因此会给它分配存储空间,c++的编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高.
*/
如何修改const常量值的更多相关文章
- Java 反射修改类的常量值、静态变量值、属性值
前言 有的时候,我们需要修改一个变量的值,但变量也许存在于 Jar 包中或其他位置,导致我们不能从代码层面进行修改,于是我们就用到了下面的场景,通过反射来进行修改变量的值. 定义一个实体类 class ...
- C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值
接收拦截+发送消息 对于处理所有消息.net 提供了wndproc进行重写 WndProc(ref Message m)protected override void WndProc(ref Mess ...
- WMsg参数常量值
//WMsg参数常量值: //创建一个窗口 const int WM_CREATE = 0x01; //当一个窗口被破坏时发送 const int WM_DESTROY = 0x02; //移动一个窗 ...
- 【转】C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值(1)
C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值(1) #region 截获消息 /// 截获消息 处理XP不能关机问题 protected ...
- 【C++编程基础】(1)—— 函数原型声明、函数模板、引用、const 常引用、const 常量指针
一.函数原型声明: 1.函数声明告诉编译器函数的名称,和如何调用函数(返回类型和参数):函数定义提供了函数的实际主体. 2.强制性的:在C++中,如果函数调用的位置在函数定义之前,则要求在函数调用之前 ...
- Java 常量值的数据类型
Java 常量值(也叫字面量)和变量一样,也是有数据类型的. 经常有面试题考察你对 Java 常量值数据类型的理解,如下: float a = 3.3; 问你这一行代码是否正确?答案肯定是不正确.为什 ...
- 无法创建“Sunlight.Silverlight.Dcs.Web.PartsSupplier”类型的常量值。此上下文仅支持基元类型或枚举类型问题
今天写代码遇到一个问题, const string SCODE = "123"; var suppliers = PartsSuppli ...
- Map生成器 map适配器如今能够使用各种不同的Generator,iterator和常量值的组合来填充Map初始化对象
Map生成器 map适配器如今能够使用各种不同的Generator,iterator和常量值的组合来填充Map初始化对象 package org.rui.collection2.map; /** * ...
- C++中如何修改const变量
一.结论 声明:不同于C语言的const变量修改问题(可以通过指针间接修改const变量的值),这里只讨论C++ 里的const. C++ const 修饰符,表示常量,即如果以后保证不会修改则声 ...
随机推荐
- Java连接RabbitMQ之创建连接
依赖包: <dependencies> <dependency> <groupId>junit</groupId> <artifactId> ...
- PCIE\AURORA\SRIO协议对比
http://www.eefocus.com/communication/335836/p3
- Opencv画图操作
1. 画矩形 MyRect rect;rect.left = 5;rect.top = 5;rect.right = 100;rect.bottom = 100;IplImage * pColorIm ...
- [UOJ86]mx的组合数——NTT+数位DP+原根与指标+卢卡斯定理
题目链接: [UOJ86]mx的组合数 题目大意:给出四个数$p,n,l,r$,对于$\forall 0\le a\le p-1$,求$l\le x\le r,C_{x}^{n}\%p=a$的$x$的 ...
- DRF 版本和认证
Django Rest Framework 版本控制组件 DRF的版本 版本控制是做什么用的, 我们为什么要用 首先我们要知道我们的版本是干嘛用的呢~~大家都知道我们开发项目是有多个版本的~~ 当我们 ...
- IOS端 margin-top 和 margin-bottom 使用负数时的区别
有以下html代码 <div style="width: 30%;" class="shang"> 1 </div> <div s ...
- python学习日记(2/3区别,环境,变量,数据类型以及简单习题)
Python2 与 python3 的区别: python2源码不标准,混乱,重复代码太多 python3统一标准,去除重复代码 python2的默认编码方式是ASCII码,不能识别中文.解决方法:在 ...
- 【题解】 bzoj2982: combination (Lucas定理)
题面戳我 Solution 板子题 Code //It is coded by ning_mew on 7.25 #include<bits/stdc++.h> #define LL lo ...
- a span做成按钮样式不选中文字
a,span做成按钮样式时,文字会被选中.加以下CSS可以让其不选中.测试三大浏览器都可以 .button { display: inline-block; -moz-user-select: non ...
- Swarm stack
什么是 stack ?例如:首先创建 secret. 然后创建 MySQL service,这是 WordPress 依赖的服务. 最后创建 WordPress service. 也就是说,这个应用包 ...