9675

在阅读Hidden Features and Dark Corners of C++/STL oncomp.lang.c++.moderated之后,我完全惊讶于以下代码片段在 Visual Studio 2008 和 G++ 4.4 中编译和工作。

这是代码:

#include <stdio.h>
int main()
{
    int x = 10;
    while (x --> 0) // x goes to 0
    {
        printf("%d ", x);
    }
}

输出:

9 8 7 6 5 4 3 2 1 0

我假设这是 C,因为它也适用于 GCC。这在标准中是哪里定义的,它是从哪里来的?

4

29 回答 29

9378

-->不是运算符。它实际上是两个独立的运算符,-->

条件的代码递减x,同时返回x的原始(未递减)值,然后0使用>运算符比较原始值。

为了更好地理解,该语句可以写成如下:

while( (x--) > 0 )
于 2009-10-29T07:00:09.617 回答
3627

或者对于完全不同的东西......x滑动到0

while (x --\
            \
             \
              \
               > 0)
     printf("%d ", x);

不是那么数学,但是...每张图片都描绘了一千个单词...

于 2012-01-18T11:18:08.440 回答
2519

这是一个非常复杂的运算符,因此甚至ISO/IEC JTC1(联合技术委员会 1)也将其描述放在 C++ 标准的两个不同部分中。

开个玩笑,它们是两个不同的运算符:分别在 C++03 标准的 §5.2.6/2 和 §5.9 中进行了描述-->

于 2009-10-29T08:38:08.740 回答
1563

x可以在相反方向更快地归零:

int x = 10;

while( 0 <---- x )
{
   printf("%d ", x);
}

8 6 4 2

你可以用箭头控制速度!

int x = 100;

while( 0 <-------------------- x )
{
   printf("%d ", x);
}

90 80 70 60 50 40 30 20 10

;)

于 2014-12-28T00:32:03.527 回答
1392

相当于

while (x-- > 0)

x--(post decrement) 等价于x = x-1,代码转换为:

while(x > 0) {
    x = x-1;
    // logic
}
x--;   // The post decrement done when x <= 0
于 2009-10-29T07:00:13.097 回答
593

它是

#include <stdio.h>

int main(void) {
  int x = 10;
  while (x-- > 0) { // x goes to 0
    printf("%d ", x);
  }
  return 0;
}

只是空间让事情看起来很有趣,--递减和>比较。

于 2009-10-29T07:00:19.180 回答
472

的用法-->具有历史意义。在 x86 架构上,递减曾经(并且在某些情况下仍然如此)比递增快。Using-->表明这x将是0,并吸引具有数学背景的人。

于 2009-11-18T12:47:41.253 回答
414

完全是极客,但我将使用这个:

#define as ;while

int main(int argc, char* argv[])
{
    int n = atoi(argv[1]);
    do printf("n is %d\n", n) as ( n --> 0);
    return 0;
}
于 2010-05-18T20:33:28.117 回答
399
while( x-- > 0 )

是如何解析的。

于 2009-10-29T07:00:20.880 回答
347

我读过的一本书(我不记得是哪本书了)说:编译器尝试使用左右规则将表达式解析为最大的标记。

在这种情况下,表达式:

x-->0

解析为最大的标记:

token 1: x
token 2: --
token 3: >
token 4: 0
conclude: x-- > 0

同样的规则适用于这个表达式:

a-----b

解析后:

token 1: a
token 2: --
token 3: --
token 4: -
token 5: b
conclude: (a--)-- - b
于 2010-04-09T00:04:09.040 回答
291

This is exactly the same as

while (x--)
于 2009-12-31T13:48:19.947 回答
258

无论如何,我们现在有一个“去”操作员。"-->"作为一个方向很容易被记住,并且“当 x 变为零时”是直截了当的。

此外,它比"for (x = 10; x > 0; x --)"某些平台更有效。

于 2009-10-29T14:45:22.637 回答
234

此代码首先比较 x 和 0,然后递减 x。(在第一个答案中也说过:您正在递减 x,然后将 x 和 0 与>运算符进行比较。)请参阅此代码的输出:

9 8 7 6 5 4 3 2 1 0

我们现在首先比较,然后通过在输出中看到 0 来递减。

如果我们想先递减然后比较,请使用以下代码:

#include <stdio.h>
int main(void)
{
    int x = 10;

    while( --x> 0 ) // x goes to 0
    {
        printf("%d ", x);
    }
    return 0;
}

该输出是:

9 8 7 6 5 4 3 2 1
于 2009-11-18T12:52:03.290 回答
193

