التعامل مع المو شراتPointers في لغة++ C 1. مواقع الذاكرة يمكنا ن نعتبرشكل الذاكرة مثل صناديق البريد حيث تمثلكل خانة موقعفي الذاكرةو تقوم بتخزين قيمة وحيدة ) قد تكون صحيحة int او حقيقةfloat او (char كل موقعفي الذاكرة له عنوان و يتم تمثيل عناوين ال ذاكرة باستخدام النظام الست عشريمن باب التسهيل كون انهفي الاصل يمثل باستخدام النظام الثناي ي فعلى سبيل المثال لتمثيل الخانة رقم 15 باستخدام النظام الثناي ي فا ننا سوف نحتاج ا لى اربع خاناتهي 1111 على عكس النظام الست عشري الذي يمثلها بخانة واحدةهيF. 2 ح. جم الا نماطفي الذاكرة قبلا ن نخو ض بالمو شراتلا بدمن التذكير بطريقة عنونة المتحولات بالذاكرة. عندما نقومب تعريف ال متحولاتفي البرنامج فا نها تا خذ حيزا في الذاكرة بما يتناسب مع حجمها 1 2 4 4 8 Char Int long float double فعلى سبيل الم ثال void main() float F=32.5;. char C= A ; int I= 2; فمسيتحجز 4 حجرات للمتحول الشكل التالي I وسيكون تمثيلهم بالذاكرة على C وحجرتين للمتحول F وحجرة للمتحول
Memory Address 20004 20005 20006 20007 20008 20009 2000a 2000b 2000c 32.5 F A C 2 I 3.الحجز الاستاتيكي فكما را ينا فا نه يتم حجز حجم المتحولات تبعا لنمطها وهذا الحجز يسمى بالحجز الساكن الستاتيكي ) static (variable ويوصف بالساكنلا ن الذاكرة المكرسة له تبقى محجوزة له طوال مدة تنفيذ البرنامج, فالمترجم هنا يعرف تماما كمية الذاكرة التي تحتاجها المتحولات,ويخص ص المترجم حجرات المتحولات ال عامة والثوابت ضمن مقطع المعطيات segment) (data ومقطع المعطيات هذا عبارةعن مساحةمن الذاكرة محدودة الطول,يحدد ويقررحجمهاالمترجمبناء على عدد ونوع المتحولات العامة والثوابت المصرح عنها بالبرنامج,ا ما المتحولات المحلية Variable) Local )والبارمترات فالمت رجم يخص ص لها حجراتفي الذاكرة عندما يتطلب تنفيذ البرنامج ذلك,ولكن يحجز المترجم بشكل ا ولي كميةمن الذاكرة المكدس (Stack) من ا جل هذه المتحولات وطول مقطع المكدس ثابت ويحدد ا ثناء الترجمة للبرنامج فالخلاصةا ن الحجز الستاتيكي يتم تحديد كمية الذاكرة المخصصة ا ثناء ترجمة البرنامج وقبل تنفيذه,نلا هذه الكمية ثابتهلا تتغير. 4.الحجز الديناميكي لنفر ض ا ننا نريد برنامجمن ا جل ترتيب معطيات عددية يدخلها المستخدمولا ا عرف هذه الكمية والكمية ليست ثابته فمن ا جل ذلك يوجد طريقتين الا ولى ا ن ا حجز مصفوفةذات حجم كبير بحيث تكفي لتخزين القيم المتوقعة وهنا سنحجز كمية كبيرةمن الذاكرة عن طريق الحجز الاستاتيكي الثانية عن طريق استخدام المو شرات والحجز الديناميكي ا ن المبدا الاساسي للتعامل مع المتحولات الديناميكية هوتخصي ص ذاكرة ديناميكية للبرنامج يتم الحجز ضمنها لهذه المتحولا ولات ستخدامها وبعد الانتهاء يتم تحرير الحجز ) ا عادة الذاكرة المحجوزة لاستخدامات اخرى ( فيما بعد. ا ذا نحن الان سنت عامل مع طريقة جديدة مع الذاكرة وهي تخصيص حجرات الذاكرة ا ثناء التنفيذ ) تنفيذ البرنامج ( وليس ا ثناء الترجمة (compile) ترجمة البرنامج. ولكن كيف يمكنا التعامل هذه المتحولات الديناميكية وكيف سوف نصرح عنها
تتم طريقة الحجز باستخدام مو شرات (عناوين )ا لى الذاكرة- الديناميكية والتي تسمى الكومةHeap وستم بهذه الطريقة بسبب فكرة الاخذ والاعادة منها وا ليها,والخلاصةا ن استخدام المتحولات الديناميكيةلا يتم مباشرة بلعن طريق مو شر. 5. عناوين المتحولاتفي الذاكرة لكل خليةمن خلايا ذاكرة الحاسب عنوان محد د,والعنوان هو رقم يبدا من 0 وينتهي بالقيمة العظمى لسعة الذاكرة. كي نستطيعان نعرف عنوانمتحولفي الذاكرة نقوم با ضافة الا شارة& قبل ال متحول وهي تعني عن وان ال متحول ) Of (Address لاحظ #include "iostream.h" #include "conio.h" void main() int x; cout << "Enter Number "; cin >> x; cout << "\nthe Number is" << x << endl; cout << "\nand The address in memory is "<< &x << endl; getch(); يظهرعنوان المتحول يظهر محتوى المتحول عند تجربة البرنامج تظهريلي النتيجة التالية
Momery Address 0x0012FF78 0x0012FF79 0x0012FF7a 0x0012FF7b 0x0012FF7c 0x0012FF7d 0x0012FF7e 5 X 6.المو شرات والتصريح عنها المو شر عبارة عنمتحول يحتوي على عنوانفي الذاكرة (و ليس قيمة عادية) وهو يشير الى to) (Point العنوان الذي يحتويهو بالتالي فهو يشير ا لىمتحول ا خر... يتم التصريحعن المو شرفي البرنامج بتحديد نوع المعطيات التي يشير اليها ) ا يهل يشير ا لى قيمةمن نوع- int char-float..)ثم اضافة العلامة ) الرمز) نجمة * ثم اسم المو شر. <متحول> * > نوع المعطيات التي يشير لها المو شر> Memory int *iptr; float *fptr; double *dptr;
لا حظوا معي الم تحول iptrهو عبارةعن مو شرمن النوع الصحيح, ا ي عنوانفي الذاكرة يتا لفمن حجرتين ومحتويات هاتين الحجرتين سوف تفسر على ا نها ا عداد صحيحة. المتحولfptr هو عبارةعن مو شرمن النوع الحقيقي,ا يا ن العنوان المخزنفي المتحول يفهم على ا نه عنوان بداية مساحةمن الذاكرة بطول ا ربعة بايتات ومحتويات هذه الحجرا ا دعات د صحيحة. المتحول dptrهو عبارةعن مو شرمن النوع المضاعف, ا يا ن العنوان المخزنفي المتحول يفهم على ا نه عنوان بداية مساحةمن الذاكرة بطول ثمانية بايتات ومحتويات هذه الحجرات ا عدادمن النمط المضاعف. تفقناان الرمز& يعيد عنوان المتغيرفي الذاكرة لاحظ هذا المثال int y = 5; int *yptr; yptr = &y; // y تا خذ عنوان yptr ان انشاء المو شر يتم على مرحلتين الاولى نعلن فيهاعن المو شرyPtr و الثانية نستد اليه عنوانمتحولفي الذاكرةو ذلك يعنيانyPtr سوف ييشرا لىا لمتحولy في الذاكرةو بالتاليمن المكن التعامل معy بشكل غير مباشرعن طريق yptrا ي بمعنى ا خر ا صبحت القيمة داخل y الخمسةهي نفسهامحتوى القيمة التي يشر اليها المو شرyPtr. كل ال متحولاتمن نوع مو شر لها نفس الحجمفي الذاكرةو هو حجم العنوان الذي تحتويه ) فهي مجهزة لتخزين العناوين) Example // PoiterAddress.cpp #include <iostream.h> int main() int x = 1, y = 5; cout<<endl<<&x<<endl<<&y; int * ptr; ptr = &x; cout<<endl<<ptr; ptr = &y; cout<<endl<<ptr; return 0; x0065fdf40 0x0065FDF0 0x0065FDF4 0x0065FDF0 ا ن هذا البرنامج يقوم بتعريف المتحولينy x, ويهيي هما بالقيمتين 5 1, ومن ثم يقوم بطباعة عناوينهما,ومن ثم يق وم بتعريف متحولمن نوع مو شر ا لى قيمةص حيحة وذل كمن خلال الا مر (x int * ).من المعل وم ا نه لدى تعريف متحول ما فا نهلن تكون له ا ية قيمة,وبالتالي يمكنا ن يا خذ قيمةع شواي ية,ولك نفي المو ش راتف ا نه ذه القيمة تمثل عنوانا من الذاكرة.ولذا يتوجب قبل استخداما ي مو شرا ن نضع فيه عنوانا محد دا. وخلاصة القول ا ن المو شر يحمل عنوان متحولمن نوعم ا,وه ذا العن وان يجب تحدي ده وا لا فا ن المو ش رق دي شير ا لى غير المكان المقصود.
7. غاية المو شر عندما نعرفعن مو شر فا ننا نستخدم الصيغة *varptr) (int حيثان اسم المو شر هوvarPtr و لكنا نستخدم الصيغةvarPtr * داخل البرنامج ) كتعبير)من اجل الوصول ا لى محتويات المتحول الذي يشير اليه المو شرvarPtr ويسمى غاية المو شر void main () int *varptr; Int var = 20 ; varptr = &var; cout << *varptr; // 20 cout << var ; // 20 يستخدم اسم المو شر مسبوق بالنجمةفي البرنامج من اجل الوصل ا لى محتويات المتحول الذي يشير اليه, ويسمىغاية المو شر و هكذاعلينا الانتباه ا لى استخد ام *varptr في جملة الاعلان يشير ا لى قيمةمن نوع عدد صحيح. استخدام *varptr في البرنامج كتعبير التي يشير اليها المو شرvarPtr. 8.الوصول ا لى المتحول المشارا ليه *varptr; int تعني اننا نعلنعن مو شر اسمهvarPtr و *varptr; cout >> تعني اننا نتعامل مع محتوى القيمة يمكن الوصول ا لى محتويات متحول لا نعرف اسمه ولكنا نعرف عنوانه كما في المثال التالي Example // PointersSource.cpp #include "stdafx.h" #include <iostream.h> int main() int x = 1, y = 5; int * ptr; ptr = &x; cout<<endl<<*ptr; ptr = &y; cout<<endl<<*ptr; return 0;
عند وضع عنوان متحول ما ضمن مو شر يجبا ن يكون المتحول والمو شرمن نفس النوعولا يمكن وضع عنوان متحولمن نوعfloat ضمن مو شر ا لى النوعint. لكن تعريف المو شر مو شر ا لىvoid مثل ) ptr ( void * يجعلمن الممكن لهذا المو شرا ن يشير ا لىا ي نوعمن المعطيات Example int main () الاعلانعن متحولين صحيحين // 15; = value2 int value1 = 5, int* p1; الاعلانعن مو شر يشير ا لى قيمةمن نوع عدد صحيح // ;p2 int* الاعلانعن مو شر ثاني يشير ا لى قيمةمن نوع عدد صحيح // &value1; p1 = جعل المو شر الاول يشير ا لى المتحول الاول // &value2; p2 = جعل المو شر الثاني يشير ا لى المتحول الثاني // ;10 = p1* تخزين القيمة 10 في المتحول الذي يشير اليه المو شر // ;p1* p2* = مساواة قيم المتحولات التي تشير لها المو شرات // ;p2 p1 = جعل المو شر الثاني يشير ا لى المتحول الذي يشير اليه المو شر الاول // ;20 = p1* تخزين القيمة 20 في المتحول الذي يشير اليه المو شر الاول // cout << "value1==" <<value1<<" value2=="<< value2; return 0; ملاحظات يمكن للمو شراتا ن تا خذ عنوانا جديدا بالمعامل new ا وا ن تا خذ عنوان ا حد المتحولات التي تنسجم مع ما تو شر عليه ) ا يلا يجوز ا سناد عنوان متحولint ا لى موشر على float )والحجزمن خلال المعامل new يتم بالشكل التالي PointerVar=new datatype; حيث datatype هي نمط قيمة المو شر عندما صرحنا عنه وهنا يتم حجز مكان جديدفي الذاكرة. لا يمكن الوصول ا لى محتوى المتحول الذيمن نمط مو شرا لا بعدا ن تتم تهيي ته ) ا ي بعدا ن يحمل عنوانا معينا ). الحذفا ي تحرير المنطقة الذاكرية المحجوزة لهذا ال مو شر يتممن خلال التابعdelete وفق الصيغة delete PointerVar; القيمة الخاصةNULL تعنيا ن المو شرلا يو شر علىا ي قيمة وهي مختلفةعن المعاملdelete فعند عملية التحرير هذا يعنيا ن المو شر لم يعد لها ي مكانفي الذاكرة ا يا ن داخلهلا يوجد عنوان ذاكري لحجرة ماب ينما عند ا سناد القيمةNULL هذا يعنيا ن له قيمة خاصةلا تمثل عنوانا فعليا ) مثل الصفر)والوصول ا لى القيمة المحتواة ضمنه سيولد خطا. يجب الانتباها ن ا سناد المو شرات يو دي ا لىا ن تحمل نفس العنوانو بالتاليا ي تغيرفي المحتوى يسري مفعوله على كلا المتحولين ا مات غير القيم فيا خذ مفعوله مرة واحدةو تبقى العناوين منفصلة علما ا ن ا سناد مو شراتمن قيم مختلفة
غير مقبول حتى لو كانت ا كبرا ي مو شر على قيمةfloat لا يمكنها ن يحتوي على مو شر على قيمة التي هيمن نمط intوfloat تخضع لنفس القواعد التي تعلمناها. int بينما القيم القسم الا ول المهندس محمد ناشد