C ++でのコンマ演算子の動作が異なりますか?


83

これ(コンマ演算子に注意してください):

#include <iostream>
int main() {
    int x;
    x = 2, 3;
    std::cout << x << "\n";
    return 0;
}

出力2

ただし、returnコンマ演算子とともに使用する場合は、次のようになります。

#include <iostream>
int f() { return 2, 3; }
int main() {
    int x;
    x = f();
    std::cout << x << "\n";
    return 0;
}

出力3

コンマ演算子の動作が異なるのはなぜreturnですか?


回答:


140

演算子の優先順位によると、コンマ演算子の優先順位はoperator=、よりも低いため、x = 2,3;と同等(x = 2),3;です。(演算子の優先順位は、演算子が引数にバインドされる方法を決定します。優先順位に応じて、他の演算子よりも厳密または緩くなります。)

カンマ式は(x = 2),3ここにあり、ではないことに注意してください2,3x = 2最初に評価され(そしてその副作用が完了し)、次に結果が破棄され、次に3評価されます(実際には何もしません)。そのため、の値はxです2。これ3はコンマ式全体(つまりx = 2,3)の結果であり、への割り当てには使用されないことに注意してくださいx。(に変更するとx = (2,3);xが割り当てられ3ます。)

の場合return 2,3;、コンマ式は2,32評価され、その結果は破棄3され、コンマ式全体の結果として評価されて返されます。これは、後でreturnステートメントによって返されます。


ステートメントに関する追加情報

式は、計算を指定する一連の演算子とそのオペランドです。

x = 2,3;式ステートメントx = 2,3はここでの式です。

式の後にセミコロンが続くのはステートメントです。

構文: attr(optional) expression(optional) ; (1)

return 2,3;ジャンプステートメントreturnステートメント)で2,3あり、ここでの式です。

構文: attr(optional) return expression(optional) ; (1)


1
良い説明。しかし、いくつかの実用的なアプリケーションはありますか?それとも単にエラーが発生しますか?
ジャン=フランソワ・ファーブル

7
@Jean-FrançoisFabreIMO混乱しているだけで、まったく役に立ちません。
songyuanyao 2016

11
for奇妙なことに、数値計算でコードをより明確にすることができるときに、ループで1〜2回使用されるのを見てきました。
バトシェバ2016

6
@Jean-FrançoisFabre:Batheshebaが言うようi += 1, j += 2に、forループのようなものを書くことができるようにするためです。誰かが、C ++文法(または、この部分がそこからコピーされたため、C文法)は、コンマの優先順位が書き込み時の割り当てよりも高く、書き込みx = 2, 3時は低くなることを定義しようとせずに、すでに十分に複雑であると判断しましたx = 2, y = 3
スティーブジェソップ2016

1
@Holger:セミコロンはステートメントを終了します。これは演算子ではありません。これは、より明確にするために答えを微調整できるものです。「x = 2、3」は、演算子が2つある式であり、for(;;)をサポートするため、=の優先順位が高くなります。(他のみんなが言ったように。)しかし、「2、3を返す;」式「2、3」を含むステートメントです。技術的には、キーワード「return」の優先順位はありません。(が効果的に、表現を受け入れ文のそれの一部が、最後に解析されます-どの演算子よりも、「優先度」を下げ表現。)
ミカバーガー

32

コンマ(の区切りとも呼ばれます)演算子は、左から右に評価されます。したがって、return 2,3;と同等return 3;です。

の評価x = 2,3;(x = 2), 3;演算子の優先順位によるものです。評価は依然として左から右であり、式全体の値は3でありx、値2を想定するという副作用があります。


2
式分離演算子を編集して詳しく説明していただけますか?同様に、私は@ songyuanyaoの答えのコメントで述べたように、私は理由を理解することができますreturn 2,3return (2,3)同じです。前者はそうあるべきだと私は信じていました(return 2),3
xyz 2016

@BiagioFestaはその部分をよく説明しています。
バトシェバ2016

1
@ prakharsingh95return 2はステートメント(たとえばfor,while,if、によって形成されたものなど)であり、式ではありません。たとえば、f(return 2)またはを書くことはできません2+return 2。したがって、(return 2),3構文的に無効です。
chi

@chiはい、その通りです。私はとして解釈return 2, 3れることを期待していたことを意味しました。(return 2), 3
xyz 2016

2
C ++の文法による@ prakharsingh95returnは、次の場合にのみ発生します。(a)return expression_opt ;、および(b)return braced-init-listのます ;
MM

20

この文:

  x = 2,3;

2つの式で構成されています

> x = 2
> 3

以来演算子の優先順位=コンマよりも優先されます,ので、x = 2評価された後 3。その後、xに等しくなり2ます。


ではreturn代わりに:

int f(){ return 2,3; }

言語構文は次のとおりです。

return <expression>

注意 returnは表現の一部ではありません。

したがって、その場合、2つの式が評価されます。

> 2
> 3

ただし、2番目の(3)のみが返されます。


2
UV'd。非常にうるさい<expression>ですが、(文法の観点から)明示的にオプションとしてマークした場合は便利です。
バトシェバ2016

2
の解析ツリーには5つの式がありますx=2,3。両方のリテラル23は、識別子と同様に解析ツリーの一番下にありますx。これらはすべて個別に有効な式です。演算子の優先順位とは、解析ツリーの下位=発生し、2つの式を4番目の式に結合することを意味します。最後に、5番目の式は、その2つの辺とを結合するコンマ演算子によって形成されます。ただし、演​​算子の優先順位が評価の順序を決定すると誤って述べています。そうではありません。評価の順序は、順序付けルールによって決定されます。x2x=2x=23
MSalters 2016

2
私は、リターンは表現の一部ではないことに言及することに投票しました
Daniel Jour 2016

@MSalters同意しますが、「since」ではなく「because」という単語を誤って使用しました。私の英語はそれほど完璧ではありません!;-=
Biagio Festa

2
ここで「マクロ表現」は専門用語ですか?プリプロセッサ関連の意味での「マクロ式」も存在する場合、それを使用するのは少し混乱しているようです。
senshin 2016

2

かっこで優先順位を強調するだけで、単純なアプローチを適用してみてください。

( x = 2 ), 3;

return ( 2, 3 );

これで、二項演算子「、」が左から右に両方で同じように機能していることがわかります。


1
トリッキーな部分は、x = 2, 3それ自体が表現であるのに対し、returnそれ自体が表現であることを認識することreturn <expression>です。したがって、それらを(x = 2, 3)ととして読みます(2, 3)
xyz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.