PDA

View Full Version : سوال: اینجا Absolute به چه معناییه؟



Mask
یک شنبه 07 آبان 1391, 16:36 عصر
Var I,J : Byte;
C : ansiChar Absolute I;
اینجا Absolute به چه معناییه؟

BORHAN TEC
یک شنبه 07 آبان 1391, 16:57 عصر
سلام
با کمی تحقیق فهمیدم در بالا متغییر C دقیقاً به I اشاره می کند، به عبارتی بهتر متغیر c دقیقاً از فضای حافظه ای I استفاده می کند. شاید بگویید که این دیگر چه کار مسخره ای است ولی یک مثال جالب در این رابطه پیدا کردم که تا به حال آنرا ندیده بودم. به این مثال دقت کنید:
procedure TMyForm.EditableChange(Sender: TObject);
var
edit: TEdit absolute Sender;
memo: TMemo absolute Sender;
combo: TComboBox absolute Sender;
begin
if Sender is TEdit then
begin
edit.Text := Uppercase(edit.Text);
end
else if Sender is TMemo then
begin
memo.Text := Uppercase(memo.Text);
end
else if (Sender is TComboBox) and (combo.Style = csDropDown) then
begin
combo.Text := Uppercase(combo.Text);
end;

SetDirtyFlag(TRUE);
end;

پیشنهاد می کنم که باز هم به کد بالا دقت کنید! :متعجب:
در بالا متغیرهای edit و memo و combo دقیقاً به Sender اشاره می کنند. ولی از آنجایی که Sender می تواند یک TEdit ویا TComboBox و یا TMemo باشد با استفاده از کلمه کلیدی Absolute توانسته ایم که عملیات را به شکل بهتری کنترل کنیم. در حقیقت کاری که این keyword می کند این است که باعث می شود متغیر تعریف شده از فضای حافظه متغیر دیگری استفاده کنید.

این هم یک منبع خوب برای مطالعه بیشتر:
http://www.deltics.co.nz/blog/?p=586

موفق باشید...

Felony
دوشنبه 08 آبان 1391, 06:44 صبح
این رهنمود از زمان دلفی 7 وجود داشت ، همونطور که شاهین گفت با استفاده از این رهنمود کامپایلر رو وادار میکنیم که برای یک متغییر فضای جدیدی در Stack در نظر نگیره و از فضای متغییر Map شده استفاده کنه .

زمانی که از این رهنمود استفاده میکنید حق مقدار دهی اولیه به متغییر رو ندارید ( متغییری که به صورت absolute تعریف شده ) ، و همچنین اجازه ترکیب اون با رهنمودهای دیگه رو هم ندارید .

مثالی برای اینکه بهتر متوجه بشید ، کد زیر رو در نظر بگیرید :

var
Str: string[32];
StrLen: Byte absolute Str;
begin
Str:= 'Delphi';
ShowMessage(IntToStr(StrLen));
end;

بعد از اجرای کد بالا عدد 6 نمایش داده میشه ، خوب چرا ؟

دلیل این رفتار این هست که ما متغییر Str رو با رشته Delphi مقدار دهی کردیم و متغییر StrLen به فضای Str مپ شده ، خوب همونطور که میدونید بایت اول رشته ها طول اونها رو نگهداری میکنه ، StrLen حاوی مقدار اولین بایت موجود در فضای متغییر Str هست ، بنابراین ما عدد 6 رو به عنوان خروجی میبینم چون طول رشته Str ما 6 هست .

حالا کد زیر رو اجرا کنید :

var
Str: string[32];
StrLen: Byte absolute Str;
begin
Str:= 'Delphi';
ShowMessage(IntToStr(StrLen));
StrLen:= 8;
ShowMessage(Str);
end;

خوب ؟ طول رشته ما 6 بود ، تو کد ما مقدار StrLen رو به 8 تغییر دادیم ، پس به عبارتی مقدار بایت اول رشته رو تغییر دادیم و رشته رو بزرگتر از اونچه که هست معرفی کردیم ، پس از اجرا به جز کلمه اصلی کاراکترهای عجیب و غریب هم میبینیم که با اون کاری که کردیم طبیعی هست ، کامپایلر مقادیر موجود تو حافظه رو به انداز طول رشته که از بایت اول رشته میخونه واکشی میکنه ، 6 کاراکتر اول همون کلمه مورد نظر ما ( Delphi ) هست ولی 2 کاراکتر باقی مقادیر قبلی در این محل از حافظه هستند !

مثال دیگه ای که قبلا تو یکی از سایت ها دیده بودم و برای خودم ذخیره کرده بودمش ، فرض کنید میخوایم یک بایت از یک عدد صحیح integer رو ( 32 بیتی ) واکشی کنیم ، خوب هر بایت 8 بیت هست ، بنابر این عدد Integer ما از 4 بایت تشکیل شده ، حالا تابع زیر رو ببینید :

function getIntByte(thisInteger: Integer; ByteIndex: Byte): Byte;
var
int_bytes: array[0..3] of Byte absolute thisInteger;
begin
Result := int_bytes[ByteIndex];
end;

متغییر int_bytes به فضای پارامتر ورودی thisInteger مپ شده ، بنابراین خیلی راحت بادادن ایندکس بایت مورد نظر میشه اون رو از فضای متغییر thisInteger واکشی کرد ، مثلا بایت 2 از عدد 2012 رو لازم داریم :

ShowMessage(IntToStr(getIntByte(2012, 1)));

موفق باشید .