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

Что такое ** на С++?

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

Спасибо.

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

4b9b3361

Ответ 1

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

Он часто используется в C, который не имеет и обозначений для ссылок, например. для обновления возвращаемого значения, которое является типом указателя:

int alloc_foo(struct foo **foo_ret)
{
    *foo_ret = malloc(sizeof(struct foo));
    return 1; /* to indicate success; return value in foo_ret */
}

Ответ 2

Вы можете распознать подпись для main():

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

Следующее эквивалентно:

int main(int argc, char** argv)

В этом случае argv является указателем на массив из char *.

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

foo[i]

выводит тот же код, что и

*(foo + i)

Ответ 3

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

Ответ 4

** указатель на указатель

Это может быть матрица (массив массивов) или массив строк (массив char) и т.д.

Ответ 5

Это двойное разыменование.

int i = 3;
int* ptr_to_i = &i;
int** ptr_to_ptr_to_i = &ptr_to_i;

std::cout << **ptr_to_ptr_to_i << std::endl;

Печать 3.

Ответ 6

Я просто хотел подчеркнуть некоторые из них для указателя на указатель. Большинство из этих затронуты другими сообщениями, но я думал, что повторение может помочь.

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

  • Поскольку массивы делятся на указатели (и указатели можно рассматривать как массивы), вы часто увидите указатель на указатель, если у вас есть:

    • Указатель на массив. Это обобщение вышеприведенного случая, поскольку "строка" (строка C-стиля, в любом случае) на самом деле представляет собой просто массив char s.

    • Массив указателей. Например, у вас может быть массив указателей на объекты, что позволяет полиморфизму или массиву указателей выбирать объекты, хранящиеся в другой коллекции.

    • Массив массивов. Опять же, массивы деградируют до указателей, так что это конкретный случай выше. Это часто используется для так называемых "зубчатых" массивов (в отличие от прямоугольных).

Ответ 8

  • int **var объявляет указатель на указатель
  • **var ссылается на содержимое указателя, который сам по себе указывает на указатель

Ответ 9

Одним из распространенных способов является то, что он позволяет функции устанавливать указатель на нуль.
Таким образом, свободный (указатель) освобождает память, выделенную для указателя, но оставляет указатель, опасно указывающий на свободную память.
Вместо этого объявите my_free (** указатель) и вызовите my_free (& pointer), чтобы my_free() мог установить указатель на null после его освобождения.

Ответ 11

Это один из приманок Си ++ Сигилс. По собственному опыту я могу поручиться быстрее и эффективнее с точки зрения чтения, используя операторы разыменования в STL-массивах и векторах. Я также использовал привычные общие методы указателей, если вам интересно.:)