Programming languages 语言是否需要预增量(+;+;x)和后增量(x+;+;)

Programming languages 语言是否需要预增量(+;+;x)和后增量(x+;+;),programming-languages,increment,post-increment,pre-increment,Programming Languages,Increment,Post Increment,Pre Increment,我从未在实际代码中看到过增量前和增量后的用例。我最常看到它们的地方是拼图。 我的意见是,它带来了更多的混乱,而不是有用的 这有什么实际的用例场景吗 难道这不能通过使用+= y=x++ y=x x+=1 这只是写同样东西的一种较短的方式,只会让那些对C(a)没有深刻理解的人感到困惑。同样的理由也可以用来取代: for (i = 0; i < 10; i++) printf ("%d\n", i); 因为任何循环构造都可以根据条件和goto构建。但是(我希望)你不会那样做,是吗

我从未在实际代码中看到过增量前增量后的用例。我最常看到它们的地方是拼图。
我的意见是,它带来了更多的混乱,而不是有用的

  • 这有什么实际的用例场景吗
  • 难道这不能通过使用+=

    y=x++

    y=x

    x+=1


这只是写同样东西的一种较短的方式,只会让那些对C(a)没有深刻理解的人感到困惑。同样的理由也可以用来取代:

for (i = 0; i < 10; i++)
    printf ("%d\n", i);
因为任何循环构造都可以根据条件和
goto
构建。但是(我希望)你不会那样做,是吗


(a) 我有时喜欢向我的学生解释这一点,将其解释为简单的语句和副作用,这使得C代码更加简洁,可读性通常没有损失或损失最小

声明如下:

y = x++;
语句将
x
赋值给
y
,其副作用是
x
随后递增
++x
是一样的,只是副作用提前发生了

类似地,赋值的副作用是它作为赋值进行计算,这意味着您可以执行以下操作:

while ((c = getchar()) != -1) count++;
42;
这让事情变得像:

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

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

< P>前和后增量运算符如果从历史和构思的角度考虑它们,则更有意义。

早在C基本上是PDP-11机器的高级汇编程序的时候,早在我们拥有优秀的优化编译器之前,就已经有了一些常用的习语,这些习语是增量后操作符的完美之选。诸如此类:

char* strcpy(char* src, char* dest)
{
  /* highly simplified version and likely not compileable as-is */
  while (*dest++ = *src++);
  return dest;
}
a[aIndex++] = b[++bIndex];
所讨论的代码生成了PDP-11(或其他)机器语言代码,大量使用了底层寻址模式(如相对直接和相对间接),这些寻址模式正好包含了这种前后递增和递减操作

那么回答你的问题:现在语言“需要”这些吗?不,当然不是。可以证明,在计算东西的指令方面,你几乎不需要什么。如果你问“这些特性值得拥有吗?”这个问题更有趣,我会回答一个合格的“是”

使用您的示例:

y = x;
x += 1;
vs

我一眼就能看出两个好处

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

  • 另外,我发现你说的是
    +=
    ,而这本身就是一种“不必要的”表达方式
    x=x+1。。。。毕竟,对于
    +=
    ,我想不出一个用例场景,而
    +=
    却不能很好地解决这个问题。

    你无意中在这里提出了一个更大的问题,随着岁月的流逝,这个问题会越来越为你所知

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

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

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

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

    char* strcpy(char* src, char* dest)
    {
      /* highly simplified version and likely not compileable as-is */
      while (*dest++ = *src++);
      return dest;
    }
    
    a[aIndex++] = b[++bIndex];
    
    你可以在这里找到关于这类事情的有趣对话:

    有必要吗?我没有必要喝自己的尿液,但它是无菌的,我喜欢它的味道Patches O'Houlihan你是一名计算机科学工程专业的学生,你觉得x++和++x之间的区别令人困惑吗?你从来没有发现用不同的方式来表达相似的东西是有用的吗?更进一步地说:虽然我认为提问者是“错的”,但我更坚定地相信这是一个真正的问题。为什么不为(I=0;I<10;I+=1)
    无效strcpy(char*a,char*b){而(*a++=*b++)}
    @Ananantha,你没有抓住重点。我想说的是,对于特定的情况,您将使用“for”而不是“while”(在这种情况下,I++/I++=1的区别是不相关的)。一句话:使用您可用的语言功能。理解它们。啊,当你写最后一条语句时,Java(或者至少我的IDE)开始抱怨:它报告了一个错误,消息不是一条语句。@MC,Java在这方面比C有点限制。+1表示历史级别,但我不确定这是flamebait,它确实是一个高级汇编程序(不确定是PDP8还是PDP11)。你的最后一段也是一个很好的观点。回答很好,但我认为一元运算符的语义与二元运算符的语义差别很大。使用
    x[f(y)][g(z)]+=10
    这样的代码实际上比
    x[f(y)][g(z)]=x[f(y)][g(z]更有效+10
    因为编译器在第一种情况下只需计算
    x[f(y)][g(z)]
    一次,但在第二种情况下可能计算两次。@gabe: