45

そのため、いくつかのインタビューの質問を行っていたところ、 void および null ポインターに関する質問に出くわしました。

戻り値の型を持たないポインターは null ポインターと呼ばれます。任意の種類のデータ型にすることができます。

これは私を完全に混乱させました!この質問によれば、void と null は同じ意味で使用できるようですが、それが正しいとは思いません。void を戻り値の型、null を値と仮定しました。しかし、私はコードの新人にすぎず、自分が正しいかどうか確信が持てません。

nullポインタとvoidポインタとは何かについて、あなたの見解を述べてください。null と void の違いを探しているわけではありません。

4

9 に答える 9

53

2 つの概念は直交しています。

  1. void ポインター ( void *) は、あるメモリ位置への生のポインターです。
  2. null ポインターは、定義上、何も指さない特別なポインターです。これは、void またはそれ以外の任意の型へのポインターにすることができます。

void ポインターは、null でもそうでなくてもかまいません。

void *void_ptr1 = nullptr;
void *void_ptr2 = malloc(42);
void *void_ptr3 = new Foo;               // void * can point to almost anything
void *void_ptr4 = (char*)void_ptr3 + 1;  // even somewhere inside an object

非 void ポインターは、null でもそうでなくてもかまいません。

Foo *f = nullptr;
Foo *g = new Foo;
于 2010-12-02T12:15:10.813 に答える
31

その答えを忘れてください。あなたのリンクからの引用:

「戻り値の型のないポインターはヌルポインターと呼ばれます。」

これは非常に明白な間違っています。ポインターの戻り値の型? 本当?悪いソースだ…

void*は、任意のポインター型 (const および/または volatile へのポインターを除く) を暗黙的に に変換できるため、ユニバーサル ポインターvoid*です。つまり、任意のポインターを type の変数に割り当てることができますvoid*。null ポインターはポインター0です

于 2010-12-02T12:15:54.693 に答える
24

voidタイプは一般に、タイプ情報が与えられていないことを意味します。

ポインタは 2 つの情報を伝達することを常に念頭に置いておく必要があります。ポインタが指すデータの( intdouble、...) は、それを解釈する方法を指定し、ポインターが指すデータのアドレスは、どこを指すかを指定ます。ポイントされたデータの実際の値を取得できます。

型情報はポインターの型 ( 、、...) にありますが、データのアドレスはポインター変数に含まれる実際の値です。double*int*

したがって、voidポインター ( void *) は型情報を指定しないポインターです。データがどこにあるかはわかりますが、それを解釈する方法はわかりません。intそのアドレスに何かがあることはわかっていますが、それが、 、doubleまたは空飛ぶ牛の配列であるかどうかはわかりません。そのようなデータを実際に使用するには、別の方法で (たとえば、他のマジック パラメーターを使用して) データの型情報を取得し、そのポインターを通常のポインター型にキャストしてから、通常どおり使用する必要があります。

void *ジェネリックプログラミングに何らかのサポートを提供するために C でよく使用されます。たとえば、qsortC ライブラリ関数を参照してください。

代わりに、NULLポインタは何も指さないポインタです。この場合、ポインターに関する一般的な型情報は存在しますが、存在しないのは、ポイントされたデータのアドレスです。もちろん、 を持つvoid *ことは可能ですNULL

v簡単な例(として宣言されていると仮定double v;):

                         Type information present
             +----------------------+----------------------+
             |          ✔           |          ✘           |
         +---+----------------------+----------------------+
    p  c |   |                      |                      |
 v  o  o | ✔ | double * ptr = &v;   | void * ptr = &v;     |
 a  i  n |   |                      |                      |
 l  n  t +---+----------------------+----------------------+
 i  t  e |   |                      |                      |
 d  e  n | ✘ | double * ptr = NULL; | void * ptr = NULL;   |
    d  t |   |                      |                      |
         +---+----------------------+----------------------+

雑学:NULLは、少なくとも現在の標準では、0 であることが保証されています。

言語の他の領域では、void型の欠如を指定するために常に使用されます。それを戻り値として使用する (注: 今はvoid, ではなくについて話しているvoid *) ということは、関数が値を返さないことを意味し、式を void にキャストすることは、値を破棄するための凝った方法です (コンパイラにシグナルを送って、特定の値を使用していないことを意識していることを他のプログラマーに伝えます)。

于 2010-12-02T12:17:24.900 に答える
12

教えてください: 違いは何ですか:

  • ガスタンクとガスなしの状態の間
  • cookie jar と no-cookies の間
  • 用語「お金」と「空のポケット」の間

これらを思いつくと、null vs void* のディレマをつかむことができます。

于 2010-12-02T12:19:56.600 に答える
8

voidは非型です。 nullは非値です。

于 2010-12-02T12:17:55.423 に答える
3

ポインター演算に関するいくつかの違いを次に示します。

これは、void が不完全型であるという事実に由来します。

void *vp;
vp++;     // error, incomplete type
vp += 2;  // same error

void *p = 0;
p++;      // still same error

int *p = 0;
p++;      // well-formed program, but UB ($5.6/5)
于 2010-12-02T12:25:50.040 に答える
2

リンクされた記事は単に間違っています。その最初の文:

戻り値の型を持たないポインタは null ポインタと呼ばれます

あらゆる種類のアラームをトリガーしています。これは非常に混乱した文章です。

あなたはほとんど正しいです。「voidへのポインタ」は型です(「戻り型」ではありません)。関数は任意の型の値を返すことができるため、(関数の) 戻り値の型になります。

null ポインターは、その型に関係なく、作成できる有効なオブジェクトではない null オブジェクトを指しているポインターです。ヌル ポインターは、「何もない」を指すと言えます。

void へのポインターも null にすることができます。

void *nothing = 0;

は完全に有効なコードであり、このポインターは型指定されていないオブジェクトを指すことができると言っていますが、現在はそうではありません。

于 2010-12-02T12:17:49.667 に答える
1

null ポインターは 0x000000 を指します (ポインターにアクセスするには正しくありません) が、void ポインターは未指定の型 ( void *) への正しいポインターです。ただし、void ポインターは null ポインターにすることができますが、ポインターを参照解除するとエラーが発生します。

于 2010-12-02T12:16:19.327 に答える