Указатель на указатель с argv - PullRequest
23 голосов
/ 03 октября 2011

Исходя из моего понимания указателя на указатель на массив символов,

% ./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]?

Мои шаги понимания:

  1. Возьмите argv, разыщите его.
  2. Он должен вернуть адресмассива указателей на символы.
  3. Использование арифметики указателей для доступа к элементам массива.

Ответы [ 3 ]

17 голосов
/ 03 октября 2011

Удобнее думать о [] как об операторе для указателей, а не массивов;он используется с обоими, но, поскольку массивы распадаются на указатели, индексирование массивов все еще имеет смысл, если смотреть таким образом.По сути, он смещает, а затем разыменовывает указатель.

Итак, с argv[1] вы получите *(argv + 1) с более удобным синтаксисом.Это дает вам второй char * в блоке памяти, на который указывает argv, поскольку char * - это тип, на который указывает argv, и [1] смещает argv на sizeof(char *) байт, а затем разыменовывает результат.

(*argv)[1] разыменовывает argv сначала с *, чтобы получить первый указатель на char, затем смещает это на 1 * sizeof(char) байт, затем разыменовывает , чтобы получитьchar.Это дает второй символ в первой строке группы строк, на который указывает argv, что, очевидно, не то же самое, что argv[1].

Так что рассматривайте переменную индексированного массива как указатель, являющийсяуправляется оператором «смещение, а затем разыменование указателя».

12 голосов
/ 03 октября 2011

Поскольку argv является указателем на указатель на char, из этого следует, что argv[1] является указателем на char. Формат printf() %s ожидает указатель на аргумент char и печатает массив символов с нулевым символом в конце, на который указывает аргумент. Поскольку argv[1] не является нулевым указателем, проблем нет.

(*argv)[1] также является допустимым C, но (*argv) эквивалентно argv[0] и является указателем на char, поэтому (*argv)[1] является вторым символом argv[0], который в вашем * / пример.

5 голосов
/ 03 октября 2011

Индексирование указателя как массива неявно разыменовывает его.p[0] равно *p, p[1] равно *(p + 1) и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...