私はC言語を学習していて、++*ptr
および*ptr++
。
例えば:
int x = 19;
int *ptr = &x;
知っている ++*ptr
および*ptr++
異なる結果が生成されますが、それはなぜですか?
これらのステートメントは、演算子のバインド方法が原因で、異なる結果を生成します。特に、接頭辞++
演算子の優先順位は*
と同じであり、右から左に関連付けられます。したがって
++*ptr
として解析されます
++(*ptr)
「ptr
が指す値を増やす」という意味です。一方、postfix++
演算子は、逆参照演算子*
よりも優先されます。その前に
*ptr++
手段
*(ptr++)
これは、「ptr
が現在指している値に評価し、ptr
の値をインクリメントする」ことを意味します(その順序は指定されていません)。
あなたが説明したコンテキストでは、x
を介して間接的にptr
をインクリメントする++*ptr
を記述したいと思うでしょう。 *ptr++
を書き込むと、ptr
がx
を越えて進むので危険です。また、x
が配列の一部ではないため、ポインターはメモリ内のどこかに(おそらくそれ自体の上に)ぶら下がっています。
お役に立てれば!
受け入れられた答えは正しくありません。接尾辞_++
_演算子の優先順位が逆参照/間接参照_*
_と同じであるとは限りません。前置演算子と後置演算子の優先順位は異なり、prefix演算子のみが逆参照/間接参照と同じ優先順位を持ちます。
優先順位テーブル が示すように、postfix _++
_は、間接参照/間接参照_*
_よりも高い優先順位を持っています。したがって、_*ptr++
_は*(ptr++)
として評価されます。 _ptr++
_はptr
の現在の値に評価されます。副作用としてのみptr
をインクリメントします。式の値は、ptr
の現在の値と同じです。したがって、ポインタに格納されている値には影響しません。それは単にポインタを逆参照する(つまり、そこに格納されている現在の値(19)を取得する)してから、ポインタを進めます。あなたの例では、ptr
の新しい位置に定義された値が格納されていないため、ポインターはガベージを指しています。今それを逆参照するのは危険です。
また、表に示されているように、接頭辞_++
_は逆参照/間接参照_*
_と同じ優先順位を持っていますが、左右の結合性のため、++(*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)++
を使用してください。