【问题标题】:why does c allow initialization of string without declaration?为什么c允许在没有声明的情况下初始化字符串?
【发布时间】:2012-10-27 11:59:20
【问题描述】:

当 dyn_mat 的参数是常量时,代码运行没有任何错误,并且 s1 和 s2 确实存储了输入值。

#include<stdio.h>

int main(int argc, char const *argv[])
{
    char *s1, *s2;
    int n1=7, n2=8;
    printf("Enter, %d \n", n1);

    scanf("%s", s1);
    scanf("%s", s2);

    int dyn_mat[155][347];

    return 0;
}

但是使用参数作为变量,比如 n1 和 n2,scanf 读取 s1 会导致分段错误。

【问题讨论】:

  • C 不允许这样做。您的代码具有未定义的行为。
  • "当dyn_mat 的[维度] 是常量时,代码运行没有任何错误,s1s2 确实存储输入值。但是将参数作为变量,比如 n1和 n2,scanf 读取 s1 给出分段错误。”代码在这两种情况下运行时都会出现同样严重的错误,只是碰巧看不到它的影响。

标签: c pointers segmentation-fault


【解决方案1】:

代码只是有未定义的行为,因为s1s2 不是有效的指针。 scanf 需要一个指向字符数组的指针,该数组的大小足以容纳读取的数据,而您没有提供这样的指针。

通常的方式是这样的:

char s1[1000];
char s2[1000];

scanf("%s", s1);
scanf("%s", s2);

(尽管您应该使用更安全的版本来指定可用缓冲区大小,而不是希望输入足够短;例如,scanf("%999s", s1);。)

【讨论】:

  • 但是当我给出常量参数时,为什么它每次都有效,而 s1 和 s2 总是毫无问题地存储输入值。
  • s1 和 s2 指向内存中的某个任意区域。您的代码会覆盖那里存在的任何内容。您在您的程序中看不到问题,因为很可能影响是在其他地方并破坏了您系统中的其他东西。
  • @icepack 我不太确定它是否会破坏您系统中的其他内容,而且它肯定不会触及操作系统。进程具有地址空间,访问冲突也会引发分段错误。见What is a segmentation fault?
  • @porkshould 实际上取决于运行环境,您所说的对于嵌入式或内核代码(或 DOS!:) 是不正确的。但是,在这种情况下,您可能是对的,因为这看起来像是在受保护的环境中运行的标准用户空间代码,因此运行过程中会发生损坏
【解决方案2】:

为什么 c 允许在没有声明的情况下初始化字符串?

C 中没有数据类型string

在 C 中存储字符串的一种可能方法是使用字符数组,该数组的最后一个元素带有 0 以指示该字符串的结尾。

您的程序没有声明任何数组,而只是指向字符的指针,这些字符没有分配给您使用scanf()复制数据的内存。

您很幸运,第一次调用 scanf() 时程序没有崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    相关资源
    最近更新 更多