假设C字符串是以空结尾的字符数组:

const char str1[] = {"abc"};
const char str2[] = {'a', 'b', 'c', '\0'};
const char str3[] = {97, 98, 99, '\0'};

都是一样的.

那么,为什么可以生成这样的字符串数组:

const char * str_arr[] = {"abc", "ABCD"};
const char * str_arr[] = { str1, str2, str3 };

但不是这样的?:

const char * str_arr[] = { {'a', 'b', 'c', '\0'}, {'A', 'B', 'C', 'D', '\0'} };
fatal error: excess elements in scalar initializer

推荐答案

const char str1[] = {"abc"};
const char str2[] = {'a', 'b', 'c', '\0'};
const char str3[] = {97, 98, 99, '\0'};

这些操作是因为C 2018 6.7.9中有关如何处理初始值设定项的规则:

  • const char str1[] = {"abc"};中,给出一个字符串文字来初始化包含const char的array.6.7.9 14表示"字符类型的数组可由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来.字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素."
  • const char str2[] = {'a', 'b', 'c', '\0'};中,给出了一个包含int个值(字符常量的类型为int)的列表来初始化array.6.7.9 17告诉我们,它们用于按顺序初始化数组的子对象(其元素).
const char * str_arr[] = {"abc", "ABCD"};
const char * str_arr[] = { str1, str2, str3 };

对于这些项目:

  • const char * str_arr[] = {"abc", "ABCD"};中,字符串列表用于初始化指针array.请注意,这不是用大括号括起来的a个字符串文字;而是two个字符串文字,因此它与上面的规则不匹配.对于使用字符串文字来初始化指针数组而不是字符类型的数组,没有特殊的规则,因此使用C的其他规则来处理它,并且两个字符串文字初始化数组的两个元素.字符串文字指定一个字符array.6.3.2.1 3表示,当数组不是sizeof的操作数、一元&的操作数或用于初始化数组的字符串文字时,它将被转换为指向其第一个元素的指针.因此,这两个数组中由字符串文字指定的每个数组都被转换为指向其第一个元素的指针,这些指针成为str_arr的初始值.
  • const char * str_arr[] = { str1, str2, str3 };str1str2str3中是array.如上所述,它们被自动转换为指向它们的第一个元素的指针,并且这些指针被用来初始化str_arr.
const char * str_arr[] = { {'a', 'b', 'c', '\0'}, {'A', 'B', 'C', 'D', '\0'} };

为此,str_arr的每个元素都是const char *,为它提供的初始值设定项是{'a', 'b', 'c', '\0'}.C中没有规定const char *可以用大括号中的int个值的列表进行初始化.当{'a', 'b', 'c', '\0'}出现在初始值设定项中时,它作为数组没有任何特殊意义.它只是一个值的列表.如何处理该值列表取决于初始化的上下文.如果有要填充的数组,则可以使用列表中的值来填充数组元素.但是没有数组,也没有规则规定将这个值列表组成一个数组,并创建一个指向该数组的指针.

C++相关问答推荐

与unions 的未定义行为

在C中使用JMP_buf数组进行线程化(在xv6中测试)

有没有更简单的方法从用户那里获取数据类型来计算结果

为什么在此程序中必须使用Volatile关键字?

特定闪存扇区的内存别名

如何在c++中包装返回空*的函数

如何将字符**传递给需要常量字符指针的常量数组的函数

如何使用C for Linux和Windows的标准输入与gdb/mi进行通信?

在为hashmap创建加载器时,我的存储桶指向它自己

整型文字后缀在左移中的用途

在C++中访问双指针

RawMotion的XInput2错误(具有较高值的XISelectEvents上的BadValue)

如何使用C++在控制台中以彩色打印被阻止的客户端

当b是无符号字符时,int a=(b<;<;2)>;>;2;和int a=b&;0x3F;之间有什么区别?

当内存来自Malloc时,将char*转换为另一个指针类型是否违反了严格的别名规则?

如果格式字符串的内存与printf的一个参数共享,会发生什么情况?

正在try 理解C++中的`正在释放的指针未被分配‘错误

为什么会出现此错误?二进制表达式的操作数无效

在我的第一个C语言中观察到的错误';你好世界';程序

为什么写入关闭管道会返回成功