Dasturlash II


Laboratoriya ishi №:3 Yangi nomlar fazosini yaratish


Download 297.3 Kb.
bet5/13
Sana07.03.2023
Hajmi297.3 Kb.
#1246573
1   2   3   4   5   6   7   8   9   ...   13
Bog'liq
Дастурлаш 2 Лаборатория иши 2021 (4)

Laboratoriya ishi №:3 Yangi nomlar fazosini yaratish


Ishning maqsadi:
Kerakli jixoz va vositalar: Kompyuter, proyektor
Nazariy ma’lumot.
Yangi nomlar fazosi yaratish. Nomlar fazosi haqida qisqacha ma'lumotga ega bo'lsangiz kerak. Endi bu tushunchani batafsilroq ko'rib chiqamiz va foydalanuvchining nomlar fazosi qanday yaratilishini ko'rib chiqamiz. Namespaces tushunchasi C++ dasturlash tilida nisbatan yaqinda paydo bo'lgan tushunchalarda biridir. Ular nomlarning o'zaro bir xilligini oldini olish (kolliziya saqlanish) uchun identifikatorlarning nomlarini lokalizatsiya qilish uchun mo'ljallangan. Nomlar fazosi tushunchasi kiritilishidan oldin, bu nomlarning barchasi bir xil global nomlar boʻlib, ko'plab nizolarni (xatoliklarni, o'zaro bir xilliklarni) keltirib chiqargan. Agar dasturda dasturchi o'zining toupper() funksiyasini yaratgan bo'lsa, u holda standart kutubxona toupper() funksiyasini (uning parametrlari ro'yxatiga qarab) almashtirishi mumkin. Ammo, ikkala funksiyaning nomlari bir xil global namespaceda saqlangan bo'ladi. Bir xil dasturlarni turli ishlab chiqaruvchilarning funksiyalari va sinflar, kutubxonalar foydalanganda nomlar bir xil bo'lgan funksiyalar dastur bajarilishida ziddiyatlarga duch keladi. Bunday holda, bir kutubxonada aniqlangan nomlar boshqa kutubxonada aniqlangan nomlar bilan to'qnashishi mumkin.
Barcha muammolar nomlar fazosi tushunchasi va namespace kalit so'z tomonidan hal qilindi. Bu kalit so'z yangi nomlar fazosi e'lon qilish orqali barcha funksiya, sinf va kutubxonalarni mahalliylashtirish imkonini beradi. Bu nomlar fazosi turli kontekstlarda bir xil nomdagi funksiya va sinflar ziddiyatga olib kelmasdan ishlatish imkonini beradi. std standart kutubxona (std -Standart Library) juda ko'p foydalanilgan bo'lishi mumkin. Tilning dastlabki variantlarida C++ kutubxonasi global nomlar fazosida belgilangan. Sezilarli darajadagi nomlar ziddiyatlari ehtimolini kamaytirish uchun std namespace nomlar fazosi yaratilgan. Bundan tashqari, ziddiyatlarni oldini olish uchun nomlar fazasi ko'lamini mahalliylashtirish uchun dasturda o'z nom fazongizni yaratishingiz mumkin. Bu shaxsiy sinf yoki funksiya kutubxonalar yaratishda muhim ahamiyatga ega.
Namespace kalit so'zi nomlar fazosi sohalarini qo'shib global namespacedan ajratish imkonini beradi. U aslida nomlar fazosi doirasini belgilaydi. Namespace kalit so'zidan foydalanishning asosiy shakli quyida ko'rsatilgan:

namespace Space{
// . . .
}

Namespace kontentida aniqlangan ixtiyoriy har bir element, bu namespace doirasida bajariladi. 1.12-dastur. my NameSpace nomli namespace e'lon namuna.

