私は C 言語を学んでいて、 と の違いをかなり混乱させてい++*ptr
ます*ptr++
。
例えば:
int x = 19;
int *ptr = &x;
私は知っていて、異なる結果++*ptr
を生み出していますが、それがなぜなのかわかりませんか?*ptr++
私は C 言語を学んでいて、 と の違いをかなり混乱させてい++*ptr
ます*ptr++
。
例えば:
int x = 19;
int *ptr = &x;
私は知っていて、異なる結果++*ptr
を生み出していますが、それがなぜなのかわかりませんか?*ptr++
These statements produce different results because of the way in which the operators bind. In particular, the prefix ++
operator has the same precedence as *
, and they associate right-to-left. Thus
++*ptr
is parsed as
++(*ptr)
meaning "increment the value pointed at by ptr
,". On the other hand, the postfix ++
operator has higher precedence than the dereferrence operator *
. Thefore
*ptr++
means
*(ptr++)
which means "increment ptr
to go to the element after the one it points at, then dereference its old value" (since postfix ++
hands back the value the pointer used to have).
あなたが説明したコンテキストでは、おそらく、 を介して間接的++*ptr
にインクリメントする を書きたいと思うでしょう。書き込みは危険です。なぜなら、それは を通り過ぎてしまうからです。また、ポインタは配列の一部ではないため、ポインタはメモリのどこかに (おそらくそれ自体の上に!) ぶら下がっています。x
ptr
*ptr++
ptr
x
x
お役に立てれば!
受け入れられた答えは正しくありません。後置++
演算子が dereference/indirection と同じ優先順位を持つわけではありません*
。前置演算子と後置演算子の優先順位は異なり、逆参照/間接参照と同じ優先順位を持つのは前置演算子のみです。
優先順位の表が示すように、postfix++
はdereference/indirection よりも優先順位が高くなり*
ます。として*ptr++
評価され*(ptr++)
ます。ptr++
の現在の値に評価されptr
ます。ptr
副作用としてのみ増加します。式の値は の現在の値と同じですptr
。したがって、ポインターに格納されている値には影響しません。単にポインタを逆参照し (つまり、そこに格納されている現在の値である 19 を取得)、次にポインタを進めます。あなたの例では、の新しい位置に定義された値が格納されていないptr
ため、ポインターはガベージを指しています。今それを逆参照するのは危険です。
また、表が示すように、接頭辞++
は dereference/indirection と同じ優先順位を持っていますが*
、左右結合のため、 として評価され++(*ptr)
ます。これは、最初にポインタを逆参照し (つまり、ポイントされたアドレスに格納されている値を取得し)、次にその値をインクリメントします。つまり、値は 20 になります。
受け入れられた答えは2つの効果について正しいですが、実際のメカニズムはそこに与えられたものとは異なります.
templatetypedef が言う*ptr
ように、結果を確実にするために括弧を提供する必要があります。たとえば、次の例では、コンピューターで GCC を使用すると 1606415888 が生成され、CLang を使用すると 0 が生成されます。
int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);
x
そして、あなたは 20 歳になると予想していまし(*ptr)++
た。代わりに使用してください。