![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сравнение массивов [D7, XP]
Очень Злой © (2011-10-03 11:38:00)Вроде как читал что масивы сравнивать нельзя.
Но на такое компилятор не ругается.
Type TmyArray: packed array[1..8] of byte;
...
var
a,b:TMyArray;
begin
...
if a=b then ...
Что сравнивается в этом случае? Указатели?
Или это зависит от версии Delphi? У меня D7
Или все-таки лучше сравнивать используя comparemem?
Anatoly Podgoretsky (2011-10-03 19:09:00) [1]
> Что сравнивается в этом случае? Указатели?
В данном случае сравниваются переменные а и в
Очень Злой (2011-10-03 14:52:00) [2]
> IsEqual := PInt64(@a)^ = PInt64(@b)^
Была подобная мысль...
Вернее думал сделать так:
Type MyRec= packed record of
case boolean of
true: (MyArray:packed array[1..8] of byte);
false: (ForCompare: int64);
end;
Но теперь решил обойтись array[1..8] of Char...
Сергей М. (2011-10-03 14:03:00) [3]> массивы типа packed array[1..8] of byte можно без проблем сравнивать?
IsEqual := PInt64(@a)^ = PInt64(@b)^
Dennis I. Komarov (2011-10-03 13:46:00) [4]
> а то пока через Move пишу
Пиши, меньше граблями получишь. Так можно делать когда понимаешь (и представляешь) как в памяти "компа" это аккуратно складывается...
Кроме того, операции с памятью нагляднее и читабельнее.
Rouse_ (2011-10-03 13:32:00) [5]
> Может их еще можно копировать через a:=b?
Можно...
Rouse_ (2011-10-03 13:32:00) [6]Но только статические однотипные.
Очень Злой (2011-10-03 13:29:00) [7]т.е. массивы типа packed array[1..8] of byte можно без проблем сравнивать?
а то я уже через CompareMem написал....
Может их еще можно копировать через a:=b?
а то пока через Move пишу (на всякий случай)...
Rouse_ (2011-10-03 13:10:00) [8]Хм, чего-то саообщения Шарка не видел перед ответом... Ну да ладно...
Rouse_ (2011-10-03 13:09:00) [9]
> Очень Злой (03.10.11 12:12) [4]
> Вот это у меня компилятор пропускает....
ну так тип же другой, массив чаров а не байт, тут уже работа как с ShortString идет через WStrLComp/AStrComp
DiamondShark (2011-10-03 12:59:00) [10]
> Очень Злой (03.10.11 12:12) [4]
> Вот это у меня компилятор пропускает....
CPU Window -- нашефсё!
Unit1.pas.17: if a=b then
0044CD9B 8BC4 mov eax,esp
0044CD9D 8D542408 lea edx,[esp+$08]
0044CDA1 B908000000 mov ecx,$00000008
0044CDA6 E89D5FFBFF call @AStrCmp
procedure _AStrCmp;
asm
{ ->EAX = Pointer to left string }
{ EDX = Pointer to right string }
{ ECX = Number of chars to compare}
Т.е. он сравнивает как строки, что неудивительно, если вспомнить, что packed array of char по доброй борландовской традиции прозрачно преобразуется в строки.
Если поменять описание типа на
type Tpassline = packed array[1..8] of byte;
то закономерно получим:
[Error] Unit1.pas(17): Operator not applicable to this operand type
В первом случае вас спасло неявное компилер-маджик преобразование типов.
Очень Злой (2011-10-03 12:12:00) [11]
type Tpassline = packed array[1..8] of char;
...
procedure aa;
var
a,b:Tpassline;
begin
if a=b then
begin
//
end;
end;
Вот это у меня компилятор пропускает....
Rouse_ (2011-10-03 12:00:00) [12]
> Но на такое компилятор не ругается.
>
> Type TmyArray: packed array[1..8] of byte;
вот именно на такое, ругается, не будет ругаться на вот такое.
Type
TmyArray = packed array of byte;
и в данном случае, т.к. массив будет динамический, то будут сравниваться указатели, а не адреса первых элементов, т.е. вот такой код:
Type
TmyArray = packed array of byte;
procedure TForm1.FormCreate(Sender: TObject);
var
a,b: TMyArray;
begin
SetLength(A, 3);
SetLength(B, 3);
a[1] := 1;
B[1] := 1;
if a <> b then
ShowMessage('False');
высветит False.
Если же массив будет обьявлен как статический: .т.е.
Type
TmyArray = packed array [1..8] of byte;
то вот этот код компилятор не пропустит:
if a=b then ...
Rouse_ (2011-10-03 11:53:00) [13]В данном случае можно через CompareMem()
Медвежонок Пятачок (2011-10-03 11:48:00) [14]сравниваются адреса первых элементов