
اشارهگر یکی از قابلیتهای قدرتمند زبان ++C محسوب میشود که آن را از زبانهای برنامهنویسی دیگر مانند جاوا یا پایتون متمایز میسازد. اشارهگرهای ++C برای دسترسی به حافظه و دستکاری آدرس مورد استفاده قرار میگیرند.
آدرس در ++C
برای درک اشارهگرها ابتدا باید با شیوه ذخیرهسازی دادهها در رایانه آشنا شوید. هر متغیر که در برنامه ایجاد میشود به یک مکان از حافظه رایانه انتساب مییابد. مقداری که در متغیر ذخیره میشود در عمل به آن مکان حافظه انتساب پیدا میکند.
++C برای دانستن این که دادهها کجا ذخیره شدهاند، یک عملگر به نام عملگر ارجاع (&) دارد. عملگر ارجاع یا (&) آدرس حافظه اشغال شده از سوی متغیر را در اختیار ما قرار میدهد. اگر var یک متغیر باشد، در این صورت &var آدرس آن متغیر است.
#include <iostream> using namespace std; int main() { int var1 = 3; int var2 = 24; int var3 = 17; cout << &var1 << endl; cout << &var2 << endl; cout << &var3 << endl; }
خروجی:
0x7fff5fbff8ac 0x7fff5fbff8a8 0x7fff5fbff8a4
نکته: توجه کنید نتایجی که شما به دست میآورید به احتمال زیاد با خروجی فوق متفاوت خواهند بود.
عبارت 0x در ابتدای آدرس نشاندهنده این است که آدرس به شکل هگزادسیمال است. همچنین توجه کنید که آدرس اول 4 بایت با آدرس دوم فرق دارد و اختلاف آدرس دوم و سوم نیز همین مقدار 4 بایت است. دلیل این مسئله آن است که اندازه متغیر صحیح (نوع متغیر int) در سیستمهای 64 بیتی، 4 بایت است.
متغیرهای اشارهگر
++C امکان دستکاری مستقیم دادهها را در حافظه فراهم کرده است. بدین ترتیب میتوان هر فضایی از حافظه را بنا به ضرورت انتساب داد یا از انتساب خارج کرد. این کار با استفاده از متغیرهای اشارهگر صورت میگیرد.
شیوه اعلان متغیر چگونه است؟
int *p; یا int* p;
گزاره فوق یک متغیر اشارهگر به نام p تعریف میکند. این متغیر یک آدرس حافظه را نگهداری میکند. علامت ستاره عملگر ارجاعزدایی است که به معنی «اشارهگری به» است. در کد فوق اشارهگر p به int اشاره میکند یعنی یک مقدار صحیح در آدرس حافظه.
عملگر ارجاع (&) و عملگر ارجاعزدایی (*)
چنان که پیشتر اشاره کردیم عملگر ارجاع آدرس یک متغیر را ارائه میکند. برای دریافت مقدار ذخیره شده در آدرس حافظه از عملگر ارجاعزدایی یعنی * استفاده میکنیم.
برای نمونه اگر متغیر number در آدرس حافظه 0x123 ذخیره شده باشد و مقدار 5 داشته باشد، عملگر ارجاع (&) مقدار 0x123 را به ما میدهد، در حالی که عملگر ارجاعزدایی (*) مقدار آن یعنی 5 را در اختیار ما قرار میدهد.
نکته: علامت (*) که در اعلان اشارهگر ++C استفاده میشود، یک عملگر ارجاعزدایی نیست و صرفاً یک نمادگذاری مشابه برای ایجاد یک اشارهگر محسوب میشود.
مثال 2
برنامه ++C زیر برای نمایش طرز کار اشارهگر نوشته شده است.
#include <iostream> using namespace std; int main() { int *pc, c; c = 5; cout << "Address of c (&c): " << &c << endl; cout << "Value of c (c): " << c << endl << endl; pc = &c; // Pointer pc holds the memory address of variable c cout << "Address that pointer pc holds (pc): "<< pc << endl; cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl; c = 11; // The content inside memory address &c is changed from 5 to 11. cout << "Address pointer pc holds (pc): " << pc << endl; cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl; *pc = 2; cout << "Address of c (&c): " << &c << endl; cout << "Value of c (c): " << c << endl << endl; return 0; }
خروجی:
Address of c (&c): 0x7fff5fbff80c Value of c (c): 5 Address that pointer pc holds (pc): 0x7fff5fbff80c Content of the address pointer pc holds (*pc): 5 Address pointer pc holds (pc): 0x7fff5fbff80c Content of the address pointer pc holds (*pc): 11 Address of c (&c): 0x7fff5fbff80c Value of c (c): 2

زمانی که ;c=5 است، مقدار 5 در آدرس متغیر c یعنی 0x7fff5fbff8c ذخیره میشود.
زمانی که ;pc=c& است، اشارهگر pc آدرس c را نگهداری میکند که 0x7fff5fbff8c است و عبارت (عملگر ارجاعزدایی) pc* مقدار ذخیره شده در آن آدرس یعنی 5 را در خروجی ارائه میکند.
زمانی که ;c=11 است، از آنجا که اشارهگر آدرس pc همان مقدار c را نگهداری میکند، شامل مقدار 0x7fff5fbff8c است. هر تغییری در مقدار c هنگام اجرای pc* نیز بازتاب مییابد و در خروجی مقدار 11 را میبینیم.
زمانی که ;pc=2* است، محتوای آدرس ذخیره شده از سوی pc یعنی 0x7fff5fbff8c تغییر پیدا میکند. این مقدار از 11 به 2 عوض میشود. از این رو وقتی به مقدار c اشاره میکنیم، مقدار آن نیز 2 شده است.
خطاهای رایج هنگام کار کردن با اشارهگرها
فرض کنید میخواهید اشارهگر pc به آدرس c اشاره کند. در این صورت:
int c, *pc; pc=c; /* Wrong! pc is address whereas, c is not an address. */ *pc=&c; /* Wrong! *pc is the value pointed by address whereas, %amp;c is an address. */ pc=&c; /* Correct! pc is an address and, %amp;pc is also an address. */ *pc=c; /* Correct! *pc is the value pointed by address and, c is also a value. */
در هر دو مورد اشارهگر pc به آدرس c اشاره نمیکند.
Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com