Mamy zmienną integer. Zajmuje ona w pamięci 4 bajty. Chcemy pobrać te 4 bajty zamienić na 4 kody ASCII i wstawić do zmiennej string. Potem chcemy zrobić czynność odwrotną.
Możemy zrobić tak:
type
TIntegerChar = packed array[1..4] of Char;
var
i: Integer;
c: TIntegerChar;
begin
c:=TIntegerChar(i);
TIntegerChar(i):=c
end;
Przepisanie z c do stringa to chyba nie jest problem...
To nie o to chodzi.
Chodzi o bezpośrednie odwołanie do pamięci.
To nie o to chodzi.
Chodzi o bezpośrednie odwołanie do pamięci.
Var
i :integer;
s: string;
begin
i:=229234;
SetLength(s,4);
Move(i, s[1], 4);
// albo Mpve(s[i], i, 4) nie pamietam, sprawdz
Nadal nie jest to bezpośrednie odwołanie do pamięci.
Można też tak
var
i: Integer;
hhh : string;
begin
i := 2147483647;
hhh:= inttohex(i,8);
i := strtoint('$'+hhh);
hhh := inttostr(i);
end;
Ale to nadal nie to.
Nadal nie jest to bezpośrednie odwołanie do pamięci.
A co rozumiesz przez bezpośrednie odwołanie. Może chcesz tak (przez wskaźniki)?
type
TBytePtr=^Byte;
var
i, j: integer;
s: string;
ip: TBytePtr;
begin
SetLength(s,4);
i:=65+25666+6553667+6553625668;
ip:=@i;
for j:=1 to 4 do
begin
s[j]:=char(ip^);
inc(ip);
end;
Label1.Caption:=s;
end;
Tak dzięki to jest niezłe ale można krócej
type
TBytePtr=^Pointer;
var
i: integer;
s: string;
ip: TBytePtr;
sp: TBytePtr;
begin
SetLength(s,4);
i:=65+25666+6553667+6553625668;
ip:=@i;
sp:=@s[1];
sp:=ip;
messagebox(0,PChar(s),'lll',MB_OK);
end;
Ale czy istnieje możliwość aby dwie zmienne integer i string wskazywały na ten sam adres w pamięci. Tzn mając adres zmiennej integer deklarujemy zmienną string tak aby wskazywała na ten sam adres co zmienna integer. Czy to się w ogóle da.
type
TIntegerChar = packed array[1..4] of Char;
var
i: Integer;
c: TIntegerChar;
begin
c:=TIntegerChar(i);
TIntegerChar(i):=c
end;
To też jest bezpośrednie...
Ale czy istnieje możliwość aby dwie zmienne integer i string wskazywały na ten sam adres w pamięci. Tzn mając adres zmiennej integer deklarujemy zmienną string tak aby wskazywała na ten sam adres co zmienna integer. Czy to się w ogóle da.
Tak, da się, poprzez rekordy wariantowe
type
TMojRekord=packed record
case integer of
0: (i: integer);
1: (s: array[1..4]of char); //nie mozna uzyc string[4] bo ma on pole zerowe zawierajace dlugosc
end;
var
x: TMojRekord;
begin
x.i:=65+25666+6553667+6553625668;
Label1.Caption:=x.s;
end;
To jest świetne rozwiązanie.
Ale ciekawe, które jest najefektywniejsze.
To jest świetne rozwiązanie.
Ale ciekawe, które jest najefektywniejsze.
Nie wiem, które najefektywniejsze, ale to na pewno najprostrze :) :
var
i: Integer;
s: array [1..4] of Char absolute i;
begin
i := 65+66 shl 8+67 shl 16+68 shl 24;
ShowMessage(s);
end;
Tak to najlepsze i chyba najefektywniejsze rozwiązanie.
Gratulacje.
Przecież wszystkie działają na tej samej zasadzie i są jednakowo efektywne.
Przecież wszystkie działają na tej samej zasadzie i są jednakowo efektywne.
No nie bardzo są jednakowo efektywne.
W dwóch ostatnich nie ma przepisywania zmiennej spod jednego adresu do drugiego. Wszystko jest pod jednym adresem w pamięci.
No tak [wstyd]
s: array [1..4] of Char absolute i;
Dryobates, masz u mnie wielkiego plusa (niestety symbolicznego, bo to nie moj watek)