使用较小的字符串文字初始化char数组

时间:2011-11-23 15:09:38

标签: c string initialization

如果我写:

char arr[8] = "abc";

是否有arr[4]可能的规范?我做了一些测试 Clang,似乎数组中剩余的字符都设置为null。 此外,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"

4 个答案:

答案 0 :(得分:16)

这是标准行为。

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

所有剩余的元素也被初始化为0 - ISO/IEC 9899:1999,6.7.8,21:

  

如果括号括起的列表中的初始值设定项少于元素或成员   用于初始化已知数组的字符串文字中的聚合或更少字符   大小比数组中的元素大,其余的聚合应该是   隐式初始化与具有静态存储持续时间的对象相同。

具有静态存储的char个对象初始化为0。

答案 1 :(得分:7)

char arr[8] = "abc";

完全等同于

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

ISO C6.7.8§21声明

  

如果括号括起的列表中的初始值设定项少于此值   是聚合的元素或成员,或者是一个或多个字符   string literal用于初始化已知大小的数组   是数组中的元素,聚合的其余部分应为   隐式初始化与具有静态存储的对象相同   持续时间。

简单来说,这意味着数组末尾的所有值都将设置为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};

答案 2 :(得分:3)

这是标准行为。如果在声明中初始化了数组的任何前缀,则未显式初始化的数组的每个元素都将初始化为默认值('\0'的{​​{1}})。它也适用于其他类型:

char

通过int a[10] = {1}; a[1]归零。

答案 3 :(得分:0)

根据标准,超出指定范围的所有指数都将设置为零/空。 this SO post

中的更多信息