[英]C Arbitrary length string
我怀疑如何分配数组的长度
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "s";
long unsigned a = strlen(str);
scanf("%s", str);
printf("%s\n%lu\n", str, a);
return 0;
}
在上面的程序中,我将字符串"s"
分配给一个char
数组。 我认为str[]
的长度是 1。所以我们不能存储超过数组的长度。 但它的行为不同。 如果我使用scanf
读取字符串,它将存储在str[]
中而没有任何错误。 数组str
的长度是多少?
示例 I/O:
Hello
Hello 1
您的str
是一个用"s"
初始化的char
数组,也就是说,它的大小为2
,长度为1
。 大小比长度大一,因为在末尾添加了 NUL 字符串终止符 ( \0
)。
您的str
数组最多可以容纳两个char
。 尝试写入更多将导致您的程序访问 memory 超出数组末尾,这是未定义的行为。
但实际发生的情况是,由于str
数组存储在 memory (在堆栈上)中的某个位置,并且 memory 区域远大于 2 个字节,因此您实际上可以写入末尾而不会导致崩溃。 这并不意味着您应该这样做。 它仍然是未定义的行为。
由于您的数组大小为2
,因此它只能容纳长度为1
的字符串,加上它的终止符。 要使用scanf()
并正确避免写入超出数组末尾,您可以使用字段宽度说明符:在%
之后和s
之前的数值,如下所示:
scanf("%1s", str);
当数组的大小由使用的初始值设定项确定时,在声明数组时未指定其大小。
在这个数组声明中
char str[] = "s";
使用字符串文字作为初始值设定项。 字符串文字是由包含的零终止字符终止的字符序列。 那就是字符串文字"s"
有两个字符{ 's', '\0' }
。
它的字符用于按顺序初始化数组str
的元素。
所以如果你会写
printf( "sizeof( str ) = %zu\n", sizeof( str ) );
那么 output 将为2
。 字符串的长度确定为终止零字符之前的字符数。 所以如果你会写
#include <string.h>
//...
printf( "strlen( str ) = %zu\n", strlen( str ) );
那么 output 将为1
。
如果您尝试在数组外写入数据,则会出现未定义的行为,因为不属于该数组的 memory 将被覆盖。 在某些情况下,您可以获得预期的结果。 在其他情况下,程序可能会异常完成。 那就是程序的行为是未定义的。
数组str
的大小为 2:1 个字节用于字符“s”,一个用于终止 null 字节。 你正在做的是写到数组的末尾。 这样做会调用未定义的行为。
当您的代码具有未定义的行为时,它可能会崩溃,它可能会 output 出现奇怪的结果,或者它可能(如在本例中)似乎正常工作。 此外,进行看似无关的更改,例如用于调试的printf
调用或未使用的局部变量,可能会改变未定义行为的表现方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.