Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Динамическое создание двумерного массива  (Прочитано 28822 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Fatal Error
Гость
« : 06-11-2003 22:21 » 

Здравствуйте всем кто суда заглянул, ныне сабж такой:

Меня интересует как создать динамически двух мерный массив, то есть типа кого:
Код:
double* M = new double[size_x][size_y]; // псевдо код :(
M[9][5]; // ошибка

Одномерный создается без проблем. Пробовал я с помощью вектора (**), компилятор не писал об ошибки в следующем коде во второй строке:
Код:
double** M = new double*[size_x*size_y];
M[9][5];
- но при работе программы выдавалось сообщение об ошибки обращения к памяти Жаль.

Может я что-то упускаю и не замечаю, как сделать это :?:

P.S.:  Чтоб было более понятно скажу, что мне надо написать класс матрицы.
« Последнее редактирование: 20-11-2007 18:24 от Алексей1153++ » Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #1 : 06-11-2003 23:34 » 

Fatal Error, Ник у тебя Улыбаюсь странный для программиста...

 Ага
Записан

А птичку нашу прошу не обижать!!!
Xeysan
Гость
« Ответ #2 : 06-11-2003 23:40 » 

Цитата
Одномерный создается без проблем. Пробовал я с помощью вектора (**), компилятор не писал об ошибки в следующем коде во второй строке:
Код:
double** M = new double*[size_x*size_y];
M[9][5];
Плохо, что перестают учиться языку С, тогда не было таких то вопросов...
Ты выделяешь память под size_x*size_y указателей на double, а на что указывают они - неизвестно... Попробуй так:
Код:
double **M = new *double[size_x]; // Вертикаль
for( int i = 0; i < size_x; i++ )
         M[i] = new double[size_y]; // Для каждой строки
« Последнее редактирование: 20-11-2007 18:24 от Алексей1153++ » Записан
Serega
Гость
« Ответ #3 : 07-11-2003 07:39 » 

Вот кое-что написал с утреца
Код:
#include <iostream>
#include <map>

using namespace std;

template <class value_type>
class Indexer
{
public:
typedef map<int,value_type> container_type;
typedef typename container_type::iterator container_iterator;

Indexer(container_type& cont) : c(&cont) {}
Indexer(const Indexer& other) : c(other.c) {}

value_type& operator[](int n) { return (*c)[n]; }

container_iterator begin() { return c->begin(); }
container_iterator end() { return c->end(); }

private:
container_type* c;
};

template <class value_type>
ostream& operator<<(ostream& os,Indexer<value_type>& indexer)
{
Indexer<value_type>::container_iterator begin = indexer.begin();
Indexer<value_type>::container_iterator end   = indexer.end();
for(; begin != end; ++begin) os << begin->second << " };
return os;
}

template <class value_type>
class Matrix
{
public:
typedef map<int,value_type> innner_container;
typedef map<int,innner_container> container_type;
typedef typename container_type::iterator container_iterator;

typedef Indexer<value_type> indexer;

indexer operator[](int n) { return c[n]; }

container_iterator begin() { return c.begin(); }
container_iterator end() { return c.end(); }

private:
container_type c;
};

template <class value_type>
ostream& operator<<(ostream& os,Matrix<value_type>& map)
{
Matrix<value_type>::container_iterator begin = map.begin();
Matrix<value_type>::container_iterator end   = map.end();
for(; begin != end; ++begin)
{
os << Matrix<value_type>::indexer(begin->second) << "\n";
}
return os;
}

int main(int argc, char* argv[])
{
Matrix<int> m;

m[1][2] = 3;
m[2][1] = 2;

cout << m;

return 0;
}
« Последнее редактирование: 20-11-2007 18:27 от Алексей1153++ » Записан
Serega
Гость
« Ответ #4 : 07-11-2003 07:40 » 

достаточно простая реализация разреженной матрицы
доделать вывод на экран и можно сдавать Отлично
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 07-11-2003 09:25 » 

Цитата: Гром
Fatal Error, Ник у тебя Улыбаюсь странный для программиста...
 Ага

Отлично  Отлично

Ну почему же странный, всё сразу ясно, а то вон Серёга его сразу шаблонами загрузил.   Ага  Ага

Fatal Error, а как ты себе это представляешь? Массив в С++ - это непрерывный поток элементов, доступ на любой элемент которого вычисляется по указателю на первый элемент плюс номер элемента. Поэтому С++ фактически не поддерживает двумерные массивы. А делает из них одномерный * одномерный.

Так что:
Код:
double **M = new double*[size_y];
for(int i=0; i<size_y; i++) M[i] = new double[size_x];
Таким образом доступ типа M
  • [y]  преобразуется в *(*(М+y)+x)

А вообще то - если надо просто лабу сдать, то сделай как Серёга показал. Только сначала разберись. Ага
« Последнее редактирование: 20-11-2007 18:29 от Алексей1153++ » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #6 : 07-11-2003 09:26 » 

Xeysan, правильно говоришь.
Записан

А птичку нашу прошу не обижать!!!
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #7 : 07-11-2003 09:27 » 

Джон, думаешь, что не зря такой ник ? Ага
Записан

А птичку нашу прошу не обижать!!!
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 07-11-2003 09:59 » 

Блин! А? Всё ухожу нафиг с форума :twisted: !!! Нефиг мне тут делать. Совсем ослеп!
Как я ответ Xeysan просмотрел?

Цитата: Гром
Xeysan, правильно говоришь.


Только сейчас увидел. А он то уже ответил. Даже код почти один в один написал.

Так что простите если можете и... не поменайте лихом.  Эх
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 07-11-2003 10:07 » 

Цитата: Гром
Джон, думаешь, что не зря такой ник ? Ага


"Что в имени тебе моём?" Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #10 : 07-11-2003 11:32 » 

Джон, ты эта - стой! Раз, Два. Куда , Куда - вернись я все прощу !!!!  Ага
Записан

А птичку нашу прошу не обижать!!!
Fatal Error
Гость
« Ответ #11 : 07-11-2003 16:23 » 

Я суда пришел не для того, чтоб мой ник обсуждали.

Serega << Спасибо, но слишком громоздко и не удобно. Лучше применять коллекции и итераторы, но в данном случае я хотел обойтись без них.

Xeysan << Замечательно, хороший способ, жаль сам не догадался, спасибо.
Записан
Xeysan
Гость
« Ответ #12 : 07-11-2003 16:28 » 

Всегда рад Улыбаюсь
Записан
Xeysan
Гость
« Ответ #13 : 07-11-2003 16:45 » 

Кстати, прошу прощения за ошибку.  :oops:  Писать нужно
Код:
double **M = new double*[size];
« Последнее редактирование: 20-11-2007 18:33 от Алексей1153++ » Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #14 : 07-11-2003 16:53 » 

Fatal Error,
Цитата

Я суда пришел не для того, чтоб мой ник обсуждали.

Извини, если обидел  Жаль не хотел  Ага просто мы веселые  Ага

Для удобства обращения к человеку у нас сделано так:
Кликаешь на ник человека к кому обращаешься в текущей теме и вот так как я к тебе обратился - получается автоматом - очень удобно.


Ты + Xeysan, надеюсь нашему полку прибыло!  :!:
Записан

А птичку нашу прошу не обижать!!!
Sashok
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #15 : 07-11-2003 18:16 » 

Цитата: Xeysan
Плохо, что перестают учиться языку С, тогда не было таких то вопросов...
Ты и прав и не прав.
Я много раз встречал людей, которых 2 семестра учили С и С++ и так и не объяснили, что a[5][2]это то же самое, что и *(*(a+5)+2). А уж если кому напишешь 3[ x] вместо x[3], так вообще говорят, что такого не может быть. А все потому, что С, фактически, опускают, начиная изучение со стандартной библиотеки шаблонов (STL). То есть, формально, С в программе есть (тут ты не прав Жжешь ), а фактически - нет (тут ты прав Жжешь ).

Цитата: Джон
Ну почему же странный, всё сразу ясно, а то вон Серёга его сразу шаблонами загрузил.   Ага  Ага
Вопрос этой темы, кстати, является еще одним аргументом в пользу того, что начинать изучать C++ надо с С, а не с шаблонов.
« Последнее редактирование: 20-11-2007 18:36 от Алексей1153++ » Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
Xeysan
Гость
« Ответ #16 : 08-11-2003 00:08 » 

Цитата

Вопрос этой темы, кстати, является еще одним аргументом в пользу того, что начинать изучать C++ надо с С, а не с шаблонов.

Совершенно согласен. Только не с С, а с Ассемблера :!:  Ага, с защищенного режима Отлично
Ну а насчет, того что там кто учил - это очень спорно, дело очень уж индивидуальное... Просто, для меня знания долго в голове не держаться, если я их не использую + должна быть связь с остальными темами... Программирование знанием языка не ограничивается...
Цитата

*(*(a+5)+2).

p.s. Некоторые мои знакомые до сих пор так пишут, хотя это некрасиво, опасно, и часто неэффективно
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #17 : 08-11-2003 07:23 » 

Xeysan, это опасно одинаково с a[5][3] и то и то обращается к тому-же отрезку памяти....

Красота - ИМХО  понятие относительное.
Эффективность тоже не причем - код ась получается похожий - счас не проверю - но думаю ты можешь сам создать листинг для 2-х случаев и посмотреть.

Просто запись *(*(a+5)+2) получается читаемой ного хуже и часто создает проблемы с пониманием кода.
Записан

А птичку нашу прошу не обижать!!!
Xeysan
Гость
« Ответ #18 : 08-11-2003 10:32 » 

Цитата

это опасно одинаково с a[5][3] и то и то обращается к тому-же отрезку памяти....

Конечно, все безопасно, если человек уверен в том, что пишет, и сейчас не три часа ночи... Улыбаюсь . Так действительно, безопасней, потому что не надо считать там скобки звездочки и тд
На счет эффективности - тоже не все так просто... Ты где проверять собрался, в VC? Ну так это привязка к конкретному ( очень неплохому  8) ) компилятору... А если ты в лесу Жжешь ?
Я имел в виду, что запись a[5][2] сразу говорит, что кому нужно, без всяких там ступеней и тд...
зы. Не воспринимай мои слова буквально, в С(++) не очень то все и стандартно и четко ( IMHO ), ну где например сказано, что int - 4 байта
Записан
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #19 : 08-11-2003 10:49 » 

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

Эффективность - работа с указателями - это С (без ++) и там все равно абсолютно какой лес - лиственный или хвойный...
Конечно реализации будут разные - но тут не принципиально. Скорость обращения к указателю со смещением или смещение в массиве относительно указателя Улыбаюсь

А вот то что ты пишешь - это касается только читабельности и проверки компайлером синтакиса. При записи как массива, получается ошибки твои будет проверять компайлер , а при путанице с + - указателей - компилятор не проверит правильность вычислений и колличества звездочек - будето общаться с тем что есть... Дык это я так и сказал.

А 3 часа ночи - ну так что же Улыбаюсь бывает и мы сидим до утра   Вот такой я вот
Записан

А птичку нашу прошу не обижать!!!
Xeysan
Гость
« Ответ #20 : 08-11-2003 14:36 » 

Ну, меня поняли Улыбаюсь
Записан
Fatal Error
Гость
« Ответ #21 : 08-11-2003 19:39 » 

Xeysan <<[/b] Да, еще интересно как правильнее будет память освобождать от этого массива delete[] M - будет достаточно или по массиву пройтись придется :?: Думаю, что надо.

Гром <<[/b] Да, я не обижаюсь, просто есть люди которые по теме не говорят, а ники обсуждать любят, флеймеры короче, я обычно их топики сразу удаляю у себя в форумах.
Записан
Sashok
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #22 : 08-11-2003 21:11 » 

