Behaviour of scanf() [duplicate]

2019-01-25 23:32发布

问题:

Possible Duplicate:
confusion in scanf() with & operator

Why we need a & in scanf for inputting integer and why not for characters. Do the & in scanf refers to merory location while getting input.

Eg:-

main()
{
int a;
char c;

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

回答1:

For each conversion specifier, scanf() expects the corresponding argument to be a pointer to the proper type: %d expects an argument of type int *, %f expects an argument of type double *, %c and %s both expect an argument of type char *, etc.

The difference between %c and %s is that the former tells scanf() to read a single character and store it in the location specified by the corresponding argument, while the latter tells scanf() to read multiple characters until it sees a 0-valued character and store all those characters in the buffer starting at the location specified by the argument.

You need to use the & operator on your arguments if they are not already of pointer type. For example:

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.

Where things get confusing is reading strings of characters (using the %s conversion specifier):

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

Why don't we need the & operator in this case? It has to do with how C treats array expressions. When the compiler sees an expression of array type (such as buf in the scanf() call), it will implicitly convert the expression from type N-element array of T to pointer to T, and set its value to the address of the first element in the array. This value is not an lvalue -- it cannot be assigned to (so you can't write something like buf = foo). The only exceptions to this rule are when the array expression is an operand of either the sizeof or & operators, or if the array expression is a string literal being used to initialize another array:

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

In short, the expression buf is implicitly converted from type char [SIZE] to char *, so we don't need to use the & operator, and in fact the type of the expression &buf would be pointer to SIZE-element array of char, or (*)[SIZE], which is not what scanf() expects for the %s conversion specifier.



回答2:

The ampersand symbol is required in both cases. scanf requires pointers (you were probably thinking of char* or char[] - they are pointers themselves).



回答3:

Scanf reads input to a memory address. a is the value held by a. &a is the location of a in memory.

In your code above, the c should be &c.



回答4:

Because scanf() needs pointers, and &a is the pointer to an integer.

In your example, you need a comma and an ampersand in front of the 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);

}

If you were reading a string, you would pass the string - a pointer to char - to scanf().



回答5:

You need to provide scanf with pointer, that's why you have & in scanf("%d",&a); . scanf("%c"c); will not work at all.



回答6:

Your example is wrong. If you have a

char c;

then you need to add an & to the name when calling scanf:

scanf("%c", &c);

However, if your variable is already a pointer, for example because it is a char[] (which is a fancy syntax for pointers), you have to omit the &.



回答7:

I like to think of the ampersand (&) as "address of". So you'd read &a as "address of a".

Also, I tried compiling this but it warned me on gcc:

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

Which is true, since a char is basically an int.



标签: c scanf