Я понимаю, что такое указатель, но я изо всех сил пытаюсь понять, для чего они используются. Я мог бы придумать ситуации, в которых вы МОЖЕТЕ использовать указатель, но эти ситуации, о которых я могу думать, также могут быть решены по-другому без дополнительной работы. В любом случае, чего я действительно не понимаю, так это использования указателей на указатели. Например, я наткнулся на этот простой C-код:
#include <stdlib.h>
int main(int argc, char** argv)
{
...
}
Насколько я понял, это должна быть программа, которую можно вызывать из командной строки с бесконечными параметрами, и это своего рода соглашение. Какова цель char** argv? Зачем здесь использовать указатель на указатель на char? Извините, если это тривиальный вопрос, но я, кажется, действительно изо всех сил пытаюсь получить здесь общую картину.
Заранее спасибо, Спаркс
возможный дубликат Как указатель на указатели работает в C? — person Sparkas schedule 05.09.2015
argv
— это (указатель на первый элемент) массив char*
. Длина массива argc
. Применяется нормальное затухание массива к указателю. — person Sparkas schedule 05.09.2015
Использование указателей в C — person Sparkas schedule 05.09.2015
Указатель на указатель (на указатель…) полезен во всех ситуациях, когда вам требуется более одного уровня косвенности.
В конкретном случае
char** args
у вас есть массив строк, которые являются аргументами, каждая строка в C являетсяchar*
, поэтому в основном у вас есть что-то вродеЧто в этом странного? Подумайте о том, что
T*
определяет тип, который является указателем наT
. Теперь, еслиT == char*
, тоchar**
определяет указатель наchar*
, который, в свою очередь, является указателем наchar
.Помните, что в C и C++ указатель может представлять массив.
Я бы никогда не догадался, что char **args будет указывать на массив указателей. Я бы просто предположил, что это будет указывать на один указатель. Хотя я не понимаю, как это работает, это, по крайней мере, помогает мне понять, почему мой данный пример работает именно так, так что спасибо за ответ! — person Sparkas; 07.09.2015
Есть примеры C, где argv попеременно объявляется как массив указателей:
Синтаксис указателя на указатель:
объявляет указатель на то, что может быть первым указателем в массиве указателей. Другое распространенное использование — передача указателя на указатель на связанный список:
Спасибо за ответ! Теперь я знаю, что char **argv указывает на массив, но я бы интуитивно использовал способ char *argv[], если бы меня попросили создать массив указателей. Я просто не совсем понимаю, как массив создается или объявляется с помощью **argv. Обычно я предполагаю, что это просто указатель на одиночный указатель, но, возможно, я пойму это, когда узнаю больше об указателях. — person Sparkas; 07.09.2015
Указатели на указатели появляются в ряде ситуаций. Вероятно, наиболее распространенным является случай, когда вам нужна функция для записи аргумента указателя.
Рассмотрим следующее:
Здесь функция
foo
обновляет переменнуюvar
, определенную вbar
, через указательp
.Теперь давайте заменим тип
T
указателем типаQ *
:Семантика точно такая же; мы записываем новое значение в
var
. Единственное отличие состоит в том, чтоvar
имеет тип указателя, поэтому нам нужно использовать несколько уровней косвенности вfoo
.Вторая распространенная ситуация — когда у вас есть массив указателей, и вы передаете этот массив другой функции. Например:
strings
— это массив указателей наchar
; каждый элемент массива является адресом строкового литерала (или NULL). При вызовеfoo
выражение массиваstrings
преобразуется («затухает») в выражение типа «указатель на указатель наchar
«, а значением выражения является адрес первого элемента массиваstrings
1. . Так как первый элемент массива является указателем, то и адрес первого элемента является указателем на указатель.Третий случай — когда вы выделяете память для 2D-массива по частям:
<�ч> 1. За исключением случаев, когда это операнд оператора
sizeof
или унарного оператора&
, или строкового литерала, используемого для инициализации другого массива в объявлении, выражение типа «N-элементный массивT
» будет преобразуется («распад») в выражение типа «указатель наT
«, а значением выражения будет адрес первого элемента массива.Спасибо за примеры, я бы не подумал об этом, и это помогает понять использование указателей. — person Sparkas; 07.09.2015