だから私はいくつかのインタビューの質問をしていて、私は偶然に出くわしました voidとnullポインターについての1つ 、それは主張します:
戻り値型のないポインタは、nullポインタと呼ばれます。どんな種類のデータ型でもかまいません。
これは私を完全に混乱させました!この質問によれば、nullとnullは同じ意味で使用できますが、私はそれが正しいとは思いません。 voidを戻り値の型、nullを値と想定しました。しかし、私は単なる新人であり、私が正しいかどうかはわかりません。
Nullポインターとvoidポインターが何であるかについての見解を示してください。 nullとvoidの違いを探していません。
2つの概念は直交しています。
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;
その答えを単に忘れてください。あなたのリンクからの引用:
「戻り値の型がないポインターは、nullポインターと呼ばれます。」
これはすごくプレーンです[〜#〜] wrong [〜#〜]。ポインタの戻り値の型?本当に?これは悪い情報源です...
void*
はユニバーサルポインターですtypeどのポインタータイプでも(constやvolatileへのポインターを除く)、暗黙的にvoid*
に変換されます。つまり、void*
型の変数に任意のポインターを割り当てることができます。 nullポインターはポインターvalue 0
一般にvoid
タイプは、タイプ情報が提供されないことを意味します。
ポインタは2つの情報を伝えることに常に注意してください。ポイントされたデータのtype(int
、double
、.. 。)、それをどのように解釈するかを指定し、それが指すデータのaddressを指定し、whereを取得できます指し示されたデータの実際の値。
タイプ情報は、ポインタのタイプ(double
*
、int
*
、...)、データのアドレスはポインタ変数に含まれる実際の値です。
したがって、void
ポインター(void *
)は、型情報を指定しないポインターです。データの場所はわかりますが、データの解釈方法はわかりません。あなたはそのアドレスに何かがあることを知っていますが、それがint
、double
、または空飛ぶ牛の配列であるかどうかはわかりません。そのようなデータを実際に使用するには、他の方法で(たとえば、他の魔法のパラメーターを使用して)データに関する型情報を取得し、そのポインターを通常のポインター型にキャストして、それを通常どおりに使用する必要があります。
void *
は、一般的なプログラミングに何らかのサポートを提供するためにCでよく使用されます。たとえば qsort
Cライブラリ関数を参照してください。
代わりに、NULL
ポインターは、何も指さないポインターです。この場合、一般にポインターに関するタイプ情報は存在しますが、欠落しているのは指定されたデータのアドレスです。もちろん、NULL
であるvoid *
を持つことは可能です。
簡単な例(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にキャストすることは、空想的な破棄方法です値(特定の値を使用していないことを意識していることをコンパイラや他のプログラマに通知しています)。
教えてください:違いは何ですか:
これらを思いついた場合は、nullとvoid *のディレマを把握できます。
voidはタイプではありません。 nullは値ではありません。
ポインター演算に関するいくつかの違いは次のとおりです。
それは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)
リンクされた記事は単に間違っています。その最初の文:
戻り値型のないポインタは、nullポインタと呼ばれます
私のためにあらゆる種類のアラームを引き起こしています。これは非常に混乱した文章です。
あなたはほぼ正しいです。 「ボイドへのポインタ」は型です(「戻り型」ではありません)。関数はどのタイプの値も返すことができるため、(関数の)戻り値の型になります。
NULLポインターは、そのタイプに関係なく、作成できる有効なオブジェクトではないNULLオブジェクトを指しているポインターです。 nullポインタは「何も」を指していないと言えます。
Voidへのポインタもnullにすることができます。
void *nothing = 0;
完全に有効なコードであり、このポインターは型なしオブジェクトを指すことができるとだけ言っていますが、今のところそうではありません。
nullポインターは0x000000(ポインターへのアクセスは正しくありません)を指していますが、voidポインターは、指定されていない型への正しいポインターです(void *
)。ただし、voidポインターはnullポインターにすることができますが、ポインターを参照しないとエラーが発生します。
A void *ptr
は、任意のタイプのデータを指すために使用できるポインターです。多分int
、float
、double
かもしれません。戻り値の型はなく、最初はポインターが(16進値を持つ)ポインター型で作成されます。このポインターを任意の型のデータに割り当てることができます。
NULLポインターはアドレスとしてNULL値を持つポインターですが、ポインターはNULL値が割り当てられているため、作成中にそのアドレスに含まれる他のデータにアクセスすることはできません。現時点で使用されていない場合は、ポインターNULLを割り当てるのが良いプログラミング手法だと思います。