C语言 C 中的字符数组和 scanf 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35024954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:18:37  来源:igfitidea点击:

Char arrays and scanf function in C

carraysscanf

提问by BratBart

I expected to get errors in following code, but I did not. I did not use &sign. Also I am editing array of chars.

我希望在以下代码中出现错误,但我没有。我没有使用&符号。我也在编辑chars数组。

#include <stdio.h>

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;
}

回答by artm

I expected to get errors in following code, but I did not.I did not use & sign.

我希望在以下代码中出现错误,但我没有。我没有使用 & 符号。

scanf("%s",name);

That's totally ok as nameis already the address of the character array.

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

回答by PSkocik

When you pass arrays to functions in C, they decay to pointers to the first item.

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

Therefore for:

因此对于:

char name[] ="yasser";

scanf("%s", name)is the same as scanf("%s", &name[0])and either of those invocations should send shivers down your spine, because unless you control what's on your stdin(which you usually don't), you're reading a potentially very long string into a limited buffer, which is a segmentation fault waiting to happen (or worse, undefined behavior).

scanf("%s", name)是一样的scanf("%s", &name[0]),要么这些调用应发凉下来你的脊椎,因为除非你控制什么是对你stdin(你通常不),你读一个可能很长的字符串转换成有限的缓冲,这是一个分割等待发生的故障(或更糟的是,未定义的行为)。

回答by Steve Summit

It sounds like you have several questions:

听起来你有几个问题:

  1. calling scanf("%s", name)should have given an error, since %sexpects a pointer and nameis an array? But as others have explained, when you use an array in an expression like this, what you always get (automatically) is a pointer to the array's first element, just as if you had written scanf("%s", &name[0]).
  2. Having scanfwrite into nameshould have given an error, since namewas initialized with a string constant? Well, that's how it was initialized, but namereally is an array, so you're free to write to it (as long as you don't write more than 10 characters into it, of course). See more on this below.
  3. Characters got copied around, even though you didn't call strcpy? No real surprise, there. Again, scanfjust wrote into your array.
  1. 调用scanf("%s", name)应该给出一个错误,因为%s需要一个指针并且name是一个数组?但正如其他人所解释的,当你在这样的表达式中使用数组时,你总是(自动)得到一个指向数组第一个元素的指针,就像你写了scanf("%s", &name[0]).
  2. 拥有scanf写入name应该给一个错误,因为name有一个字符串常量被初始化?嗯,这就是它的初始化方式,但它name确实是一个数组,因此您可以随意写入它(当然,只要您写入的字符数不超过 10 个)。请参阅下面的更多信息。
  3. 即使你没有打电话,字符也被复制了strcpy?没有真正的惊喜,在那里。同样,scanf刚刚写入您的数组。

Let's take a slightly closer look at what you did write, and what you didn't write.

让我们稍微仔细看看你写了什么,你没有写什么。

When you declare and initialize an array of char, it's completely different than when you declare and initialize a pointer to char. When you wrote

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

char name[10] = "yasser";

what the compiler did for you was sort of as if you had written

编译器为你做的事情有点像你写的

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

That is, the compiler arranges to initialize the contents of the array with the characters from the string constant, but what you get is an ordinary, writable array (notan unwritable, constant string constant).

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

If, on the other hand, you had written

另一方面,如果你写了

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

you would have gotten the problems you expected. In this case, namepis a pointer, not an array. It's initialized to point to the string constant "yasser", which is not writable. When scanftried to write to this memory, you probably would have gotten an error.

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