IPB
ЛогинПароль:

> Правила раздела!

1. Заголовок или название темы должно быть информативным !
2. Все тексты фрагментов программ должны помещаться в теги [code] ... [/code] или [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ" и используйте ПОИСК !
4. НЕ используйте форум для личного общения!
5. Самое главное - это раздел теоретический, т.е. никаких задач и программ (за исключением небольших фрагментов) - для этого есть отдельный раздел!

 
 Ответить  Открыть новую тему 
> Как создать резиновый массив?
сообщение
Сообщение #1


Гость






Синтаксиса не знаю, поэтому объясняю на пальцах:

массив[заранее_не_знаю_сколько_элементов]
i:=0
начало_цикла
 i:=i+1
 элемент_массива[i] = ввод_с_клавы(неск._букв)
 если элемент_массива[i] = 'особый_символ' то
   выйти из цикла
конец_цикла

Вопрос в том, как бы мне менять границы массива по ходу исполнения программы? Есть ли какие варианты? Может быть, использовать не массивы, а ещё что-то?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Бывалый
***

Группа: Пользователи
Сообщений: 156
Пол: Мужской

Репутация: -  0  +


В Дельфи легко, в Паскале - не помню - ввели они поддержку открытых массивов или нет. Если нет, то тогда нельзя, можно только через динамическое выделение памяти (оператор new)


--------------------
With the best regards Vit

Все всегда уезжают навсегда. Вернуться невозможно-вместо нас всегда возвращается кто-то другой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Новичок
*

Группа: Пользователи
Сообщений: 42

Репутация: -  0  +


В тмт есть open arrays
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






А что насчет new? Я бы непротив, да только непонятно как. В книжке написано, что массив все равно заранее надо определить.

Можно ли сделать что-то типа:

a:char;
j:=0;
repeat
 j:=j+1;
 ...
 new(i[j]));
 ReadLn(a);
 ...
until a='q'

Дело в том, что я к динамической памяти обратился сразу, но что-то несрослось. Как можно отодвигать с помощью new границу массива? Или можно создать с помощью new некую абстрацию типа, скажем, 3-х мерного массива?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 201

Репутация: -  0  +


В уроке про массивы на pascal.dax.ru посмотри, там есть динамическое выделение памяти под массивы.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Все, что я там понял, так это то, как создать массив, занимающий в памяти более сегмента. Это без проблем, согласен. Но массив, хоть и здоровый, все равно нужно объявить. Я же пытаюсь получить ответ на вопрос: как создать конструкцию, к которой можно обращаться с таким же удобством, как к массиву, и которая меняла бы количество своих элементов и границы по ходу программы? Просто скажите: "такое невозможно", и я отвяжусь, или процитируйте кусок кода, который был бы понятен дилетанту в паскале.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 282

Репутация: -  0  +


говоришь как изменить число элементов массива?
пишешь тип массива по максимуму(то есть с макс-ым числом элементов)удаляешь предыдущий потом создаёшь новый нужно размерности
(GetMem юзай)
при необходимости заполняешь его значениями из предыдущего массива
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Новичок
*

Группа: Пользователи
Сообщений: 38

Репутация: -  0  +


Что же до системы с New:
Значит так - каждый элемен массива должен распологаться динамически в памяти, и содержать в себе:
1. Само значение элемента (строка, число, не важно...)
2. Указатель, где в памяти находится следующий элемент.

Таким образом зная указатель на самый первый элемент массива можно прочитать и его значение, и узнать, где находится следующий элемент массива, и так до самого конца. Изменять размер массива можно динамически - это как open arrays, тоесть - хочешь - добавь в конец новый элемент, а в предыдущем укажи ссылку на него, хочешь, вставь между двумя элементами массива ещё один (из предыдущего сделай ссылку на него, а у него сделай ссылку на следующий). Важно, то что при таком методе необходимо в отдельной переменной хранить ссылку на самый первый элемент массива, иначе можно просто потерять весь массив в памяти :)
Вот тебе пример:
Код
Type
  PData = ^TData; {указатель на элемент массива}
  TData = record {Сам элемент массива}
     N: Longint; {Число - содержимое элемента}
     Next: PData; {Указатель на следующий элемент массива}
  End;
Var
 Temp,First: PData; {Два элемента, один из них для работы с текущим элементом, другой для указания, где начинается массив}
 p:word;
begin
 temp:=nil; {укажем, что первый элемент пока не заполнен}
 Repeat
    ReadLn(X);
    If X = 0 then Break; {Если мы ввели ноль, то всё.. больше элементов не надо}
    If temp = nil then {если это самый первый элемент, то...}
    begin
      New(temp); {Создадим его}
      first:=temp; {Запомним где он находится в first}
    end else {Иначе это уже не первый}
    begin
      New(temp^.Next); {Создадим новый}
      temp:=Temp^.next; {Перенесёмся в него. temp теперь уже новый}
    end;
    temp^.N := X; {Занесём в него значение}
    data^.Next := nil; {Укаджем, что следующего ещё нет}
 Until False;
 {Теперь выведем все значения, чтоб тебе было более понятно}
 temp:=first; {Установим первый элемент}
 p:=0; {Номер текущего элемента}
 while temp<>nil do {Пока мы находим элемент}
 begin
   inc(p); {наращиваем номер текущего элемента}
   writeln('a(',p,')=',temp^.N); {выводим его}
   temp:=temp^.Next; {Переносимся в следующий элемент}
 {Если следующий элемент nil, то temp тоже странет nil, и цикл while закончится}
 end;
end.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Бывалый
***

Группа: Пользователи
Сообщений: 282

Репутация: -  0  +


Some1:
хе односвязный список проповедуешь,
фигня он)слишком маленькая скорость доступа
хотя для мелких массивов это не заметишь
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Новичок
*

Группа: Пользователи
Сообщений: 38

Репутация: -  0  +


Я не проповедую,  и не большой любитель односвязный массивов. Просто даю человеку необходимую информацию.
Если ты посмотришь на первое сообщение, то там у него в предпологаемом алгоритме присутствует ввод с клавиатуры, который я думаю уже предплолгает, что массив будет "относительно" не большой.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Я это делал так:
прописываешь процедуру, а в ее var-е создаешь массив от 1 до какого-то n, которое вводишь как параметр процедуры.
Обычно работало, но только все равно остаеться ограничение памяти.
8)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Ищущий истину
******

Группа: Пользователи
Сообщений: 4 825
Пол: Мужской
Реальное имя: Олег

Репутация: -  45  +


Резиновым массивом иногда называют динамические структуры данных: стеки, очереди и т.д
если неизвестно, сколько элементов будет, лучше использовать однонаправленный список.


--------------------
Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Зачем самим мучаться с динамическим выделением памяти, когда есть все готовое? Просто работай с массивом как с коллекцией: тип TCollection модуля Objects. Очень мощная штука.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Прогрессор
****

Группа: Пользователи
Сообщений: 602
Пол: Мужской
Реальное имя: Михаил

Репутация: -  9  +


Да, с обычным массивом такое делать нельзя. С динамическим , по-моему, тоже. Разве что каждый раз, когда надо менять размер массива, создавать новый и копировать в него влезшие элементы старого smile.gif . В голову лезут всякие списки, стеки,... деревья smile.gif . Пожалуй, есть одна более подходящая идея: реализовать многомерный динамический вектор. Это указатель на массив примерно [0..9] указателей на массив [0..9] указателей... ...на массив [1..10] элементов. Должно храниться общее число элементов. В таком n-мерном векторе может поместиться до 10^n элементов. Доступ, скажем, к 143-му элементу будет выглядеть p^[0]^[0]^[1]^[4]^[3]. Это будет намного быстрее, чем в списке. Памяти на вектор уйдёт больше, чем на обычный массив, но не так уж намного. Дело в том, что она не выделяется сразу для всех 10^n эл-тов, а по мере их добавления, так что, если не ошибаюсь, для хранения m элементов потребуется m div 10 + m div 100 +... + m div 10^(n-1) + n указателей. Менять границы можно new или delete соответствующего кол-ва указателей. Конечно, реализация несколько сложна, но всё вполне нормально пишется.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Профи
****

Группа: Пользователи
Сообщений: 930
Пол: Мужской

Репутация: -  11  +


Цитата(Tonic @ 19.02.03 13:06)
Как можно отодвигать с помощью new границу массива? Или можно создать с помощью new некую абстрацию типа, скажем, 3-х мерного массива?

Какая разница NEW, или что-то ещё? И разве без списков, коллекций, объектов нельзя написать прогу небольшого размера ;) Главное, чтобы доступ к памяти был, а уж для облекчения доступа к нему завсегда функцию написать можно. Самый прикольный вариант, когда для инициализации массива, изменения размеров, чтения, записи используется одна и та же функция smile.gif
Код

FUNCTION FDSGDS(FDS,POKE,PEEK:BYTE; ADREES:LONGINT):BYTE;
....................
BEGIN
CASE FDS OF
1: ................
2: ..................
3:..........................
4:................................
.....................
END;


Вместо не нужных параметров пишутся фиктивные - нули, или любой другой мусор. На какие параметры реагировать и какую продукцию выдавать smile.gif ф-ция решает исходя из ключа FDS - инициализирует или закрывает новые сегменты памяти, читает, записывает или форматирует диск ;) Конечно, преподы за такой подход голову оторвут, или что-нибудь ещё <_< Но штука прикольная и полиморфная.

ЗЫ: Без ГОТО такая конструкция выглядит как соль без сахара.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 




- Текстовая версия 16.12.2017 8:26
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"