logo

Bir va ikki o‘lchovli massiv elementlarini tartiblash, qidirish algoritmlari va ularning murakkabligini tahlil qilish asosida dastur yaratish

Yuklangan vaqt:

08.08.2023

Ko'chirishlar soni:

0

Hajmi:

183.1015625 KB
Bir va ikki o‘lchovli massiv elementlarini tartiblash, qidirish
algoritmlari va ularning murakkabligini tahlil qilish asosida dastur
yaratish
Reja:
1. Bir va ikki o’lchovli massiv elementlarni tartiblash
2. Qidirish algoritmlari
3. Algoritmning murakkabligini tahlil qilish Massivni saralash  - bu massivdagi barcha elementlarni ma'lum tartibda
joylashtirish jarayoni. Bu ko'pincha foydalidir. Masalan, pochta qutingizdagi
elektron   pochta   xabarlari   qabul   qilingan   vaqtga   qarab   ko'rsatiladi;   yangi
elektron   pochta   xabarlari   sizga   yarim   soat,   bir   soat,   ikki   yoki   bir   kun   oldin
kelgan elektron pochta xabarlariga qaraganda ko'proq mos keladi; kontaktlar
ro'yxatiga   kirganingizda,   ismlar   odatda   alifbo   tartibida   bo'ladi,   chunki   shu
tarzda   biror   narsani   topish   osonroq.   Ushbu   holatlarning   barchasi
ma'lumotlarni namoyish qilishdan oldin ularni saralashni o'z ichiga oladi.
Saralash qanday ishlaydi?
Ma'lumotlarni   saralash   nafaqat   odamlar   uchun,   balki   kompyuterlar
uchun   ham   massiv   ichidan   qidirishni   samaraliroq   qilishi   mumkin.   Masalan,
ismlar   ro'yxatida   ma'lum   bir   ism   paydo   bo'lishini   bilishimiz   kerak   bo'lgan
holatni ko'rib chiqaylik. Buni bilish uchun siz massivning har bir elementini
bizning   qiymatimiz   bilan   tekshirishingiz   kerak.   Ko'p   elementli   qatorni
qidirish juda samarasiz (qimmat) bo'lishi mumkin.
Biroq,   bizning   nomlarimiz   qatori   alfavit   bo'yicha   tartiblangan   deb
taxmin   qiling.   Keyin   bizning   qidiruvimiz   ma'noning   birinchi   harfi   bilan
boshlanadi   va   alifboda   keyingi   harf   bilan   tugaydi.   Bunday   holda,   agar   biz
ushbu   harfga   yetib   borsak   va   ismini   topa   olmasak,   unda   biz   bu   qatorning
qolgan qismida yo'qligini aniq bilamiz, chunki biz allaqachon o'z harfimizni
alifbo tartibida topshirganmiz!
Hech   kimga   sir   emaski,   tartiblangan   massivlar   ichida   yanada   yaxshi
qidirish   algoritmlari   mavjud.   Oddiy   algoritmdan   foydalanib,   biz   faqat   20   ta
taqqoslash   yordamida   aniqlangan   elementni   1000000   elementlardan   iborat
tartibda   qidirishimiz   mumkin!   Salbiy   tomoni   shundaki,   massivni   juda   ko'p
sonli elementlarga ko'ra saralash nisbatan qimmatga tushadi va bitta qidiruv
so'rovi uchun amalga oshirilmaydi. Ba'zi   hollarda,   qatorni   saralash   qidirishni   keraksiz   holga   keltiradi.
Masalan,   biz   talabalar   orasida   eng   yaxshi   test   balini   qidirmoqdamiz.   Agar
massiv   saralanmagan   bo'lsa,   unda   biz   eng   yuqori   ballni   topish   uchun
massivning   har   bir   elementini   skanerlashimiz   kerak   bo'ladi.   Agar   massiv
saralangan   bo'lsa,   unda   eng   yuqori   ball   birinchi   pozitsiyada   yoki   oxirgisi
bo'ladi   (massivni   saralash   uslubiga   qarab:   ko'tarilish   yoki   tushish   tartibida),
shuning uchun biz qidirishning umuman hojati yo'q.
Tartiblash   odatda   qator   elementlari   juftlarini   qayta   taqqoslash   va
belgilangan   mezonlarga   mos   keladigan   bo'lsa,   ularni   almashtirish   orqali
amalga   oshiriladi.   Ushbu   elementlarni   taqqoslash   tartibi   qaysi   saralash
algoritmidan   foydalanilganiga   bog'liq.   Mezonlar   massivning   qanday
tartiblanishini belgilaydi (masalan, ko'tarilish yoki tushish tartibida).
Ikki   elementni   almashtirish   uchun   biz   C   ++   standart   kutubxonasidan
std   ::   swap   ()   funktsiyasidan   foydalanishimiz   mumkin,   bu   sarlavha   fayli
algoritmida   aniqlangan.   C   ++   11   da   std   ::   swap   ()   funktsiyasi   yordam
dasturining sarlavha fayliga ko'chirildi:
#include <iostream> 
#include <algorithm> 
 
int main()
{
        int a = 3;
        int b = 5;
        std::cout << " a = " << a << ", b = " << b << '\n';
        std::swap(a, b);          std::cout << " a = " << a << ", b = " << b << '\n';
}
Dasturni bajarish natijasi:
a=3, b=5
a=5, b=3
O'zgartirish   operatsiyasidan   so'ng   a   va   b   o'zgaruvchilarning   qiymatlari
almashtirildi.
Massivlarni tanlash usuli bo'yicha saralash
Massivlarni   saralashning   ko'plab   usullari   mavjud.   Massivlarni   tanlov
usulidan   foydalanib   saralash,   ehtimol   bu   eng   oson   bo'lsa   ham,   eng
sekinlaridan   biri.   Massivni   eng   kichikdan   kattagacha   elementlarni   tanlab
saralash uchun quyidagi amallarni bajaring:
-   0   indeksidagi   elementdan   boshlab   biz   massivdagi   eng   kichik   qiymatni
qidiramiz.
- Topilgan qiymatni nol element bilan almashtiramiz.
- Massivdagi keyingi indeks uchun # 1 va # 2 bosqichlarini takrorlang (endi
saralangan elementga tegmang).
Boshqacha qilib aytganda, biz massivdagi eng kichik elementni qidiramiz va
uni   birinchi   o'ringa   o'tkazamiz.   Keyin   biz   ikkinchi   eng   kichik   elementni
qidiramiz   va   uni   birinchi   kichik   elementdan   keyin   ikkinchi   holatga
o'tkazamiz. Ushbu jarayon massivda saralanmagan elementlar tugamaguncha
davom etadi.
Ushbu algoritm 5 ta elementdan iborat massivda qanday ishlashiga misol: { 30, 50, 20, 10, 40 }
Birinchidan ,  biz  0  indeksidan   boshlab   eng   kichik   elementni   qidiramiz :
{30, 50, 20, 10, 40}
Keyin biz eng kichik elementni 0 indeksidagi element bilan almashtiramiz:
{10, 50, 20, 30, 40}
Endi   massivning   birinchi   elementi   saralangan,   biz   unga   e'tibor   bermaymiz.
Biz keyingi eng kichik elementni qidiramiz, lekin 1 indeksidan boshlaymiz:
{10, 50, 20, 30, 40}
Va biz uni indeks 1dagi element bilan almashtiramiz:
{10, 20, 50, 30, 40}
Endi   biz   dastlabki   ikkita   elementni   e'tiborsiz   qoldirmoqdamiz.   Ikkinchi
indeksdan boshlab keyingi eng kichik elementni qidiryapsiz:
{10, 20, 50, 30, 40}
Va biz uni indeks 2 da element bilan almashtiramiz:
{10, 20, 30, 50, 40}
3-indeksdan boshlab keyingi eng kichik elementni qidiryapsiz: {10, 20, 30, 50, 40}
Va biz uni 3-indeksdagi element bilan almashtiramiz:
{10, 20, 30, 40, 50}
4-indeksdan boshlab keyingi eng kichik elementni qidiryapsiz:
{10, 20, 30, 40, 50}
Va biz uni 4-indeksdagi element bilan almashtiramiz (o'z-o'zini almashtirish
amalga oshiriladi, ya'ni biz hech narsa qilmaymiz):
{10, 20, 30, 40 50}
Bajarildi!
{10, 20, 30, 40, 50}
E'tibor   bering,   oxirgi   taqqoslash   har   doim   bitta   bo'ladi   (ya'ni   o'zini
almashtirish),   bu   keraksiz   operatsiya,   shuning   uchun   aslida   biz   qatorning
oxirgi elementidan oldin saralashni to'xtatishimiz mumkin.
C ++ da tanlash usuli yordamida massivlarni saralash
Ushbu algoritm C ++ da qanday amalga oshiriladi:
#include <iostream>  #include <algorithm> 
 
int main()
{
const int length = 5;
int array[length] = { 30, 50, 20, 10, 40 };
 
// Massivning har bir elementi bo'ylab aylantirib o'ting (oxirgisidan 
tashqari, u biz unga  y etib kelgan vaqtgacha tartiblangan bo'ladi)
for (int startIndex = 0; startIndex < length - 1; ++startIndex)
{
// eng kichikIndex o'zgaruvchisi biz ushbu takrorlashda topilgan 
eng kichik qiymat indeksini ushlab turadi.
// Ushbu iteratsiyadagi eng kichik element birinchi element 
bo'lishidan boshlang (indeks 0)
int smallestIndex = startIndex;
 
// Keyin massivning qolgan qismidan kichikroq elementni 
qidirib //toping
for (int currentIndex = startIndex + 1; currentIndex < length; +
+currentIndex)
{
// Agar biz eng kichik elementimizdan kichikroq elementni 
topsak,
if (array[currentIndex] < array[smallestIndex])
// keyin eslab qoling
smallestIndex = currentIndex;
}  
// smallestIndex endi eng kichik element.
// Bizning eng kichik raqamimizni topilgan raqam bilan 
almashtiring std::swap(array[startIndex], 
array[smallestIndex]);
}
 
// Endi butun massiv saralanib, uni ekranda ko'rsating
for (int index = 0; index < length; ++index)
std::cout << array[index] << ' ';
 
return 0;
}
Ushbu  algoritmning eng chalkash  qismi -  bu boshqa  tsikl  ichidagi tsikl
("joylashtirilgan   tsikl"   deb   nomlanadi).   Tashqi   tsikl   (startIndex)   elementlar
ustida   birma-bir   (o'z   navbatida)   takrorlanadi.   Tashqi   tsiklning   har   bir
takrorlanishida ichki tsikl (currentIndex) massivda qolgan elementlar orasida
eng   kichik   elementni   topish   uchun   ishlatiladi   (startIndex   +   1   dan   boshlab).
smallestIndex   ichki   tsikl   tomonidan   topilgan   eng   kichik   element   indeksini
kuzatib boradi. Keyin eng kichikIndex startIndex-dan o'zgartiriladi. Nihoyat,
tashqi   tsikl   (startIndex)   massivning   keyingi   indeksiga   o'tadi   va   jarayon
takrorlanadi.
Agar   yuqoridagi   dastur   qanday   ishlashini   tushunishda   muammolarga
duch   kelsangiz,   uni   qog'ozga   yozib   ko'ring.   Dastlab   (saralanmagan)   massiv
elementlarini varaqning yuqori qismidagi qatorga gorizontal ravishda yozing.
Ayni   paytda   qaysi   elementlar   startIndex,   currentIndex   va   smallestIndex
ekanligini   ko'rsatish   uchun   o'qlarni   torting.   Dasturni   qo'lda   aylantiring   va
ko'rsatkichlar o'zgarganda o'qlarni qayta chizib oling. Tashqi tsiklning har bir takrorlanishidan   so'ng,   massivning   hozirgi   holatini   (uning   elementlari
joylashishini) ko'rsatadigan yangi chiziq chizamiz.
Qidirish   algoritmlari.   Barcha   dasturchilar   muammolarni   yuechishda
massivda   biron   bir   qiymat   borligini   tekshirish   zarurligiga   duch   kelishdi.
Ushbu   muammoni   hal   qilish   uchun   ko'plab   algoritmlar   mavjud.   Ushbu
algoritmlarning barchasi boshqa dasturlash tillarida ham qo'llaniladi.
Bugun biz eng sodda qidirish algoritmini o'rganamiz (ammo ayni paytda
eng ko'p vaqt talab qiladigan) - chiziqli qidiruv.
Ushbu   algoritm   massivdagi   barcha   elementlarni   takrorlaydi,   ularni
berilgan   kalit   bilan   taqqoslaydi,   chunki   to'liq   qidirish   tufayli   qidirish   tezligi
boshqa algoritmlarga qaraganda ancha past.
Odatda,   agar   qidiruv   segmentida   elementlar   kam   bo'lsa,   aks   holda
boshqa qidirish algoritmlaridan foydalaniladi (ulardan biri ikkilik qidiruv).
Chiziqli   qidiruv   amalda   qanday   ishlashini   ko'rib   chiqamiz   Quyidagi
misolda   biz   20   elementdan   iborat   massiv   yaratdik   va   rand   funktsiyasi
yordamida uning yacheykalarini tasodifiy sonlar bilan to'ldirdik.
26-qatorda   biz   foydalanuvchidan   klaviaturadan   tugmachani   kiritishni
so'raymiz, so'ngra ushbu tugmachaning mavjudligini tekshiramiz. Agar kalit
massivning ba'zi bir katakchalariga to'g'ri kelsa, u holda biz ushbu katakning
indeksini   namoyish   etamiz.   Bu   algoritm   qanday   ishlashini   tushunish   uchun
odatiy misol.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
  int main() {
    setlocale(LC_ALL, "rus");
   
    int ans[20]; 
    int h = 0;
    int arr[20]; 
    int key; 
 
    srand ( time(NULL) );
 
    for (int i = 0; i < 20; i++) {
        arr[i] = 1 + rand() % 20; 
 
        cout << arr[i] << " "; 
 
        if (i == 9) {
            cout << endl;
        }
    }
 
    cout << endl << endl << " Kalitni   kiriting  : "; cin >> key; 
 
    for (int i = 0; i < 20; i++) {
        if (arr[i] == key) { 
            ans[h++] = i;         }
    }
 
    if (h != 0) {
        for (int i = 0; i < h; i++) {
            cout << "Kalit " << key << " da joylashgan" << ans[i] << endl; 
        }
    }
    else {
        cout << "Massivdan " << key << " topilmadi";
    }
   
    system("pause");
    return 0;
}
Lineer qidiruv 28 - 32 qatorlarda.
Keling, ushbu misolni ko'rib chiqaylik:
9-10 qatorda: biz ans massivini va h o'zgaruvchisini (nolga teng) yaratdik.
Barcha indekslar ans massivida saqlanadi.
29-qatorda: biz if dallanmalarini ishlatdik.
Agar shartning natijasi ijobiy bo'lsa, unda ans [h] katakchaga i qiymatini 
beramiz va h o'zgaruvchisini bittaga ko'paytiramiz. 34-qatorda: tekshiring:
Agar shartning natijasi ijobiy bo'lsa, unda ans massivining birinchi h 
elementlarini chiqaramiz;
Agar shart natija manfiy bo'lsa, biz "Biz qatorda kalit kalitni topmadik" ni 
chiqaramiz.
Chiziqli qidiruvdan foydalanish kerakmi
Ushbu algoritmning yagona afzalligi - bu oddiy dastur.
Minus bitta, lekin juda katta - kod sekin.
Dastlabki vazifalari uchun uni qo'g'irchoqlar uchun ishlatishni tavsiya etamiz.
Ammo, agar siz juda yuklangan dastur yoki veb-serverni ishlab chiqayotgan 
bo'lsangiz, ushbu qidiruv juda qimmatga tushadi. Sizga yanada samarali 
algoritmlar kerak bo'ladi. Masalan, ikkilik qidirish. Bu juda tez va amalga 
oshirish chiziqli qidirishdan ko'ra murakkabroq emas.
Ikki o‘lchovli massivlar, ularni e’lon qilish usullari va ularni dasturlash
tilida ishlash mexanizmlari
Ko'p   o'lchovli   massivlar.   Hozirgacha   biz   ko'rib   chiqqan   massivlar
tokchadagi   kitoblar   singari   edi.   Uzunroq   tokchada   ko'proq   kitob   bo'lishi
mumkin,   qisqaroq   javonda   kamroq   bo'lishi   mumkin.   Shunday   qilib,   kitob
javon   uzunligi   uning   imkoniyatlarini  belgilaydigan   yagona   o'lchovdir,  ya'ni.
javon   bir   o'lchovli.   Agar                 3-rasmda   ko'rsatilgan   quyosh   panellarini
simulyatsiya   qilish   uchun   massivdan   foydalanish   kerak   bo'lsa   nima   bo'ladi. Quyosh   panellari,   kitob   javonlaridan   farqli   o'laroq,   ikki   o'lchovga   ega:
uzunligi va kengligi. 0-panel 1-panel 2-panel
3-panel 4-panel 5-panel0-ustun 1-ustun
2-ustun
0-satr
1-satr 
3-rasm. Quyosh panellari massivi
Rasmda   ko'rib   turganingizdek   oltita   quyosh   panellari   ikki   o'lchovli
tartibda   joylashtirilgan:   uchta   ustunli   ikki   satr   (qatorlar).   Ammo   siz   ushbu
tartibni   har   biri   o'zi   uchta   paneldan   iborat   bo'lgan   ikkita   elementdan   iborat
massiv deb o'ylashingiz mumkin; boshqacha qilib aytganda, massivlar qatori
sifatida. C++ da ikki o'lchovli massivlarni yaratishingiz mumkin, ammo faqat
ikki  o'lchov  bilan  cheklanmaysiz.  Ehtiyojingizga  va  dasturning  xususiyatiga
qarab xotirada ko'p o'lchovli massivlarni yaratishingiz mumkin.
Ko'p o'lchovli massivlarni e'lon qilish va initsializatsiyalash.  C++ tili
har   bir   o'lchovda   ajratilishi   kerak   bo'lgan   elementlar   sonini   ko'rsatib,   ko'p
o'lchovli massivlarni e'lon qilishga imkon beradi. Shunday qilib, 3- rasmdagi
quyosh   panellarini   aks   ettiruvchi   ikki   o'lchovli   butun   sonlar   massivini
quyidagicha e'lon qilishingiz mumkin:
int solarPanellDs[2][3];
3-rasmda oltita panelning har biriga 0 dan 5 gacha bo'lgan identifikator
berilgan.   Agar   biz   butun   sonli   qatorni   bir   xil   tartibda   initsializatsiya   qilsak,
unda bu initsializatsiya quyidagicha bo’ladi: int solarPanellDs[2][3] = {{0, 1, 2}, {3, 4, 5}};
Ko'rib   turganingizdek,   boshlang'ich   sintaksis   ikki   o'lchovli   massivni
ishga   tushirishda   ishlatiladigan   sintaksisga   o'xshaydi.   Agar   qator   uchta
qator va uchta  ustundan  iborat bo'lsa,  uning  e'lonlari  va  initsializatsiyasi
quyidagicha bo'ladi:
int Array3[3][3] = {{-501, 206, 2017}, {989, 101, 206}, {303, 456, 
596}};
C   ++   tili   ko'p   o'lchovli   massiv   modelidan   foydalanishga   imkon
berishiga   qaramay,   bunday   massivlar   xotirada   hanuzgacha   bir   o'lchovli
sifatida saqlanadi.
Kompilyator   ko'p   o'lchovli   massivni   faqat   bitta   yo'nalishda
kengayadigan xotira maydoniga tushiradi.
Agar istasak, xuddi shu solarPanellDs qatorini quyidagi tarzda ishga
tushirishingiz mumkin - natija bir xil:
int  solarPanellDs[2] [3] = {0, 1, 2 , 3, 4, 5};
Biroq,   avvalgi   usul   aniqroq,   chunki   u   ko'p   o'lchovli   massiv   massivlar
massivi ekanligini tasavvur qilishni va tushunishni osonlashtiradi. Ko'p   o'lchovli   massiv   elementlariga   murojaat   qilish.   Ko'p   o'lchovli
massivni   massivlar   qatori   kabi   ko'rib   chiqaylik.   Ilgari   muhokama   qilingan
ikki o'lchovli massiv uchta satr va uchta ustunni o'z ichiga olganligi sababli,
uni   uchta   elementdan   iborat   massiv   deb   o'ylashimiz   mumkin,   ularning   har
biri uchta butun sondan iborat.
Shuning   uchun,   ushbu   massivda   butun   songa   kirish   kerak   bo'lganda,
birinchi indeksdan butun sonlarni saqlaydigan satr sonini, ikkinchi indeksdan
esa ushbu massivdagi ustun sonini ko'rsatish kerak. Quyidagi massivni ko'rib
chiqaylik:
int Array3[3][3] ={{-501, 206, 2017}, {989, 101, 206}, {303, 456, 596}};
U har biri uchta butun sonni o'z ichiga olgan uchta massiv sifatida 
qaralishi uchun initsializatsiya qilingan. Bu yerda 206 qiymatiga ega butun 
element [0][1] pozitsiyasida, 456 qiymatga ega element esa [2] [1] 
pozitsiyada.
Quyidagi misolda ikki o’lchamli massivni e’lon qilish, uni to’ldirish va
uning elementlariga murojaat qilish ko’rsatilgan.
#include <iostream>
using namespace std;
int main()
{
    const int M=3, N=2;
    int Array2 [M][N];
    cout<<"Massivni to'ldiring"<<endl;     for(int i=0; i<M; i++)
        for(int j=0; j<N; j++){
            cout<<i<<","<<j<<"-elementini kiriting: ";
            cin>>Array2[i][j];
        }
    cout<<"Massivning (1,1)-elementi:"<<Array2[1][1]<<endl;
    return 0;
}
Dasturlashda funksiyalar bilan ishlash.  Funksiya parametrlari va
argumentlari. Kelishuv bo’yicha argumentlar.
Funksiya   -   bu   ma'lum   bir   vazifani   bajarish   uchun   bayonotlar   ketma-
ketligi.   Ko'pincha,   dastur   kodi   funksiyani   bajarishi   uchun   boshqa
operatorlarni to’xtatib turadi. 
Haqiqiy   hayotda   ham   shunga   o'xshash   narsalarni   doimo   bajarasiz.
Masalan,   siz   kitob   o'qiyapsiz   va   telefon   orqali   qo'ng'iroq   qilishingiz
kerakligini   eslaysiz.   Kitobingizda   xatcho'p   qoldirasiz,   telefonni   ko'tarib
raqamni   terasiz.   Suhbatlashgandan   so'ng,   kitobni   o'qishga   qaytasiz,   ya’ni
qoldirgan sahifangizdan kitobni o’qishni davom ettirasiz.
C++   dasturlari   shunga   o'xshash   tarzda   ishlaydi.   Ba'zan,   dastur   kodni
bajarayotganda,   funksiya   murojaatiga   duch   kelishi   mumkin.   Funksiyaga
murojaat   –   bu   protsessorga   joriy   funksiyani   bekor   qilishni   va   boshqa
funktsiyani   ishlatishni   aytadigan   ifoda.   Protsessor   joriy   bajarilish   nuqtasida "xatcho'p   qoldiradi"   va   keyin   chaqirilgan   funktsiyani   ishlatadi.   Murojaat
qilingan   funksiyani   bajarish   tugagandan   so'ng,   protsessor   “xatcho'p”ga
qaytadi va to'xtatilgan funktsiya bajarilishini davom ettiradi.
Funksiyani   e’lon   qilish.   Funksiya   dastur   bajaradigan   harakatlarni
belgilaydi. Funksiyalar sizga ko'rsatmalar to'plamini ajratib ko'rsatish va unga
nom   berish   imkonini   beradi.   Keyin   dasturning   turli   qismlarida   tayinlangan
funksiya nomi yordamida bir necha marta murojaat qilish mumkin. Funksiya
aslida kodning nomlangan blokidir.
tip  funksiya_nomi(parametrlar)
{
ko’rsatmalar
}
Birinchi   satr   funksiya   sarlavhasini   aks   ettiradi.   Dastlab,   funksiyani
qaytarish   turi   (tipi)   ko'rsatiladi.   Agar   funktsiya   hech   qanday   qiymat
qaytarmasa, u holda void turi ishlatiladi.
Keyin   ixtiyoriy   identifikatorni   ifodalovchi   funktsiya   nomi   keladi.
Funksiyani   nomlashda   o'zgaruvchi   nomlashda   qo'llaniladigan   qoidalardan
foydalaniladi.
Funksiya   nomidan   keyin   parametrlar   qavs   ichida   keltirilgan.
Funktsiyaning   parametrlari   bo'lmasligi   mumkin,   bu   holda   bo'sh   qavslar
ko'rsatiladi.
Funksiya   sarlavhasidan   so'ng,   sistemali   qavslarda   bajariladigan
ko'rsatmalar berilgan funksiya tanasini ifodalaydi.
Qaytish   qiymati.   Natija   qaytarish   uchun   funksiya   return   operatoridan
foydalanadi.   Agar   funksiya   qaytarish   turi   sifatida   void   tipidan   boshqa   har
qanday   turga   ega   bo'lsa,   u   return   operatori   yordamida   qiymatni   qaytarishi
shart.   Masalan,   har   qanday   C++   dasturida   bo'lishi   kerak   bo'lgan   va   uning
bajarilishi boshlanadigan asosiy funksiya ta'rifi: int main()
{
return 0;
}
main() bajarilishini tugatgandan so'ng, return operatori yordamida butun
sonni operatsion tizimga qaytaradi.
Biz   yozadigan   funksiyalar   qiymatlarni   ham  qaytarishi  mumkin.  Buning
uchun   siz   qaytish   turini   (yoki   "qaytish   tipini")   belgilashingiz   kerak.   Bu
funksiyani e'lon qilishda, uning nomidan oldin ko'rsatiladi. Qaytish turi qaysi
qiymat qaytarilishini ko'rsatmasligini unutmang. Bu faqat ushbu qiymat turini
bildiradi.
So'ngra,   chaqirilgan   funksiya   ichida,   qaytish   qiymatini   belgilash   uchun
return   operatoridan   foydalanamiz   -   qaysi   qiymat   murojaat   qiluvchiga
qaytariladi.
Butun sonni qaytaradigan oddiy funktsiyani ko'rib chiqaylik:
int return7()
{
        // Ushbu funktsiya butun qiymatni qaytaradi, shuning uchun biz return
operatoridan foydalanishimiz kerak
        return 7;
}
void   tipi.   Yuqoridagi   funksiyaning   qaytish   turi   int,   shuning   uchun
funksiya return operatoridan foydalanishi va int turiga mos keladigan ba'zi bir
qiymatni   qaytarishi   kerak.   Qaytish   qiymati   return   bayonotidan   keyin
joylashtiriladi. Funksiyalar   qiymatlarni   qaytarishi   yoki   qaytarmasligi   mumkin.
Kompilyatorga   funksiya   qiymatni   qaytarmasligini   aytish   uchun   siz   void
return turidan foydalanishingiz kerak. Quyida berilgan doPrint() funksiyasini
ko'rib chiqamiz:
void doPrint()
{
    cout<<"Salom";
}
Ushbu   funksiya   void   qaytarish   turiga   ega,   ya'ni   funksiya   qiymatni
qaytarmaydi.   Hech   qanday   qiymat   qaytarilmasligi   sababli,   hech   qanday
return bayonoti talab qilinmaydi.
Funksiyaga   murojaat   qilish .   Funksiyadan   foydalanish   uchun   uni
chaqirish kerak. Funksiya quyidagi shaklda chaqiriladi:
funksiya_nomi(argumentlar);
Funksiya nomidan keyin qavslar qo'shiladi, unda argumentlar - funksiya
parametrlari uchun qiymatlar keltirilgan.
Masalan, eng oddiy funksiyani aniqlaymiz va uni chaqiramiz:
#include <iostream>
 
void hello()
{
        std::cout << "Salom\n";
}
  int main()
{
        hello();
        hello();
        return 0;
}
Bu   hello   funksiyasini   belgilaydi,   bu   asosiy   funksiyada   ikki   marta
chaqiriladi.   Bu   funktsiyalarning   afzalligi:   biz   ba'zi   bir   umumiy   harakatlarni
alohida funksiyaga o'tkazamiz va keyin ularni dasturning turli joylarida ko'p
marta chaqiramiz. Natijada, dastur "Salom" satrini ikki marta bosib chiqaradi.
Funksiyalarni   chaqirishda   quyidagi   xatoliklarga   yo’l   qo’ymaslik   kerak.
Quyidagi misolni qarab chiqaylik:
#include <iostream>
void returnNothing()
{
    cout<<"Salom!"<<endl;
}
int main()
{
   returnNothing();
   cout<<returnNothing();// bu xatolik 
    return 0;
} ReturnNothing()   ga   birinchi   murojatt   “Salom!”   ni   bosib   chiqaradi,
ammo   murojaat   qiluvchiga   hech   narsa   qaytarilmaydi.   Bajarilish   nuqtasi
main() funksiyasiga qaytadi, bu yerda dastur o'z bajarilishini davom ettiradi.
ReturnNothing() ga ikkinchi murojaat hatto tuzilmaydi. ReturnNothing()
funksiyasi   void   qaytarish   turiga   ega,   ya'ni   bu   funktsiya   qiymat   bermaydi.
Biroq,   main()   funksiyasi   ushbu   qiymatni   (qaytarilmagan)   cout   operatoriga
chiqish uchun yuborishga harakat qiladi. cout bu ishni ko'rib chiqa olmaydi,
chunki   chiqish   qiymati   berilmagan.   Shunday   qilib,   kompilyator   xatoga   yo'l
qo'yadi. 
main() funksiyasi haqida.  Endi siz main() funksiyasi qanday ishlashini
tushunasiz. Dastur bajarilgach, operatsion tizim main() funksiyasini chaqiradi
va   uning   bajarilishini   boshlaydi.   main()   dagi   ifodalar   ketma-ket   bajariladi.
Nihoyat,   main()   funktsiyasi   operatsion   tizimga   butun   qiymatni   qaytaradi
(odatda 0). Shuning uchun main() funksiyasi int main () deb e'lon qilinadi.
Nima   uchun   operatsion   tizimga   qiymatlarni   qaytarish   kerak?   Gap
shundaki,   main()   funksiyasining   qaytish   qiymati   operatsion   tizimga
dasturning   muvaffaqiyati   yoki   muvaffaqiyatsizligi   to'g'risida   ma'lumot
beradigan  holat kodidir. Odatda, qaytarish  qiymati 0  (nol)  har  bir narsaning
muvaffaqiyatli   bo'lganligini   anglatadi,   boshqa   har   qanday   qiymat   esa   xato   /
xato degan ma'noni anglatadi.
Shuni   bilib   olingki,   C++   standartlari   bo'yicha   main()   funktsiyasi   butun
sonni   qaytarishi   kerakligini   unutmang.   Ammo,   main()   funktsiyasi   oxirida
qaytishni ko'rsatmasangiz, xatolar bo'lmasa kompilyator avtomatik ravishda 0
qaytaradi.   Lekin   main()   funktsiyasi   oxirida   return   ni   ko'rsatish   va   main()
funktsiyasi uchun int return turidan foydalanish tavsiya etiladi.
Funksiyaning   qaytuvchi   tipi   haqida   quyidagi   ma’lumotlarni   bilib   olsih
kerak: Birinchidan,   funksiyani   qaytarish   turi   void   bo’lmasa,   u   belgilangan
turdagi   qiymatni   qaytarishi   kerak   (return   operatoridan   foydalaning).
Faqatgina   istisno   main   ()   funksiyasi   bo'lib,   u   boshqa   qiymat   berilmasa   0
qiymatini beradi.
Ikkinchidan,   protsessor   funksiyada   return   operatoriga   duch   kelganda,
darhol   qiymatni   murojaat   qiluvchiga   qaytaradi   va   ijro   etish   nuqtasi   ham
murojaat qiluvchiga o'tadi. Funksiyada qaytarilish orqasida turgan har qanday
kod e'tiborga olinmaydi.
Funktsiya   murojaat   qiluvchiga   return   orqali   faqat   bitta   qiymatni
qaytarishi   mumkin.   Bu   raqam   yoki   (masalan,   7),   yoki   o'zgaruvchining
qiymati, yoki ifoda (natijaga ega) yoki mumkin bo'lgan qiymatlar to'plamidan
ma'lum bir qiymat bo'lishi mumkin.
Ammo   bir   vaqtning   o'zida   bir   nechta   qiymatlarni   qaytarish   orqali   bitta
qiymatni qaytarish qoidasidan o'tish usullari mavjud, ammo bu haqida boshqa
darsda batafsil gaplashamiz.
Nihoyat, funktsiya muallifi uning qaytish qiymati nimani anglatishini hal
qiladi.   Ba'zi   funktsiyalar   funksiyalarni   bajarish   natijasini   (muvaffaqiyatga
erishdimi   yoki   yo'qmi)   ko'rsatish   uchun   qaytarish   qiymatlarini   holat   kodlari
sifatida   ishlatadilar.   Boshqa   funksiyalar   mumkin   bo'lgan   qiymatlar
to'plamidan   ma'lum   bir   qiymatni   qaytaradi.   Bundan   tashqari,   umuman   hech
narsa qaytarmaydigan funksiyalar mavjud.
Funksiyalardan   bir   necha   marta   foydalanish.   Xuddi   shu   funksiyani
hatto   turli   xil   dasturlarda   ham   bir   necha   marta   chaqirish   mumkin,   bu   juda
foydali:
#include <iostream>
using namespace std;
//getValueFromUser()   funksiyasi   foydalanuvchidan   qiymatni   oladi   va
keyin uni murojaat qiluvchiga qaytaradi int getValueFromUser()
{
    cout<<"Raqam kiriting:";
    int x;
    cin>>x;
    return x;
}
int main()
{
   int a = getValueFromUser();
   int b = getValueFromUser();
   cout<<a<<"+"<<b<<"="<<a+b<<endl;
   return 0;
}
Bu yerda main () 2 marta to'xtatiladi. E'tibor bering, har ikkala holatda
ham natija x qiymati o'zgaruvchida saqlanadi va keyin return yordamida main
() ga qaytariladi va u yerda a va b o’zgaruvchisi navbat bilan qiymat oladi.
Bundan   tashqari   main()   boshqa   funksiyalarni   chaqira   oladigan   yagona
funktsiya emas.  Har  qanday  funksiya  boshqa har qanday  funksiyani chaqira
oladi.
#include <iostream>
using namespace std;
void print0()
{
   cout << "O" << endl; }
 
void printK()
{
   cout << "K" << endl;
}
 
// PrintOK() funksiyasi printO() va printK() ni chaqiradi
void printOK()
{
   printO();
   printK();
}
 
int main()
{
   cout << "Starting main()" << endl;
   printOK();
   cout << "Ending main()" << endl;
   return 0;
}
Ichki funksiyalar.  C ++ da ba'zi funksiyalarni boshqa funksiyalar ichida
e'lon qilish mumkin emas (ya'ni ularni joylashtirish mumkin emas). Quyidagi
kod kompilyatsiya xatoligini keltirib chiqaradi:
#include <iostream>
using namespace std; int main()
{
      int   boo()   //   bu   funksiya   main()   funksiyasi   ichida   joylashgan,   bu   esa
ta'qiqlangan
   {
      cout << "boo!";
      return 0;
   }
   boo();
   return 0;
}
Bu aslida quyidagicha bo’ladi:
#include <iostream>
using namespace std;
int   boo()   //   bu   funksiya   main()   funksiyasi   ichida   joylashgan,   bu   esa
ta'qiqlangan
   {
      cout << "boo!";
      return 0;
   }
int main()
{
   
   boo();    return 0;
}
Funksiya   parametrlari   va   argumentlari.   Ko'p   hollarda,   biz
chaqirilgan funksiyaga qandaydir tarzda ta'sir o'tkazishi uchun ma'lumotlarni
uzatishimiz   kerak   bo'ladi.   Masalan,   agar   biz   ikkita   sonni   ko'paytirish   uchun
funksiya   yozmoqchi   bo'lsak,   unda   qanday   qilib   funktsiyaga   ular   qaysi
raqamlar   bo'lishini   aytib   berishimiz   kerak.   Aks   holda,   u   nimani   nimaga
ko'paytirishni   qayerdan   biladi?   Bu   yerda   parametrlar   va   argumentlar
tushunchasi kerak bo'ladi.
Funksiya   parametri   -   bu   funksiyada   ishlatiladigan   va   qiymatini
chaqiruvchi   (murojaat   qiluvchi)   tomonidan   ta'minlanadigan   o'zgaruvchidir.
Parametrlar funktsiyani e'lon qilishda qavs ichida ko'rsatiladi. Agar ularning
soni ko'p bo'lsa, ular vergul bilan ajratiladi, masalan:
// Bu funksiya hech qanday parametrga ega emas
void doPrint()
{
   cout << "doPrint() funksiyasi" << std::endl;
}
 
// Bu funksiya bitta parametrga ega va u int tipiga tegishli
void printValue(int a)
{
   cout << a << endl;
}
 
// Bu funksiya ikkita int tipidagi a va b parametrlariga ega int add(int a, int b)
{
   return a + b;
}
Har   bir   funksiyaning   parametrlari   faqat   shu   funksiya   doirasida   amal
qiladi.   Shuning   uchun,   agar   printValue()   va   add()   parametrlari   a   deb
nomlangan   bo'lsa,   unda   bu   nom   ziddiyatli   bo'lishini   anglatmaydi.   Ushbu
parametrlar   mustaqil   deb   hisoblanadi   va   bir-birlari   bilan   hech   qanday   ta'sir
qilmaydi.
Funksiya argumenti   - bu murojaat qiluvchidan funksiyaga uzatiladigan
va   murojaat   qiluvchida   funksiyani   chaqirishda   qavs   ichida   ko'rsatilgan
qiymat:
printValue(7);
add(4,5);
E'tibor   bering,   argumentlar   vergul   bilan   ham   ajratilgan.   Argumentlar
soni   parametrlar   soniga   to'g'ri   kelishi   kerak,   aks   holda   kompilyator   xato
xabari chiqaradi.
Funksiya   parametrlari   va   argumentlari   qanday   ishlaydi?   Funksiya
chaqirilganda   uning   barcha   parametrlari   local   o'zgaruvchilar   sifatida
yaratiladi va har bir argumentning qiymati mos keladigan parametrga (lokal
o'zgaruvchiga)   ko'chiriladi.   Ushbu   jarayon   qiymat   bo’yicha   uzatish
deyiladi. Masalan:
#include <iostream>
using namespace std; void printValues(int a, int b)
{
    cout<<a<<endl;
    cout<<b<<endl;
}
int main()
{
   printValues(8,9);
   return 0;
}
PrintValues ()   funksiyasi   chaqirilganda,   8   va   9   argumentlari   a   va   b
parametrlariga   ko'chiriladi.   a   parametrga   8,   b   parametrga   esa   9   qiymat
beriladi.
Parametrlar   va   funktsiyalarning   qaytish   qiymatlari   qanday   ishlaydi?
Parametrlar   va   qaytish   qiymatlari   yordamida   biz   ma'lumotlarni   qabul
qiladigan   va   ishlov   beradigan   funktsiyalarni   yaratib,   so'ngra   murojaat
qiluvchiga natijani qaytaramiz.
Masalan,   ikkita   butun   sonni   oladigan   va   ularning   yig'indisini
qaytaradigan oddiy funksiya:
#include <iostream>
using namespace std;
int add(int a, int b)
{
    return a+b;
}
int main()
{    cout<<add(7,8)<<endl;
   return 0;
}
Misol. Funksiyalarni bir necha usullarida chaqirish
#include <iostream>
using namespace std;
int add(int a, int b)
{
    return a+b;
}
int main()
{
   cout<<add(7,8)<<endl;
   return 0;
}
Ko’rinishi sohasi. Lokal va global o’zgaruvchilar
Ko’rinishi sohasi (scope) dasturning obyektini ishlatish mumkin bo'lgan
qismini ifodalaydi. Odatda, ko’rinish sohasi sistemali qavs ichida joylashgan
kod   bloki   bilan   cheklanadi.   Ko’rinish   sohasiga   qarab,   yaratilgan   obyektlar
global ,  lokal  yoki  avtomatik  bo'lishi mumkin.
Dastlab ,   ikkita   atamani   tushunishimiz   kerak:   ko’rinish   sohasi   va
yashash vaqti . Ko’rinish  sohasi o'zgaruvchini qayerda ishlatishni aniqlaydi.
Yashash   vaqti   (yoki   "yashash   muddati")   o'zgaruvchining   qayerda
yaratilganligini   va   u   yo'q   qilinishini   aniqlaydi.   Ushbu   ikkita   tushuncha   bir-
biriga bog'liqdir.
Blok   ichida   aniqlangan   o'zgaruvchilar   lokal   o'zgaruvchilar   deyiladi.
Lokal   o'zgaruvchilar   avtomatik   ishlash   muddatiga   ega:   ular   aniqlanish
nuqtasida   yaratiladi   (va   agar   kerak   bo'lsa,   ishga   tushiriladi)   va   blokdan chiqqandan keyin yo'q qilinadi. Lokal o'zgaruvchilar lokal ko’rinish sohasiga
(yoki   "blok")   ega,   ya'ni   ular   e’lon   qilingan   nuqtadan   kelib   chiqadi   va   ular
aniqlangan blokning oxirida chiqadi.
Masalan, quyidagi dasturni ko'rib chiqaylik:
#include <iostream>
using namespace std;
int main()
{
    int x=4;
    double y=5.0;
    cout<<x;
    return 0;
}
Asosiy   funksiya   bloki   ichida   x   va   y   o'zgaruvchilar   aniqlanganligi
sababli, ikkalasi ham main () bajarilishini tugatgandan so'ng yo'q qilinadi.
Ichki   bloklar   ichida   belgilangan   o'zgaruvchilar   ichki   blok   tugashi
bilanoq yo'q qilinadi:
#include <iostream>
int main() // tashqi blok
{
    int m=4; // bu yerda m o'zgaruvchisi e'lon qilinyapti va initsializatsiya
qilinyapti
    { // ichki blokning boshlanishi
                double   k=5.0;   //bu   yerda   k   o'zgaruvchisi   yaratiladi   va   ishga
tushiriladi     } // k ko'rinish sohasidan chiqib ketadi va bu yerda yo'q qilinadi
    // Bu yerda k o'zgaruvchisini ishlatib bo'lmaydi.
    k  = k+1; //Bu xato
        return 0;
}
Bunday   o'zgaruvchilardan   faqat   ular   aniqlangan   bloklar   ichida
foydalanish   mumkin.   Har   bir   funksiya   o'z   blokiga   ega   bo'lganligi   sababli,
bitta funksiyadagi o'zgaruvchilar boshqa funksiyadagi o'zgaruvchilarga ta'sir
qilmaydi:
#include <iostream>
using namespace std;
void someFunction()
{
    int value=5;
    // value o'zgaruvchisidan faqat shu blokda foydalanish mumkin
} // value o'zgaruvchisi ko'rinishi sohasidan chiqdi va u yo'q qilinadi
int main()
{
    // value o'zgaruvchisidan bu blokda foydalanib bo'lmaydi
    someFunction();
    return 0;
}
Turli   xil   funksiyalar   bir   xil   nomdagi   o'zgaruvchilar   yoki   parametrlarni
o'z   ichiga   olishi   mumkin.   Bu   yaxshi,   chunki   ikkita   mustaqil   funksiya o'rtasidagi   ziddiyatlarni   nomlash   ehtimoli   haqida   tashvishlanishingiz   shart
emas.   Quyidagi   misolda   ikkala   funktsiya   ham   x   va   y   o'zgaruvchilarga   ega.
Ular hatto bir-birlarining mavjudligini bilishmaydi:
#include <iostream>
using namespace std;
// add() funksiyasi
int add(int x, int y)
{
    return x + y;
}
// main() ichida ham x va y o'zgaruvchilari ishlatilgan
int main()
{
    int x = 5; // x o'zgaruvchisi e'lon qilingan
    int y = 6;
        cout   <<   add(x,   y)   <<   endl;   //main()   funksiyasining   x   qiymati   add()
funksiyasining x o'zgaruvchisiga ko'chiriladi
    return 0;
}
Ichki  bloklar  ular  belgilanadigan  tashqi  blokning  bir  qismi  hisoblanadi.
Shunday qilib, tashqi blokda aniqlangan o'zgaruvchilar ichki blok ichida ham
ko'rish mumkin:
#include <iostream>
using namespace std; int main()
{ // tashqi blok
    int x=5;
    { // ichki blokning boshlanishi
        int y=7;
        // x va y dan foydalanish mumkin
        cout << x << " + " << y << " = " << x + y;
    } // y o'zgaruvchisi yo'q qilinadi
        //   y   o'zgaruvchisini   bu   yerda   ishlatish   mumkin   emas,   chunki   u
allaqachon yo'q qilingan!
    return 0;
}
Nomlarni yashirish. Ichki blok ichidagi o'zgaruvchi tashqi blok ichidagi
o'zgaruvchiga o'xshash nomga ega bo'lishi mumkin. Bu sodir bo'lganda, ichki
(ichki)   blokdagi   o'zgaruvchi   tashqi   o'zgaruvchini   "yashiradi".   Bunga
nomlarni yashirish deyiladi:
#include <iostream>
using namespace std;
int main()
{ // tashqi blok
int a=5;
  if (a >= 5) 
{ // ichki blok
int a; // a o'zgaruvchisi ichki blokda yashirilmoqda
 
//   a   identifikatori   endi   ichki   o'rnatilgan   a   o'zgaruvchiga   ishora
qiladi.
        // a tashqi o'zgaruvchisi vaqtincha yashiringan
 
a   =   10;   //Bu   yerda   tashqi   emas,   balki   ichki   a   o'zgaruvchisiga
qiymat berilgan
 
cout << a << endl;
} // ichki a o'zgaruvchisi o'chirildi
 
// a identifikatori yana tashqi o'zgaruvchiga ishora qiladi
 
cout << a << endl;
return 0;
}
Imkon   qadar   nomlarni   yashirishga   umuman   yo'l   qo'ymaslik   kerak,
chunki bu juda chalkash holatlarda olib kelishi mumkin. Iloji boricha tashqi
o'zgaruvchilar   bilan   bir   xil   nomdagi   ichki   o'zgaruvchilarni   ishlatishdan
saqlanish lozim.
Global   o’zgaruvchilar.   Global   o'zgaruvchilar   dastur   faylida   har   qanday
funktsiyalardan   tashqarida   aniqlanadi   va   har   qanday   funksiya   tomonidan
ishlatilishi mumkin.
#include <iostream>
using namespace std;
void print(); int n = 5; //Global o'zgaruvchi
int main()
{
    print();                        // n=6
    n++;
    cout << "n=" << n << endl;   // n=7
    return 0;
}
void print()
{
    n++;
    cout << "n=" << n << endl;
}
Bu yerda n o'zgaruvchisi global va har qanday funksiyadan foydalanish
mumkin.   Bundan   tashqari,   har   qanday   funksiya   o'z   qiymatini   o'zgartirishi
mumkin.
Lokal   o’zgaruvchilar .   Kod   bloki   ichida   yaratilgan   obyektlar   (u
funksiyani   yoki   qandaydir   sikl   tipidagi   konstruktsiyani   ifodalashi   mumkin)
lokal   deb   nomlanadi.   Bunday   obyektlar   faqat   ular   belgilangan   kod   bloki
ichida mavjud bo’ladi.
Qayta   yuk l a n uvchi   funksiyalar
Ayr i m   algoritmlar   berilganlar n ing   har   xil   turdagi   qiymatlari
uch u n   qo’llan i shi   mumki n .   Masalan,   ik k ita   s on n ing   mak s imumini
topish   algoritmida   b u   sonlar   butun   yo ki   haqiqiy   turda   b o’ l ishi
mumkin.   Bun d ay   hollarda   bu   algoritmlar   ama l ga   oshiril g an   fu n k-
siyalar   nomlari   bir   xil bo’l g ani   ma ’ qul.   Bir   nechta   funksi ya ni   bir xil nom l ash,   lekin   har   xil   turdagi   parametrlar   bil a n   ish l atish
funks i yani   qayta   yuklash  deyiladi.
Kompilyator   parame t rlar   tur i ga   va   s oniga   qarab   mos   funksiyani
chaqiradi.   Bun d ay   amal n i   « hal   qilish   amali »   de yiladi   va   u ni n g
maqsadi   parametrlarga   ko’ra   aynan   (nisbatan)   to’ g’ ri   keladigan
funksiyani   cha q irishdir.   Agar   bunday   funksiya   topilmasa   kompil ya tor
xatolik   haqida   xabar   beradi.   Funksiyani   aniqlashda   funksiya
qaytaruvchi   qiym a t turining ahamiyati yo’ q .   Mis o l:
#include <iostream>
using namespace std;
int Max(int,int);
char Max(char,char);
float Max(float,float);
int Max(int,int,int);
int main()
{
    int a,b;
     char c,d;
    int k;
     float x,y;
    cin>>a>>b>>k>>c>>d>>x>>y;
    cout<<Max(a,b)<<endl;
    cout<<Max(c,d)<<endl;
    cout<<Max(a,b,k)<<endl;
    cout<<Max(x,y);
    return 0;
} int Max(int i,int j)
{
    return (i>j)?i:j;
}
char Max(char s1,char s2)
{
    return (s1>s2)?s1:s2;
}
float Max(float x,float y)
{
    return (x>y)?x:y;
}
int Max(int i,int j,int k)
{
    if(i>j)
        if(i>k)
        return i;
        else
            return k;
        if(j>k)
            return j;
        else
            return k;
}
Ag a r   funksiya   chaqirilishida   argument   turi   un i ng   prototipidagi   xud d i
sh u   o’rindagi   parametr   turi g a   mos   kelmasa,   kompilyator   uni   parametr tu r iga   keltirilishga   harakat   qiladi   -   bool   va   char   turlarini   int   t u riga,   float
t u rini   double   t u ri g a   va   int   turini   d o uble turiga   o’tkazishg a .
Qayta   yuklanuvchi   funksi ya lardan   foyda l anishda   quyidagi
qoidalarga r i oya qilish kera k :
1)   qayta   yuklanuv ch i   funksiyalar   bitta   ko’rinish   sohasida   bo’lishi
kera k ;
2)   qayta   yu kla nu vchi   funksiyalarda   ke l ishuv   bo’yicha   parametrlar
ishlatilsa,   bunday   parametrlar   barcha   qayta   yu k lanuvchi   funksiya-
larda ham ishl a t ilishi va ular bir xil   qiymatga ega bo’lish kera k ;
3)   agar   funksiyalar   parametrlarining   turi   fa q at   «const»   va   ‘&’
belgilari   bilan   farq   qilad i gan   b o’ lsa,   bu   funk s iyalar   qayta   yuklanmaydi.
Keli sh uv   b o’y i cha   argu me ntlar.  С ++   tilida   funksiya   chaqirilga n da
ayrim   argumentlarni   tushirib   q oldirish   mumkin.   B unga   funksiya
prototipida   ushbu   parametrlarni   kelishuv   bo’yi ch a   qiymatini   ko’rs a tish
orqali   e r i shish   mumkin.   Masala n ,   quyida   prototipi   keltir i lgan   funksiya
turli chaqirishga e g a bo’lishi  m umkin:
//funksiya prototipi
void Butun_Son(int I,bool Bayroq=true,char Blg=’\n’);
 //funksiyani chaqirish variantlari 
