C中的字符数组和scanf函数

我希望在下面的代码中得到错误,但我没有。 我没有使用&签名。 我也正在编辑char的数组。

 #include  int main() { char name[10] ="yasser"; printf("%s\n",name); // there is no error , // trying to edit array of chars, // also did not use & sign. scanf("%s",name); // did not use strcpy function also. printf("%s\n",name); return 0; } 

我希望在下面的代码中得到错误,但我没有。我没有使用&sign。

 scanf("%s",name); 

这完全没问题,因为name已经是字符数组的地址。

当您将数组传递给C中的函数时,它们会衰减到指向第一个项目的指针。

因此:

 char name[] ="yasser"; 

scanf("%s", name)scanf("%s", &name[0]) ,这些调用中的任何一个都应该让你的脊椎发抖,因为除非你控制你的stdin (你通常不喜欢) ‘t),你正在将一个可能非常长的字符串读入有限的缓冲区,这是一个等待发生的分段错误(或者更糟糕的是,未定义的行为)。

听起来你有几个问题:

  1. 调用scanf("%s", name)应该给出一个错误,因为%s需要一个指针而name是一个数组? 但正如其他人所解释的那样,当你在这样的表达式中使用数组时,你总是得到(自动)是指向数组第一个元素的指针,就像你写了scanf("%s", &name[0])
  2. scanf写入name应该给出错误,因为name是用字符串常量初始化的? 好吧,这就是它的初始化方式,但name确实是一个数组,所以你可以自由地写它(当然,只要你不写10个以上的字符)。 请参阅以下内容。
  3. 即使你没有调用strcpy ,字符也被复制了? 那里没有真正的惊喜。 再次, scanf只是写入你的数组。

让我们稍微仔细看看你写的是什么,以及你没写的内容。

声明和初始化char数组时,它与声明和初始化指向char的指针完全不同。 你写的时候

 char name[10] = "yasser"; 

编译器为你做了什么就像你写的一样

 char name[10]; strcpy(name, "yasser"); 

也就是说,编译器安排使用字符串常量中的字符初始化数组的内容,但是你得到的是一个普通的可写数组( 不是一个不可写的常量字符串常量)。

另一方面,如果你写了

 char *namep = "yasser"; scanf("%s", namep); 

你会遇到你期望的问题。 在这种情况下, namep是一个指针,而不是一个数组。 它被初始化为指向字符串常量"yasser" ,这是不可写的。 当scanf试图写入此内存时,您可能会遇到错误。