void* 和 void** 的心智模型?
Posted
技术标签:
【中文标题】void* 和 void** 的心智模型?【英文标题】:Mental model for void* and void**? 【发布时间】:2011-08-01 07:26:17 【问题描述】:注意:我是一名经验丰富的 C++ 程序员,所以我不需要任何指针基础知识。只是我从未与void**
合作过,并且很难将我的心智模型调整为void*
与void**
。我希望有人能很好地解释这一点,以便我更容易记住语义。
考虑以下代码:(使用例如 VC++ 2005 编译)
int main()
int obj = 42;
void* ptr_to_obj = &obj;
void* addr_of_ptr_to_obj = &ptr_to_obj;
void** ptr_to_ptr_to_obj = &ptr_to_obj;
void* another_addr = ptr_to_ptr_to_obj[0];
// another_addr+1; // not allowed : 'void*' unknown size
ptr_to_ptr_to_obj+1; // allowed
【问题讨论】:
您的代码使用 gcc 4.5.2 编译得很好,即使是another_addr+1;
部分。您能否添加您收到的错误消息?
@Philip:我最近偶然发现有一个 GCC 扩展允许对 void* 进行算术运算。这就是为什么您不会收到 GCC 错误的原因。错误信息已经在评论中:'void*' unknown size
感谢您的澄清。伙计,我讨厌那些 GNU 的人...
【参考方案1】:
void*
是指向某物的指针,但你不知道是什么。因为你不知道它是什么,你不知道它占用了多少空间,所以你不能增加指针。
void**
是指向void*
的指针,所以它是指向指针的指针。我们知道空间指针占用了多少空间,因此我们可以递增 void**
指针以指向下一个指针。
【讨论】:
void* 是指向某物的指针,并且您通常确切地知道该物是什么(例如,int 的链接列表,由 void* 引用),或者您不知道不关心(例如从 void* 到 void* 的 memcpy 副本)。 可能是迄今为止最好的解释之一。 啊..简直太棒了:) 【参考方案2】:void*
指向编译器未知类型的对象。
void**
指向一个存储void*
的变量。
【讨论】:
【参考方案3】:void *
可以指向任何东西(函数除外)。所以它甚至可以指向指针,所以它甚至可以指向其他void *
对象。
void **
是指向void *
的指针,因此它只能用于指向void *
对象。
【讨论】:
【参考方案4】:void
具有误导性,因为它听起来像 null
。但是,最好将void
视为未指定的类型。所以void*
是未指定类型的指针,void**
是指向未指定类型的指针。
【讨论】:
“但是,最好将 void 视为未指定的类型。”在void*
的上下文中很好的解释,但应该明确限定该上下文,因为这对于返回类型、参数列表等是完全错误的。【参考方案5】:
void
是一个没有对象的类型。
void *
是传统的标量类型。
void **
也是一种传统的标量类型,恰好指向void *
。
void *
可以用来指向任何东西,但我更喜欢只将它用于未初始化的存储。将void *
指向实际对象通常有更好的选择。
【讨论】:
在 C 中,void *
通常是实现“通用”函数的唯一实用方法。
@Oli:是的,我想我不确定这里的语言环境。
这是一种奇怪的心智模型以上是关于void* 和 void** 的心智模型?的主要内容,如果未能解决你的问题,请参考以下文章
ChatGPT背后模型被证实具有人类心智!斯坦福新研究炸了,知名学者:“这一天终于来了”...