10-08-2017, Saat: 19:19
(Son Düzenleme: 10-08-2017, Saat: 23:42, Düzenleyen: uparlayan.
Sebep: resim eklendi
)
(10-08-2017, Saat: 16:06)uparlayan Adlı Kullanıcıdan Alıntı: SizeOf bazı veri tiplerinde doğru sonucu vermez bilginize...
Neden ?
Çünkü;
SizeOf, bir değişkenin veya type'in bayt cinsinden depolama boyutunu verir.
Length ise bir dizinin veya stringin karakter sayısını verir.
Aradaki farkı aşağıdaki örnek kod parçacığından da test edebilirsiniz;
procedure TForm1.Button1Click(Sender: TObject); var S: String; begin S := 'ali veli'; Memo1.Clear; memo1.Lines.Add(SizeOf(S).ToString); // 4 memo1.Lines.Add(Length(S).ToString); // 8 end;
Bu konunun uzmanı değilim, böyle bir sorunun sorulmuş olmasını da açıkçası olumlu buluyorum, zira bu tarz kaliteli sorular çoğaldıkça insanın feyz alması başka bir keyif veriyor.
Ben olaya biraz daha farklı bakıp, variant değişkenin bir dizi olması durumunda bunun TByte cinsinden nasıl toplanabileceği ile ilgili farklı bir örnek kod paylaşmak istiyorum, (dediğim gibi fazla bir bilgim yok, o nedenle beni fazla hırpalamayın lütfen )
( Aşağıdaki kodu spagetti bulabilirsiniz, bazı veri tipleri için tam olarak bitmediğini de ifade etmek lazım, mazur görün lütfen. )
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Data.DB, Datasnap.DBClient, SynEdit, SynMemo; type TForm1 = class(TForm) Button1: TButton; Memo1: TSynMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TByteArr = TBytes; // veya aşağıdaki gibi //TByteArr = array of Byte; var Form1: TForm1; implementation {$R *.dfm} function StrToByte(const Value: String): TByteArr; var I : Integer; Ebat: Integer; begin Ebat := Length(Value); SetLength(Result, Ebat); for I := 0 to Ebat - 1 do Result[I] := ord(Value[I + 1]); end; function ByteToByte(const Value: Byte): TByteArr; begin SetLength(Result, 1); Result[0] := TByteArr(@Value)[ 0 ]; end; function IntToByte(const Value: Integer): TByteArr; var I : Integer; begin SetLength(Result, 4); for I := 0 to 3 do Result[I] := TByteArr(@Value)[ I ]; end; function WordToByte(const Value: Word): TByteArr; begin SetLength(Result, 2); Result[0] := TByteArr (@Value) [ 0 ]; Result[1] := TByteArr (@Value) [ 1 ]; end; function LongWordToByte(const Value: LongWord): TByteArr; var I : Integer; begin SetLength(Result, 4); for I := 0 to 3 do Result[I] := TByteArr(@Value)[I]; end; function Int64ToByte(const Value: Int64): TByteArr; var I : Integer; Ebat: Integer; begin Ebat := SizeOf(Value); SetLength(Result, Ebat); for I := 0 to Ebat - 1 do Result[I] := TByteArr(@Value)[I]; end; function VarToByte(const Value: Variant; var BaytSayisi: Integer): TByteArr; var Ebat, EkEbat: Integer; Miktar : Integer; Pointer : PVariant; I, J, Q, W : Integer; VeriTipi : Integer; Eklenti : TByteArr; W64 : Int64; Wrd : Word; LW : LongWord; S: String; begin if (VarIsArray(Value) = TRUE) then begin // Diziyi kilitleyip, gerçek değerleri tutan belleğe işaretçi koyuyoruz, bu anlamda aslında bu tıpkı SQL'de CURSOR kullanmaya benziyor... Pointer := VarArrayLock(Value); // Dizinin ilk bakıştaki uzunluğunu elde ediyoruz, bazı veri tipleri veriy yerine adresi tuttuğu için bu böyle... Ebat := VarArrayHighBound(Value, 1) - VarArrayLowBound(Value, 1) + 1; // Sonuç kümesinin boyunu parametremizdekiyle eşitliyoruz, ki zaten devamında bu kısım genişleyecek ama şimdilik bu böyle... SetLength(Result, Ebat); J := 0; // Sonuç kümesindeki bayt sayısını bununla takip edeceğiz... Miktar := Ebat; // Bu aslında varyant dizinin eleman sayısını veriyor... for I := 0 to Miktar - 1 do begin // Variant Dizinin her bir elemanı üzerinde tek tek tarama yapıyoruz... VeriTipi := VarType(Pointer^); case VeriTipi of varBoolean : begin Result[J] := Pointer^; Inc(J); end; varByte : begin Result[J] := Pointer^; Inc(J); end; varSmallInt , varWord : begin Wrd := Pointer^; EkEbat := SizeOf(Wrd); // Buna da Dikkat ! SetLength(Eklenti, EkEbat); Eklenti := WordToByte(Wrd); Ebat := Ebat + EkEbat - 1; SetLength(Result, Ebat); for Q := 0 to EkEbat - 1 do begin Result[J] := Eklenti[Q]; Inc(J); end; end; varLongWord : begin Wrd := Pointer^; EkEbat := SizeOf(Wrd); // Buna da Dikkat ! SetLength(Eklenti, EkEbat); Eklenti := LongWordToByte(Wrd); Ebat := Ebat + EkEbat - 1; SetLength(Result, Ebat); for Q := 0 to EkEbat - 1 do begin Result[J] := Eklenti[Q]; Inc(J); end; end; varSingle , varDouble , varCurrency : begin // araştırma konusu... end; varOleStr , // varStrArg , // varObject , varUStrArg , // varAny , varUString , varString : begin S := Pointer^; EkEbat := Length(S); // Dikkat ! SetLength(Eklenti, EkEbat); Eklenti := StrToByte(S); Ebat := Ebat + EkEbat - 1; SetLength(Result, Ebat); for Q := 0 to EkEbat - 1 do begin Result[J] := Eklenti[Q]; Inc(J); end; end; varInteger : begin W := Pointer^; EkEbat := SizeOf(W); // Buna da Dikkat ! SetLength(Eklenti, EkEbat); Eklenti := IntToByte(W); Ebat := Ebat + EkEbat - 1; SetLength(Result, Ebat); for Q := 0 to EkEbat - 1 do begin Result[J] := Eklenti[Q]; Inc(J); end; end; varInt64 : begin W64 := Pointer^; EkEbat := SizeOf(W64); // Buna da Dikkat ! SetLength(Eklenti, EkEbat); Eklenti := Int64ToByte(W64); Ebat := Ebat + EkEbat - 1; SetLength(Result, Ebat); for Q := 0 to EkEbat - 1 do begin Result[J] := Eklenti[Q]; Inc(J); end; end; end; Inc(Pointer); // Sonraki elemanına geçiyoruz end; VarArrayUnlock(Value); // Dizinin kilidini açıyoruz... BaytSayisi := J; end else begin end; end; procedure TForm1.Button1Click(Sender: TObject); var ba: TByteArr; I: Integer; V: Variant; vava: array of Variant; X: Integer; function iif(aBoolean: Boolean; aTrue: string; aFalse: String): String; begin if aBoolean then Result := aTrue else Result := aFalse; end; begin Memo1.Lines.Clear; V := Variant('abuzer kadayıf'); vava := [ Byte(3) , V , Integer(1453) , SmallInt(1453) , Int64(1071) , word(65537) // 256x256=65536 ! , AnsiString('AAA') , String('BBB') , WideString('CCC') ]; ba := VarToByte(Vava, X); for I := Low(ba) to High(ba) do begin Memo1.Lines.Add( IntToHex( ba[I], 4) + ' ' + iif(ba[I] > 31, Chr(ba[I]), ' ' ) + ' (' + ba[I].ToString + ')' ); end; Memo1.Lines.Add('Bayt Sayısı = ' + X.ToString); SetLength(ba, 0); //FreeAndNil(ba); end; procedure TForm1.Button2Click(Sender: TObject); var S: String; begin S := 'ali veli'; Memo1.Clear; memo1.Lines.Add(SizeOf(S).ToString); // = 4 memo1.Lines.Add(Length(S).ToString); // = 8 end; end.
YouTube Delphi Tips
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa
"Yaşlanarak değil, yaşayarak tecrübe kazanılır. Zaman insanları değil, armutları olgunlaştırır" Peyami Safa