Reputation:
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
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
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
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
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