次のコードは私を少し混乱させました:
char * strcpy(char * p, const char * q) {
while (*p++=*q++);
//return
}
これは、関数の簡素化された実装ですstrcpy
。このコードから、ポインターp
がq
インクリメントされてから逆参照され、 char に到達するまでq
割り当てられることがわかります。p
\0
while ループの最初の繰り返しについて誰かに説明してもらいたいです。
次のコードは私を少し混乱させました:
char * strcpy(char * p, const char * q) {
while (*p++=*q++);
//return
}
これは、関数の簡素化された実装ですstrcpy
。このコードから、ポインターp
がq
インクリメントされてから逆参照され、 char に到達するまでq
割り当てられることがわかります。p
\0
while ループの最初の繰り返しについて誰かに説明してもらいたいです。
++
は変数の後にあるため、式が評価されるまで増分されません。これがポストインクリメント演算子である理由です。プレインクリメントには接頭辞 ( ++p
) が付きます。 *++p
2 番目のスポットに*p++
書き込み、最初のスポットに書き込みます。
式x++
とには、結果(値) と副作用++x
の両方があります。
式の結果x++
は の現在の値ですx
。副作用として、の内容がx
1 インクリメントされます。
式の結果++x
は現在の値にx
1 を加えたものです。副作用は上記と同じです。
式が評価された直後に副作用を適用する必要はないことに注意してください。次のシーケンス ポイントの前にのみ適用する必要があります。たとえば、コードが与えられた場合
x = 1;
y = 2;
z = ++x + y++;
x
式y++
が評価される前、または の結果++x + y++
が代入される前でさえ、 の内容が変更されるという保証はありませんz
(どちらの演算子もシーケンス ポイントを導入しません) =
。式+
は2 に評価されますが、割り当てられる まで変数に値 2 が含まれない可能性があります。 ++x
x
z
x++ + x++
のような式の動作は、言語標準によって明示的に未定義であることを覚えておくことが重要です。x
式の結果がどうなるか、または評価後に どのような値が含まれるかを予測する (良い) 方法はありません。
後置演算子は単項演算子よりも優先順位が高いため、次のような式は次のよう*p++
に解析され*(p++)
ます (つまり、*
式の結果に演算子を適用していますp++
)。繰り返しますが、式の結果p++
は の現在の値でp
あるためwhile (*p++=*q++);
、最初の要素はスキップされません。
自動インクリメント/デクリメント演算子のオペランドは、左辺値でなければならないことに注意してください(基本的に、メモリの読み取りまたは変更が可能なメモリ位置を参照する式)。式x++
orの結果は左辺値で++x
はない++x++
ため、 or(x++)++
またはのようなものは記述できません++(++x)
。( is not an lvalue, but is) のようなものを書くこともできますが、おそらくコードを読んでいる誰かに叩かれるでしょう。 ++(*p++)
p++
*p++
p++
ポインタをポストインクリメントしていますp
。そのため、 の現在の値は、インクリメントされる前p
に deference 演算子によって操作されます。*
p
while
ループが次のように記述されていれば、あなたの推論は正しかったでしょう。
while (*++p=*++q);
この場合、逆参照の前にインクリメントが発生します。
いいえ、増分は割り当て後に発生します。
である場合*(++p)
、ポインターp
はインクリメントされ、その後割り当てられます。
式の右辺 (*q++) は *p++ の前に評価され、両方とも代入が行われた後にのみインクリメントされます。
ステートメントを右から左に読んでください。後置インクリメント (++q ではなく q++) は、行内の他のすべてが解決された後に発生することに注意してください。
*q --> dereference q
= --> assign the value
*p --> to p
両方を増やします。
qp が q の要素 = 0 になるまでこれを行います。これは、null ターミネータに到達するときです。
これは、strcpy 関数の実装を取り除いたものです。このコードから、ポインター p と q がインクリメントされ、逆参照され、q が \0 文字に到達するまで p に割り当てられることがわかります。
それは逆に起こります。の値*p
が に設定され*q
、両方のポインタがインクリメントされます。
int foo = bar++
foo が設定された後にインクリメントが発生する場合。それを最初に実現するには、次のようにします。int foo = ++bar
の値q++
は q
の値++q
はq+1
ループのwhile
条件はポストインクリメントを実行しています。同様に:
while (true) {
char* old_p = p;
const char* old_q = q;
++p; // or p++;
++q; // or q++;
*old_p = *old_q;
if (*old_p == '\0')
break;
}