Why do you require ampersand (&) in the scanf function. What will the output or type of error (compile or runtime) be in the following C code?
In C, all function arguments are passed by value; any changes to the function's formal parameter are not reflected in the actual parameter. For example:
void foo(int bar)
{
bar = bar + 1;
}
int main(void)
{
int x = 0;
printf("x before foo = %d\n", x);
foo(x);
printf("x after foo = %d\n", x);
return 0;
}
The output of the program will be
x before foo = 0 x after foo = 0
because bar receives the value of x (0), not a reference to x itself. Changing bar has no effect on x.
In C, the way around this is to pass a pointer to a variable:
void foo(int *bar)
{
*bar = *bar + 1;
}
int main(void)
{
int x = 0;
printf("x before foo = %d\n", x);
foo(&x);
printf("x after foo = %d\n", x);
return 0;
}
Now the output of the program is
x before foo = 0 x after foo = 1
This time, the formal parameter bar is not an int, but a pointer to int, and it receives the address of x (given by the expression &x in the call to foo), not the value contained in x. The expression *bar means "get the value in the location bar points to", so *bar = *bar + 1 corresponds to x = x + 1.
Since scanf() needs to write to its arguments, it expects those arguments to typed as pointers. The "%d" conversion specifier expects the corresponding argument to be a pointer to int (int *), the "%u" conversion specifier expects a pointer to unsigned int (unsigned *), "%s" expects a pointer to char (char *), "%f" expects a pointer to float (float *), etc. In your example, since a is typed int, you need to use the expression &a to get a pointer.
Note that if a were already a pointer type, you would not need to use the & operator in the call to scanf():
int main(void)
{
int a, *pa; // declare pa as a pointer to int
...
pa = &a; // assign address of a to pa
scanf("%d", pa); // scanf() will write to a through pa
...
}
Note also that when passing an array to a function (such as when using the "%s" conversion specifier to read a string), you don't need to use the & operator; the array expression will implicitly be converted to a pointer type:
int main(void)
{
char name[20];
...
scanf("%19s", name); // name implicitly converted from "char [20]" to "char *"
...
}