创建字符数组的方法之间的区别

Difference between methods to create a character array

我很好奇在 C 中创建字符数组的不同方法。假设我们要创建一个包含字符串 "John Smith" 的字符数组。我们可以通过显式提供元素的数量来初始化数组,即

char entireName[11] = "John Smith"; 

其中有四个space代表字符J-o-h-n,一个代表space,五个用于 S-m-i-t-h,一个用于字符串终止符 [=22=]

您也可以通过简单地输入

来完成上述操作
char entireName[] = "John Smith"; 

这两个字符数组由谁编译会有很大的区别吗?是否为两个表达式分配了相同数量的内存,并以相同的速度执行?

真正的区别是什么?

两者之间没有区别,因为您指定的大小与编译器分配的大小相同。

但是,如果您明确指定大小并且小于要复制的字符串文字的大小,例如,

char entireName[8] = "John Smith"; 

那么只有 8 个字符将被复制,其余的将被丢弃,并且也不会有 0 终止符。在大多数情况下,这不是您想要做的。出于这个原因,让编译器来做总是更好。

两者相同,但建议使用第二个。

如果您在定义和初始化期间遗漏了数组的大小,编译器将分配适当 所需的大小。与有时

的固定大小的定义相比,这不太容易出错
  1. 我们可能忘记为空终止符 [=10=] 保留 space。
  2. 我们可能会提供比指定大小更多的初始化字符串。

事实仍然如此,启用适当的警告,如果您执行上述操作,您将收到警告,但使用第二种方法,这些情况不会出现,所以不用担心。


编辑:

FWIW,在第二种情况下,数组长度将根据提供的初始化字符串长度决定。正如我们所知,编译器时间字符串不能在运行时 resized,因此这是第二种方法的唯一 可能 限制。如果在稍后的部分中,您希望数组包含比提供的初始化字符串 更大 的内容,则第二种方法不适合。

两个版本基本一致问题

然而,由于数组不是const,你显然打算改变它,所以字符串文字只是为了初始化它。在这种情况下,应强烈考虑为数组提供最大大小。

对于此示例的两种情况,分配的大小相同(编译器根据字符串文字计算大小并附加'[=11=]')。

但是,如果您打算稍后将更长的字符串存储到数组中,版本 char entireName[] = "John Smith"; 将导致 _undefined 行为(UB, **anything** can happen). This because the compiler only allocates the size required by the string literal (plus'\0'), but does not know you need more during execution. In theses case, always use the explicit form[]` .

警告:如果字符串文字的大小完全匹配给定的大小数组,您可能不会被警告(使用 gcc 4.8.2 -Wall -Wextra 测试:无警告)隐式 '[=11=]' 无法存储。所以,谨慎使用!我怀疑这是合法的一些遗留原因(实际上是在 ANSI K&C-C 之前),可能会节省 RAM 或包装。但是,如果给定的字符串文字不适合,gcc 警告,如果您启用大多数警告(对于 gcc,请参见上文)。

对于 const 数组,始终使用第二个版本,因为这更容易,甚至更明确地说明您想要给定字符串文字的大小。如果以后不能更改值,给出明确的大小没有任何好处,但是(见上文)失去了一些安全性。