Ишоракунак
- Подробности
- Обновлено 10.01.2011 17:57
- Просмотров: 1274
Ишоракунакхо (pointers) дар назари аввал мучмаланд ва боз савол оиди зарурияти донистани онхо пайдо шуданаш мумкин аст. Хакикат дар он аст, ки онхо метавонанд бисёр чизхоро осонтару соддатар кунанд. Масалан, ба воситаи ишоракунакхо шумо метавонед дар дохили функсия кимати тагйирёбандаеро, ки ба функсия хамчун аргумент накл мешавад, тагйир дихед; инчунин, дар рафти кори барнома метавонед барои массивхо ё руйхатхои пайваста хачми зарурии хотираро чудо намоед ва онро боз озод намоед.
Вазифаи ишоракунакхо аз номи онхо маълум мегардад, яъне онхо ба ягон кисми хотираи фаври ишора мекунанд. Тасаввур кунед, ки як хонае мавчуд аст, ки дар он пиёлахои бисёре. Дар яке аз ин пиёлахо порчаи когазе гузошта шудааст. Дар ин когаз мавкеи пиёлаи дигар навишта шудааст. Шумо ба он мавкеъ мегузаред ва он пиёлаи дигарро мегиред. Дар ин пиёлаи дуюм боз порчаи когазе хаст, ки дар он 18 навишта шудааст. Инак, пиёлае, ки дар он 18 буд, тагйирёбанда аст ва пиёлае, ки дар он мавкеи 18 навишта шуда буд, ишоракунак ба 18 аст.
Тарзи кор бо ишоракунакхо низ ачоиб аст, чунки ба воситаи онхо мавкееро дар хотира аник намудан мумкин аст ва ё метавон киматеро, ки дар он мавкеъ нигох дошта мешавад, дастрас намуд. Албатта, пеш аз истифодаи ишоракунак онро эълон кардан зарур аст ва коидаи эълонкуни чунин аст:
variable_type *name;
Дар ин чо variable_type - намуде, ки ба он ишоракунак name ишора карда метавонад. Ба рамзи ситорача (*) ахамият дихед, мавчуд будани он пеш аз номи ягон тагйирёбанда нишони он аст, ки ин тагйирёбанда ишоракунак аст. Масалан:
int *p; float *d15;
Дар ин чо p ишоракунак ба ягон адади бутун ва d15 ишоракунак ба ягон адади хакики.
Гуфтан зарур аст, ки ду рохи истифодаи ишоракунак барои дастрас намудани маълумот оиди хотирае, ки ба он ишоракунак ишора мекунад, мавчуд аст. 1) Мумкин аст, ки мавкеи ягон тагйирёбандаи дигарро дар хотира муайян намоем ва ё 2) мавкеи ягон тагйирёбандаро ба ягон функсия накл намоем. Барои ин, танхо номи ишоракунакро истифода бурдан кифоя аст (бе рамзи *).
Лекин барои дастрас намудани кимате, ки дар ин мавкеъ (адрес) чойгир аст, рамзи ситорачаро (*) истифода бурдан зарур аст. Номи техникии ин амал dereferencing мебошад.
Барои он ки ишоракунак ба ягон тагйирёбанда вокеан ишора кунад, зарур аст, ки адреси ин тагйирёбанда дар хотираро донем. Барои муайян кардани адреси тагйирёбанда дар хотира рамзи амперсандро (&) пеш аз номи тагйирёбанда гузоштан зарур аст. Азбаски ин амал адреси тагйирёбандаро бозмегардонад, он оператори ишора номида мешавад.
Мисол:
//namuna16.cpp
using namespace std;
#include <iostream>
#include <math>
int main() {
int x;
int *p;
p=&x;
cout<<"Kimati x:";
cin>>x;
cout<<"Kimati x "<<*p<<" ast."<<endl;
cout<<"Adresi x dar khotira "<<p<<" ast."<<endl;
return 0;
}
Дар int x; тагйирйбандаи оддии бутун эълон шудааст. Дар int *p; ишоракунак ба адади бутун эълон шудааст. Баъд, ба p бахшида шудааст адреси x дар хотираи фаври (RAM), ба воситаи рамзи &. Баъди аз тарафи истифодабаранда дохил карда шудани кимати x, cout киматеро, ки дар мавкее бо адреси p чойгир аст, чоп мекунад. Яъне, * пеш аз номи ишоракунак p кимати дар мавкее, ки ба он ишоракунак p мебарад, сабтшударо медихад. Худи p бе рамзи ситорача адреси мавкеъро медихад. Кайд мекунем, ки ишоракунак ба мавкеи x пеш аз ба x бахшидани ягон кимат ишора мекунад. Яъне баъди эълони тагйирёбанда мавкеи он дар хотира муайян аст, гарчанде кимати тагйирёбанда муайян нест.
Пеш аз истифодаи ишоракунак ба он ягон адресро бахшидан зарур аст, дар холати баръакс дар рафти ичрои барнома хатоги ва кандашавии ичрои барнома ба амал омаданашон мумкин аст.
Як мисоли дигар:
//namuna17.cpp
using namespace std;
#include <iostream>
#include <math>
int main() {
int y;
int *pr;
pr=&y;
y=7;
cout<<<"Kimati y "<<*pr<<" ast."<<endl;
cout<<"Adresi y dar khotira "<<pr<<" ast."<<endl;
*pr=15;
cout<<"Kimati *pr "<<y<<" ast."<<endl;
cout<<"Kimati pr "<<&y<<" ast."<<endl;
return 0;
}
Дар мисолхои болои ишоракунакхо ба мавкехое, ки аллакай аз тарафи тагйирёбандахои дигар (x ва y) забт карда шудаанд, ишора мекарданд.
Дар ин чо бояд гуфт, ки тагйирёбандахои намудхои гуногун андозахои гуногун доранд. Яъне тагйирёбандахо вобаста аз намудашон метавонанд микдори гуногуни байтхоро дар хотира банд намоянд. Барои муайян кардани хачми ин ё он намуд аз функсияи sizeof() истифода мебаранд. Мисол:
//namuna18.cpp
using namespace std;
#include <iostream>
int main() {
cout<<"Andozai namudi int - "<<sizeof(int)<<" byte ast."<<endl;
cout<<"Andozai namudi float - "<<sizeof(float)<<" byte ast."<<endl;
cout<<"Andozai namudi char - "<<sizeof(char)<<" byte ast."<<endl;
cout<<"Andozai namudi double - "<<sizeof(double)<<" byte ast."<<endl;
cout<<"Andozai namudi long - "<<sizeof(long)<<" byte ast."<<endl;
return 0;
}
Дар ин чо намуди long барои ададхои бутуни калон лозим аст.
Имконпазир аст, ки ишоракунакхо ба ягон мавкеи озоди хотира ишора кунанд. Ин имконият медихад, ки хачми зарурии хотираи фаври дар рафти ичрои барнома забт ва озод карда шавад. Чунин имконият барои сохтани массивхои дарозиашон тагйирёбанда ё руйхатхои пайваст лозим мешавад, ки дар мавзуъхои оянда бо онхо шинос мешавем. Лекин тавонистани истифодаи калимахои махсуси delete ва new дар оянда лозим мешавад. Калимаи махсуси new барои ба ишоракунак бахшидани адреси ягон мавкеи озоду ба барнома дастраси хотираи фаври истифода бурда мешавад. Тарзи истифодаи ин оператор чунин аст:
variable_type *ptr = new variable_type;
Дар ин сатр ду амал ичро карда мешавад:
1) кисми озоди хотира, ки хачмаш ба андозаи намуди variable_type баробар аст, бо оператори new забт мешавад.
2) ишоракунак ptr ба ин кисми нав забтшудаи хотира ишора мекунад.
Ин кисми хотираро барномахои дигар истифода бурда наметавонанд. Аз ин чо хулоса мебарояд, ки бо хотира эхтиёткорона рафтор намуда, кисми забтшударо, баъди гум шудани зарурият ба он, хатман озод намудан зарур аст. Оператори delete хотираи ба воситаи new забтшударо озод менамояд. Намуди истифодаи ин оператор чунин аст:
delete ptr;
Дар ин чо ptr номи ишоракунак. Услуби зебои барномасози талаб мекунад, ки баъди озод кардани хотираи забтшуда, ба ишоракунаки озодшуда NULL бахшем:
delete ptr; ptr = NULL;
NULL ин доимиест, ки дар компилятор муайян буда, ишора ба NULL ин ишора ба "хеч" аст. Ин рафтор шуморо аз истифодаи хатои ишоракунак эмин медорад. Боз як вазифаи NULL чунин аст: агар дар хотира дигар чои холи набошад, оператори new барои ишоракунак ягон кисми хотираро забт карда наметавонад ва ишоракунак ба NULL баробар аст. Аз ин сабаб, аз руи услуби хуби барномасози санчидан лозим аст, ки ишоракунак ба ягон чо ишора мекунад ё не. Мисол:
//namuna19.cpp
using namespace std;
#include <iostream>
int main() {
int *y;
y = new int;
if(y==NULL)
cout<<"Dar khotira joi kholi nest."<<endl;
return 0;
}
САВОЛХО БАРОИ МУСТАХКАМКУНИ
1. Вазифаи ишоракунакро бо мисол фахмонед.
2. Вазифаи амалхои * ва & чист?
3. Бо кадом максад ба ишоракунак кимати NULL мебахшанд?
4. Вазифаи операторхои delete ва new чист?