有人能解释一下为什么int array[3] = {1,2,3}
可以工作,但是char array[3] = "123"
不能工作吗?
它输出了" 123( ( "而不是" 123 "。
它说对于字符数组需要另一个空间来存放空字符,但是数组不是从0开始的吗,所以char array[3]
就足够了,因为实际上有4个空间。除非字符数组实际上需要两个空间,一个用于空字符,另一个用于特殊字符。
int array[3] = {1,2,3}
分配一个数组,最多可以容纳3个整数,您可以使用以下方式访问其中任何一个:
array[0]
array[1]
array[2]
在这里:
char array[3] = "123"
"123"
由4个字节组成。字符串文字中的字符以NUL终止符结束。但是,您分配了3个字节,最多只能容纳2个字符(+1个NUL终止符)。因此,在使用它初始化数组时,由于没有空间,'\0'
未被写入。
当您在printf
中使用%s
打印时,它会引发未定义行为,因为%s
会打印直到NUL终止符。因此,printf
会继续从无效的内存位置读取值,直到出现'\0'
。这样做可能会导致任何事情发生。您可能会看到随机垃圾输出、崩溃、分段错误等。基本上,即使看起来已经按预期“工作”,您也永远不应该依赖这种行为。
但是数组不是从0开始吗?
是的
那么
char array[3]
就足够了,因为实际上有4个空间
错了。对于char array[3]
,有效的索引为
array[0]
array[1]
array[2]
访问 array[3]
是错误的,会引起未定义行为。
通过使用下面的方法修复此问题:
char array[4] = "123";
char array[] = "123";
array[3]
肯定是未定义的行为,但是array
本身的初始化是明确定义的,因此上面的array
初始化等同于char array[] = {'1','2','3'};
。不需要空终止符的空间。另一方面,char array[3] = "1234";
是未定义的,因为“没有初始化器可以尝试为未包含在正在初始化的实体中的对象提供值”(C11草案N1570 6.7.9p2),这意味着array
太小,无法容纳4个元素{'1','2','3','4'}
。 N1570的6.7.9p32表达了预期的行为。 - user539810'\0'
没有被提供? - Spikatrix