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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передать двумерный массив в функцию 
V
    Опции темы
neosapient
Дата 18.4.2007, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Встала проблема передать двумерный массив в функцию.

Здесь часто поднимались схожие вопросы, но ... не нашел ниодного подходящего ответа

Код

#define defY 5
#define defX 6

int Mas[Y][X]

void func (int** ppMas, int x, int y)
{int i,j;
for(j=0;j<y;j++){
    for(i=0;i<x;i++){
        printf("%c",   *(*(ppMas+j)+i)   );
    }
printf("\n");
}
}

void main (void)
{
func ((int**)Mas,defY,defX);
}


Вот примерно так я планировал передовать массив, передавая в функцию указатель на массив указателей, размер по Y и по X

Как я думаю при преобразовании двумерного массива к указателю int** происходит затерание ячеек Mas[j], т.е. там появляются нулевые указатели

Как правильно здесь выкрутиться

С динамическими массивами работать не хочу
PM MAIL   Вверх
JackYF
Дата 18.4.2007, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Код

void func (int ppMas[Y][X], int x, int y)


или 

Код

void func (int ppMas[][X], int x, int y)




--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 18.4.2007, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(neosapient @  18.4.2007,  17:50 Найти цитируемый пост)
Как я думаю при преобразовании двумерного массива к указателю int** происходит затерание ячеек Mas[j], т.е. там появляются нулевые указатели
там нет указателей и появлятся им неоткуда!
Mas - это не массив указателей... это двумерный массив... разница колоссальная...
ты можешь передать массив определённой размерности с произвольной последней размерностью...
void func (int Mas [][X])

Это сообщение отредактировал(а) archimed7592 - 18.4.2007, 17:57


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
HappyLife
Дата 18.4.2007, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



archimed7592, 
не согласен.
Двумерный массив это массив массивов. И интерпретируеться как
*(*(Mas + X) + Y)
Где наглядно можно понять, что все такие это массив указателей...
Но ничего не затераеться.
И Mas[1] - хранит указатель на Mas[1][0]
  Mas[2] - хранит указаьель на Mas[2][0]

Это сообщение отредактировал(а) HappyLife - 18.4.2007, 18:23
PM MAIL   Вверх
JackYF
Дата 18.4.2007, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

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



Цитата(HappyLife @  18.4.2007,  18:23 Найти цитируемый пост)
Двумерный массив это массив массивов. И интерпретируеться как


Нет! 
HappyLife, юзай поиск по форуму. Не раз уже подобная тема поднималась.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Xenon
Дата 18.4.2007, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

void func(int**& arr, int height, int width)

Можешь и так - так сможешь мочить указатель smile


--------------------
user posted image  
PM MAIL   Вверх
vinter
Дата 18.4.2007, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



JackYF, в этом
Цитата(HappyLife @  18.4.2007,  18:23 Найти цитируемый пост)
Двумерный массив это массив массивов

он прав



--------------------
Мой блог
PM MAIL WWW   Вверх
Xenon
Дата 18.4.2007, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



При передаче одномерного массива в фунцию в качестве фактического параметра нет разницы как мы объявили оный - int [] arr или int* arr, так как в любом случае будет неявное преобразование int [] в int*. Разница есть при передаче многомерных массивов - в случае с двумерным массивом при int arr [][X] в функцие он будет интепретироваться как (*)[X], то есть sizeof(arr[0][0] / sizeof(int)) выдаст количество элементов в строке.
Или я не понял о чем спор smile

Это сообщение отредактировал(а) Xenon - 18.4.2007, 19:21


--------------------
user posted image  
PM MAIL   Вверх
betal
Дата 18.4.2007, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(JackYF @  18.4.2007,  17:54 Найти цитируемый пост)
Выделить всёкод C++
1:
    
void func (int ppMas[Y][X], int x, int y)


или 

Выделить всёкод C++
1:
    
void func (int ppMas[][X], int x, int y)



 smile 
а в случаи если массивы находятся в Динамической памяти то
Код

void func (int **ppMas, int x, int y)


Добавлено через 1 минуту и 45 секунд
Цитата(Xenon @  18.4.2007,  19:07 Найти цитируемый пост)
Выделить всёкод C++
1:
    
