Паролингизни унутдингизми?
Login
Left, Right, Center Left, Center, Right Center, Left, Right



C++ 3-darslik

FUNKSIYALAR   C++ da dasturlashning asosiy bloklaridan biri funksiya-lardir. Funksiyalarning foydasi shundaki, katta masala bir necha kichik bo'laklarga bo'linib, har biriga alohida funksiya yozilganda, masala yechish algoritmi ancha soddalashadi.

 

 Bunda dasturchi yozgan funksiyalar C++ ning standart kutubhonasi va boshqa firmalar yozgan kutub-honalar ichidagi funksiyalar bilan birlashtiriladi. Bu esa ishni osonlashtiradi. Ko'p holda dasturda takroran bejariladigan amalni funksiya sifatida yozish va kerakli joyda ushbu funksiyani chaqirish mumkin. Funksiyani programma tanasida ishlatish uchun u chaqiriladi, yani uning ismi yoziladi va unga kerakli argumentlar beriladi.

() qavslar ushbu funksiya chaqirig'ini ifodalaydi. Masalan:

 foo();

k = square(l);

 Demak, agar funksiya argumentlar olsa, ular () qavs ichida yoziladi. Argumentsiz funksiyadan keyin esa () qavslarning o'zi qo'yiladi. 

 

MA'LUMOTLAR TIPI (DATA TYPES)

    Shu paytgacha ma'lumotlar tipi deganda butun son va kasrli son bor deb kelgan edik. Lekin bu bo'limda maylumotlar tipi tushunchasini yahshiroq ko'rib chiqish kerak bo'ladi. Chunki funksiyalar bilan ishlaganda argument kiritish va qiymat qaytarishga to'g'ri keladi. 

  Agar boshidan boshlaydigan bo'lsak, kompyterda hamma turdagi ma'lumotlar 0 va 1 yordamida kodlanadi. Buning sababi shuki, elektr uskunalar uchun ikki holat tabiyi-dir, tok oqimi bor yoki yo'q, kondensatorda zaryad bor yoki yo'q va hakozo. Demak biz bu holatlarni oladigan jihozlarni bir quti deb faraz qilsak, quti ichida yo narsa bo'ladi, yo narsa bo'lmaydi. Mantiqan buni biz bir yoki nol deb belgilaymiz. Bu kabi faqat ikki holatga ega bo'lishi mumkin bo'lgan maylumot birligiga biz BIT deymiz. Bu birlik kichik bo'lgani uchun kompyuterda bitlar guruhi qo'llaniladi. Bittan keyingi birlik bu BAYT (byte). Baytni sakkizta bit tashkil etadi. Demak bir bayt yordamida biz 256 ta holatni kodlashimiz mumkin bo'ladi. 256 soni ikkining sakkizinchi darajasiga tengdir.

Bitimiz ikki holatga ega bo'lgani uchun biz kompyuterni ikkili arifmetikaga asoslangan deymiz. Ammo agar kerak bo'lsa, boshqa sistemaga asoslangan mashinalarni ham qo'llash mumkin. Masalan uchli sanoq sistemasiga asoslangan kompyuterlar bor. Informatika faniga ko'ra esa, hisoblash mashinasi uchun eng optimal sanoq sistemasi e ga teng bo'lar ekan. Demak amaldagi sistemalar ham shu songa iloji borisha yaqin bo'lishi kerakdir. 

 C/C++ da baytga asoslangan tip char dir. char tipi butun son tipida bo'lib, chegaraviy qiymatlari -128 dan +127 gachadir. Bu tip lotin alifbosi harflarini va y ana qo'shimcha bir guruh simvollarni kodlashga qulay bo'lgan. Lekin hozirda milliy alifbelarni kodlash uchun 16 bitlik UNICODE qo'llanilmoqda. U yordamida 65536 ta simvolni ko'rsatish mumkin. char tipida o'zgaruvchi e'lon qilish uchun dasturda

char g, h = 3, s;

 kabi yozish kerak. O'zgaruvchilar vergul bilan ayriladi. E'lon bilan bir vaqtning o'zida boshlang'ich qiymat ham berish imkoni bor. Mashina ichida baytdan tashkil topgan boshqa kattaliklar ham bor. Ikki baytdan tuzilgan  kattalik so'z (word) deyiladi, unda 16 bit bo'ladi. 4 ta bayt guruhi esa ikkili so'z (double word) bo'ladi. Bu birlik 32 bitli mashimalarda qo'llaniladi. Hozirda qo'llanilmoqda bo'lgan mashinalar asosan 32 bitlidir, masalan Pentium I/II/III sistemalari. C++ da butun sonlarning ikki tipi bor. Biri char - uni ko'rib chiqdik. Ikkinchisi int dir. Mashinalarning arhitekturasi qanday kattalikda bo'lsa, int tipining ham kattakigi huddi shunday bo'ladi. 16 bitlik mashinalarda int 16 bit edi. Hozirda esa int ning uzunligi 32 bitdir. int (integer - butun son) tipi charga o'hshaydi. Farqi bir baytdan kattaligidadir. 16 bitli int ning sig'imi -32768 dan +32767 gachadir. 32 bitli int esa -2 147 483 648 dan +2 147 483 647 gacha o'rin egallaydi. Bu ikki butun son tipidan tashqari C++ da ikki tur vergulli, (nuqtali) yani haqiqiy son tipi mavjud. Bulardan biri float, hotirada 4 bayt joy egallaydi. Ikkinchisi esa double, 8 bayt kattalikka ega. Bularning harakteristikalari quyidagi jadvalda berilgan. Ushbu tiplar bilan ishlaganda unsigned(ishorasiz, +/- siz), signed (ishorali) long (uzun) va short (qisqa) sifatlarini qo'llasa bo'ladi. unsigned va signed ni faqat butun son tiplari bilan qo'llasa bo'ladi. unsigned qo'llanganda sonning ishorat biti bo'lmaydi, ishorat biti sonning kattaligini bildirish uchun qo'llaniladi. Masalan char tipida 8 chi, eng katta bir odatda ishorat bitidir. Biz unsigned char ch; desak, ch o'zgaruvchimizga faqat 0 va musbat qiymatlarni berishimiz mumkin. Lekin oddiy char [-128;127] ichida bo'lsa, unsigned char [0;255] orasidagi qiymatlarni oladi, chunki biz ishorat biti ham qo'llamoqdamiz. Huddi shunday unsigned int da (4 baytli) qiymatlar [0;4 294 467 296] orasida yotadi.

signed ni ishlatib esa biz ochiqchasiga butun sonimizning ishorati bo'lishi kerakligini bildiramiz. Normalda agar signed yoki unsigned qo'yilmasa, tipimizning ishorasi bo'ladi. long int bilan qo'llanilganda 16 bitli int 32 ga aylanadi. Bu agar mashina 16 bitli bo'lsa, mashina 32 bitli arhitekturaga ega bo'lsa, int ning kattaligi 4 bayligicha qolaveradi. long double tipi esa 10 bayt joy oladi. Short sifati int bilan qo'llanilganda 32 bit emas, 16 bit joy egallashga boshlaydi. Tezlikni oshirish maqsadida kam joy egallaydigan ma'lumot tiplarini qo'llash maqsadga muofiqdir. Agar tipning nomi yozilmagan bo'lsa, o'zgaruvchi int tipiga ega deb qabul qilinadi.

 

Ma'lumot               Sinonimlar       Keng tarqalgan  

tiplarining nomlari                     harakteristikalari  

 

long double                           10 bayt, +/-3.4e-4932...+/-3.4e4932

double                                   8 bayt,   +/-1.7e-308...+/-1.7e308

float                                       4 bayt,     +/-3.4e-38...+/-3.4e38

unsigned long int                  unsigned long             

long int                                  long

unsigned int                           unsigned

int

unsigned short int                  unsigned short

short int                                  short

unsigned char           

short

char

   char va int dan tashqari C++ da yana bir necha integral tiplar mavjud. Bulardan biri bool tipidir. bool tipi faqat ikki farqli qiymat olishi mumkin. Bittasi true (to'g'ri) ikkinchisi false (noto'g'ri). bool tipi mantiqiy arifmetika amallarini bajarganda juda qo'l keladi. bool tipi boshqa bir integral tipga asoslangan bo'lishiga qaramasdan (int yoki char), yuqoridagi ikki qiymatdan tashqari boshqa qiymat ololmaydi. bool tipi o'zgaruvchilari to'g'ri shaklda initsalizatsiya qilinmagan taqdirda, ularning qiymati hato ravishda na true va na false bo'lishi mumkin.Yana boshqa bir integral tip bu wchar_t dir (wide char type - keng simvol tipi). U ham ko'pincha boshqa bir butun son tipiga asoslanadi - bir baytdan kattaroq bo'lishi kerakligi uchun short int qo'llaniladi.wchar_t simvollar kodlanishida qo'llaniladi. Masalan C++ da UNICODE ni odatda wchar_t bilan kodlaymiz. Hozirda wchar_t ning kattaligi 16 bit, lekin yuqori kattaligi necha bit bo'lishi kerakligi standartda belgilanmagan. Butun sonlarni C++ da bir necha asosda berish mumkin. Hech qanday belgi qo'yilmasdan  yozilgan son o'nlik asosda (decimal) deb qabul qilinadi.

Sakkizli asosdagi (octal) sonni berish uchun sondan oldin 0o yoki 0O belgilarini qo'yish kerak.O'n oltilik sistemadagi (hexadecimal) sonlar oldiga 0x yoki 0X lar yoziladi. Sakkizli sistemada qo'llaniladin raqamlar to'plami 0,1,2,3,4,5,6 va 7 dir. O'n oltilik asosda 0 dan 9 gacha sonlar, 10 - a, 11 - b, 12 - c, 13 - d, 14 - e va 15 uchun f qo'llaniladi. Harflar katta bo'lishi ham mumkin. Harflarning registorining (katta-kichikligi) farqi yo'q. Misol beraylik:

 

