开发者

Expression evaluation in C

while ((x[num++] = getchar()) != ' ');

This reads a char at a time and stops if it encounters a space. But how does it evaluate the parenthesis with开发者_StackOverflow社区 the space? What is the result of the parenthesis? So basically, what does this (x[num++] = getchar()) equal to, in order to compare it to a space?

I found this example in one of my class books, it was different and I got a warning so I guess it's a not good practice is it? How does the evaluation go here? Does it first assign the read value to x[num] and then compares it to space?

while(x[num++] = getchar() != ' ');


In C, a = b is an expression. It assigns b to a, and then returns a. Therefore, the condition in the while loop means:

  1. Call getchar() to get the user's input
  2. Assign the result of getchar to x[num].
  3. Increase num by 1
  4. Check if x[num] is not equal to a space ' '.

i.e.

while (true) {
  x[num] = getchar();
  num ++;
  if (!(x[num] != ' '))
    break;
}

The 2nd example has a totally different behavior. This is because the != expression will be evaluated before the assignment = without the parenthesis. Therefore, the 2nd example means

  1. Call getchar() to get the user's input
  2. Check if x[num] is not equal to a space ' '.
  3. Assign the result in step 2 (true or false) to x[num]
  4. Increase num by 1

The warning is because it's easy to mistakenly write while (a = b) to mean while (a == b).


Neither version is good coding; both ignore the possibility of reaching EOF before reading a space, and both ignore the possibility of overflowing the buffer before reading a space.

The first is otherwise correct. It contains an assignment:

x[num++] = getchar()

The result of an assignment is the value assigned. So, if getchar() returns an 'X', the result of the assignment is 'X'. Then the result of the assignment is compared with blank; they are different, and the loop repeats. If getchar() returns a blank, then the result of the assignment is also a blank, and blank equals blank, so the loop terminates.

The second is plain faulty. Because assignment has a lower precedence than !=, the result is as if the code read:

while (x[num++] = (getchar() != ' '))
    ;

That is, a character is read by getchar() and compared with blank, generating a value 1 if the character is not a blank and 0 if it is a blank. This 0 or 1 is assigned to x[num++], and then evaluated as a logical condition. If the result was 0, the loop terminates; if the result was 1, the loop continues. Note that the characters read are not recorded in this version - which is why the compiler gives the warning. It is almost invariably a mistake; on those odd occasions when it is not a mistake, you can tell the compiler that by providing the extra parentheses to make your intention crystal clear to the compiler - and to your human audience, the other people who will read your code. (Remember: if you come back in 6 months, or even 6 weeks, you'll be a different person and may well have difficulty remembering such subtleties. Make it plain to everyone. There is a fine balance to be drawn between over-parenthesizing and under-parenthesizing code.)

The code should probably read:

int c;
int max = sizeof(x) - 1;
int num = 0;

while ((c = getchar()) != EOF && num < max && (x[num++] = c) != ' ')
    ;

Note, in particular, that c must be an int and not a char.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