اشاره گر چیست ؟ { تعریف ، کاربرد و اشتباهات ما هنگام کار با اشاره گرها}
مقدمه
با سلام خدمت همه شما دوستان. ما قبلا در مورد ساختارها صحبت کرده بودیم. اما در این جلسه قصد داریم در مورد اشاره گرها صحبت کنیم. این که اصلا چی هستند ، چطور از اونها استفاده کنیم و معمولا برنامه نویس ها چه اشتباهاتی هنگام کار با اشاره گرها مرتکب میشن.
اشاره گر چیست؟
اشاره گرها ، یکی از ویژگی های قدرتمند زبان C و ++C هست که اون ها رو از سایر زبان های برنامه نویسی مثل پایتون و جاوا متفاوت میکنه. اشاره گرها برای این استفاده میشن که ما بتونیم به حافظه به صورت مستقیم دسترسی داشته باشیم.
آدرس ها در زبان C :
اجازه بدید قبل از این که مفهوم یک اشاره گر رو دقیقتر بفهمیم ، با آدرس ها در زبان C بیشتر آشنا بشیم.
اگه شما در برنامه تون یک متغیر با نام Var داشته باشید ، در این صورت Var& نشون دهنده آدرس این متغیر در حافظه است. معمولا به عملگر & میگن “reference operator ” .
در تابع scanf از علامت & استفاده میشه. بدین صورت که مقداری رو که کاربر وارد میکنه در آدرس اون متغیر ذخیره میشه. به عنوان یک مثال ، دستور زیر رو در نظر بگیرید:
scanf("%d", &var);
در این دستور ، مقداری که کاربرد وارد میکنه در آدرس متغیر var ذخیره میشه. اجازه بدید برای فهم بهتر این موضوع ، یک مثال بزنیم:
/* Example to demonstrate use of reference operator in C programming. */ #include <stdio.h> int main() { int var = 5; printf("Value: %d\n", var); printf("Address: %u", &var); //Notice, the ampersand(&) before var. return 0; }
در کد بالا ، در خط 6 ، مقدار متغیر Var و در خط 7 ، آدرسی که در اون متغیر Var ذخیره شده رو نشون میده. بدین ترتیب ، خروجی به صورت زیر خواهد بود:
Value: 5 Address: 2686778
یعنی مقدار متغیر var برابر 5 و خانه ای از حاقظه که در اون ، این متغیر ذخیره شده ، خانه 2686778 می باشد. به عبارت ساده تر “عدد 5 در خانه شماره 2686778 ذخیره شده. “
تذکر: ممکنه وقتی که شما این کد رو اجرا میکنید ، عدد مربوط به خانه حافظه ، برای شما متفاوت باشه.
تعریف یک متغیر به صورت اشاره گر:
در زبان C ، به متغیری که تنها آدرس متغیرهای دیگه رو ذخیره میکنه میگن “متغیر اشاره گر” که به اختصار “اشاره گر” نامیده میشه. اشاره گرها به صورت زیر تعریف میشن:
data_type* pointer_variable_name; int* p;
همانطور که در توضیحات آمده است در مثال بالا ، p یک متغیر اشاره گر از نوع int هست.
معرفی اپراتورهای reference (&) و dereference (*)
همونطور که گفتیم ، به اپراتور & ، اپراتور reference ، گفته میشه. با استفاده از این اپراتور ما میتونیم آدرس یک متغیر رو بدست بیاریم.
به همین شکل ، یک اپراتور دیگه وجود داره که به شما مقدار یک آدرس رو میده. به این اپراتور میگن ، اپراتور dereference و با علامت * (ستاره) نشون داده میشه. در مثال زیر نحوه استفاده از اشاره گرها و اپراتورهای reference و dereference آورده شده:
تذکر: ما در هنگام تعریف یک اشاره گر از علامت * استفاده میکنیم. توجه داشته باشید که این علامت با اپراتور dereference شبیه هست ولی اصلا اون اپراتور نیست و نباید این دو تا رو با هم دیگه اشتباه گرفت.
مثالی برای درک بهتر مفهوم اشاره گر
/* Source code to demonstrate, handling of pointers in C program */ #include <stdio.h> int main(){ int* pc; int c; c=22; printf("Address of c:%u\n",&c); printf("Value of c:%d\n\n",c); pc=&c; printf("Address of pointer pc:%u\n",pc); printf("Content of pointer pc:%d\n\n",*pc); c=11; printf("Address of pointer pc:%u\n",pc); printf("Content of pointer pc:%d\n\n",*pc); *pc=2; printf("Address of c:%u\n",&c); printf("Value of c:%d\n\n",c); return 0; }
اگه این کد رو کامپایل و اجرا کنیم ، خروجی مطابق شکل زیر خواهد بود:
Address of c: 2686784 Value of c: 22 Address of pointer pc: 2686784 Content of pointer pc: 22 Address of pointer pc: 2686784 Content of pointer pc: 11 Address of c: 2686784 Value of c: 2
توضیح :
خط 4 : یک اشاره گر با نام pc و در خط 5 نیز یک متغیر عادی با نام c ایجاد شده است. چون pc مقدار دهی اولیه نشده اند ، اشاره گر pc به آدرس خاصی اشاره نمیکند و اگر هم اشاره کند به یک آدرس random اشاره میکند. در حالی که متغیر c به یک آدرس مشخص اشاره میکند ولی دارای مقداری random است.
خط 6 : مقدار متغیر c برابر 22 قرار داده شده است. یعنی عدد 22 در آدرسی که متغیر c دارد ذخیره شده است.
توجه داشته باشید که وقتی مینویسیم c& ( آدرس c ) باید از u% استفاده کنیم نه d% . چون آدرس همیشه یک عدد مثبت هست.
همونطور هم که میبینید در خطوط بعد آدرس c و خود c در خروجی چاپ شده اند.
خط 9 : آدرس متغیر c برابر اشاره گر pc قرار داده شده است. در خروجی هم همونطور که مشاهده میکنید ، ارزش ( مقدار) pc برابر آدرسی است که c در آن ذخیره شده است و محتوای pc ( یعنی pc*) برابر محتوای c یعنی 22 است.
خط 12 : مقدار متغیر c برابر 11 قرار داده شده است. دراین خط مقدار c رو تغییر دادیم تا ببینیم که بر روی اشاره گر pc چه اتفاقی میفته.
چون اشاره گر pc به آدرس متغیر c اشاره میکنه و آدرس c تغییر نکرده ، پس مقدار pc همون آدرس c هست ولی محتوای pc برابر محتوای جدید c ، یعنی 11 میشود.
خط 15: محتوای آدرسی که pc به اون اشاره میکرد تغییر کرده. مقدار این محتوا برابر 2 شده است.
در خطوط بعد هم میبینید که آدرس متغیر c (که همون آدرسی هست که اشاره گر pcبه اون اشاره میکنه )تغییر نکرده است به همین علت همان آدرس قبلی چاپ شده ولی محتوای آن تغییر کرده است. ( محتوای آن برابر 2 شده است. )
تذکر: توجه داشته باشید که pc یک آدرس هست ولی pc* محتوای اون آدرس هست.
خیلی دور از ذهن نیست اگه بگیم دو عملگر * و & اگه با همدیگه استفاده بشن ، همدیگه رو خنثی میکنن. شکل زیر گویای همه چیز هست:
اشتباهات متداول هنگام کار با اشاره گرها
در شکل زیر 4 نمونه آوردیم که دو تا از این نمونه ها درست و دوتا از اون ها هم نادرست هستند. حتما سعی کنید این اشتباهات رو هنگام کار با اشاره گرها انجام ندید.
int c, *pc; // Wrong! pc is address whereas, c is not an address. pc = c; // Wrong! *pc is the value pointed by address whereas, %amp;c is an address. *pc = &c; // Correct! pc is an address and, %amp;pc is also an address. pc = &c; // Correct! *pc is the value pointed by address and, c is also a value. *pc = c;
علت اشتباه بودن مورد 1 : pc یک آدرس است در حالی که c یک آدرس نیست. پس برابر قرار دادن این دو اشتباه است.
علت اشتباه بودن مورد 2: pc* مقداری است که در آدرسی که pc به آن اشاره میکند ذخیره شده است.در حالی pc& یک آدرس است. پس نمیتوان این دو را برابر قرار داد.
علت صحیح بودن مورد 3 : هم pc و هم c& آدرس هستند. پس برابر قرار دادن آنها مشکلی ندارد.
علت صحیح بودن مورد 4 : pc* یک مقدار است و c هم یک مقدار است. پس میتوان این دو را مساوی قرار داد.
خوب دوستان. این جلسه هم به پایان رسید. ما به مرور زمان جلسات خیلی کاملتری رو از زبان C در سایت قرار میدیم. مثل همیشه میتونید ما رو در تلگرام و یا اینستاگرام دنبال کنید:
20 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
خدا خیرتون بده?
بسیار عالی و ساده توضیح دادید
تو چهارسال دانشگاه اینو نمیفهمیدم اصن
خواهش میکنم.
ممنون از لطف شما.
بسیار عالی ممنون
سپاس از لطف شما.
سلام خدمت نویسنده ی عزیز این مطلب
باید اعتراف کنم 5 دقیقه مطالعه ی این مطلب، قد 5 جلسه، کلاس حضوری برام مفید بود.
واقعا ممنونم
پایدار باشید 🙂
سپاس از لطف شما.
خیلی ازتون ممنونم.فردا امتحان دارم و با توضیحاتتون خیلی خوب این مبحث رو فهمیدم.
مرسی?
با سلام.
بسیار هم عالی.
انشالا که فردا امتحان خوبی داشته باشید.
موفق باشید.