私はこのコードについて混乱しています:(http://www.joelonsoftware.com/articles/CollegeAdvice.html)
while (*s++ = *t++);
実行の順序は何ですか?* s = * tが最初に実行され、次にそれぞれが増分されますか?または他の方法?
ありがとう。
編集:そしてそれがあった場合はどうなりますか:
while(*(s++) = *(t++));
と
while(++*s = ++*t);
私はこのコードについて混乱しています:(http://www.joelonsoftware.com/articles/CollegeAdvice.html)
while (*s++ = *t++);
実行の順序は何ですか?* s = * tが最初に実行され、次にそれぞれが増分されますか?または他の方法?
ありがとう。
編集:そしてそれがあった場合はどうなりますか:
while(*(s++) = *(t++));
と
while(++*s = ++*t);
while (*s++ = *t++);
優先順位の表から、がより++
も優先順位が高いことがはっきりとわかります*
。ただし、++
ここではポストインクリメント演算子として使用されているため、インクリメントは代入式の後に行われます。したがって*s = *t
、最初に発生し、次にsとtが増分されます。
編集:
while(*(s++) = *(t++));
上記と同じです。かっこを使用して、より明確にしています。++
ただし、それでもポストインクリメントであることを忘れないでください。
while(++*s = ++*t);
sの横には演算子が1つだけあります。したがって*
、最初に適用され、その結果++
が適用されてlvalue required
エラーが発生します。
while(*++s = *++t);
ここでも、s、tの横にある演算子だけです。したがって、インクリメントが最初に発生し、次にコピーが発生します。したがって、最初の文字のコピーをtからsに効果的にスキップしています。
あなたが正しいです。* s = * tが最初に実行され、次に増分されます。
インクリメントはポストインクリメントです。変数がインクリメントされた後に来るだけでなく、式が評価された後に来るという理由で投稿します。したがって、実行の順序は次のとおりです。
*s = *t
次にs++とt++
編集::
@chrisgoyal
実行の順序はあいまいな用語です。ここには2つの異なるものがあります。構文上の順序、および式のセマンティクス。
構文的には、演算子++が最初に適用されます。* sが最初に適用される場合、以下は@Hoganが言ったことと同等です。
(*s)++ = (*t)++
これはジョエルのサンプルとは大きく異なります。
演算子++のセマンティクスは、式の後に実行されることです。
それが私が何を食べているかを明らかにすることを願っています。
実際には、s++
最初t++
に適用されます。式の実行後に後置演算子が実行されることを忘れないでください。基本的に、演算子++
は両方に適用され、実行 *s = *t
されます。
ポストインクリメントでは、操作変数が最初に使用され、次に変更された後に使用されます。
コード:(while *s++ = *t++);
は以下とほぼ同等です:
while (*s = *t) {
++s;
++t;
}
2 つ目はまったく同じです。余分な括弧は何も変更しません (この場合)。括弧が何かを行うには、次のようにする必要がありますwhile ((*s)++ = (*t)++);
。これは、3 番目の例 (以下の段落で説明します) とほぼ同じです。
最後の例:while(++*s = ++*t);
は完全に異なります。逆参照 ( *
) はオペランドに近いため、これはオペランドを逆参照し、逆参照の結果をインクリメントします。つまり、ポインター自体をインクリメントするのではなく、ポインターが AT を指すものをインクリメントします。その結果、これは最初の文字をコピーし、その文字をインクリメントしてから、その文字がゼロでないかどうかをチェックし、ゼロになるまで同じことを続けます。その結果、ソースと宛先の両方が空の文字列になります (両方の最初の文字がゼロになり、文字列を終了するために使用されるため)。
したがって、増分には2つの形式があります
++s // increment before using value
s++ // increment after using value
これらの結果は逆参照できます。
*++s // or...
*s++
これは、C が実行された最初のマシンの 1 つである PDP-11 で非常にうまく機能しました。次の ops がハードウェアで利用可能でした:
*--s // or
*s++
あなたはどちらかを行うことができます
*x++ = *y++; // or
*--x = *--y; // or some combination
もしそうなら、行全体が単一の命令で発生しました。ただし、 // コメントは C99 で導入されたので、実際には私のコメント構文から抜け出すことはできませんでした。