void func(int**& arr, int height, int width)

Можешь и так - так сможешь мочить указатель smile 

опять не доглядел smile

Добавлено через 2 минуты и 24 секунды
Цитата(vinter @  18.4.2007,  19:13 Найти цитируемый пост)
JackYF, в этом
Цитата(HappyLife @  18.4.2007,  18:23 Найти цитируемый пост)
Двумерный массив это массив массивов

он прав

 smile 

Это сообщение отредактировал(а) betal - 18.4.2007, 21:36
--------------------
101100010100001101100001110100101111011легкие деньги
PM WWW ICQ   Вверх
archimed7592
Дата 18.4.2007, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



HappyLife, 
Цитата(HappyLife @  18.4.2007,  18:23 Найти цитируемый пост)
И Mas[1] - хранит указатель на Mas[1][0]
  Mas[2] - хранит указаьель на Mas[2][0]
согласен... "хранит"...
может быть скажешь мне тогда какой тип у этого указателя?
а лучше ничего не говори - покажи на деле:
Код
int a [10][20][30];
someType pointer = a[10];

1. какой должен быть тип someType (помимо того, что это указатель)?
2. где "хранится" этот указатель?
3. 
Код
int a [100];
int *pointer = a;// где "хранится" этот указатель?

4. 
Код
int a [10][20];
someType p1 = a[3]; // указатель, который где-то хранится
someType *pp1 = someExpression; // что нужно написать вместо someExpression, чтобы узнать адрес по которому он хранится?
someType p2 = a[7];
someType *pp2 = someExpression2;
// опа, да мы же можем творить чудеса! менять строки(или столбцы - неважно) местами!
*pp2 = p1;
*pp1 = p2;


если ещё остались вопросы, дам тебе ссылку на тему из около 20 страниц... может хоть она избавит тебя от твоих илюзий...

Добавлено через 2 минуты и 38 секунд
Цитата(betal @  18.4.2007,  21:36 Найти цитируемый пост)
а в случаи если массивы находятся в Динамической памяти то
почему вдруг ф-ция изменится, если массив будет в Динамической памяти (я так понимаю ты о new/delete говоришь)?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 18.4.2007, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(vinter @  18.4.2007,  19:13 Найти цитируемый пост)
он прав

да не прав
двумерный массив N x M (type array[N][M]) - это одномерный массив длины N * M, и доступ к элементу (i, j) осуществляется как array + i * M + j

Это сообщение отредактировал(а) MAKCim - 18.4.2007, 22:05


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Anikmar
Дата 18.4.2007, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(archimed7592 @  18.4.2007,  21:53 Найти цитируемый пост)
2. где "хранится" этот указатель?

Да нигде он не хранится! Он вычисляется сразу!

Двумерный массив можно рассматривать как массив одномерных массивов. Это четко прописано в стандарте.

Уже много раз на эту тему спорили.

Код

int mas [5][10];
int *pointer;

pointer = mas[0];

pointer[5] = 999;



Это абсалютно допустимая операция, pointer указатель и получает значение адреса 1-й строчки. Этот адрес в случае статического массива нигде не хранится, а вычисляется на этапе компиляции - так как базовый адрес массива известен.

В случае динамического определения массива делают так:

Код

    int **Mas;
    int Cols = 15;
    int Rows = 20;
    int i,j;

    Mas = new int*[Rows];
    for (i=0;i<Cols;i++) Mas[i] = new int[Rows];

    for (i=0;i<Cols;i++)
        for(j=0;j<Rows;j++) Mas[i][j] = RAND(100);


Все нормально компилируется и понимается как надо.
PM MAIL ICQ   Вверх
Voldemar2004
Дата 18.4.2007, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1650
Регистрация: 25.12.2004

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



Это мы представляем двумерный массив в виде таблицы, а 3-хмерный в виде куба, а ведь это одномерный вектор памяти, так ?


--------------------
i_i 
(';') 
(V)

