22

私は C 言語を学んでいて、 と の違いをかなり混乱させてい++*ptrます*ptr++

例えば:

int x = 19;
int *ptr = &x;

私は知っていて、異なる結果++*ptrを生み出していますが、それがなぜなのかわかりませんか?*ptr++

4

3 に答える 3

55

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にインクリメントする を書きたいと思うでしょう。書き込みは危険です。なぜなら、それは を通り過ぎてしまうからです。また、ポインタは配列の一部ではないため、ポインタはメモリのどこかに (おそらくそれ自体の上に!) ぶら下がっています。xptr*ptr++ptrxx

お役に立てれば!

于 2011-03-06T09:03:50.170 に答える
11

受け入れられた答えは正しくありません。後置++演算子が dereference/indirection と同じ優先順位を持つわけではありません*。前置演算子と後置演算子の優先順位は異なり、逆参照/間接参照と同じ優先順位を持つのは前置演算子のみです。

優先順位の表が示すように、postfix++はdereference/indirection よりも優先順位が高くなり*ます。として*ptr++評価され*(ptr++)ます。ptr++の現在の値に評価されptrます。ptr副作用としてのみ増加します。式の値は の現在の値と同じですptr。したがって、ポインターに格納されている値には影響しません。単にポインタを逆参照し (つまり、そこに格納されている現在の値である 19 を取得)、次にポインタを進めます。あなたの例では、の新しい位置に定義された値が格納されていないptrため、ポインターはガベージを指しています。今それを逆参照するのは危険です。

また、表が示すように、接頭辞++は dereference/indirection と同じ優先順位を持っていますが*、左右結合のため、 として評価され++(*ptr)ます。これは、最初にポインタを逆参照し (つまり、ポイントされたアドレスに格納されている値を取得し)、次にその値をインクリメントします。つまり、値は 20 になります。

受け入れられた答えは2つの効果について正しいですが、実際のメカニズムはそこに与えられたものとは異なります.

于 2016-04-29T00:52:53.960 に答える
4

templatetypedef が言う*ptrように、結果を確実にするために括弧を提供する必要があります。たとえば、次の例では、コンピューターで GCC を使用すると 1606415888 が生成され、CLang を使用すると 0 が生成されます。

int x = 19;
int *ptr = &x;
printf("%d\n", *ptr++);
printf("%d\n", *ptr);

xそして、あなたは 20 歳になると予想していまし(*ptr)++た。代わりに使用してください。

于 2011-03-06T09:14:48.150 に答える