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

为什么c允许在没有声明的情况下初始化字符串?,c,pointers,segmentation-fault,C,Pointers,Segmentation Fault,当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];

当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;
}
#包括
int main(int argc,char const*argv[]
{
字符*s1,*s2;
int n1=7,n2=8;
printf(“输入%d\n”,n1);
scanf(“%s”,s1);
scanf(“%s”,s2);
[155][347];;
返回0;
}
但是使用参数作为变量,比如n1和n2,scanf读取s1会导致分段错误。

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

通常的方式是这样的:

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

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

由于
s1
s2
不是有效的指针,因此代码只是具有未定义的行为
scanf
需要一个指向字符数组的指针,该数组足够大,可以容纳读取的数据,而您没有提供这样的指针

通常的方式是这样的:

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

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

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

C中没有数据类型
string

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

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

幸运的是,第一次调用
scanf()
,程序没有崩溃

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

C中没有数据类型
string

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

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


幸运的是,第一次调用
scanf()

C时,程序没有崩溃,这是不允许的。您的代码具有未定义的行为。“当
dyn_mat
的[dimensions]为常量时,代码将毫无错误地运行,并且
s1
s2
确实存储输入值。但是,当参数作为变量时,例如n1和n2,scanf读取s1会导致分段错误。”在这两种情况下,代码都会以相同的严重错误运行,您只是碰巧看不到它的效果。C不允许这样。您的代码具有未定义的行为。“当
dyn_mat
的[dimensions]为常量时,代码将毫无错误地运行,并且
s1
s2
确实存储输入值。但是,当参数作为变量时,例如n1和n2,scanf读取s1会导致分段错误。”在这两种情况下,代码都会以相同的严重错误运行,您只是碰巧看不到它的效果。但是,当我给出常量参数时,为什么每次都能运行,并且s1和s2总是毫无问题地存储输入值。s1和s2指向内存中的某个任意区域。您的代码将覆盖其中存在的任何内容。您在程序中看不到问题,因为最有可能的影响是在其他地方损坏了系统中的其他东西。@icepack我不太确定它是否损坏了系统中的其他东西,而且它肯定没有接触到操作系统。进程有地址空间,访问冲突也会引发分段错误。请参阅@porkshoulder,它实际上取决于运行环境,您所说的对于嵌入式或内核代码(或DOS!:)是不正确的。但是,在本例中,您可能是对的,因为这看起来像是在受保护的环境中运行的标准用户空间代码,因此损坏将发生在正在运行的进程中,但是当我提供常量参数时,为什么它每次都工作,s1和s2总是毫无问题地存储输入值。s1和s2指向内存中的某个任意区域。您的代码将覆盖其中存在的任何内容。您在程序中看不到问题,因为最有可能的影响是在其他地方损坏了系统中的其他东西。@icepack我不太确定它是否损坏了系统中的其他东西,而且它肯定没有接触到操作系统。进程有地址空间,访问冲突也会引发分段错误。请参阅@porkshoulder,它实际上取决于运行环境,您所说的对于嵌入式或内核代码(或DOS!:)是不正确的。但是,在本例中,您可能是对的,因为这看起来像是在受保护的环境中运行的标准用户空间代码,因此损坏将发生在运行的进程中