Cでの文字列の定義の詳細は何ですか?


10

私はクラスの1つに対する宿題の質問に回答することになっています。具体的には、Cの特定の配列が文字列と見なされるかどうかを言うことになっています。この記事(https://www.geeksforgeeks.org/strings-in-c-2/)に基づいて、文字列は末尾にヌルターミネータが付いた文字の配列であることを知っています。

私の主なハングアップは、次のような配列について尋ねる質問の一部です。

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

これは明らかに、末尾にヌル終了文字がある文字の配列です。ただし、途中にnullの終了文字があるため、文字列と見なされますか?それは文字列にどのように影響しますか?

編集:コメントに基づいて、私は質問の実際の表現を提供しました:

「次の配列のうち、strcpy()、strncpy()、strcmp()、strncmp()、および同様の文字列関数(すべての適用を示す)への引数として使用するために、「文字列」と見なすことができるのはどれですか? "

編集:質問が曖昧に書かれているようだったので(数人が指摘したように)、それについて教授にメールを送りました。誰かが気になるなら、彼は私に「はい、それは文字列です。重要なのはnull文字があることです。しかし、もちろんそれはすべての文字列操作に影響します。文字列はnull文字で終わります。」


4
"CS"数バイトのガベージが追加された文字列であると言うかもしれません(この場合、最後の NUL文字は無関係です)。しかし、それは「全体として」の文字列ではありません。-それでも、これをstrcpyetc に供給しても、これらの関数は"CS"パーツのみを「見る」ため、PCが爆発することはありません。
ハーゲンフォンアイツェン

2
c1は絶対にの引数として使用できますstrcmp()。文字列関数の変更の引数として使用できるかどうかは、提供されていない追加の要因によって異なります。
EOF

2
の内容c1は変更可能であるためstrcpy、ソース文字列を収容するのに十分な大きさでなかった場合を除いて、それが有効な宛先引数などにならない理由はわかりません。それは文字列ではなく、特定の目的に適したものではありません。
ジョンボリンジャー

1
全体として、質問が曖昧に表現されていることに同意します。式c1は、すべての標準ライブラリの(狭い)文字列関数の文字列引数の基本的な要件を満たします(特に名前が付けられたものをすべて含みます)が、呼び出し側が期待または望んでいる動作とは異なる場合があります(引き出される可能性のある未定義の動作を無視する場合でも)。
ジョンボリンジャー

1
ことに注意してくださいタイプの必要性があることではありませんchar。任意の文字タイプで十分です。
chux-モニカを

回答:


8

c1ほとんどは[1]と同じで&c1[0]、1つの文字列を保持しています"CS"

そこ、そこに潜んで2番目の文字列だ"324"から始まるが&c1[3]-しかし、限り、あなたはアクセスとしてc1のようにc1、文字列は、"CS"すべての関数であるstrcpy()ら。見ることになります。


[1]:c1配列、&c1[0]ポインタです。


それで、コマンドのc1ターゲット文字列として使用するのは適切strcpy()ですか?質問はあいまいです-せいぜい。
Andrew Henle

1
もちろんc1、のどちらの引数としても使用できますstrcpy()。それはあらゆる意味で完全に普通の弦です。通常の文字列では、ターミネータの後に残りのゴミが含まれることがよくあります。このゴミがプログラムにハードコードされているという事実は、作者がc1文字列以外の方法で使用するつもりであるという印象を与えますが、それは問題の一部ではありませんでした。
リーダニエルクロッカー

「」c1&c1[0]「誤解させる」と同等です。 c1配列です。 &c1[0]ポインタです。
chux-モニカを

2

Cでの文字列の定義の詳細を知りたい場合は、ソースにアクセスしてください。

C90標準から

7ライブラリ

7.1はじめに

7.1.1用語
定義文字列は、最初のヌル文字で終了し、最初のヌル文字を含む、連続した文字のシーケンスです。文字列への「ポインタ」は、最初の(アドレス指定が最も低い)文字へのポインタです。文字列の「長さ」は、ヌル文字の前の文字数であり、その「値」は、含まれる文字の値の順序です。

(後の基準に関連する変更はありませんでした。)

したがって、c1「CS」と「324」の2つの連続した文字列が含まれていますが、それ自体は文字列ではありません。

配列を関数に渡すと、最初の要素へのポインターに減衰する+c1ため、文字列(最初の要素)を指します。これは、文字列へのポインターを期待するすべての関数にとって十分なものです。「CS \ 0324」という文字列は指していませんが、あいまいなインストラクターの質問にはおそらく十分です。


4
この定義によっても、c1は明らかに文字列「CS」であると私は主張します。限目。ターミネータの後にはゼロ以外のバイトが含まれている可能性があるという事実は関係ありません。多くの文字列は、存続期間中はそのようになります。
リーダニエルクロッカー

+c1文字列でc1始まるため、文字列を指します。それは決して形c1、文字列を作る形ではありません。
Deduplicator

2
これは、ゼロバイトで終了するいくつかの文字を含むメモリセクションのアドレスです。%sで問題なくprintf()を実行すると、strlen()に完全に適切な数値が渡され、strcpy()に渡しても機能します。文字列のように聞こえます。
リーダニエルクロッカー


もちろん。ただし、配列は確かに文字列にすることができます。
Lee Daniel Crocker

0

@DevSolarの答えに加えて、与えられた文字列をいじくり回した後に発見したものがあるとすれば、

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

この文字列を出力するCS03240と、この文字列のサイズが7になります。私の理解では、\\0null文字(つまり \0)を表すためにが使用されています。もしあなたがそうするなら:

printf("\0");

出力ログには何も表示されませんが、表示された場合:

printf("\\0");

が表示\0されます。これは、バックスラッシュや引用符などの特殊文字を出力する\には、それらを一緒に使用する必要があるためです。

私を困惑させるものは出力でCS03240あり、それはサイズ7です。文字列のサイズは、その中の文字数に1(null文字の場合)を加えたものであると一般的に理解されています。また、文字列のサイズも7 char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };です。

では、この質問の補足として、ここで何が起こっているのでしょうか?


1
'\\0'ヌル文字ではありません。複数文字定数です。確かにの範囲外の実装定義値がありcharます。 c1[]でない文字列には欠けているとして、ヌル文字が。「この文字列を出力した」とは、おそらく未定義の動作を引き起こすことになります。
chux-モニカを

複数文字の定数を調べたが、正確には理解できなかった。末尾にnull文字がないためc1 []が文字列でない場合、OPによってポストされた最初のケ​​ースでサイズが7になるのはなぜですか?
rasengan__

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };7つの値で初期化されるため、サイズは7です。これは、大きさとは何の関係もありません文字列をchar c1[] = { 1, 2, 3, 4, 5, 6, 7 };まだそれはサイズ7になるだろう
復活モニカ- chux

配列c1には文字列が含まれていますか?それは別の問題です。次
chux-モニカを
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.