14-AMELIY
.pdf
14-ámeliy. Dinamikalıq yad penen islew. Kórsetkishler. Dinamikalıq bir ólshemli massivler. Dinamikalıq kóp ólshemli massivler. Yadtı bólistiriwshi funkciyalar.
Jumıstıń maqseti: C++ tilinde dinamikalıq yad penen islew, kórsetkishlerdi ańlatıw, járiyalaw, olar ústinde ámeller islew.
Teoriyalıq maǵlıwmatlar:
Ádette, biz ózgeriwshilerdi járiyalaǵanımızda, komplyator olar ushın yadtıń "stek" (stack) dep atalatuǵın bóleginen orın ajıratadı. Bul statikalıq yad dep ataladı, sebebi onıń ólshemi programma kompilyaciya etilgen waqıtta belgili boladı. Biraq, geyde bizge programmanıń orınlanıwı dawamında, máselen, paydalanıwshı tárepinen kirgizilgen maǵlıwmatqa qarap, ólshemi ózgerip turatuǵın yad kerek boladı. Bunday jaǵdaylarda yadtıń "dáste" (heap) dep atalatuǵın bóleginen paydalanamız.
Bul process dinamikalıq yadtı basqarıw dep ataladı.
Kórsetkish (Pointer): Bul basqa bir ózgeriwshiniń yadtaǵı adresin saqlaytuǵın arnawlı ózgeriwshi. Kórsetkishlerdi járiyalaw ushın ózgeriwshi atınıń aldına juldızsha (*) belgisi qoyıladı. Mısalı: int *ptr;
new operatorı: Dinamikalıq túrde yadtan orın ajıratıw ushın qollanıladı. Ol ajıratılǵan yad blogınıń baslanǵısh adresin qaytaradı. Bul adres kórsetkishke menshiklenedi.
delete operatorı: new operatorı arqalı ajıratılǵan yadtı bosatıw ushın paydalanıladı. Eger dinamikalıq ajıratılǵan yad bosatılmasa, "yadtan sızıp shıǵıw" (memory leak) júz beredi, yaǵnıy programma paydalanbay atırǵan yadtı iyelep turadı. Massivler ushın delete[] operatorı qollanıladı.
Ámeliy bólim:
1-Mısal: Kórsetkishler hám ápiwayı dinamikalıq ózgeriwshi
Bul mısalda biz bir pútin san ushın dinamikalıq yad ajıratamız, oǵan mánis beremiz hám jumısımız pitken soń yadtı bosatamız.
#include <iostream>
using namespace std;
int main() {
// int tipindegi ózgeriwshiniń adresin saqlaw ushın kórsetkish járiyalaw
int *ptr;
//'new' operatorı arqalı bir pútin san ushın yadtan orın ajıratıw
//hám onıń adresin 'ptr' kórsetkishine menshiklew ptr = new int;
if (!ptr) {
cout << "Yad ajıratıwda qátelik júz berdi!"; return 1;
}
// Kórsetkish arqalı yadtaǵı orınǵa mánis beriw *ptr = 100;
cout << "Dinamikalıq ózgeriwshiniń mánisi: " << *ptr << endl;
cout << "Yadtaǵı adresi: " << ptr << endl;
// 'delete' operatorı arqalı ajıratılǵan yadtı bosatıw
delete ptr;
cout << "\nYad bosatılǵannan keyin kórsetkishti nolge teńlestirgen durıs:" << endl;
ptr = nullptr; // yamasa NULL
cout << "Kórsetkishtiń házirgi mánisi: " << ptr << endl;
return 0;
}
2-Mısal: Dinamikalıq bir ólshemli massiv
Programma orınlanıp atırǵanda paydalanıwshıdan massivtiń ólshemin sorap, sol ólshemge sáykes dinamikalıq massiv jaratamız.
#include <iostream>
using namespace std;
int main() { int n;
cout << "Massiv ólshemin kirgiziń: "; cin >> n;
// double tipindegi n elementli massiv ushın dinamikalıq yad ajıratıw
double *arr = new double[n];
if (!arr) {
cout << "Massiv ushın yad ajıratıwda qáte júz berdi!";
return 1;
}
//Massivti elementler menen toltırıw for (int i = 0; i < n; i++) {
arr[i] = i * 1.5;
}
//Massiv elementlerin ekranǵa shıǵarıw
cout << "Dinamikalıq massiv elementleri:" << endl; for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
//Massiv ushın ajıratılǵan yadtı bosatıw
//Massivler ushın [] qosıp jazıladı! delete[] arr;
arr = nullptr;
return 0;
}
3-Mısal: Dinamikalıq eki ólshemli massiv (matritsa)
Eki ólshemli massivti dinamikalıq jaratıw biraz quramalılaw. Ol kórsetkishler massivin (hár bir elementi qatarǵa silteme) jaratıw arqalı ámelge asırıladı.
#include <iostream>
using namespace std;
int main() {
int qatarlar, baganalar;
cout << "Matritsa qatarları sanın kirgiziń: "; cin >> qatarlar;
cout << "Matritsa baǵanaları sanın kirgiziń: ";
cin >> baganalar;
//1. Qatarlarǵa silteme beriwshi kórsetkishler massivin jaratıw
int **matrix = new int*[qatarlar];
//2. Hár bir qatar ushın bólek yad ajıratıw for (int i = 0; i < qatarlar; i++) {
matrix[i] = new int[baganalar];
}
//Matritsanı toltırıw hám ekranǵa shıǵarıw cout << "Dinamikalıq matritsa:" << endl; for (int i = 0; i < qatarlar; i++) {
for (int j = 0; j < baganalar; j++) { matrix[i][j] = i + j; // Mısal ushın
ápiwayı mánis beriw
cout << matrix[i][j] << "\t";
}
cout << endl;
}
//Yadtı bosatıw (keri tártipte)
//1. Hár bir qatar ushın ajıratılǵan yadtı bosatıw for (int i = 0; i < qatarlar; i++) {
delete[] matrix[i];
}
//2. Kórsetkishler massivi ushın ajıratılǵan yadtı bosatıw
delete[] matrix; matrix = nullptr;
return 0;
}
Ózbetinshe orınlaw ushın tapsırmalar:
1.Paydalanıwshıdan qansha studenttiń maǵlıwmatın kirgiziwin soraytuǵın programma dúziń. Hár bir studenttiń jasın saqlaw ushın int tipindegi dinamikalıq massiv jaratıń. Studentlerdiń jasın kirgizip, olardıń ortasha jasın esaplap shıǵarıń. (Yadtı bosatıwdı umıtpań!).
2.Paydalanıwshı tárepinen kirgizilgen N hám M ólshemlerine iye bolǵan float tipindegi dinamikalıq eki ólshemli massiv jaratıń. Massivti tosınnan sanlar menen toltırıń hám onıń barlıq elementleriniń qosındısın tabıń.
3.Bir ólshemli dinamikalıq massivti kirgiziń. Keyin, sol massivtiń ishinen tek jup sanlardı kóshirip alıp, jańa dinamikalıq massiv jaratatuǵın programma dúziń hám nátiyjeni ekranǵa shıǵarıń. (Bunda eki dinamikalıq massivten paydalanıladı).
Teoriyalıq bólim (Kórsetkishler): Programma tekstinde ózgeriwshi járiyalanǵanda, kompilyator ózgeriwshige yadtan orın ajıratadı. Basqasha aytqanda, programma kodı yadqa júklengen waqıtta berilgenler ushın, olar jaylasqan segmenttiń basına qarata jıljıwı, yaǵnıy salıstırmalı adresti anıqlaydı hám obyekt kod payda etiwde ózgeriwshi ushıraǵan orınǵa onıń adresin jaylastıradı.
Ulıwma alǵanda, programmadaǵı turaqlılar, ózgeriwshiler, funkciyalar hám klass obyektler adreslerin yadtıń óz aldına orında saqlaw hám olar ústinen ámeller orınlawı múmkin. Mánisleri adres bolǵan ózgeriwshilerge kórsetkish ózgeriwshiler delinedi.
Kórsetkish úsh túrde bolıwı múmkin:
-qandayda bir obyektke, atap ótsek ózgeriwshige kórsetkish;
-funkciyaǵa kórsetkish;
-void kórsetkish.
Kórsetkishtiń bul qásiyetleri onıń qabıl etiliwi múmkin bolǵan mánislerde parıqlanadı.
Kórsetkish álbette qandayda bir tipke baylanısqan bolıwı kerek, yaǵnıy ol kórsetken adreske qandayda bir mánis jaylasıwı múmkin hám bul mánistiń yadta qansha orın iyelewi aldınnan belgili bolıwı shárt.
Ámeliy bólim:
C++ tilinde kórsetkishler basqa ózgeriwshilerdiń yad adreslerin saqlaytuǵın ózgeriwshiler bolıp tabıladı.
C++ tilinde adress
Eger bizde ózgeriwshi programmamızda var bolsa, &var onıń adresin yadımızda beredi. Mısalı,
1-mısal: C++ tilinde ózgeriwshi adreslerdi basıp shıǵarıw
#include <iostream> using namespace std;
int main()
{
//ózgeriwshilerdi járiyalaw int var1 = 3;
int var2 = 24; int var3 = 17;
//var1 shıǵarıw adresi
cout << "var1 adresi: "<< &var1 << endl;
// var2 shıǵarıw adresi
cout << " var2 adresi: " << &var2 << endl;
// var3 shıǵarıw adresi
cout << " var3 adresi: " << &var3 << endl;
}
Nátiyje:
var1 adresi: 0x7ffeff6177dc
var2 adresi: 0x7ffeff6177d8
var3 adresi: 0x7ffeff6177d4
C++ kórsetkishleri
Joqarıda aytılǵanday kórsetkishler mánislerdi emes, adreslerdi saqlaw ushın qollanıladı. Kórsetkishlerdi tómendegishe járiyalaymız.
int *pointVar;
Mine biz int tipindegi pointVar kórsetkishti járiyaladıq. Sonday-aq kórsetkishlerdi keyingi usıl menen járiyalay alamız.
int* pointVar; // preferred syntax
Kórsetkishlerdi járiyalawdıń taǵı bir mısalın alayıq.
int* pointVar, p;
Mine biz pointVar kórsetkishti járiyaladıq. hám ádettegi ózgeriwshi.
Esletpe: * operatorı kórsetkishlerdi járiyalaw ushın maǵlıwmatlar tipinen keyin paydalanıladı.
Kórsetkishlerge adreslerdi tayınlaw
Kórsetkishlerge adreslerdi qalay tayınlay alamız:
int* pointVar, var; var = 5;
// avr adresin pointVar kórsetkishine tayınlań pointVar = &var;
Bunda var 5 ózgeriwshige tayınlanadı. Al. var adreske pointVar kodı bar kórsetkish pointVar = &var tayınlanadı.
Kórsetkishlerden paydalanıp adresten mánis alıń
Kórtsetkish penen kórsetilgen mánisti alıw ushın biz * operatorlardı qollanamız. Mısalı:
int* pointVar, var; var = 5;
//var adresin pointVar-ǵa tayınlań pointVar = &var;
//pointVar arqalı kórsetilgen qatnas mánis
cout << *pointVar << endl; // Output: 5
Joqarıdaǵı kodta var adresi tayınlanǵan pointVar. *pointVar adreste saqlanǵan mánisti alıw ushın qollandıq. * kórsetkishleri menen paydalanılǵanda, ol silteme operatorı dep ataladı. Ol kórsetkishte jumıs isleydi hám kórsetkishte saqlanǵan adresi menen kórsetilgen mánisti beredi. Bul, *pointVar = var.
2-mısal: Kórsetkishtiń jumısı:
#include <iostream> using namespace std; int main() {
int var = 5;
//kórsetkishtiń ózgeriwshi mánisin járiyalaw int* pointVar;
//var-dıń adresi
pointVar = &var;
//var-dı basıp shıǵarıw mánisi cout << "var = " << var << endl;
//var-dı basıp shıǵarıw mánisi
cout << "Address of var (&var) = " << &var << endl
<<endl;
//pointVar kórsetkishin basıp shıǵarıw cout << "pointVar = " << pointVar << endl;
//pointVar points adresiniń mazmunın basıp shıǵarıw
cout << "Content of the address pointed to by pointVar (*pointVar) = " << *pointVar << endl;
return 0;
}
C++ te kórsetkishler menen jumıs islew.
Kórsetkishlerdiń adresin ózgertiw
int var = 5; int* pointVar;
//assign address of var pointVar = &var;
//change value at address pointVar *pointVar = 1;
cout << var << endl; // Output: 1
3-mısal: Kórsetkishler menen kórsetilgen mánislerdi ózgertiw
#include <iostream> using namespace std; int main() {
int var = 5; int* pointVar;
//store address of var pointVar = &var;
//print var
cout << "var = " << var << endl;
// print *pointVar
cout << "*pointVar = " << *pointVar << endl << endl;
cout << "Changing value of var to 7:" << endl;
//change value of var to 7 var = 7;
//print var
cout << "var = " << var << endl;
// print *pointVar
cout << "*pointVar = " << *pointVar << endl << endl;
cout << "Changing value of *pointVar to 16:" << endl;
//change value of var to 16 *pointVar = 16;
//print var
cout << "var = " << var << endl;
// print *pointVar
cout << "*pointVar = " << *pointVar << endl; return 0;
}
