在赋值中使用后缀/后缀运算符
在赋值运算符的 lhs 上使用后/前缀运算符是否可以接受?
#include<ctype.h>
void to_upper_in_place(char* string)
{
while(*string++ = toupper(*string));
}
如果没问题,之前被认为是可读的 C 代码,还是应该变成下面这样的?
#include<ctype.h>
void to_upper_in_place(char* string)
{
while(*string) {
*string = toupper(*string);
string++;
}
}
甚至:
while(*string = toupper(*string++));
回答
让我们看几个不同的案例。
(1)(有两个不同的指针)
*dest++ = toupper(*src++);
这是完全普通的 C 风格。
(2)
*dest = toupper(*src);
src++;
dest++;
这是“长手”风格。如果您害怕++
以危险的方式使用,您可以编写它。(正如我们即将看到的那样,一定程度的谨慎确实是合理的。)
(3)(回到lhs和rhs上的同一个指针)
*p = toupper(p);
p++;
这可以。
(4)
*p++ = toupper(*p);
这是有问题的,因为p
在同一个表达式中使用和修改,修改不取决于使用的值。在许多/大多数情况下,此模式呈现表达式undefined,这是一件坏事。最终很难说这个特殊情况是否实际上是未定义的,但出于这个原因,我们必须保持安全,并说 (3) 更可取。(欲了解更多-多更多-在这种不确定的行为,看到这个陷入困境的老问题。)
(5)
*p = toupper(*p++);
这更糟。它同样可能是未定义的,但如果它真的有效,它可能会增加p
得太快。
(6) 另一种安排是将增量放入循环头中,使用for
循环代替:
for(; *p; p++)
*p = toupper(*p);
这也很好。