Арифметика указателей с многомерной системой обозначений

0

Это мой первый вопрос :)

double MyArray[][6];
double* Myptr = MyArray[0];

Поэтому мне было интересно, почему, в указателе Arithmetic, я могу обозначить указатель на перемещение в одном измерении, как это,

*(Myptr + i);

но если я попытаюсь перемещаться по размерам массива с помощью цикла for, это не позволит мне

*(*(Myptr + i) + j); 

Однако это позволяет мне использовать это обозначение с самим массивом.

*(*(MyArray + i) + j);

Я хотел знать, почему это ограничение? или, может быть, я неправильно его записываю.

Теги:
arrays
multidimensional-array
pointer-arithmetic

4 ответа

0
Лучший ответ

Myptr - это указатель на double, поэтому *(Myptr + i) является двойным, и, хотя вы можете добавить j к этому, вы не можете разыгрывать результат.

Если бы вы объявили Myptr следующим образом:

double (*Myptr)[6] = MyArray;

то Myptr будет указателем на массив из 6 double s. Следовательно, *(Myptr + i) будет double[6], и выражение будет работать.

То, что вы можете индексировать массивы с использованием этого синтаксиса, к сожалению, удивительно для людей, которые видят его в первый раз и никогда не учили о разложении указателя. Самое забавное в массивах на C и C++ заключается в том, что они распадаются на указатели практически во всех обстоятельствах. Это означает, что почти всегда, когда вы используете массив (существуют исключения), массив неявно преобразуется в указатель на его первый элемент, а остальное выполняется с помощью арифметики указателя.

Например, это так, когда вы пишете MyArray[i]. Стандарт определяет MyArray[i] как означающий *(MyArray + i) (стандарт использует больше скобок, но это то, к чему это сводится), что имеет смысл, когда вы понимаете, что MyArray распадается на указатель, i добавляется к этому указатель, и полученный указатель разыменовывается. Это также объясняет, почему i[MyArray] одинаково действителен (если в плохом стиле).

В контексте многомерных массивов важно понимать, что многомерный массив является всего лишь массивом массивов. MyArray - это, в вашем случае, массив массивов двойников. MyArray[0] является массивом двойников. При расчете указателя MyArray распадается на указатель на массив двойников, а когда вы разыскиваете этот указатель и работаете с массивом, который он указывает, то этот массив также распадается на указатель (в два раза) при работе с ним. Он распадается весь путь вниз.

  • 0
    спасибо и спасибо всем :)
0

MyArray имеет тип double[][6] а MyPointer имеет тип double*.

Теперь массивы и указатели разные, но это не важно в этом контексте. Обе переменные имеют типы массивов/указателей в своих типах, но My Array имеет два (считать их: [] и [6]), а MyPointer имеет только один (считайте: *). Вот почему вы можете применять разыменование (что оператор *) для MyArray дважды, а MyPointer - только один раз.

Теперь, если вы хотите иметь указатель, который можно использовать почти так же, как вы используете MyArray, это возможно, но его тип не будет double** (поскольку массивы и указатели разные). Вы пишете это так:

double (*MyPointer2)[6] = MyArray;

У этого есть два типа массива/указателя в его типе, чтобы вы могли применить к нему разыменование дважды.

0

В этом случае MyPtr имеет только один размер, потому что он был назначен определенному "массиву" в MyArray.

  • 0
    о ... Я вижу, что указатель фактически сможет перемещаться по 2-D массиву, но точно так же, как 1-D. Это означает, что * (Myptr + I); Могу ли я покрыть весь массив?
  • 0
    Неважно, я не учел, что MyPtr - двойной указатель. Смотрите другие ответы. Но скорее всего да на ваш комментарий.
-2

Потому что Myptr является double*. Указатель на двойной. Он не знает размеры массива.

  • 0
    Можете ли вы сделать предложение, как я могу сделать так, чтобы мой указатель знал размеры?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню