简体   繁体   中英

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 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 ' ' .

ie

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM