简体   繁体   English

C 中的表达式评估

[英]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?所以基本上,这( x[num++] = getchar() )等于什么,以便将其与空格进行比较?

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?我在我的一本 class 书中找到了这个例子,它是不同的,我收到了一个警告,所以我想这是一个不好的做法,是吗? How does the evaluation go here? go这里怎么评价? Does it first assign the read value to x[num] and then compares it to space?它是否首先将读取值分配给x[num]然后将其与空间进行比较?

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

In C, a = b is an expression .在 C 中, a = b是一个表达式 It assigns b to a , and then returns a .它将b分配给a ,然后返回a Therefore, the condition in the while loop means:因此,while循环中的条件意味着:

  1. Call getchar() to get the user's input调用getchar()获取用户的输入
  2. Assign the result of getchar to x[num] .getchar的结果分配给x[num]
  3. Increase num by 1num增加 1
  4. Check if x[num] is not equal to a space ' ' .检查x[num]是否不等于空格' '

ie 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调用getchar()获取用户的输入
  2. Check if x[num] is not equal to a space ' ' .检查x[num]是否不等于空格' '
  3. Assign the result in step 2 ( true or false ) to x[num]将步骤 2 中的结果( truefalse )分配给x[num]
  4. Increase num by 1num增加 1

The warning is because it's easy to mistakenly write while (a = b) to mean while (a == b) .警告是因为很容易错误地将while (a = b)写成表示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.两者都忽略了在读取空间之前到达 EOF 的可能性,并且都忽略了在读取空间之前溢出缓冲区的可能性。

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'.因此,如果getchar()返回“X”,则赋值结果为“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.如果getchar()返回一个空白,那么赋值的结果也是一个空白,空白等于空白,所以循环终止。

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.也就是说, getchar()读取一个字符并与空白进行比较,如果字符不是空白则生成值 1,如果是空白则生成值 0。 This 0 or 1 is assigned to x[num++] , and then evaluated as a logical condition.这个 0 或 1 分配给x[num++] ,然后作为逻辑条件进行评估。 If the result was 0, the loop terminates;如果结果为 0,则循环终止; if the result was 1, the loop continues.如果结果为 1,则循环继续。 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.) (记住:如果你在 6 个月,甚至 6 周后回来,你会变成一个不同的人,可能很难记住这些微妙之处。让每个人都明白。在过度括号之间有一个很好的平衡和括号内的代码。)

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 .请特别注意, c必须是int而不是char

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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