C ++の「->」演算子とは何ですか?

2009-10-29 c++ c operators code-formatting standards-compliance

comp.lang.c++.moderated でC ++ / STLの非表示の機能とダークコーナーを読んだ後、次のスニペットが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

これはGCCでも動作するので、Cだと思います。これは規格のどこに定義されており、どこから来たのですか?

Answers

-->は演算子ではありません。実際には、2つの別個の演算子--および>です。

条件コードはxデクリメントし、 xの元の(デクリメントされていない)値を返し、 >演算子を使用して元の値を0と比較します。

よりよく理解するために、ステートメントは次のように書くことができます。

while( (x--) > 0 )

それは同等です

while (x-- > 0)

x-- (ポストデクリメント)に相当しx = x-1にコード変換、そう:

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 0

       printf("%d ", x);
     }

     return 0;
}

スペースだけで物事をおもしろく見せます--デクリメントと>比較。

while( x-- > 0 )

それがどのように解析されるかです。

これは非常に複雑な演算子であるため、 ISO / IEC JTC1(合同技術委員会1)でさえ、その説明をC ++標準の2つの異なる部分に配置しました。

冗談はさておき、彼らは、2つの異なる演算子である: --および> §5.2.6/ 2とC ++ 03標準の§5.9にそれぞれ記載。

とにかく、これで「移動先」オペレーターができました。 "-->"は方向として覚えやすく、「xがゼロになる間」は意味がストレートです。

さらに、一部のプラットフォームでは、 "for (x = 10; x > 0; x --)"よりも少し効率的です。

-->の使用には歴史的な関連があります。 x86アーキテクチャでのインクリメントよりも、デクリメントの方が高速でした(場合によっては、まだ減少しています)。 -->を使用すると、 x0になることが示唆され、数学的な背景を持つ人にアピールします。

このコードは、最初に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 ?チェックした後にデクリメントされx>0 ?

これはまったく同じです

while (x--)
{
   printf("%d ", 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 )実際にはwhile( x > 0)意味while( x > 0)ます。 x--ポストはxデクリメントします。

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

同じことを書く別の方法です。

オリジナルが「xが0になる間」のように見えるのは良いことです。

--デクリメント演算子で、 >大なり演算子です。

2つの演算子は-->ように1つの演算子として適用されます。

私が読んだ1冊の本(私はどの本を正確に覚えていない)は次のように述べています

この場合、式は次のとおりです。

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

これが複雑な表現を理解するのに役立つことを願っています^^

完全にオタクですが、私はこれを使用します:

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

または、完全に異なる何かの場合... x0スライドし0

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

それほど数学的ではありませんが、...すべての絵は千の言葉を描きます...

実際には、 xはデクリメントされており、その状態でチェックされています。それは-->ではなく、 (x--) > 0 --> (x--) > 0

注: x値は、条件がチェックされた後に変更されます。同様のケースがいくつか発生する可能性があります。次に例を示します。

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

2つの演算子の組み合わせです。最初--は値を減らすためのもので、 >は値が右側のオペランドより大きいかどうかをチェックするためのものです。

#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--)>0

ルールの本質は、左から右に向かって、有効な式を形成する文字の最大数をとることによって式が形成されるということです。

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

;)

なぜすべての複雑化?

元の質問に対する簡単な答えは次のとおりです。

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

同じことをします。このようにするべきだと言っているわけではありませんが、同じことを行い、1つの投稿で質問に回答することになります。

x--は上記の省略形であり、 >は通常の大なりoperatorです。大きな謎はありません!

今日では単純なことを複雑にする人が多すぎます;)

従来の方法では、 whileループの括弧()と中括弧{}内の終了条件で条件を定義していましたが、 -->は両方を同時に定義します。

例えば:

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

これはaをデクリメントしa a0より大きい間ループを実行します。

従来は次のようになります。

int abc(void)
{
    int a = 5;
    while(a > 0)
    {
        a--;
        // Code
    }
    a--;
}

どちらの方法でも、同じことをして同じ目標を達成します。

(x --> 0)手段(x-- > 0)

  1. あなたは(x -->)使うことができます
    output -: 9 8 7 6 5 4 3 2 1 0

  2. あなたが使用することができます(-- x > 0)それは平均です(--x > 0)
    output -: 9 8 7 6 5 4 3 2 1

  3. あなたは使うことができます
(--\
    \
     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

同様に、このコマンドを正常に実行するために多くの方法を試すことができます

コンパイラーは、トークンの入力ファイルをスキャンするときに、正規表現で定義されている最初で最も長い有効なトークンを選択します。これが、「-」がデクリメント演算子として使用され、2つのマイナス記号(「-」)が隣接していない理由です。トークンの中には、特定の文字(多くの場合空白)で区切る必要があるものと、そうでないものがあります。そのため、「5 + 5」は「5 + 5」と同じくらい有効です。 「5+」はC ++では有効なトークンではないため、トークンに特定の区切り文字は必要ありません。特定の質問では、利用可能な最初の最長のトークンは「-」でした。そのため、「-」または「->」の代わりに選択されましたが、それぞれ最長ではなく、最初の有効なトークンではありません。その結果、スキャナーは「-」を検出して減分トークンを作成し、次に大なり記号を付けて付随するトークンを作成しました。

これは-->演算子ではありません。私たちは、like演算子を持っている->ではなく、のような--> 。これは、 while(x-- >0)誤った解釈でwhile(x-- >0) 、これは単にxにデクリメント後演算子があり、このループがZeroより大きくなるまで実行されることを意味します。

このコードを記述するもう1つの簡単な方法は、 while(x--) whileループがfalse条件を取得すると停止し、ここでは1つのケース、つまり0のみです。そのため、x値が「ゼロ」にデクリメントされると停止します。

ここに-単項後置減算演算子があります。

 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ループが終了します。

Related