Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我已经在C中声明了一个大小为1的字符数组,但是我已经读取了一个大小为10的字符串,但是给出的代码工作得非常好。 #包括 int main() { 字符名[1]; scanf(“%s”,名称); printf(“%s”,名称); }_C_String - Fatal编程技术网

我已经在C中声明了一个大小为1的字符数组,但是我已经读取了一个大小为10的字符串,但是给出的代码工作得非常好。 #包括 int main() { 字符名[1]; scanf(“%s”,名称); printf(“%s”,名称); }

我已经在C中声明了一个大小为1的字符数组,但是我已经读取了一个大小为10的字符串,但是给出的代码工作得非常好。 #包括 int main() { 字符名[1]; scanf(“%s”,名称); printf(“%s”,名称); },c,string,C,String,我可以通过此声明读取任意大小的字符串首先,这是未定义的行为。这种情况下会发生什么是不可预测的 然而,我将给出一个额外的代码示例,其中包含一个额外的变量,以说明这种方法可能出现的错误 #include<stdio.h> int main() { char name[1]; scanf("%s",name); printf("%s",name); } 这是您的原始程序,带有一个附加变量,a,它被初始化为1且未更改 输出 int main() { char

我可以通过此声明读取任意大小的字符串

首先,这是未定义的行为。这种情况下会发生什么是不可预测的

然而,我将给出一个额外的代码示例,其中包含一个额外的变量,以说明这种方法可能出现的错误

#include<stdio.h>
int main()
{
    char name[1];
    scanf("%s",name);
    printf("%s",name);
}
这是您的原始程序,带有一个附加变量,
a
,它被初始化为1且未更改

输出

int main()
{
    char name[1];
    int a=1;
    printf ("a = %d\n",a);
    scanf("%s",name);
    printf("%s\n",name);
    printf ("a = %d\n",a);
}

正如您所看到的,
a
的值通过输入一个大字符串而改变。

首先,这是未定义的行为。这种情况下会发生什么是不可预测的

然而,我将给出一个额外的代码示例,其中包含一个额外的变量,以说明这种方法可能出现的错误

#include<stdio.h>
int main()
{
    char name[1];
    scanf("%s",name);
    printf("%s",name);
}
这是您的原始程序,带有一个附加变量,
a
,它被初始化为1且未更改

输出

int main()
{
    char name[1];
    int a=1;
    printf ("a = %d\n",a);
    scanf("%s",name);
    printf("%s\n",name);
    printf ("a = %d\n",a);
}

正如您所看到的,
a
的值是通过输入一个大字符串而改变的。

对于C的新手,我想解释一下实际发生的情况: 在C语言中,数组是一个连续的内存块,由指向该数组的第一个单元(内存块的第一个字节)的指针表示

下面是如何查找带有一个单元格的字符数组:

a = 1
aaaa
aaaa
a = 6381921
您在某处分配了一个字节的内存,变量
name
保存该字节的地址。 它不包含数组的长度,该信息仅用于分配它,然后被丢弃

当您调用
scanf
时,它会获取
name
中的地址,并开始用用户输入填充内存。由于
scanf
没有关于尺寸的信息,因此只有在两种情况下才会停止: 1.输入结束 2.写入内存时出错

这就是为什么不可能知道会发生什么,因为这在很大程度上取决于正在运行的程序的内存布局,而内存布局又取决于硬件、操作系统和编译器

它还取决于输入的长度

在这个简化的示例中,
scanf
将继续写入地址8、9及以上。 假设您的程序可以写入这些地址,它将用用户输入替换其中的任何内容

printf
将从7开始读取内存(名称中的地址),直到它进入一个值为0的字节,并将所有内容打印到屏幕上

如果在调用
scanf
和调用
printf
之间没有其他代码使用该内存,则输入数据仍将存在,并将正确打印到屏幕上


但是,如果有使用这些内存地址的代码,它可能会覆盖输入或破坏程序,因为它从内存中读取了错误的数据。

对于C新手,我想解释一下实际发生的情况: 在C语言中,数组是一个连续的内存块,由指向该数组的第一个单元(内存块的第一个字节)的指针表示

下面是如何查找带有一个单元格的字符数组:

a = 1
aaaa
aaaa
a = 6381921
您在某处分配了一个字节的内存,变量
name
保存该字节的地址。 它不包含数组的长度,该信息仅用于分配它,然后被丢弃

当您调用
scanf
时,它会获取
name
中的地址,并开始用用户输入填充内存。由于
scanf
没有关于尺寸的信息,因此只有在两种情况下才会停止: 1.输入结束 2.写入内存时出错

这就是为什么不可能知道会发生什么,因为这在很大程度上取决于正在运行的程序的内存布局,而内存布局又取决于硬件、操作系统和编译器

它还取决于输入的长度

在这个简化的示例中,
scanf
将继续写入地址8、9及以上。 假设您的程序可以写入这些地址,它将用用户输入替换其中的任何内容

printf
将从7开始读取内存(名称中的地址),直到它进入一个值为0的字节,并将所有内容打印到屏幕上

如果在调用
scanf
和调用
printf
之间没有其他代码使用该内存,则输入数据仍将存在,并将正确打印到屏幕上


但是,如果有使用这些内存地址的代码,它可能会覆盖输入或破坏程序,因为它从内存中读取了错误的数据。

未定义的行为。它可能有效,也可能无效。您是否建议所有数组的长度都应为1,因为在这种情况下没有发生任何不好的事情?你完全错了,程序将使用“任意长度的字符串”。不要忘记,
scanf
将在第一个空格处停止,因此您的字符串可能只有几个字节的长度。实际上,它并不正常:只是您看不到出错的影响。如果使用Valgrind或GDB运行它,您会看到一些错误(内存错误)。如果你要进一步处理
name
,你很可能会遇到SEGFULT。“我去了一个繁忙的十字路口。红灯亮了。我还是过了马路。过得很好。”这是否意味着冲红灯过十字路口是可以的?未定义的行为。它可能有效,也可能无效。您是否建议所有数组的长度都应为1,因为在这种情况下没有发生任何不好的事情?你完全错了,程序将使用“任意长度的字符串”。不要忘记,
scanf
将在第一个空格处停止,因此您的字符串可能只有几个字节的长度。实际上,它不起作用:只是您看不到