Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Как правильно сравнивать records?


Автор: artemiy 6.2.2009, 19:43
Есть две переменные var1 и var2 типа record, напр
Код

type TExample = record
     name:string;
     value:integer;
end;

Как можно проверить равенство этих переменных, кроме как 
Код

(var1.name=var2.name)and(var1.value=var2.value)
?

Автор: Rrader 6.2.2009, 21:09
Никак

Автор: Qu1nt 6.2.2009, 21:32
Rrader,
А почему так нельзя?
Код

type
  TRecord = record
    Name: Integer;
    Value: string[255];
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Rec1, Rec2: TRecord;
begin
  FillChar(Rec1, SizeOf(TRecord), 0);
  FillChar(Rec2, SizeOf(TRecord), 0);
  Rec1.Name := 1;
  Rec1.Value := 'A';
  Rec2.Name := 1;
  Rec2.Value := 'A';
  Self.Caption := BoolToStr(CompareMem(@Rec1, @Rec2, SizeOf(TRecord)), True);
end;

Автор: bems 6.2.2009, 21:40
Qu1nt, потому что мужду последним символом стрики и концом выделенного под нее блока мы не застрахованы от мусора

Добавлено через 2 минуты и 43 секунды
а, извиняюсь не заметил FillChar. Но это ж тоже не выход. Записи должны инициализироваться так как это привычно (присваиванием полям, а не заполнением блока). Я бы перегрузил сравнение  smile 

Автор: Qu1nt 6.2.2009, 21:46
С перегрузкой тоже вариант, только требует 2006-й. 

Автор: bems 6.2.2009, 21:48
лучше 2009. Но и само время ее требует. Так что это выход

Автор: Rrader 7.2.2009, 07:42
А на это что скажете?
Код

type
  TMyRec = record
    FInt: Integer;
    FName: String[255];
  end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Rec1, Rec2: TMyRec;
begin
  FillChar(Rec1, SizeOf(TMyRec), 0);
  FillChar(Rec2, SizeOf(TMyRec), 0);
  Rec1.FInt := 1;
  Rec1.FName := 'A';
  Rec2.FInt := 1;
  Rec2.FName := 'A';
  { Где-то в процессе работы меняем строку }
  Rec1.FName := 'AB';
  { А далее где-нибудь она снова изменилась, причем длина уменьшилась }
  Rec1.FName := 'A';
  Self.Caption := BoolToStr(CompareMem(@Rec1, @Rec2, SizeOf(TMyRec)), True);
end;

И еще, у ТС в записи одно поле long-string, как его сравнивать?

После дискуссий в IRC пришли к выводу, что кто как хочет, тот пусть так и сравнивает. Либо напрямую, либо через функцию, либо через перегрузку (если есть возможность - самое красивое решение) smile 
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TMyRec = record
    FInt: Integer;
    FName: String;
    class operator Equal(A, B: TMyRec): Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyRec }

class operator TMyRec.Equal(A, B: TMyRec): Boolean;
begin
  Result := (A.FInt = B.FInt) and (A.FName = B.FName);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  A, B: TMyRec;
begin
  A.FInt := 1;
  A.FName := 'Name';
  B.FInt := 1;
  B.FName := 'Name';
  ShowMessage(BoolToStr(A = B, True));
end;

end.

Автор: bems 7.2.2009, 16:35
Rrader, ну ты показал то что я имел в виде здесь
Цитата(bems @  6.2.2009,  21:40 Найти цитируемый пост)
потому что мужду последним символом стрики и концом выделенного под нее блока мы не застрахованы от мусора
А перегрузка это нормальное решение. В реализации делаем почленное сравнение а потом просто проверяем на равенство

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)