私はC++にC#を移植しています。 C++で次のステートメントを実行すると、正しい操作が得られます。私はC#で同じ文を実行すると、しかし...C#の演算子の演算順序
誰もが「++始まる」なぜ知っていますが実行されますか?私が(i%2)== 0でi = 0を実行すると、イミディエイトウィンドウが真を返すというのは狂ったことです。
私はC++にC#を移植しています。 C++で次のステートメントを実行すると、正しい操作が得られます。私はC#で同じ文を実行すると、しかし...C#の演算子の演算順序
誰もが「++始まる」なぜ知っていますが実行されますか?私が(i%2)== 0でi = 0を実行すると、イミディエイトウィンドウが真を返すというのは狂ったことです。
この質問では、演算子の優先順位は無関係です。この動作の原因となる評価順序です。
C#i++
では、左側にあるため、i % 2
より前に評価されています。したがってi % 2
はfalseで、ifの右側が評価されます。左から右に、あなたが子供を評価する各ノードで
=
buffer[i++]
if i % 2
then temp[end--]
else temp[begin++]
:
はまず、構文木を取得するための優先順位を使用します。これは、i++
がi % 2
の前に評価されることを意味します。
エリックリペットは両方ここSO上、彼のブログで、この上の記事の多くを持っている:
は個人的に私はそのようなコードを避けるだろう。これは、複数の式に分割し、あるいは未定義の動作である間に、シーケンスポイントなしに書かれた変数にアクセスするC++では? :
するのではなく、プレーンif
ステートメントを使用するために非常に良くあります。私は=
はシーケンスポイントではないと思うので、あなたの表現はC++で定義されておらず、ちょうどうまく動作したと思います。
これをビルドすると、 'buffer [i] =(i ++%2)== 0に変更できますか? temp [end--]:temp [begin ++]; ' – Rob
@Robこれはうまくいくが、恐ろしいコードだ。 – CodesInChaos
ああ、私は説明(とリンク)のおかげで、参照してください。 – tlg
私は分かりませんが、意図を明確にするのはなぜですか?
if(i % 2 == 0) {
buffer[i] = temp[end--];
} else {
buffer[i] = temp[begin++];
}
i++;
私は 'if'の後にi ++を置くことさえしました。そして演算子の優先度が高いということは、以前の実行が共通の神話であることを意味します。 – CodesInChaos
私はtempを導入し、バッファ[i ++]を2回書くのを避けると思います。しかし、はい、これはこれを処理する正しい方法です。実際には、別々の行にインクリメントを書いても何の問題もありません。 –
@CodeInChaos:あなたが正しいです、編集後に投稿してください。 – Ryan
確かにbegin < end
は正しいですか?私が間違っていなければ、最後に一つの要素が欠けてしまうでしょう。ここで
は、私はC++でそれを書くだろうかです:
for (; begin <= end; ++i)
{
buffer[i] = temp[(i & 1) == 0 ? end-- : begin++];
}
しかし、あなたが考えてみれば、それは反復ごとにフリップフロップので、ループ内の条件は、実際に、必要ありません。これは単にループ内に2コピー操作を有することがより効率的であろう:
while (begin < end)
{
buffer[i++] = temp[end--];
buffer[i++] = temp[begin++];
}
if (begin == end)
{
buffer[i++] = temp[end--];
}
Iはバック<
にループ条件を変更し、要素の数が奇数である場合にif
を添加しました。
これはC++でも定義された動作ですか? – CodesInChaos
どちらがどちらですか? –
このようなコードを書くことをやめるよう説得しなければ、私は何をするのか分からない。 –