Обращение к последнему элементу динамического массива

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Обращение к последнему элементу динамического массива

Сообщение kotompazb » 16.11.2015 03:56:34

В общем не знаю, где лучше спросить.
Length(arr)-1 или все-таки High(arr)?
Как будет эффективнее (правильнее)?
Последний раз редактировалось kotompazb 16.11.2015 13:06:52, всего редактировалось 1 раз.
Аватара пользователя
kotompazb
постоялец
 
Сообщения: 151
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Re: Обращение к последнему элементу динамического массива

Сообщение WAYFARER » 16.11.2015 09:35:41

Lenght - Возвращает число элементов в массиве,
High - Возвращает самое высокое значение
Правильнее использовать High, наверное, хотя Length(arr)-1 вернет то же самое.
Аватара пользователя
WAYFARER
энтузиаст
 
Сообщения: 537
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Re: Обращение к последнему элементу динамического массива

Сообщение resident » 16.11.2015 11:26:14

kotompazb писал(а):Как будет эффективнее (правильнее)?

IMHO, компилятор их уравняет к одним инструкциям.
А по сему, стремясь к однотипному коду, использую только Length:
Для массивов pred(Length(my_array))
Для классов pred(my_class.items.count)

p.s. Джулиан Бакнел советует начинать массивы с нуля. Там меньше вычисления адреса (т.к. нет смещения) и для циклов возможна оптимизация.
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Обращение к последнему элементу динамического массива

Сообщение Mikhail » 16.11.2015 12:03:02

kotompazb писал(а):В общем не знаю, где лучше спросить.
Length(arr) или все-таки High(arr)?
Как будет эффективнее (правильнее)?

High лучше, он вернет индекс последнего элемента при любой индексации.
Уже рекомендовали, повторюсь, лучше начинать индексацию с нуля, т.к. динамические и открытые массивы всегда начинаются с нуля, чтобы избежать путаницы.
Mikhail
энтузиаст
 
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Re: Обращение к последнему элементу динамического массива

Сообщение kotompazb » 16.11.2015 13:06:21

kotompazb писал(а):В общем не знаю, где лучше спросить.
Length(arr) или все-таки High(arr)?
Как будет эффективнее (правильнее)?

Mikhail писал(а):Уже рекомендовали, повторюсь, лучше начинать индексацию с нуля

Не сразу понял. Извиняюсь, конечно же хотел написать:
Length(arr)-1.
Щас поправлю.
Аватара пользователя
kotompazb
постоялец
 
Сообщения: 151
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Re: Обращение к последнему элементу динамического массива

Сообщение resident » 16.11.2015 15:05:56

kotompazb писал(а):-1

Так вместо единицы использую функцию Pred.
http://lazarus-ccr.sourceforge.net/docs ... /pred.html
Получается третий вариант :)
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: Обращение к последнему элементу динамического массива

Сообщение kotompazb » 16.11.2015 15:13:35

resident писал(а):Так вместо единицы использую функцию Pred.
http://lazarus-ccr.sourceforge.net/docs ... /pred.html
Получается третий вариант

Ага. Я в курсе насчет Pred.
Аватара пользователя
kotompazb
постоялец
 
Сообщения: 151
Зарегистрирован: 21.06.2012 13:03:39
Откуда: Novosibirsk, xUSSR

Re: Обращение к последнему элементу динамического массива

Сообщение gvido » 16.11.2015 18:39:54

Народ, не совсем в тему, но где-то рядом.
Код: Выделить всё
  Type
    TListFiles = array of string;
  type
    TTask = class(TThread)  {вершина структуры задачи}
      Private
       FName:             String;   
       FListOfFiles:      TListFiles;
******
end;

Массив FListOfFiles заполняется без проблем с предварительным увеличением размера массива.
Но с**а не могу его обнулить.

Код: Выделить всё
procedure TTask.ListOfFilesCLR;
begin
  if Length(FListOfFiles)>0 then
  SetLength(FlistOfFiles,0);
end;


"Проект тттт вызвал класс исключения 'External: SIGSEGV.'

по адресу 403С20

