Apr
26المؤشرات Pointers
Filed Under (Programming) by Sophto_92 on 26-04-2009
Tagged Under : knol, Pointers, المؤشرات
الموضوع الاصلي من هنا : knol.google.com
السلام عليكم ،،،
1. المؤشرات Pointers
لو قمنا بتعريف متغير x من نوع int كالتالي :
int x = 9;
الآن، عندما نريد استخدام هذا المتغير في الكود البرمجي، فالذي نقوم به هو فقط الإشارة للمتغير x ومن المنطقي أنه سيحمل القيمة 9 وليس العنوان الخاص به 5 في الذاكرة كما هو موضح في الصورة اعلاه. لكن لفترض اننا نريد العنوان الخاص بهذا المتغير في الذاكرة لسبب ما. في هذه الحالة نقوم بالتالي:
int y = &x;
القيمة المخزنة في المتغير y هي بالطبع العنوان الخاص بالمتغير x في الذاكرة وهي 5. لتعريف متغير كمؤشر نقوم بالتالي:
int *k;
ماقمنا به هو تعريف متغير k كمؤشر من نوع int. وعندما نريد استخدام هذا المؤشر فهناك امرين مهمين:
- استخدام اسم المتغير k يعني اننا نريد فقط العنوان او المؤشر للخانة الخاصة بهذا المتغير في الذاكرة.
- استخدام المتغير k* يعني اننا نريد القيمة الفعلية وليس العنوان الخاص به في الذاكرة.
مثال بسيط على اخر نقطتين :
int *z = 0;
- استخدام z يعني 4 ، كما هو موضح في الصورة اعلاه.
- استخدام z* يعني 0 ، كما هو موضخ في الصورة اعلاه.
2. استخدام المؤشرات Pointers
للمؤشرات استخدامات كثيرة جداً في لغات البرمجة، من اهم هذه الاستخدامات الارسال عن طريق عنوان (Pass By Reference) نوضحه بمثال:
1. #include<stdio.h>
2. void test1(int m, int n) //تعريف لدالة تستقبل متغيرين
3. {
4. m=5;
5. n=24;
6. }
7. void test2(int *m, int *n) //تعريف لدالة تستقبل مؤشر لمتغيرين
8. {
9. *m=5; //تخزين الرقم 5 كقيمة فعلية داخل المتغير
10. *n=24; //تخزين الرقم 24 كقيمة فعلية داخل المتغير
11. }
12. int main(void)
13. {
14. int a=10, b=16;
15. printf(”a=%d, b=%d\n”,a,b);
16. test1(a,b);
17. printf(”a=%d, b=%d\n”,a,b);
18. test2(&a , &b);
19. printf(”a=%d, b=%d\n” , a , b);
20. return 0;
}
توضيح للكود اعلاه:
- في السطر (16) مناداة الدالة (test1(10,16 وسوف تقوم هذه الدالة في السطرين (4) و (5) بتغير القيمة الى 5 و 24. لكن كما تعلم ان المتغيرين m و n هما خاصين فقط بالدالة test1 وليس لهما اي تأثير خارج هذه الدالة. لذلك عند الوصول للسطر (17) تقوم دالة الطباعة printf بطباعة الرقمين 10 و 16 وليس 5 و 24.
- لكن عند السطر (18) يتم مناداة (test2(&10,&16 وسوف تقوم بإرسال متغيرين يحملان العنوان في الذاكرة لكل من a و b للدالة test2. كما ترى في السطر(7) فالدالة تتوقع مؤشرين كما فعلنا في السطر(18)، وعند الوصول للسطر (9) و (10) نقوم بتغير القيم لكل من a و b الى 5 و 24 بدلاً من القيمة السابقة 10 و 16. استطعنا فعل ذلك بسبب ارسال عناوين الذاكرة الخاصة بـa و b بدلا من ارسال القيم الفعلية لهما كما في test1. وعند الوصول لدالة الطباعة في السطر(19) printf تقوم بالتأكيد بطبع 5 و 24 على التوالي.
مثال اخر يوضح قوة استخدام المؤشرات Pointers:
1. #include <stdio.h>
2. main()
3. {
4. int i1, i2, *p1, *p2;
5. i1 = 5;
6. p1 = &i1;
7. i2 = *p1 / 2 + 10;
8. p2 = p1;
9. printf(”i1=%d, i2=%d, *p1=%d, *p2=%d\n”, i1, i2, *p1, *p2);
}
توضيح للكود اعلاه:
- في السطر (4) قمنا بتعريف متغيرين عاديين ومتغيرين كمؤشر.
- في السطر (6) قمنا بتخزين عنوان الذاكرة الخاص بـil في المؤشر p1. وفي هذه الحالة اصبح المتغير p1 يشير الى المتغير il.
- في السطر (7) قمنا بإستخراج القيمة الفعلية في p1 بإستخدام p1* وهي 5. ثم قمنا بعملية حسابية بسيطة وتخزينها في المتغير i2.
- في السطر (8) قمنا بتخزين عنوان الذاكرة الخاص بـp1 وهوا الذي يشير الى il في المؤشر p2.
- في السطر (9) بإستخدام دالة الطباعة، النتائج سوف تكون كالتالي:
i1 = 5, i2= 12, *p1= 5, p2= 5
للتكملة فقط، تجدر الإشارة ان الـArrays في لغة C تستخدم المؤشرات، مثال :
1. int array[5] = {1,3,6,7,5};
2. int x = array[0];
3. int y = *(++array);
توضيح للكود اعلاه:
- في السطر (1) قمنا بتعريف Array تحتوي على خمسة عناصر.
- في السطر (2) قمنا بتعريف متغير x يحتوي على القيمة الموجودة في [array[0 وهي 1 في هذه الحالة. تعتبر هذه الطريقة الاولى والمعروفة للتنقل بين العناصر في الـArrays باستخدام رقم بين القوسين يدل على ترتيب العنصر في الـ Arrays.
- في السطر (3) array++ قمنا بزيادة المؤشر اللذي كان يشير لاول عنصر في الـArray الى الأشارة الى العنصر الثاني في الـArray. ثم عن طريق استخدام العلامة * الخاصة بإستخراج القيمة الفعلية من المؤشر، تم تخزين القيمة 3 في المتغير y.
٣- فيديو توضيحي
فيديو يوضح بطريقة مبسطة المقصود بالمؤشرات وكيفية استخدامها، مفيد جداً.
أ - درس Lab03 مادة Operating Systems في جامعة الملك فهد للبترول المعادن.
ب - Wikipedia















