2011-07-24 10 views
4

K & R次の文字配列を別の文字配列にコピーするstrcopyというコードスニペットを見ました。Cの構文。文字列のコピー

Tが第1配列へのポインタであり、sはtはにコピーされている配列へのポインタである場合、コードは次のとおり

void strcopy(char *s, char *t){ 

    while(*s++=*t++) 
      ; 
} 

Iは、whileループによって混乱しています。私は、条件tの中はsにコピーされているとは言いますが、ここでどの条件がテストされているのか分かりません。 *t++はいつ偽(またはゼロ)ですか?おそらく、文字列が終了したとき。文字列が終了したかどうかは、指されている文字が'\0'であるかどうかを調べることでテストできます。 K & Rと同じように言います。しかし、この本は、このテストが必要ではないことをむしばんで指摘しています。だからここで何がテストされているのだろうか?

+0

このような古典的なコード。このようなことを書くと、おそらくあなたの同僚が文句を言うでしょう...複数の行にコードを展開すると、簡単に読むのに役立ちます。コンパイラが最適化を行います。 – Stan

答えて

5

*s++ = *t++は割り当てられた値になります。文字列の最後に*t'\0'となり、代入すると式は'\0'(Cはfalseと解釈されます)と評価されます。

私は、whileの状態ですべてが処理されるため、追加のテストは必要ないと言っています。この場合には、それはもちろん

while(*s) 

のテストのようなものですので、状態は常に、左の値を評価し

*s = *t; 
t++; 
s++; 

'\0'は、falseと評価:

+0

+1 – kTiwari

6
*s++ = *t++; 

は同じであり、 while(something)で十分ですので、while(something!='\0')は必要ありません。

+0

't ++'と 's ++'、 '*'はこのケースでは必要ありません。 – ShinTakezou

+0

あなたはそうです、私はそれを急いでしまいました。修正されました。 – vsz

0

Cの割り当ては右から左に流れ、whileループは暗黙の「if」テストを行います。それではコンパイルテストです...

while(*t != 0) // for the sake off testing if the loop should continue ONLY 

別の例...

if (a = b) // note the = vs == so, this will only be true if b != 0 

そのループのフード下の擬似コードのバージョンの種類の観点からし.. 。

loop: 
*s=*t; 
if (*s == 0) should_break=1; 
s++; 
t++; 
if (should_break==1) break; 
goto loop; 
3

終端文字が

while ((*s++ = *t++) != '\0') 
    ; 
を使用して到達した場合は、明示的にテストすることができます

ASCIIテーブルで '\ 0'を検索すると、 '\ 0'の文字の値が0であることがわかります。printf("%d\n", '\0');のようなものを書くことでもわかります。

したがって、上記のwhile文も

while ((*s++ = *t++) != 0) 
    ; 

のように記述することができるしかし、whileループは常に条件が非ゼロの値を持っているかどうかをチェックするので、値を比較するために、常に冗長ですこのようにゼロに対してwhileループで実行されます。したがって、単に比較をスキップすることができます。