آخرین مطالب
LINK TABLES
خانه | برنامه‌نویسی | زبان C – اشاره گرها (جلسه ۳)

زبان C – اشاره گرها (جلسه ۳)

خب نوبت رسید به جلسه سوم زبان C که قولشو داده بودیم. امروز میخوایم در مورد مبحث زیبا و البته خیلی مهم اشاره‌ گر صحبت کنیم. لازمش اینه که مطالب جلسه قبل (انواع داده) رو خوب توی ذهن داشته باشید. دیگه صحبت کافیه و بریم سراغ درس امروز.

 

اشاره گر

جلسه قبل به انواع داده در زبان C اشاره شد. بیان شد که داده های ساده می توانند شامل کاراکتر، عدد صحیح، عدد اعشاری و اشاره گر باشند. داده ها در حافظه نگه داری می شوند و هر خانه ی حافظه هم یک آدرس مشخص دارد. وقتی یک متغیر برای ذخیره کردن داده ای خاص تعریف می شود، در واقع نام متغیر یک اسم مستعار برای آدرس آن متغیر در حافظه است. دانستن نام متغیر این امکان را فراهم می کند تا بدون درگیر شدن با آدرس در حافظه، بتوان داده را ذخیره یا بازیابی کرد. همان طور که در شکل زیر مشاهده می شود، مقدار ۱۰ در متغیری با نام a که آدرس آن خانه ۸۰F حافظه است ذخیره شده است. a یک نام مستعار برای خانه ۸۰F حافظه است. چیزی که در عمل با آن کار می شود a و نه ۸۰F است.

برای درک بهتر به مثال زیر دقت کنید:

در این مثال محلی از حافظه که ۲ بایت ظرفیت دارد برای ذخیره سازی عدد ۸ در متغیری به نام height یا ارتفاع استفاده شده است. آیا معلوم است آدرس متغیر height کجای حافظه قرار دارد؟ مشخص است که مکان آن نامعلوم است و البته دانستن آن هم اهمیتی ندارد. البته می شد به جای int از char و یا float هم استفاده کرد. خب تا این جا مشخص شد که داده هایی از نوع کاراکتر، عدد صحیح یا اعشاری چه کاربردی دارند. کافی است نوع متغیر معلوم شود و بدون دانستن آدرس حافظه مقدار متناظر در آن ذخیره شود. اما نوع دیگری از داده های ساده به نام اشاره گر وجود دارد. این نوع از داده چیست و چه کاربردی دارد؟

گاهی در برنامه نویسی لازم است به جای نام متغیر با آدرس متغیر کار کرد. اشاره‌گرها می‌توانند آدرس یک متغیر در حافظه (که یک مقدار عددی است) را در خود نگه‌دارند. اشاره‌گرها در زبان C کاربرد فراوانی دارند، به‌طوری‌که اغلب قابلیت‌های زبان C به نقش اشاره‌گرها در این زبان برمی‌گردد.

همانند سایر داده های ساده که ابتدا نیاز به تعریف داشتند، اشاره گر هم باید تعریف شود. نحوه ی تعریف اشاره گر بدین صورت است:

ابتدا باید نوع اشاره گر مشخص شود. نوع اشاره گر می تواند char یا int یا float یا داده های مرکب باشد. با معین کردن نوع اشاره گر مشخص می شود که اشاره گر به چه نوع متغیری اشاره می کند. برای فهم موضوع به مثال زیر دقت کنید:

