C++ 为什么要实现指向字符串的指针数组?

C++ 为什么要实现指向字符串的指针数组?,c++,arrays,pointers,gcc,string-literals,C++,Arrays,Pointers,Gcc,String Literals,我正在尝试使用指针实现字符串数组。下面是我的代码 #include <stdio.h> const int MAX = 4; int main () { char *names[] = { "abcd", "efgh", "ijkl", "mnop", }; int i = 0; for ( i = 0; i < MAX; i++) { printf("Value of names[%d] = %s\n", i, names[i] ); } return 0

我正在尝试使用指针实现字符串数组。下面是我的代码

#include <stdio.h>
const int MAX = 4;
int main () {
char *names[] = {
  "abcd",
  "efgh",
  "ijkl",
  "mnop",
};
int i = 0;
for ( i = 0; i < MAX; i++) {
  printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}

有什么问题吗?

字符串文字在C语言中是不可变的。任何更改字符串文字内容的尝试都会调用

根据定义,字符串的类型为char[],因此,通过将字符串文本分配给char*并不会阻止您编写以静默方式调用UB的代码

关于gcc选项,-Wwrite字符串

-Wwrite字符串

编译C时,为字符串常量指定const char[length]类型,以便将一个常量的地址复制到非const char*指针中会产生警告。这些警告有助于您在编译时找到可以尝试写入字符串常量的代码,但前提是您必须非常小心地在声明和原型中使用const。否则,这只会令人讨厌。这就是为什么我们没有向Wall发出这些警告

所以,你需要写作

 const char *names[] = {
  "abcd",
  "efgh",
  "ijkl",
  "mnop",
 };
同样地


如前所述,在大多数情况下,它可能是不值得的。

字符串文字在C中是不可变的。任何更改字符串文字内容的尝试都会调用

根据定义,字符串的类型为char[],因此,通过将字符串文本分配给char*并不会阻止您编写以静默方式调用UB的代码

关于gcc选项,-Wwrite字符串

-Wwrite字符串

编译C时,为字符串常量指定const char[length]类型,以便将一个常量的地址复制到非const char*指针中会产生警告。这些警告有助于您在编译时找到可以尝试写入字符串常量的代码,但前提是您必须非常小心地在声明和原型中使用const。否则,这只会令人讨厌。这就是为什么我们没有向Wall发出这些警告

所以,你需要写作

 const char *names[] = {
  "abcd",
  "efgh",
  "ijkl",
  "mnop",
 };
同样地


,大多数时候,可能是不值得的。

< P>代码在C中是完全有效的。然而,显然你为不同的语言编译:C++。G++是GNU编译器集合的C++前端。虽然由于.C后缀,它可能仍然使用C模式,但它会启用其他警告

一般来说,您应该使用gcc来编译C代码。在这两种语言中,在任何情况下都避免写入字符串文字。C只是在执行上不那么严格。这就是gcc在默认情况下为C禁用此警告的原因

因此,如果不打算更改数组中的字符串,则应始终将指针指向const char:

这有助于编译器检测对条目的非法写入。您还可以使数组本身为常量:


这样您就无法更改条目。这不仅有助于编译器,而且在一些平台上,微控制器至关重要地将数据存储在非可修改的存储器中。

< P>代码在C中是完全有效的。然而,显然您为不同的语言编译:C++。G++是GNU编译器集合的C++前端。虽然由于.C后缀,它可能仍然使用C模式,但它会启用其他警告

一般来说,您应该使用gcc来编译C代码。在这两种语言中,在任何情况下都避免写入字符串文字。C只是在执行上不那么严格。这就是gcc在默认情况下为C禁用此警告的原因

因此,如果不打算更改数组中的字符串,则应始终将指针指向const char:

这有助于编译器检测对条目的非法写入。您还可以使数组本身为常量:


这样您就无法更改条目。这不仅有助于编译器,而且在一些平台上,微控制器至关重要地将数据存储在非可修改的内存中。

只有在尝试用C++编译器编译代码时,才能得到这些警告。用C编译器,没有警告。可能的复制。你使用扩展名。代码,但是用G++编译,通常用于调用C++代码。对于C,您应该调用gcc。C和C++是不同的语言。只有在尝试用C++编译器编译代码时,才得到这些警告。用C编译器,没有警告。可能的复制。你使用扩展名。代码,但是用G++编译,通常用于调用C++代码。对于C,您应该调用gcc。C和C++是不同的语言。C中的字符串从来没有char *类型!使字符串文本可写是一个坏主意,而且违反了标准。@Olaf删除了该部分以避免误解,该类型显然不是指针,而是数组。谢谢你以书面形式指出这个问题@如果您谈论的是-Wwrite字符串,那么Olaf不会生成字符串文本writeable@M.M我想Olaf是想说不使用常量限定符是违反标准的,因为字符串文字不能被允许变异,即使是偶然的。@M.M:你说得对,这只是一个警告。仍然有一些编译器支持它们
为了与ANSI C之前版本兼容,C中的字符串永远不会使用char*类型!使字符串文本可写是一个坏主意,而且违反了标准。@Olaf删除了该部分以避免误解,该类型显然不是指针,而是数组。谢谢你以书面形式指出这个问题@如果您谈论的是-Wwrite字符串,那么Olaf不会生成字符串文本writeable@M.M我想Olaf是想说不使用常量限定符是违反标准的,因为字符串文字不能被允许变异,即使是偶然的。@M.M:你说得对,这只是一个警告。仍然有一些编译器支持它们,以便与ANSI C之前的版本兼容。
const char *names[] = ...
const char * const names[] = ...