Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Передать в функцию двумерный статический массив

7.3K
22 мая 2007 года
Blizzard
3 / / 10.06.2004
Есть массив:
int MasPer[20][20];

Есть функция со след. заголовком:
void vyvesti(int** Mas_2x, int Razm1, int Razm2, ofstream& fileMas);

И участок кода:
vyvesti(MasPer, KolPotr, KolPost, fileOut);

Подскажите, пожалуйста, как сделать так, чтобы это все работало?
Выдает ошибку
error C2664: 'vyvesti' : cannot convert parameter 1 from 'int [20][20]' to 'int ** '

Нужно обязательно оставить возможность передавать в ф-ю динамические массивы и желательно объявить MasPer как статический массив
3
22 мая 2007 года
Green
4.8K / / 20.01.2000
Можно так
 
Код:
void vyvesti(int Mas_2[][20], int Razm1, ofstream& fileMas);

а можно так
 
Код:
template<class T>
void vyvesti(T& Mas_2x, ofstream& fileMas);

Только вот скажи, почему бы тебе не использовать контейнеры, раз уж ты пишешь на C++ с использованием STL ?
А выглядит как автомобиль Ferrari с деревянными колесами от телеги.
309
22 мая 2007 года
el scorpio
1.1K / / 19.09.2006
Цитата:
Выдает ошибку
error C2664: 'vyvesti' : cannot convert parameter 1 from 'int [20][20]' to 'int ** '


Дело в том, что int [20][20] - это, с точки зрения машинной логики, одномерный линейный массив, посему передаваться в функцию должен указателем первого порядка (int*)

А для правильного подставления в функцию параметра int** (указатель второго порядка), нужно объявлять динамический двумерный массив, выделять под него память в куче.
Вот только код выделения/освобождения памяти будет очень длниный :(

3
22 мая 2007 года
Green
4.8K / / 20.01.2000
Цитата: el scorpio
Дело в том, что int [20][20] - это, с точки зрения машинной логики, одномерный линейный массив, посему передаваться в функцию должен указателем первого порядка (int*)


Это с точки зрения логики каких таких машин? :)

С точки зрения С++ это двумерный массив конкретной размерности, который можно передавать по ссылке или по указателю на двумерный массив этой же размерности.

 
Код:
void vyvesti( int (&Mas_2x)[20][20] );
void vyvesti( int (*Mas_2x)[20][20] );

Либо можно передать указатель на первый элемент этого массива, который будет одномерным массивом конкретной размерности.
 
Код:
void vyvesti( int(*Mas_2x)[20] );

void vyvesti( int Mas_2x[][20] );
void vyvesti( int Mas_2x[20][20] );


Можно завернуть это дело в шаблон для любых размерностей.
Но лучше использовать КОНТЕЙНЕРЫ.
255
22 мая 2007 года
Dart Bobr
1.4K / / 09.04.2004
я ваще всегда пишу так:

void Func1(int * pBuff);
{
....
}

int * pBuffer = (int *)malloc(sizeof(int) * 20 * 20);
Func1(pBuffer);

а уже в самой функции - конвертить типа:
counter = innercounter + outercounter * 20;
3
22 мая 2007 года
Green
4.8K / / 20.01.2000
Ну а ещё можно ухо почесать ногой... :)
21K
22 мая 2007 года
IERO_Distin
23 / / 21.05.2007
вариант с адресной арифметикой (неохота было память динамически выделять):
Код:
clas1 a[n][m];
//n и m - константы размера
int func(clas1 * b)
{
//..........
    for(int i=0;i<n;i++)   
        for(int j=0;j<m;j++)
            ( *(b+(j*mpwdth)+i) )=0;
//.......................................
}
//вызов:
clas1* tmp=&a[0][0];
func (tmp);

извращение конечно но работает по крайней мере
63
22 мая 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: IERO_Distin
вариант с адресной арифметикой (неохота было память динамически выделять):
Код:
clas1 a[n][m];
//n и m - константы размера
int func(clas1 * b)
{
//..........
    for(int i=0;i<n;i++)   
        for(int j=0;j<m;j++)
            ( *(b+(j*mpwdth)+i) )=0;
//.......................................
}
//вызов:
clas1* tmp=&a[0][0];
func (tmp);

извращение конечно но работает по крайней мере


Ну и зачем оно нужно?

20K
23 мая 2007 года
sja
22 / / 08.01.2007
Самый простой способ сдедующий (быстроработающий к тому же:)
НЕ НУЖНО НИКАКИХ КОНТЕЙНЕРОВ!

Код:
#include <iostream>
using namespace std;

int mass[20][20];

void output (int *mass) // преобразуем к одномерн. массиву
{
    cout << mass[20*0 + 0] << endl;
    cout << mass[20*0 + 1] << endl;
    cout << mass[20*3 + 7] << endl; //если размерность известна
};                                                       // то все добро :)

int main(int argc, char *argv[])
{
    mass[0][0] = 1;
    mass[0][1] = 2;
    mass[3][7] = 3;
   
    output (&mass[0][0]);//передаем адрес певрого элемента масс.
   
    system("PAUSE");
    return EXIT_SUCCESS;
}

Если неизвестна размерность массива, то ее можно тоже передать в функции - типа
void output (int *mass, int SIZE_X, int SIZE_Y)
92
23 мая 2007 года
Тень Пса
2.2K / / 19.10.2006
а если размерность не известна? :))))))))) не добро?
3
23 мая 2007 года
Green
4.8K / / 20.01.2000
Цитата: sja
Самый простой способ сдедующий (быстроработающий к тому же:)
НЕ НУЖНО НИКАКИХ КОНТЕЙНЕРОВ!


Ну так и cout не нужен, и двумерный массив не нужен.
Нафига тебе вообще C++ ?

До чего же народ любит забивать гвозди микроскопом...

255
23 мая 2007 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Green
Ну а ещё можно ухо почесать ногой... :)



ну, не знаю. мне так удобно.

3
23 мая 2007 года
Green
4.8K / / 20.01.2000
Цитата: Dart Bobr

[QUOTE=Green;193587]Ну а ещё можно ухо почесать ногой... :)


ну, не знаю. мне так удобно.[/QUOTE]
Попробуй почесать рукой. Вот увидишь, это удобнее. :D

92
23 мая 2007 года
Тень Пса
2.2K / / 19.10.2006
[offtop]
Цитата: Green
Ну так и cout не нужен, и двумерный массив не нужен.
Нафига тебе вообще C++ ?

До чего же народ любит забивать гвозди микроскопом...



ааааааааааааааа... как сказал! как сказал!!!!! :D
[/offtop]

20K
23 мая 2007 года
sja
22 / / 08.01.2007
Цитата: Тень Пса
а если размерность не известна? :))))))))) не добро?



а если не известна, то о чем вообще речь? чем пукать сказал бы по делу что-нибудь!

хотя у автора топика передается в функцию размер массива.

дзен рядом! но судя по всему не для всех... мир не спасти...

92
23 мая 2007 года
Тень Пса
2.2K / / 19.10.2006
по делу говорилось еще до Вашего поста, уважаемый. и вместо того, чтобы как вы выразились "пукать", лучше бы шли и делали RTFM относительно С++ и в частности STL.

а то что Вы привели в качестве мегарешения, простите, бред =)

PS: речь о том, что массив может быть и динамическим
63
23 мая 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: sja
а если не известна, то о чем вообще речь?


Речь о том, что такие ситуации должны быть предусмотрены в программе, а ты видимо, предлагаешь принцип - "Если я не знаю, как это реализовать, то это надо просто выбросить из ТЗ";).
Как ты сам сказал в предыдущем своем посте, размерность массива можно передавать в функцию отдельными аргументами. Но у этого подхода есть объективные недостатки:
1) Это просто неудобно. Ее придется хранить в отдельной переменной/переменных, передавать ее везде, где требуется работа с массивом.
2) Если передавать размерность массива отдельно от него, то можно допустить ошибку - передать ее некорректно. И тогда ошибка пойдет дальше, в функцию-обработчик, и т.д.
3) Массив фиксированной длины сам по себе не слишком удобен.

А теперь правильное решение поставленной задачи. По шагам.
1) Ясно, что размерность массива есть его неотъемлемая характеристика.
2) Значит, их нужно хранить вместе, причем обеспечивать корректную установку значений этой характеристики при создании массива, при его резайзе, и прочих изменениях, а так же обеспечить возможность получение актуального значения этой характеристики в любой момент времени.
3) Поразмыслив немного, придем к выводу, что было бы неплохо написать собственный шаблонный класс, реализующий описанные в п. 2 возможности.
4) Заглянув в std::vector, видим, что такой класс уже есть, причем реализующий, дополнительно, большое кол-во других ценнейших возможностей, описанный в известных книгах по стандартной библиотеке С++ и имеющий полную документацию.
Ну и каков будет твой выбор?...

Цитата: sja

хотя у автора топика передается в функцию размер массива.


Возможно, автор просто не знает других способов. Но зачем отвергать их, если они намного лучше?

Цитата: sja

дзен рядом! но судя по всему не для всех... мир не спасти...


Зачем упрекать кого-то в том, что он постит не по теме, и самому тут же вляпываться в какую-то пессимистичную философию?;)

20K
24 мая 2007 года
sja
22 / / 08.01.2007
Я выложил свой вариант решения задачи, который вполне может быть использован в программе.
А если неизвестна размерность массива перед его обработкой и если передаются переменные в функцию с искажением размерности, то искать причину надо в ждругом месте :)
Тут только либо искусственный интеллект, либо лсб.
7.3K
24 мая 2007 года
Blizzard
3 / / 10.06.2004
Спасибо всем! Посмотрел возможнные варианты и решил делать все массивы динамическими. Насчет vector и ООП - не перевариваю как-то, люблю программировать на низком уровне. Моя мечта - написать по-настоящему большую программу, чтобы понять, что без ООП не обойтись :). Для проги в 3000 строк структур хватает.

P. S. Вот и смайлик низкоуровневый

P. P. S. Кто-нибудь обязательно предложит программировать на асме. Пробовал, но по ряду причин выбрал C++.
92
24 мая 2007 года
Тень Пса
2.2K / / 19.10.2006
тогда уж ты выбрал С :) ибо отличие-то основное С++ от С - это ООП :)
63
24 мая 2007 года
Zorkus
2.6K / / 04.11.2006
Цитата: sja
Я выложил свой вариант решения задачи, который вполне может быть использован в программе.


Он совершенно корректен, не спорю. Он будет компилиться и прекрасно работать, для этой конкретной задачи. Но в реальной жизни твой вариант будет малопригоден. Использовать-то можно, но ЗАЧЕМ, если есть варианты гораздо лучше.

Цитата: sja

А если неизвестна размерность массива перед его обработкой и если передаются переменные в функцию с искажением размерности, то искать причину надо в ждругом месте :)


Именно сказал, хорошо - в ДРУГОМ месте.
1. В проектировании. Механизмы передачи и обработки настолько непрозрачные, что в них данные исчезают, как в черных дырах.
2. В нерациональном использовании средств и незнании стандартных реализаций тривиальных вещей.
Вопрос на засыпку - для чего была создана Стандартная библиотека? ;)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог