Подтвердить что ты не робот

Что такое void * и какие переменные/объекты он может указывать на

В частности, может ли он указывать на int/float и т.д.? Как насчет таких объектов, как NSString и т.п.? Будем очень благодарны за любые примеры.

4b9b3361

Ответ 1

void* - такой указатель, что любой указатель может быть неявно преобразован в void*.

Например:

int* p = new int;
void* pv = p; //OK;
p = pv; //Error, the opposite conversion must be explicit in C++ (in C this is OK too)

Также обратите внимание, что указатели на const не могут быть преобразованы в void* без const_cast

например.

const int * pc = new const int(4);
void * pv = pc; //Error
const void* pcv = pc; //OK

Hth.

Ответ 2

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

Таким образом, любой указатель может быть отброшен в void *, но не наоборот, потому что кастинг (например) указатель на указатель на int указывает на его добавление - путем выполнения акта вы объявляете, что цель данные целые, поэтому, естественно, вы должны прямо сказать это. Другое дело, все, что вы делаете, говорит, что указатель int - это какой-то указатель, и это нормально.

Это, вероятно, то же самое в С++.

Ответ 3

A void * может указывать на любую подобную данным вещь в памяти, такую ​​как целочисленное значение, структуру или что-то еще.

Обратите внимание, однако, что вы не можете свободно конвертировать между void * и указателями функций. Это связано с тем, что на некоторых архитектурах код не находится в том же адресном пространстве, что и данные, и, следовательно, возможно, что адрес 0x00000000 для кода относится к другому набору бит, чем адрес 0x00000000 для данных.

Было бы возможно реализовать компилятор, чтобы void * был достаточно большим, чтобы запомнить разницу, но в целом я думаю, что это не сделано, вместо этого язык оставляет его undefined.

На типичных/основных компьютерах код и данные находятся в одном и том же адресном пространстве, а затем компиляторы обычно генерируют разумные результаты, если вы храните указатель на функцию void *, так как это может быть весьма полезно.

Ответ 4

Помимо всего остального, что уже было сказано другими пользователями, void* он обычно используется в определениях обратного вызова. Это позволяет вашему обратному сообщению получать пользовательские данные любого типа, включая ваши собственные определенные объекты/структуры, которые перед тем, как использовать его, должны быть добавлены к соответствующему типу:

void my_player_cb(int reason, void* data)
{
    Player_t* player = (Player_t*)data;

    if (reason == END_OF_FILE)
    {    
        if (player->playing)
        {
          // execute stop(), release allocated resources and 
          // start() playing the next file on the list
        }
    }
}

Ответ 5

void* может указывать на адрес в памяти, но синтаксис не имеет информации о типе. вы можете использовать его для любого типа указателя, но вы несете ответственность за то, чтобы этот тип соответствовал семантике данных.