user posted image
PM MAIL   Вверх
MAKCim
Дата 18.4.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(Anikmar @  18.4.2007,  22:04 Найти цитируемый пост)
Этот адрес в случае статического массива нигде не хранится, а вычисляется на этапе компиляции - так как базовый адрес массива известен.

он может вычислиться только при условии, что mas находится не в стеке
в случае стека до выполнения esp неизвестен

Добавлено через 1 минуту и 12 секунд
Цитата(Voldemar2004 @  18.4.2007,  22:07 Найти цитируемый пост)
Это мы представляем двумерный массив в виде таблицы, а 3-хмерный в виде куба, а ведь это одномерный вектор памяти, так ?

в случае type array[X1][X2]...[Xn], где Xi - константы, да


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Xenon
Дата 18.4.2007, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Просто важно не забывать, что в случае с динамическими массивами - это просто кучка разбросанных по памяти массивов.


--------------------
user posted image  
PM MAIL   Вверх
Anikmar
Дата 18.4.2007, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(MAKCim @  18.4.2007,  22:08 Найти цитируемый пост)
он может вычислиться только при условии, что mas находится не в стеке
в случае стека до выполнения esp неизвестен

Я неправильно выразился. Вычисляется прибавлением смещения к базовому адресу, а базовый уже получается либо в стеке либо в куче - все равно.

Просто при статическом объявлении массив сразу залезает в единый блок памяти.

На примере двухмерных массивов:
Мнение, что адрес элемента массива вычисляется как БАЗА + Размерность1*Индекс1+размерность 2 правильное только в отношении статических массивов. Для динамических адрес элемента = Указатель[Индекс1]+Индекс2
PM MAIL ICQ   Вверх
archimed7592
Дата 18.4.2007, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(Anikmar @  18.4.2007,  22:04 Найти цитируемый пост)
Да нигде он не хранится!
а че ты мне это говоришь? я этого не утверждал... перечитай мой пост... там везде акцент на слово храниться в кавычках....
Цитата(Anikmar @  18.4.2007,  22:04 Найти цитируемый пост)
В случае динамического определения массива делают так:
это ты так делаешь...это уже массив указателей...
если же оставить обыкновенный двухмерный массив, то абсолютно ничего не изменится (кроме того, что адрес массива теперь будет лежать в определённой переменной):
Код
void f (int a [][5])
{
}

int main ()
{
    int a [10][5];
    f (a);
    
    int (*dynamic_arr)[5] = new int [10][5];
    f (dynamic_arr);
    
    return 0;
}


Добавлено @ 22:22
Цитата(Anikmar @  18.4.2007,  22:16 Найти цитируемый пост)
Для динамических адрес элемента = Указатель[Индекс1]+Индекс2 

для статических тоже:
Код
    int a [10][5];
    int *el_addr = a[3]+2;


Это сообщение отредактировал(а) archimed7592 - 18.4.2007, 22:24


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
vinter
Дата 18.4.2007, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



Цитата(MAKCim @  18.4.2007,  22:02 Найти цитируемый пост)
да не правдвумерный массив N x M (type array[N][M]) - это одномерный массив длины N * M, и доступ к элементу (i, j) осуществляется как array + i * M + j

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


--------------------
Мой блог
PM MAIL WWW   Вверх
archimed7592
Дата 19.4.2007, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(vinter @  18.4.2007,  23:08 Найти цитируемый пост)
то что в памяти он лежит линейно, ни о чем не говорит, двумерный массив, это массив, в котором каждый элемент является массивом
с этим полностью согласен...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Anikmar
Дата 19.4.2007, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(archimed7592 @  18.4.2007,  22:19 Найти цитируемый пост)
это ты так делаешь...это уже массив указателей...

А как динамический двумерный массив создаете вы? Есть принципиально другой метод? (без шаблонов, разумеется) Чтобы потом обращаться к нему с помощью стандартного синтаксиса?
PM MAIL ICQ   Вверх
archimed7592
Дата 19.4.2007, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(Anikmar @  19.4.2007,  08:46 Найти цитируемый пост)
А как динамический двумерный массив создаете вы?
ну я ж тебе показал... могу ещё раз:
Код
const int fixed_dimension = 5;
int denamic_dimension;
std::cin >> dynamic_dimension;
int (*dynamic_arr)[fixed_dimension] = new int [dynamic_dimension][fixed_dimension];

