لمحة عن التعامل مع المؤشرات في الدلفي(pointer)
#1
بسم الله الرحمن الرحيم
اليوم إن شاء الله راح نشوف لمحة بسيطة عن التعامل مع المؤشرات

المؤشر هو VARIABLE الذي محتواه يحتون على عنوان في الذاكرة

لإعلان عن مؤشر نستعمل (^)
مثال
كود :
Pvariable:^integer ;
Pvariable هي عنوان في الذاكرة
في معظم الحالات عند الإعلان عن مؤشر نستعمل الحرف P هذا لكي نعاود مراجعة السورس نستطيع تمييزه
PMyVariable
PSum
Padd
و هنالك نوعان من المؤاشرات
1- typed pointer
2- untyped pointer

سوف نرى الفرق بينهما

قبل الخوض في أنواع المؤشر أود التلويح لشئ مهم و هما Function Addr و operator @
أخي القارئ لكي تفهم أهمية ما ذكرته ما عليك إلى المتباعة و سوف تفهم إن شاء الله

1- typed pointer

كود :
var Pvariable :^integer; i : integer; begin Pvariable :=@(i); Pvariable^ :=4; Edit1.Text :=IntToStr(i); end;
Pvariable :=@(i); = لإسترجاع عنوان variable i
Pvariable^ :=4; = نعطي رقم 4 ل variable i يعني عنوان variable i في الذاكرة
جيد الآن سوف نرى كيفية إنشاء مؤشر جديد
كود :
type Pvar=^integer; var Pvariable:Pvar;
شوف هذا الكود تم نخوض في الموضوع
كود :
Type Pvar = ^integer; var Pvariable : Pvar; begin New(Pvariable); Pvariable^:=4; Edit2.Text := IntToStr(Pvariable^); Dispose(Pvariable); end;

الجديد الآن هو New و Dispose و هما عبارة عن procedure
و نستعملها لإدارة مساحة الذاكرة
نستعمل New لتخصيص مساحة في الذاكرة
نستعمل Dipose لمسح المساحة التي خصصنها في الذاكرة

كما يمكننا أيضا إستعمال GetMem و FreeMem
و لهم نفس العمل
مثال
كود :
Type Pvar = ^integer; var Pvariable : Pvar; begin GetMem(Pvariable,sizeof(integer)); Pvariable^:=4; Edit3.Text:=IntToStr(Pvariable^); FreeMem(Pvariable,sizeof(integer)); end;
2- untyped pointer
للإعلان نستعمل pointer
مثال
كود :
Ppot:pointer;
نستعمل هذا النوع لإسناد محتوى أي typed pointer
مثال
كود :
var Pvariable :^integer; Ppot:point begin Ppot:=Pvariable;
في هذه الحالة سوف ترجع لنا قيمة عشوائية للمؤشر

و يمكننا أيضا إسناد قيمة معينة
كود :
var Ppot:pointer; i : integer; begin i :=4; Ppot:=@(i); integer(Ppot^):=i; Edit4.Text:=IntToStr(Integer(Ppot^)); end;
هذا كل شئ و يمكنك أخي المتتبع التعمق في دراسة Pointer


الملفات المرفقة
.rar   The Pointer.rar (الحجم : 1.91 ك ب / التحميلات : 115)
الرد
#2
جميل اخي الكريم,
درس جديد بالنسبة ليSmile لم اتعامل مع المؤشرات من قبل,
إقتباس :يحتون على عنوان في الذاكرة
طيب طرحت اخي الكريم لمحة عن المؤشرات, لكن لم تطرح لماذا تستخدم هذه المؤشرات غير انه يحتوى على عنوآن في الذآكرة,
طيب في اي حآل يحتاج المبرمج حجز مثلا مكان في الذآكرة ؟ الا يحجز الدلفي تلقآئيّا مكان في الذآكرة عند الحآجة الى ذلك؟ ولماذا نحتاج الى عناوين في الذاكرة ؟ وماذا نستفيد من ذلك
هذه اسئلة مبدئيّة,

بارك الله لكم جميعا,
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد
#3
السلام عليكم ورحمة الله
آه... سبقتني أخي paix144
كنت سأكتب موضوع طويل وشيق حول المؤشرات
إقتباس :طيب في اي حآل يحتاج المبرمج حجز مثلا مكان في الذآكرة ؟ الا يحجز الدلفي تلقآئيّا مكان في الذآكرة عند الحآجة الى ذلك؟ ولماذا نحتاج الى عناوين في الذاكرة ؟ وماذا نستفيد من ذلك
هذه اسئلة مبدئيّة,
يتضمن الإجابة عن هذه الأسئلة كلها Smile
هناك أشياء لا يمكن فعلها إلا باستخدام المؤشرات
عندما يقال: دلفي يجمع بين السهولة والقوة (يقصد بالقوة أساسا إمكانية استخدام المؤشرات وإدراج ASM)
... يتبع.
اللهم احقن دماء المسلمين، لا تنسوهم بالدعاء...
الرد
#4
السلام عليكم
أخي كاش واحد و الله عندما كنت أكتب الموضوع فكرت باش نعطيك الموضوع لإحدات إضافات
يمكنك إضافة ما تشاء أخي
أخي AL-MOB4RM3G
سأعطيك بعض نقاط قوة المؤشرات في البرمجة
يستعمل غالبا في المشاريع الكبيرة لإيجاد لا يمكن حلها بطريقة أخرى
المؤشرات سريعة و لا تستهلك الكثير من الذاكرة
مبدأ المؤشرات هو تسسير الذاكرة
==========================
شوف هذا المثال أخي وجدت في أحد المواقع
لو طلبنا من واحد مبتدأ إستغلال Procedure GetComputerName
لعمل هذا
كود :
S: String; Size: Cardinal; begin Size := 255; GetComputerName(PChar(S), Size); ShowMessage(S); end;
الصحيح هو هذا
كود :
var S: PChar; Size: Cardinal; begin S := StrAlloc(MAX_COMPUTERNAME_LENGTH + 1); Size := MAX_COMPUTERNAME_LENGTH + 1; GetComputerName(S, Size); ShowMessage(S); StrDispose(S); end;
و بعض API يجب التعامل معهم بالمؤشرات
الرد
#5
السلام عليكم

موضوع المؤشرات طويل كنت كدلك أعد له الا أن الوقت لم يسمح لي بترتيب الموضوع

اضافة لتعريف المؤشر

المؤشر عبارة عن عدد صحيح في 32 بت و هو بحجم 4 بايت والدي يحتوي على عنوان ما في الداكرة(متغير)

وهدا مثال آخر يزيد من التوضيح

PHP كود :
var i:Integer;
p1,p2:^Integer;
begin
 i
:= 10;
 
p1:=@i;
 
p2:=p1;
 
p2:=@p1;
 
form1.Caption:= IntToStr(p2^);
end; 

السطر االأول نسند قيمة للمتغير i
السطر الثاني المؤشر p1 سيحتوي على عنوان المتغير i
السطر الثالت المؤشر p2 يؤشر على نفس العنوان الدي يؤشر اليه p1 وكدلك قيمة المتغير الدي يؤشر اليه p1 والدي هو i
أي p2^=i
السطر الرابع المؤشر p2 يؤشر فقط على على عنوان p1 في الداكرة أي p2^<>i
لا اله الا أنت سبحانك اني كنت من الضالمين
الرد
#6
السلام عليكم
موضوع جميل , فقط كإظافة :thumbs: :

PHP كود :
//Table Pointer ...
Type
 MyArr 
= Array [0..9] Of Byte;
 
PMyArr = ^MyArr;
//.................

//Record Pointer ...
{$A-}//Packed Record//
Type
 MyRec 
= Record
 F_Name
: String[50];
 
L_Name: String[60];
 
Age: Byte;
 
End;
PMyRec = ^MyRec;
//...................

procedure TForm1.Button1Click(Sender: TObject);
Var
 
Ref: PMyArr;
 
i: Byte;
begin
New(Ref);
For 
i:= 0 To High(MyArr) Do
 
Ref^[i]:= Trunc(Random(255));
MessageBoxA(0,Pchar('#5 : ' + IntToStr(Ref^[4])),Nil,0);
Dispose(Ref);
end;

procedure TForm1.Button2Click(Sender: TObject);
Var
 
Ref: PMyRec;
begin
New(Ref);
With Ref^ Do
 
Begin
 F_Name
:= 'TF6M';
 
L_Name:= 'M6FT';
 
Age:= 22;
 
End;
MessageBoxA(0,Pchar(Format('My Name : %S ' +
                     
#13 + 'My Last Name : %S' +
                     #13 + 'My Age: %d'
             
,[Ref^.F_Name,Ref^.L_Name,Ref^.Age])),Nil,0);
Dispose(Ref);
end; 

كما نلاحظ فإن تطبيقات المؤشرات كثيرة منها الجداول و أيضا المسجلات كالمثال
السابق :thumbsup: ... بالتوفيق ,,
I'M Fly Like A G6

الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم