web-dev-qa-db-ja.com

char *の配列は '\ 0'または "\ 0"で終わる必要がありますか?

Charポインタの配列があるとしましょう

char* array[] = { "abc", "def" };

さて、最後に何を入れるべきでしょうか?

char* array[] = { "abc", "def", '\0' };

または

char* array[] = { "abc", "def", "\0" };

しかし、どちらも機能します。私たちはそれに応じて終了をチェックするための条件を置くだけです

お気に入り

array[ index ] != '\0';

または

array[ index ] != "\0";

私の質問はどちらが良い方法ですか?ほとんどのプログラマーがどちらを使用していますか?

編集

ほとんどの回答は、NULLは '\ 0'および "\ 0"よりも優れていると言っています。しかし、私はいつもそれを考えました

NULLは0x0または0と同じ「\ 0」と同じ

違いますか?

15
Andrew-Dufresne

NULLで終わります。どうして?これらのいずれも実行できないためです。

_array[index] == '\0'
array[index] == "\0"
_

1つ目は、_char *_をcharと比較することです。これはnotが必要なものです。これを行う必要があります:

_array[index][0] == '\0'
_

2つ目も機能しません。 _char *_を_char *_と比較していますが、この比較は意味がありません。 2つのポインタが同じメモリの一部を指している場合は合格です。 2つの文字列を比較するために_==_を使用することはできません。strcmp()関数を使用する必要があります。すてきな。一方、次のとおりです。

_array[index] == NULL
_

うまく機能し、あなたのポイントを伝えます。

28
Chris Lutz

C99仕様によると、

  • NULLはnullポインター定数に展開されます。これは必須ではありませんが、通常はvoid *型です
  • '\0'は文字定数です。文字定数はint型であるため、単純な0と同等です。
  • "\0"はnullで終了する文字列リテラルであり、複合リテラル(char [2]){ 0, 0 }と同等です。

NULL'\0'および0はすべてnullポインター定数であるため、変換時にすべてnullポインターが生成されますが、"\0"はnull以外のchar *を生成します(これはconstとして扱う必要があります)未定義);このポインターはリテラルの出現ごとに異なる可能性があるため、センチネル値として使用することはできません。

0の整数定数式をnullポインター定数として使用できますが('\0'またはsizeof foo - sizeof foo + (int)0.0など)、意図を明確にするためにNULLを使用する必要があります。

7
Christoph

これらの2つのうち、最初の1つはタイプの誤りです。 '\ 0'はポインターではなく文字です。ポインターに変換できるため、コンパイラーはそれを受け入れます。

2つ目は、偶然にのみ機能します。 「\ 0」は2文字の文字列リテラルです。それらがソースファイルの複数の場所で発生する場合、コンパイラはそれらを同一にする場合がありますが、そうする必要はありません。

だから最初のものを書く正しい方法は

char* array[] = { "abc", "def", NULL };

array[index]==NULLをテストします。 2番目のものをテストする適切な方法はarray[index][0]=='\0'です。文字列に '\ 0'をドロップすることもできます(つまり、""とスペルします)。これにはすでにnullバイトが含まれているためです。

6

まあ、技術的には'\0'は文字ですが、"\0"は文字列なので、null終了文字をチェックする場合は前者が正しいです。ただし、 Chris Lutzが彼の回答で指摘 のように、現在の形式では比較は機能しません。

1
ChrisF

ヌル終端は、歴史の本に残された最良の設計パターンです。 Cストリングの背後にはまだ多くの慣性があるため、そこで回避することはできません。しかし、OPの例でそれを使用する理由はありません。

ターミネータは使用せず、sizeof(array)/ sizeof(array [0])を使用して要素の数を取得します。

0
Alan

文字の配列をnull文字で終了することは、Cの文字列に固有の規則にすぎません。完全に異なるもの(文字ポインターの配列)を扱っているため、実際にはCの規則とは関係ありません。文字列。もちろん、nullポインタで終了することもできます。これはおそらく、ポインターの配列の規則になる可能性があります。それを行うには他の方法があります。あなたはそこにない慣例を想定しているので、それがどのように「うまくいく」べきかを人々に尋ねることはできません。

0
newacct