Butun_Son(1,false,’a’);
Butun_Son(2,false); 
Butun_Son(3);
Birinchi   chaqiruvda   barcha   parame t rlar   mos   ar g ume n t l ar   orq a li
qiymatlarini   qabul   qiladi,   ikkinchi   holda   I   p a ramet r i   2   qiy m atini,
bayroq   parametri   false   qiy m atini   va   Blg   o’ zgaruv ch isi   ke l ishuv
bo’yicha ‘\n’ qiymatini   qab u l qila d i. Keli sh uv   bo’yicha   qiymat   berishni n g   bitta   sha r ti   bor   -   para-
metrlar   ro’yxatida   kelishuv   b o’yicha   qiymat   beri l gan   parametrlardan
keyingi   p arametrlar   h am   keli sh uv   b o’yicha   qiymatga   ega   bo’lishlari
shart.   Yuqoridagi   misolda   I   par a metri   ke lishuv   bo’ y icha   qiymat   qabul
qiling a n   holda,   Bay r oq   yoki   Blg   parametrlari   qiymatsiz   bo’l i shi
mumkin   emas.   Misol   tariqasida   ber i lgan   sonni   ko’rsatilgan
aniqlikda   chop   e tuvchi   p r ogrammani   ko’rayl i k.   Qo’yi l gan
masalani   yechishda   sonni   daraja g a   oshirish   funksiyasi   -   pow()
va
suz u vchi   nuqtali   uzun   sondan   modul   olish   fabs l ()   funksiyasidan
foydal-niladi.   B u   funk s iyalar   prototipi   «math.h»   sarlavha
faylida joylashgan.
#include <iostream>
#include <math.h>
using namespace std;
void Chop_qilish(double Numb, double Aniqlik=1, bool Bayroq = true)
{
    if(!Bayroq)
        Numb=fabsl(Numb);
    Numb=(int)(Numb*pow(10,Aniqlik));
    Numb=Numb/pow(10,Aniqlik);
    cout<<Numb<<'\n';
}
int main()
{
    double Mpi=-3.141592654;     Chop_qilish(Mpi,4,false);
    Chop_qilish(Mpi,2);
    Chop_qilish(Mpi);
    return 0;
}
Programmada   s onni   turli   aniqlikda   (Aniql i k   parametri
qiymati   orqali)   chop   etish   uchun   har   xil   variantlarda   Chop_qilish()
funksiyasi   chaqirilgan.   Programma   ishla sh i   natijasida   ekranda
quyidagi sonlar chop etil a di:
3.1 4 15   -
3. 1 4  
-3.1
Parametrning   kelishuv   b o’yicha   beriladigan   qiymati   o’zgarmas,
global   o’ z garuv ch i   yoki   qa n daydir   funksiya   tomonidan   q aytaradi g an
qiymat bo’li sh i mumkin.
Rekursiv funksiyalar.
Rekursiya   -   bu   nafaqat   ilm-fan   sohasida,   balki   kundalik   hayotda   ham
uchraydigan juda keng tarqalgan hodisa. 
Dasturlashda  rekursiya   funksiyalar   bilan  chambarchas  bog'liq,  aniqrog'i
dasturlashdagi   funksiyalar   tufayli   rekursiya   yoki   rekursiv   funksiya   kabi
tushunchalar mavjud.  
Dasturlashda  rekursiya   funksiyalar   bilan  chambarchas  bog'liq,  aniqrog'i
dasturlashdagi   funksiyalar   tufayli   rekursiya   yoki   rekursiv   funksiya   kabi
narsalar   mavjud.   Oddiy   so'zlar   bilan   aytganda,   rekursiya   -   bu   funksiya
qismini   o'zi   orqali   belgilash,   ya'ni   o'zini   to'g'ridan-to'g'ri   (tanasida)   yoki bilvosita   (boshqa   funktsiya   orqali)   chaqiradigan   funksiya.   Odatda   rekursiv
muammolarga   sonning   faktorialini   topish,   Fibonachchi   raqamini   topish   va
hokazolarni   keltirish     mumkin.   Bu   kabi   masalalarni   sikllar   yordamida   ham
hal   qilish   mumkin.   Umuman   aytganda,   iterativ   ravishda   yechilgan   hamma
narsani rekursiv, ya'ni rekursiv funksiya yordamida hal qilish mumkin. 
C++   da   rekursiv   funksiya   (yoki   shunchaki   "rekursiya")   o'zini   o'zi
chaqiradigan funksiya.
Masalan:
#include <iostream>
using namespace std;
void countOut(int count1)
{
    std::cout << "push " << count1 << '\n';
    countOut(count1-1); //countOut () funktsiyasi o'zini rekursiv chaqiradi
}
int main()
{
    countOut(4);
    return 0;
}
countOut(4)   ga   murojaat   qilish   “push   4”   yozuvini   bosib   chiqaradi   va
keyin countOut (3) ni chaqiradi. countOut (3) “push 3” ni bosib chiqaradi va
countOut (2) ga murojaat qiladi.
Rekursiyani   tugatish   sharti.   Rekursiv   funksiya   chaqiruvlari   odatdagi
funktsiya   murojaatlari   singari   ishlaydi.   Shu   bilan   birga,   yuqoridagi   dastur
oddiy funksiyalar va rekursivlar o'rtasidagi eng muhim farqni aks ettiradi: siz rekursiyani tugatish shartini belgilashingiz kerak, aks holda funktsiya cheksiz
marta bajariladi.
Rekursiyani   tugatish   sharti   -   bu   bajarilgandan   so'ng   rekursiv
funksiyani o'zi chaqirishni to'xtatadigan shart. Ushbu holat odatda if ifodasini
ishlatadi.
Bu   yerda   yuqoridagi   funksiyaga   misol   keltirilgan,   ammo   bu   yerda
rekursiya tugashi sharti ham mavjud:
#include <iostream>
using namespace std;
void countOut(int count1)
{
    cout << "push " << count1 << '\n';
    if (count1 > 1) // chiqish sharti
        countOut(count1-1);
    cout << "pop " << count1 << '\n';
}
int main()
{
    countOut(4);
    return 0;
}
Ushbu   dasturni   ishga   tushirganimizda   quyidagi   qiymatlar   ekranda   chop
etiladi boshlanadi:
push 4
push 3
push 2 push 1
Rekursiv   algoritmlar.   Eng
mashhur   matematik   rekursiv
algoritmlardan   biri   bu
Fibonachchi   ketma-ketligi.
Fibonachchi   ketma-ketligini
tabiatda   ham   ko'rish   mumkin:   daraxt   shoxlari,   spiral   kabuklar,   ananas
mevalari, ochiladigan fern va boshqalar.
Fibonachchi raqamlarining har biri berilgan son joylashgan kvadratning
gorizontal   tomonining   uzunligi.   Fibonachchi   raqamlari   matematik   jihatdan
quyidagicha aniqlanadi:
F(n) = 0, agar n = 0
1, agar n = 1
F(n-1) + F(n-2), agar n > 1
Shunday   qilib,   Fibonachchi   sonini   hisoblash   uchun   rekursiv   funksiyani
yozish juda oson:
#include <iostream>
using namespace std;
int fibonacci(int number)
{
    if (number == 0)
        return 0;
    if (number == 1)
        return 1; //
    return fibonacci(number-1) + fibonacci(number-2);
} // Dastlabki 13 ta Fibonachchi sonini topish
int main()
{
    for (int count=0; count < 13; ++count)
        cout << fibonacci(count) << " ";
    return 0;
}
Rekursiya va Iteratsiya. 
Rekursiv   funksiyalar   haqida   eng   ko'p   so'raladigan   savol:   "Nima   uchun
rekursiv funksiyadan foydalanish kerak, chunki bu masalalarni for sikli yoki
while sikli yordamida ham bajarish mumkin?” Ma'lum bo'lishicha, har doim
rekursiv   masalani   takroriy   ravishda   hal   qilishingiz   mumkin.   Biroq,
ahamiyatsiz   bo'lmagan   holatlar   uchun   rekursiv   versiyani   yozish   va   o'qish
ko'pincha   ancha   osonlashadi.   Masalan,   n-Fibonachchi   raqamini   hisoblash
funksiyasini   takrorlash   operatorlari   yordamida   yozish   mumkin,   ammo   bu
murakkab bo'ladi.
Iteratsion   funktsiyalar   ( for   yoki   while   sikllaridan   foydalanadigan
funksiyalar)   deyarli   har   doim   o'zlarining   rekursiv   o'xshashlariga   qaraganda
samaraliroq.   Buning   sababi   shundaki,   har   safar   funksiya   chaqirilganda
ma'lum miqdordagi resurslar sarflanadi. Iterativ funksiyalar ancha kam resurs
sarf qiladi.
Bu   takrorlanadigan   funktsiyalar   har   doim   eng   yaxshi   variant   degani
emas.   Ba'zan   rekursiv   dastur   yanada   toza   va   sodda   bo'lishi   mumkin   va
qo'shimcha   qo'shimcha   xarajatlar   ko'proq   bo'lishi   mumkin,   bu   kodni kelgusida   saqlashdagi   qiyinchiliklarni   minimallashtiradi,   ayniqsa   algoritm
echim topishga juda ko'p vaqt ketmasa.
Umuman   olganda,   rekursiya,   agar   quyidagilarning   aksariyati   to'g'ri
bo'lsa, yaxshi tanlovdir:
– rekursiv kodni amalga oshirish ancha oson;
– rekursiya chuqurligini cheklash mumkin;
– algoritmning   takrorlanadigan   versiyasi   ma'lumotlar   to'plamini
boshqarishni talab qiladi;
– bu   dasturning   ishlashiga   bevosita   ta'sir   ko'rsatadigan   muhim   kod
emas.
Funksiyalardan   foydalanish   sabablari.   Dastlabki   boshlovchi
dasturchilarda ko'pincha "Masalani funksiyalarsiz bajarish va barcha kodlarni
to'g'ridan-to'g'ri main() funksiyasiga qo'yish mumkinmi?" degan savol paydo
bo’ladi. Agar dastur kodingiz atigi 10-20 satrdan iborat bo'lsa, unda siz buni
qila   olasiz.   Jiddiy   eslatma   sifatida,   funksiyalar   kodni   murakkablashtirishga
emas,   balki   soddalashtirishga   qaratilgan.   Ularning   notrivial   dasturlarda   juda
foydali bo'lgan bir qator afzalliklar bor.
Struktura.   Dasturlar   hajmi/murakkabligi   oshib   borgan   sari,   barcha
kodlarni   main()   ichida   saqlash   qiyin   bo'ladi.   Funksiya   mini-dasturga
o'xshaydi,   biz   uni   kodning   qolgan   qismi   bilan   asosiy   dasturdan   alohida
yozishimiz   mumkin.   Bu   sizga   murakkab   vazifalarni   kichikroq   va   sodda
vazifalarga   ajratishga   imkon   beradi,   bu   esa   dasturning   umumiy
murakkabligini keskin pasaytiradi.
Takror   foydalanish.   Funksiya   e'lon   qilingandan   so'ng,   uni   ko'p   marta
chaqirish   mumkin.   Bu   kodning   takrorlanishiga   yo'l   qo'ymaydi   va   kodni
nusxalash/joylashtirishda xatolar ehtimolini kamaytiradi. Funksiyalar boshqa dasturlarda   ham   ishlatilishi   mumkin,   bu   har   safar   noldan   yozilishi   kerak
bo'lgan kod miqdorini kamaytiradi.
Testlash.   Funksiyalar   keraksiz   kodni   olib   tashlaganligi   sababli,   uni
testlash   osonroq   bo'ladi   va   funksiya   mustaqil   birlik   bo'lgani   uchun,   uning
ishlashiga   ishonch   hosil   qilish   uchun   uni   bir   marta   sinab   ko'rishimiz   kerak,
keyin   uni   sinovdan   o'tkazmasdan   (bu   funksiyaga   o'zgartirish
kiritmagunimizcha) qayta-qayta ishlata olamiz.
Modernizatsiya.   Agar   dasturga   o'zgartirish   kiritishingiz   yoki   uning
funksiyasini   kengaytirishingiz   kerak   bo'lsa,   unda   funksiyalar   juda   yaxshi
imkoniyatdir.  Ularning  yordami  bilan  hamma  joyda  ishlashlari  uchun  ularni
bitta joyda o'zgartirishingiz mumkin.
Abstraktsiya.   Funksiyadan foydalanish  uchun  biz uning  nomini,  kirish
ma'lumotlarini,   chiqish   ma'lumotlarini   va   funksiya   qayerda   joylashganligini
bilishimiz   kerak.   Uning   qanday   ishlashini   bilishimiz   shart   emas.   Bu
boshqalar   tushunishi   mumkin   bo'lgan   kod   yozish   uchun   juda   foydalidir
(masalan,   C++   standart   kutubxonasi   va   undagi   barcha   narsalar   shu   prinsip
asosida tuzilgan).
Har   safar   kiritish   yoki   chiqarish   operatori   uchun   std::cin   yoki   std::cout
deb   nomlaganimizda,   biz   C++   standart   kutubxonasidan   yuqoridagi   barcha
tushunchalarga amal qiladigan funksiyadan foydalanamiz.
Funksiyalardan   samarali   foydalanish.   Yangi   boshlovchilar   duch
keladigan  eng  keng  tarqalgan  muammolardan  biri  bu  funksiyalarni  qayerda,
qachon   va   qanday   qilib   samarali   ishlatishni   tushunishdir.   Funktsiyalarni
yozish uchun ba'zi bir asosiy ko'rsatmalar:
1-tavsiya . Dasturda bir necha marta paydo bo'lgan kod funksiya sifatida
yaxshi   yozilgan.   Masalan,   agar   biz   xuddi   shu   tarzda   foydalanuvchidan   bir
necha marta ma'lumotlarni olsak, bu alohida funktsiyani yozish uchun ajoyib
imkoniyat. 2-tavsiya .   Biron   bir   narsani   saralash   uchun   ishlatiladigan   kod   alohida
funksiya   sifatida   yozilgan   yaxshiroqdir.   Masalan,   bizda   saralash   kerak
bo'lgan   narsalar   ro'yxati   bo'lsa,   biz   saralash   funksiyasini   yozamiz,   bu   yerda
biz saralanmagan ro'yxatni o'tkazamiz va saralangan joyni olamiz.
3-tavsiya . Funksiya bitta (va faqat bitta) vazifani bajarishi kerak.
4-tavsiya .   Agar   funksiya   juda   katta,   murakkab   yoki   tushunarsiz   bo'lib
qolsa,   uni   bir   nechta   kichik   funksiyalarga   bo'lish   kerak.   Bunga   kodni   qayta
ishlash deyiladi.

Bir va ikki o‘lchovli massiv elementlarini tartiblash, qidirish algoritmlari va ularning murakkabligini tahlil qilish asosida dastur yaratish Reja: 1. Bir va ikki o’lchovli massiv elementlarni tartiblash 2. Qidirish algoritmlari 3. Algoritmning murakkabligini tahlil qilish

Massivni saralash - bu massivdagi barcha elementlarni ma'lum tartibda joylashtirish jarayoni. Bu ko'pincha foydalidir. Masalan, pochta qutingizdagi elektron pochta xabarlari qabul qilingan vaqtga qarab ko'rsatiladi; yangi elektron pochta xabarlari sizga yarim soat, bir soat, ikki yoki bir kun oldin kelgan elektron pochta xabarlariga qaraganda ko'proq mos keladi; kontaktlar ro'yxatiga kirganingizda, ismlar odatda alifbo tartibida bo'ladi, chunki shu tarzda biror narsani topish osonroq. Ushbu holatlarning barchasi ma'lumotlarni namoyish qilishdan oldin ularni saralashni o'z ichiga oladi. Saralash qanday ishlaydi? Ma'lumotlarni saralash nafaqat odamlar uchun, balki kompyuterlar uchun ham massiv ichidan qidirishni samaraliroq qilishi mumkin. Masalan, ismlar ro'yxatida ma'lum bir ism paydo bo'lishini bilishimiz kerak bo'lgan holatni ko'rib chiqaylik. Buni bilish uchun siz massivning har bir elementini bizning qiymatimiz bilan tekshirishingiz kerak. Ko'p elementli qatorni qidirish juda samarasiz (qimmat) bo'lishi mumkin. Biroq, bizning nomlarimiz qatori alfavit bo'yicha tartiblangan deb taxmin qiling. Keyin bizning qidiruvimiz ma'noning birinchi harfi bilan boshlanadi va alifboda keyingi harf bilan tugaydi. Bunday holda, agar biz ushbu harfga yetib borsak va ismini topa olmasak, unda biz bu qatorning qolgan qismida yo'qligini aniq bilamiz, chunki biz allaqachon o'z harfimizni alifbo tartibida topshirganmiz! Hech kimga sir emaski, tartiblangan massivlar ichida yanada yaxshi qidirish algoritmlari mavjud. Oddiy algoritmdan foydalanib, biz faqat 20 ta taqqoslash yordamida aniqlangan elementni 1000000 elementlardan iborat tartibda qidirishimiz mumkin! Salbiy tomoni shundaki, massivni juda ko'p sonli elementlarga ko'ra saralash nisbatan qimmatga tushadi va bitta qidiruv so'rovi uchun amalga oshirilmaydi.