суть то не в этом smile
суть в том, что двумерный массив, вне зависимости от его месторасположения (automatic/static/dynamic storage duration), передают в ф-цию одинакового...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
HappyLife
Дата 19.4.2007, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Спасибо братки) Поддержали smile 

Это сообщение отредактировал(а) HappyLife - 19.4.2007, 09:21
PM MAIL   Вверх
Anikmar
Дата 19.4.2007, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(archimed7592 @  19.4.2007,  08:52 Найти цитируемый пост)

ну я ж тебе показал... могу ещё раз:
const int fixed_dimension = 5;
int denamic_dimension;
std::cin >> dynamic_dimension;
int (*dynamic_arr)[fixed_dimension] = new int [dynamic_dimension][fixed_dimension];


Упс. Чего то я не понял. 
Это же не динамический двумерный массив. Это получится динамический массив массив из 5 фиксированных элементов - по сути одномерный, если рассматривать массив из 5 элементов как отдельный тип данных.

А каким образом вы создадите динамически двумерный массив, где оба измерения динамические?

Цитата(archimed7592 @  19.4.2007,  08:52 Найти цитируемый пост)
суть то не в этом 
суть в том, что двумерный массив, вне зависимости от его месторасположения (automatic/static/dynamic storage duration), передают в ф-цию одинакового... 

Это естественно. Главное знать границы

PM MAIL ICQ   Вверх
MAKCim
Дата 19.4.2007, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(vinter @  18.4.2007,  23:08 Найти цитируемый пост)
нет, прав! то что в памяти он лежит линейно, ни о чем не говорит, двумерный массив, это массив, в котором каждый элемент является массивом, и не спорь пожалуйста, это голая теория и с ней спорить не надо

ну раз теория, тогда каждый элемент в двумерном массиве является просто элементом определенного типа, а не массивом как сказал ты, это раз
во-вторых массив - понятие обобщенное, одномерный, двумерный и т.д массивы - частные случаи массива как линейной последовательности элементов, на которой можно задать функции вида F(i): X -> Y(i), где i - количество индексов, X - исходная последовательность, Y - функция от количества индексов в массиве
т. е F(2) = X -> Y(2) (каждому элементу из X поставим в соответствие элемент из Y(2) = {a1 * N2 + a2}, где N2 - вторая размерность массива, a1, a2 - индексы), аналогично, F(3) = X -> Y(3) (Y(3) = {a1 * N3 + a2 * N2 + a3}), продолжая, получим
Y(i) = {a1 * Ni + a2 * Ni-1 + ... + ai}


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
betal
Дата 19.4.2007, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Voldemar2004 @  18.4.2007,  22:07 Найти цитируемый пост)
Это мы представляем двумерный массив в виде таблицы, а 3-хмерный в виде куба, а ведь это одномерный вектор памяти, так ?

Он располагается в физической памяти как одномерный массив. Ибо по другому он не умеет.
Суть только в адресах. И в адресах которые хранят указатель на другие адреса.
Дабы правильно увидеть это представляй его в виде таблици или куба.  smile 
--------------------
101100010100001101100001110100101111011легкие деньги
PM WWW ICQ   Вверх
Anikmar
Дата 19.4.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Что-то на счет теории я недопониаю. Существует отдельная теория о массивах?
Например в языке Бейсик прямо в описании языка говорилось, что двумерный массив представляет собой большой одномерный.
А в описании Си говорится, что многомерный массив - это массив массивов и совсем необязательно, что он занимает единый блок памяти.

Тут речь идет не о теории, а о конкретной реализации способа хранения многомерных массивов. В языке Си их по сути 2. Но смысл массива от этого не меняется.
PM MAIL ICQ   Вверх
archimed7592
Дата 19.4.2007, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(Anikmar @  19.4.2007,  09:33 Найти цитируемый пост)
А каким образом вы создадите динамически двумерный массив, где оба измерения динамические?
Цитата(Anikmar @  19.4.2007,  09:33 Найти цитируемый пост)
Это естественно.

вот и славненько smile
ты наверное забыл с чего всё началось smile :
Цитата(betal @  18.4.2007,  21:36 Найти цитируемый пост)
а в случаи если массивы находятся в Динамической памяти то






--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
betal
Дата 19.4.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Начнем с того в чем разница между переменной и массивом ?!?
В том что массив хранит в себе массив переменных одного типа.

Что-то тип того по имени мы получаем доступ к началу (адресу) первого элемента массива. А номер уже указывает на адресс массива + его порядковый номер в этом массиве

--------------------
101100010100001101100001110100101111011легкие деньги
PM WWW ICQ   Вверх
archimed7592
Дата 19.4.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(Anikmar @  19.4.2007,  09:42 Найти цитируемый пост)
В языке Си их по сути 2. Но смысл массива от этого не меняется. 
второй, это надо понимать массив указателей? тогда, имхо, смысл меняется, хоть и работа с ним выглядит также(но не всегда - передача в ф-цию к примеру)

Добавлено через 1 минуту и 21 секунду
Цитата(betal @  19.4.2007,  09:51 Найти цитируемый пост)
Начнем с того в чем разница между переменной и массивом ?!?
массив - это тип... абстракция... переменная - сущность...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
HappyLife
Дата 19.4.2007, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Давайте закончим сыр бор на пустом месте.
Ведь достаточно открыть Страуструп 3 издание, приложение B раздел 7. Где все это описано.
PM MAIL   Вверх
betal
Дата 19.4.2007, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(HappyLife @  19.4.2007,  09:59 Найти цитируемый пост)
Давайте закончим сыр бор на пустом месте.
Ведь достаточно открыть Страуструп 3 издание, приложение B раздел 7. Где все это описано. 

 smile 
--------------------
101100010100001101100001110100101111011легкие деньги
PM WWW ICQ   Вверх
MAKCim
Дата 19.4.2007, 10:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(Anikmar @  19.4.2007,  09:42 Найти цитируемый пост)
Тут речь идет не о теории, а о конкретной реализации способа хранения многомерных массивов. В языке Си их по сути 2. Но смысл массива от этого не меняется. 

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


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

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


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(HappyLife @  19.4.2007,  09:59 Найти цитируемый пост)
едь достаточно открыть Страуструп 3 издание, приложение B раздел 7. Где все это описано. 
это там ты вычитал про то, что в a[i] хранится указатель? smile 


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Anikmar
Дата 19.4.2007, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Цитата(archimed7592 @  19.4.2007,  09:46 Найти цитируемый пост)
вот и славненько 
ты наверное забыл с чего всё началось  :
Цитата(betal @  18.4.2007,  21:36 )
а в случаи если массивы находятся в Динамической памяти то


Вовсе нет, я имею в виду 2 способа хранения. Если честно, я не лез в ассемблерный код, к какому общему виду приводит компилятор работу с массивом, но думаю все-таки к варианту динамического создания. Я говорю про способ извлечения конкретного элеменгта массива.

Допустим мы имеем статический массив
int a[4][6];

Потом получаем доступ к элементу:
a[2][3] = 1;

Как компилятор получает доступ к такому элементу? Если рассматривать массив как единый блок памяти, то очень просто:
a + (6 * 2) + 3; - Получаем адрес искомого элемента

Если рассуждать с точки зрения массива указателей, то алгоритм рассчета несколько другой (тоже очень просто):
a[2] + 3;

Я на 99% уверен, что компилятор в конечном итоге рассчитывает адрес именно по второму способу - так как он более общий. А в случае статического массива указатели физически хранить не надо, а их можно вычислить.

Цитата(archimed7592 @  19.4.2007,  10:07 Найти цитируемый пост)
это там ты вычитал про то, что в a[i] хранится указатель?   

А по вашему что там?
int a[3][4];
int *p;

p = a[2];

Какое значение получит p, как не указатель? Другой вопрос, что физически он может там и не храниться.


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


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(Anikmar @  19.4.2007,  10:11 Найти цитируемый пост)
что физически он может там и не храниться.
ну эт типа сказать, что sum(2,3) хранит число 5...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 19.4.2007, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(Anikmar @  19.4.2007,  10:11 Найти цитируемый пост)
Я на 99% уверен, что компилятор в конечном итоге рассчитывает адрес именно по второму способу - так как он более общий

