c - 在赋值中使用后缀/后缀运算符

标签 c

在赋值运算符的 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) 更可取。 (有关这种未定义行为的更多信息 - 更多,请参阅 this beleaguered old question。)

(5)

*p = toupper(*p++);

这更糟。它同样可能未定义,但如果它能正常工作,它可能会过快地增加 p

(6) 另一种安排是通过使用 for 循环代替将增量放入循环头中:

for(; *p; p++)
    *p = toupper(*p);

这样也行。

关于c - 在赋值中使用后缀/后缀运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66146760/

相关文章:

c - 在C中输入和反转多个字符串?

c - char arr[0] 的含义

c - 当我将字符串文字分配给非常量指针时,为什么我的 C 编译器不发出警告?

C:将字符串读入动态数组

c - 交换 "C"中句子中的单词

android - 从 GetStringUTFChars JNI 得不到结果

c# - 将 C 中的外部 DLL 附加到 c# 中的 WinForm 项目

c - 交换时无需担心数据类型

c - 如何使用 C 将单个文件复制到 Linux 中的不同分区

c - 一个 POSIX 兼容的操作系统通常会扩展 C 标准库的现有实现?