Маъруза 26. Препроцессор директивалари. Идентификаторларнинг амал доираси. Макросларни аниқлаш ва жойлаштириш.
Режа:
Идентификаторларнинг амал доираси.
Макросларни аниқлаш ва жойлаштириш
Макросларда ишлатиладиган амаллар
Бирлашмалар ва улар устида амаллар
Таянч атамалар: include, define, локал, глобал, cin, if, for, return, ўзгарувчи, идентификатор, макрос.
26.1. Идентификаторларнинг амал доираси
Ўзгарувчилар функция танасида ёки ундан ташқарида эълон қилиниши мумкин. Функция ичида эълон қилинган ўзгарувчиларга локал ўзгарувчилар дейилади. Бундай ўзгарувчилар хотирадаги дастур стекида жойлашади ва фақат ўзи эълон қилинган функция танасида амал қилади. Бошқарув асосий функцияга қайтиши билан локал ўзгарувчилар учун ажратилган хотира бўшатилади (ўчирилади).
Ҳар бир ўзгарувчи ўзининг амал қилиш соҳаси ва яшаш вақти хусусиятлари билан характерланади.
Ўзгарувчи амал қилиш соҳаси деганда ўзгарувчини ишлатиш мумкин бўлган дастур соҳаси (қисми) тушунилади. Бу тушунча билан ўзгарувчининг кўриниш соҳаси узвий боғланган. Ўзгарувчи амал қилиш соҳасидан чиққанда кўринмай қолади. Иккинчи томондан, ўзгарувчи амал қилиш соҳасида бўлиши, лекин кўринмаслиги мумкин. Бунда кўриниш соҳасига рухсат бериш амали «::» ёрдамида кўринмас ўзгарувчига мурожат қилиш мумкин бўлади.
Ўзгарувчининг яшаш вақти деб, у мавжуд бўлган дастур бўлагининг бажарилишига кетган вақт интервалига айтилади.
Локал ўзгарувчилар ўзлари эълон қилинган функция ёки блок чегарасида кўриниш соҳасига эга. Блокдаги ички блокларда худди шу номдаги ўзгарувчи эълон қилинган бўлса, ички блокларда бу локал ўзгарувчи ҳам амал қилмай қолади. Локал ўзгарувчи яшаш вақти - блок ёки функцияни бажариш вақти билан аниқланади. Бу ҳол шуни англатадики, турли функцияларда бир-бирига умуман боғлиқ бўлма-ган бир хил номдаги локал ўзгарувчиларни ишлатиш мумкин.
Қуйидаги дастурда маин() ва сум() функцияларида бир хил номдаги ўзгарувчиларни ишлатиш кўрсатилган. Дастурда иккита соннинг йиғиндиси ҳисобланади ва чоп этилади:
#include
using namespace std;
// funksiya prototipi
int sum(int a, int b);
int main()
{
// lokal o‘zgaruvchilar
int x=r;
int y=4;
cout << sum(x, y);
return 0;
}
int sum(int a,int b)
{
// lokal o‘zgaruvchi
int x=a+b;
return x;
}
Глобал ўзгарувчилар дастур матнида функция аниқланишидан ташқарида эълон қилинади ва эълон қилинган жойидан бошлаб дастур охиригача амал қилади.
#include
using namespace std;
int f1();
int f2();
int main()
{
cout<return 0;
}
int f1()
{
return x; // kompilyatsiya xatosi ro‘y beradi
}
int x=10; // global o‘zgaruvchi e’loni
int f2() { return x*x; }
Юқорида келтирилган дастурда компилясия хатоси рўй беради, чунки f1() функция учун x ўзгарувчиси номаълум ҳисобланади.
Дастур матнида глобал ўзгарувчиларни улар эълонидан кейин ёзилган ихтиёрий функцияда ишлатиш мумкин. Шу сабабли, глобал ўзгарувчилар дастур матнининг бошида ёзилади. Функция ичидан глобал ўзгарувчига мурожат қилиш учун функцияда унинг номи билан мос тушадиган локал ўзгарувчилар бўлмаслиги керак. Агар глобал ўзгарувчи эълонида унга бошланғич қиймат берилмаган бўлса, уларнинг қиймати 0 ҳисобланади. Глобал ўзгарувчининг амал қилиш соҳаси унинг кўриниш соҳаси билан устма-уст тушади.
Шуни қайд этиш керакки, тажрибали дастур тузувчилар имкон қадар глобал ўзгарувчиларни ишлатмасликка ҳаракат қилишади, чунки бундай ўзгарувчилар қийматини дастурнинг ихтиёрий жойидан ўзгартириш хавфи мавжудлиги сабабли дастур ишлашида мазмунан хатолар юзага келиши мумкин. Бу фикримизни тасдиқловчи дастурни кўрайлик.
#include
using namespace std;
// global o‘zgaruvchi e’loni
int test = 100;
void Chop_qilish(void);
int main()
{
//lokal o‘zgaruvchi e’loni
int test=10;
//global o‘zgaruvchi chop qilish funksiyasini chaqirish
Chop_qilish();
cout << “Lokal o’zgaruvchi: ” << test << ‘\n’;
return 0;
}
void Chop_qilish(void)
{
cout<< “Global o’zgaruvchi: ” << test << ‘\n’;
}
Дастур бошида тест глобал ўзгарувчиси 100 қиймати билан эълон қилинади. Кейинчалик, main() функциясида тест номи билан локал ўзгарувчиси 10 қиймати билан эълон қилинади. Дастурда, Chop_qilish() функциясига мурожаат қилинганида, асосий функция танасидан вақтинча чиқилади ва натижада main() функциясида эълон қилинган барча локал ўзгарувчиларга мурожаат қилиш мумкин бўлмай қолади. Шу сабабли Chop_qilish() функциясида глобал тест ўзгарувчисининг қийматини чоп этилади. Асосий дастурга қайтилгандан кейин, main() функциясидаги локал тест ўзгарувчиси глобал тест ўзгарувчисини «беркитади» ва локал тест ўзгарувчини қиймати чоп этилади. Дастур ишлаши натижасида экранга қуйидаги натижалар чоп этилади:
Global o‘zgaruvchi: 100
Lokal o‘zgaruvchi: 10
:: амали.
Юқорида қайд қилингандек, локал ўзгарувчи эълони худди шу номдаги глобал ўзгарувчини «беркитади» ва бу жойдан глобал ўзгарувчига мурожат қилиш имкони бўлмай қолади. C++ тилида бундай ҳолатларда ҳам глобал ўзгарувчига мурожат қилиш имко-нияти сақланиб қолинган. Бунинг учун «кўриниш соҳасига рухсат бериш» амалидан фойдаланиш мумкин ва ўзгарувчи олдига иккита нуқта - «::» қўйиш зарур бўлади. Мисол тариқасида қуйидаги програмани келтирамиз:
#include
using namespace std;
//global o‘zgaruvchi e’loni
int uzg=5;
int main()
{
//lokal o‘zgaruvchi e’loni
int uzg=70;
//lokal o‘zgaruvchini chop etish
cout << uzg << ‘/n’;
//global o‘zgaruvchini chop etish
cout << ::uzg << ‘/n’;
return 0;
}
Дастур ишлаши натижасида экранга олдин 70 ва кейин 5 сонлари чоп этилади.
Do'stlaringiz bilan baham: |