Ko‘rsatkich arifmetikasi
Ko‘rsatkich arifmetikasi
Ko‘rsatkich arifmetikasi — ko‘rsatkich xotiradagi boshqa elementga ishora qilishi uchun uning qiymatini o‘zgartirish demakdir.
Oldingi sahifada ko‘rganimizdek, massiv elementlari xotirada yonma-yon saqlanadi. Shuning uchun ko‘rsatkich bitta elementga ishora qilayotgan bo‘lsa, unga 1 qo‘shish uni keyingi elementga siljitadi:
Misol
int myNumbers[4] = {25, 50, 75, 100};
int *p = myNumbers; // points to myNumbers[0]
printf("%d\n", *p); // 25
printf("%d\n", *(p + 1)); // 50
printf("%d\n", *(p + 2)); // 75
printf("%d\n", *(p + 3)); // 100
Oshirish va kamaytirish
Ko‘rsatkichni ++ va -- (shuningdek, += / -=) yordamida siljitishingiz mumkin:
Misol
int myNumbers[3] = {10, 20, 30};
int *p = myNumbers; // myNumbers[0]
printf("%d\n", *p); // 10
p++; // move to myNumbers[1]
printf("%d\n", *p); // 20
p--; // back to myNumbers[0]
printf("%d\n", *p); // 10
p += 2; // jump to myNumbers[2]
printf("%d\n", *p); // 30
Bu ko‘rsatkichni xuddi hisoblagich kabi siljitish mumkinligini ko‘rsatadi: har safar p++ yoki p-- ishlatganingizda, u massivdagi keyingi yoki oldingi elementga o‘tadi.
Ko‘rsatkichlarni ayirish (masofa)
Bitta massivdagi elementlarga ishora qiluvchi ikki ko‘rsatkichni ayirib, ular orasida nechta element borligini bilib olishingiz mumkin:
Misol
int myNumbers[5] = {10, 20, 30, 40, 50};
int *start = &myNumbers[1]; // points to 20
int *end = &myNumbers[4]; // points to 50
printf("%ld\n", end - start); // 3 elements apart
Bu yerda:
startikkinchi elementga (20) ishora qiladi.endbeshinchi elementga (50) ishora qiladi.end - startular orasidagi elementlar sonini beradi: 3.
Eslatma: Ko‘rsatkichlarni ayirish faqat ikkala ko‘rsatkich bitta massivga ishora qilganda ishlaydi. Natija baytlarda emas, elementlarda o‘lchanadi.
Ko‘rsatkich arifmetikasi tipga bog‘liq
Barcha ko‘rsatkichlar ham bir xil siljimaydi.
Ko‘rsatkichga 1 qo‘shganingizda, u shunchaki 1 baytga emas, balki o‘zi ishora qilayotgan narsaning o‘lchamiga oldinga siljiydi.
Masalan:
int*ko‘rsatkichi butun son o‘lchamiga (odatda 4 bayt) siljiydi.char*ko‘rsatkichi belgi o‘lchamiga (1 bayt) siljiydi.
Demak, ikkala ko‘rsatkich ham 1000 xotira manzilidan boshlansa:
int*→p + 11004manziliga siljiydichar*→p + 11001manziliga siljiydi
Bu ko‘rsatkichning siljishi siz qo‘shgan songa emas, balki u ishora qilayotgan ma’lumot tipiga bog‘liq ekanini ko‘rsatadi:
Misol
int myNumbers[2] = {1, 2};
char letters[] = "Hi"; // 'H', 'i', '\0'
int *pi = myNumbers; // int pointer
char *pc = letters; // char pointer
printf("%p\n", (void*)pi);
printf("%p\n", (void*)(pi + 1)); // moves by sizeof(int) (4 bytes)
printf("%p\n", (void*)(pi + 2)); // moves by sizeof(int) (4 bytes)
printf("%p\n", (void*)pc);
printf("%p\n", (void*)(pc + 1)); // moves by 1 byte
Ko‘rsatkichlar bilan sikl
Oldingi bobda *(ptr + i) yordamida massivni sikl bilan aylanib chiqishni o‘rgandingiz.
Endi boshqa usulni ko‘rib chiqaylik — sikl ichida ko‘rsatkichning o‘zini siljitish. Ko‘rsatkich har safar oshirilganda (p++), u xotiradagi keyingi elementga o‘tadi:
Misol
int myNumbers[4] = {25, 50, 75, 100};
int *p = myNumbers; // start of array
for (int i = 0; i < 4; i++) {
printf("%d\n", *p);
p++; // move to next element
}
Har bir iteratsiyada quyidagilar sodir bo‘ladi:
*pjoriy element qiymatini beradi.p++ko‘rsatkichni massivdagi keyingi elementga siljitadi.- Massiv indeksi (
i) kerak emas — joriy o‘rinni ko‘rsatkichning o‘zi kuzatib boradi.
Maslahat: Sikldan bunday foydalanish xotira bilan bevosita ishlashda keng tarqalgan, chunki indeks raqami o‘rniga ko‘rsatkichning o‘zi massiv bo‘ylab harakatlanadi.
Keng tarqalgan xatolardan saqlaning
- Noto‘g‘ri tipdan foydalanish: Ko‘rsatkichning siljishi uning tipiga bog‘liq ekanini unutmang.
int*4 baytlik qadamlar bilan,char*esa har safar 1 baytga siljiydi. Ularni chalkashtirib yuborsangiz, ko‘rsatkich noto‘g‘ri xotira joylariga ishora qiladi. - Initsializatsiya qilinmagan ko‘rsatkichlar: Ko‘rsatkichdan foydalanishdan oldin u haqiqatan mavjud narsaga ishora qilayotganiga doim ishonch hosil qiling. Hech qayerga ishora qilmaydigan ko‘rsatkichdan foydalanish dasturingizning ishdan chiqishiga sabab bo‘lishi mumkin.
- Chegaradan chiqib ketish: Ko‘rsatkichni hech qachon massiv oxiridan keyinga yoki boshlanishidan oldinga siljitmang. Yagona xavfsiz "tashqi" o‘rin — oxiridan bir qadam keyingi o‘rin, u ham faqat ko‘rsatkichlarni taqqoslash uchun, qiymatlarga murojaat qilish uchun emas.
Va ehtiyot bo‘ling: ko‘rsatkichlar bilan ehtiyotkorlik bilan ishlash kerak, chunki boshqa xotira manzillarida saqlangan ma’lumotlarni buzib qo‘yish mumkin.
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
