45

所以我正在处理一些面试问题,我遇到了一个关于 void 和 null pointers的问题,它声称:

没有返回类型的指针称为空指针。它可以是任何类型的数据类型。

这让我彻底困惑!根据这个问题,似乎 void 和 null 可以互换使用,我不认为这是正确的。我假设 void 是一个返回类型,而 null 是一个值。但我只是一个代码新手,我不确定我是对的。

请就什么是空指针和空指针表达您的看法。我不是在寻找无效和无效之间的区别。

4

9 回答 9

53

这两个概念是正交的:

  1. void 指针 ( void *) 是指向某个内存位置的原始指针。
  2. 根据定义,空指针是不指向任何东西的特殊指针。它可以是指向任何类型、void 或其他类型的指针。

void 指针可以为空,也可以不为空:

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

非空指针也可以为空或不为空:

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

只是简单地忘记那个答案。来自您的链接的报价:

“没有返回类型的指针称为空指针。”

这是非常明显的错误。指针的返回类型?真的吗?这是一个糟糕的来源......

void*是通用指针类型,因为任何指针类型(指向 const 和/或 volatile 的指针除外)都可以隐式转换为void*. 换句话说,您可以将任何指针分配给类型为 的变量void*。空指针是指针0

于 2010-12-02T12:15:54.693 回答
24

类型通常void意味着没有给出类型信息。

您应该始终牢记,指针传达两条信息:指向数据的类型( int, double, ...),它指定如何解释它,以及它指向的数据的地址,它指定您在哪里可以得到指向数据的实际值。

类型信息在指针的类型中(, , ...),而数据的地址是指针变量中包含的实际值。double*int*

因此,void指针 ( void *) 是不指定任何类型信息的指针。它会告诉您数据在哪里,但不会告诉您如何解释它。你知道那个地址有东西,但你不知道它是一个int、一个double还是一组飞牛。要实际使用此类数据,您必须以其他方式(例如使用其他魔术参数)获取有关它的类型信息,将该指针转换为常规指针类型,然后照常使用它。

void *在 C 中经常用于为泛型编程提供某种支持;参见例如qsortC 库函数。

NULL相反,指针是不指向任何内容的指针。在这种情况下,通常存在有关指针的类型信息,但缺少的是指向数据的地址。当然,也可以有一个void *that is 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 |   |                      |                      |
         +---+----------------------+----------------------+

Trivia :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

链接的文章是完全错误的。它的第一句话:

没有返回类型的指针称为空指针

正在为我触发各种警报。这是一篇非常混乱的文章。

你几乎是正确的。“指向 void 的指针”是一种类型(不是“返回类型”)。任何类型的值都可以由函数返回,因此是(函数的)返回类型。

空指针是一个指针,无论其类型如何,都指向空对象,该对象不是任何可以创建的有效对象。可以说空指针指向“无”。

指向 void 的指针也可以为空;

void *nothing = 0;

是完全有效的代码,只是说这个指针能够指向一个无类型的对象,但现在它不是。

于 2010-12-02T12:17:49.667 回答
2

Avoid *ptr是可用于指向任何类型数据的指针。也许int,,,。float_ double它没有返回类型,最初是使用指针类型(具有十六进制值)创建的指针,我们可以将此指针分配给任何类型的数据。

空指针是地址为 NULL 的指针,该指针被赋予 NULL 值,因此它不能用于访问其地址在创建时可能包含的其他数据。我认为如果目前不使用指针 NULL,则将其分配为一种很好的编程技术。

于 2016-09-24T14:41:43.647 回答
1

空指针指向 0x000000(访问指针不正确),而空指针是指向未指定类型的正确指针(void *)。但是,void 指针可以是空指针,但是取消引用指针会产生错误。

于 2010-12-02T12:16:19.327 回答