user3796109
user3796109

Reputation:

Weird C Output Order of Operations

I am learning from a C textbook that has the following code for taking input and printing it out:

#include <stdio.h>
main(){
  int c;
  while ((c=getchar())!=EOF)
    putchar(c);
    printf("%c\n", c);
}

To try to understand how the syntax works, I fiddled with the code block above, namely deleting the pair of parentheses surrounding c=getchar(). So the code now looks as follows:

#include <stdio.h>
main(){
  int c;
  while (c=getchar()!=EOF)
    putchar(c);
    printf("%c\n", c);
}

Everything still works as expected, but, now every line (input and output) except the first is preceded by two frowny faces :( :( when I run the .exe file. The textbook says the pair of parentheses I removed is necessary because != would be done before the assignment (since !=has higher precedence than =), but I don't understand why the modified code prints out the frowny-face characters...

Upvotes: 0

Views: 107

Answers (4)

David C. Rankin
David C. Rankin

Reputation: 84559

Any time you are performing an assignment within a conditional expression, you must enclose the assignment in parentheses. As others have noted, otherwise, the conditional is evaluated before the assignment. You need to get in the habit of passing additional flags to tell the compiler to output ALL warnings. At a minimum -Wall (to show all warnings). For example:

gcc -Wall yourfile.c -o output

If you had attempted compiling with -Wall, you would have received:

warning: suggest parentheses around assignment used as truth value [-Wparentheses]
while (c=getchar()!=EOF)
^

This will allow you to catch many more potential problems than compiling without warnings.

Upvotes: 0

Yu Hao
Yu Hao

Reputation: 122383

while(c = getchar() != EOF) {...}

Here, c is not assigned the return value of getchar, but rather the value of the expression getchar() != EOF, which is either 1 or 0 depending on whether it's true.

So the output is actually the ASCII 1. They are not printable characters. Your machine outputs ASCII 1 as a frowny face.

Upvotes: 1

Ed Swangren
Ed Swangren

Reputation: 124672

c = getchar() != EOF

Operator precedence: http://en.cppreference.com/w/cpp/language/operator_precedence

See the = way down below the !=? That's why. Your code (conceptually) evaluates to this:

int x = getchar() != EOF;
int c = x;

The parentheses were not optional. You version:

c = (getchar != EOF)

Is not the same as:

(c = getchar()) != EOF

Upvotes: 1

Jim Balter
Jim Balter

Reputation: 16406

getchar()!=EOF

Is equal to 1 when the char read isn't EOF. So you're setting c to 1 and then printing that ... it comes out as the "frowny face" you're seeing.

To try to understand how the syntax works

While test cases are good to checking out your understanding of the syntactic and semantic rules of the language, they aren't good for learning them. There are many texts and tutorials that explain C's syntax, particularly its expression syntax and precedence rules.

Upvotes: 1

Related Questions