الگوریتمستان - متغیرهای مرجع در ++C

معرفی متغیرهای مرجع در زبان برنامه‌نویسی ++C و آشنایی با مهمترین کاربردهای آنها

✤    ۱۶ شهریور ۱۳۸۵ - آخرین به‌روزرسانی: ۱۵ خرداد ۱۳۸۸

زبان برنامه‌نویسی C از دو نوع متغیر پشتیبانی می‌کند: متغیرهای معمولی و اشاره‌گرها (متغیرهای حاوی آدرس حافظه). زبان ++C نوع سومی را به این مجموعه اضافه کرده است: متغیرهای مرجع (Reference).

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

  

int a;

int &b = a;

  

عبارت فوق متغیر b را مرجعی برای a معرفی می‌کند. از این کد به بعد متغیرهای a و b معادل هم هستند. یعنی تغییرات a در b و تغییرات b در a تاثیر می‌گذارد. در واقع a و b از یک محل حافظه استفاده می‌کنند؛ یا اینکه یک خانه حافظه، دو نام متفاوت دارد.

کاربرد اصلی متغیرهای مرجع را می‌توان در انتقال اطلاعات به توابع و بالعکس دید. همانطور که می‌دانید در زبان C دو روش برای انتقال اطلاعات به تابع و بالعکس وجود دارد: مقدار و اشاره‌گر. زمانی که از روش اول استفاده می‌کنیم، آرگومان متناظر با پارامتر تابع فقط یک کپی از مقدار آن پارامتر را دارد. یعنی تغییر متغیر آرگومان تاثیری در متغیر پارامتر ندارد. مثلا:

  

void func(int a) {

  a = 5;

}

  

void main() {

  int n = 6;

  func(n);

  printf("%d", n);

}

  

زمانی که تابع func فراخوانی می‌شود، یک کپی از مقدار n در a قرار می‌گیرد (یعنی 6). تک دستور تابع func مقدار a را تغییر می‌دهد. این تغییر هیچ اثری در n ندارد و مقدار n همان 6 چاپ می‌شود. چرا که n به صورت مقدار به تابع ارسال شده است.

اگر بخواهیم از روش اشاره‌گر استفاده کنیم، برنامه فوق به این صورت خواهد شد:

  

void func(int *a) {

  *a = 5;

}

  

void main() {

  int n = 6;

  func(&n);

  printf ("%d", n);

}

  

با تغییراتی که اعمال شده، مقدار n در تابع قابل تغییر است. یعنی آخرین دستور برنامه مقدار 5 را برای n چاپ می‌کند.

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

  

void func(int &a) {

  a = 5;

}

  

void main() {

  int n = 6;

  func(n);

  cout << n;

}

  

متغیر a یک مرجع برای n معرفی شده است. پس تغییر a تاثیر مستقیم در n دارد. در نتیجه مقدار n در تابع قابل تغییر است. این برنامه هم مثل برنامه قبلی خروجی 5 دارد. در واقع متغیر مرجع همان کار اشاره‌گر را به صورت ساده‌تر انجام می‌دهد. چرا که برای متغیرهای مرجع نیاز به کار کردن با اپراتورهایی مانند & و * نیست.

پارامترهای مرجع کاربرد جالب دیگری نیز دارند. فرض کنید یک کلاس با صدها تابع و متغیر عضو تعریف کرده‌اید و تابعی دارید که یک متغیر از این نوع کلاس را دریافت کرده و بر اساس این داده‌ها، عملیاتی را انجام می‌دهد. به عنوان مثال:

  

void func(myclass a)

  

با توجه به اینکه کلاس تعریف شده حجم زیادی دارد، انتقال اطلاعات بین برنامه و تابع به کندی انجام می‌شود. مخصوصا اگر مجبور باشید تابع را چندین و چند بار فراخوانی کنید (نظیر توابع مربوط به سربارگذاری عملگرها). در این حالت بهتر است تعریف فوق را با تعریف زیر عوض کنید:

  

