(char)0
と'\0'
を使用して文字配列内の終端のnull文字を示すことの違いは何ですか?
文字リテラルの円記号表記を使用すると、文字自体を使用する代わりに、文字の数値を指定できます。つまり、'\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'
と書くことができます。
どちらも0ですが、(char) 0
はcharですが、'\0'
は(直感的には)int
です。値が0の場合、通常、このタイプの違いはプログラムに影響を与えません。
'\0'
、それはそのための定数だからです。
ゼロはCで多くの異なることを意味する可能性があります。意図が文字列の終了であることを混乱させることがないため、ヌル文字 '\ 0'を使用する必要があります。
Charを0に設定すると、null終了を意味する可能性がありますが、charを文字列の一部としてではなく、計算用の8ビット整数として使用していることを意味する場合もあります。同じコードでポインタも使用していて、それらをゼロと比較する場合、これはさらに混乱する可能性があります。これは、nullポインタになります。