NULL
C では、ゼロのさまざまな値 ( 、NUL
)の間に違いがあるようです0
。
ASCII 文字がまたは'0'
に評価されることはわかっています。48
0x30
ポインタNULL
は通常、次のように定義されます。
#define NULL 0
または
#define NULL (void *)0
また、評価しそうなNUL
キャラクターもいます。'\0'
0
これら 3 つの値が等しくならない場合もありますか?
これは 64 ビット システムでも同様ですか?
ベストアンサー1
注:この回答は C++ ではなく C 言語に適用されます。
ヌルポインタ
整数定数リテラルは、0
使用されるコンテキストに応じて意味が異なります。いずれの場合も、値 を持つ整数定数であることに変わりはなく0
、単に記述方法が異なるだけです。
ポインターが定数リテラルと比較されている場合0
、これはポインターがヌル ポインターであるかどうかを確認するチェックです。これはヌル ポインター0
定数と呼ばれます。C 標準では、0
型へのキャストはvoid *
ヌル ポインターとヌル ポインター定数の両方であると定義されています。
さらに、読みやすさを向上させるために、マクロはNULL
ヘッダー ファイルに提供されていますstddef.h
。コンパイラによっては、#undef NULL
これを奇妙なものに再定義できる可能性があります。
したがって、ヌル ポインターをチェックする有効な方法をいくつか示します。
if (pointer == NULL)
NULL
NULL
は、ヌル ポインターと等しいかどうかを比較するように定義されています。有効なヌル ポインター定数である限り、の実際の定義は実装によって定義されます。
if (pointer == 0)
0
ヌルポインタ定数の別の表現です。
if (!pointer)
このif
ステートメントは暗黙的に「0 ではない」をチェックするので、これを逆にして「0 である」という意味にします。
以下は、ヌル ポインターをチェックする無効な方法です。
int mynull = 0;
<some code>
if (pointer == mynull)
コンパイラにとって、これはヌル ポインターのチェックではなく、2 つの変数の等価性チェックです。コード内で mynull が変更せず、コンパイラの最適化によって 0 が if ステートメントに定数として折り畳まれる場合は、これが機能する可能性がありますが、これは保証されておらず、コンパイラは C 標準に従って少なくとも 1 つの診断メッセージ (警告またはエラー) を生成する必要があります。
C 言語のヌル ポインターの値は、基盤となるアーキテクチャでは関係ないことに注意してください。基盤となるアーキテクチャにアドレス 0xDEADBEEF として定義されたヌル ポインター値がある場合、この混乱を解決するのはコンパイラーの責任です。
そのため、この奇妙なアーキテクチャでも、次の方法は null ポインターをチェックする有効な方法です。
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
以下は、ヌル ポインターをチェックする無効な方法です。
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
これらはコンパイラによって通常の比較として認識されるためです。
ヌル文字
'\0'
はヌル文字として定義されます。つまり、すべてのビットがゼロに設定された文字です。'\0'
は (すべての文字リテラルと同様に) 整数定数であり、この場合は値がゼロです。したがって、 は'\0'
装飾のない整数定数と完全に同等です0
。唯一の違いは、人間の読者に伝える意図(「これをヌル文字として使用しています。」) にあります。
'\0'
ポインタとは何の関係もありません。ただし、次のようなコードが見つかるかもしれません:
if (!*char_pointer)
char ポインタが null 文字を指しているかどうかを確認します。
if (*char_pointer)
char ポインタが null 以外の文字を指しているかどうかを確認します。
これらをヌル ポインターと混同しないでください。ビット表現が同じで、これにより便利な相互運用が可能になるという理由だけで、これらは実際には同じものではありません。
参考文献
見るcomp.lang.c FAQ の質問 5.3詳しくはこのPDFC 標準については、セクション 6.3.2.3 ポインタ、段落 3 を参照してください。