char d = 10, j = 0o11; // d 10 ga teng, j 9 ga teng.

int f = 0X10;          // f 16 ga teng    

   Butun son va kasr son tiplaridan tashqari C++ da void (bo'sh, hech narsa) tipi ham mavjud. Bu tipning oladigan qiymatlari bo'sh to'plamga tengdir. Void tipidagi ma'lumot chala tugallangan hisoblanadi. Boshqa turdagi ma'lumotni void ga keltirish mumkindir. Bu tip bilan ishlashni dasturlarimizda ko'rib chiqamiz.

 

MA'LUMOTLAR TIPINI KELTIRISH (DATA CASTING)

    Gohida bir turdagi o'zgaruvchining qiymatini boshqa tipdagi o'zgaruvchiga berish kerak bo'ladi. Bu amal ma'lumot tipini keltirish (data type casting) deyiladi. Ko'p hollarda bu amal avtomatik ravishda, kompilyator tarafidan bajariladi. Masalan ushbu parchani ko'raylik:

 char c = 33;

int k;

k = c;

    Bu yerda k ning sig'imi c nikidan kattaroqdir. Shuning uchun c ning qiymatini k ga berishda hech qanday muammo paydo bo'lmaydi. Quyidagi misolni ko'raylik:

 int i = 5;

float f = 9.77;

float result;

 result = f + i;

    C++ ning kompilyatori ikki turdagi o'zgaruvchilar bilan ishlay olmaydi. Shu sababli ifodadagi sig'imi kichik bo'lgan o'zgaruvchilar ifodadagi qatnashgan eng katta sig'imga o'tqaziladi. Bu ham avtomatik tarzda bajariladi. i o'zgaruvchimiz qiymati vaqtinchalik float tipidagi o'zgaruvchiga beriladi. Bu vaqtinchalik o'zgaruvchi esa f ga qo'shiladi. Chiqqan javob result ga beriladi. Yuqorida ko'rib chiqqanlarimiz kompilyator tarafidan bajariladi. Bu kabi tip o'zgarishlarini avtomatik konversiya(implicit conversion) deymiz. Lekin gohida to'g'ri kelmaydigan tiplarni birga qo'llashga to'g'ri keladi. Masalan float tipiga double tipni o'tqazish, char ga int va hokazo. Bu hollarda ochiq konversiya (explicit conversion) amalini bajarishimiz kerak. Buni bajarishning ikki uslubi bor. Birinchisi C da qo'llaniladigan yo'l, ikkinchisi C++ uslubi. C da tipni keltirish uchun o'zgaruvchi oldiga kerakli tipni () qavslar ichida yozamiz.

 

int k = 100;

char s;

 s = (char)k;

   Yuqorida k ning qiymatini char tipidagi vaqtinchalik o'zgaruvchiga berildi, keyin s ga ushbu o'zgaruvchi qiymatini berildi.Bu yerda etibor berilishi kerak bo'lgan narsa shuki, 100 char ga ham to'g'ri keladi. Agar k ning qiymati char oladigan qiymattan kattaroq/kichikroq bo'ladigan bo'lsa, bu hato olib keladi. Shu sababli C dagi tip keltirish nisbatan havfli hisoblanadi. Lekin albatta bilib qo'llanilsa katta yordam beradi. C++ da ma'lumotlar tipini keltirish uchun mahsus operatorlar kiritildi. C uslubidagi keltirish hamma sharoitda qo'llanilar edi. C++ ning keltirish operatorlari esa faqat o'ziga ajratilgan funksiyalarni bajaradi. Undan tashqari ular C dagi keltirishlardan ko'ra kuchsizroqdir. Shu sababli hato ehtimoli kamaytirildi. Yana bir afzallik tarafi shundaki, yangi stildagi keltirish operatorlari tip tekshirishlarini bajarishadi, agar noto'g'ri keltirish bajarilsa, bu sintaktik hatoga olib keladi.

Ular quyida berilgan:

 static_cast

dynamic_cast

const_cast

reinterpret_cast

 static_cast ni ko'rib chiqaylik.

 int k = 200;

char h;

 h = static_cast<char>(k);

 

  static_cast dan keyin kerakli tip nomi <> qavslar ichida beriladi, va tipi o'zgarishi kerak bo'lgan o'zgaruvchi () qavslar ichida parametr sifatida beriladi.       Static_cast kompilyatsiya davrida tip keltirishlarida qo'llaniladi.dynamic_cast esa dastur ishlash davrida tip keltirishlari uchun qo'llaniladi.

const_cast esa o'zgaruvchilardan const (o'zgarmas) va volatile (o'zgaruvchan, uchuvchan) sifatlarini olib tashlashda qo'llaniladi. Odatda const o'zgaruvchining qiymatini o'zgartirib bo'lmaydi. Ushbu holda const_castqo'llaniladi. reinterpret_cast  odatiy bo'lmagan keltirishlarni bajarishda qo'llaniladi (masalan void* ni int ga). reinterpret_cast o'zgaruvchining bitlarini boshqa ma'noda qo'llashga imkon beredi. Bu operator bilib ishlatilinishi kerak. Ushbu operatorlar bilan keyinroq yanada yaqin tanishamiz.

 

MATEMATIK KUTUBHONA FUNKSIYALARI

    Standart kutubhonaning matematik funksiyalari ko'pgina amallarni bajarishga imkon beradi. Biz bu kutubhona misolida funksiyalar bilan ishlashni ko'rib chiqamiz. Masalan bizning dasturimizda quyidagi satr bor bo'lsin:

 

double = k;

int m = 123;

k = sin(m);

 kompilyator uchbu satrni ko'rganida,standart kutubhonadan sin funksiyasini chaqiradi. Kirish qiymati sifatida m ni berdik. Javob, yani funksiyadan qaytgan qiymat k ga berildi.Funksiya agumentlari o'zgarmas sonlar (konstanta) o'zgaruvchilar, ifodalar va boshqa mos keluvchi qiymat qaytaradigan funksiyalar bo'lishi mumkin. Masalan:

 int g = 49, k = 100;

cout << "4900 ning ildizi -> "<< sqrt( g * k );

 Ekranda:

 

4900 ning ildizi -> 70;

 Matematik funksiyalar aksariyat hollarda double tipidagi qiymat qaytarishadi.Kiruvchi argumentning tipi sifatida esa double ga keltirilishi mumkin bo'lgan tip beriladi. Bu funksiyalarni ishlatish uchun math.h (yangi ko'rinishda cmath)e'lon faylini include bilan asosiy dastur tanasiga kiritish kerak.Quyida matematik funksiya-lar kutubhonasining bazi bir a'zolarini beraylik. x va y o'zgaruvchilari double tipiga ega.

Funksiya     Aniqlanishi                                 Misol

 

ceil(x)      x ni x dan katta yoki unga teng b-n         ceil(12.6) = 13.0

             eng kichik butun songacha yahlitlaydi       ceil(-2.4) = -2.0

cos(x)       x ning trigonometrik kosinusi (x radianda)  cos(0.0)   = 1.0

exp(x)       e ning x chi darajasi (eskponetsial f-ya)   exp(1.0)   =  2.71828

                                                         exp(2.0)   = 7.38906

fabs(x)      x ning absolut qiymati                      x>0 => abs(x) = x

                                                         x=0 => abs(x) = 0.0

                                                         x<0 => abs(x) = -x

floor(x)     x ni x dan kichik bo'lgan eng katta         floor(4.8) = 4.0

             butun songacha yahlitlaydi                  floor(-15.9) = -16.0

fmod(x,y)    x/y ning qoldig'ini kasr son tipida beradi  fmod(7.3,1.7) = 0.5