про все компиляторы говорить не буду, но GCC использует первый способ для первого случая


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
betal
Дата 19.4.2007, 10:19 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Anikmar @  19.4.2007,  10:11 Найти цитируемый пост)
А по вашему что там?
int a[3][4];
int *p;

p = a[2];

Какое значение получит p, как не указатель? Другой вопрос, что физически он может там и не храниться.

А при чем это здесь? Вы говорите о указателе? Если ДА ?! ТО Общий вид будет примерно таков
*(p+2); - это в случаи если массив одномерний 
а здесь будет немного другой вид

Добавлено через 30 секунд
Цитата(archimed7592 @  19.4.2007,  10:16 Найти цитируемый пост)
ну эт типа сказать, что sum(2,3) хранит число 5... 

 smile 
--------------------
101100010100001101100001110100101111011легкие деньги
PM WWW ICQ   Вверх
Anikmar
Дата 19.4.2007, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Я про это и говорю. 
В случае с двумерными массивами по первому измерению находятся именно указатели. И необязательно подряд. Храняться они там или вычисляются по ходу пьесы зависит от способа объявления массива не более того.
PM MAIL ICQ   Вверх
dizzy1984
Дата 19.4.2007, 11:49 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Предложенные варианты
Код

void f (arr[y][x]);

и
Код

void f (arr[][x]);

имеют один явный недостаток.
А именно в них нельзя передать автоматические массивы произвольной размерности.
Вы, конечно, можете возразить, что для таких случаев есть динамическая память.
Я согласен. Но она неудобна тем, что ее надо еще не забыть освободить.
Я хочу долнить следующим вариантом:
Код

void f(int * arr, int m)

где m - количество элементов в строке матрицы.
Однако адресация внутри функции f при таком варианте изменится
с 
Код

arr[a][b] 

на 
Код

arr[a*m+b]


Ну и не могу не вмешаться.
Часть неразберихи вызвана путаницей.
Я вижу 3 ветки обсуждений :
1. Что такое статический и динамический двумерный массив в понимании c++.
2. Что такое одномерная и двумерная матрица в линейной алгебре.
3. Что такое статический и динамический двумерный массив в понимании мэнэджера памяти с++.
Нельзя сравнивать вещи из разных "веток" обсуждений.

Это сообщение отредактировал(а) dizzy1984 - 19.4.2007, 11:53
PM MAIL   Вверх
Anikmar
Дата 19.4.2007, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Мой вариант:

Массив динамический, размерность - любая
Код

void f(int **var, int xsize, int ysize)


Доступ к элементу массива - как обычно var[a][b]

PM MAIL ICQ   Вверх
vinter
Дата 19.4.2007, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

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



MAKCim, игра слов. Я еще раз повторяю, допустим мне плевать как они расположены в памяти, и если структурно изобразить как выглядит двумерный массив, то будет именно массив массивов, а на то как оно лежит в памяти и какие формулы используются для преобразования индексов, мне глубоко фиолоетово. А чтобы не было непоняток, так открой любую книгу по С/С++ и посмотри что там написано, нигде не обьясняется так как написал ты. Просто надо уметь признавать свою неправоту, чего от тебя я не заметил за все мое существование на этом форуме


--------------------
Мой блог
PM MAIL WWW   Вверх
archimed7592
Дата 19.4.2007, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

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



Цитата(dizzy1984 @  19.4.2007,  11:49 Найти цитируемый пост)
А именно в них нельзя передать автоматические массивы произвольной размерности.