当我运行此代码时,我的编译器将打印出 9876543210。

#include <iostream>
int main()
{
    int x = 10;

    while( x --> 0 ) // x goes to 0
    {
        std::cout << x;
    }
}

正如预期的那样。while( x-- > 0 )实际上的意思while( x > 0)。帖子x--递减。x

while( x > 0 ) 
{
    x--;
    std::cout << x;
}

是写同一件事的不同方式。

很高兴原始看起来像“虽然 x 变为 0”。

于 2010-01-17T00:46:01.193 回答
159

--和之间缺少一个空格>x是后减量,即检查条件后减量x>0 ?

于 2009-12-28T16:32:54.157 回答
149

--递减运算符并且>大于运算符。

这两个运算符作为一个单独的运算符应用,例如-->.

于 2010-04-06T10:45:37.610 回答
140

它是两个运算符的组合。首先--是用于递减值,>用于检查该值是否大于右侧操作数。

#include<stdio.h>

int main()
{
    int x = 10;

    while (x-- > 0)
        printf("%d ",x);

    return 0;
}

输出将是:

9 8 7 6 5 4 3 2 1 0            
于 2013-04-02T11:22:40.140 回答
131

C 和 C++ 遵循“最大咀嚼”规则。同样的方式a---b被翻译成(a--) - b,在你的情况下 x-->0翻译成(x--)>0

该规则本质上说的是,从左到右,表达式是通过获取将形成有效标记的最大字符来形成的。

于 2014-02-10T17:29:22.903 回答
130

实际上,x是在递减后,并且正在检查该条件。不是-->,是(x--) > 0

注意:x检查条件后会更改值,因为它是后减的。一些类似的情况也可能发生,例如:

-->    x-->0
++>    x++>0
-->=   x-->=0
++>=   x++>=0
于 2012-08-18T07:34:12.943 回答
33

为什么所有的并发症?

原始问题的简单答案是:

#include <stdio.h>

int main()
{
    int x = 10;
    while (x > 0)
    {
        printf("%d ", x);
        x = x-1;
    }
}

它做同样的事情。我并不是说你应该这样做,但它会做同样的事情,并且会在一篇文章中回答这个问题。

x--只是上述的简写,只是>一个普通的大于operator。没有什么大谜团!

现在有太多人把简单的事情复杂化了;)

于 2016-10-27T15:09:20.750 回答
30

我们在while循环括号“ ()”中定义条件并在大括号“”中定义条件的传统方式,{}但这是一种一次性定义所有条件的方式。例如:-->

int abc(){
    int a = 5
    while((a--) > 0){ // Decrement and comparison both at once
        // Code
    }
}

它说,递减a并运行循环,直到时间a大于0

其他方式应该是这样的:

int abc() {
    int a = 5;
    while(a > 0) {
        a = a -1 // Decrement inside loop
        // Code
    }
}

两种方式,我们做同样的事情,实现同样的目标。

于 2017-05-28T20:10:34.777 回答
27
char sep = '\n'  /1\
; int i = 68    /1  \
; while (i  ---      1\
                       \
                       /1/1/1                               /1\
                                                            /1\
                                                            /1\
                                                            /1\
                                                            /1\
                            /           1\
                           /            1 \
                          /             1  \
                         /              1   \
                         /1            /1    \
                          /1          /1      \
                           /1        /1        /1/1> 0) std::cout \
                              <<i<<                               sep;

对于更大的数字,C++20 引入了一些更高级的循环特性。首先,i我们可以构建一个反向循环解循环并将其转移到std::ostream. 但是,速度i是实现定义的,因此我们可以使用新的 C++20 速度运算符<<i<<来加快速度。我们还必须通过构建墙来捕获它,如果我们不这样做,则i离开范围并取消引用它会导致未定义的行为。要指定分隔符,我们可以使用:

 std::cout \
           sep

我们有一个从 67 到 1 的 for 循环。

于 2021-01-23T07:32:43.550 回答
25

(x --> 0)意味着(x-- > 0)

  1. 您可以使用(x -->)
    Output: 9 8 7 6 5 4 3 2 1 0
  1. 你可以用(-- x > 0) It's mean(--x > 0)
    Output: 9 8 7 6 5 4 3 2 1
  1. 您可以使用
(--\
    \
     x > 0)

Output: 9 8 7 6 5 4 3 2 1

  1. 您可以使用
(\
  \
   x --> 0)

Output: 9 8 7 6 5 4 3 2 1 0

  1. 您可以使用
(\
  \
   x --> 0
          \
           \
            )