log(x)       x ning natural lagorifmi (e asosiga ko'ra)  log(2.718282) = 1.0

log10(x)     x ning 10 asosiga ko'ra lagorifmi           log10(1000.0) = 3.0

pow(x,y)     x ning y chi darajasini beradi              pow(3,4) = 81.0   

                                                         pow(16,0.25) = 2

sin(x)       x ning trigonometrik sinusi (x radianda)    sin(0.0)   = 0.0

sqrt(x)      x ning kvadrat ildizi                       sqrt(625.0) = 25.0

tan(x)       x ning trigonometrik tangensi (x radianda)  tan(0.0) = 0

 

FUNKSIYALARNING TUZILISHI

    Funksiyalar dasturchi ishini juda yengillashtiradi. Funksiyalar yordamida programma modullashadi, qismlarga bo'limadi. Bu esa keyinchalik dasturni rivojlantirishni osonlashtiradi. Dastur yozilish davrida hatolarni topishni yengillashtiradi. Bir misolda funksiyaning asosiy qismlarini ko'rib chiqaylik.

 

int foo(int k, int t) {

   int result;

     result = k * t; 

   return (result);

} 

  Yuqoridagi foo funksiyamizning ismi, () qavslar ichidagi parametrlar – int tipidagi k va t lar kirish argument-laridir, ular faqat ushbu funksiya ichida ko'rinadi va qo'llaniladi. Bunday o'zgaruvchilar lokal(local-mahalliy)

deyiladi. result foo() ning ichida e'lon qilinganligi uchun u ham lokaldir. Demak biz funksiya ichida o'zgaruvchilarni va klaslarni (class) e'lon qilishimiz mumkin ekan. Lekin funksiya ichida boshqa funksiyani e'lon qilib bo'lmaydi. foo() funksiyamiz qiymat ham qaytaradi. Qaytish qiymatining tipi foo() ning e'lonida eng boshida kelgan - int tipiga ega. Biz funksiyadan qaytarmoqchi bo'lgan qiymatning tipi ham funksiya e'lon qilgan qaytish qiymati tipiga mos kelishi kerak - ayni o'sha tipda bo'lishi yoki o'sha tipga keltirilishi mumkin bo'lgan tipga ega bo'lishi shart. Funksiyadan qiymatni return ifodasi bilan qaytaramiz. Agar funksiya hech narsa qaytarmasa e'londa  void tipini yozamiz. Yani:

 void funk(){

   int g = 10;

      cout << g;

   return;

} 

 

Bu funksiya void (bo'sh, hech narsasiz) tipidagi qiymatni qaytaradi. Boshqacha qilib aytganda qaytargan qiymati bo'sh to'plamdir. Lekin funksiya hech narsa qaytarmaydi deya olmaymiz. Chunki hech narsa qaytarmaydigan mahsus funksiyalar ham bor. Ularning qaytish qiymati belgilana-digan joyga hech narsa yozilmaydi. Biz unday funksiyalarni keyinroq qo'rib chiqamiz. Bu yerda bir nuqta shuki, agar funksiya mahsus bo'lmasa, lekin oldida qaytish qiymati tipi ko'rsatilmagan bo'lsa, qaytish qiymati int tipiga ega deb qabul qilinadi.

void qaytish tipli funksiyalardan chiqish uchun return; deb yozsak yetarlidir.Yoki return ni qoldirib ketsak ham bo'ladi. Funksiyaning qismlari bajaradan vazifasiga ko'ra turlicha nomlanadi. Yuqorida korib chiqqanimiz funksiya aniqlanishi (function definition) deyiladi, chunki biz bunda funksiyaning bajaradigan amallarini funksiya nomidan keyin,{} qavslar ichida aniqlab yozib chiqyapmiz. Funksiya aniqlanishida {} qavslardan oldin nuqta-vergul (;) qo'yish hatodir. Bundan tashqari funksiya e'loni,

prototipi yoki deklaratsiyasi (function prototype) tushunchasi qo'llaniladi. Bunda funksiyaning nomidan keyin hamon nuqta-vergul qo'yiladi, funksiya tanasi esa berilmaydi. C++ da funksiya qo'llanilishidan oldin uning aniqlanishi yoki hech bo'lmaganda e'loni kompilyatorga uchragan bo'lishi kerak. Agar funksiya e'loni boshqa funksiyalar aniqlanishidan tashqarida berilgan bo'lsa, uning kuchi ushbu fayl ohirigacha boradi. Biror bir funksiya ichida berilgan bo'lsa kuchi faqat o'cha funksiya ichida tarqaladi. E'lon fayllarda aynan shu funksiya e'lonlari berilgan bo'ladi. Funksiya e'loni va funksiya aniqlanishi bir-biriga mos tushishi kerak.

Funksiya e'loniga misol:

 double square(char, bool);

float average(int a, int b, int c);

 Funksiya e'lonlarda kirish parametrlarining faqat tipi yozish kifoya, huddi square() funksiyasidek. Yoki kiruvchi parametrlarning nomi ham berilishi mumkin, bu nomlar kompilyator tarafidan etiborga olinmaydi, biroq dasturning o'qilishini ancha osonlashtiradi. Bulardan tashqari C++ da funksiya imzosi (function signature) tushunchasi bor. Funksiya imzosiga funksiya nomi, kiruvchi parametrlar tipi, soni, ketma-ketligi kiradi. Funksiyadan qaytuvchi qiymat tipi imzoga kirmaydi.

 int foo();             //No1

int foo(char, int);    //No2

double foo();          //No3 - No1 funksiya bilan imzolari ayni.

void foo(int, char);   //No4 - No2 bilan imzolari farqli.

char foo(char, int);   //No5 - No2 bilan imzolari ayni.

int foo(void);         //No6 - No1 va No3 bilan imzolari ayni,

                       //      No1 bilan e'lonlari ham ayni.

 

Yuqoridagi misolda kirish parametrlari bo'lmasa biz () qavsning ichiga void deb yozishimiz mumkin (No6 ga qarang). Yoki () qavslarning quruq o'zini yozaversak ham bo'ladi (No1 ga qarang). Yana  bir tushuncha - funksiya chaqirig'idir. Dasturda funksiyani chaqirib,qo'llashimiz uchun uning chaqiriq ko'rinishini ishlatamiz. () qavslari funksiya chaqirig'ida qo'llaniladi. Agar funksiyaning kirish argumentlari bo'lmasa, () qavslar bo'sh holda qo'llaniladi. Aslida () qavslar C++ da operatorlardir. Funksiya kirish parametrlarini har birini ayri-ayri yozish kerak, masalan yuqoridagi

float average(int a, int b, int c);

funksiyasini

float average(int a,b,c); // Hato!

deb yozishimiz hatodir. 

 Hali etib o'tganimizdek, funksiya kirish parametrlari ushbu funksiyaning lokal o'zgaruvchilaridir. Bu o'zgaruvchilarni funksiya tanasida boshqattan e'lon qilish sintaksis hatoga olib keladi. Bir dastur yozaylik.

 

//Funksiya bilan ishlash

# include <iostream.h>

 

int foo(int a, int b); //Funksiya prototipi,

                       //argumentlar ismi shart emas.

 int main()

{

   for (int k = 1; k <6; k++){

      for (int l = 5; l>0; l--){

         cout << foo(k,l) << " ";        //Funksiya chaqirig'i.

      }//end for (l...)

      cout << endl;

   }//end for (k...)

return (0);

} //end main()

 //foo() funksiyasining aniqlanishi

int foo(int c, int d)

{ //Funksiya tanasi    

   return(c * d);

}

 

Ekranda:

 5 4 3 2 1

10 8 6 4 2

15 12 9 6 3

20 16 12 8 4

25 20 15 10 5

 Bizda ikki sikl ichida foo() funksiyamiz chaqirilmoqda. Funksiyaga k va l o'zgaruvchilarining nushalari uzatil-moqda. Nushalarning qiymati mos ravishda funksiyaning aniqlanishida berilgan c va d o'zgaruvchilarga berilmoqda. k va l ning nushalari deganimizda adashmadik, chunki ushbu o'zgaruvchilarining qiymatlari funksiya chaqirig'idan hech qanday ta'sir ko'rmaydi. C++ dagi funksiyalarning bir noqulay tarafi shundaki, funksiyadan faqat bitta qiymat qaytadi. Undan tashqari yuqorida ko'rganimizdek, funksiyaga berilgan o'zgaruvchilarning faqat nushalari bilan ish ko'rilarkan. Ularning qiymatini normal sharoitda funksiya ichida o'zgartirish mumkin emas. Lekin bu muammolar ko'rsatkichlar yordamida osonlikcha hal etiladi. Funksiya chaqiriqlarida avtomatik ma'lumot tipining konversiyasi bajariladi. Bu amal kompilyator tomonidan bajarilganligi sababli funksiyalarni chaqirganda ehtiyot bo'lish kerak. Javob hato ham bo'lishi mumkin. Shu sababli kirish parametrlar tipi sifatida katta hajmli tiplarni qo'llash maqsadga muofiq bo'ladi. Masalan double tipi har qanday sonli tipdagi qiymatni o'z ichiga olishi mumkin. Lekin bunday qiladigan bo'lsak, biz tezlikdan yutqazishimiz turgan gap. Avtomatik konversiyaga misol keltiraylik.

int division(int m, int k){

return (m / k);

}

 

dasturda chaqirsak:

...

float f = 14.7;

double d = 3.6;

int j = division(f,d); //f 14 bo'lib kiradi, d 3 bo'lib kiradi

                       // 14/3 - butun sonli bo'lish esa 4 javobini beradi 

cout << j;

...

 

Ekranda:

 4

   Demak kompilyator f va d o'zgaruvchilarining kasr qismlarini tashlab yuborar ekan. Qiymatlarni pastroq sig'imli tiplarga o'zgartirish hatoga olib keladi.

 

E'LON FAYLLARI

    Standart kutubhona ichidagi funksiyalarni ishlatish uchun ularning prototiplari joylashgan e'lon fayllarini include preprosessor buyrug'i bilan dastur ichiga kirgazish kerak.Quyida biz ba'zi bir keng qo'llaniladigan e'lon fayllarini keltirib o'tamiz, ularning yangi va bor bo'lsa eski ismlarini beramiz. Quyida yangi bo'lgan atamalarni keyinchalik tushuntirib o'tamiz.

 <assert.h> Dastur ishlashini diagnostika qilish uchun kerakli makrolar va

ma'lumotlarni e'lon qiladi. Yangi ismi <cassert>.

<ctype.h>Simvollarni test qilishda va harflar registorini kattadan kichikka va teskarisiga o'zgartirishda qo'l-laniladigan funksiyalar e'lonlarini o'z ichiga oladi. Yangi ismi <cctype>.

<float.h> Kasrli (haqiqiy) sonlarning sistemaga bog'liq limitlari aniqlangan.

Yangi ismi <cfloat>.

<limits.h> Butun sonlarning sistemaga bog'liq limitlari berilgan. Yangi ismi

<climits>.

<math.h> Matematik funksiyalar kutubhonasini e'lon qiladi. Yangi ismi <cmath>.

<stdio.h> Standart kirish/chiqish funksiyalarining e'lonlari berilgan. Yangi

ismi <cstdio>.

<stdlib.h> Sonlarni tekstga, tekstni songa aylantiruvchi funksiyalar, hotira bilan ishlaydigan funksiyalar, tasodifiy sonlar generatsiya qiluvchi funksiyalari va boshqa yordamchi funksiyalar e'lonlarini o'z ichiga oladi.

Yangi ismi <cstdlib>.

<string.h> C uslubida satrlar bilan ishlovchi funksiyalar e'loni berilgan.

Yangi ismi <cstring>.

<time.h> Vaqt va sana  bilan ishlaydigan funksiylar e'lonlari berilgan. Yangi

ismi <ctime>.

<iostream.h>Standart kirish/chiqish oqimi bilan ishlovchi funksiyalar e'loni kiritilgan.  Yangi ismi <iostream>.

<iomanip.h>  Oqim manipulyatorlari berilgan. Yangi ismi <iomanip>.<fstream.h> Diskda joylashgan fayllar bilan kirish/chiqish amallarini bajaruvchi funksiyalar ellonlari berilgan. Yangi ismi <fstream>. Quyidagi e'lon fayllarining faqat bitta ismi bir. 

<utility> Boshqa kutubhonalar tomonidan qo'llaniladigan yordamchi funksiyalar va klaslarning e'lonlari kiritilgan

<vector>, <list>, <deque>, <queue>, <stack>, <map>, <set>, <bitset> standart kutubhona konteyner klaslarining e'lonlarini o'z ichiga olganlar.

<functional> Standart kutubhona algoritmlari tomonidan qo'llaniladigan klas va funksiyalarini e'lon qiladi.

<memory> Standart kutubhona konteynerlari uchun hotira ajratishda qo'llaniladigan funksiya va klaslar e'lonlari berilgan.

<iterator> Konteynerlar ichidagi ma'lumotlar manipulyatsiyasida qo'llaniladigan iterator klaslari e'lonlari berilgan.

<algorithm> Konteynerlardagi ma'lumitlarni qayta ishlashda qo'llaniladigan funksiya va klaslar e'lonlari berilgan.

<exception>, <stdexcept> Fafqulotda hodisalar mehanizmini bajaruvchi klaslar berilgan.

<string> Standart kutubhonaning string klasi e'loni berilgan.

<sstream> Hotiradagi satrlarga kirish/chiqishni bajaradi-gan funksiyalar prototipi berilgan.

<locale> Mahalliy sharoitga moslashgan birliklar (pul,

vaqt, sonlarning turli ko'rinishlari) bilan ishlaydigan funksiyalar e'lonlari berilgan.

<limits> Hisoblash sistemalarida sonli ma'lumot tiplari-ning chegaralarini belgilashda ishlatiladigan klas e'lonlari berilgan.

<typeinfo> Ijro vaqtida tip identefikatsiyasi uchun qo'llaniladigan klaslar e'loni kiritilgan. Qo'llanuvchi yozgan e'lon fayllari .h bilan tugasa maqsadga muofiq bo'ladi. Bunday fayllar qo'shtirnoqlarga olingan holda dasturga kiritiladi, yani

masalan:

 # include "mening_faylim.h"

 

TASODIFIY QIYMATLARNI KELTIRIB CHIQARISH

    Kompyuter faning ko'p sohalarida tasodifiy qiymatlar bilan ishlash kerak bo'ladi. Masalan o'yin tuzganda, ma'lum bir tabiiy hodisani modellashtirganda va hokazo. Bunda dasturlash tasodifiy qiymatni olishga asoslangan. Va o'sha tasodifiy qiymatga bog'langan holda biror bir funksiya bajariladi yoki ifoda hisoblanadi. Tasodifiy qiymatni standart kutubhonaning rand() funksiyasi bilanolsa bo'ladi. rand() 0...RAND_NAX orasida yotgan butun son qiymatini qaytaradi. RAND_MAX <stdlib.h> da aniqlangan simvolik konstantadir. Uning kattaligi 32767 dan kichik bo'lmasligi kerak. rand() qaytaradigan qiymat aslini olganda psevdo-tasodifiydir. Yani dastur qayta-qayta ishlatilganda ayni qiymatlarni beraveradi. To'la tasodifiy qilish uchun dastur har gal ishlatilganda ma'lum bir o'zgaruvchan qiymatga asoslanib boshlanishi kerak.Buning uchun srand() funksiyasi qo'llaniladi. srand() dasturda faqat bir marta chaqirilsa yetarlidir. Dastur ishlash davomida esa ehtiyojga qarab, rand() chaqirilaveradi. Tasodifiy qiymatlar bilan ishlash uchun <stdlib.h> ni include bilan e'lon qilishimiz kerak. Yuqoridagi funksiyalarning prototiplarini berib o'taylik:

void srand(unsigned int seed);

int rand();

 

Biz har gal dastur ishlaganda srand() ga seed o'zgaruvchisini klaviaturadan kiritishimiz mumkin, yoki buni avtomatik tarzda bo'ladigan qilishimiz mumkin.

Buning bir yo'li

 srand( time(NULL) );

 deb yozishdir. Bunda kompyuter avtomatik ravishda o'z ichidagi soatning qiymatini time() funksiyasi yordamida o'qiydi va srand() ga parametr sifatida beradi. time() ni NULL yoki 0 argument bilan chaqirganimizda kompyuter soatining joriy vaqti sekundlar ko'rinishida qaytaradi. Vaqt bilan ishlash uchun <time.h> ni e'lon qilish kerak bo'ladi. Nardaning 6 lik toshidek ishlaydigan dastur yozaylik. 

 

//rand()/srand() bilan ishlash.

# include <iostream.h>

# include <stdlib.h>

# include <time.h>

 

int main()

{

   srand( time(NULL) );

   int k;

   for (k = 1; k<11; k++){

      cout << (1 + rand() % 6) << ( (k % 5 == 0) ? endl : " " );

   }//end for(k...)

 

   return (0);

}//end main()

 

Bu yerda amallar siklda bajarilmoqda. rand() % 6 ifodasi masshtablash (scaling) deyiladi. rand() dan qaytuvchi qiymat 0...RAND_MAX orasida bo'lishi mumkin, biz bu qiymatni 6 ga ko'ra modulini olsak, bizda javob sifatida faqat 0, 1, 2, 3, 4 va 5 qiymatlari bo'lishi mumkin. Keyin esa biz bu qiymatlarni siljitamiz, yani 1 raqamini qo'shamiz. Shunda javoblar bizga kerakli oraliqda yotgan bo'ladi. ?: shart operatori bilan biz har bir raqamdan keyin ekranga nima bosilib chiqishini hal qilyapmiz, bu yoki endl bo'ladi, yoki bo'shliq bo'ladi. Tasodifiy qiymatlar bilan biz keyingi dasturlarimizda hali yana ishlaymiz.

 C/C++ dagi enumeration (ketma-ketlik) tipini tanishtirib o'taylik. Enumeration butun sonli konstantalar yig'indi-sidir.Konstantalar qiymati agar boshlangich qiymat berilmagan bo'lsa, noldan boshlanadi va 1 ga oshib boraveradi, yoki biz qiymatlarni o'zimiz berishimiz mumkin. Masalan:

 enum MeningSinifim {AKMAL, TOHIR, NIGORA};

MeninigSinfim SinfA;

SinfA = TOHIR;

SinfA = AKMAL;

  Bu yerdagi MeningSinfim qo'llanuvchi tarafidan tuzilgan yangi tipdir.Keyin esa ushbu tipda bo'lgan SinfA o'zgaruv

chisini e'lon qilamiz. Ushbu tipdagi o'zgaruvchi faqat uchta farqli qiymatni qabul qiladi. Bunda AKMAL 0 ga teng, TOHIR 1 ga va NIGORA 2 ga teng bo'ladi. Lekin biz enumeration tipida bo'lgan o'zgaruvchilarga faqat {} qavslar ichida berilgan simvolik ismlarni bera olamiz. Yani to'g'ridan-to'g'ri sonli qiymat bera olmaymiz. Boshqa bir ketma-ketlik:

 enum Oylar {YAN = 1, FEV, MAR, APR, MAY, IYUN, IYUL, AVG, SEN, OKT, NOY, DEK};

 Bunda qiymatlar birdan boshlanadi va birga ortib boradi. Enumeration qiymatlari katta harflar bilan yozilsa, dastur ichida ajralib turadi. Va sonli konstantalardan ko'ra ishlash qulayroqdir.

 

DASTUR BIRLIKLARINING SIFATLARI

 O'zgaruvchilarning kattaligi, ismi va turidan tashqari yana bir necha boshqa  hossalari bor. Bulardan biri hotirada saqlanish tipidir. O'zgaruvchilar hotirada ikki uslubda saqlanishi mumkin. Birinchisi avtomatik, ikkinchisi statik yo'ldir. Avtomatik bo'lgan birlik u e'lon qilingan blok bajarilishi boshlanganda tuziladi, va ushbu blok tugaganda buziladi, u hotirada egallagan joy esa bo'shatiladi. Faqat o'zgaruvchilar avtomatik bolishi mumkin. Avtomatik sifatini berish uchun o'zgaruvchi boshiga auto yoki register so'zlari qo'yiladi. Aslida lokal o'zgaruvchilar oldiga hech narsa yozilmasa, ularga auto sifati beriladi.

  Dastur ijro etilganda o'zgaruvchilar markaziy prosessor registrlariga yuklanib shlov ko'radilar. Keyin esa yana hotiraga qaytariladilar. Agar register  sifatini qo'llasak, biz kompyuterga ushbu o'zgaruvchini ishlov ko'rish payti davomida registrlarning birida saqlashni tavsiya etgan bo'lamiz. Bunda hotiraga va hotiradan yuklashga vaqt ketmaydi. Albatta bu juda katta vaqt yutug'i bermasligi mumkin, lekin agar sikl ichida ishlatilsa, yutuq sezilarli darajada bo'lishi mumkin. Shuni etish kerakki, hozirgi kundagi kompilyatorlar bunday ko'p ishlatiladigan o'zgaruvchilarni ajrata olishdi va o'zlari ular bilan ishlashni optimizatsiya qilishadi. Shu sababli o'zgaruvchini register deb e'lon qilish shart bo'lmay qoldi.

  Hotirada boshqa tur saqlanish yo'li bu statik saqlanishdir. Statik sifatini o'zgaruvchi va funksiyalar olishlari mumkin. Bunday birliklar dastur boshlanish nuqtasida hotirada quriladilar va dastur tugashiga qadar saqlanib turadilar. O'zgaruvchi va funksiyalarni statik qilib e'lon qilish uchun static  yoki extern (tashqi) ifodalari e'lon boshiga qo'yiladi. Statik o'zgaruvchilar

dastur boshida hotirada quriladilar va initsalizatsiya qilinadilar. Fuksiyalarning ismi esa dastur boshidan bor bo'ladi. Lekin statik birliklar dastur boshidan mavjud bo'lishi, ularni dasturning istalgan nuqtasida turib qo'llasa bo'ladi degan gap emas. Hotirada saqlanish uslubi bilan qo'llanilish sohasi tushunchalari farqli narsalardir. O'zgaruvchi mavjud bo'lishi mumkin, biroq ijro ko'rayatgan blok ichida ko'rinmasligi mumkin.

 Dasturda ikki hil statik birliklar bor.  Birinchi hili bu tashqi identefikatorlardir. Bular global sohada aniqlangan o'zgaruvchi va funksiyalardir. Ikkinchi tur statik birliklar esa static ifodasi bilan e'lon qilingan lokal o'zgaruvchilardir. Global o'zgaruvchi va funksiyalar oldida extern deb yozilmasa ham ular extern sifatiga ega bo'ladilar. Global o'zgaruvchilar ularning e'lonlarini funksiyalar tashqarisida yozish bilan olinadi. Bunday o'zgaruvchi va funksiyalar o'zlaridan faylda keyin keluvchi har qanday funksiya tomonidan qo'llanilishi mumkin.

 Global o'zgaruvchilarni ehtiyotorlik bilan ishlatish kerak. Bunday o'zgaruvchilarni harqanday funksiya o'zgartirish imkoniga ega. O'zgaruvchiga aloqasi yo'q funksiya uning qiymatini bilib-bilmasdan o'zgartirsa, dastur mantig'i buzilishi mumkin. Shu sababli global sohada iloji boricha kamroq o'zgaruvchi aniqlanishi lozim. Faqat bir joyda ishlatilinadigan o'zgaruvchilar o'sha blok ichida aniqlanishi kerak. Ularni global qilish noto'g'ridir. Lokal o'zgaruvchilarni, yani funksiya ichida e'lon qilingan o'zgaruvchilarni static so'zi bilan e'lon qilish mumkin. Bunda ular ikkinchi hil static birliklarni tashkil qilishgan bo'lishadi. Albatta ular faqat o'sha funksiya ichida qo'llanishlari mumkin. Ammo funksiya bajarilib tugaganidan so'ng static o'zgaruvchilar o'z qiymatlarini saqlab qoladilar va keyingi funksiya chaqirig'ida saqlanib qolingan qiymatni yana ishlatishlari yoki o'zgartirishlari mumkin.

 Statik o'zgaruvchilar e'lon paytida initsalizatsiya qilinadilar. Agar ularga e'lon paytida ochiqchasiga qiymat berilmagan bo'lsa, ular nolga tenglashtiriladi.

 static double d = 0.7; // ochiqchasiga qiymat berish,

static int k;          // qiymati nol bo'ladi.

 Agar static yoki extern ifodalari global identefikatorlar bilan qo'llanilsa, ushbu identefikatorlar mahsus ma'noga egadirlar. Biz u hollarni keyin ko'rib o'tamiz.

 

QO'LLANILISH SOHASI (SCOPE RULES)

 O'zgaruvchi dasturning faqat ma'lum sohasida ma'moga egadir. Yani faqat biror bir blok, yoki bu blok ichida joylashgan bloklar ichida qo'llanilishi mumkin. Bunday blokni soha (qo'llanilish sohasi - scope) deb ataylik. Identefikator (oz'garuvchi yoki funksiya ismi) besh hil sohada aniqlanishi mumkin. Bular funksiya sohasi, fayl sohasi, blok sohasi, funksiya prototipi sohasi va klas sohasi.

 Agar identefikator e'loni hech bir funksiya ichida joylashmagan bo'lsa, u fayl sohasiga egadir. Ushbu identefikator e'lon nuqtasidan to fayl ohirigacha ko'rinadi. Global o'zgaruvchilar, funksiya prototiplari va aniqlanishlari shunday sohaga egadirlar.

 Etiketlar (label), yani identefikatorlardan keyin ikki nuqta (:) keluvchi

ismlar, masalan:

chiqish: 

mahsus ismlardir. Ular dastur nuqtasini belgilab turadilar. Dasturning boshqa yeridan esa ushbu nuqtaga sakrashni (jump) bajarish mumkin. Va faqat etiketlar funksiya sohasiga egadirlar. Etiketlarga ular e'lon qilingan funksiyaning istalgan joyidan murojaat qilish mumkin. Lekin funksiya tashqarisidan ularga ishora qilish ta'qiqlanadi. Shu sababli ularning  qo'llanilish sohasi funksiyadir. Etiketlar switch va goto ifodalarida ishlatilinadi. Goto qo'llanilgan bir blokni misol qilaylik. 

 int factorial(int k) {

if (k<2)

   goto end;

else

   return ( k*factorial(k-1) );

 end:

   return (1);

}

 

Bu funksiya sonning faktorialini hisoblaydi. Bunda 0 va 1 sonlari uchun faktorial 1 ga teng, 1 dan katta x soni uchun esa x! = x*(x-1)*(x-2)...2*1 formulasi bo'yicha hisoblanadi. Yuqoridagi funksiya rekursiya metodini ishlatmoqda, yani o'zini-o'zini chaqirmoqda. Bu usul dasturlashda keng qo'llaniladi. Funksiyamiz ichida bitta dona etiket - end: qollanilmoqda. Etiketlarni qo'llash strukturali dasturlashga to'g'ri kelmaydi, shu sababli ularni ishlatmaslikga harakat qilish kerak.

Blok ichida e'lon qilingan identefikator blok sohasiga egadir. Bu soha o'zgaruvchi e'lonidan boshlanadi va } qavsda (blokni yopuvchi qavs) tugaydi.  Funksiyaning lokal o'zgaruvchilari hamda funksiyaning kiruvchi parametrlari blok sohasiga egadirlar. Bunda parametrlar ham funksiyaning local o'zgaruvchilari qatoriga kiradilar. Bloklar bir-birining ichida joylashgan

bo'lishi mumkin. Agar tashqi blokda ham, ichki blokda ham ayni ismli  identefikator mavjud bo'lsa, dastur isjrosi ichki blokda sodir bo'layatgan bir vaqtda ichki identefikator tashqi blokdagi identefikatorni to'sib turadi. Yani ichki blokda tashqi blok identefikatorining ismi ko'rinmaydi. Bunda ichki blok faqat o'zining o'zgaruvchisi bilan ish yuritishi mumkin. Ayni ismli tashqi blok identefikatorini ko'rmaydi. Lokal o'zgaruvchilar static deya belgilanishlariga qaramay, faqat aniqlangan bloklaridagina qo'llanila oladilar. Ular dasturning butun hayoti davomida mavjud bo'lishlari ularning qo'llanilish sohalariga ta'sir ko'rsatmaydi.  Funksiya prototipi sohasiga ega o'zgaruvchilar funksiya e'lonida berilgan identefikatorlardir. Aytib o'tkanimizdek, funksiya prototipida faqat o'zgaruvchi tipini bersak yetarlidir. identefikator ismi berilsa, ushbu ism kompilyator tomonidan hisobga olinmaydi. Bu ismlarni dasturning boshqa yerida hech bir qiyinchiliksiz qo'llash mumkin. Kompilyator hato bermaydi. Klas sohasiga ega ismlar klas nomli bloklarda aniqlanadilar. Bizlar klaslarni keyinroq o'tamiz.

Hozir soha va hotirada saqlanish tipi mavzusida bir misol keltiraylik.

 

//Qo'llanilish sohasi, static va auto

//o'zgaruvchilarga misollar.

 # include <iostream.h>

long r = 100; //global o'zgaruvchi,

                      //funksiyalar tashqarisida aniqlangan

void staticLocal(); //funksiya prototipi yoki e'loni

void globalAuto(int k /* k funksiya prototipi sohasiga ega */); //f-ya e'loni

 

int main ()

{

   staticLocal();

   staticLocal();

   int m = 6;

   globalAuto(m);

   ::r = ::r + 30;  

   cout "main da global long r: ";

   cout << ::r << endl; //global long r to'liq aniqlangan

                                   //ismi o'rqali qo'llanilmoqda

   m++;//m = 7

   globalAuto(m);

      int r = 10; //tashqi sohadagi main ga nisbatan lokal o'zgaruvchi;

                       //long r ni to'sadi

   cout << "tashqi sohadagi lokal r: " << r << endl;

      { //ichki blok

          short r = 3; //ichki sohadagi lokal o'zgaruvchi;

                       //int r ni to'sadi

          cout << "ichki sohadagi lokal r: " << r << endl;

      }

   cout << "tashqi sohadagi lokal r: " << r << endl;

   return (0);

}

 void staticLocal() {

   static  int s = 0; //statik o'zgaruvchi

   cout << "staticLocal da: " << s << endl;

   s++; //s = 1;

}

 void globalAuto(int i) {

   int g = 333; //avtomatik o'zgaruvchi

   cout << "globalAuto da: " << i << " ";

   cout << g << " ";

   g++;

   cout << r << endl; //global long r ekranga bosiladi

}

  Ekranda:

staticLocal da: 0

staticLocal da: 1

globalAuto da: 6 333 100

main da global long r: 130

globalAuto da: 7 333 130

tashqi sohadagi lokal r: 10

ichki sohadagi lokal r: 3

tashqi sohadagi lokal r: 10

 

ARGUMENT OLMAYDIGAN FUNKSIYALAR

 Agar funksiya prototipida () qavslar ichiga void deb yozilsa, yoki hech narsa yozilmasa, ushbu funksiya kirish argument olmaydi. Bu qonun C++ da o'rinlidir. Lekin C da bo'sh argument belgisi, yani () qavslar boshqa ma'no beradi. Bu e'lon funksiya istalgancha argument olishi mumkin deganidir. Shu sababli C da yozilgan eski dasturlar C++ kompilyatorlarida hato berishlari mumkindir.  

Bundan tashqari funksiya prototipi ahamiyati haqida yozib o'taylik. Iloji boricha har doim funksiya prototiplarini berib o'tish kerak, bu modulli dasturlashning asosidir. Prototip va e'lonlar alohida e'lon fayllar ichida berilishi mumkin. Funksiya yoki klas o'zgartirilganda e'lon fayllari

o'zgarishsiz qoladi. Faqat funksiya aniqlangan fayllar ichiga o'zgartirishlar kiritiladi. Bu esa juda qulaydir.  

 inline SIFATLI FUNKSIYALAR

 Funksiyalar dastur yozishda katta qulayliklar beradilar. Lekin mashina saviyasida funksiyani har gal chaqirtirish qo'shimcha ish bajarilishiga olib keladi. Registrlardagi o'zgaruvchilar o'zgartiriladi, lokal yozgaruvchilar quriladi, parametr sifatida berilgan argumentlar funksiya stekiga o'ziladi. Bu, albatta, qo'shimcha vaqt oladi. Umuman aytganda, hech funksiyasiz yozilgan dastur, yani hamma amallari faqat main() funksiyasi ichida bajariladigan monolit programma, bir necha funksiyalarga ega, ayni ishni bajaradigan dasturdan tezroq ishlaydi. Funksiyalarning bu noqulayligini tuzatish uchun inline (satr ichida) ifodasi funksiya e'loni bilan birga qo'llaniladi. inline sifatli funksiyalar tanasi dasturdagi ushbu funksiya chaqirig'i uchragan joyga qo'yiladi. inline deb ayniqsa kichik funksiyalarni belgilash effektivdir. inline ning o'ziga yarasha kamchiligi ham bor, inline qo'llanilganda dastur hajmi oshdi. Agar funksiya katta bo'lsa va dastur ichida ko'p marotaba chaqirilsa, programma hajmi juda kattalashib ketishi mumkin.

 Oddiy, inline sifati qo'llanilmagan funksiyalar chaqirilish mehanizmi quyidagicha bo'ladi. Dastur kodining ma'lum bir yerida funksiya tanasi bir marotaba aniqlangan bo'ladi. Funksiya chaqirig'i uchragan yerda funksiya joylashgan yerga ko'rsatkich qo'yiladi. Demak, funksiya chaqirig'ida dastur funksiyaga sakrashni bajaradi. Funksiya o'z ishini bajarib bo'lgandan keyin dastur ishlashi yana sakrash joyiga qaytadi. Bu dastur hajmini ihchamlikda saqlaydi, lekin funksiya chaqiriqlari vaqt oladi. 

Kompilyator inline ifodasini inobatga olmasligi mumkin, yani funksiya oddiy holda kompilyatsiya qilinishi mumkin. Va ko'pincha shunday bo'ladi ham. Amalda faqat juda kichik funksiyalar inline deya kompilyatsiya qilinadi. inline sifatli funksiyalarga o'zgartirishlar kiritilganda ularni ishlatgan boshqa dastur bloklari ham qaytadan kompilyatsiya qilinishi kerak. Agar katta proyektlar ustida ish bajarilayatgan bo'lsa, bu  ko'p vaqt olishi mumkin. inline funksiyalar C da qo'llanilgan # define makrolari o'rnida qo'llanilish uchun mo'ljallangan. Makrolar emas, balki inline funksiyalar qo'llanilishi dastur yozilishini tartibga soladi. Makro funksiyalarni keyinroq o'tamiz. 

//inline ifodasining qo'llanilishi

 

# include <iostream.h>

inline int sum(int a, int b);//funksiya prototipi

int main() {

   int j = -356,

       i =  490;

   cout << "j + i = " << sum(j,i) <<endl;

   return (0);

}

int sum(int a, int b){ //funksiya aniqlanishi

   return( a + b );

}

 Ekranda:

j + i = 134

 

KO'RSATKICHLAR VA FUNKSIYA CHAQIRIQLARIDA ULARNING QO'LLANILISHI

 C/C++ da funksiya chaqirig'iga kirish parametrlarini berishning ikki usuli bordir. Birinchi usul qiyamat bo'yicha chaqiriq (call-by-value) deyiladi. Ikkinchi usul ko'rsatkich bo'yicha chaqiriq (call-by-reference) deb nomlanadi. Hozirgacha yozgan hamma funksiyalar qiymat bo'yicha chaqirilardi. Buning ma'nosi shuki, funksiyaga o'zgaruvchining o'zi emas, balki uning nushasi argument sifatida beriladi. Buning afzal tomoni shundaki, o'zgaruvchi qiymatini funksiya ichida o'zgartirish imkoni yo'qdir. Bu esa havfsizlikni ta'minlaydi. Ammo, agar o'zgaruvchi yoki ifoda hotirada katta joy egallasa, uning nushasini olish va funksiyaga argument sifatida berish sezilarli vaqt olishi mumkin. 

Ko'rsatkich bo'yicha chaqiriqda o'zgaruvchi nushasi emas, uning o'zi argument sifatida funksiyaga uzatilinadi. Bu chaqiriqni bajarishning ikki usuli mavjud. Bittasini biz hozir ko'rib chiqamiz, ikkinchi usulni esa keyinroq. Hozir o'tadigan ko'rsatkichni o'zbekchada &-ko'rsatkich (AND ko'rsatkich - reference) deb ataylik. Ikkinchi tur ko'rsatkichning esa inglizcha nomlanishini saqlab qo'laylik, yani pointer (ko'rsatkich) deb nomlaylik. Bu kelishishdan maqsad, inglizchadagi reference va pointer so'zlar o'zbekchaga ko'rsatkich deb tarjima qilinadi. Bu ikki ifodaning tagida yotuvchi mehanizmlar o'zhshash bo'lishlariga qaramay, ularning qo'llanishlari farqlidir. Shuning uchun ularning nomlanishlarida chalkashlik vujudga kelmasligi kerak. 

 Etkanimizdek, ko'rsatkich bo'yicha chaqiriqda o'zgaruvchining o'zi parametr bo'lib funksiyaga beriladi. Funksiya ichida o'zgaruvchi qiymati o'zgartirilishi mumkin. Bu esa havfsizlik muammosini keltirb chiqarishi mumkin. Chunki aloqasi yo'q funksiya ham o'zgaruvchiga yangi qiyamat berishi mumkin. Bu esa dastur mantig'i buzilishiga olib keladi. Lekin, albatta, bilib ishlatilsa, ko'rsatkichli chaqiriq katta foyda keltirishi mumkin.  &-ko'rsatkichli parametrni belgilash uchun funksiya prototipi va aniqlanishida parametr tipidan keyin & belgisi qo'yiladi. Funksiya chaqirig'i oddiy funksiyaning ko'rinishiga egadir. Pointerlarni qo'llaganimizda esa funksiya chaqirig'i ham boshqacha ko'rinishga egadir. Ammo pointerlarni keyinroq ko'rib

chiqamiz.

Bir misol keltiraylik.

//Qiymat va &-ko'rsatkichli chaqiriqlarga misol

# include <iostream.h>

int qiymat_10(int);            //e'lon

int korsatkich_10(int &);      //e'lon

int f, g;

int  main(){

   f = g = 7;  

   cout << f << endl;

   cout << qiymat_10(f) << endl;

   cout << f << endl << endl;

   cout << g << endl;

   cout << korsatkich_10(g) << endl; //chaqiriq ko'rinishi o'zgarmaydi 

   cout << g << endl;

  return (0);

}

int qiymat_10(int k){

   return ( k * 10 );

}

int korsatkich_10(int &t){

   return ( t * 100 );

}

 Ekranda:

7

70

7

7

700

700

 

Bu yerda g o'zgaruvchimiz korsatkich_10(int &) funksiyamizga kirib chiqqandan so'ng qiymati o'zgardi. Ko'rsatkich bo'yicha chaqiriqda kirish argumentlaridan nusha olinmaydi, shu sababli funksiya chaqirig'i ham juda tez bajariladi.  &-ko'rsatkichlarni huddi oddiy o'zgaruvchilarning ikkinchi ismi deb qarashimiz mumkin. Ularning birinchi qo'llanilish yo'lini - funksiya kirish parametrida ishlatilishini ko'rib chiqdik. &-ko'rsatkichni blok ichida ham ko'llasak bo'ladi. Bunda bir muhim marsani unutmaslik kerakki &-ko'rsatkich e'lon vaqtida initsalizatsiya qilinishi kerak, yani ayni tipda bo'lgan boshqa bir oddiy o'zgaruvchi unga tenglashtirilishi kerak. Buni va boshqa tushunchalarni misolda ko'rib chiqaylik.

 //const ifodasi bilan tanishish;

//&-ko'rsatkichlarning ikkinchi qo'llanilish usuli

 # include <iostream.h>

 void printInt(const int &); //funksiya prototipi

 

double d = 3.999;

int j = 10;

int main()

{

   double &rd = d; //d ga rd nomli &-ko'rsatkich

   const int &crj = j; //const ko'rsatkich

   const short int k = 3; //const o'zgaruvchi - konstanta

   cout << rd << endl;

   printInt(j);

   printInt(crj);

   return (0);

}

void printInt(const int &i) //...int& i... deb yozish ham mumkin;

{                           //kirish argumenti const dir

   cout << i << endl;

   return;

}

 Ekranda:

3.999

10

 

Ko'rganimizdek, rd ko'rsatkichimiz d o'zgaruvchi qiymatini ekranga bosib chiqarish imkonini beradi. Ko'rsatkich o'rqali o'zgaruchining qiymatini ham o'zgartirsa bo'ladi. &-ko'rsatkichning asosiy hususiyati shundaki mahsus sintaksis - & belgisining qo'yilishi faqat ko'rsatkich e'lonida qo'llaniladi halos. Dastur davomida esa oddiy o'zgaruvchi kabi ishlov ko'raveradi. Bu juda qulaydir, albatta. Lekin ko'rsatkich ishlatilganda ehtiyot bo'lish kerak, chunki, masalan, funksiya tanasi ichida argumentning nushasi bilan emas, uning o'zi bilan ish bajarilayatganligi esdan chiqishi mumkin.   

const (o'zgarmas) ifodasiga kelaylik. Umuman olganda bu nisbatan yangi ifodadir. Masalan C da ishlagan dasturchilar uni ishlatishmaydi ham.  const ni qo'llashdan maqsad, ma'lum bir identefikatorni o'zgarmas holga keltirishdir. Masalan, o'zgaruvchi yoki argument const bilan sifatlantirilsa, ularning qiymatini o'zgartirish mumkin emas. Lekin boshqa amallarni bajarish

mumkin. Ularni ekranga chiqarish, qiymatlarini boshqa o'zgaruvchiga berish ta'qiqlanmaydi. const ifodasisiz ham dasturlash mumkin, ammo const yordamida tartibli, chiroyli va eng muhimi kam hatoli dasturlashni amalga oshirsa bo'ladi. const ning ta'siri shundaki, const qilingan o'zgaruvchilar kerakmas joyda o'zgarolmaydilar. Agar funksiya argumenti const deb belgilangan bo'lsa, ushbu argumentni funksiya tanasida o'zgartirilishga harakat qilinsa, kompilyator hato beradi. Bu esa o'zgaruvchining himoyasini oshirgan bo'ladi. const ning qo'llanilish shakli ko'pdir. Shulardan asosiylarini ko'rib chiqsak.

Yuqoridagi misoldagi

const int &crj = j;

amali bilan biz &-ko'rsatkichni e'lon va initsalizatsiya qildik. Ammo crj ko'rsatkichimiz const qilib belgilandan, bu degani crj ko'rsatkichi orqali j o'zgaruvchisining qiymatini o'zgartira olmaymiz. Agar const ifodasi qo'llanilmaganda edi, masalan yuqoridagi

 double &rd = d;

 

ifodadagi rd ko'rsatkichi yordamida d ning qiymatini qiyinchiliksiz o'zgartirishimiz mumkin. d ning qiymatini 1 ga oshirish uchun

 

d++;

yoki

rd++;

 deb yozishimiz kifoyadir.

 Yana bir marta qaytarib o'taylikki, &-ko'rsatkichlar e'lon vaqtida initsalizatsiya qilinishi shartdir. Yani quyidagi ko'rinishdagi bir misol hatodir:

 int h = 4;

int &k; // hato!

k = h;  // bu ikki satr birga qo'shilib yoziladi: int &k = h;

 Ba'zi bir dasturchilar &-ko'rsatkich e'londa & belgisini o'zgaruvchi tipi bilan birga yozadilar. Bunining sababi shuki, & belgisining C/C++ dagi ikkinchi vazifasi o'zgaruvchi yoki ob'ektning adresini qaytarishdir. Unda & ni o'zgaruvchiga yopishtirib yozish shartdir. Demak, & tipga yopishtirib yozish & ning qo'llanishlarini bir-biridan farqlab turadi. Lekin & ni ko'rsatkich e'lonida qo'llaganda, uning qanday yozilishining ahamiyati yo'q. Adres olish amalini biz keyinroq ko'rib chiqamiz.

...

int H = 4;

int F;

int &k = H;            

int& d = F;             // yuqoridagi e'lon bilan aynidir

void foo(long &l);

void hoo(double& f);    // yuqoridagi protopip bilan aynidir

...

 

Bir necha ko'rsatkichni e'lon qilish uchun:

 int a, b , c;

int &t = a, &u = b, &s = c;

 Bu yerda & operatori har bir o'zgaruvchi oldida yozilishi shart.  &-ko'rsatkich ko'rsatayotdan hotira sohasining adresini o'zgartirib bo'lmaydi.

Masalan:

 int K = 6;

int &rK = K;

K ning hotiradagi adresi 34AD3 bolsin, rK ko'rsatkichning adresi esa 85AB4.

K ning qiymati 6, rK ning qiymati ham 6 bo'ladi. Biz rK ga qaytadan boshqa o'zgaruvchini tenglashtirsak, rK yangi o'zgaruvchiga ko'rsatmaydi, balki yangi o'zgaruvchining qiymatini K ning adresiga yozib qo'yadi. Masalan yangi o'zgaruvchi N bo'lsin, uning adresi 456F2, qiymati esa 3

bo'lsin. Agar biz 

rK = N;

desak, rK N ga ko'rsatmaydi, balki K ning adresi - 34AD3 bo'yicha N ning qiymatini - 3 ni yozadi. Yani K ning qiymati 6 dan 3 ga o'zgaradi.

Yuqoridagi dasturda:

 const short int k = 3;

 deb yozdik. Bu const ning ikkinchi usulda qo'llanilishidir. Agar o'zgaruvchi tipi oldidan const qo'llanilsa, o'zgaruvchi konstantaga aylanadi, dastur davomida biz uning qiymatini o'zgartira olmaymiz. Bu usul bilan biz Pascaldagi kabi konstantalarni e'lon qilishimiz mumkin. Bu yerda bitta shart bor, const bilan sifatlantirilgan o'zgaruvchilar e'lon davrida initsalizatsiya qilinishlari shart. Umuman olganda bu qonun const ning boshqa joylarda qo'llanilganida ham o'z kuchini saqlaydi. Albatta, faqat funksiya argumentlari bilan qo'llanilganda bu qonun ishlamaydi. C/C++ da yana # define ifodasi yordamida ham simvolik konstantalarni e'lon qilish mumkin. Ushbu usulni keyin ko'rib chiqamiz. Undan tashqari enum strukturalari ham sonli kostantalarni belgilaydi. 

 Dasturimizda printInt() funksiyamizga kiradigan int& tipidagi argumentimizni const deya belgiladik. Buning ma'nosi shuki, funksiya ichida ushbu argument o'zgartirilishga harakat qilinsa, kompilyator hato beradi. Yani funksiya const bo'lib kirgan argumentlarni (hoh ular o'zgaruvchi nushalari bo'lsin, hoh o'zgaruvchilarga ko'rsatkich yoki pointer bo'lsin) qiymatlarini o'zgartira olmaydilar.

 Funksiya faqat bitta qiymat qaytaradi dedik. Bu qaytgan qiymatni biz o'zgaruvchiga berishimiz mumkin. Agar bittadan ko'proq o'zgaruvchini o'zgartirmoqchi bo'lsak, o'zgaradigan ob'ektlarni ko'rsatkich yoki pointer sifatida kiruvchi argument qilib funksiyaga berishimiz mumkin. Bundan tashqari biz funksiyadan &-ko'rsatkichni qaytarishimiz mumkin. Lekin bu yersa ehtiyot bo'lish zarur, ko'rsatkich funksiya ichidagi static o'zgaruvchiga ko'rsatib turishi lozim. Chunki oddiy o'zgaruvchilar avtomatik ravishda funksiya tugaganida hotiradan olib tashlanadi. Buni misolda ko'raylik.   

...

int& square(int k){

   static int s = 0; //s static sifatiga ega bo'lishi shart;

   int& rs = s;

   s = k * k;

   return (rs);

}

 ...

int g = 4;

int j = square(g); // j = 16

...

 

FUNKSIYA ARGUMENTLARNING BERILGAN QIYMATLARI

 Ba'zi bir funksiyalar ko'pincha bir hil qiymatli argumentlar bilan chaqirilishi mumkin. Bu holda, agar biz funksiya argumentlariga ushbu ko'p qo'llaniladigan qiymatlarni bersak, funksiya argumentsiz chaqirilganda bu qiymatlar kompilyator tomonidan chaqiriqqa kiritiladi. Berilgan qiymatlar funksiya prototipida berilsa kifoyadir. Berilgan qiymatli argumentlar parametrlar ro'hatida eng o'ng tomonda yozilishi kerak. Buning sababi shuki, agar argument qiymati tashlanib o'tilgan bo'lsa, va u o'ng tomonda joylashmagan bo'lsa, biz bo'sh vergullani qo'yishimizga to'g'ri keladi, bu esa mumkin emas. Agar bir necha berilgan qiymatli argumentlar bor bo'lsa, va eng o'ngda joylashmagan argument tushurilib qoldirilsa, undan keyingi argumentlar ham yozilmasligi kerak.

Bir misol keltiraylik.

 //Berilgan qiymatli parametrlar bilan ishlash

# include <iostream.h>

int square(int = 1, int = 1); // ...(int a=1, int b=1)...

                              // yuqoridagi kabi o'zgaruvchilar otini ham

                              // berishimiz mumkin

int main()

{

   int s = 3, t = 7;

   cout << "Paremetrsiz: " << square()<< endl;

   cout << "Bitta parametr (ikkinchisi) bilan:" << square(t) << endl;

   cout << "Ikkita parametr bilan:" << square(s,t) << endl;

   return (0);

}

 

int square(int k, int g){

   return ( k * g );

}

Ekranda:

Parametrsiz: 1

Bitta parametr (ikkinchisi) bilan: 7

Ikkita parametr bilan: 21

 

FUNKSIYA ISMI YUKLANISHI

 Bir hil ismli bir necha funksiya e'lon qilinishi mumkin. Bu C++ dagi juda kuchli tushunchalardandir. Yuklatilgan funksiyalarning faqat kirish parametrlari farqli bo'lishi yetarlidir. Qaytish parametri yuklatilishda ahamiyati yo'qdir. Yuklangan funksiyalar chaqirilganda, qaysi funksiyani chaqirish kirish parametrlarining soniga, ularning tipiga va navbatiga bog'liqdir. Yani ism yuklanishida funksiyaning imzosi rol o'ynidi. Agar kirish parametrlari va ismlari ayni funksiyalarning farqi faqat ularning qaytish qiymatlarida bo'lsa, bu yuklanish bo'lmaydi, kompilyator buni hato deb e'lon qiladi. 

 Funksiya yuklanishi asosan ayni ishni yoki amalni farqli usul bilan farqli  ma'lumot tiplari ustida bajarish uchun qo'llaniladi. Masalan bir fazoviy jismning hajmini hisoblash kerak bo'lsin. Har bir jismning hajmi farqli formula yordamida, yani farqli usulda topiladi, bir jismda radius tushunchasi bor bo'lsa, boshqasida asos yoki tomon tushunchasi bor bo'ladi, bu esa farqli ma'lumot tiplariga kiradi. Lekin amal ayni - hajmni hisoblash. Demak, biz funksiya yuklanishi mehanizmini qo'llasak bo'ladi. Bir hil amalni bajaruvchi funksiyalarni ayni nom bilan atashimiz esa, dasturni o'qib tushunishni osonlashtiradi. 

 Kompilaytor biz bergan funksiya imzosidan (imzoga funksiya ismi va kirish parametrlari kiradi, funksiyaning qaytish qiymati esa imzoga kirmaydi) yagona ism tuzadi, dastur ijrosi davruda esa funksiya chaqirig'idagi argumentlarga qarab, kerakli funksiyani chaqiradi. Yangi ismni tuzish operatsiyasi ismlar dekoratsiyasi deb ataladi. Bu tushunchalarni misolda ko'rib chiqaylik.

 // Yuklatilgan funksiyalarni qo'llash

 # include <iostream.h>

# include <math.h>

// Yangi ismlar sohasini aniqladik        

namespace                       

   mathematics {

      const double Pi = 3.14159265358979;

 double hajm(double radius); // sharning hajmi uchun - 4/3 * Pi * r^3

double hajm(double a, double b, double s) // kubning hajmi uchun - abc

}

 using namespace mathematics;

int main()

{

   double d = 5.99; // sharning radiusi

   int x = 7, y = 18, z = 43;

   cout << "Sharninig hajmi: " << hajm(d) << endl;

   cout << "Kubning hajmi: " << hajm(x,y,z) << endl;  

   return (0);

}

 double mathematics::hajm(double radius) {

   return (  (Pi * pow(radius,3) * 4.0) / 3.0  );

}

 double mathematics::hajm(double a, double b, double c) {

   return ( a * b * c );

}

 Ekranda:

Sharning hajmi: 900.2623

Kubning hajmi: 5418

 Yuqoridagi dasturda yangi ismlar sohasini aniqladik, unda Pi konstantasini e'lon qildik. shaqning hajmini hisoblashda standart kutubhonadagi pow() funksiyasini ishlatdik, shu sababli <math.h> e'lon faylini # include ifodasi bilan kiritdik. Ismlar sohasida joylashgan funksiyalarni aniqlash uchun, yani ularning tanasini yozish uchun biz ilarning to'liq ismini berishimiz kerak. Albatta, agar funksiya ismlar sohasining ichida aniqlangan bo'lsa, tashqarida boshqattan yozib o'tirishning hojati yo'q. hajm() funksiyalarining to'liq ismi mathematics::hajm(...) dir. :: operatori sohalarni bog'lovchi operatordir. Yangi ismlar sohasini faqatgina misol tariqasida berdik, uni funksiya yuklanishlari bilan hech qanday aloqasi yo'qdir. Funksiya ismlari  yuklanishi, ko'rib turganimizdek, juda qulay narsadir. Funksiya yuklanishini qo'llaganimizda, funksiyalar argumentlarining berilgan qiymatlarini ehtiyotkorlik bilan qo'llashimiz lozim. Masalan bizda ikkita funksiyamiz bor bo'lsin.

 foo(int k = 0); // berilgan qiymati 0

foo();

 Bu ikki funksiya yuklatilgan. Lekin agar biz birinchi funksiyani dasturda argumentsiz chaqirsak, kompilyator qaysi funksiyani chaqirishni bilmaydi, va shu sababli hato beradi. Biroq bu deganimiz funksiya yuklanishi bilan berilgan qiymatlar qo'llanilishi mumkin emas deganimiz emas, eng muhimi funksiya chaqirig'ini ikki hil tushunish bo'lmasligi kerak.

 FUNKSIYA SHABLONLARI

 Funksiya shablonlari (function templates) ham funksiya yuklanishiga o'hshash tushunchadir. Bunda eng asosiy farq funksiya shablonlarida  amal ham bir hil yo'l bilan bajariladi. Masalan bir necha sonlar ichidan eng kattasini topish kerak bo'lsin. Sonlar to'plami faqat tipi bilan farqlanadi, int, double yoki float. Ishlash algoritmi esa aynidir. Bu holda biz funksiyalarni yuklab o'tirmasdan, shablon yozib qo'ya qolamiz.

Funkisya shabloni yoki yuklanishisiz ham bu masalani yechish mumkinku degan savol paydo bo'ladi. Masalan, agar biz kiradigan parametrlarning hammasini long double qilsak, istalgan sonli tipdagi argumentni bera olamiz, chunki kompilyator o'zi avtomatik ravishda kirish tiplarini long double ga o'zgartiradi. Lekin, agar biz bunday funksiya yozadigan bo'lsak, hotiradan va tezlikdan yutqizamiz. Dasturimizda faqat char tipidagi, bir baytli qiymatlar bilan ishlashimiz mumkin. long double esa 10 bayt, va eng katta sonni aniqlash uchun sonlarni solishtirganimizda, long double qiymatlarni solishtirish char tipidagi qiymatlarni solishtirishdan ko'ra ancha ko'p vaqt oladi. Qolaversa, har doim ham kompilyator tiplarni biridan ikkinchasiga to'g'ri keltira oladi. Shablonlarning strukturasi bilan tanishaylik. Bizning funksiya ikkita kirish argumentini bir biriga qo'shsin, va javobni qaytarsin.

 template <class T>

T summa(T a, T b) {

   return ( a + b);

}

 Shablon funksiya e'loni va aniqlanishidan oldin template <> ifodasi yoziladi, <> qavslardan keyin nuqta-vergul (;) qo'yilmaydi. <> qavslar ichida funksiya kirish parametrlari, chiqish qiymati va lokal o'zgaruvchilar tiplari beriladi. Ushbu formal tiplarning har birining oldida class yoki typename (tip ismi) so'zi qo'yilish kerak. Yuqoridagi misolda T ning o'rniga istalgan boshqa identefikator qo'yish mumkin. Misollar beraylik.

template <class javob, class uzunlik, class englik, class balandlik>

javob hajmKub(uzunlik a, englik b, balandlik c);

 template <typename T>

T maximum(T k, T l);

Yuqorida yozgan shablonimizni qo'llagan holga bir misol keltiraylik.

 // Shablonlar bilan ishlash

# include <iostream.h>

template <class T>

T summa(T a, T b) {

   return ( a + b );

}

 int main()

{

int x = 22, y = 456;

float m = .01, n = 56.90; // kasrli sonda nuqtadan oldingi (butun qismdagi)

                          // nolni berish shart emas: ... m = .01 ...

   cout << "int: 22 + 456 = " << summa(x,y) << endl;

   cout << "float: 0.01 + 56.90 = " << summa(0.01,56.90) << endl;

   return (0);

}

 Ekranda:

int: 22 + 456 = 478

float: 0.01 + 56.90 = 56.91

 Shablonlarni funksiyalardan tashqari klaslarga ham qo'llasa bo'ladi. Ko'rib turganimizdek, shablonlar faqat bir marotaba yoziladi. Keyin esa mos keladigan tiplar qo'yilib, yozilib ketilaveradi. Aslida shablonlar C++ ning standartida juda ko'p qo'llanilgan. Agar bilib ishlatilsa, shablonlar dasturchining eng kuchli quroliga aylanishi mumkin. Biz keyinroq yana shablonlar mavzusiga qaytamiz.

Share