احمد غريب

الفرق الجوهرى بين pointer و reference

20 ردود في هذا الموضوع

السلام عليكم

تعتبر مشكله ال pointer من اكبر المشاكل التى تواجه مبرمجى السى و السى بلس بلس, فى الحقيقه المشكله ليست pointer ولكن reference التى تسبب سوء الفهم.

دعونى ابداء ببعض الامثله:

انظر لهذين المثالين:

void incr1(int* a){(*a)++;}

void incr2(int& a){a++;}

والان لإستدعاء incr1 او incr2 نقوم بالتالى :

incr1(&x);
incr2(x);

فى الحاله الاولى نستخدم pointer ولذالك نظطر لوضع العنصر a بعلامة * حتى نصل للمحتوى العنصر وفى اغلب الاحيان يفهم مبرمج السى والسى بلس بلس الداله الاولى دون اى مشقه, ولكن عندما يرى الداله الثانيه يصاب بالذهول ويفقد ما فهمه فى الداله الاولى. او على الاقل هذا ما كان يحدث لى , ربما يرجع ذالك لانى تعاملت معى الاسمبلى وفى الاسمبلى لا توجد الحاله الثانيه.

والان دعونى اعطيكم مثال ثلاث يعقد المسئله اكثر:

int* P=&i;

هذا دليل على ان p* معناها i&, هل اتضحت الصوره, لو p* هى نفسها i& إذاً لابد ان تكون ++(*a) تساوى ++(a&) , ولكن حسب المثال الاول فهذين التعبرين غير متساويين ؟؟؟!!!

دعونى اشرح لكم لماذا هذا الاختلاف الغير منطقى :

المشكله تكمن فى ان & لها معنين فى لغة السى على حسب مقعها من علامة =, لاحظ معى التالى:

i=5;
int* P=&i;

هذه الجمله تعنى ان i تحتوى على رقم معين من نوع int و i& هو العنوان الذى يحوى الرقم و P هى من نوع بوينتر يعنى بالعربى عنوان, هنا لا توجد اى مشكله والموضوع منطقى حتى الان ولكن لاحظ الان هذه الجمله:

i=5;
int &P=i;

هناك تكمن المشكله, ماهى P فى هذه الحاله, هل هى pointer بالتاكيد لا لانها ستحصل على قيمه i, فى هذه الحاله P هى reference, وماهو معناها؟؟

بكل إختصار وكى لا اطيل عليكم P و i كلاهما عنوان لنفس الذاكره حيث انك لو قمت بالعمليه التاليه:

P=6;

فانت بطريقه غير مباشره غيرت محتوى i والان i ايضاً تساوى 6.

لو عدنا الان للمثال الاول :

void incr1(int& a){a++;}
incr2(x);

لعرفنا من المثال ان ما قمنا به ما هو إلى إعطاء x إسم جديد الا وهو a وذالك باستخدام & بالطريقه الثانيه.

ملاحظه هامه :

int &P; //Error Error

فى لغه السى غير مسموح تعين reference بدون ان تذكر المقابل, لابد ان يكون هناك مقابل ل P& على النحو التالى:

int &P=i;

,ولابد ان يكون المقابل من نوع متغير ولا يجوز ان تضع قيمه وإنما متغير فقط.

هذه المعلومات لا توجد مشروحه بنفس الطريقه فى اى كتاب قراته ولا اى سايت حاولت التعلم منه, ولكن هى مجهود شخصى منى, وقد اكون على خطاء, ولكن كل التجارب التى قمت بها اوصلتنى لنفس النتيجه, لذالك ارجو من من لديه اى إضافه ان لا يبخل علينا بها.

ملحوظه:

كل هذه المعلومات مستخلصه فى كتاب Bjarne Stroustrup ولكنه لا يوضح العلاقه بين reference عندما تكون من ناحية الشمال لعلامة = او من ناحية اليمين وعلامة ال pointer.

والسلام عليكم

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أستاذ كبير

كبير جدا

يا عيني

قسم وسمعني :lol:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

والله اخى برق الموضوع دا بالذات حيرنى فتره طويله عشان كدا قلت خلينى اطرح الموضوع عشان افيد الاخوه فى المنتدى وفى نفس الوقت استفيد انا إن شاء الله.

انا لسى مبتدى فى لغه السى بلس بلس وبحاول افهم بس فى عقد كتيره, وانا ما احبش افهم نص نص, لازم اكون يا فاهم الموضوع كله يا بالاش.

وعلى فكره فى موضيع من النوع دا كتيرا اوى وإن شاء الله حطرحها للنقاش فى القريب العاجل.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

اهلا وسهلا اخي احمد غريب يعني شرحك واضح ومفهوم ولاعندي اضافات سواء تاكيد على كلامك فان مفهوم الموؤشرات pointers يعني اننا نتعامل مع متغير مثله مثل ايمتغير والميزه الوحيده له هو اننا نخزن بداخله عنوان يسهل علينا التعامل مع الذاكرة بشكل مباشر بواسطة هذا العنوان.

