Char arrays and scanf function in C

2019-05-25 20:39发布

问题:

I expected to get errors in following code, but I did not. I did not use & sign. Also I am editing array of 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;
}

回答1:

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 name is already the address of the character array.



回答2:

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

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).



回答3:

It sounds like you have several questions:

  1. calling scanf("%s", name) should have given an error, since %s expects a pointer and name is 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 scanf write into name should have given an error, since name was initialized with a string constant? Well, that's how it was initialized, but name really 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, scanf just wrote into your array.

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 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 (not an 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, namep is a pointer, not an array. It's initialized to point to the string constant "yasser", which is not writable. When scanf tried to write to this memory, you probably would have gotten an error.



标签: c arrays scanf