namespace MyNameSpace {
int i,k;
void myfunc (int i) { cout <class myclass {
public:
void set(int x) { i = x; }
int get() { return i; }

Nom maydoni nima?


Nomlar maydoni kod maydonini belgilaydi, unda barcha identifikatorlarning o'ziga xosligi kafolatlanadi. Odatiy bo'lib, global o'zgaruvchilar va muntazam funktsiyalar global nomlar maydonida aniqlanadi. Masalan:
bitta
2
3
4
5
6 int g_z = 4;
int boo (int z)
{
qaytish -z;
}
Global o'zgaruvchi g_z va boo () funksiyasi global nomlar maydonida aniqlanadi. Yuqoridagi misolda, boo.h va doo.h fayllari kiritilganda, doOperation () ning ikkala versiyasi ham global nomlar maydoniga kiritilgan va bu aslida nom ziddiyatiga sabab bo'lgan. Ikki mustaqil ob'ekt birgalikda foydalanilganda bir-biriga zid bo'lishi mumkin bo'lgan identifikatorlarga ega bo'lgan bunday vaziyatlardan qochish uchun C ++ nomlar maydoni kalit so'zidan foydalangan holda o'z nomlar bo'shliqlarini e'lon qilish imkonini beradi. Foydalanuvchi tomonidan belgilangan nomlar maydonida e'lon qilingan hamma narsa faqat shu nom maydoniga tegishli (global emas).
Yuqoridagi misoldagi sarlavha fayllarini qayta yozamiz, lekin nomlar maydonidan foydalanib:
boo.h:
bitta
2
3
4
5
6
7
8 nom maydoni Boo
{
// doOperation () ning ushbu versiyasi Boo nom maydoniga tegishli
int doOperation (int a, int b)
{
a + b qaytarish;
}
}
doo.h:
bitta
2
3
4
5
6
7
8 nom maydoni Doo
{
// doOperation () ning ushbu versiyasi Doo nom maydoniga tegishli
int doOperation (int a, int b)
{
a - b qaytish;
}
}
Endi boo.h dan doOperation () Boo nom maydonida va doo.h dan doOperation () Doo nom maydonida. Keling, main.cpp ni qayta kompilyatsiya qilganimizda nima sodir bo'lishini ko'rib chiqaylik:
bitta
2
3
4
5 int main ()
{
std :: cout << doOperation (5, 4); // bu yerda doOperation () ning qaysi versiyasi ishlaydi?
qaytish 0;
}
Boshqa xatolik yuzaga keladi:
C: \ VCProjects \ Test.cpp (15): xato C2065: 'doOperation': e'lon qilinmagan identifikator
Shunday bo'ldiki, biz doOperation () funksiyasini chaqirmoqchi bo'lganimizda, kompilyator doOperation () ta'rifi uchun global nomlar maydoniga qaradi. Biroq, bizning doOperation () versiyalarimizdan hech biri global nomlar maydonida bo'lmaganligi sababli, kompilyator doOperation () ta'rifini umuman topa olmadi! Kompilyatorga doOperation () ning qaysi versiyasidan foydalanish kerakligini aytishning ikki xil usuli mavjud: scope resolver operatori orqali yoki bayonotlar yordamida (bular haqida keyingi darsda gaplashamiz).
Ko'lamni aniqlash operatori orqali nom maydoniga kirish (: :)
Kompilyatorga ma'lum bir nom maydonida identifikatorni qidirishni aytishning birinchi usuli - kerakli nomlar maydoni nomini, shuningdek, sohani aniqlash operatori (: :) va kerakli identifikatordan foydalanish.
Masalan, kompilyatorga Boo nom maydonidagi doOperation () versiyasidan foydalanishni aytaylik:
bitta
2
3
4
5 int asosiy (yaroqsiz)
{
std :: cout << Boo :: doOperation (5, 4);
qaytish 0;
}
Natija:
9
Agar biz Doo nom maydonidan doOperation () versiyasidan foydalanmoqchi bo'lsak:
bitta
2
3
4
5 int asosiy (yaroqsiz)
{
std :: cout << Doo :: doOperation (5, 4);
qaytish 0;
}
Natija:
bitta
Qo'llanish doirasini aniqlash operatori yaxshi, chunki u sizga ma'lum bir nom maydonini tanlash imkonini beradi. Biz hatto quyidagilarni qila olamiz:
bitta
2
3
4
5
6 int asosiy (yaroqsiz)
{
std :: cout << Boo :: doOperation (5, 4) << '\ n';
std :: cout << Doo :: doOperation (5, 4) << '\ n';
qaytish 0;
}
Natija:
9
bitta
Shuningdek, ushbu operatordan hech qanday prefikssiz foydalanish mumkin (masalan, :: doOperation). Bunday holda, biz global nomlar maydoniga murojaat qilamiz.
Xuddi shu nomdagi nomlar maydoni
Nom maydonlarini bir nechta joylarda (yoki bir nechta fayllarda yoki bitta fayl ichida bir nechta joylarda) e'lon qilishga ruxsat beriladi. Bitta nom bloki ichidagi hamma narsa faqat shu blokning bir qismi hisoblanadi.
add.h:
bitta
2
3
4
5
6
7
8 nom maydoni DoMath
{
// add () funksiyasi DoMath nom maydonining bir qismidir
int qo'shish (int x, int y)
{
qaytish x + y;
}
}
subtract.h:
bitta
2
3
4
5
6
7
8 nom maydoni DoMath
{
// Subtract () funksiyasi DoMath nom maydonining bir qismidir
int ayirish (int x, int y)
{
qaytish x - y;
}
}
main.cpp:
bitta
2
3
4
5
6
7
sakkiz
9
10 #include "add.h" // import DoMath :: add ()
#include "subtract.h" // import DoMath :: subtract ()
int main (yaroqsiz)
{
std :: cout << DoMath :: qo'shish (5, 4) << '\ n';
std :: cout << DoMath :: ayirish (5, 4) << '\ n';
qaytish 0;
}
Hammasi kerak bo'lganidek ishlaydi.
C++ standart kutubxonasi ushbu xususiyatdan keng foydalanadi, chunki undagi barcha sarlavha fayllari o'z funksiyalarini std nom maydonida amalga oshiradi.
Taxalluslar va ichki nomlar maydoni
Ba'zi nomlar bo'shliqlari boshqa nom maydonlari ichiga joylashtirilishi mumkin. Masalan:
bitta
2
3
4
5
6
7
sakkiz
9
10
o'n bir
12
o'n uch
14
15 #include
nom maydoni Boo
{
nom maydoni Doo
{
const int g_x = 7;
}
}
int main ()
{
std :: cout << Boo :: Doo :: g_x;
qaytish 0;
}

E'tibor bering, Doo Boo ichida bo'lgani uchun g_x ga Boo :: Doo :: g_x orqali kirish mumkin.



Download 297.3 Kb.

Do'stlaringiz bilan baham:
1   2   3   4   5   6   7   8   9   ...   13




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling