المؤشرات pointer

*معنى المؤشر pointer : -
- هو نوع من انواع البيانات . ويعرف بانه متغير يحتفظ ( يخزن به ) بعنوان مكان فى الذاكرة . أى هو( متغير يُستخدم ليحمل عنوان متغير آخر فى الذاكرة )
- اى أن المؤشر يشير إلى مكان فى الذاكرة.
- من المعلوم أن كل مكان فى الذاكرة له عنوان والجهاز يتعامل مع هذا المكان بالعنوان المحدد له ونحن بطريقه غير مباشرة نتعامل مع هذا العنوان .
- فمثلا فى هذا الاعلان int d = 5 ; معناه احجز مكان فى الذاكرة ram حجمه 2 byte واجعل اسمه d وضع فيه القيمة 5
- عندما ترغب فى استخدام المؤشرات هناك خطوتان :-
· الأولى : أن تعلن عن هذا المؤشر وتخبر المترجم عن اسمه وعن نوعيه البيانات التى تشير إليها.
· الثانية : تهيئ هذا المؤشر بأن تجعله يشير إلى احد المتغيرات الفعلية

** الإعلان عن المؤشر **
- عندما ترغب فى استخدام المؤشر يجب ان تعلن عنه اولاً كما نفعل مع بقية المتغيرات ( أي يتم الإعلان عن مؤشر إلى اى متغير من انواع البيانات بنفس الطريقة التى تعلن بها عن البيانات العادية )
- وعندما ترغب فى الإعلان عن مؤشر يجب ان نحدد شيئيين :-
الأول : هو اسم المؤشر ويتم اختيارة كما نختار المتغيرات العادية
الثانية : هو نوعية البيانات التى سيشير إليها
- هـذا الإعلان يخبر المترجـم أن المتغير p أصبح مؤشراص الى مساحة فى الذاكرة مقدارها 2 byte مع الاحتفاظ بعنوان هذا المكان فى المتغير p
float * degree;
- هذا الاعلان يخبر المترجم أننا نريد استخدام المؤشر degress وان هذا المؤشر سيشير إلى بيانات من نوع float

- وإذا كنت ستستخدم المؤشر ليشير إلى تركيب يجب أن تعلن عن التركيب أولاً . مثل :
struct student
{
char name[40];
int mark;
}
ثم نعلن عن المؤشر بعد ذلك . مثل :
struct student *st;
** تهيئة المؤشر **
- بعد أن نعلن عن المؤشر يتم تهيئته اى نجعله يشير إلى عنوان فى الذاكرة فعلاً ويتم ذلك باستخدام معامل العنوان & هذا المعامل يستخدم للحصول على عنوان أى متغير فى الذاكرة الجهاز
- هذا المعامل من المعاملات الأحادية unary وعندما نضعه قبل احد المتغيرات فإنه يعنى عنوان هذا المتغير فى الذاكرة مثلاً: scanf(“%d”,&var);
- مثال على تهيئة المتغير وجعله يشير إلى عنوان فى الذاكرة
كود:

int num; int *ptr; num = 5; ptr = &num
;- فى هذه العبارات نعلن عن المتغير العددى num ثم نعلن عن المتغير ptr الذى سنستخدمه كمؤشر ليشير إلى عنوان المتغير num فى الذاكرة
- بعد ذلك نهيئ المتغير num ونضع فيه الرقم 5
- أما العبارة ptr = &num فاننا نستخدم المعامل & لنحصل على عنوان المتغير num فى الذاكرة ونضع هذا العنوان فى المؤشر ptr
- بهذا الشكل يصبح المؤشر ptr حاملاً لعنوان المتغير num أى انه ( يشير ) إلى هذا المتغير.
** استخدام المؤشر ** هناك طريقتان لاستخدامه :-
الطريقة الأولى : هى ان تستخدم العنوان الموجود فى المؤشر .
- فى هذه الحالة نستخدم اسم المؤشر بدون إضافات.
- فمثلا إذا أردت ان نمرر العنوان إلى إجراء آخر نكتب : addten(ptr);
- هنا نستدعى الإجراء addten ونمرر له المؤشر ptr اى عنوان المتغير num فى الذاكرة
الطريقة الثانية : هى ان تستخدمه لتعديل قيمة المتغير
- فى هذه الحالة نضع حرف ( * ) قبله مثلاً *ptr = 10 ;
- فى هذه الحالة نعدّل قيمة المتغير num إلى 10 ولكن بطريقة غير مباشرة
- كذلك يمكن ان نستخدم المؤشر لقراءة محتويات العنوان الذى يشير إليه المؤشر نكتب a=*ptr;
* تمرين :
كود:
كود:
 	#include<stdio.h> void main(void) { int u = 3; int v; int *pu;  /* pointer to an integer */ int  *pv  /* pointer to an integer */
كود:
كود:
pu = &u; /* assing address of u to pu */ v = pu; /* assign values of u to v */ pv =&v; /* assing address of v to pv */ printf(“\n u=%d &u=%x pu=%x *pu=%d” , u , &u , pu , *pu); printf(“\n v=%d &v=%x pv=%x *pv=%d” , v , &v , pv , *pv); }
ملاحظات :
- لاحظ ان pu مشير إلى u ,pv مشير إلى v . وعلى هذا يمثل عنوان u ويمثل pv عنوان v
- فى السطر الأول u تمثـل القيمة 3 ويتحـدد عنوان u تلقائيا بواسطة المترجم بأنه مثلا FF8E (فى النظام السادس عشر )
- وتتحدد هذه القيمة للمشير pu . لذا يمثل pu العنوان ( السادس عشر ) FF8E
- كذلك القيمة التى يشير إليها pu ( اى القيمة المخزنة فى خلية فى الذاكرة التى عنوانها FF8E ) تعنى 3
- وبالمثل فى السكر الثانى يبين أن v تمثل القيمة 3 حيث اننا حددنا القيمة *pv الى v