K&R Exercise 1-6 & 1-7: working with EOF I'm working through K&amp;R at the moment and I've found my first exercise that seems to be a good use for my first CodeReview post.

Exercise 1-6 - Verify that the expression getchar() != EOF is 0 or 1.

Exercise 1-7 - Write a program to print the value of EOF.

I've completed both of these together in the same file. 

I think I've understood the question here, but let me know if I haven't. I wanted to post here before looking up any sort of "official" answer so that I could learn some stuff instead of just "going to the back of the book".

#include &lt;stdio.h&gt;

void main()
{
        int c;

        c = getchar();
        while ((c = getchar()) != EOF == (0 | 1)) {
                putchar(c);
        }
        printf("%d\n", EOF);
}


Compiled with:

gcc putchar.c -o putchar


Sending EOF using:

&lt;ctrl-d&gt;


Runs through fine, and when I ctrl-d I get a -1 return code.
This is a nice, clear, short attempt at the exercise.
You've avoided a couple of common problems:

You're correctly using int for the return value from getchar().  A common mistake is to be misled by the name and to assign directly to a char variable.  That doesn't work, because truncating to char prevents EOF from being distinguished from a valid char value.
You've correctly matched the %d specifier to the type of EOF.


One simple way to improve your code is to get the compiler to point out weaknesses for you (by default, most C compilers are very lenient; you have to specifically ask for more warnings):
gcc -std=c11 -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Wconversion putchar.c -o putchar

You can make it easier by writing a simple Makefile that contains just:
CFLAGS = -std=c11 -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Wconversion

And you can then build simply with
make putchar

When you've enabled warnings, you'll see:
198374.c:3:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
 void main()
      ^~~~

The fix for that should be obvious.

Now to the meat of the program.  Firstly, before the loop we have a statement
    c = getchar();

This consumes and ignores one character.  We probably didn't mean to throw that one away.

Now consider this expression:
 (c = getchar()) != EOF == (0 | 1)

We're actually comparing (after the assignment) c != EOF against 0|1.  But | is the bitwise-or operator, so 0|1 evaluates to just 1.  When c is not EOF, then c!=EOF is 1, and the condition is satisfied.  The last time around the loop (when c becomes EOF), then c!=EOF is 0, and the loop exits.
What we want to do is save the result of c != EOF and compare that to 0 and to 1 separately.  Or, even more simply for this exercise, just print it to standard output:
    do {
        c = getchar();
        printf(&quot;getchar() != EOF: %d\n&quot;, c != EOF);
    } while (c != EOF);

Note: given that we haven't been asked to copy the input to output, we shouldn't have the putchar() call.
If we really want to prove that c != EOF is always either 0 or 1, we could test it automatically:
    do {
        c = getchar();
        if ((c != EOF) != 0  &amp;&amp;  (c != EOF) != 1) {
            fprintf(stderr, &quot;(c != EOF) was neither 0 nor 1\n&quot;);
            return 1;
        }
    } while (c != EOF);

You might choose to use a switch statement instead of the if; I think that's clearer:
        c = getchar();
        switch (c != EOF) {
        case 0:             /* okay */
        case 1:             /* okay */
            break;
        default:
            fprintf(stderr, &quot;(c != EOF) was neither 0 nor 1\n&quot;);
            return 1;
        }


Modified code
#include &lt;stdio.h&gt;

int main()
{
        int c;

        do {
            c = getchar();
            switch (c != EOF) {
            case 0:             /* okay */
            case 1:             /* okay */
                break;
            default:
                fprintf(stderr, &quot;(c != EOF) was neither 0 nor 1\n&quot;);
                return 1;
            }
        } while (c != EOF);

        printf(&quot;%d\n&quot;, c);
}