3

在实际代码中,我从未见过预增量后增量的用例。我最常看到它们的唯一地方是谜题。
我的观点是,它引入了更多的混乱而不是有用。

  • 是否有任何真实的用例场景
  • 这不能通过使用 += 来完成吗

    y = x++

    y = x
    x += 1

4

3 回答 3

7

这只是写同一件事的一种更短的方式,只会让那些不深入了解 C (a)的人感到困惑。可以为替换提出相同的论点:

for (i = 0; i < 10; i++)
    printf ("%d\n", i);

和:

i = 0;
while (i < 10) {
    printf ("%d\n", i);
    i = i + 1;
}

因为 anyfor也可以用while, 或:

i = 0;
loop: if (i < 10) {
    printf ("%d\n", i);
    i = i + 1;
    goto loop;
}

因为任何循环构造都可以由条件和goto. 但是(我希望)你不会那样做,对吗?


(a)我有时喜欢用简单的语句和副作用向我的学生解释这一点,这可以让 C 代码更简洁,通常不会或最小程度地降低可读性。

对于声明:

y = x++;

语句分配x给具有随后递增y的副作用。是一样的,只是副作用是提前发生的。x++x

同样,赋值的副作用是它评估为所分配的值,这意味着您可以执行以下操作:

while ((c = getchar()) != -1) count++;

这使得事情像:

42;

完全有效但无用的 C 语句。

于 2010-03-25T05:36:59.933 回答
6

如果您根据历史和构思它们的时间来考虑它们,那么前置和后置增量运算符会更有意义。

早在 C 基本上是 PDP-11 机器的高级汇编程序的日子里</flamebait>,早在我们拥有现在拥有的良好优化编译器之前,就有一些常用的习惯用法非常适合后增量运算符。像这样的事情:

char* strcpy(char* src, char* dest)
{
  /* highly simplified version and likely not compileable as-is */
  while (*dest++ = *src++);
  return dest;
}

有问题的代码生成了 PDP-11(或其他)机器语言代码,这些代码大量使用了底层寻址模式(如相对直接和相对间接),这些寻址模式正好结合了这些类型的前后递增和递减操作。

所以回答你的问题:现在语言“需要”这些吗?不,当然不。可以证明,就计算事物而言,您只需要很少的指令。如果您问“这些功能是否可取?”,这个问题会更有趣。对此,我会回答一个合格的“是”。

使用您的示例:

y = x;
x += 1;

对比

y = x++;

我可以立即看到两个优势。

  1. 代码更简洁。为了理解你在做什么,我需要知道的一切都在一个地方(只要我知道语言,自然!)而不是分散开来。跨两条线“展开”似乎是一件很挑剔的事情,但如果你要做数千条线,最终会产生很大的不同。
  2. 在第二种情况下,即使是由糟糕的编译器生成的代码也更有可能是原子的。在第一种情况下,除非你有一个好的编译器,否则它很可能不会。(并非所有平台都有良好、强大的优化编译器。)

此外,我发现你在谈论+=它本身是一种“不需要”的说法时非常有说服力x = x + 1;......毕竟没有我能想到的用例场景,因为+=它不能很好地_ = _ + _代替.

于 2010-03-25T05:41:48.793 回答
0

你在这里不小心提出了一个更大的问题,随着岁月的流逝,它会让你越来越了解它。

语言经常犯错误,在不应该提供“能力”的情况下。IMO, ++ 应该只是一个独立的语句,绝对不是表达式运算符。

尽量牢记以下几点:目标不是创建代码供有能力的工程师阅读。目标是创建代码,让有能力的工程师在凌晨 3 点筋疲力尽并开始喝咖啡时阅读。

如果一个工程师对你说“所有的代码结构都会给你带来麻烦。你只需要知道你在做什么。”然后笑着走开,因为他只是暴露了自己是问题的一部分。

换句话说,请不要编写这样的代码:

a[aIndex++] = b[++bIndex];

你可以在这里找到一个关于这种事情的有趣对话: 为什么要避免 JavaScript 中的自增 ("++") 和自减 ("--") 运算符?

于 2014-12-06T14:41:54.227 回答