Qisqa chiziqli usulni qanday usulda o'tkazish kerak

Qisqartma qatorini dalil sifatida qabul qilishni xohlayman

procedure f(const a, b: Array of shortstring);

Buni ma'lum uzunlikdagi ma'lum uzunliklar va qisqa uzunlikdagi massivlar bilan chaqirishni istardim, masalan.

var
  A, B: array[1..2] of string[5];
  C, D: array[1..40] of string[12];
begin
  f(A,B);
  f(C,D);
end;

Ushbu natija E2008 mos kelmaydigan turdagi kompilyator xatoida. Nima sababdan? Qisqa chiziqli kataloglarni (har qanday uzunlikdagi qatorlar/satrlarni) oladigan amaliyotni yozish mumkinmi?

Qisqa klavishni nima uchun ishlatish kerak?

Qisqartmalar mavjud yozuvlardagi joylardir. Ushbu rekorddan minglab qisqa yo'llar bor. B-Tree Filer ma'lumotlar bazasiga SQL ma'lumotlar bazasiga ma'lumotlarni ko'chirish bo'yicha bir qadam bo'lib, yozuvni datasetga aylantirish va barcha joylar to'g'ri yo'nalishga aylanadi. Buni tekshirish uchun yozuvlardagi CompareMem dan foydalanmoqdaman, lekin u qanday maydonda ishlash xatoligi haqida etarli ma'lumot bermaydi. Shunday qilib, kichik ro'yxat yaratildi, ikki yozuvni solishtirish uchun kodni kiriting. Bu kodni ishlab chiqaruvchi men uchun qisqa burilishlarni solishtirish uchun kerak bo'lgan funksiya kerak edi. Qisqa chiziqlardagi CompareMem yordamida yakunlandi.

3
@David: Men ular uchun bir muddat avval yaxshi foydalanishni topdim. Men juda qattiq yineluvchi daraxt asosidagi ajralish kodida xotira sızmalarını qiyinlashtirdi. Belgini nomini ShortString -ga string dan o'zgartirib, nomi FastMM-ning FullDebugMode hisobotida xotira dampiga ichki ko'rinishga ega bo'lib, uni topish osonroq bo'ladi muammo.
qo'shib qo'ydi muallif Mason Wheeler, manba
Faqat bir qator mag'lubiyatdan foydalaning. Uzoq muddatni e'lon qilish haqida o'ylamang. Sizning hayotingiz ancha oson bo'ladi.
qo'shib qo'ydi muallif Johan, manba
Nima uchun qisqa yo'llarni ishlatmoqchisiz? Meni hayotim uchun foydaliroq bo'lganda ishlay olmayman.
qo'shib qo'ydi muallif David Heffernan, manba
ShortString-dan foydalanmasdan, o'zingizni bu qadar osonroq qilishingiz mumkin. Dinamik bir qator turi e'lon qilish va shu turdagi foydalanish juda ham oson ishlaydi; kodni Length dan foydalangan holda topishingiz mumkin va chegaralar har doim 0 dan yuqori (ArrayVar) bo'ladimi va ushbu turdagi dalillaringizni usulingizga o'tkazib berasiz.
qo'shib qo'ydi muallif Ken White, manba
@DavidHeffernan Qisqa jadvallar nima uchun ishlatilganligi bilan bog'liq savol.
qo'shib qo'ydi muallif MGH, manba

4 javoblar

ShortString uzunligi 0 dan 255 belgigacha. ShortString uzunligi dinamik ravishda o'zgarishi mumkin, lekin xotira statik jihatdan ajratilgan 256 bayt, birinchi bayt mag'lubiyatning uzunligini saqlaydi va qolgan 255 bayt belgilar uchun mavjud, faqat shu tarzda e'lon qilingan mag'lubiyat [5] (5 bayt + 1 bayt uzunligi) talab qilinadigan ko'p xotira. siz turdagi foydalanishingiz mumkin

type
    MyString = string[5];
...
procedure f(const a, b: Array of MyString);
...

var
    A, B: array[1..2] of MyString;
begin
    f(A,B);
