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);
}
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.
The ampersand symbol is required in both cases. scanf requires pointers (you were probably thinking of char* or char[] - they are pointers themselves).
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
.
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()
.
You need to provide scanf with pointer, that's why you have & in scanf("%d",&a);
. scanf("%c"c); will not work at all.
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 &
.
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.