繁体   English   中英

scanf()(C语言)让我困惑

[英]scanf() (C Language ) confused me

我什么时候需要在C中插入/不插入& for 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

scanf将扫描的值放入其参数指向的地址中。 &是地址运算符,它用于获取变量的地址。

但是,您正在使用数组,并且当用作函数参数时,数组会降级为指针。 因此,在数组的情况下,您不需要使用&运算符。

例:

char s[81];
int n;
int* nptr;
//Initialize nptr to some meaningful value
scanf("%s %d %d",s,&n,nptr);

在这种情况下,我们需要使用&运算符来保存地址。 我们不需要将它与nptr一起使用,因为它已经是指向内存中某个位置的指针,也不是s,因为当数组传递给函数时,数组会被降级为指针。

格式说明符后面的参数必须是指针。 将数组名称传递给函数时,将传递初始元素位置 ,因此您不需要在示例中使用& 你可以这样做(来自K&R ):

int day, year;
char monthname[20];

scanf("%d %s %d", &day, monthname, &year);

由于日期和年份都是int ,因此必须使用&来获取这些变量的地址。 由于monthname是一个数组,无&是必需的。

在C中,当您处理数组时:

int c_array[24];
c_array == &c_array == &c_array[0]

是的,它很有趣 - 它们看起来一样(区别在于类型)。 这个

从comp.lang.c常见问题解答: 我认为你总是需要传递给scanf每个变量&

我强烈建议您阅读comp.lang.c常见问题的其余部分。

s1返回数组第一个元素的地址,而&s1返回数组本身的地址。 第一个元素的地址和数组本身的地址是相同的,因此两个表示都起作用。

只是一个猜测,但我认为这是因为s1s2s3是数组。

如果a是一个数组,则a&a在此上下文中生成指针:

  • a由于数组衰减到指针(C99, §6.3.2.1/ 3 ):

    除非它是sizeof运算符或一元&运算符的操作数 ,或者是用于初始化数组的字符串文字,否则将类型为''array of type''的表达式转换为类型为''指针的表达式type''指向数组对象的初始元素,而不是左值。

    ...重点补充

  • &a作为&运算符的结果 - 它返回指向对象的指针。

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

通常,您可以像在未注释的行中一样使用scanf。 C数组的工作方式是s1,s2等数组的名称,而s3实际上是数组第一个元素的地址。 但是对于任何基元,您必须使用&variable语法。 例如:

float f;
scanf("%f", &f);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM