PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : اشاره گرها



Y@SiN
02-26-2010, 10:38 PM
1- همونطور که می دونید تک تک بایتهای حافظه برای خودشون آدرسی دارن ، که یه عدد صحیح و مثبته! این آدرسها دقیقا مثل کد پستی عمل می کنن؛ یعنی کاملا منحصربفرد هستن ، و می شه ازشون برای ارجاع به بایت استفاده کرد.

2- هر متغیری که تعریف می شه بسته به اندازه ای که داره تعدادی بایت حافظه بهش اختصاص داده می شه. این بایتها یه ویژگی مهم دارن و اون متوالی بودن اونهاست. یعنی بایتهایی که به یه متغیر اختصاص داره همگی پشت سر هم قرار دارن.

حالا بریم سراغ اشاره گرها: اشاره گر نوعی متغیره که محتوای اون یه آدرس حافظه کامپیوتره. به این مثال توجه کنید:



کد:





int a ;

int *b ;

b = &a ;




دو خط اول متغیر a رو به عنوان متغیر صحیح و b رو یه اشاره گر صحیح معرفی می کنن (یعنی آدرس موجود در اشاره گر b مربوط می شه به یه متغیر صحیح). توسط خط سوم آدرس متغیر a در b قرار می گیره. مثلا اگه متغیر a بایتهای شماره ۱۰۰۰ و 1001 رو در اختیار داشته باشه مقدار 1000 برای متغیر b در نظر گرفته می شه (اصطلاحا گفته می شه که اشاره گر b به a اشاره داره). اینجا ممکنه دو سوال براتون پیش بیاد: چرا فقط آدرس بایت اول تو اشاره گر قرار می گیره ، و چرا اصولا برای اشاره گر نوع تعیین می شه؟ مگر نه اینکه اونها حاوی آدرس حافظه هستن؛ به چه دلیل نوع محلی که اشاره گر بهش اشاره داره مشخص می شه؟

Y@SiN
02-26-2010, 10:39 PM
یه مثال دیگه:





کد:


long int a , *b , c ;

a = 69355 ;

b = &a ;

c = *b ;






عبارت b* رو بخونید: "محتوای محلی که متغیر b بهش اشاره داره". پس خط آخر مقدار ۶9355 رو به c اختصاص می ده (به کاربردهای متفاوت اپراتورهای & و * دقت کنید). فرض کنیم بایتهای شماره 1000 تا 1003 برای ذخیره کردن مقدار متغیر a استفاده شده باشن (متغیر از نوع long int در حالت استاندارد چهار بایت اندازه داره). پس اشاره گر b مقدار 1000 رو داره. وقتی برنامه به خط آخر می رسه باید محتوای محلی رو که b به اون اشاره داره در c قرار بده. اما از کجا متوجه می شه که علاوه بر بایت شماره 1000 باید سه بایت بعدی رو هم استفاده بکنه؟ و چطور متوجه می شه که باید این چهار بایت رو به صورت عدد صحیح تفسیر کنه (ممکن بود این چهار بایت مربوط به یه عدد اعشاری چهار بایتی float می بود)؟ به همین خاطره که نوع اشاره گر تعیین می شه. وقتی اشاره گر b از نوع long int مشخص شده برنامه متوجه می شه که باید از چهاربایت به صورت عدد صحیح استفاده بکنه. اگه تعیین نوع برای اشاره گر انجام نمی شد مشکلات زیادی به وجود می اومد. البته ما اشاره گرهای بدون نوع (void) هم داریم ، که کاربرد اختصاصی خودشون رو دارن.

Y@SiN
02-26-2010, 10:40 PM
حالا می ریم سراغ کاربرد اشاره گرها در برنامه نویسی. مطمئنا کاربرد اشاره گرها مربوط به مثال بالا نمی شه! چون براحتی می تونستیم بنویسم c = a و اصلا نیازی به اشاره گر نبود. یکی از کاربردهای اشاره گر مربوط می شه به انتقال داده ها بین توابع مختلف در برنامه. متغیرهایی که در حالت عادی به تابع ارسال می شن (به عنوان پارامتر) از تغییر پیدا کردن توسط تابع مصون هستن. چرا که تابع یه کپی از اونها رو استفاده می کنه. مثلا:









void func ( int n )

{

n++ ;

}

void main ( )

{

int n = 10 ;

func ( n ) ;

cout << n ;

}






مقدار n تابع func یه واحد افزایش پیدا می کنه ، اما این تغییر تاثیری در n تابع اصلی نداره. پس عدد 10 توسط cout به خروجی ارسال می شه. اما مواقعی هست که ما نیاز داریم بتونیم مقدار متغیر رو تغییر بدیم. مثل تابعی که دو متغیر رو دریافت می کنه و مقدارهاشون رو با هم عوض می کنه. اینجا اشاره گر به کمک ما می یاد:






void swap ( int *a , int *b )

{

int t ;

t = *a ;

*a = *b ;

*b = t ;

}

void main()

{

int m = 15 , n = 10 ;

swap ( &m , &n );

cout << "m = " << m << " , n = " << n ;

}




به جای محتویات متغیرهای m و n آدرس حافظه اونها به تابع ارسال می شه. پس اشاره گر a به m و اشاره گر b به n اشاره می کنن. حالا به مراحل مختلف تابع swap توجه کنید:

خط دوم : محتوای محلی که a به اون اشاره داره (یعنی مقدار m) در t قرار می گیره. پس t = 15.

خط سوم : محتوای محلی که b به اون اشاره داره (یعنی مقدار n) به محلی که a به اون اشاره داره (یعنی m) منصوب می شه. پس m = 10.

خط چهارم : محتوای t به محلی که b به اون اشاره داره (یعنی n) منصوب می شه. پس n = 15.

بعد از اینکه کنترل به تابع اصلی برمی گرده مقادیر m و n با هم عوض شدن! و خروجی به این صورته:






m = 10 , n = 15

Y@SiN
02-26-2010, 10:41 PM
مهمترین و اصلی ترین کاربرد اشاره گرها مربوط به کار با متغیرهای پویا می شه. متغیرهای عادی که در برنامه ها استفاده می شن ایستا هستن؛ یعنی توسط خود برنامه حافظه بهشون اختصاص داده می شه و آخر کار توسط خود برنامه حافظه آزاد می شه. متغیرهای پویا عکس این حالت هستن. یعنی باید خودتون حافظه بگیرید و خودتون آزاد کنید. این نوع متغیر توسط اشاره گر کنترل می شه. یه مثال ساده می زنم:









void main ( )

{

int *p ;

p = new int ;

*p = 5 ;

cout << *p ;

delete p ;

}





توسط دستور new حافظه ای به عنوان عدد صحیح رزرو می شه ، و آدرس اون در اشاره گر p قرار می گیره. بعد از انجام دادن هر عملیات دلخواهی روی این حافظه ، توسط دستور delete حافظه آزاد می شه.