我会去查找这个问题,但说实话我不知道从何处开始,因为我不知道它被称为什么。我见过像这样将变量传递给函数的:
myFunction((void**)&variable);
这让我非常困惑,因为所有这些都很熟悉;只是我以前从未见过它们像这样组合在一起。
这是什么意思?我是新手,所以尽量少用行话,谢谢!
我会去查找这个问题,但说实话我不知道从何处开始,因为我不知道它被称为什么。我见过像这样将变量传递给函数的:
myFunction((void**)&variable);
这让我非常困惑,因为所有这些都很熟悉;只是我以前从未见过它们像这样组合在一起。
这是什么意思?我是新手,所以尽量少用行话,谢谢!
void*
是指向任何类型的指针。 void **
是另一级间接性 - “指向指向任何类型的指针”。基本上,当您想要允许函数返回任何类型的指针时,就会传入它。
&variable
获取变量的地址。 变量应该已经是某种指针,才能使用该方法,但它可能不是 void *
- 例如,它可能是 int *
,因此获取其地址将导致一个int **
。如果该函数需要使用 void **
,则需要将其转换为该类型。
(当然,它需要实际返回正确类型的对象,否则调用代码将在后续尝试以错误方式使用它时失败。)
逐个拆开它...
myFunction接受一个指向void类型的指针指针(这基本上意味着它可以指向任何东西)。它可能声明为以下内容:
myFunction(void **something);
你传入的任何内容都必须具有该类型。因此,你需要获取指针的地址,并使用(void **)进行转换,使其成为一个void指针。这基本上是将其剥离了任何关于它所指向的内容的想法 - 否则编译器可能会抱怨。
这意味着&variable是一个指针的地址(&执行此操作)- 因此variable是一个指针。指向什么?谁知道!
以下是更完整的代码片段,以便了解它们如何组合在一起:
#include <stdio.h>
int myInteger = 1;
int myOtherInt = 2;
int *myPointer = &myInteger;
myFunction(void **something){
*something = &myOtherInt;
}
main(){
printf("Address:%p Value:%d\n", myPointer, *myPointer);
myFunction((void**)&myPointer);
printf("Address:%p Value:%d\n", myPointer, *myPointer);
}
Address:0x601020 Value:1
Address:0x601024 Value:2
您可以看到,myFunction改变了myPointer的值 - 这是因为它被传递了指针的地址。
void
类型指针的一种方法。在Windows系统中,像CoCreateInstance()
这样的函数经常使用此方法。ISomeInterface* ifaceptr = 0;
HRESULT hr = ::CoCreateInstance(CLSID_SomeImplementation, NULL, CLSCTX_ALL,
IID_ISomeInterface, (void**)&ifaceptr);
if(SUCCEEDED(hr))
{
ifaceptr->DoSomething();
}
该代码将指向ISomeInterface
的指针转换为指向void
指针,以便CoCreateInstance()
可以将ifaceptr
设置为有效值。
由于它是指向void
指针的指针,所以根据接口ID(例如IID_ISomeInterface),该函数可以输出任何类型的指针。
void**
参数返回它。您可以使用IID_ISomeInterface
参数告诉它您想要的类型,您需要负责正确使用类型转换将void**
转换为可用的内容。 - Ken BloomCoCreateInstance()
会根据接口ID(例如示例中的IID_ISomeInterface
)“知道”输出指针应该是什么类型。此外,对于给定架构,所有指针大小都相同(例如,在32位系统上,所有指针都为4字节,而在64位系统上,所有指针都为8字节)。不存在void
类型,但可以有void
指针。这基本上意味着指向任何类型的指针。 - In silicovoid*
转换,您可以始终将其转换为和从void
指针转换。是否安全取决于不同的情况。例如,将Foo*
强制转换为void*
,然后再转换回Foo*
始终是安全的,但是将Bar*
强制转换为void*
,然后再转换回Foo*
绝对不安全(假设Foo
和Bar
不相关)。这就是为什么我们通过标识符告诉CoCreateInstance()
实际上void
指针是哪种类型的原因。 - In silico它是一个指向未指定类型变量的指针的指针。所有指针的大小相同,所以void*
仅表示“指向某个东西的指针,但我不知道它是什么”。一个void**
也可以是一个未指定类型的二维数组。
这将把&variable
强制转换为void**
(即指向指向void
的指针)。
例如,如果你有以下内容:
void myFunction(void** arg);
int* variable;
这里使用一元运算符 &
取得变量 variable
的地址,并将其传递给 myFunction()
。