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

时间:2015-06-05 13:06:32

标签: c arrays string initialization

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

char entireName[11] = "John Smith"; 

其中有四个空格用于字符J - o - h - n,一个用于空格,五个用于S - {{1 } - m - i - t,以及一个字符串终结符h

您也可以通过输入

来完成上述操作
\0

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

有什么区别?

3 个答案:

答案 0 :(得分:6)

两者都相同,但第二个是可取的。

如果在定义和初始化期间忽略了数组的大小,编译器将分配正确的大小。与有时具有固定大小的定义

相比,这更不容易出错
  1. 我们可能忘记为null-terminator \0保留空格。
  2. 我们可能会提供一个初始化字符串 more ,而不是指定的大小。
  3. 事实仍然是,如果您启用了适当的警告,如果您执行上述操作,您将收到警告,但使用第二种方法时,不会出现这些情况,因此不必担心。

    编辑:

    FWIW,在第二种情况下,数组长度将根据提供的初始化字符串长度决定。我们知道,编译器时间字符串在运行时不能调整大小,因此这是第二种方法的唯一可能的限制。如果在以后的某个部分,您希望数组保存更大的内容,而不是提供的初始化字符串,则第二种方法不适用。

答案 1 :(得分:3)

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

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

char entireName[8] = "John Smith"; 

然后只复制8个字符,其余部分将被丢弃,也不会有0个终结符。在大多数情况下,这不是您想要做的。出于这个原因,让编译器完成它总是更好。

答案 2 :(得分:3)

两个版本基本相同,如问题中所述。

但是,由于数组不是const,您显然打算更改它,因此字符串文字只是初始化它。在这种情况下,应该强烈考虑给出数组的最大大小。

分配的大小对于此示例的两种情况都是相同的(编译器根据字符串文字计算大小并附加'\0')。

但是,如果您打算稍后将更长的字符串存储到数组中,则版本char entireName[] = "John Smith";将导致_undefined behavior (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 []`。< / p>

警告:如果字符串文字完全的大小与数组的给定大小匹配,则可能不会收到警告(使用gcc 4.8.2 -Wall -Wextra:无警告)无法存储implictit '\0'。所以,谨慎使用!我怀疑这是合法的遗留原因(实际上是在ANSI-K-C-C之前),可能节省RAM或打包。但是,如果给定的字符串文字不适合,则gcc 警告,如果启用大多数警告(对于gcc,请参阅上文)。

对于const数组,总是使用第二个版本,因为这样更容易,甚至更明确地说明您想要给定字符串文字的大小。如果不能更改后面的值,则在给出明确的大小时不会获得任何结果,但是(见上文)某些安全性会丢失。