【问题标题】:What exactly does void * meanvoid * 到底是什么意思
【发布时间】:2014-04-03 02:43:41
【问题描述】:

我看到void * 被解释为指向未使用的内存块的指针。我还看到void * 被描述为指向任何类型的指针,或者指向任何类型的指针都可以转换为void *
据我所知,int * 表示指向类型int 的指针。所以请记住这一点,void * 的字面意思是什么?它是指向类型void 的指针吗?这似乎不对,因为我不知道 void 可能是一种类型。

【问题讨论】:

  • 在这种情况下,将void 视为通配符。

标签: c pointers void-pointers


【解决方案1】:

void * 是指向void 的指针。

C11:6.3.2.3 指针:

指向void 的指针可以转换为或从指向任何对象类型的指针转​​换。指向的指针 任何对象类型都可以转换为指向 void 并再次返回的指针;结果应 比较等于原始指针。

编译器不会让您取消引用 void* 指针,因为它不知道指向的对象的大小,但您需要在取消引用之前将 void * 类型指针转换为正确的类型。

【讨论】:

  • 确实如此。 void * 基本上是通用指针。您通常将它用作句柄,这是一种本质上混淆指针类型以防止用户做他们不应该做的事情的方法,因为C 缺少@987654328 的概念@ 和 public 用于结构,你不能在不知道它已经是什么的情况下取消引用 void *。它也可以用来让你让一个函数接受不同的类型,并让一个辅助参数告诉函数它应该如何处理它(原始泛型)。
  • 这里我会避免使用“句柄”一词,因为它过去曾用于指代 void **(特别是在经典 Mac OS 内存管理器 API 中)。
【解决方案2】:

让我们从这个例子开始:

    int a = 65;
    int *q = &a;
    void *p = q;
    char *c = p;


(来源:qiniudn.com

我们定义了一个int变量a和一个指向它的int指针q。 p 在void * 指针中。 a的起始地址是0x8400(为了简单起见)。

指针是地址,仅此而已。

无论是什么类型的指针,它们的内存大小都是一样的,它们的值都是一个地址。 所以,

printf("%p, %p", *p, *q);

将显示:

0x8400, 0x8400

类型:您如何解释日期

如图所示,内存中的数据是65000000(这是little endian)。如果我们想使用它,我们必须指定它是什么! type 就是这样做的。

printf("%d %c", *p, *q);

如果我们将它打印为整数,我们会得到65。如果我们将它们打印为 char,我们会得到 A(asciicode)。

p + 1 指向0x8401q + 1 指向0x8404

void *:通用类型

根据维基百科:

程序可以将指向任何类型数据(函数指针除外)的指针转换为指向 void 的指针并返回到原始类型而不会丢失信息,这使得这些指针对于多态函数很有用。

是的,void * 定义了一个简单的指针单元,它可以转换为任何指针,反之亦然。但是你不能取消引用它,因为它没有指定类型。

如果你想操纵字节,你应该总是使用void *

char * 不等于void *

不完全是。

C 语言标准没有明确保证不同的指针类型具有相同的大小。

您不能总是希望char * 在不同平台上具有相同的大小。

char * 转换为int * 可能会造成混淆,并且可能会出错。

【讨论】:

    【解决方案3】:

    它的意思是:一个指向某个内存的指针,但是这个指针不包含关于可能存储在那个内存中的数据的类型的任何信息。

    这就是为什么不能取消引用 void * 的原因:取消引用操作(以及获取右值,或通过左值写入)需要将内存位置中的位解释为特定类型,但我们不'不知道将内存解释为哪种类型。

    程序员有责任确保读入的数据与读出的数据类型相匹配。程序员可以通过将void * 转换为指向对象类型的指针来帮助自己。

    如果您希望有一个通用接口来处理多种可能类型的内存,而无需用户进行大量转换,这将非常有用。例如free() 采用void *,因为在执行free 操作时不需要类型信息。

    【讨论】:

      【解决方案4】:

      void * 是指向未指定类型数据的指针。因此,它不能直接使用;必须先将其转换为可用的数据类型,然后才能取消引用。

      【讨论】:

      • 感谢您澄清必须在取消引用之前强制转换。
      猜你喜欢
      • 1970-01-01
      • 2020-05-01
      • 2017-08-07
      • 2017-07-20
      • 2014-09-23
      • 2014-07-25
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多