0

Что такое ** в C++?

9

Описание проблемы

Я столкнулся с некоторым кодом, а также с ошибками, которые сгенерировал мой компилятор, содержащими токен <code>**</code> перед переменной (например, имя_переменной unreferenced - или что-то подобное, точно не помню). Я довольно уверен, что это связано с указателями. Если бы мне пришлось догадываться, то это выглядит так, будто компилятор пытается разыменовать указатель дважды. Токен <code>**</code> довольно сложно найти в интернете. Можете ли вы указать на хороший сайт или документацию, или кто-то мог бы объяснить это здесь?

Спасибо.

Также, если можно, добавлю: в каких ситуациях полезно иметь указатель на указатель? Разве не следует использовать оригинальный указатель вместо создания еще одного указателя на оригинальный указатель?

5 ответ(ов)

0

В языке C ** действительно представляет собой не только указатель на указатель (как в объявлении), но и разыменование разыменования (в выражении).

Этот подход часто используется в C, так как язык не поддерживает нотацию & для ссылок. Например, он полезен для обновления возвращаемого значения, которое является указателем:

int alloc_foo(struct foo **foo_ret)
{
    *foo_ret = malloc(sizeof(struct foo));
    return 1; /* указывает на успешное выполнение; возвращаемое значение в foo_ret */
}

В этом примере foo_ret является указателем на указатель на структуру foo. Разыменование *foo_ret позволяет выделить память для нового объекта типа struct foo и установить адрес этого объекта в память, на которую указывает foo_ret. Это способ, позволяющий функции изменять значение foo_ret в вызывающем коде.

0

Вы можете узнать сигнатуру функции main() следующим образом:

int main(int argc, char* argv[])

Следующий вариант является эквивалентным:

int main(int argc, char** argv)

В этом случае, argv представляет собой указатель на массив указателей на char.

В языке C оператор индексации [] является просто другим способом выполнения арифметики указателей. Например,

foo[i]

выдает такой же код, как и

*(foo + i)

Это означает, что использование [] в C — это просто более удобная форма записи работы с указателями.

0

Это не токен **. Это просто токен *, за которым следует другой токен *. В вашем случае у вас есть указатель на указатель, и он разыменовывается дважды, чтобы получить то, на что действительно указывает.

0

** — это указатель на указатель.

Он может использоваться для представления матрицы (массива массивов) или массива строк (массива типа char), и так далее.

0

Это двойная разыменовывающая операция.

В приведённом вами коде мы имеем три переменные:

  1. int i = 3; — обычная переменная типа int, которая хранит значение 3.
  2. int* ptr_to_i = &i; — указатель ptr_to_i, который указывает на адрес переменной i.
  3. int** ptr_to_ptr_to_i = &ptr_to_i; — указатель на указатель ptr_to_ptr_to_i, который указывает на адрес указателя ptr_to_i.

Когда вы выполняете std::cout << **ptr_to_ptr_to_i << std::endl;, происходит следующее:

  1. *ptr_to_ptr_to_i разыменовывает первый указатель, т.е. получает значение ptr_to_i, что является адресом переменной i.
  2. Далее, второе разыменование **ptr_to_ptr_to_i получает значение по этому адресу, т.е. значение переменной i, которое равно 3.

Таким образом, код выводит на экран значение 3.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь