То есть массив массивов из десяти целых. И в принципе его можно привести к типу ((int [10])*) или как там записывается указатель на массив из 10-ти целых.
> 1. В массиве int A[10][10] ,- является ли A типом (int **) > ? > (Я так понял, что не является ,- он у меня функциями void a > (int ** b) наотрез не принимается Если размер известен заранее, то лучше передавать int b[][10] - все будет работать, если же нет, то выход для C - передавать двойной указатель и размерности (ну или засунуть тело массива и размерности в структуру и передавать везде указатель на нее) и ввести отдельную функцию индексирования этого массива. Ну или сделать массив указателей на одномерные массивы, как в последующем примере (который GG).
> и кроме того я последовательно память просмотрел ,- мой > вывод - массив размещен последовательно) :-)))) А что ты ожидал увидеть? :-)
> В конечном счете мне нужно было динамически выделить int > A[10][10]. > Как я понял new может выделить только последовальную > область, поэтому пришлось бы самому A[a][a*10+b];
> int ** GG, ee=0; > GG = new (int *) [10]; > while (ee<10) GG[ee++] = new int [10]; Это один из самых распространенных способов.
Использование new, говорит об использовании C++, а там есть куча хороших контейнеров. Например vector. Об этом позже.
> Странно, но это у меня работает как int GG[10][10], т. е. > как аналог int A[10][10], при том, что и void a (int ** b) > его принимает. Не странно.
> Я в принципе не до конца понимаю ситуацию, поэтому > расчитываю, что вы что-нибудь умное скажите и у меня все > станет на свои места. В C многомерный массив трактуется как массив массивов. Первое индексирование находит нужный одномерный массив, а второе - нужный элемент в этом массиве.
Чтобы лучше понять, что происходит, представь себе массив структур
struct S{
int a1;
int a2;
int a3;
int a4;
int a5;
};
struct S arr[5];
---
В памяти последовательно будут размещаться все эти структуры. Массив массивов не имеет принципиального отличия. int a[5][10] читается как (int a[10])[5]. И в памяти последовательно размещаются пять десятимерных массивов (именно так, потому как у скобок свой приоритет при составлении типа).
Операция a[i] - взятие индекса в C выполняется как взятие нужных данных по смещению (sizeof(*a) * i) от начала массива, то есть длина одной записи в массиве умножается на индекс.
В случае с int **a - невозможно определить размер второй размерности массива, вернее возможно, он равен 1 - поэтому компилятор и говорит о несоответсвии типов. Случай с массивом указателей работает потому, что все массивы одномерные: одномерный массив указателей на строки и по одномерному массиву с элементами каждой строки. Массив указателей можно имеет тип (int *)[], а его можно передавать как (int **)
> Что по этому поводу говорит стандарт языка C/C++ > и как решаются проблемы с динамическими многомерными > массивами (предполагаю, что все решается как-то более > элегантно) ? Используй vector<vector<int>>. Его описание есть и в MSDN и во всех описаниях STL.
Или остановись на массиве указателей на строки
ЗЫ: Смешение стилей программирования - не очень хорошая идея (в частности использование new в явно C-style программе). У C есть своя функция для выделения памяти: malloc, а new предназначена не для выделения памяти, а для создания объектов.
1. В массиве int A[10][10] ,- является ли A типом (int **) ?
(Я так понял, что не является ,- он у меня функциями void a (int ** b) наотрез не принимается
и кроме того я последовательно память просмотрел ,- мой вывод - массив размещен последовательно)
В конечном счете мне нужно было динамически выделить int A[10][10].
Как я понял new может выделить только последовальную область, поэтому пришлось бы самому A[a][a*10+b];
int ** GG, ee=0;
GG = new (int *) [10];
while (ee<10) GG[ee++] = new int [10];
Странно, но это у меня работает как int GG[10][10], т. е. как аналог int A[10][10], при том, что и void a (int ** b) его принимает.
Я в принципе не до конца понимаю ситуацию, поэтому расчитываю, что вы что-нибудь умное скажите и у меня все станет на свои места.
Что по этому поводу говорит стандарт языка C/C++
и как решаются проблемы с динамическими многомерными массивами (предполагаю, что все решается как-то более элегантно) ?
2. Если кто реализовывал алгоритм разгадывания "японского кросворда" (числа преобразовывать в картинки)
(делали это простым перебором или логическим анализом).
> Легче свой один маленький клас написат, > если ето единственое использование Это оно сейчас единственное. А через год может быть уже не единственное. А STL как раз на масштабируемость упирает.
Не обобшай15.10.03 19:29 Автор: sem4a Статус: Незарегистрированный пользователь
> > На фига писать свой класс-массив, если в STL уже все > есть. > > STL плохая библиотека, много memory leaks, но удобная В STL (да и вообще при использовании шаблонов) инстанцируется только то, что используется. Не думаю, что в реализации vector::vector и vector::operator[] так уж много ликов. Даже в MSVC6. А в данном случае именно эта функциональность нужна.
> > В какой именно <б>реализации</б> STL много > > меморы леакс? ;) > > VC++ 6.0 SP 5 бееееееееее....
А я-то думал что-то новое... Ну что сказать, это одна из самых печальных реализаций STL, которые я видел :) (кстати, сервис-паки на этот предмет не слишком помогают).
Рекомендую STLPort либо (если по каким-то причинам хочется именно MS) STL из VC7, правда, если я не путаю, VC 6 она не собирается.
Никак.14.10.03 12:37 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman
Сам когда-то сталкивался с этой проблемой.
Метод, предлженный Вами, вполне работоспособен и ни чему не противоречит. Единственное, что он не удобен, поскольку требует создание и инициализацию массива указателей.
В оригинале, когда многомерный массив согдается не динамически, отводится память только под данные. Компилятор "знает" о размере строки и о количестве столбцов и генерит соответствующий код.
На сколько я знаю ни в каком из стандартов С, ни в С++ не предусмотрен необходимый для этого оператор (динамически определяющий размерности массива для указателя).
Может помочь С++, только индексы придется передавать по-другому. Не array_ptr[ i ][ j ], а, например, array.ref( i, j ), где метод ref будет возвращать ссылку на элемент массива.
А все-таки было бы удобно, если бы в С эта возможность была бы предусмотрена, хотя по возможности следует вообще не прользоваться массивами. Но это уже философия.
а можно немного философии??15.10.03 22:28 Автор: zelych Статус: Member
Каким бы большим не был массив, его размера может не хватить.
Каким бы маленьким не был массив, обязательно найдуться неиспользуемые элементы.
Если задачу можно решить без массива, то так и следует поступить.
Пример: Напишите програмку, которая делает следующее - последовательно вводятся числа (количество введенных чисел немзвестно/неограничено), при вводе заранее оговоренного числа программа должна выдать второе по максимальности число (именно не самое максимальное, а второе по величине) и закончить работу.
Так и хочется завести массив, считывать циклически введенные числа в последовательные ячейки массива, при вводе ключевого числа вывалиться из цикла ввода, отсортировать массив и выдать значение второго элемента. Проблема в том, что надо обойтись без массива, поскольку количество введенных чисел неограничено.
Из ностальгии: Смотрел когда-то на исходники программы математического моделирования динамических систем, где под параметры звеньев и связей были отведены приличного размера массивы и понимал, что программа может столкнуться с проблемой нехватки свободных элементов массива при большом количистве исходных данных. Благо массивы были огромные, а задачи решались в основном элементарные. И програмка эта была очень жирная в памяти - очень неудобно было.
Разумеется исключением из этих правил будут являться хакерские задачи типа: решить систему из ЧЕТЫРЕХ линейных уравнений с ЧЕТЫРЬМЯ неизвестными матричным методом.
> Каким бы большим не был массив, его размера может не > хватить. > Каким бы маленьким не был массив, обязательно найдуться > неиспользуемые элементы.
кажется это основное свойство памяти - она частенько заканчивается..
а всякие списки и очереди здорово ударяют как по эффективности использования памяти, так и по производительности..
Интересно ;-)16.10.03 13:24 Автор: HandleX <Александр М.> Статус: The Elderman
> Пример: Напишите програмку, которая делает следующее - > последовательно вводятся числа (количество введенных чисел > немзвестно/неограничено), при вводе заранее оговоренного > числа программа должна выдать второе по максимальности > число (именно не самое максимальное, а второе по величине) > и закончить работу. > > Так и хочется завести массив, считывать циклически > введенные числа в последовательные ячейки массива, при > вводе ключевого числа вывалиться из цикла ввода, > отсортировать массив и выдать значение второго элемента. > Проблема в том, что надо обойтись без массива, поскольку > количество введенных чисел неограничено. Гы. Ну не знаю, мне не хочется ;-)
Program Sort;
Var aValue, Max, oldMax, stopValue: Integer;
Begin
Max := Low(Integer);
Write('Введите значение для остановки>');
ReadLn(stopValue);
Repeat
Write('Input value>');
ReadLn(aValue);
If aValue > Max Then
Begin
OldMax := Max;
Max := aValue;
End;
Until aValue = stopValue;
WriteLn('oldMax = ', oldMax, ', Max = ', Max);
WriteLn('Enjoy and good bye... There was no any arrays!');
End.