در این خط متغیری با نام pointer اعلان شده است که از نوع اشاره گر به یک متغیر char است. چگونه می توان به این متغیر مقدار دهی کرد؟ برای این منظور، ابتدا باید یک متغیر از نوع char تعریف شده باشد. به مثال زیر دقت کنید:

  • در خط یک متغیری از نوع کاراکتر با نام alefba تعریف شده و کد اسکلی کاراکتر A در آن ذخیره شده است.
  • در خط دو متغیری با نام pointer از نوع اشاره گر به یک متغیر char تعریف شده است.
  • در خط سه آدرس متغیر alefba توسط عملگر آدرس (&) استخراج شده و در اشاره گر pointer ذخیره شده است. روش مقدار دهی به اشاره گر بدین شکل است. یعنی باید از عملگر آدرس استفاده کرد. اگر با عملگرها آشنایی ندارید می توانند مقاله عملگرها در زبان C را مطالعه کنید.

 توجه شود که نوع اشاره‌گر و متغیری که به آن اشاره می‌کند باید یکسان باشد. به مثال زیر دقت کنید:

  • در خط یک متغیری از نوع کاراکتر تعریف مقدار دهی شده است
  • در خط دو متغیری با نام pointer از نوع اشاره گر به یک متغیر int تعریف شده است.
  • در خط سه به اشاره گر مقدار دهی شده است. اما این مقدار دهی اشتباه است، چرا که اشاره گری از نوع int به متغیری از نوع char اشاره می کند. می توانید دلیل اشتباه بودن را توضیح دهید؟ اگر صبر کنید، تا انتهای این پست پاسخ را خواهید یافت.

تا این جا نحوه مقدار دهی اشاره گرها بیان شد. اما دسترسی به محتوای آن ها چگونه است؟

برای دسترسی به محتوای اشاره گرها باید از عمگر ستاره (*) استفاده شود. این عملگر محتوای اشاره گر (محتوای خانه ای که اشاره گر به آن اشاره می کند.) را استخراج می کند.

برای درک بهتر به مثال زیر توجه کنید :

  • در خط یک اشاره گری از نوع int تعریف شده است.
  • در خط دو متغیرهای z و y از نوع int تعریف شده اند.
  • در خط سه متغیر y با عدد۱۴۲ مقدار دهی شده است.
  • در خط چهار آدرس متغیر y درون اشاره گر x قرار داده شده است.
  • در خط پنج محتوای خانه ای که اشاره گر x به آن اشاره می کند (x به آدرس متغیر y اشاره می کند) درون متغیر z قرار داده شده و z دارای مقدار ۱۴۲ می شود.

.  وقتی عمل جمع عددی با متغیر اشاره‌گر صورت می‌گیرد اشاره‌گر به‌اندازه حاصل‌ضرب عدد درتعداد بایت‌های نوع داده‌ای که اشاره می‌کند جلو می‌رود. همین برای عمل تفریق هم صدق می‌کند. اگر مقداری از متغیر اشاره‌گر کم شود در محاسبات تعداد بایت‌های نوع داده محسوب می‌شود.

عملیات روی اشاره‌گرها

برای آشنایی با عملگرها می توانند مقاله عملگرها در زبان C را مطالعه کنید. عملیات جمع (+)، تفریق (-)، افزایش (++) و کاهش (–) را می‌توان روی متغیرهای اشاره‌گر انجام داد. چون اشاره‌گر حاوی آدرسی در حافظه است وقتی محاسباتی روی آن انجام می‌گیرد رفتار متفاوتی نشان می‌دهد. اگر a یک مقدار مثبت فرض شود. وقتی عمل جمع a با متغیر اشاره‌گر صورت می‌گیرد، اشاره‌گر به‌ اندازه ی a*(تعداد بایت‌های نوع داده‌ای که اشاره گر به آن اشاره می‌کند) جلو می‌رود. گیج کننده بود؟ 😉 پس به مثال زیر دقت کنید:

  • در خط یک متغیر a  و اشاره گر p از نوع int تعریف شده اند.
  • در خط دو آدرس متغیر a درون اشاره گر p قرار داده شده است.
  • در خط سوم اشاره گر p با ۴ جمع شده است. p از نوع int و دو بایتی است. پس هنگامی که با ۴ جمع می شود به اندازه ۴*۲ یعنی ۸ بایت جلو می رود.
  • توضیح بیشتر: اشاره گر int آدرس متغیرهای دو بایتی را در خود نگه می دارد. وقتی با ۴ جمع می شود منظور آن است که به ۴ آدرس جلوتر اشاره کن و هر آدرس هم ۲ بایت را اشغال می کند. پس حاصل جمع با ۴ به ۸ بایت جلوتر اشاره می کند.اگر آدرس متغیر a برابر با ۱۰۰۰ باشد. حاصل این جمع برابر با ۱۰۰۸ می شود.

