4

C演算では、結合性は、インクリメント、デクリメント、および割り当てに対するものです。

  2. postfix ++ and -- 
  3. prefix ++ and -- 
  16. Direct assignment = 

完全なリストはここにありますCのウィキペディア演算子

私の質問は私たちがいつ持っているかです

int a, b;

b = 1;
a = b++;

printf("%d", a); // a is equal to 1

b = 1;
a = ++b;

printf("%d", a); //a is equal to 2

直接代入の前に接尾辞インクリメント演算子を使用する必要があるのに、b ++で1に等しいのはなぜですか?

また、両方が代入の前にあるのに、プレフィックスインクリメント演算子がポストフィックスと異なるのはなぜですか?

操作の結合性に関しては、非常に重要なことを理解していないと確信しています。

4

3 に答える 3

15

接尾辞演算子a++はインクリメントaしてから元の値を返します。つまり、次のようになります。

{ temp=a; a=a+1; return temp; }

プレフィックス++aは新しい値を返します。

{ a=a+1; return a; }

これは、演算子の優先順位とは関係ありません。

(そして、結合性a-b-cはに等しい(a-b)-cかどうかを決定しa-(b-c)ます。)

于 2010-03-07T06:48:27.203 に答える
6

演算子の優先順位と結合性は、前に何が起こり、後に何が起こるかを教えてくれません。演算子の優先順位/結合性はそれとは何の関係もありません。C言語では、「前」や「後」などの時間的関係は、いわゆるシーケンスポイントによって定義され、シーケンスポイントによってのみ定義されます(これは完全に別の話です)。

演算子の優先順位/結合性は、どのオペランドがどの演算子に属しているかを示すだけです。たとえば、式は正式にはととしてa = b++解釈できます。演算子の優先順位/結合性は、この場合、後者の解釈が正しく、前者が正しくないことを示しています(つまり、の結果に適用され、結果には適用されません)。(a = b)++a = (b++)++ba = b

bこれもまた、最初にインクリメントする必要があるという意味ではありません。演算子の優先順位/結合性は、もう一度、「最初に」何が起こり、「次に」何が起こるかとは関係がありません。これは、式の結果b++がに割り当てられていることを示しているだけですa。定義上、b++(接尾辞の増分)の結果はの元の値ですbこれが、の元の値である1aを取得する理由です。変数がインクリメントされるタイミングは、割り当てられたの値である限り、まったく関係ありません。コンパイラーは、この式を任意の順序で評価し、いつでも増分することができます。bbabbaどういうわけか元の値を取得しますb(そして、その「どういうわけか」が内部でどのように機能するかは誰も気にしません)。

たとえば、コンパイラa = b++は次の基本操作のシーケンスとして評価できます。

(1) a := b
(2) b := b + 1

または、次のように評価できます

(1) b := b + 1
(2) a = b - 1

b最初のケースでは実際には最後にインクリメントされ、2番目のケースでは最初にインクリメントされることに注意してくださいb。ただし、どちらの場合もa、同じ正しい値、つまり元の値をb取得します。これは、取得する必要がある値です。

ただし、上記の2つの例は、説明のためだけのものです。実際には、のような式は内部にシーケンスポイントがa = ++bありa = b++ません。つまり、あなたの観点からは、これらの式のすべてが同時に発生します。「前」、「後」、「最初」、「次」、「最後」はありません。このような表現は、一連の小さなステップに意味のある形で分解できないという意味で「アトミック」です。

于 2010-03-07T06:56:57.257 に答える
1

AndreyTがすでに指摘しているように、優先順位と結合性は評価の順序について教えてくれません。彼らはグループ化についてだけあなたに話します。たとえば、優先順位は、の代わりにa*b+cグループ化された使用法を示します。コンパイラーは自由に評価でき、任意の順序でこれらの式のいずれかに適合します。結合性は、同じ優先順位の演算子、ほとんどの場合、同じ演算子がある場合のグループ化について示します。たとえば、それは、ではなく、と同等であることを示しています(そうでない場合、減算は結合性のままです)。(a*b)+ca*(b+c)abca-b-c(a-b)-ca-(b-c)

評価の順序は、シーケンスポイントによって定義されます。完全な式の最後にシーケンスポイントがあります(とりわけ)。シーケンスポイントでは、以前のすべての評価が行われている必要があり、後続の評価はまだ行われていない可能性があります。

あなたの特定の例を見ると、a=b++;では、結果は主にポストインクリメント自体の定義からのものです。ポストインクリメントにより、変数の前の値が生成され、次のシーケンスポイントの前に、その変数の値がインクリメントされます。事前インクリメントは、インクリメントが適用された変数の値を生成します。ただし、どちらの場合も、割り当てに対して特定の順序で変数をインクリメントする必要があるという意味ではありません。たとえば、プリインクリメントの例では、コンパイラは次と同等のことを完全に自由に実行できます。

temp = b+1;
a = temp;
b = b + 1;

同様に、ポストインクリメントバージョンでは、変数は割り当ての前または後にインクリメントできます。

a = b;
b = b + 1;

また:

temp = b;
b = b + 1;
a = temp;

ただし、いずれの場合も、に割り当てられる値は、インクリメントされる前aの値である必要がありbます。

于 2010-03-07T07:20:36.613 に答える