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

Указатель на указатель с 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, разыщите его.
  • Он должен вернуть адрес массива указателей в символы.
  • Использование арифметики указателей для доступа к элементам массива.
4b9b3361

Ответ 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) и т.д.