Вне класса динамический массив обнуляется без проблем.

Внутри класс поле - динамический массив обнуляется как-то иначе?
gvido
постоялец
 
Сообщения: 188
Зарегистрирован: 28.03.2012 11:35:31

Re: Обращение к последнему элементу динамического массива

Сообщение Дож » 16.11.2015 19:00:27

gvido писал(а):"Проект тттт вызвал класс исключения 'External: SIGSEGV.'

Нужен полный код использования класса TTask, от создания до уничтожения.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Обращение к последнему элементу динамического массива

Сообщение zub » 16.11.2015 19:03:39

>>Массив FListOfFiles заполняется без проблем с предварительным увеличением размера массива
Скорее всего заполняется какраз с проблемами)) или в промежутке между заполнением - очищением портится
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обращение к последнему элементу динамического массива

Сообщение gvido » 16.11.2015 20:30:01

zub писал(а):Нужен полный код использования класса TTask, от создания до уничтожения.

Это собственно пока только заготовка.
Код: Выделить всё
  Type
    TListFiles = array of string;

  type
    TTask = class(TThread)  {вершина структуры задачи}
      Private
       FName:             String;    {Текстовая метка. Например - "Задача 1"}
       FFileMask:         String;    {Маска поиска файлов в основной папке задачи. Например: *a*.arj}
       FFoldPath:         String;    {Папка с которой нашинается обработка задачи}
       FListOfFiles:      TListFiles;
       FFoldError:        String;    {Папка с отбракованными файлами текущей задачи}
      Protected

      Public
       Constructor Create(aName: String; CreateSuspended: boolean = True);
       procedure DoScanDir;
       Procedure ListOfFilesCLR;
//*
       Property Name: String Read FName Write FName;
       Property FileMask: String Read FFilemask Write FFileMask;
       Property Foldpath: String Read FFoldpath Write FFoldPath;
       Property ListOfFiles: TlistFiles Read FListOfFiles;

    end;

    Function StrToTimeType(Value:String):TTimeType;
    Function TimeTypeToStr(Value:TTimeType):String;
    Function FullFilePath(const fDir,fFile:string): String;


implementation   
Constructor TTask.Create(aName: String; CreateSuspended: boolean = True);
begin
     FName:=aName;
     FFoldPath:=     '';
     FFoldError:=    '';
     FFileMask:=     '';
     FreeOnTerminate := True;
     inherited Create(CreateSuspended);
end;
procedure TTask.DoScanDir;
Var
Info : TSearchRec;
begin
       If DirectoryExistsUTF8(FFoldPath) and (FFileMask<>'')  then
          begin
               If FindFirstUTF8(FFoldPath+'\'+FFileMask,faAnyFile and not faDirectory,Info)=0 then
                   try
                      repeat
                            SetLength(FlistOfFiles,Length(FlistOfFiles)+1);
                            FListOfFiles[Pred(Length(FlistOfFiles))]:=info.Name;
                      until (FindNextUTF8(Info)<>0);
                   finally
                   FindCloseUTF8(Info);
               end;
          end;
end;
procedure TTask.ListOfFilesCLR;
begin
  if Length(FListOfFiles)>0 then
Finalize(FListOfFiles,Length(FListOfFiles));
end;


Использоваение:
Код: Выделить всё

unit frmMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, RTTIGrids, RTTICtrls, Forms, Controls, Graphics,
  Dialogs, Grids, ComCtrls, Menus, ExtCtrls, StdCtrls, ValEdit, ComboEx, inicol,
  inifiles,LCLType, gvsclass;

type

  { TfrmMane }

  TfrmMane = class(TForm)
    ListBox1: TListBox;
    ToolButton2: TToolButton;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1KeyPress(Sender: TObject; var Key: char);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  frmMane: TfrmMane;
  Task: TTask;

implementation

{$R *.lfm}

{ TfrmMane }

procedure TfrmMane.FormCreate(Sender: TObject);
var
  i: integer;
begin
     Task:=TTask.Create('Входящие 311-П',true);
     Task.FileMask:='mz*_30.821';
     task.Foldpath:='U:\ЦБ\ptkpsd\post\post';
     Task.DoScanDir{(task.Foldpath,Task.FileMask)};
     for i:=0 to pred(length(task.ListOfFiles)) do
        begin
           listbox1.Items.Append(Task.ListOfFiles[i]);
        end;
end;


procedure TfrmMane.ListBox1KeyPress(Sender: TObject; var Key: char);
var
  i:integer;
begin
  if key=Chr(vk_delete) then listbox1.Items.Clear;
  if key='a' then
     begin
      if length(task.ListOfFiles)>0 then
       begin
         for i:=0 to pred(length(task.ListOfFiles)) do
           listbox1.Items.Append(Task.ListOfFiles[i]);
       end;
     end;
  if key='c' then task.ListOfFilesCLR;
end;

end. 


zub писал(а):>>Массив FListOfFiles заполняется без проблем с предварительным увеличением размера массиваСкорее всего заполняется какраз с проблемами)) или в промежутке между заполнением - очищением портится

он нормально заполняется и выводится содержимое в listbox.

хотел подглянуть как чистится TStringList, так хрен подглядишь. :(

Пробовал использовать
Код: Выделить всё
Finalize(FListOfFiles,length(FListOfFiles));
внутри класса - тоже ошибка.
Последний раз редактировалось gvido 16.11.2015 22:15:13, всего редактировалось 4 раз(а).
gvido
постоялец
 
Сообщения: 188
Зарегистрирован: 28.03.2012 11:35:31

Re: Обращение к последнему элементу динамического массива

Сообщение zub » 16.11.2015 21:51:46

gvido
Цените пожалуйста время форумчан. Давайте не обрывки, а минимальный компилируемый пример с ошибкой. Заодно, пока будешь делать пример и ошибку выловишь))
В приведенных обрывках имхо проблем нет.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Обращение к последнему элементу динамического массива

Сообщение gvido » 16.11.2015 22:00:44

zub писал(а):gvidoЦените пожалуйста время форумчан. Давайте не обрывки, а минимальный компилируемый пример с ошибкой. Заодно, пока будешь делать пример и ошибку выловишь))В приведенных обрывках имхо проблем нет.

Сорьки, забыл убрать, не используемые в данном примере поля. Исправил.
Код должен собраться.

только что собрал все эту хрень в делфи 10 (сцуко!!!!) все отработало.

Все, вопрос, закрыт Finalize(array); без доп параметра зачистил массив.
Последний раз редактировалось gvido 16.11.2015 22:54:26, всего редактировалось 2 раз(а).
gvido
постоялец
 
Сообщения: 188
Зарегистрирован: 28.03.2012 11:35:31

Re: Обращение к последнему элементу динамического массива

Сообщение Mikhail » 16.11.2015 22:37:39

gvido писал(а):
zub писал(а):gvidoЦените пожалуйста время форумчан. Давайте не обрывки, а минимальный компилируемый пример с ошибкой. Заодно, пока будешь делать пример и ошибку выловишь))В приведенных обрывках имхо проблем нет.

Сорьки, забыл убрать, не используемые в данном примере поля. Исправил.
Код должен собраться.

только что собрал все эту хрень в делфи 10 (сцуко!!!!) все отработало.
вот урезанный проект:
https://yadi.sk/d/Q4-6-8oCkVvnt
пути и маску файлов в основной форме нужно сменить.

Вы хотите сканировать каталог в отдельном потоке?
Mikhail
энтузиаст
 
Сообщения: 565
Зарегистрирован: 24.10.2013 16:06:47

Re: Обращение к последнему элементу динамического массива

Сообщение gvido » 16.11.2015 22:45:32

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

Чувствовал, что, что кручусь где-то рядом с кодом, но никак не мог нащупать.

До сихпор не понятно - почему не работает внутри класса array:=nil или setlength(array,Length(array))!?!??
Последний раз редактировалось gvido 17.11.2015 01:26:50, всего редактировалось 3 раз(а).
gvido
постоялец
 
Сообщения: 188
Зарегистрирован: 28.03.2012 11:35:31

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru
cron