c-png-clipart

C++: Boshlang’ich tushunchalar

  • E’lon qilish va aniqlash

  • Obyekt

  • Soha

  • Xotira davri

  • L-ifodalar va R-ifodalar

E’lon qilish va aniqlash

C++ dasturlash tilida o’zgaruvchi, doimiy, funksiya, sinf va boshqa nomlar foydalanilishidan oldin aniqlanishi kerak. Ko’p hollarda aniqlanish va e’lon qilish bir vaqtda bajariladi. Lekin ularning farqi bor. Bu farqni quyidagi misollarda ko’rish mumkin:

  1. extern int a; // a e’lon qilinyapti
  2.  
  3. extern const int b; // b e’lon qilinyapti
  4.  
  5. int Func(int); // Func e’lon qilinyapti
  6.  
  7. struct S; // S e’lon qilinyapti
  8.  
  9. typedef int Integer; // Integer e’lon qilinyapti
  10.  
  11. int a; // a aniqlanyapti
  12.  
  13. extern const int b = 10; // b aniqlanyapti
  14.  
  15. int Func(int x) // Func aniqlanyapti
  16. {
  17. return x + a;
  18. }
  19.  
  20. struct S // S aniqlanyapti
  21. {
  22. int x; // x aniqlanyapti
  23. static int y; // y e’lon qilinyapti
  24.  
  25. S() : x(0) { } // S ning konstruktori aniqlanyapti
  26. };
  27.  
  28. int S::y = 1; // S ning y a’zosi aniqlanyapti
  29.  
  30. enum {Oq, Qora}; // Oq va Qora aniqlanyapti

Quyidagi misollarda e’lon qilish va aniqlash bir vaqtda bajariladi. Faraz qilaylik, bizda misol.cpp fayli mavjud va u quyidagi matnga ega.

  1. // misol.cpp
  2. #include <iostream>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. // Shaxs sinfi va uning a'zolari aniqlanyapti
  8. class Shaxs
  9. {
  10. public:
  11. string Ism;
  12. int Yosh;
  13. };
  14.  
  15. // Shaxs sinfi nusxasi P aniqlanyapti
  16. Shaxs P;
  17.  
  18. // Funksiya Func aniqlanyapti
  19. void Func(Shaxs p)
  20. {
  21. // ...
  22. cout << "Ismi: " << p.Ism << endl;
  23. cout << "Yoshi: " << p.Yosh << endl;
  24. }
  25.  
  26. // Year e’lon qilinyapti
  27. extern int Year;
  28.  
  29. // main funksiyasida yuqoridagi nomlar foydalanilyapti
  30. int main()
  31. {
  32. P.Ism = "Tom";
  33. P.Yosh = 15;
  34. Func(P);
  35. return 0;
  36. }

Yuqorida Year o’zgaruvchisi e’lon qilinyapti. Undan foydalanish mumkin qachonki u misol.cpp faylini o’zida yoki boshqa faylda aniqlangan bo’lsa.

Obyekt

C++ standartiga ko’ra, obyekt bu xotiraning biror bir qismi yoki sohasidir (funksiya ob’yekt emas u hatto xotiraning biror qismini egallasada). Obyekt u aniqlanganda, new operatori yordamida va kompillyator tomonidan yaratilishi mumkin (masalan, this, __func__ o’zgaruvchilari kompillyator tomonidan yaratiladi). Obyekt nomga ega bo’lishi mumkin. Obyekt ma’lumot turiga ega, masalan, int, double, string va h. Obyekt xotira davriga ega va bu davr ob’yektning mavjudlik davrini belgilaydi. Obyekt polimorf bo’lishi mumkin, ya’ni, u bir yoki undan ortiq virtual funksiyalarga ega bo’lishi mumkin (keyingi darslarda to’liqroq yoritiladi).

Obyekt o’z tarkibiga boshqa ob’yektlarni olishi mumkin. Obyekt tarkibidagi obyektlar subobyektlar deyiladi. Subobyekt sinf a’zosi, “ona” obyekt (vorislik) yoki massiv elementi sifatida bo’lishi mumkin. Ikkita obyekt bir xil adresga ega bo’lishi mumkin agar biri ikkinchisining tarkibida bo’lsa.