اما المرجع او الاشاره - لا أجد ترجمة مناسبة لها - reference فهو نفهمه على انه نسخة عن المنغير والفارق الوحيد هو الاسم أي اقصد عندما تكتب:

int & rx = x;

فهذا معناه ان الrx هو نسخة من x ففي اي مكان استخدمنا rx فكاننا نستخدم x .

ويمكننا بشكلكبير وسهل من التعامل مع reference في مواقع كثيرة من البرنامج واقرب مثال ماكتبته انت فوق من استدعاء الدوال فلاتحتاج لكتابةمعامل العنونه &. في استدعاء دالة كذلك لانحتاج لاستخدام معامل الوصول المباشر* فيجسم الدالة وهذا يعطينا تحكم اكبر وقلة في الاخطاء.

السؤال الذي يطرح نفسه متى نستخدم المؤشرات ومتى نستخدم reference؟

من يترى يجيب ؟!!!!1

والسلام عليكم.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

حيا الله السهم النارى فين الغيبه إن شاء الله تكون بخير والف عافيه.

رداً على سؤالك الكريم:

يقول stroustup وهو مصمم لغه السى بلس بلس, انه من الافضل إستخدام reference فى جميع الحالات التى يمكن إستخدامها فيه, وذالك لان إستخدامها يجبرك على إعطائها قيمه اوليه, اما ال pointer فلا يشترط إعطائها قيمه اوليه من ما يجعل قيمت المؤشر تؤشر إلى null, وهذا يتسبب فى خلل فى إستخدام الذاكره إذا لم تكن حذراً فى إستخدامها.

بالتاكيد هناك حالات كثيره لا تستطيع ان تستخدم ال reference فيها مثلاً فى اول مره تحجز فيها الذاكره او تريد ان تستخدم مؤشر إلى function معين الخ.

اظن افضل مثال للمؤشر هو عندما تسئل شخص "إسمك إيه" فيرد عليك "انا إسمى هانى" ثم يردف قائلاً " بس بيدلعونى يا بوائل" :

إذاُ نستخلص من هذا الحوار الشيق ان هانى هو هو وائل, ولو ناديت هانى او وائل فسيجيبك نفس الشخص, كذالك إذا إستخدمت xr او إستخدمت x فانت تستخدم نفس المحتوى الذى يكمن فى الذاكره.

اسف على المثال السخيف ولكن تقريباً هذه افضل طريقه عندى لإيصال المعلومه.

والسلام عليكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الله يحيك ويعافيك موجود في المنتدى والحمد لله.

وصلت المعلومه اخي احمد ونتظر منك المزيد وتشارك معنا هنا بكثره.

يعطيك العافيه.

على فكره بالعكس مثال الاسم مو مثال سخيف فالكثيريستخدمونه عند شرح المؤشرات .

وبالتوفيق أخي احمد.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مرحبا بكم جميعا..

Reference هي فقط تسمية للمتغير وليس نسخة منه..

يجب ان نفرق بين تمررير المتغيرات بالقيمة للدوال, و ما بين تعريف متغير على أنه تسمية جديدة.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم,

نعرف أننا يمكن أن نستعمل Reference في عدة مجالات كتمرير البارامترات وغيرها. وأظن أن من بين استعمالاتها المفيدة حين نتعامل مع المتغيرات من نوع const . ولهذا سأدرج هذه الأمثلة البسيطة حتى نرى كيف يمكن أن نتعامل معها .

int x=5;
int & rx=x;
int *p= &x;
int* k= ℞
*p=30;

هنا حين نقرأ قيم المؤشرات p و k يتضح لنا بالفعل أن القيمتان x و rx هما اسمان لمتغير واحد لأن لهما نفس العنوان وأن التغيير *p=30 سيغير قيمة الإثنين معا .

وفي هذا المثال :

const int x=5;
const int & rx=x;
int *p= (int*)&x;
int* k= (int*)℞
*p=30;

هنا نرى أن في الأول rx ستأخذ نفس قيمة x ولكن ستكون لهما عناوين مختلفة وبالتالي حين نغير *p=30 فسنرى أن x ستتغير ولكن rx ستحافظ على قيمتها.

إلى اللقاء.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

امثله رائعه اخى chik ولكن لى سؤال الان ما هو الفرق بين هاذين التعريفين

const int &rx=x;
int rx = x;

هل تصبح rx فى ذاكره مختلفه فى الحاله الاولى, فى هذه الحاله فالتعبرين غير مختلفين إلا فى شيئ واحد وهو ان فى الحله الاولى لا يمكن كتابة التالى

const int&rx

ولكن فى الحاله الثانيه يسمح بكتابة التالى

int rx;

يعنى بدون تحديد القيمه الابتدائيه.

لذالك ارجو التوضيح لو الامر غير ذالك.

والسلام

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

وعليكم السلام >>>>> ارد السلام بعد شهرين :)

عارف ان الرد متأخر لكن حبيت اشكرك+ ,ودّي اسأل .. الموضوع هذا وين مدفون؟؟ :rolleyes: ... لم اشاهد الموضوع الا اليوم ...

