所以我对编程很新,我在3天前开始使用C语言.我正在创建这个简短的程序来测试自己.这只是一个非常基本的C程序,要求你的名字和姓氏.这是代码:
#include <stdio.h>
int main()
{
char first[20];
char last[20];
printf("Please enter your first name:");
scanf("%s",&first);
printf("\nand Please enter your last name:");
scanf("%s",&last);
printf("Greetings fellow %s %s!\n",first,last);
return(0);
}
Run Code Online (Sandbox Code Playgroud)
但是当我去编译时,我每次都会得到这个错误:
checkname.c:9: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
checkname.c:11: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
我知道我可以使用,gets()但显然它很糟糕,我不应该使用它.这段代码有什么问题?我不明白问题是什么.
小智 7
我知道我可以使用,
gets()但显然它很糟糕,我不应该使用它.
确切地说,确切地说 - 它容易出现缓冲区溢出错误.并且scanf()同样是邪恶的(部分是出于同样的原因 - 指定缓冲区长度并不容易,而且无论如何,它都比必要的更复杂,很难做到正确,而且对于简单的原始I/O来说它是非常昂贵的),不要也不要用它.使用fgets()获取用户输入,它通过让在脚被枪击节省您传递给它的缓冲区的长度被写入到:
char buf[0x40];
fgets(buf, sizeof(buf), stdin);
Run Code Online (Sandbox Code Playgroud)
既然你知道"如何",我会向你解释"为什么".
传递给函数时,数组被称为衰减为指针.如果将a传递char []给函数,它将看到char *它指向数组的第一个元素.这就是为什么你不必&为(char)数组(概念上是C中的字符串)显式使用"addressof"()运算符的原因.
如果使用它,则不会获得指向数组的第一个元素的指针,而是指向数组本身的指针,而这不是您想要的.
(一般来说,它可以工作,因为它显然对你有用,但理论上它会调用未定义的行为,因为传入的表达式的实际类型和%s转换说明符所期望的类型不匹配.)
本文档是关于数组和指针的一个很好的读物,请务必阅读并理解它.