Standartga ko’ra, barchasi obyekt deyilsada, obyekt so’zi odatda murakkab yoki tarkibiy qismga ega bo’lgan obyektlarga, masalan sinf nusxalariga nisbatan ishlatiladi. Skalyar turdagi, masalan int, double, char obyektlarini odatda o’zgaruvchilar deyiladi.

Soha

Har bir nom dastur matnining biror sohasida (global soha, namespace sohasi, blok yoki lokal soha, funksiya sohasi, funksiya prototipi sohasi, sinf sohasi, enumeration sohasi, shablon parametri sohasi) e’lon qilinadi. Bu soha dastur matnining shu nom foydalanilishi mumkin bo’lgan eng katta qismi hisoblanadi va bu sohada shu nom sohani aniqlash operatori :: siz foydalanilishi mumkin. Bu soha nomning e’lon qilingan sohasi deyiladi. Lekin nom, e’lon qilingan sohaning amal qilish sohasi deb ataluvchi sohasidagina mavjud. Bu soha esa nom e’lon qilingan nuqtadan boshlanadi. Lekin nomning amal qilish sohasi har doim ham uzluksiz bo’lmasligi mumkin.

  1. // misol2.cpp
  2. int j = 1;
  3.  
  4. int main()
  5. {
  6. int i, j;
  7. j = 2;
  8. ::j = 3;
  9. }

Ushbu misolda birinchi ‘j’ ning e’lon qilingan sohasi misol2.cpp faylining to’liq matni, ya’ni global soha hisoblanadi. Amal qilish sohasi esa int j dan keyin boshlanadi va misol2.cpp fayli matnining oxirigacha davom etadi. Lekin bu soha main funksiya “tanasi” da, vergul dan } belgigacha bo’lgan sohani o’z ichiga olmaydi. Chunki verguldan so’ng xuddi shu nom bilan boshqa o’zgaruvchi e’lon qilingan.

Ikkinchi ‘j’ ning e’lon qilingan sohasi funksiyaning “tanasi”, ya’ni { } belgilar orasidagi soha hisoblanadi, ya’ni funksiya sohasi. Uning amal qilish sohasi nuqta-verguldan oldin boshlanadi va } belgida tugaydi. Ikkinchi ‘j’ ning amal qilish sohasida birinchi ‘j’ “yashiriladi” va u :: operatori orqali foydalaniladi.

  1. int x = 12;
  2.  
  3. { int x = x; } // lokal x o’zining shaxsiy (noma’lum) qiymatiga teng
  4.  
  5. const int i = 10;
  6.  
  7. { int i[i]; } // lokal i 10 elementli massiv
  8.  
  9. const int Oq = 5;
  10.  
  11. { enum { Oq = Oq + 1, Qora = Oq + 1 }; } // Oq 6 va Qora 7 ga teng

enum elementlarining e’lon qilingan sohasi enum e’lon qilingan soha hisoblanadi.

Xotira davri

Har bir obyekt xotira davriga ega. Bu obyektning xususiyati bo’lib, dastur xotirasining shu obyekt egallagan qismi, sohasining davrini belgilaydi. Obyekt bir vaqtning o’zida faqat bitta xotira davriga ega bo’lishi mumkin. Obyektning xotira davri obyekt qanday yaratilishiga asosan aniqlanadi va quyidagilardan biri bo’lishi mumkin:

  • statik xotira davri

  • oqim (thread) xotira davri (C++ 11 dan boshlab)

  • avtomatik xotira davri

  • dinamik xotira davri

Statik, oqim va avtomatik xotira davrlari kompillyator tomonidan bilvosita yaratiladigan obyektlar bilan bog’liq (obyektlar aniqlanganda ular bilvosita yaratiladi). Dinamik xotira davri new operatori bilan yaratiladigan obyektlar bilan bog’liq.

Global yoki namespace sohada aniqlangan obyektlar, static belgili lokal yoki sinf a’zosi bo’lgan obyektlar statik xotira davriga ega bo’ladilar. Bunday obyektlar uchun xotira dastur ishga tushganda ajratiladi va dastur ishi yakunlanganda bo’shatiladi. Boshqacha aytganda, ularning xotiradagi o’rni yoki adresi dasturning butun ishi davomida o’zgarmaydi.

