web-dev-qa-db-ja.com

(char)0と '\ 0'の違いは何ですか? Cで

(char)0'\0'を使用して文字配列内の終端のnull文字を示すことの違いは何ですか?

29
Sathya

文字リテラルの円記号表記を使用すると、文字自体を使用する代わりに、文字の数値を指定できます。つまり、'\1' [*]は「数値が1の文字」を意味し、'\2'は「数値が2の文字」などを意味します。 Cの癖のため、文字リテラルは実際にはint型を持ち、実際にintは、fgetcの戻り値などの他のコンテキストで文字を処理するためにも使用されます。したがって、'\1'は、「数値が1の文字の、intとしての数値」などを意味します。

文字are Cの数値なので、「数値が1の文字」は実際にはis(char)1であり、'\1'の追加の装飾はコンパイラに影響を与えません-'\1'はCの1と同じ型および値。したがって、独自のエスケープコードを持たない印刷不可能な文字を挿入する場合は、文字リテラルよりも文字列リテラルの方がバックスラッシュ表記が必要です。

個人的には、私が0を意味する場合は0を記述し、暗黙の変換を実行することを好みます。理解するのが非常に難しい人もいます。それらの人々と作業するとき、値0の文字を意味する場合、つまり'\0'がすぐにchar型に暗黙的に変換されることが予想される場合は、0と書くと役立ちます。同様に、nullポインター定数を意味する場合はNULLを、値0のdoubleを意味する場合は0.0などを書くと役立ちます。

それがコンパイラに何らかの違いをもたらすかどうか、そしてキャストが必要かどうかは、コンテキストに依存します。 '\0'のタイプと値は0とまったく同じであるため、まったく同じ状況でcharにキャストする必要があります。したがって、'\0'(char)0はタイプが異なるため、完全に等価な式については、(char)'\0'(char)0、または'\0'0のいずれかを検討できます。 NULLには、実装で定義された型があります。整数型の場合があるため、ポインター型にキャストする必要がある場合があります。 0.0の型はdoubleであるため、確かに0とは異なります。それでも、float f = 1.0;float f = 1;およびfloat f = 1.0fと同じですが、iがintである1.0 / iは通常、1 / iとは異なる値を持っています。

したがって、'\0'0のどちらを使用するかに関する一般的な規則は、純粋にコードの読者の便宜のためです。これは、コンパイラにとっても同じです。あなた(そしてあなたの同僚)の見た目を好むものを選ぶか、マクロASCII_NULを定義してください。

[*]または'\01'-バックスラッシュは10進数ではなくoctal数値を導入するため、0で始まることを確認することでこれを少し明確にするのが賢明な場合があります。0、1の違いはありませんもちろん2。 「時々」と言います。バックスラッシュの後には8桁の数字が3つしか続かないため、\0101の代わりに\101を記述して、それが8進数の値であることを読者に思い出させることができないためです。それはすべてかなり厄介であり、さらに多くの装飾につながります:大文字のAの場合は\x41なので、必要に応じて0の場合は'\x0'と書くことができます。

23
Steve Jessop

どちらも0ですが、(char) 0はcharですが、'\0'は(直感的には)intです。値が0の場合、通常、このタイプの違いはプログラムに影響を与えません。

'\0'、それはそのための定数だからです。

27

ゼロはCで多くの異なることを意味する可能性があります。意図が文字列の終了であることを混乱させることがないため、ヌル文字 '\ 0'を使用する必要があります。

Charを0に設定すると、null終了を意味する可能性がありますが、charを文字列の一部としてではなく、計算用の8ビット整数として使用していることを意味する場合もあります。同じコードでポインタも使用していて、それらをゼロと比較する場合、これはさらに混乱する可能性があります。これは、nullポインタになります。

2
Lundin