题 C ++中的“ - >”运算符是什么?


看完之后 隐藏的功能和C ++ / STL的黑暗角落 上 comp.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);
    }
}

我假设这是C,因为它也适用于GCC。标准中定义了哪里,它来自何处?


7782


起源


或者甚至只是适当的间距...我不认为我曾经见过变量和它们之间的空间 ++ 要么 -- 之前... - Matthew Scharley
可以恢复此“转到”运算符(0 < - x)。还有一个“运行到”运算符(0 <---- x)。 Geez,我听过的最有趣的问题c ++ syntax =)+1。 - SadSido
有趣的是,尽管解释是非常错误的,但它确实描述了代码的正确用法。 :) - Noldorin
想象一下新的语法可能性: #define upto ++<, #define downto -->。如果你感觉邪恶,你可以做到 #define for while( 和 #define do ) { (和 #define done ;}) 和写 for x downto 0 do printf("%d\n", x) done 哦,人性...... - Chris Lutz
打开了一种全新的富有表现力的编码方式的可能性,非常值得牺牲一些编译器警告:bool CheckNegative(int x){return x <0?真假 ); } - ttt


答案:


--> 不是运营商。它实际上是两个独立的运营商, -- 和 >

条件的代码递减 x回来的时候 x原始(未递减)值,然后将原始值与。进行比较 0 使用 > 运营商。

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

while( (x--) > 0 )

7479



然后,它在某种情况下看起来像某种范围运算符。 - Charles Salvia
假设x后递减然后与0比较,则说x在与0比较后递减 - Charles Salvia
在Java中它也编译:) - Steven Devijver
它的名字@Jay是糟糕的编程风格:-)这就是问题首先被问到的事实。将操作符文本绑定到它们正在操作的东西而不是不相关的东西上更有意义 while (x-- > 0) 会更贴切。它还使得正在发生的事情变得更加明显(至少在固定字体编辑器中)意味着这个答案中的括号不是必需的。 - paxdiablo
那么要解释“ - >”运算符,你必须使用“((”运算符和“ - )>”运算符? - Ira Baxter


或者对于完全不同的东西... x幻灯片到0

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

不是那么数学,但......每张图片都描绘了千言万语。 ...


2382



对不起,我没有得到这个。这个怎么用? - mafu
@mafutrct - 我记得它在C中只是附加下一行,好像没有换行符。这里的\ s基本上什么都不做。 - Hogan
IIRC,K&R C允许在减量运算符' - '之间的空格,在这种情况下你可以在它的中间有反斜杠,这看起来更酷。 :) - Jules
@ArnavBorborah这是一个古老的表达意思 why waste words when a picture does a better job ,在这种情况下用作笑话。 (实际上有2个关键字 while 和 printf ) - unsynchronized
是的,这个模糊不清的幻灯片操作员。我怎么会忘记! - demonkoryu


这是一个非常复杂的操作员,所以甚至 ISO / IEC JTC1(联合技术委员会1) 将其描述放在C ++标准的两个不同部分。

开玩笑说,他们是两个不同的运营商: -- 和 > 分别在C ++ 03标准的§5.2.6/ 2和§5.9中描述。


2221





它相当于

while (x-- > 0)

1142



虽然这可能有助于许多人理解代码,但正确解释它的几行会有所帮助。 - Dukeling
@Dukeling x-- 是简写符号 x-1 - Albert Renshaw
@AlbertRenshaw我肯定你回答的一年之久的评论意味着解释它不是一个单一的运营商,而是两个以混乱方式处理的运营商会有所帮助。 - mah
@ mbomb007对不起,我打算说x- = 1 - 起来晚了哈哈 - Albert Renshaw
@AlbertRenshaw但是 x -= 1 和 x-- 是不一样的...如果你想这样写,那就必须如此 while (x >= 0) { x -= 1; } - Krzysztof Karski


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

;)


861



哪个操作系统,这种类型的输出生成,我使用的是ubuntu 12.04,因为我有一个错误信息 - Bhuvanesh
虽然这应该是显而易见的,对于每个刚接触C ++的人来说都是这样:不要这样做。如果您需要增加/减少多个,请使用增强赋值。 - Blimeo
零“激光”。 while(0> - - - - - - - - - - ---------- x)...相同的输出。 - Samuel Danielson
@phord你确定它不编译? - > coliru.stacked-crooked.com/a/5aa89a65e3a86c98 - doc
@doc它用c ++编译,但不用c编译。 - phord


它的

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

     while( x-- > 0 ){ // x goes to 0

       printf("%d ", x);
     }

     return 0;
}

只是空间让事情变得有趣, -- 减量和 > 相比较。


498





用法 --> 具有历史意义。减少(在某些情况下仍然是),比在x86架构上递增更快。运用 --> 暗示 x 要去 0,并呼吁具有数学背景的人。


372



不完全正确。递减和递增需要相同的时间,这样做的好处是,与比较变量相比,与零的比较非常快。许多架构都是如此,而不仅仅是x86。任何带有JZ指令的东西(如果为零则跳转)。你可以找到许多向后写的“for”循环来节省比较周期。这在x86上特别快,因为递减变量的行为适当地设置了零标志,因此您可以在不必明确比较变量的情况下进行分支。 - burito
好吧,递减到零意味着你只需要与每个循环迭代的0进行比较,而向n迭代则意味着与每次迭代的n进行比较。前者往往更容易(在某些架构上,在每次数据寄存器操作后都会自动测试)。 - Joey Adams
@burrito虽然我并不反对,但通常会非常接近地预测以非零值为条件的循环。 - Duncan
增量和减量同样快,可能在所有平台上(绝对在x86上)。不同之处在于测试循环结束条件。要查看计数器是否已达到零几乎是免费的 - 当您递减一个值时,在处理器中设置零标志并检测您只需要检查该标志的结束条件,而在结束条件之前需要增加比较操作时可以检测到。 - lego
当然,由于现代编译器可以自动进行矢量化和反向循环,所以现在所有这些都没有实际意义。 - Lambda Fairy


while( x-- > 0 )

是如何解析的。


324





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

#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;
}

292



我希望我从未遇到任何源代码...... - mk12
@ Mk12那不是源代码......它是象形文字:-) - raffian
@SAFX - 这将是完美的象形文字 埃及括号 - mouviciel
这不编译。 C不是Pascal,里面的内部 do ... while 是一份声明清单。在C中它是一个块,所以它必须是 do { ... } while。 - user207421
@EJP它确实编译。语法是 do statement while ( expression ) ;。话虽如此,我希望我理解这个例子就是一个笑话。 - Escualo


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

在这种情况下,表达式:

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

我希望这有助于理解复杂的表达式^^


283



你的第二个解释是不正确的。编译器会看到 a-----b 并思考 (a--)-- - b,因为没有编译 a-- 不返回左值。 - Tim Leaf
另外, x 和 -- 是两个单独的令牌。 - Roland Illig
这被称为 最大的蒙克。 - RJFalconer
@DoctorT:它通过词法分析器。只有语义传递能够发出错误。所以他的解释是正确的。 - v.oddou
只要你想 --> 是一个操作员(这是通过提出问题暗示的),这个答案根本没有用 - 你会认为令牌2是 -->, 不只是 --。如果你知道的话 --> 不是运算符,你可能在理解问题中的代码时没有问题,因此,除非你有一个完全不同的问题,否则我不确定这是如何有用的。 - Dukeling