![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как изменть значение указателя?
Дурдом © (2005-01-03 02:40:00)Доброй ночи!
Можно ли средствами Делфи не прибегая к инлайн-ассемблеру сделать следующее:
var
A1:array[0..$FF] of byte;
FileMapped:pointer; //указатель на кусок памяти
n:integer;
---
begin
for i:=0 to $FF do
A1[i]:=значение байта (по адресу (указателя на кусок памяти+i))
Это означает, что FileMapped указывает на некий массив байт, и надо заполнить массив A1 байтами, на которые указывает FileMapped (пододвигая значение указателя на 1 в право, но если можно по-другому - я не против).
Fay (2005-01-04 01:05:00) [1]2 GuAV © (04.01.05 0:57) [41]
Я не спец по асму, поэтому работаю с секундометром 8)
GuAV (2005-01-04 00:57:00) [2]Fay © (04.01.05 0:16) [40]
Я не вижу объяснений результатам в пользу move. при прямом присвоении rep movsd + возможно movsw + возможно movsb, при малых размерах (до 20) ещё лучше . Экономим на вызове, на ветвлении...
Fay (2005-01-04 00:16:00) [3]2 GuAV © (03.01.05 20:56) [24]
Мне седня удалось получить результаты и в пользу Move, и "не в пользу". Причём с одними и теми же условиями - просто в разное время 8)
GuAV (2005-01-03 22:36:00) [4]DWORD - fundamental, а PChar - generic.
GuAV (2005-01-03 22:34:00) [5]begin...end © (03.01.05 22:23) [35]
rtfm: fundamental and generic types
type->F1->declaring types->see also->about types
begin...end (2005-01-03 22:32:00) [6]> [36] GuAV © (03.01.05 22:27)
Да, я уже в CPU посмотрел, в случае Inc(PWideChar) прибавляется смещение 2.
Но всё же я считаю, что эти предосторожности лишние. Ты меня не переубедишь :-)
P.S. Пойду спать.
GuAV (2005-01-03 22:27:00) [7]program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
P1: PAnsiChar;
P2: PWideChar;
P3: PLongWord;
begin
P1 := 'Hello';
P2 := 'world';
P3 := @HInstance;
WriteLn(IntToHex(Integer(P1),8));
WriteLn(IntToHex(Integer(P2),8));
WriteLn(IntToHex(Integer(P3),8));
Inc(P1);
Inc(P2);
Inc(P3);
WriteLn(IntToHex(Integer(P1),8));
WriteLn(IntToHex(Integer(P2),8));
WriteLn(IntToHex(Integer(P3),8));
ReadLn;
end.
begin...end (2005-01-03 22:23:00) [8]> [33] GuAV © (03.01.05 22:15)
> DWORD aka LongWord по определению 32 байта.
Что-то многовато :-)
Нельзя исключать, что через 100 лет словом будет называться 4 байта, например.
begin...end (2005-01-03 22:20:00) [9]> [32] GuAV © (03.01.05 22:13)
> там Inc(P) заставит P указывать на следующий символ, не
> важно занимает ли он 1 или 2 байта в текущей реализации.
Почему? По-моему, указатель просто будет указывать на следующий байт, а не перескакивать, например, на 2 байта.
GuAV (2005-01-03 22:15:00) [10]begin...end © (03.01.05 22:08) [31]
Например, что мешает увеличиться или уменьшиться DWORD'у?
DWORD aka LongWord по определению 32 байта. а вот Cardinalу действительно никто не запрещает изменить размер, и возможно он изменится когда-нибудь.
GuAV (2005-01-03 22:13:00) [11]begin...end © (03.01.05 22:08) [31]
StrUtils для работы со строками. там Inc(P) заставит P указывать на следующий символ, не важно занимает ли он 1 или 2 байта в текущей реализации.
Кроме того наличие у Borland implementation-specific кода я считаю нормальным, т.к. они отвечают за этот самый implementation, а в своём коде я бы избежал таких конструкций.
begin...end (2005-01-03 22:08:00) [12]> [30] GuAV © (03.01.05 22:03)
Тем не менее, Borland, например, в модуле StrUtils спокойно пишет Inc(P), где P: PChar.
В будущем может случиться что угодно. Например, что мешает увеличиться или уменьшиться DWORD'у?
GuAV (2005-01-03 22:03:00) [13]begin...end © (03.01.05 21:59) [29]
Сейчас - в случае другого pascal-совместимого транслятора. А в будущем - возможно очень скоро.
> What happened to your code when the implementation
> will have changed ?
кстати, правильно совсем наоборот :-)
begin...end (2005-01-03 21:59:00) [14]> [28] GuAV © (03.01.05 21:56)
[25]: символ это не обязательно байт.
Вопрос: в каком случае СЕЙЧАС Char - это не байт?
> What happened to your code when the implementation will
> have changed ?
Я не доживу, мне кажется.
GuAV (2005-01-03 21:56:00) [15]begin...end © (03.01.05 21:49) [27]
The generic PChar represents a pointer to a Char (that is, in its current implementation, to an AnsiChar).
What happened to your code when the implementation will have changed ?
begin...end (2005-01-03 21:49:00) [16]> [25] GuAV © (03.01.05 21:34)
The generic PChar represents a pointer to a Char (that is, in its current implementation, to an AnsiChar). А AnsiChar - это 1 байт, в отличие от WideChar. Разве нет?
Дурдом (2005-01-03 21:48:00) [17]УРА!!! Как раз почти как я хотел!
type
TA = array [0..$0F] of Byte;
var
hFile1Map:pointer;
i:integer;
begin
Sign1:=TA(pointer(dword(hFile1Map)+i)^);
end;
[IMHO]
Благо, это не С++ - там вообще в типах чёрт голову сломит, и компилер там вредный. Мдя, программер из меня...
[/IMHO]
GuAV (2005-01-03 21:34:00) [18]begin...end © (03.01.05 20:39) [23]
к PChar приводить не хорошо. символ это не обязательно байт.
GuAV (2005-01-03 20:56:00) [19]var
M: array[0..1000] of integer;
FileMapped: Pointer = @M;
procedure P1;
type
TA1 = array [0..999] of Byte;
var
A1: TA1;
begin
A1 := TA1(FileMapped^);
end;
procedure P2;
type
TA1 = array [0..999] of Byte;
var
A1: TA1;
begin
Move(FileMapped^, A1 , SizeOF(A1));
end;
procedure TForm1.Button1Click(Sender: TObject);
const
TestCount = 1000000;
var
A, B: Cardinal; i: integer;
begin
A := GetTickCount;
for i := 0 to TestCount do P1;
A := GetTickCount - A;
B := GetTickCount;
for i := 0 to TestCount do P2;
B := GetTickCount - B;
Caption := Format('P1 = %d, P2 = %d', [A, B]);
// P1 = 283, P2 = 350
// win98, D7, {$O+}
// для 320 разрыв ещё существеннее
end;
begin...end (2005-01-03 20:39:00) [20]А-а, это... Ну тогда вот так ещё можно:
type
AT = array [0..$0F] of Byte;
var
FileMapped: Pointer;
A1: AT;
I: Integer;
begin
for I := 0 to $0F do
A1[I] := PByte(PChar(FileMapped) + I)^
end.