语言是否需要 preIncrement (++x) 和 postIncrement (x++)

发布于 2024-08-26 15:45:18 字数 250 浏览 7 评论 0原文

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

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

    y = x++

    y = x
    x += 1

I have never seen the usecase for pre-increment and post-increment in actual code. The only place i see them most often are puzzles.
My opinion is, it introduces more confusion rather than being useful.

  • is there any real use case scenario for this
  • can't this can be done by using +=

    y = x++

    y = x
    x += 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我不在是我 2024-09-02 15:45:18

这只是编写相同内容的更简短的方式,并且只会让那些不深入了解 C (a) 的人感到困惑。同样的论点可以用于替换:

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

与:

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

因为任何 for 也可以用 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 语句。

It's just a shorter way of writing the same thing and it's only confusing to those who don't deeply understand C (a). The same argument could be made for replacing:

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

with:

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

since any for can also be done with while, or:

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

since any loop construct can be built out of conditions and goto. But (I'm hoping) you wouldn't do that, would you?


(a) I sometimes like to explain this to my students as simple statements and side effects, something that allows C code to be more succinct with usually no or minimal loss in readability.

For the statement:

y = x++;

the statement is assigning x to y with the side effect that x is incremented afterwards. ++x is the same, it's just that the side effect happens beforehand.

Similarly, the side effect of an assignment is that it evaluates as the value assigned, meaning you can do things like:

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

and which makes things like:

42;

perfectly valid, but useless, C statements.

忱杏 2024-09-02 15:45:18

如果您根据历史和构思时间来考虑前自增和后自增运算符,它们就更有意义。

早在 C 基本上是 PDP-11 机器的高级汇编器的时代,早在我们拥有现在拥有的优秀优化编译器之前,就有一些常见的习惯用法后增量运算符非常适合。像这样的事情:

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;.... 毕竟,我能想到的 += 没有任何用例场景无法通过 _ = _ + _ 很好地服务 相反。

The pre- and post-increment operators make much more sense if you consider them in the light of history and when they were conceived.

Back in the days when C was basically a high-level assembler for PDP-11 machines</flamebait>, and long before we had the nice optimizing compilers we have now, there were common idioms used that the post-increment operators were perfect for. Things like this:

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

The code in question generated PDP-11 (or other) machine language code that made heavy use of the underlying addressing modes (like relative direct and relative indirect) that incorporated exactly these kinds of pre- and post-increment and decrement operations.

So to answer your question: do languages "need" these nowadays? No, of course not. It's provable that you need very little in terms of instructions to compute things. The question is more interesting if you ask "are these features desirable?" To that I'd answer a qualified "yes".

Using your examples:

y = x;
x += 1;

vs.

y = x++;

I can see two advantages right off the top of my head.

  1. The code is more succinct. Everything I need to know to understand what you're doing is in one place (as long as I know the language, naturally!) instead of spread out. "Spreading out" across two lines seems like a picky thing but if you're doing thousands of them it can make a big difference in the end.
  2. It is far more likely that the code generated even by a crappy compiler will be atomic in the second case. In the first case it very likely will not be unless you have a nice compiler. (Not all platforms have good, strong optimizing compilers.)

Also, I find it very telling that you're talking about += when that itself is an "unneeded" way of saying x = x + 1;.... After all there is no use case scenario I can think of for += that couldn't be served fine by _ = _ + _ instead.

好倦 2024-09-02 15:45:18

你不小心在这里提出了一个更大的问题,随着时间的推移,这个问题会让你越来越了解。

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

尽量牢记以下几点: 目标不是创建代码供有能力的工程师阅读。我们的目标是为有能力的工程师创建代码,让他在凌晨 3 点筋疲力尽、喝了咖啡因后可以阅读。

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

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

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

您可以在这里找到关于此类事情的有趣对话:
为什么要避免递增(“++”)和递减(“--” JavaScript 中的 ) 运算符?

You're accidentally raising a much larger issue here, and it's one that will make itself more and more known to you as the years (decades) go by.

Languages often make the mistake of supplying "abilities" when they shouldn't. IMO, ++ should be a stand-alone statement only, and absolutely not an expression operator.

Try to keep the following close to heart: The goal is not to create code for the competent engineer to read. The goal is to create code for the competent engineer to read when he is exhausted at 3am and hopped up on caffeine.

If an engineer says to you "All code constructs can get you into trouble. You just have to know what you're doing.", then walk away laughing, because he's just exposed himself as part of the problem.

In other words, please don't ever code anything like this:

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

You can find a interesting conversation about this kind of thing here:
Why avoid increment ("++") and decrement ("--") operators in JavaScript?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文