Код
template <typname DoublyDerereferencable>
void f (DoublyDerereferencable var, int xsize, int ysize)
{
var [xsize - 1][ysize - 1] += 10;
}
передавай, что душе угодно


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
neosapient
Дата 19.4.2007, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Задал простой вопрос, так все стали флудить вокруг да около... :( 
Устал читать

В понимании языка С/С++ двумерный массив это массив массивов, то есть массив указателей на массивы. 
Я думаю многие работали на Бейсике (хотя бы в школе), в котором двумерный массив это единый участок в памяти
если приветси псевдокод
Mas = array [Y][X]
0 < i < X 
0 < j < Y
То благодоря последовательному размещению в памяти можем обратиться к ячейке памяти
Mas[j][i] == Mas[1][(j-1)*X+i]


Возвращаясь на язык С/С++
Буду рассматривать именно бейсиковский двумерный массив
Mas[j][i]
*(Mas+j)[i]
*(*(Mas+j)+i)
-----
int(  Mas+j*X+i  )
Mas[0][j*X+i]

Проблема в другом
Необходимо правильно указать компилятору, что передается указатель(4-х байтный адрес)начала массива массивов

Как правильно преобразовать тип из бейсиковского двумерного массива [][] к указателю **

Это сообщение отредактировал(а) neosapient - 19.4.2007, 14:19
PM MAIL   Вверх
neosapient
Дата 19.4.2007, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Короче, воспользовался 
int Mas[Y][X]
int* pMas = (int*)Mas;
обращение к ячейки
*(  Mas+j*X+i  )


А все навороты делает компилятор

Логически разницу между бейсиковским и сишным двумерными массивами могу сравнить с борьбой конструкций IF...THEN...ELSE   и   SWITCH...CASE...BREAK
Я имею в виду (для тех немногих, что не знают), что при использовании  SWITCH...CASE...BREAK компилятор не преобразует к дереву из элементов IF...THEN...ELSE, а создает сводную таблицу переходов...
PM MAIL   Вверх
likehood
Дата 19.4.2007, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

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



neosapient, делай так:
Код

void func(int* a, int nStr, int nCol)
{
    for (int i=0; i<nStr; i++)
    {
        for (int j=0; j<nCol; j++)
            printf("%d", a[i*nCol+j]);
        printf("\n");
    }
}

int main()
{
    int arr[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    func((int*)arr, 3, 3);
    return 0;
}


Добавлено через 1 минуту и 33 секунды
смотрю, так и сделал smile
PM MAIL   Вверх
Anikmar
Дата 19.4.2007, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

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



Добавлю.
Так передавать можно только статический массив или динамический, созданный как одномерный. 
PM MAIL ICQ   Вверх
MAKCim
Дата 19.4.2007, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(vinter @  19.4.2007,  12:08 Найти цитируемый пост)
Я еще раз повторяю, допустим мне плевать как они расположены в памяти, и если структурно изобразить как выглядит двумерный массив, то будет именно массив массивов, а на то как оно лежит в памяти и какие формулы используются для преобразования индексов, мне глубоко фиолоетово

заметь, в моем посте не было ни одного высказывания на тему того, как массив расположен в памяти
кроме того, изобразить можно все, что угодно как угодно, так что изображение двумерного массива (заметь, массива, а не массива массивов) в виде матрицы еще не говорит о том, что это массив массивов
матрица - это всего лишь одна из форм описания таких вещей
Цитата(vinter @  19.4.2007,  12:08 Найти цитируемый пост)
А чтобы не было непоняток, так открой любую книгу по С/С++ и посмотри что там написано, нигде не обьясняется так как написал ты

в книгах по С/С++ такое и не должно быть написано
Цитата(vinter @  19.4.2007,  12:08 Найти цитируемый пост)
Просто надо уметь признавать свою неправоту, чего от тебя я не заметил за все мое существование на этом форуме 

в чем я не прав по пунктам?

Это сообщение отредактировал(а) MAKCim - 19.4.2007, 19:11


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
nerezus
Дата 20.4.2007, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


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

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



Цитата

о есть sizeof(arr[0][0] / sizeof(int)) выдаст количество элементов в строке
 неа, sizeof приводится к константе на этапе компиляции.

Цитата

заметь, в моем посте не было ни одного высказывания на тему того, как массив расположен в памяти
 А разве элементы расположены не подряд? Нас учили, что ВСЕГДА подряд.


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
Xenon
Дата 20.4.2007, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



nerezus, какая разница принципиальная?


--------------------
user posted image  
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1129 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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