[关闭]
@CrazyHenry 2018-01-26T20:51:46.000000Z 字数 1479 阅读 1235

3.x 关于字面值常量

ccccC++Primer


首先,我们来看看字面值常量有哪些?

实际上,字面值也是基本类型,只不过都是constant,并且没有名字,都是临时量。临时量只在代码的那一行有效,一旦遇到;,临时量就会被销毁。比如字面值"Hello",就是一个以'\0'结束的字符数组,并且是一个constant,注意:这个const有可能是顶层const,也有可能是一个底层const。
比如字面值42,就是一个具有顶层const的整型字面值常量!
"Hello"就不一定了!具体看如下的分析:
在学习const关键字的时候,我们知道=左侧的对象如果没有底层const,右侧一定不能有底层const:

  1. const int a = 0;
  2. int *p = &a;//error,不能将const int *转换为int *

所以,当"Hello"作为字面值的时候,虽然字面值本身是一个常量数组,但是,由于C++的特殊性,数组在作为=的右侧对象时,一般都会转换为指向首元素的指针(除了左侧是个引用类型对象/\以及初始化数组的时候)!由于数组是个常量数组,所以其首元素的指针必定有底层const。这样,这个字面值就拥有底层const了!而就如上面所说的:=左侧的对象如果没有底层const,右侧一定不能有底层const。如果右侧具有底层const,左侧必须具有底层const

  1. char *p = "Hello";
  2. //error,因为"Hello"在这个时候会转换为指向常量字符'H'的指针,因此该指针的类型是const char *。所以这种情况下,该语句不是合法的。但是,由于一些编译器的特性,该语句只会提示一个warning,实际上,让一个普通的指针,指向一个常量是非常危险的!因为,一旦这个时候,你使用解引用*p改变字符串字面值的内容,就会使程序崩溃!
  3. 比如下面的代码就会崩溃:
  4. char *p = "Hello";
  5. *p = 'A';//执行之后,程序崩溃

正确的做法有两种:

  1. //方法1:
  2. const char *p = "Hello";
  3. //这种做法就是真的让p拥有一个底层const,这样再解引用*p就会被编译器发现!防止程序崩溃。
  4. //方法2:
  5. char a[] = "Hello";//这时,"Hello"也不会转换为指针,具有顶层const
  6. char *p = a;//a会转换为指向'H'的指针,由于这时的'H'已经不是常量,所以指针的类型就是char *,=左边的指针p也不需要底层const了!

字符数组的初始化方式有两种:

  1. 方法1
  2. char a[] = "Hello";
  3. char a[6] = "Hello";
  4. 方法2
  5. char a[] = {'H','e','l','l','o','\0'}
  6. char a[6] = {'H','e','l','l','o','\0'}
  7. 注意:
  8. char a[7] = "Hello";//这时a[6]值初始化为'\0'
  9. char a[7] = {'H','e','l','l','o','\0'}//这时a[6]值初始化为'\0'
  10. 注意:
  11. char a[] = {'H','e','l','l','o'};//error
  12. char a[5] = "Hello";//error
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注