# include int foo1(int k) {return (k * k);} void foo2(int *iPtr) {*iPtr = (*iPtr) * (*iPtr);} int main() { int qiymat = 9; int javob = 0; javob = foo1(qiymat); // javob = 81 cout << "javob = " << javob << endl; foo2(&qiymat); // qiymat = 81 cout << "qiymat = " << qiymat << endl; return (0); } Ekranda: javob = 81 qiymat = 81 Yuqoridagi dasturimizda foo2() funksiya chaqirig'ida qiymat nomli
o'zgaruvchimizning adresini oldik (& operatori) va funksiya berdik.
foo2() funksiyamiz iPtr pointer argumentining qiymatini * operatori yordamida
o'zgartiryapti.
Funksiya e'lonida pointer tipidagi parametrlardan keyin o'zgaruvchi ismlarini
berish shart emas. Masalan:
int func(int * , char * ); // funksiya e'loni
int func(int *arg1, char *arg2); // funksiya e'loni
Yuqoridagi ikki e'lon aynidir.
Aytib o'tkanimizdek, massivlarning ismlari birinchi elementlariga
ko'rsatkichdir. Hatto, agar massiv bir indeksli bo'lsa, biz massivlar bilan
ishlash uchun pointer sintaksisini qo'llashimiz mumkin. Kompilyator
foo(int m[]);
e'lonini
foo(int * const m);
e'loniga almashtiradi. Yuqoridagi m pointerini "int tipiga o'zgarmas pointer"
deb o'qiymiz. const bilan pointerlarning qo'llanilishini alohida ko'rib
chiqamiz.
const SIFATLI POINTERLAR const ifodasi yordamida sifatlantirilgan o'zgaruvchining qiymatini normal
sharoitda o'zgartira olmaymiz. const ni qo'llash dasturning hatolardan
holi bo'lishiga yordam beradi. Aslida ko'p dasturchilar const ni qo'llashga
o'rganishmagan. Shu sababli ular katta imkoniyatlarni boy beradilar. Bir
qarashda const ning keragi yo'qdek tuyuladi. Chunki const ni qo'llash
dasturning hech qaysi bir yerida majburiy emas. Masalan konstantalarni
belgilash uchun # define ifodasini qo'llasak bo'ladi, kiruvchi argumentlarni
ham const sifatisiz e'lon qilsak, dastur mantig'i o'zgarishsiz qoladi.
Lekin const kerak-kerakmas joyda o'zgaruvchi va ob'ektlarning
holat-qiymatlarini o'zgartirilishidan himoyalaydi. Yani ob'ekt qiymatini faqat
cheklangan funksiyalar va boshqa dastur bloklari o'zgartira oladilar.
Bu kabi dasturlash uslubi esa, yani ma'lumotni berkitish va uni himoya
qilish ob'ektli dasturlash falsafasiga kiradi.
Ko'rsatkich qo'llanilgan funksiyalarda, agar argumentlar funksiya tanasida
o'zgartirilmasa, kirish parametrlari const deb e'lon qilinishlari kerak.
Masalan, bir massiv elementlarini ekranga bosib chiqaradigan funksiya
massiv elementlarini o'zgartirishiga hojat yo'q. Shu sababli argumentdagi
massiv const sifatiga ega bo'ladi. Endi, agar dasturchi adashib, funksiya
tanasida ushbu massivni o'zgartiradigan kod yozsa, kompilyator hato beradi.
Yani bizning o'zgaruvchimiz himoyalangan bo'ladi. Bu mulohazalar boshqa
tipdagi const sifatli funksiya kirish parametrlariga ham tegishlidir.
Pointerlar bilan const ni to'rt hil turli kombinatsiya qo'llashimiz mumkin.
1. Oddiy pointer va oddiy o'zgaruvchi (pointer ko'rsatayatgan o'zgaruvchi).
2. const pointer va oddiy o'zgaruvchi.
3. Oddiy pointer va const o'zgaruvchi.
4. const pointer va const o'zgaruvchi.
Yuqoridagilarni tushuntirib beraylik. Birinchi kombinatsiyada o'zgaruvchini hech bir narsa himoya qilmаyapti. Ikkinchi holda esa o'zgaruchining qiymatini
o'zgartirsa bo'ladi, lekin pointer ko'rsatayоtgan adresni o'zgartirish ta'qiqlanadi. Masalan massiv ismi ham const pointerdir. Va u ko'rsatayatgan massiv birinchi elementi-ni o'zgartirishimiz mumkin. Endi uchinchi holda pointeri-
miz oddiy, lekin u ko'rsatayatgan o'zgaruvchi himoyalan
gandir. Va nihoyat, to'rtinchi variantda eng yuqori darajadagi o'zgaruvchi himoyasita'minlanadi.
Yuqoridagi tushunchalarga misol berib o'taylik.
// const ifodasi va pointerlar