2011-11-23 37 views
10

如果我写:初始化字符数组与规模较小的字符串文字

char arr[8] = "abc"; 

有没有在什么arr[4]可能是任何规范?我用 Clang做了一些测试,似乎数组中剩余的字符都设置为空。 另外,char arr[8] = "";每个字节为零。不知道这是否是编译器方便,标准的行为,纯粹的巧合还是我弄错了。


void a() 
{ 
    char arr[8] = "abc"; /* breakpoint here, line 3 */ 
    strcpy(arr, "1234567"); 
} 
int main() 
{ 
    a(); 
    a(); 
    return 0; 
} 

调试成绩单:

 
Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) s 
Current language: auto; currently minimal 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$1 = "abc\000\000\000\000" 
(gdb) c  
Continuing. 

Breakpoint 1, a() at str.c:3 
3   char arr[8] = "abc"; 
(gdb) p arr 
$2 = "1234567" 
(gdb) s 
4   strcpy(arr, "1234567"); 
(gdb) p arr 
$3 = "abc\000\000\000\000" 
+0

@Lundin - 实际上,编曲[3]设置为空终止,所以他有权要求有关ARR [4] –

+0

@JamesCaccese似乎是一个错字...无论如何,这一切都在我发布的答案中解释。 – Lundin

+0

@Lundin - 谁是错字,你的或者是sidyll的?您的评论arr [4]之上的设置为空终止,因为“”为false。 arr [3]被设置为空终止,因为“”,arr [4]被设置为零,因为它没有被明确初始化。你的回答是正确的,但你的评论是关闭的,它会混淆这个问题。既然你不能编辑评论,你应该删除它。 –

回答

16

这是标准的行为。

arr[3]被初始化为0,因为终止0是字符串文字的一部分。

所有其余元件都被初始化为0太 - ISO/IEC 9899:1999,6.7.8。,21:

如果在一个大括号内的列表更少初始化值多于一个集合体的元件或部件 ,或用于初始化数组的已知大小的数组的字符串字符数少于数组中的元素,聚合的其余部分应为 隐含地初始化与具有静态存储持续时间的对象相同。

而且char静态存储对象初始化为0

+0

感谢您的标准参考。 – sidyll

+0

...但这只是为大括号包含的列表定义的,这不是被质疑的代码使用的,不是? – kusma

+1

不,“字符串文字...中的字符数......”或更少。 –

3

这是标准的行为。如果在声明中初始化了数组的任何前缀,则未明确初始化的数组中的每个元素都被初始化为默认值('\0',对于char)。通过a[9]

int a[10] = {1}; 

零出a[1]:这也适用于其他类型。

0

根据标准,超出了规定的将被设为零/零的所有指标。在this SO post

7
char arr[8] = "abc"; 

更多信息是完全等效于

char arr[8] = {'a', 'b', 'c', '\0'}; 

ISO C 6.7.8§21指出

如果在一支柱封闭更少初始化列表比 是元素或聚合的成员,或者更少的字符在 用于初始化已知大小的数组的字符串常量,其中 是数组中的元素,聚合的其余部分应为 ,隐含地初始化为具有静态存储的持续时间为 的对象。

用简单的英语,这意味着在你的数组结束的所有值将被设置为0,所以标准保证你的代码等同于:

char arr[8] = {'a', 'b', 'c', '\0', 0, 0, 0, 0}; 

现在当然,“\ 0'恰好也是零值。

此规则适用于所有数组,而不仅限于字符串。同样,初始化一个结构体时也是如此,但只是明确地设置了一些结构体(6.7.8§18)。


这就是为什么可以像

char arr[8] = ""; 

在这个例子中写的代码,所述阵列的所述第一元件被初始化显式地以“\ 0”,而其余条目的隐含零。编译器把这

char arr[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 
+0

具有静态存储时间的对象是什么意思?我无法理解这部分规范。你能解释一下吗? –