Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамический массив, Как расширить? 
:(
    Опции темы
Proxin
Дата 2.3.2010, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



делаю массив так:
Код

type ma:array[0..0] of integer;mp:^ma;
var m:mp;
begin
getmem(m,4*sizeof(integer));
// и так далее, данными заполняю.

А как добавить ещё одни элемент, чтобы размер массива стал на одни элемент больше? Пока придумал только делать через функцию со вторым вспомогательным массивом, но наверняка есть какой-то способ проще. Пишу на borland tp7.0.

Это сообщение отредактировал(а) Proxin - 2.3.2010, 15:41
PM MAIL   Вверх
ФедосеевПавел
Дата 2.3.2010, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 2
Всего: 10



Нет. Проще никак. Можно только выделять вспомогательный массив не на один элемент больше, а  с небольшим запасом (на 5, на 10, на 100).
PM   Вверх
Proxin
Дата 2.3.2010, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



это печально. получается, в турбе нет нормальных динамических массивов.
спасибо.
и ещё вопрос - как узнать индекс последнего элемента в массиве? high не подходит.

Это сообщение отредактировал(а) Proxin - 2.3.2010, 16:43
PM MAIL   Вверх
ФедосеевПавел
Дата 2.3.2010, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 2
Всего: 10



Но ты же сам его определяешь. Храни в отдельной переменной.
PM   Вверх
volvo877
Дата 2.3.2010, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



Proxin, больше НИКОГДА так не делай. Ты потерял возможность обращаться к какому-либо элементу дин.массива, отличному от 0, при включенном режиме {$R+} (а этот режим при отладке вообще не вздумай выключать, если хочешь, чтобы программа работала, и выдавала правильные, а не какие-попало результаты). Смотри:
Код
{$R+}
type
  ma = array[0..0] of integer;
  mp = ^ma;

var
  m: mp;
  i: integer;
begin
  getmem(m,4*sizeof(integer));
  for i := 0 to 3 do
  begin
    m^[i] := i;
  end;
end.
Должно работать, да? А не будет:
Код
Turbo Pascal  Version 7.0  Copyright (c) 1983,92 Borland International
Runtime error 201 at 0000:0040.
, потому как ты описал тип-массив с индексами от 0 до 0, и тут же выходишь за пределы диапазона.

Я делаю так:
Код
{$R+}
type
  T = integer;
  ma = array[0 .. pred(65520 div sizeof(T))] of T;
  mp = ^ma;
И волки сыты (имеешь возможность обращаться к любому элементу массива) и овцы - целы (Range Check не отключен, и позволит тебе ловить другие вылеты за границы диапазона в программе).

Добавлено через 10 минут и 18 секунд
Цитата(Proxin @  2.3.2010,  14:26 Найти цитируемый пост)
Пока придумал только делать через функцию со вторым вспомогательным массивом
Навскидку - как минимум два варианта, избавляющих тебя от доп. массива и постоянных перераспределений памяти:
1) напиши свою реализацию через связный список, тогда будешь добавлять/удалять элементы легко
2) воспользуйся TCollection для хранения данных вместо дин. массива.

Третий вариант (перейти на FPC, где динамические массивы, и не только, есть) не озвучиваю, хотя очень хочется smile
PM MAIL   Вверх
Proxin
Дата 2.3.2010, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Можно пример реализации через связанные списки, или где почитать?
PM MAIL   Вверх
Frees
Дата 5.3.2010, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



ma = array of integer;
и
SetLength()

или так только в делфи?

Это сообщение отредактировал(а) Frees - 5.3.2010, 23:29


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
volvo877
Дата 5.3.2010, 23:46 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 2
Всего: 116



Цитата(Frees @  5.3.2010,  22:29 Найти цитируемый пост)
или так только в делфи?
Так - в любом 32 битном компиляторе. В Turbo Pascal-е вот так:
Код
type
  T = integer;

type
  ptlistitem = ^listitem;
  listitem = object
    info : record
      index: integer;
      value: T;
    end;
    next : ptlistitem;

    constructor init(the_index: integer);
    destructor done;
  end;

  tdynarr =
  object
  private
    len: integer;
    head, tail: ptlistitem;
    function At(atIndex: integer): ptlistitem;
    procedure append;

  public
    constructor init;
    destructor done;

    procedure put(atIndex: integer; value: T);
    function get(atIndex: integer): T;

    procedure setlength(the_len: integer);
  end;

constructor listitem.init(the_index: integer);
begin
  info.index := the_index; info.value := 0;
  next := nil;
end;
destructor listitem.done;
begin end;


constructor tdynarr.Init;
begin
  head := nil; tail := nil;
  len := -1;
end;
destructor tdynarr.Done;
var p, pt: ptListItem;
begin
  p := head;
  while p <> nil do begin
    pt := p;
    p := p^.next;
    dispose(pt, done);
  end;
end;

procedure tdynarr.append;
var
  new_elem: ptListItem;
begin
  inc(len);
  new_elem := new(ptListItem, init(len));

  if head = nil then head := new_elem
  else tail^.next := new_elem;

  tail := new_elem;
end;

procedure tdynarr.put(atIndex: integer; value: T);
var p: ptlistitem;
begin
  p := At(atIndex);
  if p <> nil then p^.info.value := value;
end;
function tdynarr.get(atIndex: integer): T;
var p: ptlistitem;
begin
  get := -1; { <--- Error !!! }
  p := At(atIndex);
  if p <> nil then get := p^.info.value;
end;

procedure tdynarr.setlength(the_len: integer);
begin
  while len < the_len do append;
end;
function tdynarr.At(atIndex: integer): ptlistitem;
var p: ptlistitem;
begin
  if atIndex > -1 then p := head else p := nil;

  while (p <> nil) and (p^.info.index < atIndex) do begin
    p := p^.next;
  end;
  At := p;
end;

var
  arr: tdynarr;
  i: integer;

begin
  arr.init;
  arr.setlength(10);

  for i := 0 to 9 do
  begin
    arr.put(i, 3 * i);
  end;
  for i := 0 to 9 do
  begin
    writeln(arr.get(i));
  end;
  arr.done;
end.

(писано на коленке, прямо в Блокноте, так что могут быть огрехи в синтаксисе, хотя я старался не допустить. Это если не перераспределять память при каждом увеличении массива. С Integer-ами, разумеется, будет работать неэффективно, но если тип элементов - бОльшего размера, то...).

Proxin, почему не рассматриваешь второй и третий предложенный варианты?
PM MAIL   Вверх
Proxin
Дата 6.3.2010, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



спасибо большое.
почему не рассматриваю другие варианты? потому что посмотреть охота как это делается на ранних компиляторах. а с tcollection -  не знаю, как реализовать. почитать где про них можно?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

1. Обсуждать и делится взломанными компонентами или программным обеспечением

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.4515 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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