حال می توانید جواب سوال بالا را بدهید. چرا باید اشاره گر و متغیری که به آن اشاره می کند از یک نوع باشند؟ برای پاسخ از مثال بالا کمک گرفته می شود. اگر اشاره گر از نوع char بود، حاصل جمع به ۴ بایت جلوتر اشاره می کرد. در واقع معیار اشاره گر در این حالت خانه های یک بایتی است در حالی که متغیر مورد نظر دو بایتی است.

عملگر افزایش (++) مقدار متغیر معمولی را یکی اضافه می‌کند درحالی‌که متغیر اشاره‌گر را به تعداد بایت‌های نوع داده آن حرکت می‌دهد. مثلا برای اشاره‌گر به نوع داده ی float ،چون float چهار بایت دارد با افزایش اشاره‌گر ۴ واحد به آن اضافه می‌شود. بنابراین به ۴ بایت بعدی حافظه اشاره می‌کند.

 عملیات ضرب و تقسیم روی یک اشاره‌گر انجام نمی‌گیرد و باعث بروز خطای کامپایلر می‌شود.

جلسه امروز کمی طولانی شد اما خب مطالب مهمی بود که باید یاد می‌گرفتید. توی جلسه آینده میریم سراغ آرایه ها (اینجا کلیک کن) و کمی بیشتر باهاشون آشنا می شیم. خسته نباشید دوستای خوبم 🙂

درباره ی احسان عبداللهی

احسان عبداللهی هستم | کارشناسی الکترونیک خوندم و کارشناسی ارشد مخابرات |در سال 94 وب سایت میکرولرن را راه اندازی کردم | سعی کردم هر چیزی را به صورت کاربردی دنبال کنم، برای همین از کارشناسی کار با میکروکنترلرهای AVR و ARM، برنامه نویسی C و طراحی PCB را به صورت تخصصی کار کردم و از کارشناسی ارشد برنامه نویسی پایتون ، Computer vision و deep learning را به صورت تخصصی و کاربردی شروع کردم | الان هم سعی میکنم همیشه خودم را به روز نگه دارم و لذت کار کردن با دنیای برنامه نویسی و امبدد سیستم ها را به دیگران انتقال بدم

۱۳ دیدگاه

  1. سلام و تشکر از زحماتتون و سایت خوبتون.من همرو فهمیدم فقط نمیفهمم اشاره گر به چه دردی میخوره وقتی همه کارارو میشه با متغیر ها انجام داد ؟ ممنون میشم پاسخ بدید

  2. جناب عبداللهی عزیز خیلی از مطالب مفیدی که قراردادین سپاسگزارم
    از خداوند بهترین ها را برایتان آرزو دارم

  3. عالی بود اما کم. یعنی نیاز به توضیح بیشتر داشت.
    من در کنارش، ۲ بخش اول این رو هم
    http://www.cplusplus.com/doc/tutorial/pointers/
    خوندم تا بهتر متوجه بشم.

  4. سلام این قضیهfloatو۱۰۰۰واقعا نفهمیدم دوباره توضیح میدین توی قسمت اخر که به جمع و تفریق اشاره میکنه؟
    سوال دوم اینه که من متن فهمیدم ولی واقعا مفهوم اشاره گر و مشخص شدن ادرس حافظه گه گفتین یه عدد هست رو نفهمیدم.چیزی که من درک کردم اینه که اشاره گرها صرفا یک متغیر واسطه هستن

  5. انواع داده از نوع شمارشی (enum) رو تو آموزش های خوبتون از قلم انداختید جناب مهندس.

  6. واقعا عالی توضیح میدید . هر ابهامی که یک فرد میتونه داشته باشه رو رفع میکنید . واقعا تشکر میکنم به خاطر حوصله و دقتی که در تالیف مطالبتون صرف میکنید .

    • هدف ما اینه که به ساده ترین زبان، مطالب را برای شما توضیح بدیم تا ابهامی باقی نمونه و بتونید راه را بهتر پیش برید. حتما اگه سوالی براتون پیش اومد در بخش نظرات مطرح کنید تا پاسخ داده بشه.

  7. بسیار عالی اگه امکان داره مطالب را هم در تلگرام بزارید

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *