@CrazyHenry
2018-01-26T20:51:46.000000Z
字数 1479
阅读 1235
ccccC++Primer
- Author:李英民 | Henry
- E-mail: li
_
yingmin@
outlookdot
com- Home: https://liyingmin.wixsite.com/henry
快速了解我: About Me
转载请保留上述引用内容,谢谢配合!
首先,我们来看看字面值常量有哪些?
实际上,字面值也是基本类型,只不过都是constant,并且没有名字,都是临时量。临时量只在代码的那一行有效,一旦遇到;
,临时量就会被销毁。比如字面值"Hello"
,就是一个以'\0'
结束的字符数组,并且是一个constant,注意:这个const有可能是顶层const,也有可能是一个底层const。
比如字面值42
,就是一个具有顶层const的整型字面值常量!
而"Hello"
就不一定了!具体看如下的分析:
在学习const关键字的时候,我们知道=
左侧的对象如果没有底层const,右侧一定不能有底层const:
const int a = 0;
int *p = &a;//error,不能将const int *转换为int *
所以,当"Hello"
作为字面值的时候,虽然字面值本身是一个常量数组,但是,由于C++
的特殊性,数组在作为=
的右侧对象时,一般都会转换为指向首元素的指针(除了左侧是个引用类型对象/\以及初始化数组的时候)!由于数组是个常量数组,所以其首元素的指针必定有底层const。这样,这个字面值就拥有底层const了!而就如上面所说的:=
左侧的对象如果没有底层const,右侧一定不能有底层const。如果右侧具有底层const,左侧必须具有底层const:
char *p = "Hello";
//error,因为"Hello"在这个时候会转换为指向常量字符'H'的指针,因此该指针的类型是const char *。所以这种情况下,该语句不是合法的。但是,由于一些编译器的特性,该语句只会提示一个warning,实际上,让一个普通的指针,指向一个常量是非常危险的!因为,一旦这个时候,你使用解引用*p改变字符串字面值的内容,就会使程序崩溃!
比如下面的代码就会崩溃:
char *p = "Hello";
*p = 'A';//执行之后,程序崩溃
正确的做法有两种:
//方法1:
const char *p = "Hello";
//这种做法就是真的让p拥有一个底层const,这样再解引用*p就会被编译器发现!防止程序崩溃。
//方法2:
char a[] = "Hello";//这时,"Hello"也不会转换为指针,具有顶层const
char *p = a;//a会转换为指向'H'的指针,由于这时的'H'已经不是常量,所以指针的类型就是char *,=左边的指针p也不需要底层const了!
字符数组的初始化方式有两种:
方法1:
char a[] = "Hello";
char a[6] = "Hello";
方法2:
char a[] = {'H','e','l','l','o','\0'}
char a[6] = {'H','e','l','l','o','\0'}
注意:
char a[7] = "Hello";//这时a[6]值初始化为'\0'
char a[7] = {'H','e','l','l','o','\0'}//这时a[6]值初始化为'\0'
注意:
char a[] = {'H','e','l','l','o'};//error
char a[5] = "Hello";//error