В чем разница между void* и void**?
Это специальное свойство, которому void* также может быть назначен указатель на указатель и отброшен назад, а исходное значение получено.
Я где-то читал эту строку. Значит ли это void* и void** такие же?
В чем разница?
редактировать
void* может содержать любой указатель. Тогда что такое void** нужны?
6 ответов
один указывает на черную дыру.
другой указывает на вещь, указывающую на черную дыру.
они на самом деле не одно и то же, но указатели могут быть преобразованы в void *. Вы можете конвертировать int * до void * потому что, ну, это указатель. void ** is еще указатель (он просто указывает на указатель), и так как это указатель, вы можете преобразовать его в void *. В этом есть смысл?
тем не менее, я не думаю Я когда-либо использовал void **, но если вам нужен массив void *s, тогда тип будет void **. (In C)void * часто используется для удержания указателя на некоторые пользовательские данные, но вы не будете знать заранее, какой тип этих данных будет. Если у вас был массив из них, то void **.
так как у вас также есть это помечено как C++: предыдущий случай на самом деле не применяется: вы можете использовать std::vector<void *>. Действительно,void * может быть сомнительным-абстрактная база может соответствовать вашим целям лучше. void * полезен в основном в C.
пустота* * - указатель на пустоту*. Void* может быть преобразован туда и обратно в любой тип указателя (включая void**). Так что вы можете сделать:
char* -> void*
void* -> void**
void** -> void*
void* -> char*
Вы можете не do:
char* -> void**
void** -> char*
таким образом, они не то же самое.
A void * может содержать любой указатель. Так как нет фактических void объекты, a void * всегда является указателем на какой-либо другой тип.
A void ** является указателем на указатель на void или адрес void *, т. е. адрес указателя на Void. Это реальный тип и не имеет никаких магических свойств.
но поскольку void * может содержать любой указатель, он также может содержать, например,void **.
void **f(int x) {
static void *y;
static int *iy;
y = &x;
iy = &x;
// return &iy; // not ok
return &y; // ok
}
Если вы хотите сохранить какой-то указатель или что-то еще, вы, вероятно, будете использовать void*.
однако, если вы хотите написать функцию, которая может инициализировать этот волшебный указатель, то вам нужно передать этот аргумент этой функции как void**
void fun1();
int fun2(int);
double fun3(long);
bool fun4(int, long, double);
int rand(void** pp)
{
switch(time()%4)
{
case 0: *pp = fun1; return 0;
case 1: *pp = fun2; return 1;
case 2: *pp = fun3; return 2;
case 3: *pp = fun4; return 3;
}
}
int main()
{
void* pointer;
int funId;
funId = rand(&pointer);
setCallback(pointer, funId);
}
одно из основных различий заключается в том, что правило, которое вы указываете жирным шрифтом, не применяется к void**.
void* - указатель (или указатель на начало массива неизвестного типа). void* - указатель на адрес указателя (или указатель на начало 2D-массива).
кроме того, если вы пишете на C (а не на C++), то нет параметра by-reference, только по значению или по указателю.
Э. Г.
// By value C and C++
void MyFunction(int a)
{
}
// By pointer C and C++
void MyFunction(int* a)
{
}
// By reference C++ only
void MyFunction(int& a)
{
}
Если вы хотите функцию, которая изменяет адрес указателя (например, void* ptr;)
и позволяет вызывающему коду by affected by перемена,
затем вам нужно передать указатель по ссылке pass ptr to (void*&) и использовать ptr внутри функции
или передайте указатель на указатель (void**) и передайте &ptr и используйте *ptr внутри функции.