2

単純な文字列連結プログラムを書いています。

プログラムは私が投稿した方法で動作します。ただし、最初に次のコードを使用して文字列の末尾を検索するように記述しました。

while (*s++)
    ;

しかし、その方法はうまくいきませんでした。渡した文字列が正しくコピーされませんでした。具体的には、「\0」を保持する char[] 変数に「abc」をコピーしようとしました。

C K&Rの本を読むと、うまくいくようです。そのコンパクトなフォームは、次の手順を実行する必要があります。

  1. *s は '\0' と比較されます
  2. s は次のアドレスを指します

では、なぜうまくいかないのでしょうか。Debian で gcc を使用してコンパイルしています。

このバージョンが機能することがわかりました:

strncat(char *s, const char *t, int n)
{
    char *s_start = s;

    while (*s)
        s++;

    for ( ; n > 0 && *t; n--, s++, t++)
        *s = *t;

    *(s++) = '\0';

    return s_start;
}

前もって感謝します。

4

5 に答える 5

15

の終了後、null ターミネータの後の文字をwhile (*s++);指しsます。次のコードではそれを考慮してください。

于 2010-02-01T03:07:44.300 に答える
6

問題はそれです

 while (*s++)
     ;

s がゼロの場合でも、常に s をインクリメントします (*s は false)。

 while (*s)
    s++;

*s が非ゼロの場合にのみ s をインクリメントします

したがって、最初のものは s を最初の \0 の後の最初の文字を指すままにし、2 番目のものは s を最初の \0 を指すままにします。

于 2010-02-01T03:12:27.550 に答える
4

違いがあります。最初のケースでは、s は '\0' の後の位置を指し、2 番目のケースは '\0' で停止します。

于 2010-02-01T03:08:41.507 に答える
2

John Knoeller が言ったように、実行の最後にNULLのの場所を指します。しかし、正しい解決策のためにパフォーマンスを犠牲にする必要はありません..自分で見てください:

while (*s++); --s;

トリックを行う必要があります。

于 2010-02-01T05:10:17.827 に答える
0

さらに、これまで述べてきたことに加えて、C では、ポインターを逆参照しなくても、ポインターが未割り当てのメモリーを指すことは技術的に違法であることに注意してください。したがって、プログラムが動作しているように見えても、必ずプログラムを修正してください。

于 2010-02-01T05:04:47.527 に答える