Вы можете добиться того, что вы хотите таким образом:
void foo(int *array) { }
int column_size = 5;
int main() {
int array[column_size][2];
foo(&array[0][0]);
return 0;
}
хотя вы должны позаботиться о том, как вы читаете элементы внутри функции foo
. Для того, чтобы прочитать array[c][r]
элемент, который вы должны сделать:
int element = *(array + c * column_size + r);
Общая функция прибудете элемент:
int get_element(int *array, int row, int column, int column_size) {
int element = *(array + row * column_size + column);
return element;
}
Итак, если вы, скажем, в 2D массив как INT array[M][N]
и вы хотите получить элемент array[i][j]
, который вы просто вызываете функцию следующим образом:
getElement(&array[0][0], i, j, N)
Почему это работает?
Причина, по которой вышеуказанная функция работает, может быть выяснена, если вы знаете, как массивы 2D сохраняются в памяти. Массивы сохраняются строка за строкой, так скажем, у вас есть следующий массив:
int a[3][3] = {{1, 2, 4}, {5, 6, 7}, {8, 9, 10}};
давайте предположим, что целое 4 байта и & а [0] [0] соответствует 0x10 адресу памяти. Затем 1 сохраняется в 0x10 адрес памяти, 2 сохраняется в 0x14, ..., 7 сохраняется в 0x24 адрес памяти, ... и 10 сохраняется в адресе памяти 0x30 (см. Следующую таблицу).
*Memory*
Memory address => Value => Pointer pointing at this memory address
0x10 => 1 => &a[0][0]
0x14 => 2 => (&a[0][0] + 1) or (&a[0][1])
0x18 => 4 => (&a[0][0] + 2) or (&a[0][2])
0x1c => 5 => (&a[0][0] + 3 * 1 + 0) or (&a[1][0])
0x20 => 6 => (&a[0][0] + 3 * 1 + 1) or (&a[1][1])
0x24 => 7 => (&a[0][0] + 3 * 1 + 1) or (&a[1][2])
0x28 => 8 => (&a[0][0] + 3 * 2 + 0) or (&a[2][0])
0x2c => 9 => (&a[0][0] + 3 * 2 + 1) or (&a[2][1])
0x30 => 10 => (&a[0][0] + 3 * 2 + 2) or (&a[2][2])
Теперь, когда у вас есть следующий указатель:
int *pt = (&a[0][0] + 2);
pt
указатель будет указывать 2 элемента после a[0][0]
. Таким образом, pt
указывает на [0] [2]. *pt
будет равна 4.
Теперь предположим, что вы хотите получить элемент a[i][j]
. Чтобы получить этот элемент , вам нужно переместить i * COLUMN_SIZE
элементов, чтобы попасть в правильную строку, где находится элемент (каждая строка содержит COLUMN_SIZE
элементов), а затем вам нужно добавить j
, чтобы попасть в нужный столбец.
Если вы хотите получить a[2][1]
(где COLUMN_SIZE = 3
), то 2 * COLUMN_SIZE = 6
+ 1
= 7
. Итак, чтобы получить элемент a[2][1]
, вы делаете *(&a[0][0] + 2 * 3 + 1)
или *(&a[0][0] + 7)
.
Для некоторых замечательных уроков по указателям, посмотрите здесь: Stanford CS Ed Library.
Но функция может ссылаться только на массив как 1D-массив (вектор), а не как 2D-массив с правильным размером. –
@ jonathan-leffler Да, я знал о коде, который вы публикуете. Но реальный вопрос касался пропущенных указателей, поэтому @functional сделал то, что я хотел. Благодарю. – Ockonal
@функциональный Отличный ответ! – Ockonal