Разыменование имен многомерных массивов и арифметика указателей - PullRequest
4 голосов
/ 06 декабря 2011

У меня есть этот многомерный массив:

char marr[][3] = {{"abc"},{"def"}};

Теперь, если мы встретим выражение *marr по определению (ISO / IEC 9899: 1999), оно говорит (и я цитирую)

Если операнд имеет тип «указатель на тип», результат имеет тип «тип»

, и мы имеем в этом выражении, что marr распадается на указатель на его первый элемент, который вв этом случае указатель на массив, поэтому мы получаем массив типа 3 размера, когда у нас есть выражение * marr.Поэтому мой вопрос заключается в том, почему, когда мы делаем (* marr) + 1, мы добавляем 1 байт только к адресу, а не к 3, который является размером массива.

Извините за мое невежество, я не очень яркий человек, язастрять иногда на тривиальные вещи, как это.

Спасибо за ваше время.

Ответы [ 2 ]

3 голосов
/ 06 декабря 2011

Причиной увеличения (*marr) на 1 байт является то, что *marr относится к char[3], {"abc"}.Если вы еще не знаете:

*marr == marr[0] == &marr[0][0]
(*marr) + 1 == &marr[0][1]

Если бы у вас было всего char single_array[3] = {"abc"};, как далеко вы могли бы ожидать, что single_array + 1 продвинется в памяти?1 байт справа, а не 3, поскольку тип этого массива равен char, а sizeof(char) равен 1.

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

Основное отличие двух приведенных выше примеров заключается в том, что:

  • Первый разыменовывается вchar[3], а затем увеличивается, поэтому размер приращения равен sizeof(char).
  • Второй шаг увеличивает char[][3], поэтому размер приращения равен sizeof(char[3]), а затем разыменовывается.
1 голос
/ 06 декабря 2011

Добавляет один, потому что тип char (1 байт). Прямо как:

char *p = 0x00;
++p; /* is now 0x01 */

Когда вы разыменовываете char [][], оно будет использоваться как char * в выражении.

Чтобы добавить 3, сначала нужно сделать арифметику, а затем разыменовать:

*(marr+1)

Вы делали:

(*marr)+1

который разыменовывается первым.

...