187

C ++ではコンマ演算子はどのように機能しますか?

たとえば、私がそうする場合:

a = b, c;  

最終的にbまたはcに等しくなりますか?

(はい、これはテストが簡単です。誰かが答えをすばやく見つけるために、ここに文書化するだけです。)

更新: この質問は、コンマ演算子を使用するときにニュアンスを明らかにしました。これを文書化するだけです:

a = b, c;    // a is set to the value of b!

a = (b, c);  // a is set to the value of c!

この質問は、実際にはコードのタイプミスに触発されました。意図されたもの

a = b;
c = d;

になって

a = b,    //  <-  Note comma typo!
c = d;
4

9 に答える 9

133

C++ではコンマ演算子がオーバーロードされる可能性があることに注意してください。したがって、実際の動作は予想とは大きく異なる場合があります。

例として、Boost.Spiritは、コンマ演算子を非常に巧妙に使用して、シンボルテーブルのリスト初期化子を実装します。したがって、次の構文が可能で意味のあるものになります。

keywords = "and", "or", "not", "xor";

演算子の優先順位により、コードは(意図的に!)と同一であることに注意してください。

(((keywords = "and"), "or"), "not"), "xor";

つまり、呼び出される最初の演算子はkeywords.operator =("and")、残りoperator,のが呼び出されるプロキシオブジェクトを返します。

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");
于 2008-09-10T14:21:54.993 に答える
130

コンマ演算子は、すべての C/C++ 演算子の中で最も優先度が低くなります。したがって、式にバインドするのは常に最後になります。つまり、次のようになります。

a = b, c;

次と同等です。

(a = b), c;

もう 1 つの興味深い事実は、コンマ演算子がシーケンス ポイントを導入することです。これは、式が次のことを意味します。

a+b, c(), d

は、3 つの部分式 ( a+bc()、およびd ) が順番に評価されることが保証されています。副作用がある場合、これは重要です。通常、コンパイラは、適切と思われる順序で部分式を評価できます。たとえば、関数呼び出しでは次のようになります。

someFunc(arg1, arg2, arg3)

引数は任意の順序で評価できます。関数呼び出しのコンマは演算子ではないことに注意してください。それらはセパレーターです。

于 2008-09-22T11:49:36.230 に答える
77

に等しくなりbます。

コンマ演算子は、割り当てよりも優先順位が低くなります。

于 2008-09-10T14:14:27.910 に答える
73

コンマ演算子:

  • 優先度が最も低い
  • 左結合です

コンマ演算子のデフォルト バージョンは、すべてのタイプ (組み込みおよびカスタム) に対して定義されており、次のように機能しますexprA , exprB

  • exprA評価される
  • の結果exprAは無視されます
  • exprB評価される
  • の結果exprBは、式全体の結果として返されます

ほとんどの演算子では、コンパイラは実行の順序を選択でき、最終結果に影響しない場合は実行をスキップする必要さえあります (たとえばfalse && foo()、 への呼び出しをスキップしますfoo)。ただし、これはカンマ演算子には当てはまらず、上記の手順は常に発生します*

実際には、デフォルトのコンマ演算子はセミコロンとほぼ同じように機能します。違いは、セミコロンで区切られた 2 つの式は 2 つの別個のステートメントを形成するのに対し、コンマ区切りはすべてを 1 つの式として保持することです。このため、次のシナリオでコンマ演算子が使用されることがあります。

  • C 構文には、ステートメントではなく単一の式が必要です。例えばif( HERE )
  • forC 構文では、ループの初期化などで、複数ではなく単一のステートメントが必要です。for ( HERE ; ; )
  • 中括弧をスキップして単一のステートメントを保持したい場合: if (foo) HERE ;(そうしないでください。本当に醜いです!)

ステートメントが式でない場合、セミコロンをコンマに置き換えることはできません。たとえば、これらは許可されていません。

  • (foo, if (foo) bar)(ifは式ではありません)
  • int x、int y (変数宣言は式ではありません)

あなたの場合、次のものがあります。

  • a=b, c;、カンマ演算子をオーバーロードしない型であるとa=b; c;仮定すると、 と同等です。a
  • a = b, c = d;がカンマ演算子をオーバーロードしない型であるとa=b; c=d;仮定すると、と同等です。a

すべてのコンマが実際にはコンマ演算子であるとは限らないことに注意してください。完全に異なる意味を持ついくつかのコンマ:

  • int a, b;--- 変数宣言リストはコンマで区切られていますが、これらはコンマ演算子ではありません
  • int a=5, b=3;--- これもコンマ区切りの変数宣言リストです
  • foo(x,y)--- コンマ区切りの引数リスト。実際、任意の順序xy評価できます。
  • FOO(x,y)--- コンマ区切りのマクロ引数リスト
  • foo<a,b>--- コンマ区切りのテンプレート引数リスト
  • int foo(int a, int b)--- カンマ区切りのパラメータ リスト
  • Foo::Foo() : a(5), b(3) {}--- クラス コンストラクター内のコンマ区切りの初期化子リスト

*最適化を適用する場合、これは完全には当てはまりません。コードの特定の部分が残りの部分にまったく影響を与えないことをコンパイラが認識した場合、コンパイラは不要なステートメントを削除します。

さらに読む: http://en.wikipedia.org/wiki/Comma_o​​perator

于 2013-10-05T14:43:20.383 に答える
40

の値はaになりますが、式bの値はになります。つまり、c

d = (a = b, c);

aと等しくなりb、 とd等しくなりcます。

于 2008-09-15T18:29:25.323 に答える
8

bの値はaに割り当てられます。cには何も起こりません

于 2008-09-10T14:16:54.113 に答える
3

はいカンマ演算子は代入演算子より優先度が低い

#include<stdio.h>
int main()
{
          int i;
          i = (1,2,3);
          printf("i:%d\n",i);
          return 0;
}

出力 : i=3
コンマ演算子は常に右端の値を返すためです。
コンマ演算子と代入演算子の場合:

 int main()
{
      int i;
      i = 1,2,3;
      printf("i:%d\n",i);
      return 0;
}

出力: i=1
コンマ演算子は割り当てよりも優先順位が低いことがわかっているため.....

于 2015-07-04T13:31:23.830 に答える
2

コンマ演算子は代入演算子よりも優先順位が低いため、aの値はbと等しくなります。

于 2008-09-10T14:22:01.967 に答える
-3

まず最初に: Comma は実際には演算子ではありません。コンパイラにとっては、他のトークンとのコンテキストで意味を持つ単なるトークンです。

これは何を意味し、なぜ気にするのですか?

例 1:

異なるコンテキストでの同じトークンの意味の違いを理解するために、次の例を見てみましょう。

class Example {
   Foo<int, char*> ContentA;
}

通常、C++ の初心者は、この式は物事を比較できる/比較するだろうと考えるでしょうが、それは絶対に間違って<います。>,

もちろん、上記の例の正しい解釈は、それがテンプレートの説明であるということです。

例 2:

通常、複数の初期化変数および/またはループの各反復後に実行する必要がある複数の式を使用して for ループを記述する場合、コンマも使用します。

for(a=5,b=0;a<42;a++,b--)
   ...

コンマの意味は、使用のコンテキストに依存します。ここでは、forコンストラクションのコンテキストです。

コンテキスト内のコンマは実際には何を意味しますか?

さらに複雑にするために (C++ ではいつものように) コンマ演算子自体をオーバーロードできます (指摘してくれたKonrad Rudolphに感謝します)。

質問に戻ると、コード

a = b, c;

コンパイラにとって次のようなことを意味します

(a = b), c;

トークン/オペレーターの優先度がトークンの優先度よりも高いためです。=,

これは次のような文脈で解釈されます

a = b;
c;

(解釈はコンテキストに依存することに注意してください。ここでは、関数/メソッドの呼び出しでも、テンプレートの開始でもありません。)

于 2013-04-07T10:39:17.477 に答える