Сначала короткое объяснение арифметике указателя. Когда вы имеете дело с динамическими страницами памяти, то все, что вы имеете - это указатели на начала блоков памяти. Вы хотите просмотреть всю строку памяти, чтобы понять какие функции необходимы для работы с данными, хранящимися в памяти? Это возможно путем изменения места в памяти, на которое указывает указатель. Это называется арифметикой указателя.

 

Сначала вы должны создать тип:

Code:

Type Pinteger : ^Integer;

 

Var MyPtr : Pinteger;

 Мне кажется, что в начале вы использовали плохой пример, имеет смысл использовать 32-битный указатель для 16-битной величины или распределять 10 байт для переменной. 

 Pascal позволяет вам использовать методы NEW и DISPOSE, которые автоматически распределяют и освобождают правильные размеры блока. 

 Например:

 

Я ищу функцию, которая была бы эквивалентом сишной функции memcmp.

Я создал следующие две функции, существенно повышающие произвотельность в приложениях, активно работающих с данными. Вам нужно всего-лишь обеспечить контроль типов и границ допустимого диапазона, все остальное они сделают с любым типом данных лучше нас :-) .

 

 

Code:

function Keys_are_Equal(var OldRec, NewRec;

KeyLn : word): boolean; assembler;

asm

PUSH    DS

MOV     AL,01

CLD

LES     DI,NewRec

LDS     SI,OldRec

MOV     CX,KeyLn

CLI

REPE    CMPSB

STI

JZ      @1

XOR     AL,AL

@1:

POP     DS

end;

 

Code:

function First_Key_is_Less(var NewRec, OldRec;

Keyln : word): boolean; assembler;

asm

PUSH    DS

MOV     AL,01

CLD

LES     DI,NewRec

LDS     SI,OldRec

MOV     CX,KeyLn

CLI

REPE    CMPSB

STI

JZ      @5

JGE     @6

@5: XOR     AL,AL

@6: POP     DS

end;

Я создал простой модуль и разработал несколько простых методов, помогающих избежать использования неактуальных (в оригинале было "stale" - черствый, несвежий) указателей. Я настоятельно рекомендую добавить во все модули, содержащие указатели или объектные переменные секцию инициализации ('initialization') и установить все указатели (объектные переменные это те же реальные указатели) в nil. Что это даст:

Code:

uses WinCRT;

 

procedure TForm1.Button1Click(Sender: TObject);

var

MyArray: array[0..30] of char;

b: ^char;

i: integer;

begin

StrCopy(MyArray, 'Delphi World - это круто!!!');

b := @MyArray;

for i := StrLen(MyArray) downto0do

begin

   write(b^);

   inc(b, sizeof(char));

end;

end;

 

Code:

{©Drkb v.3(2007): drkb ru}

var

  p1 : ^String;

  s1 : String;

begin

  s1 := 'NotTest';

  new (p1);

  p1 := @s1;

  p1^ := 'Test';

  Label1.Caption := s1

 

 

 

StrAlloc непосредственно использует GetMem, поэтому обе функции живут за счет Кучи. StrAlloc имеет преимущество: он распределяет на два байта больше, чем вы просите и там хранит размер размещенного блока. Поэтому StrDispose знает сколько памяти освободить и вы можете этого не помнить (в отличие от GetMem/FreeMem). Не смешивайте при работе эти две функциональные пары, иначе вы будете потрясены количеством возникающих ошибок!

...мне также понадобилось в подпрограмме получить ссылку на дочернее MDI-окно без сообщения подпрограмме с каким конкретно классом MDI необходимо работать. Что я сделал: я передавал в виде параметров тип дочернего MDI-окна и ссылку как нетипизированную переменную и затем обрабатывал это в подпрограмме.

 

Вот пример. Эта подпрограмма работает с дочерним окном, которое может иметь только один экземпляр. Если оно не открыто, подпрограмма создаст его, если оно открыто, оно переместит его на передний план.

 

Тут мы рассмотрим несоклько примером освобождения памяти.

Способ преобразования указателей на указатели на функции  Часто вам нужно указатель на функцию для функции обратного вызова. Но то, что ,
 
если вы хотите указать метод обратного вызова , как? Преобразованиеметода
 
Указатель на функцию указателя не является тривиальной задачей, оба типа
 
incomatible друг с другом. Хотя у вас есть возможность  преобразования ,

Если вы хотите удалить переменную, что никакая другая программа не может прочитать из памяти больше, просто используйте эту функцию:

 

Code:

ZeroMemory(Addr(yourVar), SizeOf(yourVar));

ZeroMemory(Addr(yourStr), Length(yourStr));

// ZeroMemory(Address of the variable, Size of the variable);

 

Очень полезно, если вы задали пароль, и вы хотите, что никто другой не может его получить.