Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > 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
Код
int Array[10][20];
MyFunc((int *)Array);
//---------------------------------------------------------------------------
void MyFunc(int *Arg)
{
int (*Array1)[20]=(int(*)[20])Arg;
Array1[1][5]=1;
}

Автор: gray_k 14.11.2003, 17:17
Не понял, совсем плохой стал наверное под конец рабочей недели confused.gif.
В вопросе было:
как в функцию у которой параметр - указатель на двумерный массив (размер заранее не известен) - 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
Любой двумерный массив можно представить ввиде одномерного так что думай smile.gif

Автор: 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
Позвольте я обобщу все вышесказанное...

Код

// первую размерность передаем, вторая фиксирована
void f(int a[][20], int n)
{
 int sum=0; // для примера сумма
 for(int i=0; i<n; ++i)
 for(int j=0; j<20; ++j)
   sum += a[i][j];
 //...
}

int a[10][20];

void main(void)
{
 f(a, 10);
}


wbr.

Автор: gray_k 17.11.2003, 09:33
Обобщение просто супер smile.gif.
Это и так сразу было понятно. Вопрос то был про статический массив и указатель в функции.
Я почему его задал. Например есть у вас метод или функция к исходнику которой нет доступа, но вызывать в программе его можно. В качестве параметров передеётся (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
Ну блин, устал уже smile.gif.
Вопрос - есть функция. В списке аргументов у неё указатель на двумерный массив (int **) и его размеры.
Как в такую функцию передеть статический массив?

Автор: RAN 17.11.2003, 22:01
Никак. Статический массив нельзя привести к int**

Автор: Waters 18.11.2003, 19:04
Цитата
...В списке аргументов у неё указатель на двумерный массив (int **) и его размеры.


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]);

поидее веть имя массифа яфляеца указателем на перфый элемент , а элементы перфого масива яфляюца указателями на вторые масифы ! smile.gif каламбур полнейший но работать фроде как должно smile.gif
А такая на фид простенькая задачка smile.gif У мя щас компилятора под рукой нету поэтому проферить немогу smile.gif

Автор: Ars 20.11.2003, 10:57
Цитата
элементы перфого масива яфляюца указателями на вторые масифы

Неверное представление о статических массивах. Двумерный статический массив на самом деле - одномерный, но его логически можно представить как двумерный. А если функция считает, что ей передали указатель на массив указателей, она возможно и отработает без эксцепшона, но все равно неправильно

Автор: GanZaleZ 20.11.2003, 22:35
Ну это ясево что он одномерный smile.gif федь если бы был четырехмерный то это не значить что он и в памяти по четырехмерному распологаеца smile.gif

Автор: Ars 21.11.2003, 10:21
Цитата
Ну это ясево что он одномерный  федь если бы был четырехмерный то это не значить что он и в памяти по четырехмерному распологаеца 
biggrin.gif
Ну простите за неточность... Я имел ввиду, что он располагается в памяти одним непрерывным куском

Автор: Freeman 1.12.2003, 00:32
Может понравиться, все равно я не долго думал smile.gif)

#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
smile.gif

Автор: Ars 1.12.2003, 10:44
Цитата
int *s;
s=new int[a*b];
s=(int *)h;

Что это? wow.gif

Автор: Freeman 1.12.2003, 18:33
Цитата(Ars @ 1.12.2003, 10:44)
Цитата
int *s;
s=new int[a*b];
s=(int *)h;

Что это? wow.gif

Ну как что , создание динамического массива общей размерностью a*b, чтобы компилятор знал размер памяти на которую указывает s или h, это точно работает проверял

Автор: Ars 1.12.2003, 19:07
С таким же успехом будет работать и следующий код, зато без утечек памяти smile.gif
Код
#include <iostream.h>
void f(int **h, int a, int b)
{
for(int i=0; i<a; i++)
for(int j=0; j<b; j++)
cout << *((int *)h + i*b + j) << ' ';
}

void main()
{
int a[2][4]={{1,2,3,4},{10,20,30,40}};

f((int**)a, 2, 4);
}

Автор: Freeman 2.12.2003, 20:51
Ну ладно согласен , будет работать, но важна идея smile.gif smile.gif

Автор: 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 ->
Цитата
Неверное представление о статических массивах. Двумерный статический массив на самом деле - одномерный, но его логически можно представить как двумерный. А если функция считает, что ей передали указатель на массив указателей, она возможно и отработает без эксцепшона, но все равно неправильно

Полностью согласен потому и задал вопрос вышк

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)