Аналог сишного типа данных

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Дож
Если коротко... При создании вычислительного кластера, можно вручную задавать условную длину путей от одного узла до другого. Это самый обычный граф. В массив записываются "длины дуг графа". В каждой ячейке своё число. Эта константа указывает при создании графа (кластера), что все дуги имеют одинаковую длину. Условно говоря, сколько бы дуг не было, они все имеют длину 2, что закладывается в константу. Т.е. это массив-константа с одной-единственной ячейкой у которой значение - 2.

Добавлено спустя 4 минуты 27 секунд:
По старому, так сказать, методу, такую константу следует объявлять так:

Код: Выделить всё

Const
  MPI_UNWEIGHTED: array[0..0] of integer = (2);

Но при этом мы уходим в область типизированных констант, которые не совсем и константы.
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Мне кажется, что тут два пути, либо писать "как на Си" (PInteger, тогда и MPI_UNWEIGHTED можно будет передать, и динамический массив через @arr[0]), либо писать свой тип-враппер (TGraphLengths = object/record, function IsUNWEIGHTED: Boolean, function ToCArray: PInteger).

Т.е. это массив-константа с одной-единственной ячейкой у которой значение - 2.

Вы путаете значение 2 и указатель 2. Правильнее так: массив-константа, длина которого равна числу вершин в графе, а все значения одинаковы (цитата: "all edges have the same (effectively no) weight").
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Дож
Я склоняюсь к варианту "как на си".
Аватара пользователя
Дож
энтузиаст
Сообщения: 900
Зарегистрирован: 12.10.2008 16:14:47

Сообщение Дож »

Отличный выбор!
fedan
новенький
Сообщения: 70
Зарегистрирован: 15.09.2016 20:18:48

Сообщение fedan »

Vadim писал(а):fedan
Остаётся только вопрос, а будет ли такое работать в паскале:

Нет.
Можно как-то так попробовать:

Код: Выделить всё

program Project1;

{$POINTERMATH ON}
{$MODE OBJFPC}
uses
  SysUtils;

const
  MPI_UNWEIGHTED = PInteger(2);

var
  arr: PIntegerArray;
  arrLen: UInt32;
  I: Integer;
begin
  arr := PIntegerArray(MPI_UNWEIGHTED);
  Writeln('0x', IntToHex(UIntPtr(arr), 8));

  arrLen := 5;
  arr := AllocMem(arrLen * sizeof(Integer));
  try
    for I := 0 to arrLen - 1 do
      arr^[I] := I + 1;

    for I := 0 to arrLen - 1 do
      Writeln(arr^[I]);
  finally
    {arr :=} ReallocMem(arr, 0);
  end;
  Writeln('0x', IntToHex(UIntPtr(arr), 8));
end.


Изображение

Добавлено спустя 44 минуты 14 секунд:
Vadim писал(а):Дож
Я склоняюсь к варианту "как на си".


Можно функции конвертеры написать:

Код: Выделить всё

program DynArrayToPInteger;
{$POINTERMATH ON}
{$MODE OBJFPC}

type
  TIntArray = specialize TArray<Integer>;

function DynIntArrayToCIntArray(const Arr: TIntArray): PInteger;
var
  resLen: UIntPtr;
begin
  resLen := High(Arr) + 1;
  GetMem(Result, resLen * sizeof(Integer));
  Move(Arr[Low(Arr)], Result^, ResLen * sizeof(Integer));
end;

function CIntArrayToDynIntArray(const Arr: PInteger; arrLen: UIntPtr): TIntArray;
begin
  if (Assigned(Arr)) and (arrLen > 0) then
  begin
    SetLength(Result, arrLen);
    Move(Arr[0], Result[0], arrLen * sizeof(Integer));
  end;
end;

var
  arr: TIntArray = ();
  arrLen: UIntPtr;
  I: Integer;
  p: PInteger;
begin
  arrLen := 5;
  SetLength(arr, arrLen);
  try
    for I := 0 to arrLen - 1 do
      arr[I] := I + 1;

    p := DynIntArrayToCIntArray(arr);
    for I := 0 to arrLen - 1 do
      Writeln(p[I]);

    Writeln;

    SetLength(arr, 0);
    arr := CIntArrayToDynIntArray(p, arrLen);
    for I := 0 to arrLen - 1 do
      Writeln(arr[I]);

  finally
    SetLength(arr, 0);
    FreeMem(p);
  end;
end.


Изображение
Аватара пользователя
debi12345
долгожитель
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Сообщение debi12345 »

Кто-нибудь знает, есть ли в FPC какой-нибудь приблизительный аналог сишного int128_t?

В основных языках для этого сварганили синтетический тип "decimal"
fedan
новенький
Сообщения: 70
Зарегистрирован: 15.09.2016 20:18:48

Сообщение fedan »

serbod писал(а):
Mirage писал(а):В Паскале есть модификатор absolute, можно через него привязать идентификатор к любому адресу памяти или адресу переменной любого типа. Что позволяет использовать одну и ту же память переменными разного типа.



absolute может свграть как баг в
x86_64(amd64)


Например var

a: integer absolute to pchar или другой указатель

Добавлено спустя 7 минут 37 секунд:
serbod писал(а):
Mirage писал(а):В Паскале есть модификатор absolute, можно через него привязать идентификатор к любому адресу памяти или адресу переменной любого типа. Что позволяет использовать одну и ту же память переменными разного типа.



absolute может свграть как баг в
x86_64(amd64)


Например var

a: integer absolute to pchar или другой указатель

Чтобы такого не происходило следует использовать PtrUint или UintPtr
Ответить