why do we use '&' operator in scanf like scanf("%d", &x); but why not
in printf() like printf("%d" , x);
In addition to the other (correct) answers about scanf()'s need for
a pointer to any given variable in order to make a change to that
variable's value, note that printf() and scanf() are not symmetric
in the first place. That is, there are directives for printf() that
mean something quite different in scanf(), and vice versa. I
mention this because the names and other similarities make people
think they "work the same", but they do not.
Consider, for instance:
int width, maxlen;
char *str;
... set up the variables ...
printf("%*.*s\n", width, maxlen, str);
which prints a string in the given field width, using at most
"maxlen" characters of the string. For scanf(), however, "%*s"
does not mean "find a width" but rather "suppress assignment",
and to set a maximum length you must use a literal numeric
value:
char buf[100];
int ret;
...
ret = scanf("%99s", buf);
Here scanf() will write at most 100 characters into buf[], and if
ret is not 0 or EOF (and 0 just happens to be impossible), at least
two. The last written byte will be the '\0' that terminates a C
string.
On the other hand, with printf() you can even supply an ordinary
array that is not '\0'-terminated:
char s[4] = { '1', '2', '3', '4' };
...
printf("%.4s\n", s); /* prints "1234", even though s has no '\0' */
So: printf() %s can handle arrays without '\0', but scanf() %s
always produces arrays with '\0'; %* in printf() means field-width
but %* in scanf() means suppress assignment; printf() takes %f to
print float or double, but scanf() takes %f to read float and %lf
to read double; and so on. Despite surface similarities, these
are as different beasts as a house cat and a Siberian tiger.