Fatal Error, безусловно прийдется пройтись по массиву. А после этого не забыть и delete[] M.

Чтобы раз и навсегда разобраться с подобными вопросами, помни основное правило: каждому new должен соответствовать свой delete, в точности с тем же адресом, причем только один раз.
Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
Xeysan
Гость
« Ответ #23 : 08-11-2003 21:59 » 

Кстати, прочитал я эту заметку, и вспомнился мне первый курс вуза... Как преподаватель освобождал память из-под дерева.
Код:
free( root );
Я шокирован!  Абсолютно серьезно!!! Жжешь  Отлично
« Последнее редактирование: 20-11-2007 18:40 от Алексей1153++ » Записан
Sashok
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #24 : 08-11-2003 22:39 » 

Цитата: Xeysan
Кстати, прочитал я эту заметку, и вспомнился мне первый курс вуза... Как преподаватель освобождал память из-под дерева.
Код:
free( root );
Я шокирован!  Абсолютно серьезно!!! Жжешь  Отлично
Отлично  Отлично  Отлично

Мне несколько раз приходилось натаскивать студентов с проблемами по С++. Я в таких случаях всегда прошу, чтобы мне принесли лекции и рекомендованные книги. Могу засвидетельствовать, что проблем с освобождением памяти у преподавателей полно.

