Указатель на указатель с argv
Основываясь на моем понимании указателя на указатель на массив символов,
% ./pointer one two
argv
+----+ +----+
| . | ---> | . | ---> "./pointer\0"
+----+ +----+
| . | ---> "one\0"
+----+
| . | ---> "two\0"
+----+
Из кода:
int main(int argc, char **argv) {
printf("Value of argv[1]: %s", argv[1]);
}
Мой вопрос: почему argv [1] приемлемо? Почему это не что-то вроде (* argv) [1]?
Мое понимание:
- Возьмите argv, разыщите его.
- Он должен вернуть адрес массива указателей в символы.
- Использование арифметики указателей для доступа к элементам массива.
Ответы
Ответ 1
Более удобно думать о []
как о операторах для указателей, а не массивов; он использовался с обоими, но поскольку распад массивов на указатели массива индексирования все еще имеет смысл, если он посмотрел на этот путь. По сути, это смещает, затем разыгрывает указатель.
Итак, с argv[1]
то, что вы действительно получили, это *(argv + 1)
, выраженное более удобным синтаксисом. Это дает вам второй char *
в блоке памяти, на который указывает argv
, так как char *
- это тип argv
указывает на, а [1]
смещает argv
на sizeof(char *)
байты, затем разыгрывает результат.
(*argv)[1]
будет сначала искать argv
с *
, чтобы получить первый указатель на char
, а затем смещать его на 1 * sizeof(char)
байты, а затем разыгрывать, чтобы получить char
. Это дает второй символ в первой строке группы строк, на которые указывает argv
, что, очевидно, не совпадает с argv[1]
.
Итак, подумайте об индексированной переменной массива как о указателе, на котором работает оператор "смещение, а затем разыменовать указатель".
Ответ 2
Поскольку argv
является указателем на указатель на char
, из этого следует, что argv[1]
является указателем на char
. Формат printf()
%s
ожидает указатель на аргумент char и печатает массив символов с нулевым завершающим символом, на который указывает аргумент. Поскольку argv[1]
не является нулевым указателем, нет проблем.
(*argv)[1]
также действителен C, но (*argv)
эквивалентен argv[0]
и является указателем на char
, поэтому (*argv)[1]
является вторым символом argv[0]
, который есть /
в вашем примере.
Ответ 3
Индексирование указателя как массива неявно разыгрывает его. p[0]
- *p
, p[1]
- *(p + 1)
и т.д.