2017-08-21 11 views
0

私はヌル文字が必要な理由を正確に読んでいます。そして、私には幾分意味をなさないthis answerが見つかりました。それは、文字配列(C文字列の場合)が実際の文字列よりもはるかに大きく割り当てられるため、必要であると述べています。そのため、最後を象徴する方法が必要です。ヌル文字の必要性についての混乱?

しかし、なぜこれらの配列は、イニシャライザ(なし、なし、実際には文字列リテラルに直接割り当てるときに暗黙的に追加されます)に基づいたサイズ控除で構成されていません。同様に、文字列を保持する配列がサイズ控除を使用して構築されている場合、配列が文字列より大きくないのでヌル文字の必要はありません。もちろん、配列の最後で終了します。

+3

関連性の高い関連度:https://stackoverflow.com/questions/4418708/whats-the-rationale-for-null-terminated-strings?rq=1 – EdChum

+0

配列を持たない場合はどうでしょうか?ポインタ*?それが指しているデータのサイズをどのように知っていますか? –

+0

@EdChumありがとう、私は類似点を見ることができますが、私は本当に私の質問に答えているとは思わない..少なくとも私のスキミングに基づいていない –

答えて

0

従来、文字列配列には終了記号が付いていました。理由は単純です:2つの値(配列の先頭と配列の長さ)を送るのではなく、ただ1つの値、配列の先頭を渡すだけです。これにより、署名の呼び出しは簡単になりますが、呼び出し元にはいくつかの要件があります。

C/C++自体では、ヌル文字は終了記号であるため、すべてのランタイム関数は最初のヌル文字が行末であることを意図して動作します。適用されたロジックの観点から、同じ時点で端末シンボルが異なる可能性があります。たとえば、HTTPヘッダーでは、ヘッダーの終わりと単一のCR-LFをマークするCR-LF-CR-LFシーケンスがありますシーケンスは単なるスタート・オブ・ネクスト・ラインです。

0

しかし、なぜこれらの配列は、ちょうど(文字列リテラルに直接割り当てるときに、実際に が暗黙のうちに追加されたヌル文字なし)初期化子に基づいてサイズ控除 で構成されていないではありません。

私はあなたが書くことができない理由を意味しているとします

char t[] = "abracadabra"; 
をし、コンパイラが11の大きさを推測するのでしょうか?

11文字ではないため、12文字であるため、配列のサイズが11の場合、何かが失われます。NULを含むバイトは参照されず、コンパイラは違いを生じません。

char t[] = "abracadabra"; // an array deduced from a C-string literal 

char t[11] = { 'a', 'b', 'r', 'a', 'c', 'a', 'b', 'r', 'a' }; // a "real" array not a C-string! 

最初は12のスコープの終わりにバイトと第11

歴史を解放しなければなりませんrraysはポインタ算術の上に文法的な砂糖のようなものです。

0

...そのchar配列は...しばしばひどいです答え、実際の文字列

よりもはるかに大きいが割り当てられるため。

Cの文字列はに動的に割り当てられます。つまり、実行時にどれくらいの時間がかかるかわからないことを意味します。大規模な配列を事前に割り当てる代わりに、大部分をゼロで埋める代わりに、malloc(required_size+1)と末尾に1つのヌル文字を付けることができます。

は逆に、はコンパイル時に知らある文字列リテラルは、間違いなくないある「実際の文字列よりもはるかに大きい割り当てられました」。あらかじめどれだけのスペースが必要かを正確に知っているので、何のポイントもありません。

しかし、なぜこれらの配列は、ちょうど初期化子あなたが行くそこ

size_t expected; 
if (read(fd, &expected, sizeof(expected)) == sizeof(expected)) { 
    char *buf = malloc(expected + 1); 
    if (buf && read(fd, buf, expected) == expected) { 
    buf[expected] = 0; 
    /* now do something with buf */ 
    } 
} 

、動的にサイズの文字列に基づいて、サイズの控除で構成されていないではありません。あなたの "サイズ控除"は何ですか? 「イニシャライザ」とは何ですか?

std::stringを使用して、あまり醜い例を書いている可能性があります。質問にはC++というタグが付いているからですが、具体的に質問しているCの文字列です。

1

なぜヌル文字が必要なのかについては、私は読んでいます。それは、文字配列(C文字列の場合)が実際の文字列よりもはるかに大きく割り当てられるため、必要であると述べています。そのため、最後を象徴する方法が必要です。

答えは誤解を招きます。これは実際にヌル終了が必要な理由ではありません。より多くのアップポントで受け入れられた答えが良いです。

配列が文字列よりも大きくないので、ヌル文字の必要はありません。もちろん、配列の最後に終了します。

関数の引数として配列を使用できないことを思い出してください。配列全体を引数にコピーするのが遅くなるため、可能であっても、望みません。

したがって、間接的に配列を参照する必要があります。インダイレクションは、通常、ポインタ(または参照)を使用して実現されます。今では、「文字配列のサイズが42のポインタ」を持つことができますが、引数は特定のサイズの文字列を指すことができるのであまり役に立ちません。

代わりに、共通のアプローチは、配列の最初の要素へのポインタを使用することです。これは非常に一般的なパターンであり、言語には配列の名前が最初の要素へのポインタに暗黙的に崩壊するルールがあります。

しかし、その配列の要素へのポインタに基づいて、配列の大きさを知ることはできますか?それはいけません。追加情報が必要です。 C言語の設計者は、終端文字(すでにC言語が使用しているBCPL言語で使用されていた規約)を使用するオプションを選択したことを示しています。


TL; DRサイズ情報を間接的に列を参照する必要があるために必要な、その間接配列のサイズについての知識を隠しています。ヌルターミネーションは、文字列の内容内でサイズ情報をエンコードする1つの方法であり、C言語のデザイナーが選択した方法です。

0

文字列は、しばしば中間結果を保持するcharアレイを作成し、その内容を変更することによって操作される:バッファは、我々は気に7つの文字を有するstrcpyを呼び出した後

char buffer[128]; 
strcpy(buffer, "Hello, "); 
strcat(buffer, "world"); 
std::cout << buffer << '\n'; 

と、 strcatへの呼び出しの後には12があります。そのため、バッファ内の文字の数が変更される可能性があります。また、いくつの文字が存在するかを示す方法が必要です。 1つの規則は、文字数を配列の最初の位置に置き、その後の実際の文字を置くことです。もう1つの慣例は、重要な文字の最後にマーカーを付けることです。ここではトレードオフがありますが、C++に組み込まれたCの決定は終わりのマーカーで行われます。

関連する問題