Output: 9 8 7 6 5 4 3 2 1 0

  1. 你也可以使用
(
 x 
  --> 
      0
       )

Output: 9 8 7 6 5 4 3 2 1 0

同样,您可以尝试很多方法来成功执行此命令。

于 2019-09-23T12:39:00.043 回答
20

您可以使用穿甲箭头操作符来代替常规的箭头操作符 (-->):--x> (注意箭头尖端的那些锋利的倒钩)。它为穿甲增加了 +1,因此它比常规箭头运算符更快地完成循环 1 迭代。自己试试:

int x = 10;
while( --x> 0 )
    printf("%d ", x);
于 2021-06-03T20:01:38.323 回答
7

实际上,您可以“创建”一个 --> 运算符只是为了好玩)

class MyClass {
    class Helper
    {
        MyClass* ptr;
        Helper(MyClass* _this): ptr{_this} {}
    public:
        Helper(const Helper&) = delete;
        Helper(Helper&&) = delete;
        void operator=(const Helper&) = delete;
        void operator=(Helper&&) = delete;
        operator MyClass()
        {
            auto tmp = *ptr;
            tmp._value++;
            return tmp;
        }
        friend MyClass;
        void operator>(int){std::cout << "Operator -->" << std::endl;}
    };

    int _value = 0;
public:
    MyClass() = default;
    MyClass(int value): _value{value} {}
    Helper operator--(int)
    {
        _value--;
        return Helper(this);
    }
    int get() const noexcept
    {
        return _value;
    }
    bool operator>(int num) const noexcept
    {
        return _value > num; 
    }
};

int main()
{
    MyClass obj(5);
    obj > 1;            //operator >
    obj--;              //operator --
    MyClass b = obj--;  //still works
    std::cout << b.get() << std::endl;      //4
    std::cout << obj.get() << std::endl;    //3
    b --> 5;            //operator -->
    //But there is at least one problem
    auto c = obj--;     //auto can deduce a private type :(
}

但正如我所说,这只是为了好玩;)

于 2021-07-01T13:21:38.490 回答
4

-->根本不是运营商。我们有一个运算符 like ->,但不是 like -->。这只是一个错误的解释,while(x-- >0)它仅仅意味着 x 具有后减量运算符,并且此循环将运行直到它大于

编写此代码的另一种简单方法是while(x--). 当 while循环遇到错误条件时将停止,这里只有一种情况,即0. 因此,当 x 值减为零时,它将停止。

于 2020-06-15T18:15:17.883 回答
4

--是一元后减运算符。

 while (x-- > 0) // x goes to 0
 {
     printf("%d ", x);
 }
  • 一开始,条件将评估为 (x > 0) // 10 > 0
  • 现在因为条件为真,它将以递减的值进入循环 x-- // x = 9
  • 这就是为什么第一个打印值为 9
  • 等等。在最后一个循环x=1中,所以条件为真。根据一元运算符,该值在打印时更改为x = 0
  • 现在,x = 0将条件评估(x > 0 )为 false 并退出while循环。
于 2020-07-06T11:28:09.783 回答
3

-->不是运算符,它是--(后自减)和>(大于比较)的并置。

循环看起来更熟悉:

#include <stdio.h>
int main() {
    int x = 10;
    while (x-- > 0) { // x goes to 0
        printf("%d ", x);
    }
}

10此循环是枚举(排除的上限)和包含的下限之间的值的经典习惯用法0,对于从最后一个到第一个遍历数组元素很有用。

初始值10是迭代的总数(例如数组的长度),加上循环内使用的第一个值。The是循环内0的最后一个值,因此注释x 变为 0x

请注意,x循环完成后的值为-1

另请注意,如果具有无符号类型(例如 ) ,此循环将以相同的方式运行,这比简单的替代方案具有很大的优势。xsize_tfor (i = length-1; i >= 0; i--)

出于这个原因,我实际上是这种令人惊讶的语法的粉丝:while (x --> 0). 我觉得这个成语既醒目又优雅,就像for (;;)vs:一样while (1)(看起来很像while (l))。它也适用于语法受 C 启发的其他语言:C++、Objective-C、java、javascript、C# 等等。

于 2021-03-12T12:44:08.810 回答
1

这就是你的意思。

while((x--) > 0)

小时候听过,

停止不要,放手 (روکو مت، جانے دو)

逗号使人混淆的地方

停下,别放手。(روکو، مت جانے دو)

现在编程中也会发生同样的情况,SPACE 会造成混乱。:D

于 2021-06-02T05:47:18.877 回答