انا قرأت في احد كتب السي ان الفرق الرئيسي .. انه المراجع اسهلمن المؤشرات وبالتالي تستخدم لسهولتها .. هذا اللي كنت فاهمه :(

تم تعديل بواسطه الشـمري
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

تسلم والله ما قصرت

معلومات ممتازه نريد الكثير منها

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

Reference بياخذ نسخة من اسم المتغير.

Pointer بياخذ نسخة من عنوان المتغير .

الفرق هنا في رأيَ

Pointers تستخدم في هياكل البيانات Data Structures - Trees - Linked Lists..etc .

Reference بصعوبة جداً تستطيع استخدامها في هياكل البيانات ؟ - لم ار كود لهذا اطلاقاً ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

انا الحقيقة لم اتعرض لموقف احتجت فيه الReference من قبل

و لكن شكرا على المعلومة فربما لانني لم اكن اعرفها جيدا فلم اجد لها استخداما و ربما الان يمكنني ان اجد لها استخداما مفيدا :lol:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

انا كنت فاكر الموضوع دا مات وشبع موت كمان, سبحان الله....

الاخ الشمرى انا لا اعتقد ان المراجع اسهل من المؤشرات لان إمكانياتها محدوده وكما ذكر الاخ احمد صالح فلا تستطيع إستخدامها فى هياكل البيانات, كذلك انت مجبور ان تعطيها قيمه اوليه حتى تستطيع إنشائها وذلك حتى يجبر المستخدم بان يلتزم بقوانين معينه, المشكله الاساسيه والتى تحير كل مبتدء هى ان لها معنين, فهى مؤشر عندما تكون على يسار علامة = وعنوان عندما تكون على يمين العلامه.. كما هو موضح فى الامثله السابقه...

الجميل فى لغة الاسمبلى هو ان كل شيئ عنوان, المؤشرات عباره عن عناوين, المقابض ايضاً عناوين حتى الشفره لها عنوان ويمكنك إستدعائها عن طريق العناوين, والغريب فى الامر ان برامج السى والسى بلس بلس والدلفى بعد تحوليها إلى برامج تتحول المؤشرات والمقابض الخ .. إلى عناوين من نوع int..

والسلام عليكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم ..

هذا ما أحتاج إليه فِعلاً ..

بالفعل كان محيرني هو الفرق بينهم ، فالشكر الجزيل للأستاذ أحمد غريب ..

على هذا التوضيح الواضح كثير ... ونتمنى لمزيد والمزيد من هذه الدروس .. :rolleyes:

تحياتي ..

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اشكرك يا أحمد على الموضوع الجميل ده وأشكر كل من ساهم فيه

حقيقة انا لم أر هذا الدرس الا بعد الاشاره اليه في المواضيع المثبته , يعني جيت متاخر شهوووور

و لي وقفه مع هذه النقطه

int* p=&i;

هذا دليل على ان p* معناها i&, هل اتضحت الصوره, لو p* هى نفسها i& إذاً لابد ان تكون ++(*a) تساوى ++(a&) , ولكن حسب المثال الاول فهذين التعبرين غير متساويين ؟؟؟!!!

هذا الكود يفسر بهذا المعنى

int * p;
p = &i;

اذاً p هي التي تساوي &i

التغيير حدث في كلمة

int *

فمعناها عمل مؤشر لمتغير من نوع int

انا أستخدم طريقه بسيطه لفهم العلامتين * و & (الطريقه من تأليفي ومش عايز حد يضحك)

أفترض أن

* = 1/&

يعني * هي مقلوب &

اذاً من المعادله

p = &i;

بقسمة كل من الطرفين على &

(1/&)p = i; // كود asm4all

يعني

*p = i;

وهو المطلوب اثباته

لهذا

(*p)++;

تعني

i++;

نأتي للـ Reference , بنفس الطريقه

الفرق في

int &

وتعني اعادة تسمية المتغير كما قال ikossan

ومعنى

int & rx = x;

أعطي اسم جديد للمتغير x وسوف يكون rx

ومنها rx هو نفسه x أي انه متغير واحد باسمين

تم تعديل المشاركه بعد مشاركة الباشمهندس :D

تم تعديل بواسطه Asm4all
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
لهذا

*p++;

تعني

i++;

تصحيح بسيط

 *p++

تعني أن يزيد قيمة الpointer نفسه أي يشير للعنوان التالي أما اذا كنت تريد أن تقوم بعمل ما يكافئ ++i فيجب عليك كتابتها هكذا

 (*p)++

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

يااااااااااااااخبر ابيض هو الموضوع دا لسى عايش, اشكر كل من ساهم فى رفعه والاضافات الراقية من الاخ عاصم احمد فور اول ;) والاخ الباشمهندس

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

(*p)++;

صح , نسيت :D

عاصم

خطأ , مين عاصم ده يا جدعان :s

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

asm .... مش كدة بيكتبو عاصم بالبلغاري؟ :P

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .