为什么c会删除两个按顺序初始化的char数组之间的空字符?

问题描述 投票:0回答:1

我正在学习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
中的空字符,或者只是从不将其放入内存中。谢谢。

arrays c char
1个回答
0
投票

每当我创建这样的单个字符数组时,空字符总是放置在末尾

错误。当你这样做时:

char s1[] = {'h', 'e', 'l', 'l', 'o'};

总是创建一个恰好包含 5 个元素的数组,并使用您在初始化程序中提供的 5 个字符进行填充。该数组在末尾包含空字节。

如果内存中该数组之后碰巧有一个值为 0 的字节,则可能看起来该数组是以 null 结尾的,但事实并非如此。尝试读取

s1[5]
就是读取超出数组末尾的内容,这样做会在代码中触发 未定义的行为。这在您的案例中表现出来,有时似乎有效,有时则无效。

© www.soinside.com 2019 - 2024. All rights reserved.