C++中的"-->"操作符是什么?

在阅读了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。这在标准中的定义是什么,它来自哪里?

951061 次浏览

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

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

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

while( (x--) > 0 )

它相当于

while (x-- > 0)

x--(后减量)等价于x = x-1(但返回x的原始值),因此代码转换为:

while(x > 0) {x = x-1;// logic}x--;   // The post decrement done when x <= 0

这是

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

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

while( x-- > 0 )

这是如何解析的。

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

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

无论如何,我们现在有一个“go to”运算符。"-->"很容易被记住是一个方向,而“而x归零”是直的。

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

-->的使用具有历史意义。在x86架构上,递减(在某些情况下仍然如此)比递增更快。使用-->表明x将转向0,并吸引那些有数学背景的人。

这段代码首先比较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

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

这和

while (x--)

当我运行此代码时,我的编译器将打印出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”。

--递减操作符,>大于操作符。

这两个运算符作为单个运算符应用,如-->

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

在这种情况下,表达式:

x-->0

解析到最大的令牌:

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

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

a-----b

解析后:

token 1: atoken 2: --token 3: --token 4: -token 5: bconclude: (a--)-- - b

绝对的极客,但我会用这个:

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

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

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

不是那么数学,但是…每幅画都画了一千个字…

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

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

-->    x-->0++>    x++>0-->=   x-->=0++>=   x++>=0

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

#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

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

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

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

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

;)

为什么这么复杂?

对最初问题的简单回答是:

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

它做同样的事情。我不是说你应该这样做,但它做同样的事情,会回答这个问题在一个职位。

x--只是上面的简写,>只是一个正常的大于operator。没有什么大的神秘!

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

传统的方式我们定义的条件,而循环括号“()”和终止条件内的大括号“{}”,但这-->是一次定义所有的方式。例如:

int abc(){int a = 5while((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}}

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

(x --> 0)表示(x-- > 0)

  1. 你可以使用(x -->)
    Output: 9 8 7 6 5 4 3 2 1 0
  1. 你可以使用(-- x > 0)意思是(--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

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

这个-->根本不是一个运算符。我们有一个像->这样的运算符,但不像-->。这只是对while(x-- >0)的错误解释,这只是意味着x有后减量运算符,这个循环将运行到它大于

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

这里--是一元后减量运算符。

 while (x-- > 0) // x goes to 0{printf("%d ", x);}
  • 一开始,条件将评估为(x > 0) // 10 > 0
  • 现在因为条件为true,它将以递减的值进入循环x-- // x = 9
  • 这就是为什么第一个打印值是9
  • 以此类推。在最后一个循环x=1中,条件为真。根据一元操作符,打印时值更改为x = 0
  • 现在,x = 0将条件(x > 0 )评估为false,循环退出。
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循环。

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

循环看起来更熟悉:

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

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

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

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

另请注意,如果x具有无符号类型(如size_t),则此循环将以相同的方式运行,这比朴素替代方案for (i = length-1; i >= 0; i--)具有强大的优势。

出于这个原因,我实际上是这个令人惊讶的语法的粉丝:while (x --> 0)。我觉得这个习语引人注目且优雅,就像for (;;) vs:while (1)(看起来与while (l)相似得令人困惑)。它也适用于其他语法受C启发的语言:C++、Objective-C、java、javascript、C#等等。

这就是你的意思。

while((x--) > 0)

我们小时候听说过,

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

逗号造成混乱的地方

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

现在编程也会发生同样的事情,一个空间会让人困惑。: D

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

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