当我编译scanf("%s", &var);
时,gcc 发回一个警告:
warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[20]’
但是,当我编译时scanf("%s", var);
,没有应用警告。这两段代码都有效,而且我正在阅读的书特别提到要使用 & 符号,但即使在某些示例中也没有。
我的问题是,即使书中没有指定,我是否应该继续使用与号?
从您发布的内容来看,var
是一个 char 数组。在这种情况下,您不需要 & 符号,只是名称var
将根据需要评估为 (char *)。
细节:
scanf 需要一个指向将存储输入的变量的指针。在字符串的情况下,您需要一个指向内存中字符数组的指针,该数组足够大以存储读入的任何字符串。当您声明类似 的内容时,您使用 var[0] 为第一个字符char var[100]
腾出 100 秒的空间char
和 var[99] 指的是第 100 个字符。数组名称本身的计算结果与 完全相同&var[0]
,它是指向序列第一个字符的指针,正是 scanf 所需要的。因此,您需要做的就是scanf("%s", var);
,但请注意,scanf
它不会对输入字符串强制执行大小限制,因此如果用户输入长度为 101 的字符串,您将有缓冲区溢出,这将导致错误,甚至更糟糕的是,安全问题。更好的选择通常是fgets
这确实允许输入字符串的大小限制。
我邀请任何其他回答者在这里给出一个很好的指针和参考摘要。我认为如果不在这里和那里犯一些错误,我就无法做到这一点,而且我无意应对随之而来的书呆子愤怒。
因此,我将向您指出一个很好的资源,以了解位于您问题核心的指针和引用。http://www.cplusplus.com/doc/tutorial/pointers/
&
从scanf("%s", &var);
中删除scanf("%s", var);
。
当您使用这样的数组时:
char name[20];
您必须考虑与它相关联的由 20 个字符组成的内存区域。要获得该内存区域的开头地址,您必须使用数组的名称,而要获得该数组的单个字符的地址,您必须使用这样的 sintax:&name[i]。
您正在使用 scanf 读取字符串,该字符串是 C 中的 char 数组。 scanf 需要与要读取的变量类型关联的内存区域的地址。在这种情况下,您正在读取一个数组,因此您只需使用名称。如果要读取单个变量而不是数组,则必须使用 & 符号。例如:
char myChar;
scanf("%c", &myChar);
我希望这会有所帮助。