Misal 1. #include using name space std;
//max- funksiyanın prototipi
int max (int, int);
//əsas funksiya
int main ( )
{int a,b,c,d;
cout <<”\n a,b,c-ni daxil edin”;
cin >>a>>b>>c;
d=max(max(a,b),c);
cout<<”\n max(a,b,c)=”<}
\\max funksiyanın təyini
int max(int x, int y)
{if x>y return x;
else return y;}
} Burada funksiyanın prototipindən istifadə olunmuşdur. Funksiyanın prototipi dedikdə funksiyanın adı, tipi, formal parametrlərin tipi göstərilən təsviri başa düşülür. Bu təsvirdən istifadə etməklə funksiyaya düzgün müraciət edilir. Funksiyanın prototipində formal parametrlərin adını göstərmək vacib deyil. Lakin formal parametrlərin adı göstərilə də bilər:
int max(int x, int y);
Əsas funksiyanın daxilində də digər obyektlərin təsviri ilə yanaşı funksiyanın prototipini də vermək olar. Belə təsvir görünmə oblastı ilə əlaqədardır və bir qədər sonra izah olunacaqdır.
49.Başlıq faylları
C++ dilinin standart kitabxanası bir neçə hissələrdən ibarətdir və bu hissələrin hər birinə bir başlıq faylı uyğundur. Başlıq fayllarında funksiyaların prototipləri yerləşir. Bu fayllarda funksiyaların istifadə etdiyi müxtəlif sabit və dəyişənlərin təyini də yerləşir. Aşağıdaki cədvəldə C++ dilində proqrama qoşula bilən bəzi başlıq fayllarının adları və onların funksiyaları göstərilmişdir.
Standart kitabxananın başlıq fayllarının adları
İzah
Proqramın otlodkasına kömək edən əlavə diaqnostika üçün məlumatlar yerləşir. Köhnə versiyası:
Simvolların müəyyən xassələrini yoxlayan və böyük hərfləri kiçik hərflərə və tərsinə çevirən funksiyaların protoptipləri yerləşir. Digər versiyası:
Verilən sistem üçün sürüşkən nöqtəli ədədlərin son ölçüsünü müəyyən edir. Digər versiyası
Sistemə qoyulan ümumi məhdudluq yerləşir. Digər versiyası:
Riyazi kitabxana funksiyalarının prototipləri yerləşir. Digər versiyası:
Ədədləri mətnə çevirən və tərsinə, təsadüfi ədədləri generasiya edən və digər əhəmiyyətli əməliyyatları yerinə yetirən funksiyaların prototipləri yerləşir. Digər versiya:
C-stilində sətirlərlə işləmək üçün olan funksiyaların prototipləri yerləşir. Digər versiyası:
Vaxt və tarixlə işləmək üçün olan tiplər və funksiyaların prototipləri yerləşir. Digər versiyası:
Standart giriş və çıxış funksiyalarının prototipləri yerləşir. Digər versiyası:
Verilənlər axınını formatlaşdırmağa imkan verən əməliyyatlar üçün olan funksiyaların prototipləri yerləşir. Digər versiyası:
Diskdə olan faylların oxunması və ya faylların diskə yazılması üçün olan funksiyaların prototipləri yerləşir. Digər versiyası:
Standart kitabxananın başlıq fayllarının çoxunun istifadə etdiyi sinif və funksiyalar yerləşir.
-mətn rejimində ekrana çıxışı idarə etmək üçün olan funksiyaların prototipləri yerləçir. Məsələ, ekranı təmizləmək: clrscr. və s.
İstifadəçi özünə lazım olan başlıq faylı yarada bilər. Belə fayllar .h və .hpp və ya .hxx tipinə malik olurlar. Proqramçı tərəfindən təyin olunan başlıq faylları da proqrama #include direktivi vasitəsi ilə qoşulur. Məsələ math.h-başlıq faylı proqrama #include -direktivi ilə proqramın əvvəlində yazmaqla proqrama qoşulur.
50.Kitabxana funksiyalarından istifadə edilməsi
Kitabxana funksiyaları ayrıca fayllarda saxlanılan köməkçi funksiyalardır. Proqramçı öz xüsusi kitabxana funksiyalarını da yarada bilər. Standart funksiyalardan istifadə etmək üçün uyğun kitabxanadan başlıq fayllarını proqrama qoşmaq lazımdır. Bu prosessor önü vasitə olan #include direktivi vasitəsi ilə yerinə yetirilir. Bu direktivdə başlıq faylının adı yazılır. Məsələ,
#include və ya
#include Bu fayllarda kitabxana funksiyalarının prototipləri yerləşir.
Translyasiya mərhələsinin əvvəlində funksiyanın prototipləri əsas funksiyadan əvvəl qoyulur və bundan sonra kompilyator funksiyalara müraciətin düzgünlüyünə nəzarət edə bilər. Funksiyaları realizasiya edən proqramın özü obyekt kod şəklində olur və əsas proqrama əlaqələrin redaktə olunması (kompanovka mərhələsində) mərhələsində qoşulur.
//Qabarıq dördbucaqlının sahəsi
#include using namespace std;
#include #include typedef double D; //double tipinin adlandırılması
D Line(D,D,D,D); // Line funksiyasının prototipi
D Heron(D,D,D,D,D,D); //Heron funksiyasının prototipi
//əsas funksiya
int main( )
{D x1,y1, x2,y2, x3,y3, x4,y4, S1234;
clrcr ();
cout <<”x1=”; cin>>x1; cout<<”y1=”;cin>>y1;
cout<<”x2=”; cin>>x2; cout<<”y2=”;cin>>y2;
cout<<”x3=”; cin>>x3; cout<<”y3=”;cin>>y3;
cout<<”x4=”; cin>>y4; cout<<”y4=”; cin>>y4;
S1234=Heron(x1,y1, x2,y2, x3,y3)+
Heron(x1,y1, x3,y3, x4,y4);
Cout<<”Dördbucaqlının sahəsi=”<}
//Line funksiyasının təyini
D Line (D a, D b, D c, D d)
{return sqrt ((a-c)*(a-c)+(b-d)*(b-d));}
//Heron funksiyasının təyini
D Heron (D a1, D a2, D b1, D b2, D c1, D c2)
{D p, ab, bc, ca;
ab=Line(a1, a2, b1, b2); bc=Line(b1, b2, c1, c2);
ca=Line(c1, c2, a1, a2); p=(ab+bc+ca)/2;
return sqrt (p*(p-ab)*(p-bc)*(p-ca));
}
Bu proqramda üç standart kitabxanadan-iostream, math.n, conio.h.-başlıq fayllarından istifadə edilmişdir. Bunlardan ikisi ilə artıq biz tanışıq.
Üçüncüsü (conio.h)-isə mətn rijemində ekrana çıxışı idarə etmək üçündür (Pascal dilində crt-moduluna oxşardır). Proqramda bu kitabxanadan clrscr( )-ekranı təmizləyən funksiyasından istifadə edilmişdir.
Göstərilən proqramda yeni bir element də vardır. Bu
typedef double D;-sətridir.
typedef işçi sözü tipin spesfikatorudur və tipi işarə etmək üçün tipin adının sinonimini təyin edir. Nəticədə, baxılan proqramda double sözü əvəzinə bir dənə D-hərfi yazılır. Göstərilən təsvir qlobaldır və həm əsas funksiyada, həm də köməkçi funksiyalarda təsir oblastlarına malikdir.
Bu proqramda bir cəhətə də fikir verək. Heron funksiyasında Line funksiyasına müraciət edlir. Əsas funksiyadan isə Heron funksiyasında müraciət edilir. Kompilyator üçün vacibdir ki, müraciət edən funksiyadan əvvəl ya müraciət edilən proqramın prototipi və ya özü təyin edilsin. Ona görə də proqramda Line funksiyasının prototipini götürsək səhv alınmaz. Lakin Line və Heron funksiyalarının təyin olduğu yerləri dəyişsək kompilyator səhv haqqında məlumat verər.
51.Funksiyaların rekursiv olaraq təyini. Rekursiya anlayışı
C++ dilində də funksiyaları rekursiv olaraq da təyin etmək olar. Özündən özünə müraciət edən funksiya rekursiv olaraq təyin olunan funksiya adlanır. Rekursiv funksiyalara misallar:
n!= n=
və s.
Fibonaççi ədədləri; F =F +F , n=2,3, ... F =F =1.
Rekursiv məsələ ümumi halda bir neçə mərhələyə bölünür. Məsələnin həlli üçün rekursiv funksiyaya müraciət edilir. Bu funksiya baza məsələ adlanan sadə məsələni necə həll etməyi “bilir”. Əgər bu funksiyaya daha mürəkkəb məsələnin həlli üçün müraciət edilərsə, onda o, bu məsələni iki hissəyə bölür. Bu hissələrdən birini funksiya həll etməyi bacarır, digər hissəni isə həll etməyi bacarmır. Rekursiyanın yerinə yetirilə bilən olması üçün axırıncı hissə ilkin məsələyə oxşar olmalı və ilkin məsələ ilə müqayisədə daha sadə olmalıdır. Yeni alınan məsələ ilkin məsələ ilkin məsələyə oxşar olur və bu məsələni həll etmək üçün funksiya yenidən özünə müraciət edir. Bu rekursiv müraciət və ya rekursiv addım adlanır. Rekursiv addım return işçi sözü ilə əlaqədardır. Belə ki, onun nəticəsi məsələnin həll oluna bilən hissəsi ilə birləşdirilir və son nəticə formalaşdırılır. Bu son nəticə funksiyaya ilkin müraciət olunan yerə qaytarılır. Rekursiv addım o vaxta qədər davam edir ki, həlli trivial olan baza məsələ alınsın.
n-ə qədər ədələrin faktoriallarının rekursiv funksiya şəklində hesablanmasına baxaq.
# include < iostream>
using namespace std;
unsigned long int factorial(unsigned long);
// funksiyanın prototipi
int main( )
{
// 10-a qədər ədələrin faktoriallarının hesablanması
for (int i=0; i<=10; i++)
cout<< setw(2)<return 0;
}
// Factorial funksiyasının rekursiv təsviri
unsigned long int factorial (unsigned long n)
{
//baza halı
if (n<=1)
return 1;
//rekursiv addım
else
return n*factorial(n-1);
} // faktorial funksiyasının sonu
52.Fibonaççi ədədlər ardıcıllıgının rekursiya ilə alınması
Fibonaççi ədədlər ardıcılığı 0 və 1-lə başlayır və hər bir sonrakı hədd əvvəlki iki həddin cəminə bərabər olur. Fibonaççi ədədlər ardıcıllığı;
0, 1, 1, 2, 3, 5, 8, 13, 21, 34,… .
Fibonnaççi funksiyası vasitəsi ilə Fibonaççi ədədlər ardıcıllığının rekursiv olaraq alınması proqramını aşağıdakı kimi yazmaq olar;
# include using namespace std;
int main()
{
unsigned long result,n ;
cout<<”tam ədədi daxil edin:”;
cin>>n;
//daxil edilən ədəd üçün fibonaççi ədədlərinin hesablanması
result=Fibonaççi(n);
//nəticənin çıxışı
cout<<”Fibonaçi(“<return 0;
}
//fibonaççi funksiyasının rekursiv təyini
unsigned long fibonaççi (unsigned long n)
{//baza halı
if (n==0//n==1)
return n;
//rekursiv addım
else
return fibonaççi (n-1)+fibonaççi(n-2);
}
//fibonaççi funksiyasının sonu
53.Qlobal dəyişənlər vasitəsi ilə qiymətlərin funksiya daxilinə ötürülməsi
Əgər dəyişən blokun daxilində təsvir olunarsa, onda bu dəyişən lokal dəyişən adlanır və blokdan kənarda yerləşən bloklarda lokal dəyişənlərdən istifadə etmək olmaz. Blok öz işini qurtardıqdan sonra lokal dəyişənlərdəki qiymətlər də saxlanılmır. Əgər dəyişənlər blokdan xaricdə və proqramın mətnində əvvəlcədən təsvir olunarsa belə dəyişənlərə qlobal dəyişənlər deyilir. Qlobal dəyişənlərdən blokların daxilində də istifadə etmək olar. Məsələ,
double x;
int fun( )
{int y; …}
void main ( )
{float y; …}
x-dəyişəni fun və main funksiyalarına nəzərən qlobal dəyişəndir və onların daxilində istifadə oluna bilər. Fun və main funksiyalarının hər ikisi eyni adlı y-dəyişəninə malikdirlər. Bu lokal dəyişənlərin bir-biri ilə əlaqəsi yoxdur və müxtəlif kəmiyyətlərdir. Bu lokal dəyişənlər ancaq x-qlobal dəyişəni vasitəsi ilə bir-biri ilə əlaqələndirilə bilər.
Funksiyalara müraciət zamanı qiymətlərin ötürülməsi həm faktiki parametrlər, həm də qlobal dəyişənlər vasitəsi ilə ola bilər. Aşağıda üç ədəddən ən böyüyünün tapılması proqramı bu mexanizmdən istifadə edərək tərtib edilmişdir.
#include using namespace std;
int z; //Qlobal dəyişənin təsvir
void max (int x, int y)
{if(x>y)z=x; else z=y;}
void main ( )
{int a,b,c;
cout <<”a=”; cin>>a;
cout<<”b=”; cin >>b;
cout<<”c=”; cin >>c;
max(a,b);
max(z,c);
cout<<”max=”<}
max funksiyasının yerinə yetirilməsinın nəticəsi z-qlobal dəsyişənində qalır. Lokal dəyişənlər z-qlobal dəyişəni vasitəsi ilə əlaqələndirilir. Ona görə də funksiyaya 2-ci dəfə müraciət edən zaman z-qlobal dəyişəni həm arqument, həm də nəticə rolunu oynayır.
54.Yaddaş sinifləri
Proqramda istifadə olunan hər bir dəyişənə yaddaşda yer ayrılır. Dəyişənlər üçün yaddaşda yer ya kompilyasiya mərhələsində, ya da yerinə yetirilmə mərhələsində ayrılır. Dəyişənlərə ayrılan yaddaşın 5 spesifikatoru müvcuddur:
avtomatik (avto-açar sözü);
xarici (extern-açar sözü);
statik (static-açar sözü);
registr yaddaş (register-açar sözü);
mutable-siniflərlə işləyəndə istifadə olunur.
Qlobal dəyişənə yaddaşın xarici bölümündə yer ayrılır. Bu maqnit diskdə olan xarici yaddaş deyildir. Extern sinfinə malik olan operativ yaddaşdır.
Qlobal dəyişənləri ya blokdan xaricdə və ya blokun daxilində extern sözünün köməyi ilə təsvir etmək lazımdır. Bu hal o zaman istifadə olunur ki, proqram modulu ayrıca faylda yerləşir və ayrıca kompilyasiya olunur.
Tutaq ki, əsas və köməkçi funksiyalar ayrı-ayrı fayllarda yerləşmişdir:
fayl 1: fayl 2: - - - - void func ( )
int var; {extern int var;
void main ( ) var=10*var;
{var=5; }
func ( );
cout <}
Burada əsas funksiya ilə koməkçi func funksiyası arasındaki qiymətlərin dəyişməsi var qlobal dəyişəni vasitəsi ilə olur və bu dəyişənə yer kompilyasiya vaxtı yaddaşın xarici bölümündə (extern sinfində) ayrılır.
Blok daxilində elan olunan lokal dəyişənlərə yer bloka müraciət zamanı avtomatik yaddaşda stek prinsipi ilə ayrılır və blokdan çıxan zaman ayrılan yer azad olunur. Bu halda avto-sözü susma prinsipinə görə başa düşülür və yazmaq vacib deyildir. Statik yaddaş blok daxilində lokallaşdırılır, avtomatik yaddaşdan fərqli olaraq blokdan çıxan zaman azad olunmur. Bloka təkrar daxil olan zaman statik dəyişənlər əvvəlki qiymətlərini saxlayırlar. Statik dəyişənlərin təsvirinə aid misal:
f( )
{static int a=10; …}
Statik dəyişənlər başlanğıc qiyməti ancaq bir dəfə-bloka daxil olan zaman alırlar. Əgər dəyişənlərə başlanğıc qiymətlər verilməsə, onlar “0”-qiyməti alırlar. Statik dəyişənlərdən adətən bloka daxil olmalarının sayını hesablamaq üçün istifadə edilir.
Registr yaddaş lokal dəyiənlərə ayrılır. Proqramda bütün əməliyyatların yerinə yetirilməsində praktiki olaraq registrlə iştirak edirlər. Registr yaddaşdan istifadə olunmasını kompilyatorlar həll edir.
Aşağıdaki misalda dəyişənlərin təsvirinin müxtəlif üsulları nümayış etdirilmişdir:
int var; //Var xarici(qlobal) dəyişənin təsviri
int main ( )
{extern int var; //eyni var-qlobal dəyişənin təsviri
…
}
{… //Buradan var dəyişəni görünür, var1-görünmür
}
int var1; //Var1-ın qlobal təsviri
func3 ( )
{int var; //Burada var-lokal dəyişəndir
//Var1-lokal dəyişəni görünür
}
func4 ( )
{auto int var1; //Var1-lokal dəyişəndir
//Var-qlobal dəyişəni görünür}
55.İdentifikatorların təsir oblastları
İdentifikatorun təsir oblastı proqramın elə bir hissəsidir ki, həmin hissədən identifikatora müraciə etmək mümkündür. Məsələ, blok daxilində təsvir olunan lokal dəyişənə ancaq bu blokdan və ya bu bloku daxilinə alan bloklardan müraciət etmək mümkündür. İdentifikatorların dörd təsir oblastları vardır:
-“funksiya” təsir oblastı;
-“fayl” təsir oblastı;
-“blok” təsir oblastı;
-“funksiyanın prototipi” təsir oblastı:
İstənilən funksiyanın xaricində təsvir olunan identifikator “fayl” tipli təsir oblastına malikdir. Belə identifikator onun təyin olunduğu nöqtədən başlayaraq faylın sonuna qədər olan bütün funksiyalara məlumdur. Qlobal dəyişənlər və funksiyaların xaricində təsvir olunan funksiyaların prototipləri “fayl” tipli təsir oblastlarına malikdirlər. Nişanlar (özündən sonra: qoyulan identifikatorlar) “funksiya” tipinə malik olan yeganə identifikatorlardır. Nişanlar switch və goto operatorlarında istifadə olunur. Nişanları funksiyanın daxilində istifadə etmək olar, ancaq funksiyadan xaricdən ona müraciət etmək olmaz.
Blokun daxilində təsvir olunan identifikatorlar “blok” tipli təsir oblastına malikdirlər. Lokal dəyişənlər və funksiyaların parametrləri “blok” tipli təsir oblastlarına malikdir. Əgər bloklar bir birinə daxil olarsa və eyni ada malikdirsə, onda xarici blokda təsvir olunan identifikator daxili blok yekunlaşana qədər “görünmür”. Bu onu bildirir ki, daxili blok yerinə yetirildikdə ancaq öz lokal dəyişənlərini “görür”.
Static tipli lokal dəyişənlər də “blok” təsir oblastına malik dəyişənlərdir. “Prototip” tipli təsir oblastına malik yeganə identifikatorlar funksiyaların prototipində göstərilən parametrlərdir. Funksiyaların prototipində parametrlərin adlar deyil, tipləri göstərilir. Əgər parametrlərin adları göstərilərsə bu adlar kompilyator tərəfindən nəzərdən atılır. Ona görə də funksiyaların prototiplərində göstərilən parametrlərdən təkrar olaraq proqramın digər yerlərində iki mənalılıqdan qorxmadan istifadə etmək olar.
56.Parametirsiz funksiyaların təşkili
C++ dilində funksiyanın parametrlərinin siyahısı boş olarsa bu hissə ya dairəvi mötərizənin işərisində heç bir parametr yazılmır və ya void yazılır.
Məsələ, void print( );
yazılarsa print funksiyası heç bir arqument tələb etmir və qiymət qaytarmır. Aşağıdaki proqramda arqument tələb etməyən funksiyaların təşkili qaydası nümayış etdirilmişdir.
//Arqumentsiz funksiyanın təşkili
#include using namespace std;
void function1( ); //funksiyanın prototipi
void function2( ); //funksiyanın prototipi
int main ( )
{
function1( ); //function1-funksiyasına müraciət
function2( ); //function2-funksiyasına müraciət
return 0;
}
//function1-də arqumentlərin siyahısı boşdur və bu
//funksiya heç bir arqument tələb etmir
Void function1 ( )
{
cout<<”function1-heç bir arqument qəbul etmir”<}
//function2-arqumentlərin siyahısında void-dən istifadə
//olunur və bu funksiya da heç bir arqument tələb etmir.
Void function2(void)
{
cout<<”function2-heç bir arqument qəbul etmir”<}
Nəticə:
function1-heç bir arqument qəbul etmir
function2-heç bir arqument qəbul etmir
C-dilində arqumentsiz funksiya C++ dilindən fəqrlidir. Belə ki, C-dilində arqumentlərin boş siyahısı olduqda funksiyanın tələb etdiyi istənilən arqumenti funksiya daxilində ötürmək olar. Bu halda C++ dilində proqramın kompilyasiyası zamanı sintaksis səhv alınar. C++ dilində arqumentlərin siyahısı boş olduqda funksiya arqument tələb etmir.
57.İnline funksiyası