哪里是空字符的固定长度的空字符串?

问题描述:

所以我就好奇阅读一些C代码;假设我们有以下代码:哪里是空字符的固定长度的空字符串?

char text[10] = ""; 

C编译器在哪里放置空字符?

我能想到的3种可能情况下

  1. 在开始的时候,然后9个字符的任何用于在存储器
  2. 最后,垃圾所以9个字符,然后尾随'\0'
  3. 它与10 '\0'

的问题完全填满它,这取决于这两种情况下,是否有必要添加尾随'\0'strncpy时。如果是案例2和案例3,那么这不是必须的,但是一个好主意;如果是案例1,那么这是绝对必要的。

是哪一个?

+0

我会带门#3,蒙蒂。这与'strncpy()'的作用无关。它应该做的是它指定要做的事情。 –

+0

您询问了C编译器,但将其标记为C和C++。 C和C++在这里有一些不同之处,所以如果这不是你要求的,C++标签是不合适的。 – hvd

+0

@ hvd认为我也将C++放在那里,因为如何处理这两种情况会很有趣。但你说得对;文本本身并没有提到C++ –

在初始化中,text阵列填充空字节(即#选项3)。

char text[10] = ""; 

相当于:

char text[10] = { '\0' }; 

在这的text第一元件被明确地初始化为零,并且它们中的其余的是隐式所要求的C11, Initialization 6.7.9, 21初始化为零:

如果在大括号括起来的列表中的初始化器数量少于 是元素或聚合的成员,或者在中较少的字符用于初始化已知大小的数组的字符串字符串,其中 是数组中的元素,聚合的其余部分应为 ,隐含地初始化为具有静态存储的持续时间的对象。

字符串文字""具有字符数组char[1]的类型C和const char [1]在C++中。

你可以把它想象以下方式

在C

chat no_name[] = { '\0' }; 

在C++

const chat no_name[] = { '\0' }; 

当一个字符串文字被用来初始化一个字符数组那么它的所有字符都被用作初始值。因此,对于这个声明

char text[10] = ""; 

你其实有

char text[10] = { '\0' }; 

阵列的所有其它字符没有相应的初始化(除非是文字[0]的第一个字符),那么他们将被初始化由0

从C标准(6.7.9初始化)

14的字符类别M的数组AY由字符串被初始化 字面或UTF-8字符串文字,任选在大括号。字符串常量的 连续字节(包括终止空 字符,如果有房间或如果阵列是未知大小的) 初始化数组的元素。

21如果在一个大括号内的列表更少初始化值多于 是元件或聚集体的成员,或在用于初始化的阵列的 字符串文字更少的字符已知的尺寸比有 是数组中的元素,所述聚集体的其余部分应 初始化隐含的相同具有静态存储 持续时间的对象

,最后

10如果具有自动存储持续时间的对象没有初始化 明确地,它的值是不确定的。如果具有静态 或线程存储持续时间的对象未被明确初始化,则:

- 如果它具有指针类型,则将其初始化为空指针;

- 如果它有算术类型,它被初始化为(正或无符号)零;

- 如果它是一个聚合,每个成员根据这些规则初始化(递归) ,并且任何填充被初始化为零位;

- 如果它是一个联合,根据这些规则初始化第一个命名成员 (并递归),并且任何填充将 初始化为零位;

类似的是用C++标准编写的。

考虑到,在C您可以写信例如通过以下方式

char text[5] = "Hello"; 
     ^^^ 

在这种情况下,字符数组将不会有终止零,因为没有准备的房间。 :)这是一样的,如果你定义

char text[5] = { 'H', 'e', 'l', 'l', 'o' }; 

引用N1256(大致C99),由于存在之前或之后的语言不相关的变化:

6.7.8初始化

14字符类型的阵列可以是由字符串文字初始化,可选择括在大括号中。字符串文字的连续字符(包括终止空字符,如果有空间或数组未知大小)初始化数组的元素。

""是由文字串一个字符的(其终止空字符),并且该段指出的是一个字符用于初始化数组,这意味着第一个字符被初始化为零的元素。没有什么在这里,说会发生什么变化阵列的其余部分的,但有:

21如果在一个大括号内的名单少初始化值多于元素或聚集的成员,或者更少的字符在用于初始化一个已知大小的数组(比数组中有元素)的字符串字面值中,聚合的其余部分应该与具有静态存储持续时间的对象相同地初始化。

本段声明其余字符的初始化与静态存储持续时间相同,这意味着数组的其余部分也被初始化为零。

值得一提的还有就是“是否有房”在P14:

在C,char a[5] = "hello";是完全有效的过了,这种情况下也,你可能要问哪里编译器会将空字符。这里的答案是:它没有。