Каково различие между пустотой* и пусто **?

Это - специальное свойство, которые освобождают*, может также быть присвоен указатель на указатель и брошен, и исходное значение получено.

Я считал эту строку где-нибудь. Это означает void* и void** то же? Каково различие?

Править

void* может содержать любой указатель. Затем, что void** необходимый для?

11
задан Peter Mortensen 12 September 2010 в 11:20
поделиться

6 ответов

Один указывает на черную дыру.

Другой указывает на то, что указывает на черную дыру.


На самом деле это не одно и то же, но указатели можно преобразовать в void * . Вы можете преобразовать int * в void * , потому что это указатель. void ** по-прежнему указатель (он просто указывает на указатель), и, поскольку это указатель, вы можете преобразовать его в void * . В этом есть какой-то смысл?

Тем не менее, я не думаю, что когда-либо использовал void ** , но если вам нужен массив из void * s, то тип будет void ** . (В C) void * часто используется для хранения указателя на некоторые пользовательские данные, но вы не будете знать заранее, какого типа будут эти данные. Если у вас есть их массив, тогда void ** .

Так как у вас это тоже помечено как C ++: Предыдущий случай на самом деле не применим: вы можете использовать std :: vector . На самом деле, void * может быть сомнительным - абстрактная база могла бы лучше соответствовать вашим целям. void * используется в основном в C.

53
ответ дан 3 December 2019 в 00:44
поделиться

void** - это указатель на void*. void* может быть преобразован в любой тип указателя (включая void**). Поэтому вы можете сделать:

char* -> void*
void* -> void**
void** -> void*
void* -> char*

Вы можете не сделать:

char* -> void**
void** -> char*

поэтому они не одно и то же.

6
ответ дан 3 December 2019 в 00:44
поделиться

A void * может содержать любой указатель. Поскольку реальных объектов void не существует, 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
}
3
ответ дан 3 December 2019 в 00:44
поделиться

void * - это указатель (или указатель на начало массива неизвестного типа). void * - указатель на адрес указателя (или указатель на начало 2D-массива).

Кроме того, если вы пишете на C (а не на C ++), тогда нет параметра по ссылке, только по значению или по указателю.

Например.

// 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;)
и позволяет вызывающему коду быть затронутым изменением,
тогда вам нужно передать указатель по ссылке, передать ptr в (void * &) и использовать ptr внутри функции
или передайте указатель на указатель (void **) и передайте & ptr и используйте * ptr внутри функции.

0
ответ дан 3 December 2019 в 00:44
поделиться

Одно из основных отличий заключается в том, что правило, которое вы выделили жирным шрифтом, не применяется к void**.

1
ответ дан 3 December 2019 в 00:44
поделиться

Если вы хотите хранить какой-то указатель или что-то еще, вы, вероятно, будете использовать 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);
}
2
ответ дан 3 December 2019 в 00:44
поделиться