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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передать двумерный массив в функцию 
V
    Опции темы
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   Вверх
Страницы: (4) Все 1 2 [3] 4 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0628 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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