SizeOf/fi
│
Deutsch (de) │
English (en) │
suomi (fi) │
русский (ru) │
Käännösaikainen funktio SizeOf
arvioi tietyn tyyppisen nimen tai muuttujan tunnisteen koon tavuina (byte).
sizeOf
voi olla myös käännösaikaisissa laajennuksissa, kuten kääntäjädirektiiveissä.
Käyttö
SizeOf
esiintyy erityisesti assembly-kielessä tai kun suoritetaan muistin manuaalista allokointia:
program sizeOfDemo(input, output, stderr);
{$typedAddress on}
uses
heaptrc;
type
s = record
c: char;
i: longint;
end;
var
x: ^s;
begin
returnNilIfGrowHeapFails := true;
getMem(x, sizeOf(x));
if not assigned(x) then
begin
writeLn(stderr, 'malloc for x failed');
halt(1);
end;
x^.c := 'r';
x^.i := -42;
freeMem(x, sizeOf(x));
end.
Rakenteellisten tietotyyppien suora käsittely assembly-kielellä edellyttää myös tietojen (datan) koon tuntemusta:
program sizeOfDemo(input, output, stderr);
type
integerArray = array of integer;
function sum(const f: integerArray): int64;
{$ifdef CPUx86_64}
assembler;
{$asmMode intel}
asm
// ensure f is in a particular register
mov rsi, f // rsi := f (pointer to an array)
// check for nil pointer (i.e. empty array)
test rsi, rsi // rsi = 0 ?
jz @sum_abort // if rsi = nil then goto abort
// load last index of array [theoretically there is highF]
mov rcx, [rsi] - sizeOf(sizeInt) // rcx := (rsi - sizeOf(sizeInt))^
// load first element, since loop condition won't reach it
{$if sizeOf(integer) = 4}
mov eax, [rsi] // eax := rsi^
{$elseif sizeOf(integer) = 2}
mov ax, [rsi] // ax := rsi^
{$else} {$error unexpected integer size} {$endif}
// we're done, if f doesn't contain any more elements
test rcx, rcx // rcx = 0 ?
jz @sum_done // if high(f) = 0 then goto done
@sum_iterate:
{$if sizeOf(integer) = 4}
mov edx, [rsi + rcx * 4] // edx := (rsi + 4 * rcx)^
{$elseif sizeOf(integer) = 2}
mov dx, [rsi + rcx * 2] // dx := (rsi + 2 * rcx)^
{$else} {$error unexpected scale factor} {$endif}
add rax, rdx // rax := rax + rdx
jo @sum_abort // if OF then goto abort
loop @sum_iterate // dec(rcx)
// if rcx <> 0 then goto iterate
jmp @sum_done // goto done
@sum_abort:
// load neutral element for addition
xor rax, rax // rax := 0
@sum_done:
end;
{$else}
unimplemented;
begin
sum := 0;
end;
{$endif}
begin
writeLn(sum(integerArray.create(2, 5, 11, 17, 23)));
end.
FPC:llä integer
kokonaisluvun koko riippuu käytetystä
kääntäjän moodista.
SizeOf(sizeInt)
lisättiin kuitenkin vain esittelyä varten.
{$ifdef CPUx86_64}
haarassa sizeOf(sizeInt)
on aina 8
.
Vertailevia huomautuksia
Dynaamiset taulukot ja vastaavat
Koskadynaamiset taulukot toteutetaan osoittimina
are realized as pointers to a block on the heap, sizeOf
arvioi osoittimen koon.
Dynaamisen taulukon koon määrittämiseksi. SizeOf
on käytettävä yhdessä funktion length
kanssa.
program dynamicArraySizeDemo(input, output, stderr);
uses
sysUtils;
resourcestring
enteredN = 'You''ve entered %0:d integers';
totalData = 'occupying a total of %0:d Bytes.';
var
f: array of longint;
begin
setLength(f, 0);
while not eof() do
begin
setLength(f, length(f) + 1);
readLn(f[length(f)]);
end;
writeLn(format(enteredN, [length(f)]));
writeLn(format(totalData, [length(f) * sizeOf(f[0])]));
end.
Lähestymistapa on sama ANSI strings merkkijonoille (riippuen myös {$longstrings}
kääntäjän kytkimen tilasta, jota merkitään myös string
).
Ei saa unohtaa, että dynaamisissa taulukoissa on hallintatiedot viitatun hyötykuorman edessä. Joten jos todella halutaan tietää, kuinka paljon muistia on varattu yhdelle taulukolla, niin on otettava huomioon myös suurin (viimeinen indeksi taulukossa) ja viitearvojen kentät.
Luokat
Luokat (class) ovat myös viitteitä. Luokka TObject
tarjoaa
funktion instanceSize
. Se palauttaa olion koon, koska se määräytyy luokan tyypin määritelmän mukaan. Lisämuistia, jota rakentajat (constructor) ovat käyttäneet tai mikä tahansa metodi, ei oteta huomioon. Huomaa, että luokat voivat sisältää myös dynaamisia taulukoita tai ANSI-merkkijonoja.