حساب پوینتر (Pointer Arithmetic)
اینجا درباره «حساب پوینتر (Pointer Arithmetic)» حرف می زنیم. یعنی تغییر آدرس یک پوینتر تا به عنصر دیگری برسد. «پوینتر (Pointer)» آدرسی از حافظه را نگه می دارد. با افزودن 1، پوینتر به عنصر بعدی می رود. چون عناصر آرایه کنار هم هستند، این حرکت معنی دار است. همچنین، برای مرور سریع، حساب پوینتر را ذخیره کن.
تعریف سادهِ حساب پوینتر
وقتی 1 به پوینتر اضافه می کنی، به عنصر بعدی می رسد. چون آرایه پشت سرهم ذخیره می شود. مثال پایین همین را نشان می دهد.
int myNumbers[4] = {25, 50, 75, 100};
int *p = myNumbers;
printf("%d\n", *p);
printf("%d\n", *(p + 1));
printf("%d\n", *(p + 2));
printf("%d\n", *(p + 3));
نکته: این حرکت بر اساس نوع داده است، نه بایت خام. پایین تر توضیح می دهیم.
افزایش و کاهش پوینتر (++/--)
می توانی با ++ ، -- ، و حتی += یا -=، پوینتر را جابه جا کنی. هر بار ++ یعنی رفتن به عنصر بعدی.
int myNumbers[3] = {10, 20, 30};
int *p = myNumbers;
printf("%d\n", *p);
p++;
printf("%d\n", *p);
p--;
printf("%d\n", *p);
p += 2;
printf("%d\n", *p);
تفریق دو پوینتر (فاصله)
اگر هر دو پوینتر داخل یک آرایه باشند، می توانی آن ها را از هم کم کنی. خروجی، تعداد عناصر فاصله است.
int myNumbers[5] = {10, 20, 30, 40, 50};
int *start = &myNumbers[1];
int *end = &myNumbers[4];
printf("%ld\n", end - start);
نکته: تفریق فقط وقتی معتبر است که هر دو پوینتر داخل همان آرایه باشند. نتیجه بر حسب «تعداد عنصر» است، نه بایت.
وابستگی حرکت به نوع داده
افزودن 1 به پوینتر، به اندازه sizeof(نوع) جلو می رود. برای int* معمولا 4 بایت. برای char* یک بایت.
int myNumbers[2] = {1, 2};
char letters[] = "Hi";
int *pi = myNumbers;
char *pc = letters;
printf("%p\n", (void*)pi);
printf("%p\n", (void*)(pi + 1));
printf("%p\n", (void*)(pi + 2));
printf("%p\n", (void*)pc);
printf("%p\n", (void*)(pc + 1));
حلقه با خود پوینتر
می توانی در حلقه، خود پوینتر را حرکت دهی. هر بار p++ به عنصر بعدی می رود. اندیس لازم نیست.
int myNumbers[4] = {25, 50, 75, 100};
int *p = myNumbers;
for (int i = 0; i < 4; i++) {
printf("%d\n", *p);
p++;
}
اشتباهات رایج در حساب پوینتر
- نوع اشتباه: int* با گام 4 بایت می رود؛ char* با 1 بایت.
- پوینتر بدون مقدار: قبلِ استفاده، به مکان معتبر اشاره کند.
- خارج شدن از محدوده: جلوتر از آخر یا قبل از اول نرو.
هشدار: بی دقتی با پوینتر می تواند داده های حافظه دیگر را خراب کند.
برای پیش نیاز این بحث، صفحه پوینتر و آرایه را ببین. برای ادامه، سر بزن به پوینتر به پوینتر.
جمع بندی سریع
- حساب پوینتر یعنی جابه جایی روی عناصر.
- گام حرکت به نوع داده بستگی دارد.
- تفریق پوینتر فقط در یک آرایه معتبر است.
- در حلقه، خود پوینتر را حرکت بده.
- حواست به محدوده و مقداردهی باشد.