MrYuran 16 8 мая, 2013 Опубликовано 8 мая, 2013 · Жалоба Итак, есть матрица float matrix[N][M] = {...}; есть функция, в которую передается указатель на матрицу и её размерности в виде параметров void foo(float *matrix_ptr, int n, int m); Вопрос простой: каким образом можно внутри функции обратиться к данным массива в виде temp = matrix_ptr[j]; средствами чистого си? Единственный вариант, который видится - вычислять смещения вручную. Либо жестко задавать размерность в параметрах функции. Может, есть какое-нибудь волшебное заклинание, приводящее произвольный указатель к массиву нужной размерности? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 35 8 мая, 2013 Опубликовано 8 мая, 2013 · Жалоба На эту тему есть хорошее высказывание: "В языке С нет многомерных массивов, но есть массивы из одномерных массивов". :) Ваша задача традиционно решается иным заданием исходного массива: // создаем массив массивов NxM: int i; float **matrix; matrix = (float**)malloc( N * sizeof(float*)); // создаем массив указателей на строки for( i=0; i < N; i++) matrix[i] = (float*)malloc( M * sizeof(float)); // аллокируем строки // зовем функцию: func( matrix, N, M); // заполняет матрицу NxM единичками // удаляем массив: for( i=0; i < N; i++) free( matrix[i]); // удаляем строки free( matrix); // удаляем указатель на них ..... // сама функция определена так: void func( float **matrix, int N, int M) { int i, j; for( i=0; i < N; i++) for( j=0; j < M; j++) matrix[i][j] = 1; // заполняем единичками } Заметим, что, несмотря на "вычурность" инициализации такой матрицы, она поддерживает традиционное обращение к своему элементу - matrix[j]. Кстати, этот случай как раз хорош для C++, т.к. в нем удобно создать класс для квадратных матриц, где их создание запихнуть в конструктор, а удаление в деструктор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 34 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба Заметим, что, несмотря на "вычурность" инициализации такой матрицы, она поддерживает традиционное обращение к своему элементу - matrix[j]. Кстати, этот случай как раз хорош для C++, т.к. в нем удобно создать класс для квадратных матриц, где их создание запихнуть в конструктор, а удаление в деструктор. На плюсах как раз можно тут без всяких классов обойтись и решить задачу в исходном виде: template <typename T, size_t N, size_t M> int m(T (& a)[N][M]) { printf("N: %d, M: %d\n", N, M); return a[1][1]; // к примеру, элемент с индексами 1, 1 } float matrix[5][6] = { ... }; int main() { printf("%f\n", m(matrix) ); return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба Ваша задача традиционно решается иным заданием исходного массива: Осталось сделать то же самое, но статически. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ek74 0 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба Осталось сделать то же самое, но статически. Если писать на Си и есть поддержка стандарта c99 (для GCC включаем -std=c99), то можно так #include <stdio.h> float matrix1[3][4] = { { 1.0f, 2.0f, 3.0f, 4.0f }, { 5.0f, 6.0f, 7.0f, 8.0f }, { 9.0f, 10.0f, 11.0f, 12.0f } }; float matrix2[4][2] = { { 1.0f, 2.0f }, { 3.0f, 4.0f }, { 5.0f, 6.0f }, { 7.0f, 8.0f } }; void matrix_out(int n, int m, float matrix[n][m]) { printf("Матрица[%d][%d]:\n", n, m); for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) printf("\t%f", matrix[i][j]); putchar('\n'); } } int main() { matrix_out(3, 4, matrix1); matrix_out(4, 2, matrix2); return 0; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба Если писать на Си и есть поддержка стандарта c99 (для GCC включаем -std=c99), то можно так А ведь сработало! :08: А всего-то - размерности в параметрах функции объявлены раньше, чем массив Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба А всего-то - размерности в параметрах функции объявлены раньше, чем массив Ага, и получаем грязный хак из-за зависимости от порядка следования аргументов, что не рекомендуется :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 16 13 мая, 2013 Опубликовано 13 мая, 2013 · Жалоба Ага, и получаем грязный хак из-за зависимости от порядка следования аргументов, что не рекомендуется :( Я пока что проверял результат под цыгвином в винде, а чуть позже буду под mspgcc смотреть. Посмотрю в листинге, что получится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться