我正在学习c。我有以下代码:
char s1[] = {'h', 'e', 'l', 'l', 'o'};
char s2[] = {'w', 'o', 'r', 'l', 'd'};
printf("Original strings:\n\t%s\n\t%s\n", s1, s2);
每当我创建这样的单个字符数组时,空字符总是放置在末尾。所以,我预计输出是
Original strings:
hello
world
输出实际上是
Original strings:
helloworld
world
第一个数组的初始化似乎末尾没有空字符
'\0'
,而第二个数组始终使用空字符进行初始化。这些数组也总是在内存中彼此相邻放置(我打印地址,&s1[i]
,以及存储在那里的值,s1[i]
):
0x7fffe344a98e 104 'h'
0x7fffe344a98f 101 'e'
0x7fffe344a990 108 'l'
0x7fffe344a991 108 'l'
0x7fffe344a992 111 'o'
0x7fffe344a993 119 'w' - not '\0' ?
0x7fffe344a994 111 'o'
0x7fffe344a995 114 'r'
0x7fffe344a996 108 'l'
0x7fffe344a997 100 'd'
0x7fffe344a998 0 '\0'
这些条件导致
printf
函数打印 helloworld
而不是仅打印 hello
s1
,因为在 'd' 之后之前没有空字符。如果我删除 s2
,则 s1
会在末尾使用空字符进行初始化并正常打印(使用 %s
)。我想了解为什么当我立即声明第二个字符数组时,c 会删除 'o'
中 s1
之后的空字符。
我可以指定两个数组的大小(例如,
s1[6] = {'h', ...}
),我的问题就解决了。但是,当我在代码中按顺序创建两个字符数组时,我不明白为什么 c 会删除 s1
中的空字符,或者只是从不将其放入内存中。谢谢。
每当我创建这样的单个字符数组时,空字符总是放置在末尾
错误。当你这样做时:
char s1[] = {'h', 'e', 'l', 'l', 'o'};
您总是创建一个恰好包含 5 个元素的数组,并使用您在初始化程序中提供的 5 个字符进行填充。该数组不在末尾包含空字节。
如果内存中该数组之后碰巧有一个值为 0 的字节,则可能看起来该数组是以 null 结尾的,但事实并非如此。尝试读取
s1[5]
就是读取超出数组末尾的内容,这样做会在代码中触发 未定义的行为。这在您的案例中表现出来,有时似乎有效,有时则无效。