• ベストアンサー

ポインタの値の判別

ポインタ自体の値でヌルと0の判別はどのように行えばよいですか? char* p = NULL; char* p = (char*)0; このどちらが実行されても==NULLも==0も真だったので、この方法では判別できませんでした。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

基本的には判別する方法はないのですが、限定的な意味であれば判別できなくもありません。 例えば、NULLマクロが0として定義されているか、(void*)0として定義されているかを調べるには、 sizeof(NULL*0) としてやれば、NULLが(void*)0に定義されている場合にはコンパイルエラーを発生させることができます。 また、sizeof演算子の評価結果を調べれば、int型とlong型のサイズが異なる処理系であれば、0と定義されたか、0Lと定義されたかを調べることができます。 int型とlong型のサイズが同じ処理系や、もっと独自の定義をしているかどうかを調べるには、いったん文字列に置き換えるしかありません。 #define STR(x) VAL(x) #define VAL(x) #x const char *null = STR(NULL); とすれば、NULLマクロの定義内容が文字列として得られますので、この文字列を解析すれば判別が可能です。 いったん何かの変数に格納された後では、単なる0とNULLを判別する手立てはありません。

その他の回答 (4)

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.4

C言語の文法上はヌルポインタ(無効なポインタ)を表す記号は0であって、NULLは標準ヘッダ内で定義されたマクロに過ぎません。 そしてNULLマクロの値はヌルポインタすなわち0ですので、実行時に両者を区別することは不可能です。 ちなみにプロセッサ・アドレス(や整数値)とポインタ値との対応はC言語として規定されていないので、ゼロに限らず整数値をポインタに代入したりする操作は処理系依存です。 char* p = 0; については整数ゼロをポインタに代入しているのではなく、記号0で表されるヌルポインタを代入していると見るべきです。

回答No.3

ポインタとしての、NULL を、定数 0 と比較すると、「等しくなること」が規格で要求されます。 ここで注意しておきたいのは、 char *p = NULL; char *p = (char *)0; として代入した場合、変数 p の内容は、メモリのビットパターンで見た場合、「0」とは限らないということです。 NULL (ポインタ値0)がポインタに代入された場合、「その処理系で、通常の動作ではデータを保存できない」番地に読み替えられるビットパターンが代入されることになっています。そして、そのビットパターンは「0」である必然性はありません。 逆に言えば、C言語なり、C++で、物理的な「0番地」をアクセスする標準的な方法はありません。 もっとも、多くの処理系では、ポインタに、0をだ乳しても、NULL を代入しても、いずれの方法でも、このポインタ経由で「0」番地がアクセスできてしまいますが。 ですから、 char *p = 0; は、文法上正しいのですが、 int i = 0; char *p = i; は、C++ではエラー、C言語では(エラーではないが)普通は「警告」の対象になります。

回答No.2

C++の場合はポインタ変数に対して扱う場合「0」は「NULL」になります。 C言語の場合はNULLの値は処理系に依存します。私は「0」以外の処理系を見たことがありませんけど。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

borland c++ では、 #ifndef NULL # if defined(__cplusplus) || defined(_Windows) # define NULL 0 # else # define NULL ((void *)0) # endif #endif のようになっていました。 確か、0は、NULLポインタとしてどのポインタにもキャストできたような気がしますが、 NULLは、あくまでNULLとして扱うのがいいと思いますね。 (0と同一視すべきではない)

関連するQ&A