Не передаётся двумерный массив в C
int detForDIM3(int** matrix) { // function for calculating determinant of matrix 3 by 3)
//
}
Plane* makePlane(Point *x, Point *y, Point *z) {
int matrix[DIM][DIM];
***
plane->vals[colFor1] = detForDIM3(&matrix);
Я хочу передать в функцию матрицу 3 на 3 ( DIM*DIM ). Создаю её в программе, передаю, но получает detForDIM3 только указатель на ничто. Как это исправить Пробовал передавать: int matrix[][DIM] - не помогло int **matrix - не помогло
detForDIM3(matrix) - не помогло detForDIM3(&matrix) - не помогло
Вот, собственно скриншот большего куска кода с тем, что передаётся:
При matrix[][DIM] передаётся только первая строка
Ответы (3 шт):
// matrixp - указатель на матрицу
void f(int (*matrixp)[DIM][DIM]){
...
(*matrixp)[i][j] - значения
}
void g(void) {
int matrix[DIM][DIM];
f(&matrix);
}
Жаль, что у вас С, а не С++... Там проще.
Смотрите, когда компилятор видит матрицу типа int a[M][N], то он генерирует обращение к a[i][j] как к *((int*)a + i*M + j) - и ему обязательно нужно знать это значение M. Поэтому передавать нужно как минимум как
.... func(int a[][M],...)
где M - значение времени компиляции. Если у вас все матрицы с одинаковым количеством столбцов - можно так.
Но если вы не привязаны к конкретно матрице, например, какой-то библиотекой - то проще реализовать матрицу именно как int** и передавать как указатель. Для этого ее надо один раз создать - типа,
int ** a = malloc(N*sizeof(int*));
for(int i = 0; i < N; ++i)
a[i] = malloc(M*sizeof(int));
и тогда работать с a, как с матрицей. Просто теперь компилятор будет выполнять обращение иначе - как
*(*(a+i)+j)
и ему уже не нужно знать размерность матрицы. Такую матрицу вы просто передаете как int** (сопровождая размерами при необходимости для себя, а не для компилятора).
Примерно так.
Ну, а тут выбирайте, что для вашей ситуации подходит больше...
#define DIM 3
inline int getValue(int* martix, int x, int y) {
return martix[DIM * y + x];
}
int main() {
int matrix[DIM][DIM];
int cell21 = getValue((int*)matrix, 2, 1);
}
В памяти ваш массив (при обнулении его значений) выглядит так:
00 00 00 00 00 00 00 00 00
При выделении памяти в стэке для стэка эти две строчки эквивалентны:
int a[3][3];
int a[9];
Поэтому нужно передавать как int*. Если размер массива динамический, нужно передавать и его кол-во строк и/или кол-во столбцов. Чтобы получить значение массива ячейки используется вот такая формула:
a[columnCount * y + x];
Взгляните на рисунок с байтами, на эту формулу и попытайтесь найти значение matrix[2][1], если вы хотите точно понять, как это работает.
Вот формула чтоб найти a[z][y][x] при a[sizeZ][sizeY][sizeX]:
int* _a = (int*)a;
_a[(sizeX * sizeY) * z + sizeX * y + x]; // пропускаем "таблицу" ((sizeX * sizeY) * z)
// затем пропускаем строку (sizeX * y)
// затем добавляем смещение (x)
Заметьте, на первую размерность всем всегда всё равно)