void func(const myclass &a)

  

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

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

همانطور که قبلا عنوان کردم، مرجع یک متغیر با خود متغیر هیچ تفاوتی ندارد. این مسئله باعث می‌شود که شما بتوانید از توابعی با مقدار بازگشتی مرجع در سمت چپ علامت تساوی (=) استفاده کنید! برنامه زیر را در نظر بگیرید:

  

int arr[3];

  

int &func(int i) {

  return arr[i];

}

  

void main() {

  func(0) = 2;

  func(1) = 6;

  func(2) = -2;

  cout << arr[0] << "\t" << arr[1] << "\t" << arr[2];

}

  

زمانی که تابع func با مقدار صفر فراخوانی می‌شود، یک مرجع به عنصر اول آرایه بر می‌گرداند. در نتیجه دستور اول تابع اصلی، مقدار این عنصر را برابر 2 قرار می‌دهد. خروجی برنامه به این صورت خواهد بود:

  

2     6    -2

  

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

هنگام استفاده از متغیرهای مرجع به این نکات توجه کنید:

1 - متغیرهای مرجع در C وجود ندارد و مختص زبان ++C است.

2 - مرجع به متغیر مرجع نمی‌توان تعریف کرد. قطعه کد زیر کامپایل نمی‌شود:

  

int a, &b = a;

int &c = b;

  

3 - آرایه‌ای از مرجع‌ها قابل تعریف نیست.

4 - از مرجع‌ها برای ساختمان‌های بیتی نمی‌توان استفاده کرد.

5 - اشاره‌گر به مرجع وجود ندارد.


نسخه‌ی اولیه‌ی این نوشته از وبلاگ برنامه‌نویسی و طراحی الگوریتم به الگوریتمستان منتقل شده است.

تا کنون ۲۵ امتیاز ثبت شده
نوشته لایک نداشت؟
 
به اشتراک گذاری نوشته

amasoudfam.ir/l/o3iog

اشتراک‌گذاری در LinkedIn     اشتراک‌گذاری در Twitter     ارسال با Telegram

نام: *  
پست الکترونیک (محرمانه):
پیام: *  
• مهدی
۱۱ بهمن ۱۳۸۷، ساعت ۲۱:۴۹

سلام:

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

                                                                                            قبلا از زحمات شما سپاس گزارم مهدی.

مسعود اقدسی‌فام
۱۳ بهمن ۱۳۸۷، ساعت ۱۹:۳۸

سلام مهدی خان

ممنون از محبتهاتون.

من به شخصه در زمینه الکترونیک تخصصی ندارم. اما با یکی از دوستانم در این مورد صحبت کردم. شما چقدر قبلا برای میکروکنترلهای ای وی آر برنامه نویسی کردید؟ تجربه ای دارید؟

• زهرا
۲۸ اردیبهشت ۱۳۹۱، ساعت ۲۰:۴۷

مطالب واقعا خلاصه و مفیده .ممنونم خیلی بدردم خورد .08

• ali
۵ آبان ۱۳۹۱، ساعت ۰۶:۱۷

متشکرم

• Arman
۲۰ بهمن ۱۳۹۲، ساعت ۲۲:۵۸

اقا مرسی. عالی بود موفق باشید

۲۰

• برنامه نویس
۱۳ اردیبهشت ۱۳۹۳، ساعت ۰۸:۵۸

عالی بود.

با تشکر

• برنامه نویس
۲۶ آذر ۱۳۹۳، ساعت ۱۶:۴۹

خوبه ولی باید بیشتر راجبه این موضوع بحث بشه چون گسترده است مباحث سی پلاس پلاس سعی کنید سورس کد هم قرار بدید

06

• اسرا
۲۱ آبان ۱۳۹۷، ساعت ۱۳:۴۱

05050809090913131313

• متین
۱۰ آبان ۱۳۹۹، ساعت ۲۱:۴۷

مطلب نسبتا خوبی بود ولی خیلی از نکات داخلش نبود