3

重複の可能性:
C では NULL は常にゼロですか?

次のコード:

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

if (NULL == 0)
    printf("the NULL is same as 0\n");

printf("0 : %s\n", 0);
printf("p1 : %s\n", p1);
printf("p1 : %x\n", p1);
printf("&p1 : %x\n", &p1);

printf("NULL : %s\n", NULL);
printf("p2 : %s\n", p2);
printf("p2 : %x\n", p2);
printf("&p2 : %x\n", &p2);
printf("*p2 : %s\n", *p2);

出力:

the NULL is same as 0
0 : (null)
p1 : (null)
p1 : 0
&p1 : bf9a0204
NULL : (null)
p2 : (null)
p2 : 0
&p2 : bf9a0208
Segmentation fault (core dumped)

私は疑問に思う:

(ヌル)は何を表していますか?

ポインタ p1 または p2 はアドレス 0x0 を指していますか?

ステートメント printf("p1 : %x\n", p1); を実行しますか? 出力 p1 : 0 は、p1 がアドレス 0x0 を指していることを示しますか?

4

3 に答える 3

6

これらすべての初期化

char *p1 = 0;
char *p2 = NULL;
char *p3 = (char *)0;

同等です。それらはすべて、これらのポインターをタイプのヌルポインター値char *で初期化します。そのヌル ポインター値の物理表現は、プラットフォームに依存します。0x0物理アドレスで表されることは保証されていません。一般に、それらが「指す」物理アドレスを言う方法はありません。

0x0出力から判断すると、プラットフォームのヌルポインター値はたまたま物理アドレスで表されます。ただし、ポインター値を出力する適切な方法printfは、フォーマット指定子を使用するか%p、ポインター値を適切な整数型に変換することです。を使用%xしてポインターを出力すると、未定義の動作が発生します。

表示される出力は、 null ポインターで指定子を使用しようとしたとき(null)の反応です。これは未定義の動作につながりますが、標準ライブラリの実装により、最悪の事態を回避し、代わりに印刷することを決定したようです。printf%s(null)

実際、コード サンプルのすべてのprintfステートメントが正しく構成されておらず、それぞれが未定義の動作を引き起こしています。

于 2012-07-02T18:25:19.090 に答える
3

(ヌル)は何を表していますか?

これはprintf()、null ポインター値が渡されたときに文字列を出力する要求を明らかに処理する方法です。ポインタ値の標準書式指定子は次のとおりです。%p

ポインタ p1 または p2 はアドレス 0x0 を指していますか?

必ずしも。これらは、プラットフォーム上でヌル ポインターが指すものを指します。

ステートメント printf("p1 : %x\n", p1); を実行します。出力 p1 : 0 は、p1 がアドレス 0x0 を指していることを示しますか?

いいえ、それは null ポインター値が printf() にポインターとして渡されたときに変換され、unsigned intunsigned int再解釈されると(%x が期待するものです)、値がゼロになることを示しているだけです。繰り返しますが、ポインタの正しい書式指定子は%p.

于 2012-07-02T18:25:16.850 に答える
0

NULL は通常、数値 0 として定義され、多くの場合、ポインター型 (ほとんどの場合void *) にキャストされます。ただし、C 標準では、NULL ポインターがゼロであることは保証されていません。別の不正なメモリアドレスであるプラットフォーム (特に奇妙な古いハードウェア、一部の組み込みシステムなど) があります。

ただし、null ポインターを常にゼロであるかのように操作できる場合があります。書き込みは;if (pointer)に変換されます。if (pointer != NULL)さらに、ポインターに割り当てられた、またはポインターと比較されたゼロ値に遭遇すると、ほとんどのコンパイラーは、技術的にゼロではない場合でも、それを NULL を含む操作として扱います。

于 2012-07-02T18:46:12.177 に答える