我何时需要在C中插入/不插入&
scanf()
?谢谢。
int main()
{
char s1[81], s2[81], s3[81];
scanf("%s%s%s", s1, s2, s3);
// If replace scanf() with the expression below, it works too.
// scanf("%s%s%s", &s1, &s2, &s3);
printf("\ns1 = %s\ns2 = %s\ns3 = %s", s1, s2, s3);
return 0;
}
//programming is fun
//
//s1 = programming
//s2 = is
//s3 = fun
答案 0 :(得分:9)
scanf将扫描的值放在其参数指向的地址中。 &是地址运算符,它用于获取变量的地址。
但是,您正在使用数组,并且当用作函数参数时,数组会降级为指针。所以,你不需要使用&数组的运算符。
示例:
char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);
在这种情况下,我们需要使用&运营商得到的地址是n保留。我们不需要将它与nptr一起使用,因为它已经是指向内存中某个位置的指针,也不是s,因为当数组传递给函数时,数组会被降级为指针。
答案 1 :(得分:6)
格式说明符后面的参数必须是指针。将数组名称传递给函数时,将传递初始元素的位置,因此您的示例中根本不需要使用&
。你可以这样做(来自K&R):
int day, year;
char monthname[20];
scanf("%d %s %d", &day, monthname, &year);
由于日期和年份为int
,您必须使用&
来获取这些变量的地址。由于monthname
是一个数组,因此不需要&
。
答案 2 :(得分:4)
答案 3 :(得分:3)
来自comp.lang.c FAQ:I thought you always needed an &
on each variable passed to scanf
.
我强烈建议您阅读其余的comp.lang.c FAQ。
答案 4 :(得分:2)
s1
返回数组第一个元素的地址,而&s1
返回数组本身的地址。第一个元素的地址和数组本身的地址是相同的,因此两个表示都可以工作。
答案 5 :(得分:1)
只是一个猜测,但我认为这是因为s1
,s2
和s3
是数组。
答案 6 :(得分:1)
如果a
是一个数组,则a
和&a
都会在此上下文中生成指针:
a
由于数组衰减为指针(C99,§6.3.2.1/ 3 )而导致:
除非是sizeof运算符或一元&运算符的操作数。运算符,或者是用于初始化数组的字符串文字,具有类型''数组类型''的表达式将转换为类型为''指向类型'的指针的表达式,指向数组对象的初始元素并且不是左值。
...强调添加
&a
作为&
运算符的结果 - 它返回指向对象的指针。
答案 7 :(得分:1)
Scanf接受可变数量的参数。 scanf的第一个参数是格式,然后n表示要存储的值,而n是格式字符串中指定的格式数。因为您正在使用数组,所以要存储您必须提供数组基址的值。
//If int int i; scanf("%d",&i); // store int value at address &i float f; scanf("%f",&f); //store float value at address &f int a[10]; scanf("%s",a); //store string or array value at a
如果在最后一行中使用a会让您感到困惑,您可以尝试使用第一个元素的地址进行相同的操作,即& a [0]。
希望它有所帮助,
GG
答案 8 :(得分:0)
通常,您可以像在未注释的行中那样使用scanf。 C数组的工作方式是s1,s2等数组的名称,而s3实际上是数组第一个元素的地址。但是对于任何基元,您必须使用& variable语法。例如:
float f;
scanf("%f", &f);