end;
7
qo'shib qo'ydi
@MGH Bu mumkin emas. mag'lubiyatning qatori [5] va satr majmuasi [12] mos keladigan turlar emas.
qo'shib qo'ydi muallif Ondrej Kelle, manba
Javobingiz uchun tashakkur. Bu faqat [5] mag'lubiyatga oid muammolarni hal qiladi. Men nima qilishni xohlayotganimni yaxshiroq ko'rsatish uchun savolimni yangiladim.
qo'shib qo'ydi muallif MGH, manba

Ikkita turdagi ochiq qatorni birlashtirasiz.

Birinchidan, klassik Turbo Paskalning "mag'lubiyati" (Delphi IIRC da "ochiq yo'l" deb ham nomlanadi), bu asosan [255] dir. Qator [255] butun kataklarning ustunligidek, ochiq-oydin majmuasi, barcha qisqa yo'l turlarini o'zgartiradi.

"Xx" qatori sintaksisi Delphi (4+?) Ochiq qatordir. Bu faqat strings emas, balki har qanday turdagi ochiq-oydin qator va uni ifodalash uchun sintaksisi f (nonarrayparam, [arrayelement0, arrayelement1]);

Biron-bir tarzda har ikki sintaksisni bir-biriga aralashtirasiz va hatto soliksiyani mos yozuvlar orqali o'tadigan CONST qo'shimchasini qo'shib, ayirboshlashni istisno qilasiz.

Tasavvur qilamanki, shortstringda ishlash afzalligi bor. Ba'zi holatlarda u mavjud. Ochiq qator bu holatlardan biri emas. TP da ham emas :-)

1
qo'shib qo'ydi

Men shunga o'xshash vaziyatda quyidagilarni foydalanganman:

type
  TOpenArrayOfOpenString = record
  strict private
    FSizeOfString: Integer;
    FpStart: PChar;
    FArrayLength: Integer;
    function GetItemPtr(AIndex: Integer): PShortString;
  public
    constructor Init(var AFirstString: Openstring; AArrayLength: Integer);
    function Equals(const AArray: TOpenArrayOfOpenString): Boolean;

    property SizeOfString: Integer read FSizeOfString;
    property pStart: PChar read FpStart;
    property ArrayLength: Integer read FArrayLength;
    property ItemPtrs[AIndex: Integer]: PShortString read GetItemPtr; default;
  end;

{ TOpenArrayOfOpenString }

constructor TOpenArrayOfOpenString.Init(var AFirstString: Openstring; AArrayLength: Integer);
begin
  FSizeOfString := SizeOf(AFirstString);
  FpStart := @AFirstString[0];//incl. length byte!
  FArrayLength := AArrayLength;
end;

function TOpenArrayOfOpenString.Equals(const AArray: TOpenArrayOfOpenString): Boolean;
begin
  Result := CompareMem(pStart, AArray.pStart, SizeOfString * ArrayLength);
end;

function TOpenArrayOfOpenString.GetItemPtr(AIndex: Integer): PShortString;
begin
  Result := PShortString(pStart + AIndex * SizeOfString);
end;

Siz buni quyidagi tarzda ishlatishingiz mumkin:

procedure f(const a: TOpenArrayOfOpenString);
var
  i: Integer;
begin
  for i := 0 to Pred(a.ArrayLength) do
    Writeln(a[i]^);
end;

procedure Test;
var
  A: array[1..2] of string[5];
  C: array[1..40] of string[12];
begin
  f(TOpenArrayOfOpenString.Init(A[1], Length(A)));
  f(TOpenArrayOfOpenString.Init(C[1], Length(C)));
end;

Tilga kiritilgan yechim bo'lishi mumkin emas va u haqiqatga/umidga asoslanganidek, biroz xakerlikdir ... qatordagi iplar bir-biriga yaqinlashib qolgan. Lekin bu menga bir muddat ishlagan.

1
qo'shib qo'ydi
   type
      shortStrings =array[1..2] of string[5];  
    ...
    a,b : shortString;
    ..
    procedure rock(a,b : shortStrings);
    ..
0
qo'shib qo'ydi