scanf()的行为

时间:2010-08-12 16:57:41

标签: c scanf

  

可能重复:
  confusion in scanf() with & operator

为什么我们需要一个&在scanf中输入整数,为什么不输入字符。 做&在scanf中,在获取输入时指的是merory位置。

例如: -

main()
{
int a;
char c;

scanf("%d",&a);
scanf("%c"c);
}

7 个答案:

答案 0 :(得分:6)

两种情况都需要符号符号。 scanf需要指针(你可能会想到char *或char [] - 它们本身就是指针)。

答案 1 :(得分:6)

对于每个转换说明符,scanf()期望相应的参数是指向正确类型的指针:%d期望类型为int *的参数,%f期望参数类型double *%c%s都期望char *类型的参数等。

%c%s之间的区别在于前者告诉scanf()读取单个字符并将其存储在相应参数指定的位置,而后者告诉scanf()读取多个字符,直到它看到一个0值字符,并将所有这些字符存储在缓冲区中,从参数指定的位置开始。

如果参数不是指针类型,则需要在参数上使用&运算符。例如:

int x;
int *px = some_valid_memory_location_such_as_&x;
char c;
char *pc = some_valid_memory_location_such_as_&c;
...
scanf("%d", &x); // x is not a pointer type, so we must use the & operator
scanf("%d", px); // px is a pointer type, so we don't need the & operator
scanf("%c", &c); // etc.
scanf("%c", pc); // etc.

令人困惑的地方是阅读字符的字符串(使用%s转换说明符):

char buf[SIZE];
scanf("%s", buf);    // expression 'buf' *implicitly* converted to pointer type

在这种情况下,为什么我们不需要&运算符?它与C如何处理数组表达式有关。当编译器看到数组类型的表达式(例如buf调用中的scanf())时,它会隐式地将表达式从类型N-element array of T转换为pointer to T,并设置其value到数组中第一个元素的地址。此值不是左值 - 无法分配(因此您无法编写类似buf = foo的内容)。此规则的唯一例外是当数组表达式是sizeof&运算符的操作数时,或者数组表达式是用于初始化另一个数组的字符串文字时:

char *p = "This is a test";  // string literal implicitly converted to char *,
                             // string *address* written to p
char a[] = "This is a test"; // string literal not implicitly converted,
                             // string *contents* copied to a

简而言之,表达式buf 隐式从类型char [SIZE]转换为char *,因此我们不需要使用{{1} }运算符,实际上表达式&的类型将是&bufpointer to SIZE-element array of char,这不是(*)[SIZE]scanf()转换说明符所期望的。

答案 2 :(得分:2)

Scanf将输入读取到内存地址a是a所持有的值。 &aa在记忆中的位置。

在上面的代码中,c应为&c

答案 3 :(得分:1)

因为scanf()需要指针,&a是指向整数的指针。

在您的示例中,您需要在c前面使用逗号和&符号。

int main(void)
{
    int a;
    char c;
    char s[21];

    scanf("%d",&a);
    scanf("%c", &c);   // Fixed!
    scanf("%20s", s);
    printf("a = %d, c = %c, s = <<%s>>\n", a, c, s);

}

如果你正在读一个字符串,你会把字符串 - 一个指向char的指针 - 传递给scanf()

答案 4 :(得分:0)

您需要使用指针提供 scanf ,这就是 scanf(“%d”,&amp; a)&amp; 的原因; 。的的scanf( “%C” c)中;根本不会工作。

答案 5 :(得分:0)

你的例子是错的。如果你有

char c;

然后,在调用&时,您需要在名称中添加scanf

scanf("%c", &c);

然而,如果你的变量已经是一个指针,例如因为它是一个char[](这是指针的花哨语法),你必须省略{{1} }。

答案 6 :(得分:0)

我喜欢将&符号(&amp;)视为“地址”。因此,您将&a视为“地址”。

另外,我尝试编译这个但是它在gcc上警告我:

Warning: format "%c" expects type 'char *', but argument 2 has type 'int'

这是真的,因为char基本上是一个int。