12

Cの文字配列の最後に「\0」(null)を追加する必要があるのはなぜですか?K&R 2(1.9文字配列)で読みました。最長の文字列を見つけるための本のコードは次のとおりです。

#include <stdio.h>
#define MAXLINE 1000
int readline(char line[], int maxline);
void copy(char to[], char from[]);

main() {
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];
    max = 0;
    while ((len = readline(line, MAXLINE)) > 0)
        if (len > max) {
            max = len;
            copy(longest, line);
        }
    if (max > 0)
        printf("%s", longest);
    return 0;
}

int readline(char s[],int lim) {
    int c, i;
    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0'; //WHY DO WE DO THIS???
    return i;
}

void copy(char to[], char from[]) {
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

私の質問は、なぜ文字配列の最後の要素を'\ 0'に設定するのですか?プログラムはそれがなくても正常に動作します...助けてください...

4

8 に答える 8

15

これは、ライブラリが文字列の終わりを知る方法であるため、 C文字列をで終了する必要があり'\0'ます(そして、あなたの場合、これはcopy()関数が期待するものです)。

プログラムはそれがなくても正常に動作します...

これがないと、プログラムの動作は未定義になります。プログラムが期待どおりに動作する場合、あなたは幸運です(または、現実の世界では未定義の動作が最も不便な状況で現れるため、不幸です)。

于 2012-12-16T18:17:04.547 に答える
1

cでは、「文字列」はnullで終了する文字の配列を意味します。これをパスカル文字列と比較してください。これは、文字列の長さを示すバイトが前に付いた最大255文字を意味します(ただし、終了は必要ありません)。

それぞれのアプローチには長所と短所があります。

于 2012-12-16T18:24:46.360 に答える
1

特に、長さが不明な文字の配列を指す文字列ポインタは、NULLターミネータが文字列の長さを決定する唯一の方法です。

リンクでのNULL終了に関する素晴らしい議論

于 2012-12-16T18:20:36.553 に答える
0

実際、文字配列を \0 で終了する必要はありません。これは char*、またはそれで終了する必要がある文字列の C 表現です。

配列に関しては、文字列 (char* による表現) に転送する場合は、末尾に \0 を追加する必要があります。

一方、配列を char* としてアドレス指定し、それに char* 関数を使用する場合は、配列の末尾に \0 を付ける必要があります。

于 2012-12-17T11:26:43.050 に答える
0

C では、最初の null 文字で終了し、最初の null 文字を含む連続した文字列として文字列が定義されているためです。

基本的に、C の作成者は、一連の文字 + 文字列の長さとして文字列を定義するか、魔法のマーカーを使用して文字列の終わりを区切るかを選択できました。

この件に関する詳細については、次の記事を読むことをお勧めします。

Poul-Henning Kamp による「最も高価な 1 バイトの間違い」 http://queue.acm.org/detail.cfm?id=2010365

于 2012-12-16T18:34:23.917 に答える
0

あなたは実際にここに答えを書いています:

void copy(char to[], char from[]) {
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

この関数のループは、からの配列で '\0' に遭遇するまで続きます。終端のゼロがない場合、ループは、ゼロまたは無効なメモリ領域に遭遇するまで、不明な数のステップを続行します。

于 2012-12-16T18:50:36.200 に答える
0

'\0'配列内の は文字列の末尾を示します。これは、この文字の後の文字は文字列の一部とは見なされないことを意味します。文字配列の一部ではないという意味ではありません。つまり、インデックスを作成することでこれらの文字にアクセスすることはできますが、この文字配列に対して文字列関連のものを呼び出す場合、これらの文字は一部ではありません。

文字列を適切な形式にし、文字列関数で正しく動作させるには、null で終わる文字配列にする必要があります。NULL がない場合、文字配列で文字列関数を呼び出すと、プログラムは未定義の動作を示します。ほとんどの場合、幸運にも結果が得られるかもしれませんが、それでも未定義の動作です。

于 2016-12-12T07:28:40.767 に答える
-1

これは文字列終了記号です。これが発生すると、コンパイラは文字列が終了したことを認識します。

于 2012-12-16T20:07:47.833 に答える