Ba'zi hollarda, qatorni saralash qidirishni keraksiz holga keltiradi. Masalan, biz talabalar orasida eng yaxshi test balini qidirmoqdamiz. Agar massiv saralanmagan bo'lsa, unda biz eng yuqori ballni topish uchun massivning har bir elementini skanerlashimiz kerak bo'ladi. Agar massiv saralangan bo'lsa, unda eng yuqori ball birinchi pozitsiyada yoki oxirgisi bo'ladi (massivni saralash uslubiga qarab: ko'tarilish yoki tushish tartibida), shuning uchun biz qidirishning umuman hojati yo'q. Tartiblash odatda qator elementlari juftlarini qayta taqqoslash va belgilangan mezonlarga mos keladigan bo'lsa, ularni almashtirish orqali amalga oshiriladi. Ushbu elementlarni taqqoslash tartibi qaysi saralash algoritmidan foydalanilganiga bog'liq. Mezonlar massivning qanday tartiblanishini belgilaydi (masalan, ko'tarilish yoki tushish tartibida). Ikki elementni almashtirish uchun biz C ++ standart kutubxonasidan std :: swap () funktsiyasidan foydalanishimiz mumkin, bu sarlavha fayli algoritmida aniqlangan. C ++ 11 da std :: swap () funktsiyasi yordam dasturining sarlavha fayliga ko'chirildi: #include <iostream> #include <algorithm> int main() {         int a = 3;         int b = 5;         std::cout << " a = " << a << ", b = " << b << '\n';         std::swap(a, b);

        std::cout << " a = " << a << ", b = " << b << '\n'; } Dasturni bajarish natijasi: a=3, b=5 a=5, b=3 O'zgartirish operatsiyasidan so'ng a va b o'zgaruvchilarning qiymatlari almashtirildi. Massivlarni tanlash usuli bo'yicha saralash Massivlarni saralashning ko'plab usullari mavjud. Massivlarni tanlov usulidan foydalanib saralash, ehtimol bu eng oson bo'lsa ham, eng sekinlaridan biri. Massivni eng kichikdan kattagacha elementlarni tanlab saralash uchun quyidagi amallarni bajaring: - 0 indeksidagi elementdan boshlab biz massivdagi eng kichik qiymatni qidiramiz. - Topilgan qiymatni nol element bilan almashtiramiz. - Massivdagi keyingi indeks uchun # 1 va # 2 bosqichlarini takrorlang (endi saralangan elementga tegmang). Boshqacha qilib aytganda, biz massivdagi eng kichik elementni qidiramiz va uni birinchi o'ringa o'tkazamiz. Keyin biz ikkinchi eng kichik elementni qidiramiz va uni birinchi kichik elementdan keyin ikkinchi holatga o'tkazamiz. Ushbu jarayon massivda saralanmagan elementlar tugamaguncha davom etadi. Ushbu algoritm 5 ta elementdan iborat massivda qanday ishlashiga misol:

{ 30, 50, 20, 10, 40 } Birinchidan , biz 0 indeksidan boshlab eng kichik elementni qidiramiz : {30, 50, 20, 10, 40} Keyin biz eng kichik elementni 0 indeksidagi element bilan almashtiramiz: {10, 50, 20, 30, 40} Endi massivning birinchi elementi saralangan, biz unga e'tibor bermaymiz. Biz keyingi eng kichik elementni qidiramiz, lekin 1 indeksidan boshlaymiz: {10, 50, 20, 30, 40} Va biz uni indeks 1dagi element bilan almashtiramiz: {10, 20, 50, 30, 40} Endi biz dastlabki ikkita elementni e'tiborsiz qoldirmoqdamiz. Ikkinchi indeksdan boshlab keyingi eng kichik elementni qidiryapsiz: {10, 20, 50, 30, 40} Va biz uni indeks 2 da element bilan almashtiramiz: {10, 20, 30, 50, 40} 3-indeksdan boshlab keyingi eng kichik elementni qidiryapsiz: