به نهمین جلسه از آموزش برنامه نویسی ++C خوش آمدید. در این جلسه با مبحث اشاره گر در ++C آشنا خواهیم شد.
اشاره گر در ++C
کار را با یک سوال آغاز می کنیم؟ اگر ما بخواهیم یک عدد صحیح را درون یک متغیر ذخیره کنیم، از چه نوع متغیری استفاده می کنیم؟ جواب long ، int و … است. یک عدد اعشاری را چطور؟ آن را هم در یک متغیر از جنس float یا double ذخیره می کنیم. حالا یک سوال دیگر: اگر بخواهیم آدرس یک خانه از حافظه را در یک متغیر ذخیره کنیم، از چه نوع متغیری باید استفاده کنیم؟
جواب سوال فوق را نمی دانیم، چون تا به حال با چنین موردی برخورد نکرده ایم. از آنجا که آدرس حافظه نه int است و نه float و نه هیچ نوع دیگری، پس می بایست از یک مفهوم جدید استفاده کنیم. این مفهوم جدید اشاره گر (pointer) نام دارد که در این جلسه به شرح آن خواهیم پرداخت.
طبق تعریف، اشاره گر متغیری است که حاوی یک آدرس باشد. از آنجا که در این تعریف از واژه متغیر استفاده کرده ایم، پس اشاره گر هم مانند متغیر ۴ ویژگی نام، جنس، مقدار و آدرس را خواهد داشت. تنها تفاوت در مقداری است که در درون آن ذخیره می شود، و آن چیزی نیست غیر از آدرس یک خانه از حافظه.
اشاره گر در ++C
عملگر ارجاع (Reference Operator)
پیش از اینکه نحوه تعریف اشاره گر در ++C را بررسی کنیم، لازم است تا با مفهوم عملگر ارجاع آشنا شویم. عملگر ارجاع را با کاراکتر & نشان می دهیم. کار این عملگر دریافت آدرس یک خانه حافظه است. یعنی اگر ما بخواهیم آدرس متغیر n را بدست بیاوریم، کافیست تا عملگر ارجاع & را قبل از اسم آن متغیر قرار دهیم.
به قطعه کد زیر توجه کنید:
1 2 3 4 5 6 7 |
int main() { int n = 44; cout << "n = " << n << endl; cout << "&n = " << &n << endl; } |
در قطعه کد بالا در خط ۵ مقدار متغیر n و در خط ۶ آدرس آن را چاپ کرده ایم. خروجی به صورت زیر است:
1 2 |
n = 44 &n = 0x7fff5e9b5aac |
تعریف و مقداریابی اشاره گر در ++C
1 2 3 4 5 6 7 8 9 10 |
int main() { int n = 44; cout << "n = " << n << " , &n = " << &n << endl; int* pn = &n; cout << "pn = " << pn << endl; cout << "&pn = " << &pn << endl; cout << "*pn = " << *pn << endl; } |
در قطعه کد فوق در خط ۴ مقدار متغیر n و آدرس آن چاپ شده است. در خط ۶ یک اشاره گر به نام pn تعریف کرده و آن را به n اشاره داده ایم (آدرس n را درون اشاره گر ذخیره کرده ایم). عبارت *int به این معنی است که اشاره گر تعریف شده به یک خانه از جنس int اشاره می کند (* علامت اشاره است). پس این نکته را به خاطر بسپارید: جنسی که برای یک اشاره گر در ++C ذکر می شود، جنس خودش نیست. جنس خانه ای است که به آن اشاره می کند.
در خطوط ۷ ، ۸ و ۹ مقادیر pn ، pn& و pn* چاپ شده است. با pn به محتوای درون اشاره گر (آدرس n) و با pn& به آدرس اشاره گر دسترسی خواهیم داشت. pn* نیز به معنی مقداریابی اشاره گر است و منظور محتوای خانه ای است که pn به آن اشاره می کند.
خروجی این قطعه کد به این صورت است:
1 2 3 4 |
n = 44 , &n = 0x7fff5e4b7a8c pn = 0x7fff5e4b7a8c &pn = 0x7fff5e4b7a80 *pn = 44 |
اینکه برای مقادیر n& و pn مقادیر یکسانی چاپ شده است، نشان می دهد که pn در حال اشاره به n است (آدرس n را در درون خود دارد). اینکه برای pn& آدرس متفاوتی چاپ شده نیز به این معناست که اشاره گر متغیر مستقلی است و آدرس مستقلی دارد. جهت توضیحات بیشتر به ویدئوی ضمیمه آموزش مراجعه کنید.
نکته جالب توجه در خط ۴ دیده می شود. اینکه ما بصورت غیرمستقیم و بدون استفاده از نام متغیر n ، از طریق اشاره گر pn توانسته ایم به مقدار متغیر n دسترسی پیدا کنیم. به این مدل استفاده از اشاره گر مقداریابی اشاره گر گفته می شود.
اشاره گر به اشاره گر
اشاره گر به هر چیزی که آدرس داشته باشد، می تواند اشاره کند، حتی به یک اشاره گر دیگر.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
int main() { int n = 44; cout << "n = " << n << " , &n = " << &n << endl; int* pn = &n; cout << "pn = " << pn << endl; cout << "&pn = " << &pn << endl; cout << "*pn = " << *pn << endl; int** ppn = &pn; cout << "ppn = " << ppn << endl; cout << "&ppn = " << &ppn << endl; cout << "*ppn = " << *ppn << endl; cout << "**ppn = " << **ppn << endl; } |
در قطعه کد فوق خطوط ۳ تا ۹ مانند قبل هستند. در خط ۱۱ یک اشاره گر دیگر به نام ppn تعریف کرده و آن را به pn اشاره داده ایم (اشاره گر به اشاره گر). عبارت **int به این معنی است که اشاره گر تعریف شده به یک خانه از جنس *int (به pn) اشاره می کند.
خروجی این قطعه کد به این صورت است:
1 2 3 4 5 6 7 8 |
n = 44 , &n = 0x7fff51f0ba4c pn = 0x7fff51f0ba4c &pn = 0x7fff51f0ba40 *pn = 44 ppn = 0x7fff51f0ba40 &ppn = 0x7fff51f0ba38 *ppn = 0x7fff51f0ba4c **ppn = 44 |
سناریوی مدنظر ما در قطعه کد فوق به این صورت است: (ppn -> pn -> n). به آدرس هایی که در خروجی چاپ شده اند، دقت کنید. آیا آنها نشان دهنده اشاره ppn به pn و نیز اشاره pn به n هستند؟
نکته جالب توجه در خط ۸ دیده می شود. اینکه ما بصورت غیرمستقیم و بدون استفاده از نام متغیر n و حتی اشاره گر pn، از طریق اشاره گر ppn توانسته ایم به مقدار متغیر n دسترسی پیدا کنیم.
به پایان این جلسه آموزشی رسیدیم. در آینده با بخشهای دیگری از زبان ++C آشنا خواهیم شد. با ما همراه باشید…
12 دیدگاه. ارسال دیدگاه جدید
سلام استاد خدا خیرتون بده
واقعا این بحث برام مبهم بود. ولی با توضیحات شما کاملا درکش کردم
دقیقا همونطور هست که باید باشه
ابهام باقی نمی ذارید
ان شاءالله موفق و سلامت و عاقبت به خیر باشین
ممنون مهندس جان. من دوره سی رو از یه سایت دیگه تهیه کردم و کامل دیدم ولی مفهوم پوینتر برام جا نمیافتاد. با اینکه شما سی پلاس پلاس تدریس میکنید مفهوم پوینتر رو خیلی عالی بیان کردید. بسیار ممنون
سلام خدا قوت
ببخشید آیا در هر اجرا، آدرس متغیر مورد نظر فرق میکنه؟
هر باری که اجرا میکنم آدرس های مختلفی پرینت میشه.
ممکنه فرق کنه ممکن هم هست ثابت باشه. این موضوع اهمیت خاصی نداره.
سلام
ممنون از آموزش های خوبتون، انشالله هر جا که هستید موفق باشید.
merci az tadriseton, shoma kare mano kheyli rahat kardin, sepasgozaram chon ketabe c++ be zabane almani nazdike 800 safhe hast vali ba tozihate shoma daram ghadam be ghadam yad migiram .
Ali hastam az Zürich Switzerland.
mamnoon az shoma dooste aziz.
سلام. واقعا خیلی خوب و واضح توضیح میدید. ممنونم ازتون
با عرض سلام و خسته نباشید خدمت شما استاد بزرگوار
با اینکه بنده سالهاست که تجربهی برنامهنویسی به زبانهای مختلف رو دارم و به مطالبی که فرمودید آگاهی دارم ولی با نگاهکردن به ویدئوی آموزشیتون واقعا لذت بردم و تا آخر اون رو نگاه کردم. شیوا، رسا و بسیار قابل فهم توضیح دادید، از خداوند برای شما صحت و توفیق روز افزون دارم. تشکر از وقتی که برای کسایی که علاقهمند به برنامهنویسی هستند میذارید.
امیدوارم که در این مسیری که قدم نهادید دلسرد نشوید و شاهد آموزشهای بیشتری از شما باشیم.
در پناه خدا باشید، یا حق.
دوست عزیز بسیار ممنون و سپاسگزارم.
کاربران فهیم و قدرشناسی چون شما انگیزه ادامه مسیر رو در بنده دو چندان میکنه.
انشاا.. با قدرت این مسیر رو ادامه داده و حتی دوره های آموزشی دیگری رو در آینده استارت خواهم زد.
بنده هم برای شما آرزوی پیروزی و موفقیت روز افزون می کنم.
سلام استاد خسته نباشید
با تشکر از آموزشهای خوب و خاصتون.
یه سوال داشتم
آیا متغیری هست که بتونه در یک آرایه هم مقادیر کاراکتری و هم اعداد رو ذخیره و هر وقت خواستین خروجی بده؟
دوست عزیز اگر منظورتون امکان تعریف آرایهای هست که بیش از یک نوع داده رو بتونه در خودش ذخیره کنه، باید بگم که خیر. امکان انجام اینکار وجود نداره.