const char*、char const*和const char const*之间的区别以及字符串存储方式
const char*, char const*, const char const*和string storage这个问题的出现的原因是因为在C/C++中,指针和常量的组合有多种形式,不同的组合表示不同的含义。这可能会导致初学者混淆和困惑。
解决这个问题的方法是记住以下规则:
1. 当const位于*的左边时,表示指针指向一个常量对象。例如,const int * p表示通过指针p无法更改int对象。
2. 当const位于*的右边时,表示指针是一个常量指针。例如,int * const p表示p是一个无法更改的常量指针。
3. 如果在*的两侧都有const,则表示它是一个常量指针,无法通过指针更改对象。例如,int const * const p。
这些规则可以帮助我们理解和记忆不同形式的指针和常量的组合。通过正确理解和使用这些组合,我们可以更好地编写和理解C/C++代码。
const char* , char const* 和 const char const* 是指向常量字符的指针类型,它们的语法上是等价的。指针本身不是const。但是 const char const* 是无效的,因为"const"重复了。这就好像说 "const const int",重复的"const"是无效的。顺序不重要,所以也可以说 "int const int"。
在C99标准中,可以重复使用"const"。但是在C++中,是不允许重复的。
另外,编译器是以一种未指定的方式存储字符串字面量的。但是编译器允许将它们存储在程序的只读部分。因此,您不能对字符串字面量进行写操作。可以保证它们在整个程序生命周期内保持分配(换句话说,它们具有静态存储期)。
在面试中,您应该注意C和C++之间的细微差别。在C99中,如上所述,允许使用"const const int"。在C89和C++中不允许。但是在C++中,如果应用于一个自身是const的typedef,可以引入多余的const:
typedef int const cint; cint const a = 0; // 这个const是多余的!
对于模板参数也是一样的。
问题的原因是对于指针和指向字符的指针的不同声明方式的混淆。这些不同的声明方式涉及到指针的可变性和指向字符的可变性。
解决方法是明确理解每种声明方式的含义和用法。下面是对每种声明方式的解释:
1. const char*:这是一个指向字符(或多个字符)的指针,你可以改变指针的值,但不能改变指针所指向的字符的值。换句话说,这个声明常用于字符串字面值。
2. char const*:这也是一个指向字符(或多个字符)的指针,你可以改变指针的值,但不能改变指针所指向的字符的值。与第一种声明方式相同,这个声明也常用于字符串字面值。
3. const char const*:这个声明是错误的,可能是打算使用第四种声明方式。
4. const char * const:这是一个指向字符(或多个字符)的指针,你不能改变指针的值,也不能改变指针所指向的字符的值。这种声明通常用于全局指针,用于指向不应该被意外改变的字符串字面值。
字符串字面值通常会被存储在代码之后,通常是在一个名为"rodata"的段或部分中。