تفاوت میان نسخه‌های «اشاره‌گر (علوم رایانه)»

جز
جز (اصلاح پیوند به صفحه ابهام‌زدایی با استفاده از AWB)
در فرهنگ [[علوم رایانه]] متغیرهای از نوع '''اشاره‌گر''' {{انگلیسی|Pointer}}، به [[متغیر|متغیرهایی]] گفته می‌شود که محتوای آن ها،آن‌ها، آدرس خانه‌ای از [[حافظه (رایانه)|حافظه]] یا نیل<ref>nil</ref> است. در عمل، اشاره‌گر متغیری است که به متغیر دیگری اشاره می‌کند.
 
اشاره‌گرها از پرکاربردترین نوع متغیرها در [[زبان برنامه‌سازی|زبان‌های برنامه‌سازی]] محسوب می‌شوند. این امر به این علت است که اشاره‌گرها، گاهی اوقات تنها راه بیان محاسبه‌ای مشخص هستند و بخشی دیگر به این علت است که معمولاً باعث فشردگی و کارائی بیشتر قطعه برنامه‌ها نسبت به ایجاد آنها با روش‌های دیگر می‌شود.
 
== اشاره‌گرها در زبان‌های برنامه‌نویسی مختلف ==
 
=== زبان سی ===
در [[زبان سی]] اشاره‌گرها یکی از اجزای پایه زبان هستند و ارتباط اساسی با [[آرایه (ساختمان داده‌ها)|آرایه]]، [[ساختار (برنامه‌نویسی)|ساختارها]]، و توابع دارند. چندین [[عملگر]] مختلف برای کار بر روی اشاره‌گرها وجود دارد که مهمترین آنها [[عملگر یکانی|عملگرهای یکانی]] * و & هستند. عملگر & (عملگر ''آدرس'') آدرس [[عملوند]] خود را برمی‌گردد. عملگر * (عملگر ''در آدرس'') هم محتوای خانه‌ای که آدرس آن عملوندش قرار دارد را در دسترس می‌سازد. برای تعریف یک اشاره گر باید قبل از نام آن علامت * قرار گیرد.
 
<source lang="c">
</source>
 
به اندازه size بایت از سیستم فضا گرفته و اشاره گری به ابتدای این مکان را برمیگرداندبرمی‌گرداند. تابع free که بدین صورت اعلان شده:
<source lang="c">
void
free(void *ptr);
</source>
حافظه ای که آدرس اولین بایت آن در ptr قرار دارد را به سیستم برمیگرداندبرمی‌گرداند.
 
<source lang="c">
 
==== اشاره گرها و فراخوانی توابع ====
در زبان سی، وقتی که متغیری را به عنوان آرگومان برای تابع ارسال می‌کنیم، در حقیقت مقدار آن متغیر در پارامتر تابع کپی می‌شود و کلیه عملیات بر روی آن کپی انجام می‌شود و متغیر اصلی بدون تغییر باقی می‌ماند. این کار به کمک یک [[پشته]] انجام می‌شود. برای اینکه تابع قادر باشد تا بر روی آرگومانها تغییر ایجاد کند، باید به جای مقدار، آدرس آرگومان را ارسال کنیم. چرا که به کمک آدرس تابع می‌تواند مستقیماً به سراغ حافظه رفته و محتوای آن را تغییر دهد. برای اینکه اشاره گری به تابع ارسال شود، پارامترهای تابع باید از نوع اشاره گر تعریف شوند. تابع زیر محتوای دو متغیر را با یکدیگر تعویض می‌کند.
 
<source lang="c">
</source>
 
==== اشاره گرها و آرایه هاآرایه‌ها ====
در زبان سی نام یک آرایه، اشاره گری به اولین عنصر آرایه است. برای دستیابی به بقیه عناصر آرایه، شماره اندیس آن خانه با آدرس اولین خانه جمع می‌شود. (چون خانه‌های آرایه به صورت پشت سر هم در حافظه ذخیره می‌شوند.)
 
<source lang="c">
</source>
 
در مثال بالا ip = a مقدار a (که اشاره گری به یک عدد صحیح است) را به اشاره گر ip انتساب می‌دهد.می‌دهد؛ بنابراین از این به بعد می‌توان از طریق اشاره گر ip هم به محتویات آرایه دسترسی داشت. ip[1] = 12۱۲ عدد ۱۲ را به دومین عنصر آرایه (چون در سی اندیس آرایه هاآرایه‌ها از صفر شروع می‌شود) انتساب می‌دهد.
 
در خط آخر، ابتدا ip (که آدرس یک خانه را دربر دارددربردارد و آدرس هم یک عدد است) با ۲ جمع شده و سپس یک آدرس جدید به دست می‌آید که همان عنصر سوم آرایه است. سپس عدد ۶۷ در این آدرس قرار می‌گیرد.
 
==== اشاره گرها و توابع ====
همانند آرایه، نام یک تابع هم یک اشاره گر است. در زبان سی، نام یک تابع به ابتدای محلی از حافظه اشاره می‌کند که کدهای تابع در آنجا قرار دارند. در هنگام کار با اشاره‌گر به توابع بهتر است برای بالا بردن خوانایی از typedef هاtypedefها استفاده کنید.
 
<source lang="c">
typedef void (*func_t) (int*, int*);
</source>
اعلان بالا، [[نوع داده]] جدیدی به نام func_t تعریف می‌کند. این توع داده یک [[اشاره گر به تابع]] است. اما فقط می‌تواند به توابعی اشاره کند که دو آرگومان از نوع {{چر}}int* دریافت می‌کنند و هیچ چیزی بر نمی‌گردانندبرنمی‌گردانند. (مانند تابع swap که قبلاً تعریف کردیم)
 
<source lang="c">
</source>
 
دستور func_t exchg یک اشاره گر به تابع به نام exchg ایجاد می‌کند که exchg می‌تواند به توابعی که دو اشاره گر به عدد صحیح می‌گیرند و هیچ چیز برنمی‌گردانند اشاره کند. دستور exchg = &swap آدرس اشاره گر swap را در exchg قرار می‌دهد. حالا که آدرس تابع در اشاره گر exchg در دسترس است، می‌توان تابع را از طریق این اشاره گر فراخوانی کرد. اشاره گر به توابع را می‌توان به عنوان آرگومان به توابع دیگر ارسال کرد. همچنین می‌توان آنها را در آرایه ذخیره کرد. مثلاً در [[کتابخانه استاندارد سی]] تابعی به نام bsearch وجود دارد که عمل [[جستجوی دودویی]] را انجام می‌دهد. این تابع بدین شکل اعلان شده استشده‌است:
<source lang="c">
void *
int (*compar) (const void *, const void *));
</source>
پارامتر آخر این تابع، اشاره گر به تابعی است که یک عدد صحیح برمیگرداندبرمی‌گرداند و دو آرگومان از نوع اشاره گر دریافت می‌کند. اشاره گرها از نوع void تعریف شده اندشده‌اند تا بتوانند به هر نوع داده ایداده‌ای اشاره کنند.
 
=== مشکلات اشاره گرها ===
اشاره گرهایی هنوز مقدار دهی نشده اندنشده‌اند و به جایی اشاره نمی‌کنند می‌توانند برای برنامه خطرناک باشند. به مثال زیر توجه کنید:
 
<source lang="c">
</source>
 
اشاره گر x هنوز مقدار دهی نشده و به یک خانه تصادفی اشاره میکند.می‌کند؛ بنابراین دستور دوم سعی می‌کند عدد ۱۲ را در یک جای تصادفی از حافظه قرار دهد. اگر خوش شانش باشید، این خانه به جایی در خارج از محدوده آدرس دهی برنامه اشاره می‌کند. چون در این صورت سیستم‌عامل اجازه دسترسی به آن خانه را نداده و پیغام segmentation fault تولید می‌کند. اما اگر بد شانس باشید و آن خانه در محدوده آدرس دهی برنامه باشد، محتوای یکی از [[ساختمان داده]] برنامه خود را بازنویسی کرده‌اید . اطلاعات آسیب خواهند دید.
 
== پانوشته‌ها ==
 
{{پانویس}}
 
۴۲۱

ویرایش