Арифметика указателей

Арифметика указателя в mikroPascal PRO для ARM ограничена:

Назначение и сравнение

Простой оператор присваивания (=) может использоваться для присвоения значения одного указателя другому, если они одного типа.

Присвоение целочисленной константе 0 указателю присваивает ему значение нулевого указателя.

Два указателя, указывающие на один и тот же массив, можно сравнить с помощью реляционных операторов =, <>, <, <=,> и> =. Результаты этих операций такие же, как если бы они использовались для значений индексов соответствующих элементов массива:

var ptr1 : ^byte;
    ptr2 : ^byte;
    a : array[10] of byte;    // массив a, содержащий 10 элементов байта типа

begin           
  ptr1 := @a[4];
  ptr2 := @a[2];

  if (ptr1 = ptr2) then ...   // не будет выполняться, так как 4 не равно 2
  if (ptr1 > ptr2) then ...   // будет выполняться как 4 больше, чем 2

  if (ptr1^ = ptr2^) then ... // если значение, на которое указывает ptr1, равно значению, на которое указывает ptr2 ...
  if (ptr1^ > ptr2^) then ... // если значение, на которое указывает ptr1, больше значения, на которое указывает ptr2 ...
end.
  Примечание : Сравнение указателей, указывающих на разные объекты / массивы, может выполняться по собственной ответственности программиста - необходим точный обзор физического хранения данных.

Добавление указателя

Вы можете использовать Inc для добавления целочисленного значения в указатель. Результат сложения определяется только в том случае, если указатель указывает на элемент массива, и если результатом является указатель, указывающий на тот же массив (или один элемент за его пределами).

Если указатель объявлен для указания типа, добавление целочисленного значения n к указателю увеличивает значение указателя на n * sizeof (type), если указатель остается в пределах допустимого диапазона (первый элемент - один за последним элементом). Если тип имеет размер 10 байт, то добавление 5 к указателю на тип ускоряет указатель 50 байт в памяти.

Например:

var
  a : array[10] of byte;    // array a containing 10 elements of type byte
  ptr : ^byte;              // pointer to byte
  	
begin
  ptr := @a[0];       // ptr - указатель на байт, указывающий на [0]
  ptr := ptr + 3;     // ptr + 3 - указатель, указывающий на [3]
  ptr^ := 6;	    // a [3] теперь равна 6
  Inc(ptr);           // ptr now points to the next element of array a: a[4]
end.

Кроме того, вы можете суммировать значения, на которые указывают указатели.

Например:

var
  i, j, x :  byte; // переменные
  ptr1 : ^byte;    // указатели на байт
  ptr2 : ^byte;

begin
  i := 10;        // присвойте значение 10 переменной; i по адресу 0x0038
  j := 5;         // присвойте значение 10 переменной; j находится по адресу 0x003A
  
  ptr1 := @i;     // ptr1 - указатель на байт, указывающий на i
  ptr2 := @j;     // ptr2 - указатель, указывающий на j

  x := ptr1^ + ptr2^;   // результат равен сумме значений, на которые указывает; x = 5
end.

Вычитание указателей

Подобно добавлению, вы можете использовать Dec для вычитания целочисленного значения из указателя.

Если указатель объявлен для указания типа, то вычитание целочисленного значения n из указателя уменьшает значение указателя на n * sizeof (type), если указатель остается в пределах допустимого диапазона (первый элемент - один за последним элементом) , Если тип имеет размер 10 байт, то вычитание 5 из указателя на тип отталкивает указатель 50 байт в памяти.

Например:

var
  a : array[10] of byte;    // массив a, содержащий 10 элементов байта типа
  ptr : ^byte;              // указатель на байт

begin
  ptr := @a[6];       // ptr - указатель на байт, указывающий на [6]
  ptr := ptr - 3;     // ptr-3 - указатель, указывающий на [3]
  ptr^ := 6;	    // a [3] теперь равна 6
  Dec(ptr);           // Теперь ptr указывает на предыдущий элемент массива a: a [2]
end.

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

Например:

var
  i, j, x :  byte; // переменные
  ptr1 : ^byte;    // указатели на байт
  ptr2 : ^byte;

begin
  i := 10;        // присвойте значение 10 переменной; i находится по адресу 0x0039
  j := 5;         // присвойте значение 5 переменной; j находится по адресу 0x003A
  
  ptr1 := @i;     // ptr1 - указатель на байт, указывающий на i
  ptr2 := @j;     // ptr2 - указатель, указывающий на j

  x := ptr2 - ptr1;     // результат равен расстоянию между двумя остроконечными адресами; x = 1 (1 байт) 
  x := ptr1^ - ptr2^;   // result is equal to the difference of the values pointed to; x = 5
end.