thread_local belgili barcha obyektlar oqim xotira davriga ega. Bunday obyektlar uchun xotira ular foydalanilgan oqimlar yaratilganida ajratiladi va oqimlar ishini tugatganida bo’shatiladi. Global obyektdan farqli ravishda, thread_local obyekt har bir oqim uchun alohida yaratiladi. Eslatma: oqim bu dastur kodini bajaruvchi subdastur (подпрограмма). Dastur kodi bir yoki undan ortiq oqimlar tomonidan bajarilishi mumkin.

Blok/lokal sohada aniqlangan register belgili, yoki blok/lokal sohada aniqlangan static yoki extern belgisiz obyektlar avtomatik xotira davriga ega. Bunday obyektlar faqat ular aniqlangan blok ichidagina mavjud bo’ladi.

new operatori orqali yaratiladigan obyektlar dinamik xotira davriga ega bo’ladilar. Bunday obyektlar delete operatori orqali tugatiladi. Statik, oqim va avtomatik xotira davriga ega obyektlarning yaratilishi va tugatilishi kompillyator tomonidan bilvosita boshqariladi. Dinamik obyektlarning yaratilishi va tugatilishi esa dasturchi tomonidan boshqariladi.

// misol3.cpp
#include <string>
 
namespace MyNamespace
{
    int i;                // Statik xotira davriga ega
}
 
int j = 1;                // Statik xotira davriga ega
 
thread_local int TI;      // Oqim xotira davriga ega
 
double *PD;               // Statik xotira davriga ega
 
struct Person
{
    // ...
    static int Count;
};
 
int Person::Count = 0;        // Statik xotira davriga ega
 
void SomeFunc()
{
    static char C = ‘A’;      // Statik xotira davriga ega
    register int rv;          // Avtomatik xotira davriga ega
    std::string Str;          // Avtomatik xotira davriga ega
    // ...
    if (Str == “”)
    {
        int N;                // Avtomatik xotira davriga ega
        // ...
    }
}
 
int main()
{
    // PD ko’rsatgan obyekt dinamik xotira davriga ega
    PD = new double(3.14);
    // ...
    delete PD;
}

L-ifodalar va R-ifodalar

Operatorlar va operandlar ketma-ketligidan iborat hisoblash birligi ifoda deyiladi. Ifodaning natijasi biror bir turdagi qiymatga olib kelishi mumkin. C++ standartiga ko’ra, har bir ifoda o’z qiymat kategoriyasiga ega va u quyidagilardan biri bo’lishi mumkin:

  • lvalue (left-value), ya’ni chap tomon qiymati, yoki l-ifoda. Bu odatda “=” operatorining chap tomonida turgan operand, masalan, funksiya yoki obyekt bo’lishi mumkin.

  • xvalue (“eXpiring” value), ya’ni tugab borayotgan qiymat, yoki x-ifoda. Bu tugatilish arafasida turgan vaqtinchali obyekt, yoki funksiya natijasi bo’lishi mumkin.

  • prvalue (“pure” rvalue), ya’ni “butunlay” o’ng tomon qiymat, yoki x-ifoda bo’lmagan r-ifoda. r-ifoda odatda “=” operatorining o’ng tomonida turgan operand, masalan, o’zgarmas literallar 20, true, 3.5 yoki natijasi adres (reference) bo’lmagan funksiyaning qiymati.

  1. int i;
  2. i = 1; // i l-ifoda. i = 1; ning natijasi ham l-ifoda, chunki (i = 1) = 5; ifoda ham to’g’ri. 1 va 5 lar esa prvalue
  3.  
  4. int& Func1() // l-ifoda, chunki Func1() = 10; ifoda ham to’gri hisoblanadi
  5. {
  6. //...
  7. }
  8.  
  9. int* Func2() // Func2() r-ifoda, lekin *Func2() l-ifoda, chunki *Func2() = 50; ifoda to'g'ri hisoblanadi
  10. {
  11. //...
  12. }
  13.  
  14. std::string Func3() // Func3() x-ifoda. Chungi uning natijasida yaratilgan obyekt resursi boshqa obyektga “ko’chiriladi” (C++ 11 dan boshlab)
  15. {
  16. //...
  17. }
  18.  
  19. double Func4() // Func4() x-ifoda bo’lmagan r-ifoda, yoki prvalue.
  20. {
  21. //...
  22. }
(929 marta o'qilgan, bugun 1 marta o'qildi)

O'xshash maqolalar: