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

8

我原本以为以下代码会出现错误,但实际上没有。我没有使用 & 符号。另外,我正在编辑字符数组。

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

3
这段代码运行正确,您的期望有误。还有什么需要说的呢? - Ed Heal
我知道我是错的,我希望有声明。 - BratBart
1
https://dev59.com/sW445IYBdhLWcg3w9O7R - Flikk
1
只是顺便提一下,& 符号被称为“取地址运算符”。 - Ziezi
1
数组具有固定的大小但不固定的内容。这意味着您可以修改内容但不能修改大小,这是您所困惑的吗? - Michi
我不确定,但我认为OP问的是在执行char name[10] ="yasser";之后是否可以使用scanf修改数组。 - Michi
5个回答

11
我原本预期以下代码会出现错误,但实际上没有出错。我没有使用 & 符号。
scanf("%s",name);

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


任何数组都会衰变为指向其第一个元素的指针。因此,您不需要地址。 - SenselessCoder
3
接近正确,但还不太对。 name 不是字符数组的地址,而是大小为10的数组。当将 name 传递给 scanf() 函数时,它会被转换为该数组的第一个元素的地址。 - chux - Reinstate Monica
4
为了概括@SenselessCoder的评论,以下结论始终成立:myArray == &(myArray[0])。 - Aaron Burke
1
哈哈,不错 @AaronBurke。 - SenselessCoder

5

听起来你有几个问题:

  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 尝试写入此内存时,您可能会收到错误。


3
当您在C语言中将数组传递给函数时,它们会衰减为指向第一个元素的指针。
因此,对于以下代码:
char name[] ="yasser";

scanf("%s", name)scanf("%s", &name[0])相同。但无论哪种调用方式,都应该让你毛骨悚然,因为除非你控制stdin的内容(通常不可能),否则你会将一个潜在非常长的字符串读入到有限的缓冲区中,这就像是一个分段错误等待发生(或者更糟糕,未定义行为)。


5
这与scanf("%s", &name[0])相同,但与scanf("%s", &name)不同。后者会导致未定义的行为。 - M.M

0
#include <stdio.h> 
#include <string.h>
int main()//fonction principale
{

char  name[10] ="yasser";
int longeur=0;
printf("%s\n",name);

scanf("%s",name);
longeur = strlen(name);
for (int i=0;i<longeur;i++) {
    printf("%c",*(name+i));
}
return 0;}

1
请在引用的代码周围添加详细信息,说明原帖作者犯了什么错误,以及您提出的解决方案如何帮助他/她解决问题。理解“原因”也将有助于其他社区成员从中学习。 - Tom Taylor

0
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp) {
    char *myName = (char *) calloc(10, sizeof(char));
    *(myName)='K'; *(myName+1)='h'; *(myName+2)='a'; *(myName+3)='l'; *(myName+4)='i'; *(myName+5)='d';
    printf("%s\n",myName);
    scanf("%s",myName);
    printf("%s\n",myName);
    return (EXIT_SUCCESS);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接