7

私は自分のgccでこれを試しました:

int a=1;
cout<<(--a)--;

出力は0です。しかし、それをに変更します

cout<<--(a--);

エラーが発生します(デクリメントオペランドとして左辺値が必要です)。誰かがこれについて私に教えてもらえますか?

ありがとう!

4

3 に答える 3

12

の両方のバージョンは++引数として左辺値を必要としますが、接頭辞バージョンは引数として左辺値を返し、後置バージョンは右辺値を返します。

いずれにせよ、シーケンスポイント間で同じオブジェクトを2回変更することはできないため、「動作する」例ではundefind動作が呼び出されます。出力は、コンパイラーが実行したいと思うものであれば何でもかまいません。好奇心から質問しているだけなら問題ありませんが、これが実際のコードに関連している場合は、何か間違ったことをしている可能性があります。

于 2011-05-20T03:16:50.677 に答える
8

predecrementは--aデクリメントaし、それからあなた自身を返しaます。したがって、後置デクリメントを含め、任意の方法で変更を続けることができます。

postdecrementはa--デクリメントaしますが、デクリメント前のaの値を返します。それは本質的にあなたにのコピーを与えていますa。ただし、このコピーを事前にデクリメントすることはできません。これは左辺値ではないため、デクリメントするものはありません。それがエラーである理由です。

プレデクリメントはへの参照を返すものと考え、ポストデクリメントはa定数値で返すものと考えてください。

于 2011-05-20T03:16:44.243 に答える
4
(--a)--

シーケンスポイントを介在させずに同じオブジェクトを2回変更するため、これは未定義の動作です。コンパイラは、UBを呼び出したときにレポートする必要はありません。多くの状況で、UBを検出することさえできません。ただし、適切な警告をオンにすると(そして、自分の警告が何を提供するかを確認する必要があります)、場合によってはそれが可能になることがあります。

--(a--)

プレフィックスデクリメントには左辺値が必要ですが、ポストフィックスデクリメントは右辺値を返します。これは、未定義の動作とは異なり、コンパイラが報告する必要があるエラーです。

于 2011-05-20T03:19:14.897 に答える