关于C++中常量的理解

来源:互联网 发布:java开发工程师· 编辑:程序博客网 时间:2024/05/16 17:06

1:在内存中的实际形式

字符常量 实际上是一个整型数,

而字符串常量 实质上的类型是 const char 类型的数组(属于C风格的字符串)

 

2:定义的方式

 旧式的定义方法:宏定义,#define (符号常量名)(常量)

 推荐的定义方式:Const

两者的区别:

Define:除了字符串常量以外,其它的字面值常量都不占用内存空间

一、常量:(不可以定义结构型常量)

 

   常量包括字面常量,符号常量,契约型常量,枚举常量这几种类型。

 

二、字面常量包括:整形常量,字符型常量,字符串常量。注意:不存在数组常量,结构体常量等结构型的字面常量。但是存在结构型的符号常量

 

三、符号常量:(可以定义结构型常量)

 

      #defineconst定义的常量!

 

这两种常量之间的区别:

 

1#define定义的常量,除了字符串字面常量外都不占内存,所以无法取常量的地址,仅仅是宏替换而已

 

eg

#define NAME  “pang dong”        //本质是字符串字面常量,会占用静态存储区

        #define MAX 256           // 本质是整形的字面常量,不会分配内存

 2 const定义的常量要分情况考虑:

     你可以去一个const符号常量的地址:

对于基本数据类型的const常量,编译器会重新在内存中创建一个他的一个拷贝,(真正的基本数据类型的const常量会被编译器放到符号表中而不分配内存空间)你通过其地址访问到的就是这个拷贝而不是原始的符号常量;

而对于构造类型的const常量,实际上他是编译时不允许修改的常量,是占内存空间的,因此如果你能绕过编译器的静态类型安全检查机制,就可以在运行时修改其内存单元。从理论上讲,只要握有一个对象(针对C++中的结构类型常量)的指针,你就可以设法绕过编译器修改它的内存。

 

3:字符串常量的深入理解

C语言中

字符串常量保存在字符数组或字符指针中

C++ 中,字符串常量 可以保存在String 对象中

 

三者的区别:

(1)       保存在数组中:实质为 复制

(2)       字符指针:实质为 将一指针指向一个 Const char* 类型的内存

(3)       String对象:实质也是 复制,但String 对象提供了对字符串更强的操作

 

 

 

????

String str = “hello world”;  赋值以后,“hello world” 这一字符串常量是否还占用内存,它的生命周期到啥时结束??

解答:

"abc"是常量吗?答案是有时是,有时不是。

  不是常量的情况:"abc"作为字符数组初始值的时候就不是,如

                  char str[] = "abc";

    因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为

    字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为

    char str[3] = {'a','b','c'};

                  又根据上面的总结1,所以char str[] = "abc";的最终结果是

    char str[4] = {'a','b','c','/0'};

    做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里

    "abc/0"因为不是常量,所以应该被放在栈上。

 

  是常量的情况:  "abc"赋给一个字符指针变量时,如

                  char* ptr = "abc";

    因为定义的是一个普通指针,并没有定义空间来存放"abc",所以编译器得帮我们

    找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器

    最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译

    通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序

    常量区中的东西。

    记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,

    但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,

    但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'

    话编译器就不会让它编译通过,也就避免了上面说的运行时异常。

    又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc/0"

    放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,

    只不过是它所指向的东西被放在常量区罢了。

原创粉丝点击