Confusing Operator Precedence

Peculiar things can happen if you ignore operator precedence:

main()

{

int ch;

while( ch = getch() != '\r' )

printf( "%d\n", ch );

}

Instead of assigning the result of the getch library-function call to ch, the above code assigns the value 0 to ch when you press the ENTER key and the value 1 when you press any other key. (The values 1 and 0 represent true and false.)

The error occurs because the inequality operator (!=) has higher precedence than the assignment operator (=). The expression

ch = getch() != '\r'

is the same as

ch = (getch() != '\r')

Both expressions compare the result of the getch call to the character constant \r. The result of that comparison is then assigned to ch.

For the program to work correctly, these operations must happen in the reverse order. The result of the function call must be assigned to the variable before the variable is compared to the constant. We can solve the problem by adding parentheses:

main()

{

int ch;

while( (ch = getch()) != '\r')

printf( "%d\n", ch );

}

Parentheses have the highest precedence of any operator, so the expression

(ch = getch()) != '\r'

works correctly. It assigns the result of the getch call to ch before comparing ch to the constant.

The list of precedence-related errors is almost endless. Fortunately, QuickC makes it unnecessary to memorize precedence rules. To view a complete table of operator precedences, see Appendix A, “C Language Guide,” and online help in the Graphical Development Environment.

Summary: Use parentheses to avoid operator precedence problems.

When in doubt, use extra parentheses to make the order of operations absolutely clear. Extra parentheses don't degrade performance, and they can improve readability as well as minimize precedence problems.