Как передать двумерный статический массив в функцию на Си?
Есть массив char mass[1024][1024] и функция int fun(char*) . При вставке функции fun(mass) , компилятор выдаёт предупреждение о несоответствии типов, приходиться приводить тип fun((char*)mass)<> или fun((char*)&mass)<> . Есть ли возможность для указания статического массива как аргумента? И почему типы разные?
- Вопрос задан более трёх лет назад
- 2797 просмотров
Комментировать
Решения вопроса 1
Не ИТ-специалист
Целиком массив в функцию не передаётся (если только не обернуть его в структуру), а передаётся указатель на его 0-й элемент и формальный аргумент функции должен быть указателем на тип элементов массива, передаваемого фактическим аргументом.
n-мерный массив — это 1-мерный массив (n-1)-мерных массивов и, соответственно, формальным аргументом функции должен быть указатель на (n-1)-мерный массив.
В данном случае
int fun(char (*)[1024]); int fun(char (*m)[1024])*. */>
Ответ написан более трёх лет назад
Нравится 1 1 комментарий
Данил Тунев @lada-guy Автор вопроса
Спасибо, очень логично,в выходные заценю
Ответы на вопрос 1
«I’m here to consult you» © Dogbert
Есть массив char mass[1024][1024] и функция int fun(char*)
в такую функцию можно передать fun(&mass[0][0]) .
Есть ли возможность для указания статического массива как аргумента?
В смысле массива статической размерности? Легко: int fun(char a[][1000]); . fun(mass);
Ответ написан более трёх лет назад
Данил Тунев @lada-guy Автор вопроса
Компилятор gcc не разрешает такого рода аргументы: int fun(char mass[][1000]); Только с помощью указателей передаются массивы. В общем разобрался, спасибо за ответ!
Компилятор gcc не разрешает такого рода аргументы: int fun(char mass[][1000])
О, как интересно. Данил Тунев расскажи мне, почему, а то я даже отдалённо не вижу никаких проблем?
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- C
- +1 ещё
Почему мой пин постоянно 1?
- 1 подписчик
- вчера
- 134 просмотра
Передать двумерный статический массив в функцию
То есть передать можно, используя различные ухищрения, но скорей всего функция не будет работать так, как вы предполагаете.
Есть такой универсальный подход. Это интерпретировать любой двумерный массив, как одномерный, и передавать значения размеров каждой размерности массива.
void f( int a[], size_t m, size_t n ); //. int A[3][4]; f( reinterpret_cast( A ), 3, 4 );
Вот демонстрационная программа
#include #include void f( int a[], size_t m, size_t n ) < for ( size_t i = 0; i < m; i++ ) < for ( size_t j = 0; j < n; j++ ) a[i * n + j ] = i * n + j; >> int main() < const size_t M = 3; const size_t N = 4; int a[M][N]; f( reinterpret_cast( a ), M, N ); for ( size_t i = 0; i < M; i++ ) < for ( size_t j = 0; j < N; j++ ) std::cout return 0; >
Ее вывод на консоль
0 1 2 3 4 5 6 7 8 9 10 11
Если же писать программу на C, а не на C++, то там есть массивы переменной длины, и поэтому вам было бы проще.
В C++ для этих целей лучше использовать стандартный класс std::vector
std::vector> v( 3, std::vector( 4 ) );
Что касается вашего вопроса
2)Статические 2D массивы хранятся в памяти линейно. Динамические хранятся тоже линейно или нет?
то если вы будете распределять его в памяти как двумерный массив, то естественно его элементы будут храниться линейно по строкам. Например
int ( *a )[4] = new int[3][4];
А что касается этого вопроса
3)Какую связь имеет статический 2D массив с указателями?
то любой массив в выражениях (за редким исключением) неявно преобразуется в указатель на свой первый элемент.
Отслеживать
ответ дан 6 ноя 2015 в 19:03
Vlad from Moscow Vlad from Moscow
44.8k 3 3 золотых знака 38 38 серебряных знаков 89 89 бронзовых знаков
А как сделать эту функцию универсальнее, чтобы она принимала любые A[x][y] ?
6 ноя 2015 в 19:08
@neko69 Что значит «любые»? Если любые двумерные массивы с любыми значениями размерностей, то сделайте ее шаблонной.
6 ноя 2015 в 19:10
Шаблонная, в смысле template
6 ноя 2015 в 19:12
@neko69 Если вы хотите иметь дело именно с двумерными массивами, то без этого не обойтись.
6 ноя 2015 в 19:13
@neko69 Смотрите мой обновленный ответ.
6 ноя 2015 в 19:17
В gcc сделать это совсем просто.
Вы можете передавать в функцию размерности матрицы (достаточно только «низших») и обращаться к элементам по индексам естестственным образом. Например:
void func (int n_lines, int n_columns, int array[][n_columns])
К сожалению g++ (и c++) не поддерживает такую передачу матриц в функцию. Поэтому проще всего (обладая знанием, что все элементы матрицы располагаются в памяти последовательно, сначала первая строка, за ней вторая и т.д.) передать в функцию адрес первого элемента матрицы, а в функции рассматривать ее как одномерный массив.
Естественно, пересчитывать индексы придется самому.
Вот пример файла, в котором представлены обе версии программы и результаты его запуска:
avp@avp-ubu1:hashcode$ cat c1.c #include #ifdef __cplusplus #include #endif static int aa[4][3] = < , , , >; #ifdef __cplusplus void func_matrix (int n, int m, int *x) < x[0] = x[(n - 1) * m + m - 1]; for (int i = 0; i < n; i++) for (int j = 0; j < m || !puts(""); j++) std::cout #else void func_matrix (int n, int m, int x[n][m]) < int i, j; x[0][0] = x[n - 1][m - 1]; for (i = 0; i < n; i++) for (j = 0; j < m || !puts(""); j++) printf("%d ", x[i][j]); >#endif int main (int ac, char *av[]) < #ifdef __cplusplus func_matrix(4, 3, &aa[0][0]); #else func_matrix(4, 3, aa); #endif >avp@avp-ubu1:hashcode$ gcc c1.c && ./a.out 43 12 13 21 22 23 31 32 33 41 42 43 avp@avp-ubu1:hashcode$ g++ c1.c && ./a.out 43 12 13 21 22 23 31 32 33 41 42 43 avp@avp-ubu1:hashcode$
Если вопросы еще остались, задавайте.
UPD
Вот вариант с указателями на строки «плотной» матрицы.
Берем статическую матрицу, делаем для нее массив указателей, передаем его в функцию транспонирования, которая делает в динамической памяти «плотную» транспонированную матрицу и возвращает новый массив указателей на ее строки.
#include #include int ** make_lines_ptrs (int *mx, int a, int b) < int **p = (int **)malloc(a * sizeof(int *)); for (int i = 0; i < a; i++) p[i] = mx + i * b; return p; >int ** transp (const int * const * m, int a, int b) < int *mx = (int *)malloc(a * b * sizeof(int)); for (int i = 0; i < a; i++) for (int j = 0; j < b; j++) mx[j * a + i] = m[i][j]; return make_lines_ptrs(mx, b, a); >void pri_mx (const int * const * m, int a, int b) < for (int i = 0; i < a; i++) for (int j = 0; j < b || !puts(""); j++) printf("%d ", m[i][j]); >static int aa[4][3] = < , , , >; int main (int ac, char *av[])
Ну, память перед выходом Вы уж сами освободите?
Передача массива в функцию и возврат из функции
Особенность передачи массивов в функции в языке Си в том, что передается не сам массив, а адрес массива, который хранится в локальном указателе на него.
Это можно сделать по-разному, но результат будет одинаковый:
- void some_function(int array[]);
- void some_function(int *array);
При этом обязательно нужно указать тип элемента массива.
Размер массива в функцию автоматически не передается, поэтому если размер массива заранее (на этапе компиляции) не оговорен, то нужно передать параметр, который содержит количество элементов в массиве, например number_of_elements:
void some_function(int array[], int number_of_elements);
Следующая программа передает массивы в функцию show_array, которая использует цикл for для вывода значений массивов:
show_array.c
void show_array (int array [], int number_of_elements)
for ( int i = 0; i < number_of_elements; i++) printf("%d\t", array[i]);
>
printf(«\n»);
>
int main()
int little_numbers[5] = ;
int big_numbers[3] = ;
show_array(little_numbers, 5);
show_array(big_numbers, 3);
>
Массив просто передается в функцию по имени (а его имя — это адрес первого элемента), а также указывает параметр, который сообщает функции количество элементов, содержащихся в массиве:
Изменение массива из функции
Возможно ли поменять значения элементов из функции?
Ответ положительный — да, это возможно, причем ничего дополнительно для этого указывать не нужно, так как в функцию передается адрес массива, а не сами значения, то и доступ происходит к тем же самым элементам, а не к их копиям.
Следующая программа использует функцию get_values, чтобы присвоить три значения массиву numbers:
values_from_keyboard.c
#include
void read_array(int array[], int number_of_elements)
for(int i = 0; i < number_of_elements; i++)
printf(«Введите значение №%d: «, i);
scanf(«%d», &array[i]);
>
>
int main()
int numbers[3] = ;
read_array (numbers, 3); //массив будет изменен!
printf(» Значения массива\n»);
for (int i = 0; i < 3; i++) printf(" numbers [%d] \n", i);
>
Как видите, программа передает массив в функцию по имени, а функция присваивает массиву элементы.
Таким образом, функция может изменить элементы массива, если ей это нужно.
Как передать матрицу в функцию?

Как в функцию передать указатель на матрицу?
Че то я немного туплю, давно с функциями не работал, мне нужно реализовать функцию которая бы.

Как передать матрицу, которую мы получили в следующую функцию?
#include "stdafx.h" #include"iostream" using namespace std; struct matr < int x; int y; .
Указатели и матрицы: как правильно передать матрицу в функцию?
Здравствуйте! Во время того, как переписывал программу функциями возникла проблема, а именно.
Как передать матрицу, полученную в одной функции, в другую функцию?
как передать матрицу ,которую мы получили в одной функции в другую функцию? Написала функции для.