Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как передать массив в функцию(*) |
Автор: gray_k 14.11.2003, 16:07 |
Собственно тема задана раньше, но неявно. Захотелось вывести это в отдельный топик. Есть функция void f(int **) {return;} Как в эту функцию передать двумерный массив, созданный статически. Вот так не получается void f1() { int i[2][2]; f(i); } Компилятор ругается на приведение типов. |
Автор: Ars 14.11.2003, 16:39 | ||
|
Автор: gray_k 14.11.2003, 17:17 |
Не понял, совсем плохой стал наверное под конец рабочей недели ![]() В вопросе было: как в функцию у которой параметр - указатель на двумерный массив (размер заранее не известен) - f(int **) передать из другой функции массив, созданный статически и локально внутри этой функции. |
Автор: Ars 14.11.2003, 18:44 |
Передать-то можно все, что угодно, на крайняк используя явное преобразование типов. Даже можно указатель передать через int. И совсем другое - что потом с этим добром делать в функции. Как функция узнает размерность массива? Если хочется через функцию, ничего не выйдет. Но можно попробовать через шаблоны |
Автор: gray_k 14.11.2003, 19:25 |
Передать размер массива проблем нет. А если использовать явное приведение типов f((int **) MyArray) - то внутри функции при попытке обращения к элементу массива выскакивает Access Violation. |
Автор: Oksiv 14.11.2003, 22:02 |
Любой двумерный массив можно представить ввиде одномерного так что думай ![]() |
Автор: bel_nikita 15.11.2003, 12:52 |
А мне кажется, что статический массив передать невозможно. Т.к. при объявлении массива, типа int А[5][5], память выделяется сразу. Т.е. элементы будут идти по-порядку: А[0][0], A[0][1], ....,A[0][4],A[1][0],... При int **А. Элементы идут не по-порядку. Это же указатель на массив указателей. |
Автор: Nastya 15.11.2003, 14:17 |
1. Так можно передать динамический массив 2. При передаче статическго массива обязательно указывать вторую размерность void f(int mas[][10]) 3. Если вышеуказанным образом передавать статический массив, то обращатся к его элементам надо не mas[i][j], а через указтели вручную расчитывая номер элемента. |
Автор: Waters 16.11.2003, 07:38 | ||
Позвольте я обобщу все вышесказанное...
wbr. |
Автор: gray_k 17.11.2003, 09:33 |
Обобщение просто супер ![]() Это и так сразу было понятно. Вопрос то был про статический массив и указатель в функции. Я почему его задал. Например есть у вас метод или функция к исходнику которой нет доступа, но вызывать в программе его можно. В качестве параметров передеётся (int **, int x, int y). Как загнать туда двумерный массив обявленный статически. Из всего вышесказанного можно сделать вывод, что необходимо либо пользоваться динамическим массивом, либо действовать через временный массив. |
Автор: knave 17.11.2003, 12:56 |
Вот это без проблем откомпилировалось void f(int ar[2][2]) { return; } int main(int argc, char* argv[]) { int i[2][2]; f(i); return 0; } |
Автор: gray_k 17.11.2003, 13:08 |
Ну блин, устал уже ![]() Вопрос - есть функция. В списке аргументов у неё указатель на двумерный массив (int **) и его размеры. Как в такую функцию передеть статический массив? |
Автор: RAN 17.11.2003, 22:01 |
Никак. Статический массив нельзя привести к int** |
Автор: Waters 18.11.2003, 19:04 | ||
int ** это не указатель на двумерный массив (в том виде, в каком это требует стандарт). |
Автор: akul 19.11.2003, 15:02 |
to gray_k: Сначала надо понять, что все массивы в С есть линейные последовательности, потом - что int ** есть указатель на указатель на инт. Тогда станет понятно, что для работы этой функции, скорее всего, требуется как сам массив int, так массив указателей на начала его строк, адрес которого и передается. Первое у тебя есть, второго - нет. Значит, надо его сформировать и передать его адрес. |
Автор: GanZaleZ 19.11.2003, 22:46 |
попробуй передать int i[2][2]; f(i[2]); поидее веть имя массифа яфляеца указателем на перфый элемент , а элементы перфого масива яфляюца указателями на вторые масифы ! ![]() ![]() А такая на фид простенькая задачка ![]() ![]() |
Автор: Ars 20.11.2003, 10:57 | ||
Неверное представление о статических массивах. Двумерный статический массив на самом деле - одномерный, но его логически можно представить как двумерный. А если функция считает, что ей передали указатель на массив указателей, она возможно и отработает без эксцепшона, но все равно неправильно |
Автор: GanZaleZ 20.11.2003, 22:35 |
Ну это ясево что он одномерный ![]() ![]() |
Автор: Ars 21.11.2003, 10:21 | ||
![]() Ну простите за неточность... Я имел ввиду, что он располагается в памяти одним непрерывным куском |
Автор: Freeman 1.12.2003, 00:32 |
Может понравиться, все равно я не долго думал ![]() #include <iostream.h> void f(int **h, int a, int b) { int *s; s=new int[a*b]; s=(int *)h; for(int i=0; i<a; i++) for(int j=0; j<b; j++) cout << *(s + i*b + j) << ' '; } void main() { int a[2][4]={{1,2,3,4},{10,20,30,40}}; f((int**)a, 2, 4); } |
Автор: Freeman 1.12.2003, 03:38 |
![]() |
Автор: Ars 1.12.2003, 10:44 | ||
Что это? ![]() |
Автор: Freeman 1.12.2003, 18:33 | ||||
Ну как что , создание динамического массива общей размерностью a*b, чтобы компилятор знал размер памяти на которую указывает s или h, это точно работает проверял |
Автор: Ars 1.12.2003, 19:07 | ||
С таким же успехом будет работать и следующий код, зато без утечек памяти ![]()
|
Автор: Freeman 2.12.2003, 20:51 |
Ну ладно согласен , будет работать, но важна идея ![]() ![]() |
Автор: Hroft 8.12.2003, 11:12 |
по-моему, неплох такой вариант: #include <iostream> void f(int **a,int n,int m) { std::cout<<a[0]<<std::endl; for (int i=0;i<n;++i) { for (int j=0;j<m;++j) { std::cout<<a[i][j]<<" "; } std::cout<<std::endl; } } typedef int *pint; int main(int argc, char* argv[]) { const int n = 3; const int m = 2; int i1[n][m] = {{1,2},{3,4},{5,6}}; int **i2 = new pint[n]; int **i3; int i = 0; for (i=0;i<n;++i) { i2[i] = new int[m]; for (int j=0;j<m;++j) { i2[i][j] = (n-1)*i + j + 1 + 100; } } i3 = new pint[n]; for (i=0;i<n;++i) { i3[i] = i1[i]; // скопировать только указатели, а не значения, // так что невелика потеря времени и памяти } f(i2,n,m); //dynamic f(i3,n,m); //static return 0; } |
Автор: Mellorn 11.12.2003, 15:04 |
Вот вы все используете такую весч! void tratata(int ** array) - сколько помню себя кодющим "**" было указателем на указтель.. это ведь не двойной массив... (во всяком случае мой компилятор матерится почем зря) _________________________ С уважение Мэл. прошу обьясните мне эту фичу с ** =) |
Автор: Mellorn 11.12.2003, 15:07 | ||
P.S ->
Полностью согласен потому и задал вопрос вышк |