如果我写:
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"
答案 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
中的更多信息