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),你正在将一个可能非常长的字符串读入有限的缓冲区,这是一个等待发生的分段错误(或者更糟糕的是,未定义的行为)。
听起来你有几个问题:
- 调用
scanf("%s", name)
应该给出一个错误,因为%s
需要一个指针而name
是一个数组? 但正如其他人所解释的那样,当你在这样的表达式中使用数组时,你总是得到(自动)是指向数组第一个元素的指针,就像你写了scanf("%s", &name[0])
。 - 将
scanf
写入name
应该给出错误,因为name
是用字符串常量初始化的? 好吧,这就是它的初始化方式,但name
确实是一个数组,所以你可以自由地写它(当然,只要你不写10个以上的字符)。 请参阅以下内容。 - 即使你没有调用
strcpy
,字符也被复制了? 那里没有真正的惊喜。 再次,scanf
只是写入你的数组。
让我们稍微仔细看看你写的是什么,以及你没写的内容。
声明和初始化char
数组时,它与声明和初始化指向char
的指针完全不同。 你写的时候
char name[10] = "yasser";
编译器为你做了什么就像你写的一样
char name[10]; strcpy(name, "yasser");
也就是说,编译器安排使用字符串常量中的字符初始化数组的内容,但是你得到的是一个普通的可写数组( 不是一个不可写的常量字符串常量)。
另一方面,如果你写了
char *namep = "yasser"; scanf("%s", namep);
你会遇到你期望的问题。 在这种情况下, namep
是一个指针,而不是一个数组。 它被初始化为指向字符串常量"yasser"
,这是不可写的。 当scanf
试图写入此内存时,您可能会遇到错误。