Арифметика с двойным указателем

У меня есть 2D матрица

matrix[m][n];

Я знаю, что матрица — это двойной указатель с типом int**, Я хотел бы получить двойной указатель, указывающий на подматрицу исходной матрицы. Например, я хочу, чтобы подматрица запускалась для ячейки (1,1). Как я могу получить такой двойной указатель из исходной матрицы [m] [n]?

0

Решение

Матрица, определенная как двумерный массив постоянного размера:

    Int matrix [m][n];

хранится как m смежных блоков из n элементов. Поэтому вы можете технически представить это как плоскую последовательность m * n элементов в памяти. Вы можете использовать арифметику указателей, чтобы найти начало строки или найти конкретный элемент. Но вы не можете найти подматрицу int таким образом.

Двойной указатель:

    int **pmatrix;

подчиняется другой логике: это указатель на указатель и выглядит как массив из m указателей, указывающих на строки из n последовательных элементов. поэтому ваши элементы не обязательно являются последовательными. Вы можете использовать арифметику указателя и косвенность, чтобы найти начало строки или определенного элемента. Но опять же это не может адресовать подматрицу.

И матрица, и матрица pmatrix могут использоваться с одномерным или двумерным индексированием, но компилятор генерирует другой код для адресации элементов.

Для получения подматриц вы должны выполнять итерации, чтобы найти правильные элементы, используя вертикальные и горизонтальные смещения, но вы не можете себе представить, как передать указатель на подматрицу, если не копируете нужные элементы в новую матрицу размера цели

1

Другие решения

Я знаю, что матрица — это двойной указатель с типом int **.

Нет, ты не Массивы не указатели. Если вы объявили это как int matrix[m][n];то тип выражение matrix является int [m][n]; если matrix операнд sizeof или одинарный & операторы, его тип будет преобразован («распад») в int (*)[n] (указатель на nэлемент массива int).

Проблема в том, что вы не можете создавать произвольные подматрицы, просто объявив указатель правильного типа; C и C ++ не предоставляют простой способ «разрезать» массивы таким способом. Вы, конечно, можете создать указатель типа int (*)[n-1] и назначьте значение &matrix[1][1] к нему (с соответствующим приведением), но он не будет делать то, что вы хотите.

РЕДАКТИРОВАТЬ

Теперь, когда передо мной настоящая клавиатура, я могу немного подробнее остановиться на этом.

Давайте представим матрицу 3х3, объявленную следующим образом:

int m[3][3] = {{0,1,2},{3,4,5},{6,7,8}};

Мы обычно визуализируем такую ​​матрицу как

+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+

В C и C ++ 2-мерные массивы располагаются в рядные основнымы порядок1, 2, поэтому приведенная выше матрица будет представлена ​​в памяти как

   +---+
m: | 0 | m[0][0]
+---+
| 1 | m[0][1]
+---+
| 2 | m[0][2]
+---+
| 3 | m[1][0]
+---+
| 4 | m[1][1]
+---+
| 5 | m[1][2]
+---+
| 6 | m[2][0]
+---+
| 7 | m[2][1]
+---+
| 8 | m[2][2]
+---+

Итак, предположим, что вы хотите, чтобы подматрица 2×2 начиналась с m[1][1]:

+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | +---+---+
+---+ | 4 | 5 |
| 6 | +---+---+
+---+ | 7 | 8 |
+---+---+

Это соответствует следующим элементам массива:

   +---+
m: | 0 | m[0][0]
+---+
| 1 | m[0][1]
+---+
| 2 | m[0][2]
+---+
| 3 | m[1][0]
+---+

+---+
| 4 | m[1][1]
+---+
| 5 | m[1][2]
+---+

+---+
| 6 | m[2][0]
+---+

+---+
| 7 | m[2][1]
+---+
| 8 | m[2][2]
+---+

Это не смежный подмассив внутри m, так просто объявив указатель и установив его &m[1][1] не буду делать то, что вы действительно хотите. Вам нужно будет создать отдельный матричный объект и скопировать в него нужные элементы:

int subm[2][2] = {{m[1][1], m[1][2]}, {m[2][1], m[2][2]}};

Вы можете написать функцию для захвата 2×2 «среза» вашей матрицы следующим образом:

void slice2x2( int (*mat)[3], int (*submat)[2], size_t startx, size_t starty )
{
for ( size_t i = 0; i < 2; i++ )
for ( size_t j = 0; j < 2; j++ )
submat[i][j] = mat[startx + i][starty + j];
}

int main( void )
{
int matrix[3][3] = {{0,1,2},{3,4,5},{6,7,8}};
int submat[2][2];

slice2x2( matrix, submat, 1, 1 );

// do something with submat
}

  1. Предварительная публикация проекта стандарта C 2011, §6.2.5.1, №3.
  2. Предварительная публикация проекта стандарта C ++ 2014, §8.3.4, №9

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector