c++用关于const变量的疑问

问题描述

c++用关于const变量的疑问

首先看下面一段代码:

 #include <iostream>

using namespace std;

int
main()
{
    const int i = 10;

    int *pi = const_cast<int *>(&i);
    ++*pi;
    cout << "  i = " << i << ", @" << &i << endl;
    cout << "*pi = " << *pi << ", @" << pi << endl;

}

运行结果是:

i = 10, @0x28ff44

*pi = 11, @0x28ff44

我想问的是,变量 i 的值到底有没有被改变?问什么同一个地址输出的值不一样?

解决方案

这里是编译器决定的,你用VS2008调试就会发现,i的值在调试窗口里都是变化了的。但是const表示的是一个常量,不可变的,如果用const-cast又可将它改变,就自相矛盾了。
于是编译器采取了一种方案,在汇编里可以看出端倪:

    cout << "  i = " << i << ", @" << &i << endl;
004142B8  mov         esi,esp
004142BA  mov         eax,dword ptr [__imp_std::endl (41A348h)]
004142BF  push        eax
004142C0  mov         edi,esp
004142C2  lea         ecx,[i]
004142C5  push        ecx
004142C6  push        offset string ", @" (417880h)
004142CB  mov         ebx,esp
004142CD  push        0Ah
004142CF  push        offset string "  i = " (417878h)
004142D4  mov         edx,dword ptr [__imp_std::cout (41A34Ch)]
004142DA  push        edx

10是直接使用的(见上面的push 0Ah),并不是按我们的惯性思维从地址里去取的。

解决方案二:

如果在 i 的定义前增加 volatile ,则可以看到最后的输入结果: i =11;

{
volatile const int i = 10;

    int *pi = const_cast<int *>(&i);
    ++*pi;
    TRACE("i = %d;@i = 0x%xrn",i,&i);
    TRACE("pi = %d,@pi = 0x%xrn",*pi,pi);

    TRACE("rn");
}

输出为:
i = 11;@i = 0x12edb0

pi = 11,@pi = 0x12edb0
以上为 VS2005 编译、运行的结果。

解决方案三:

const_cast并不允许修改原来的常量值,c++里const_cast转换一个常量值的结果是未定义,i的值并不会改变,而pi里的值是个随机的值

解决方案四:

从 VS2008 编译器的内存来看,这个地址 0x28ff44 的值已经是 11 了。

应该是 VS2008 等 编译器做了处理,i 是不可变的,在输出 i 时并没有从内存中去读取数据。

解决方案五:

变量i的值应该是不变的吧

解决方案六:

你的i地址发生了强制转换了。。。

解决方案七:

我将程序在vs2012和g++上都试了,它们结果一样的。很明显我们可以肯定,使用const_cast可以返回一个非常量指针指向常量。
并且可以改变常量的值,即原来存放该常量的地址的内容被改变。要确保不出错就应该使用对返回的指针的解引用,而不要再去使用原来存放常量的那个变量(常量)。

解决方案八:

如果const int i = 10;定义成全局的,或前缀static。您再如此这般的试一试。嘿嘿!

时间: 2024-10-03 03:01:52

c++用关于const变量的疑问的相关文章

求C语言高手解惑,一个关于const变量定义数组大小问题

问题描述 求C语言高手解惑,一个关于const变量定义数组大小问题 我在函数的外部定义了一个BlockSize,然后又定义了一个结构(两者都是在函数外部).编译的时候,出现一个error.提示说:variably modified 'array' at file scope const int BlockSize = 20;//define BlockSize 20typedef struct _node { int array[BlockSize]; struct _node* next;}N

浅谈const变量赋值报错分析_C 语言

从变量到常量的赋值是合法C++的语法约定的, 如从char 到const char顺畅: 但从char **到 const char **编译器就会报错: 复制代码 代码如下: error: invalid conversion from `char**' to `const char**' 示例: int main(int argc, char *argv[]) { char a = '1'; const char b = a; char * a2 = "12345"; const

关于C/C++ const变量 const指针 以及C++ 引用变量的解析

 关于C/C++ const变量 const指针 以及C++ 引用变量的解析    首先我们知道const表示一个不能更改的值,在程序中往往使用这种属性来保证安全,但是这种操作在C和C++中却不同  我测试中C++不能用MEMCPY进行更改但是C却可以  其中我们常见的  const int a = 10;一个常量,不能更改其a的值  const int *p1;一个指针但是他的返回值是const int类型  如我们可以  p = &a;  int* const p;一个指针,这个指针在整个生

c++中const变量问题的简单分析

常变量:  const 类型说明符 变量名 常引用:  const 类型说明符 &引用名 常对象:  类名 const 对象名 常成员函数:  类名::fun(形参) const 常数组:  类型说明符 const 数组名[大小]    常指针:  const 类型说明符* 指针名 ,类型说明符* const 指针名 首先提示的是:在常变量(const 类型说明符 变量名).常引用(const 类型说明符 &引用名).常对象(类名 const 对象名). 常数组(类型说明符 const 数

const的相关,修改定义的变量

问题描述 const的相关,修改定义的变量 const int a;与const int*piint *const pi;是不是不一样啊,前面的那个a的值不能通过a=8:和pi=&a的形式来修改吧,但是后面的那2个可以通过这两种中的一种修改的把,比如const int*pi中,不能对*pi进行修改,但是可以对pi进行重新赋值啊,这样不就间接改了*pi了吗,是这样的吗 解决方案 const int * pi 和const char * p是一样的,都是说明不能直接对指针指向的地址赋值,而可以修改指

const extern static

const const最好理解,修饰的东西不能被修改 指针类型根据位置的不同可以理解成3种情况: I 常量指针 // 初始化之后不能赋值,指向的对象可以是任意对象,对象可变. NSString * const pt1; II 指向常量的指针 // 初始化之后可以赋值,即指向别的常量,指针本身的值可以修改,指向的值不能修改 const NSString * pt2; III 指向常量的常量指针 const NSString *  const pt3; extern 等同于c,全局变量的定义, //

strcpy-自己对一个const定义的数组不能更改,用库函数却能进行相应操作,

问题描述 自己对一个const定义的数组不能更改,用库函数却能进行相应操作, 自己对一个const定义的数组不能更改,用库函数却能进行相应操作,比如strcpy(),其实现也是一个个赋值的,为什么自己用赋值语句就不行呢?有点疑问,没搞清楚,请大侠帮小弟解解惑,感激不尽. 前提我是知道const的含义的,知道其用法的. 解决方案 http://blog.csdn.net/heyabo/article/details/8745942根据C++标准,对于修改const变量,属于:未定义行为(指行为不可

C++中const的运用

(1)欲阻止一个变量被改变,可以使用const关键字.在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了: (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const: (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值: (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量: (5)对于类的成员函数,有时候必须指定其返回值为con

C语言中正确使用const

基本解释 const是一个C语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助. 虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题. 问题:const变量 & 常量 为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢? const int n = 5; int a[n]