I've been working the exercises from K&R: The C Programming Language and noticed something that confused me a bit.
#include <stdio.h>
#define BLANK ' '
int c;
int d;
d = 0;
c = getchar();
When I execute this code, getchar() is called even though it's assigned to the variable 'c', yet 'c' was never called. I also just changed the variable 'c' to
c = printf("hi");
which prints "hi" when the program is executed. So, this behavior is consistent but it still doesn't make sense to me.
CodePudding user response:
This is fairly standard for many imperative programming languages1 - the statement c = getchar();
means that the program should, at that point in time, invoke getchar()
(which reads a character from the standard input, waiting if necessary), and store its return value to some storage location that was allocated for the variable called c
. The fact that you do not use c
later is irrelevant (note that I use the word "use" and not the word "call" as you did; we do not call variables).
In your second example with printf
, you have a function with a very visible side effect (printing to the console). Again, that side effect occurs when the statement c = printf(...)
is executed, not when c
is later used.
You'll also notice that in the following snippet, getchar is only called once, regardless of whether you use the value of c
zero times, once, twice, or even more:
int c;
c = getchar();
printf("%c", c);
printf("%c", c);
1 There are other families of languages, where you indeed do have variables that refer to computation that hasn't happened yet. Such a thing often occurs in functional languages in various scenarios, but C does not fall into that category.
2 This question deals with two functions that have side effects and/or are impure. If you study the language more deeply and start learning about things like concurrent programming or compiler design, you should know that these rules apply to visible effects, such as the side effects you observed. If a function only does a calculation as a result of its input parameters with no outside influence (like the console input or reading shared memory locations) or side effect (like console output or writing to shared memory locations), then there are more subtle effects (such as the compiler reordering things whose effects you can't see, to achieve improved efficiency, while still ensuring that the side effects that you can see follow the rules discussed here)
CodePudding user response:
If you had c = &getchar
(but then c
would have to be of type int (*)(void)
and not int
), it would be as you described, because then you'd save a function pointer to getchar
in c
. You'd then be able to do c()
later on.
But you have getchar()
here which is already a function invocation! So the function gets called (using operator ()
) at this line, and the result is stored in c
.