При этом попробуй сам устройся преподавателем в хорошее место! Окажется, что бумажек не хватает, формального образования не хватает, зимою - лета, осенью - весны не хватает  Ха-ха-ха  А у тех преподавателей - всего хватает!!!

Извиняюсь за обилие восклицательных знаков - крик души, наболело.
« Последнее редактирование: 20-11-2007 18:44 от Алексей1153++ » Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #25 : 08-11-2003 23:15 » 

Цитата

Ну, меня поняли

В смысле?

Fatal Error,
Цитата

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


 Отлично  смотри счас тут тебе расскажут кто я тут  Ага
Шучу - адресок форумов приложи....

Sashok, ты прав - правда мне везло в основном... Но и такие были, что на вводной лекции пообещали учиться вместе с нами в результате у нас спрашивали как и что.  :twisted:
Записан

А птичку нашу прошу не обижать!!!
CrazyRabbit
Участник

il
Offline Offline

« Ответ #26 : 09-11-2003 12:20 » 

Цитата: Sashok
А уж если кому напишешь 3[ x] вместо x[3], так вообще говорят, что такого не может быть.

Привет всем.
Цитата
Мы все учились понемногу, чему-нибудь и как-нибудь...
Улыбаюсь В мою бытность студентом
Цитата
Мудрых преподавателей слушал я не внимательно...
, учился потом сам по книгам.
Так вот, в моих книгах по ANSI C сказано, например :
Цитата
Идентификатор. Последовательность букв, цифр и символв подчеркивания, начинающаяся с  буквы или символа подчеркивания, считается идентификатором языка Си.

Это ближайшая книга Подбельского и Фомина Программирование на языке Си
Сам ворос.
В какой реализации языка константа (целая десятичная, в данном случае) может использоваться в качестве идентификатора?
« Последнее редактирование: 20-11-2007 18:45 от Алексей1153++ » Записан
CrazyRabbit
Участник

il
Offline Offline

« Ответ #27 : 09-11-2003 12:27 » 

Можно, просто послать  Отлично , где об этом пишут.
Записан
Serega
Гость
« Ответ #28 : 09-11-2003 14:41 » 

Цитата: Sashok
А уж если кому напишешь 3[ x] вместо x[3], так вообще говорят, что такого не может быть.
На самом деле так писать не стоит, ничего хорошего по этому поводу компилятор не скажет, это не ассемблер, где такое допустимо
« Последнее редактирование: 20-11-2007 18:47 от Алексей1153++ » Записан
Anonymous
Гость
« Ответ #29 : 09-11-2003 16:54 » 

Цитата: Xeysan
Кстати, прошу прощения за ошибку.  :oops:  Писать нужно
Код:
double **M = new double*[size];

Ну хоть какое-то оправдание я себе нашёл Ага ,  ещё раз сорри за слепоту.

Джон
« Последнее редактирование: 20-11-2007 18:48 от Алексей1153++ » Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines