Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как передать массив в функцию(*) 
:(
    Опции темы
gray_k
Дата 14.11.2003, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1015
Регистрация: 9.1.2003
Где: Москва

Репутация: нет
Всего: 22



Собственно тема задана раньше, но неявно. Захотелось вывести это в отдельный топик.
Есть функция
void f(int **)
{return;}
Как в эту функцию передать двумерный массив, созданный статически.
Вот так не получается
void f1()
{
int i[2][2];
f(i);
}
Компилятор ругается на приведение типов.


--------------------
С уважением.
Gray.
PM MAIL   Вверх
Ars
Дата 14.11.2003, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Код
int Array[10][20];
MyFunc((int *)Array);
//---------------------------------------------------------------------------
void MyFunc(int *Arg)
{
int (*Array1)[20]=(int(*)[20])Arg;
Array1[1][5]=1;
}


Это сообщение отредактировал(а) Ars - 14.11.2003, 16:41


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
gray_k
Дата 14.11.2003, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1015
Регистрация: 9.1.2003
Где: Москва

Репутация: нет
Всего: 22



Не понял, совсем плохой стал наверное под конец рабочей недели confused.gif.
В вопросе было:
как в функцию у которой параметр - указатель на двумерный массив (размер заранее не известен) - f(int **) передать из другой функции массив, созданный статически и локально внутри этой функции.


--------------------
С уважением.
Gray.
PM MAIL   Вверх
Ars
Дата 14.11.2003, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



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


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
gray_k
Дата 14.11.2003, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1015
Регистрация: 9.1.2003
Где: Москва

Репутация: нет
Всего: 22



Передать размер массива проблем нет. А если использовать явное приведение типов
f((int **) MyArray) - то внутри функции при попытке обращения к элементу массива выскакивает Access Violation.


--------------------
С уважением.
Gray.
PM MAIL   Вверх
Oksiv
Дата 14.11.2003, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 17.10.2003
Где: Санкт-Петербург, Гражданка

Репутация: нет
Всего: нет



Любой двумерный массив можно представить ввиде одномерного так что думай smile.gif
PM MAIL WWW ICQ   Вверх
bel_nikita
Дата 15.11.2003, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



А мне кажется, что статический массив передать невозможно.
Т.к. при объявлении массива, типа int А[5][5], память выделяется сразу. Т.е. элементы будут идти по-порядку: А[0][0], A[0][1], ....,A[0][4],A[1][0],...
При int **А. Элементы идут не по-порядку. Это же указатель на массив указателей.


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
Nastya
Дата 15.11.2003, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 27.3.2002
Где: Мариуполь

Репутация: 5
Всего: 44



1. Так можно передать динамический массив
2. При передаче статическго массива обязательно указывать вторую размерность
void f(int mas[][10])
3. Если вышеуказанным образом передавать статический массив, то обращатся к его элементам надо не mas[i][j], а через указтели вручную расчитывая номер элемента.



--------------------
Что бы понять рекурсию, надо понять рекурсию

"Профессионал - это человек сделавший все возможные ошибки в очень узкой области". Н.Бор
PM MAIL   Вверх
Waters
Дата 16.11.2003, 07:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 16.11.2003

Репутация: нет
Всего: нет



Позвольте я обобщу все вышесказанное...

Код

// первую размерность передаем, вторая фиксирована
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.
PM MAIL   Вверх
gray_k
Дата 17.11.2003, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1015
Регистрация: 9.1.2003
Где: Москва

Репутация: нет
Всего: 22



Обобщение просто супер smile.gif.
Это и так сразу было понятно. Вопрос то был про статический массив и указатель в функции.
Я почему его задал. Например есть у вас метод или функция к исходнику которой нет доступа, но вызывать в программе его можно. В качестве параметров передеётся (int **, int x, int y). Как загнать туда двумерный массив обявленный статически.
Из всего вышесказанного можно сделать вывод, что необходимо либо пользоваться динамическим массивом, либо действовать через временный массив.


--------------------
С уважением.
Gray.
PM MAIL   Вверх
knave
Дата 17.11.2003, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 320
Регистрация: 6.3.2003
Где: Санкт-Питербург ( Россия)

Репутация: 1
Всего: 5



Вот это без проблем откомпилировалось

void f(int ar[2][2])
{
return;
}
int main(int argc, char* argv[])
{
int i[2][2];

f(i);
return 0;
}




--------------------
С наилучшими пожеланиями !!!
PM MAIL ICQ   Вверх
gray_k
Дата 17.11.2003, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1015
Регистрация: 9.1.2003
Где: Москва

Репутация: нет
Всего: 22



Ну блин, устал уже smile.gif.
Вопрос - есть функция. В списке аргументов у неё указатель на двумерный массив (int **) и его размеры.
Как в такую функцию передеть статический массив?


--------------------
С уважением.
Gray.
PM MAIL   Вверх
RAN
Дата 17.11.2003, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

Репутация: 5
Всего: 6



Никак. Статический массив нельзя привести к int**
PM MAIL ICQ   Вверх
Waters
Дата 18.11.2003, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 16.11.2003

Репутация: нет
Всего: нет



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


int ** это не указатель на двумерный массив (в том виде, в каком это требует стандарт).

Это сообщение отредактировал(а) Waters - 18.11.2003, 19:09
PM MAIL   Вверх
akul
Дата 19.11.2003, 15:02 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











to gray_k:
Сначала надо понять, что все массивы в С есть линейные последовательности, потом - что int ** есть указатель на указатель на инт. Тогда станет понятно, что для работы этой функции, скорее всего, требуется как сам массив int, так массив указателей на начала его строк, адрес которого и передается. Первое у тебя есть, второго - нет. Значит, надо его сформировать и передать его адрес.
  Вверх
GanZaleZ
Дата 19.11.2003, 22:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 15.7.2003

Репутация: нет
Всего: нет



попробуй передать

int i[2][2];

f(i[2]);

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

PM MAIL   Вверх
Ars
Дата 20.11.2003, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Цитата
элементы перфого масива яфляюца указателями на вторые масифы

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


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
GanZaleZ
Дата 20.11.2003, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 15.7.2003

Репутация: нет
Всего: нет



Ну это ясево что он одномерный smile.gif федь если бы был четырехмерный то это не значить что он и в памяти по четырехмерному распологаеца smile.gif
PM MAIL   Вверх
Ars
Дата 21.11.2003, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



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


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
Freeman
Дата 1.12.2003, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 29.11.2003

Репутация: нет
Всего: нет



Может понравиться, все равно я не долго думал 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);
}
PM MAIL   Вверх
Freeman
Дата 1.12.2003, 03:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 29.11.2003

Репутация: нет
Всего: нет



smile.gif


Это сообщение отредактировал(а) Freeman - 1.12.2003, 03:40
PM MAIL   Вверх
Ars
Дата 1.12.2003, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



Цитата
int *s;
s=new int[a*b];
s=(int *)h;

Что это? wow.gif


--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
Freeman
Дата 1.12.2003, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 29.11.2003

Репутация: нет
Всего: нет



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

Что это? wow.gif

Ну как что , создание динамического массива общей размерностью a*b, чтобы компилятор знал размер памяти на которую указывает s или h, это точно работает проверял
PM MAIL   Вверх
Ars
Дата 1.12.2003, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 325
Регистрация: 28.8.2003
Где: Московская обл.

Репутация: 2
Всего: 2



С таким же успехом будет работать и следующий код, зато без утечек памяти 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);
}



--------------------
Есть многое на свете, друг Горацио,
С чем очень долго можно прое..!
PM MAIL   Вверх
Freeman
Дата 2.12.2003, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 44
Регистрация: 29.11.2003

Репутация: нет
Всего: нет



Ну ладно согласен , будет работать, но важна идея smile.gif smile.gif
PM MAIL   Вверх
Hroft
Дата 8.12.2003, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 20.10.2003
Где: Москва

Репутация: нет
Всего: 3



по-моему, неплох такой вариант:

#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;
}
PM MAIL ICQ   Вверх
Mellorn
Дата 11.12.2003, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 3.12.2003

Репутация: 1
Всего: 1



Вот вы все используете такую весч!
void tratata(int ** array) - сколько помню себя кодющим "**" было указателем на указтель.. это ведь не двойной массив... (во всяком случае мой компилятор матерится почем зря)

_________________________
С уважение Мэл. прошу обьясните мне эту фичу с ** =)
PM MAIL   Вверх
Mellorn
Дата 11.12.2003, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 3.12.2003

Репутация: 1
Всего: 1



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

Полностью согласен потому и задал вопрос вышк
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1275 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.