0

重複の可能性:
これらの未定義の動作を誰かが説明できますか(i = i ++ + ++ i、i = i ++など…)

私の友人と私は、考えられる最悪のforループを考え出そうとしていじっていました(したがって、これがひどいコードであるとは言わないでください!)。

私の友人はこれをforループで思いついた:

for (int i = 0; i++ & ++i % (++i % 2) ? --i : i++; i++);

見た目は問題ありませんが、浮動小数点の例外のため、初めてでも入力できません。ですから、私の最初の考えは、モジュロが0で除算されるということでした。しかし、これを実行すると、正常に実行されるため、そうではないようです。

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2);
}

しかし、これはしません:

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? --i : i++;
}

しかし、それは見知らぬ人になります。最初のケースは正常に実行され、2番目のケースは正常に実行されません。

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? 0 : 1;
}

for (int i = 0; i < 100; i++) {
    i++ & ++i % (++i % 2) ? 1 : 0; // 1 and 0 switched
}

だから今では何が起こっているのか本当に混乱していますが、それは再び奇妙になります。(正常に実行された)ケースを? 0 : 1ifステートメントに入れると、浮動小数点例外が再度スローされます。

for (int i = 0; i < 100; i++) {
    if (i++ & ++i % (++i % 2) ? 0 : 1);
}

私はこれで完全に迷子になっています。誰かがここで何が起こっているのか考えを持っていますか?

4

2 に答える 2

3

でうまくいかないi++ & ++i。演算子はオペランドの&シーケンスを行わないため、両側に増分を設定すると、未定義の動作が発生します。

ちなみに、これはおそらくゼロ除算の例外ですが、必ずしもFPUからのものではありません。

于 2013-02-05T05:14:29.587 に答える
1

一般に、CおよびC ++では、このような複数のインクリメント操作を1つの式に混在させることはお勧めできません。これは、通常、未定義の動作が発生するためです。未定義の振る舞いでは、物事が不思議なことに振る舞いを変えることは驚くべきことではありません。

一方、Javaは、すべての算術演算および論理演算に厳密な仕様を提供します(fpstrict以外の式の浮動小数点指数の精度を除く)。これらすべてをJavaに入れて(intがもはや有効なブール式ではないという事実を無視して)、一貫した答えを与えることができますが、それはあなたが期待するものではないかもしれません。

于 2013-02-05T05:07:38.717 に答える