我正在浏览一些面试题,其中有一个关于空指针和空类型指针的问题 (点击这里查看),它声称:
没有返回类型的指针称为空指针。它可以是任何类型的数据。
这让我感到非常困惑!根据这个问题,似乎可以随意使用 void 和 null ,但我不认为这是正确的。 我认为 void 是一种返回类型,null 是一种值。但我只是一个新手程序员,不能确认自己的理解是否正确。
请您解释一下空指针和空类型指针分别指什么。我不是在寻找区别 between null and void。
我正在浏览一些面试题,其中有一个关于空指针和空类型指针的问题 (点击这里查看),它声称:
没有返回类型的指针称为空指针。它可以是任何类型的数据。
这让我感到非常困惑!根据这个问题,似乎可以随意使用 void 和 null ,但我不认为这是正确的。 我认为 void 是一种返回类型,null 是一种值。但我只是一个新手程序员,不能确认自己的理解是否正确。
请您解释一下空指针和空类型指针分别指什么。我不是在寻找区别 between null and void。
这两个概念是正交的:
void *
)是指向某个内存位置的原始指针。一个void指针可以是null或非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 或非 null。Foo *f = nullptr;
Foo *g = new Foo;
void *
的意思是“指向内存的指针;我不知道那里存储了什么数据”。任何“普通”的指针(例如 int *
、char *
、MyStruct *
)都可以隐式转换为 void *
类型;它代表着原始的“一小块内存”。 - Chowlett请忘记那个答案吧。来自您链接中的一句话:
"没有返回类型的指针称为空指针。"
这是非常错误的。一个指针的返回类型?真的吗?这是一个糟糕的来源...
void*
是通用指针类型,因为任何指针类型(除了指向const和/或volatile的指针)都可以隐式转换为void*
。换句话说,您可以将任何指针分配给类型为void*
的变量。空指针是指针值0。
0
代表空指针。当需要将0
视为指针并根据实现生成正确的底层表示时,编译器会生成适当的代码。 - Matthieu M.void
类型通常意味着没有给出任何类型信息。
您应该始终记住,指针传递两个信息:所指数据的类型(int
、double
等),它指定了如何解释它,以及指向数据的地址,它指定了您可以获取指向数据实际值的位置。
类型信息在指针的类型中(double
*
、int
*
等),而数据的地址是指针变量中包含的实际值。
因此,void
指针(void *
)是一个不指定任何类型信息的指针。它告诉您数据在哪里,但不告诉您如何解释它。您知道在那个地址有某些东西,但您不知道它是int
、double
还是一组飞牛。要实际使用这样的数据,必须以其他方式获取其类型信息(例如使用其他魔术参数),将该指针强制转换为常规指针类型,然后像平常一样使用它。
void *
通常用于C语言中提供对泛型编程的某种支持;例如,请参见C库函数qsort
。
相反,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 vs void* 的困境。
void 是一种非类型。
null 是一种非值。
void *ptr
是一个指针,可以用来指向任何类型的数据。它可以是 int
、float
或者 double
等等。它没有初始的指针类型,只有指针类型的十六进制值,我们可以将这个指针赋值给任何类型的数据。
而空指针则是具有 NULL 值地址的指针,指针被赋予 NULL 值地址以防止在创建时使用指针访问其他可能包含其地址的数据。我认为在目前未使用指针时将其赋值为 NULL 是一种良好的编程技巧。
void *nothing = 0;
void*
参数。如果您熟悉Java或C#,它大致相当于接受Object
。 - Pedro d'Aquino以下是指针算术运算的一些差异:
这源于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)
空指针指向0x000000(这是不正确的访问指针),而void指针是指向未指定类型(void *
)的正确指针。然而,void指针可以是空指针,但是解除引用指针将生成错误。
NULL
是任何指针的有效值,但在指针值为 NULL 的情况下并没有对象。此外,根据你的逻辑,void*
指针不能为 NULL,因为它既是“正确”的又是“不正确”的。这是明显不正确的说法。 - MSalters