Комерциялық емес акционерлік қоғам

 Алматы энергетика және байланыс институты

 Компьютерлік технологиялар кафедрасы

 

 

 

ОБЪЕКТІГЕ  БАҒДАРЛАНҒАН ПРОГРАММАЛАУ

 580703 - «Ақпараттық жүйелер» мамандығының

барлық оқу түрінің студенттері үшін зертханалық жұмыстарды орындауға арналған әдістемелік нұсқаулар 

 

 

 

Алматы 2010 

ҚҰРАСТЫРУШЫ: Т.С. Бимағамбетов С++ тіліндегі объектіге бағдарланған программалау. 580703 – «Ақпараттық жүйелер» мамандығының барлық оқу  түрлерінің студенттері үшін зертханалық жұмыстарды орындауға арналған әдістемелік нұсқаулар. Алматы: АЭжБИ, 2010. – 14 б. 

Зертханалық жұмыс 2006 жылы институт басылымынан шыққан «Объектіге бағдарланған программалау» әдістемелік нұсқаудың жалғасы болып табылады. Нұсқауда библиотека стандартының шаблоны (Standard Template Library, STL) негіздері берілген, олар контейнер кластары, алгоритмдер мен итераторлар.

Әрбір жұмыста оның қысқаша теориясы,  орындалу тәртібі мен бақылау сұрақтары берілген, сонымен қатар тақырыпқа сай прогамманы құру мысалдары келтірілген.

 

КІРІСПЕ 

         Әдістемелік зертханалық нұсқауда С++ тілінің библиотека стандартының бір бөлігін құрайтын библиотека стандартының шаблоны (Standard Template Library, STL) оның негіздері: контейнер кластары, алгоритмдер мен итераторлар беріліп отыр.  Деректерді сақтауда контейнер кластары тізім (списки), векторлар, жиындар (множество) т.б. құрылымдар қолданады. Алгоримдер кондейнерлерді операциялармен жабдықтап, ал итераторлар оның элементтерін алу жолдарын қамтамасыз етеді. STL компонентері стандарттық деректер типтерімен қатар басқада жаңа кластар объектілерін мен алгоритмдерін қолдана алады. Сондықтан динамикалық массивтерді, байланыс тізімдерін, сұраптауда т.б. элементтермен жұмыс жасағанда олардың программаларын жеке түрде құруын қажет етпейді. Оның орнына бағдарлама құрушы керекті контейнерлерді таңдап алып, соған сай әдістер мен алгоритмді қолданады.

         STL компоненттерін қолданғанда #include директивасы арқылы бағдарламаның басында жазылуға тиіс. Мысалы векторлармен жұмыс істегенде  #include <vector>.

Нұсқауда жұмыстың міндеті, қысқаша теориясы, орындалу тәртібі мен бақылау сұрақтары берілген, сонымен қатар тақырыпқа сай бағдарламаны құру мысалдары келтірілген.

Сабаққа жіберілу алдында студент зертханалық жұмысты мәтінін жазып келіп  (немесе әдістемелік нұсқау болуы керек), жұмыстың міндетін, қысқаша теориясына шолу жасап, бақылау сұрақтарына жауап беру керек.   

 

№8 зертханалық жұмыс. Контейнерлер.Тізбектелген контейнерлер

 

Жұмыс мақсаты- стандартты үлгілер кітапханасымен танысу. Контейнерлермен жұмыс.

 

8.1. Жұмыстың тәсілі

 

8.1.1. Стандартты үлгілер кітапханасы (STL)

 

С++ тілінде контейнерлер класына арналған, өзіндік кітапхана бар. Ол стандартты үлгілер кітапханасы деп аталады (Standard Template Library,  STL).STL  контейнерлер, алгоритмдер және итераторлардан құралған.

 

Контейнерлер  дегеніміз – мәліметтерді сақтауды ұйымдастырудың тәсілі. Әр бір контейнер типінің элементтерімен (объектілерімен) жұмыс жасау тәсілдері, контейнер типіне сәйкес контейнерлік класста анықталған. Олар контейнерде сақталған объектілердің нақты типіне тәуелді емес. Сол себепті контейнердің бір түрін әртүрлі типті объектілермен жұмыс жасауға және сақтауға қолдануға болады. Бұл үлгілер класының көмегімен жүзеге асады.

 

8.1.1 Кесте

Контейнер

Мінездемесі

Артықшылығы мен кемшілігі

Массив

Бекітілген мөлшер

Индекс бойынша тез кездейсоқ рұқсат.

Мәліметтерді ортасына жай қою (алып тастау).

Мөлшер программалар орындалу барысында өзгертілмейді

Вектор

Қайтадан реттелетін, кеңейтілетін массив

Индекс бойынша тез кездейсоқ рұқсат.

Мәліметтерді соңына тез қою (алып тастау).

Мәліметтерді ортасына жай қою(алып тастау).

 

Тізім

Байланысқан тізімге ұқсас

Мәліметтерді кез келген жерге тез қою (алып тастау). Екі шетіне де тез рұқсат.

Жай кездейсоқ рұқсат.

 

Екі жақты рұқсатпен кезек

Вектор сияқты, тек рұқсат екі шетінен

Тез кездейсоқ рұқсат.

Мәліметтерді ортасына тез қою (алып тастау).

Мәліметтерді соңына немесе басына жай қою (алып тастау).

 

Контейнерлерді қолдану программалардың сенімділігін, шыдамдылығын және әмбебаптылығын жоғарылатуға мүмкіндік береді. Алайда бұл жерде С++ тілінің компиляторының жұмыс істеуіне байланысты тез әсер етудің төмендеуінің орны өте маңызды болуы мүмкіндігін айта кеткен жөн.

Контейнерлер тізбектелген және ассоциативтік болып бөлінеді. Бұл жұмыста біз тек тізбектелген контейнерлерді қарастырамыз.

Тізбектелген контейнерлер біртипті объектілердің соңғы санын үзілмейтін тізбек ретінде сақтауға мүмкіндік береді және келесі түрлері бар: векторлар,  тізімдер, екі жақты рұқсатпен кезектер, кезек және басты кезек. Алғашқы үшеуі маңыздылары болып табылады, ал қалғандары қосалқы. 8.1. кестеде тізбектелген контейнерлер мінездемелері берілген, салыстыру үшін қарапайым массивтер келтіріледі.

Аталған контейнерлердің әрқайсысының өз құрамындағы объектілерге қолданатын өзінің іс-әрекеттер жиыны бар. Контейнерді таңдау программадағы объектіге қандай іс-әрекет жасау керектігіне байланысты. Мысалы, егер тізбектің ортасындағы элементтерді жиі қою немесе алып тастау қажет болса, онда тізімді қолданған жөн. Ал егер де элементтерді қою немесе алып тастау көбіне тізбектің басына немесе соңына орындалса, онда екі жақты кезекті қолданған тиімдірек.

Класстардың стандартты кітапханасы келесі тақырыптық файлдарда анықталған: <vector>, <list>, <deque>. Бұл тақырыптық файлдарды программаға қосу керек. Қандай типті объектілердің сақталатындығы жөніндегі мәліметтердің берілуі, параметрдің үлгіге берілуі ретінде жүреді. Мысалы, vector<int>fvec// бүтін сандар векторын құрау (int типті). Сонымен қатар контейнерлер мөлшерінің өзгешеліктерін анықтап керек емес, олар мәліметтердің жадыда орналасуын өздері қамтамасыз етеді. Тізбектелген контейнерлер әртүрлі операциялар жиынын қабылдайды, олардың арасында 8.1.1 кестедегі орындалу өзгешеліктерімен сәйкес келетіндері бар.

8.1.2 Кесте

 

Операция

 

Тәсіл

Тізбектелген контейнер түрі

vector

deque

list

Басына қою

push_front()

жоқ             +            +

Басынан алып тастау

pop_front()

жоқ             +            +

Соңына қою

push_back()

+                 +            +

Соңынан алып тастау

pop_back()

+                 +            +

Кез келген жерге қою

insert()

(+)             (+)           +

Кез келген жерден алып тастау

erase()

(+)             (+)           +

Элементке еркін рұқсат

[] немесе at()

жоқ            +            +

                                                                                                                                                         

«+» белгісі, сәйкес операция контейнерге орнатылған n объектілер санынан тәуелсіз уақыт ішінде жүзеге асатынын білдіреді. (+) белгісі операция n- ға пропорционал уақыт ішінде жүзеге асатынын білдіреді. Кестеден вектор әсіресе элементтерге еркін рұқсат, екі шетіне қою және екі шетінен алып тастау әрекеттерін орындайды. Тізім кез келген жерге элементтерді қою және алып тастауды жүзеге асырады, бірақ өзінің элементтеріне еркін рұқсаты жоқ.

8.1.2 Векторлар

Векторлар- ақылды массивтар. Олар өздерін автоматты түрде жадыда орналастырады, қою немесе алып тастау өлшеміне байланысты өз мөлшерін кеңейтумен немесе сығумен айналысады. Кездейсоқ рұқсат өте тез орындалады, сонымен қатар вектор соңына жаңа мәліметтер қосу әлдеқайда тез орындалады.

Мысал қарастырайық.

#include<iostream>

#include<vector>

void main() { vector<int>v //int типті вектор құрау

v.push_back(10);v.push_back(11);v.push_back(12);v.push_back(13);//мәліметтерді вектор соңына енгізу

v[0]=20;v[3]=23;// жаңа белгілеулер енгізу

for(int i=0;i<v.size();i++) cout<<v[i]<<"\t";// 20  11  12  23

}

Берілген мысалда push_back(),size() тәсілдері мен [] операторы қолданылған.

Векторда сақталатын айнымалылардың типі ретінде int типті үлгілер форматы қолданылады. Біз контейнер мөлшерін анықтамаймыз, сондықтан ол басында 0-ге тең. Push_back() тәсілі өз аргументінің мәнін вектордың соңына қояды, вектор басын тізімдердегідей және кезектердегідей емес, яғни оны жаңа элемент қоюға қолдануға болмайды. 10,11,12,13  мәндерін тексереміз де [] операторы арқылы 10-ды 20-ға, 13-ті 23-ке ауыстырамыз. Size() тәсілі контейнердегі элементтер санын қайтарады.

Басқа тәсілдер (конструкторлар):swap()- бір вектордың мәліметтерін екінші векторға алмастырады, бірақ та элементтер орналасу қатары өзгермейді, empty()- вектор құрамы, back()- вектордың соңғы элементінің мәнін қайтарады.

8.1.3 Тізімдер

Тізімдер әр элементінің оң жағынан және сол жағынан меңзеушісі бар, екі рет байланысқан тізім ретінде беріледі. Контейнер құрамында бірінші және соңғы элементтерінің адресі болады, сондықтан тізімнің екі шетіне де рұқсат тез жүзеге асады.

Мысал қарастырайық.

#include<iostream>

#include<list>

void main() { list<int>ilist //int типті тізім құрау

ilist.push_back(10);ilist.push_back(11);//мәліметтерді соңына енгізу

ilist.push_back(12);ilist.push_back(13);//элементтерді басына қою

int size=ilist.size();//элементтер саны

for(int i=0;i<v.size();i++) cout<<ilist.front()<<"\t";// басындағы мәліметтерді оқу

ilist.pop_front();//басындағы мәліметтерді алу

}

} Программа нәтижесі 13 12 10 11

Басқа тәсілдер(конструкторлар):reverse()- элементтер мәнін айналдыру, merge()- элементтерді біріктіреді, unique()- қайталанатын элементтерді кетіреді. Кейбір тәсілдер тек тізімдерде ғана қолданылатынын айта кету керек.

Тізімдерді көбіне тізім ортасына қою немесе кетіру операцияларына

қолданған тиімді. Бұл жерде векторлар мен кезектерді қолданған тиімсіз, себебі қою немесе алып тастау нүктелерінің үстіндегі элементтер қозғалмалы болуы тиіс. Ал тізімге келетін болсақ, бірнеше меңзеушілердің ғана мағынасы өзгереді.

8.1.4 Екі жақты рұқсатпен кезек

Екі жақты рұқсатпен кезек(deque) векторлар мен байланысқан тізімге ұқсайды. Векторлардағыдай еркін рұқсат және тізімдегідей кезектің басына және соңына рұқсат бар. Жалпылап айтқанда бұл екі шеті бар вектор.

Бір айта кететіні, вектор мен екі жақты рұқсаты бар кезекте жады басқаша бөлінеді. Вектор әрқашан жадының көршілес ұяшықтарында орынға ие болады, кезек жадының бірнеше сегменттерінде орналасуы мүмкін, сондықтан кезек барлық жайғдайда дерлік міндетті түрде жадыда орналасады, бірақ сегменттелген объектілерге рұқсат әрдайым әлдеқайда жай жылдамдықпен жүзеге асады.

Мысал қарастырайық.

#include<iostream>

#include<deque>

void main() { deque<int>deq //int типті кезек құрау

deq.push_back(10);deq.push_back(11);//мәліметтерді соңына енгізу

deq.push_front(12);deq.push_front(13);//элементтерді басына қою

deq[2]=33; //еркін элементті өзгерту

for(int i=0;i<deq.size();i++) cout<<deq[i]<<"\t";// басындағы мәліметтерді оқу

ilist.pop_front();//басындағы мәліметтерді алу

} Программа нәтижесі 13 12 33 11

 

8.2 Зертханалық жұмысқа тапсырмалар

8.2.1 Сәйкес келетін конструктор көмегімен мөлшері 5 және мәндері бірдей 1-ге тең болатын, бүтін типті элементтерден құралған v векторын құрайтын программа кұрастырыңыз. Экранға вектор мөлшері мен оның элементтерінің мәндерін шығарыңыз. «[]» операторының көмегімен вектордың екінші элементін 3-ке көбейтіңіз, ал at() тәсілінің көмегімен вектордың төртінші элементін 1-ге азайтыңыз. Экранға қайтадан вектор мөлшері мен оның элементтерінің мәндерін шығарыңыз. Front() және back() тәсілдерінің көмегімен вектордың бірінші элементін  5 –ке азайтыңыз, ал соңғы элементті 2-ге көбейтіңіз.

8.2.2 Сәйкес келетін конструктор көмегімен мөлшері 5 және мәндері

бірдей сәйкесінше 1 және -2-ге тең болатын, бүтін типті элементтерден құралған v1 және v2 векторларын құрайтын программа кұрастырыңыз. Экранға векторлардың мөлшері мен олардың элементтерінің мәндерін шығарыңыз. Push_back() тәсілінің көмегімен мәні  21-ге тең болатын элементті вектордың  соңына қосыңыз  және экранға v1 векторының мөлшері мен элементтерінің мәндерін шығарыңыз. Pop_back() тәсілінің көмегімен  v2 векторының соңғы элементін кетіріңіз және v2 векторының мөлшері мен элементтерінің мәндерін шығарыңыз.

8.2.3 Бастапқы конструктор көмегімен бүтін типті элементтерден үш бос L1,L2,L3 тізімін құрайтын программа жазыңыз. Бірінші тізімнің басына 0, 1, 2,  3, 4 мәндерін енгізіңіз, екінші тізімнің соңына 10, 11, 12 мәндерін енгізіңіз және L3=L2 меншіктеуін орындаңыз. Итераторлар көмегімен экранға құралған тізімдердің мөлшері мен олардың элементтерінің мәндерін шығарыңыз.

8.2.4 8.2.3-ке ұқсас L1, L2 тізімдерін құрап, инициализациялаңыздар. Экранға олар туралы мәліметтерді шығарыңыздар. Remove() тәсілінің көмегімен L2 тізімінен мәні 12-ге тең элементті кетіріңіз және экранға L2 тізімі туралы мәліметтер шығарыңыз. Merge() тәслінің көмегімен L1 тізіміне L1 және L2 тізімдерін қосыңыз, экранға L1 тізімі туралы мәліметтерді шығарыңыз. Sort() және reverse() тәсілдерінің көмегімен сәйкесінше басында L1 тізімін өсу ретімен реттеңіз, содан соң элементтердің орналасу ретін қарама- қарсыға ауыстырыңыз. Әр операциядан соң экранға L1 тізімі туралы мәліметтерді шығарыңыз.

8.2.5 Deque тізбектелген контейнері негізінде, бүтін мәндерді сақтау үшін q1, q2, q3 адаптерлерін кұрайтын программа құрыңыз. Empty(), front() және pop тәсілдерінің көмегімен q1 адаптерінің құрамын экранға шығарыңыз.

8.3 Бақылау сұрақтары

8.3.1 Контейнерлер дегеніміз не? Олар не үшін керек?

8.3.2 Контейнерлер түрлері.

8.3.3 Тізбектелген контейнерлер: векторлар, тізімдер және екі жақты кезектер.

8.3.4 Тізбектелген контейнерлер адаптерлері.

8.3.5 Ассоциативтік контейнерлер.

8.3.6 Арнайы контейнер: биттік көбею.

 

№9 Зертханалық жұмыс. Алгоритмдер. Функционалдық объектілер.

 

Жұмыс мақсаты- стандартты үлгілер кітапханасымен танысу. Алгоритмдар және функционалдық объектілермен жұмыс.

 

9.1 Жұмыстың тәсілі

STL- да алгоритмдар контейнерді қолданушыға қажет операциялардың барлығын орындайды. Ондай алгоритмдардың жалпы саны 60- қа жуық. Әр алгоритм функция үлгісі немесе функция үлгілерінің жиыны ретінде іске асырылған. Алгоритмдерді қолданушының нақты талаптарына келтіру үшін функционалдық объектілер қолданылады.

Қалыпты алгортимдерді қолдану, қалыпты кітапхананың басқа да құралдарын қолданғандай, программистті жазудан, тізбекті реттеу циклдарын жөндеуден құтылдырады. Бұл, программа қателерінің азаюына септігін тигізеді, оны өңдеу уақытын азайтады, оны шағынырақ және оқытылуға жеңілірек етеді. Қалыпты алгоритмдарды хабарлау <algorithm> деген бас тақырыптық файлда болады, ал <functional> деген файл қалыпты функционалдық объектілер үшін. Барлық алгоритмдарды 5 түрге бөлуге болады.

1.   Тізбектермен модификацияланбайтын операциялар (тізбек элементтерінің мәндерін  немесе жалпы тізбекті өзгертпейді, тізбектен мәліметті шығарып алады немесе элементтің тізбектегі орнын анықтайды).

2.   Тізбектермен модификацияланатын операциялар (тізбекті немесе оның элементтерінің мәндерін өзгерте алады).

 

9.1 Кесте

Алгоритмдар

                                     Мағынасы

find()

Мәні көрсетілген мәнге тең болатын бірінші элементті іздейді

count()

Контейнерде, мәні берілген мәнге тең болатын қанша элемент бар екенін санайды

sort()

Контейнер элементтерін реттейді

search()

Бір контейнерде берілген тізбекті келесі контейнерден іздейді

merge()

Екі контейнердің элементтерін біріктіріп үшінші контейнер құрайды

for_seach()

Белгілі бір іс-әрекетті контейнердің әр бір элементіне орындайды

transform()

Контейнер элементтерін трансформалап, басқа контейнерге ауыстырады

 

3.   Тізбектерді реттеу алгоритмдері

4.   Жиындар және пирамидалармен жұмыс жасайтын алгоритмдер

5.   Хабарландырулары <numeric> бас тақырыптық файлында орналасқан, жалпыланған сандық алгоритмдер

Айта кететін жайт, алгортимге параметр ретінде өңделіп жатқан тізбектің басы мен соңын анықтайтын итераторлар беріледі. Контейнер типі, берілген алгоритм қолданылатын итератор түрін анықтайды. Мысалы, реттеу алгоритмі sort() еркін рұқсат итераторларын қолдануды қажет етеді. Сондықтан ол list контейнерімен жұмыс жасай алмайды. Алгоритмдер тізбектер шегінен шығуды тексермейді. 9.1 Кестеде кейбір алгоритмдер мен олардың мағыналары берілген.

Мысал қарастырайық.

Алгоритм find().

#include<iostream>

#include<algorithm>

int arr[]={11,22,33,44,55};

void main() { int*ptr; ptr=find(arr,arr+5,33);//бірінші 33 мәнін табу

cout<<”Мәні 33-ке тең бірінші объект мына позициядан табылды”<<(ptr-arr);

}

Жауабы: Мәні 33-ке тең бірінші объект мына позициядан табылды 2.

Функционалдық объект greater<>().

#include<iostream>

#include<algorithm>

#include<functional>

int arr[]={11,22,33,44,55};

void main() { sort(arr,arr+5, greater<>());//int типті мәндерді реттеу

for(int i=0;i<6;i++)

cout<<arr[i]<<”\t”; }  

Жауабы: 55 44 33 22 11

Әдетте алгоритм өсу реті бойынша реттейді, бірақ greater<>() функционалдық объектін қолдану реттеу түрін өзгертеді.

9.2 Зертханалық жұмысқа тапсырмалар

Есептерді шығарғанда тек C++ тілінің қалыпты кітапханасының құралдарын қолданыңыз.

9.2.1 Search() алгоритмі бір контейнерде берілген тізбекті келесі контейнерден іздейді.

Екі массив arr1[]={5, 2, 1, 2, 3, 0, 3} және arr2[]={1, 2, 3} берілген. arr2[]={1, 2, 3} массивында берілген 1, 2, 3 тізбегі қай элементтен бастап кездесетінін табу керек.

 9.2.2 Бүтін сандардан тұратын вектор құрап, оларды инициализациялайтын программа құрастырыңыз. Экранға оның элементтерінің мәндерін шығарыңыз. find() тәсілінің көмегімен вектор элементтері арасынан берілген мәнді тауып, іздеу нәтижесін экранға шығарыңыз. count() тәсілінің көмегімен мәні берілген мәнге тең болатын вектор элементтерінің санын санап, нәтижесін экранға шығарыңыз.

9.2.3 Бүтін сандардан құралған, мөлшері 4 және 2 элементтен тұратын екі вектор құрап, инициализациялайтын программа құрыңыз. for_seach() тәсілінің және функция көмегімен оның элементтерінің мәндерін экранға шығарыңыз.

9.2.4 Cәйкес келетін конструкторлар арқылы үш нақты типті v, v1, v2 векторларын құрайтын программа құрастырыңыз. Алғашқы екеуін кез келген кездейсоқ мәндермен инициализациялаңыз, ал v2 векторын екі реттелген тізбектен тұратындай етіп инициализациялаңыз. Осы векторлардың элементтерінің мәндерін экранға шығарыңыз. sort() және stable_sort() тәсілдерінің көмегімен v және v1 векторларын сәйкесінше қарапайым және тұрақты реттеп, экранға осы векторлар мәндерін шығарыңыз. binary_search() тәсілінің көмегімен берілген мәнді v векторынан тауып, іздеу нәтижесін экранға шығарыңыз. implace_merge() алгоритмінің көмегімен v2 векторының екі реттелген тізбегін біріктіріңіз де осы вектордың элементтерінің мәндерін экранға шығарыңыз. 

9.3 Бақылау сұрақтары

9.3.1 Қалыпты алгоритмдар мен функционалды объектілердің хабарландырулары қандай файлдарда орналасады?

9.3.2 Алгортимдардың негізгі түрлерін атаңыз.

9.3.3 Алгоритмдар қалай жүзеге асады?

9.3.4 Жиындар және пирамидалармен жұмыс жасайтын қандай

алгоритмдер?

9.3.5 Тізбектермен модификацияланатын және модификацияланбайтын операциялар.

9.3.6 Арнайы контейнер: биттік көбею.

 

№10 зертханалық жұмыс. Итераторлар. Жиындық итераторлар.

 

Жұмыс мақсаты- стандартты үлгілер кітапханасымен танысу. Итераторлармен жұмыс.

 

10.1 Жұмыстың тәсілі

10.1.1 Итераторлар

Итераторлар- сілтеушілерге ұқсас заттар. Итераторлар STL- дa iterator класының объектісі болып табылады. Олар контейнер класстармен, жиындармен және жиын буферларымен жұмыс жасау үшін қолданылады. Итераторлармен жұмыс жасағанда көрсетіліп тұрған элемент және келесі элементке сілтеуші деген ұғымдар қолданылады. Тізбектің көрсетіліп тұрған элементіне рұқсат, сілтеушілерді қолданғандағыдай, «*» және «->» операцияларының көмегімен орындалады. Келесі элементке өту инкремент операциясы «++»(«--») арқылы орындалады. Сонымен қатар барлық итераторларға меншіктеу, тең және тең емеске тексеру операциялары тән. Алайда әртүрлі итераторлар әр түрлі қасиеттерге ие. Әр типті итераторлар үшін өзінің итераторлары қолданылады.  Итераторладың негізгі үш типі бар: тура, екі бағытты  және кездейсоқ рұқсатпен. Тура итератор контейнер бойымен тек тіке бағытта өте алады. Мұндай итератор кері бағытта жүре алмайды және контейнердің кез келген жеріне қойылмайды. Екі бағытты итератор екі бағытта да жүре алады, ал кездейсоқ рұқсатты итератор екі бағытта да жүре алады және контейнердің кез келген жеріне өте алады. Итератордың екі арнайы түрі бар: бұл кіріс итераторы, кіру құрылғысына сілтей алады (cin немесе қарапайым кіру файлы), сонымен қатар нәтижені шығару итераторы(cout). 10.1 Кестеде итераторлар типтерінің қасиеттері көрсетілген.

 

10.1 Кесте

Итератор типтері

Жазу/оқу

Мәнді сақтау

Бағыт

Рұқсат

 

Кездейсоқ рұқсатпен

Жазу және оқу

Мүмкін

Екі бағытта

кездейсоқ

Екі бағытты

Жазу және оқу

Мүмкін

Екі бағытта

сызықтық

Тура

Жазу және оқу

Мүмкін

Тек тура

сызықтық

Шығыс

Жазу

Мүмкін емес

Тек тура

сызықтық

Кіріс

Оқу

Мүмкін емес

Тек тура

сызықтық

 

10.1.2 Итератор адаптерлері

Итератор адаптерлері бұл, арнайы итераторлар. Олар мынандай іс- әрекеттерді орындайтын алгоритмдерді орындайды:

1.   Элементтерді кері бағытта таңдау (кері итераторлар)

2. Қою режимі (қою итераторлары)

3. Мәліметтер жиынымен жұмыс жасау (жиындық итераторлар)

Кері итераторлар reverse_iterator деп белгіленеді, оны қолданғанда rbegin() және rend() тәсілдері қолданылады.

Мысал қарастырайық.

#include<iostream>

#include<list>

void main() { int arr[]={ 2,4,6,8,10}; list<int>thelist;

for(int i=0;i<5;i++)

thelist.hush_back(arr[i]) // массив құрамын тізімге ауыстыру

list<int>::reverse_iterator revit; //кері итератор

revit=thelist.rbegin(); // реверстік итерация

while(revit!=thelist.rend()) // тізім бойынша экрандық нәтижесімен бірге

cout<<*revit++<<”\t”;

}

Жауабы: 10 8 6 4 2

Контейнердің өтуі соңынан басталады, бұл кезде rbegin() тәсілі шақырылады.

Қою итераторлары контейнердің басына, соңына және кез келген жеріне жаңа элемент қоюға арналған. Олар front_inserter,  back_inserter, inserter.

Жиындық итераторлар қалыпты алгоритмдермен жұмыс жасаған кезде шығыс-кіріс жиындарымен жұмысты қамтамасыз етеді. Екі жиындық итератор бар: ostream_iterator және istream_iterator.

Мысал қарастырайық.

#include<iostream>

#include<list>

#include<algorithm>

void main() { int arr[]={2,4,6,8,10}; list<int>thelist;

for(int i=0;i<5;i++)

ostream_iterator<int>ositer(cout,”,”);

copy(thelist.begin(),thelist.end(),ositer);

}

Жауабы: 2,4,6,8,10. ostream_iterator итераторы int типін оқу үшін. Конструктордың екі параметрі болып мәндер жазылатын жиын және сол мәндердің әрқайсысының ізінен шығарылып отыратын жол табылады. Жиын мәні файл аты немесе cout.

10.1.3 Итераторлар интеллектуалды сілтеушілер ретінде

Бізге белгілі болғандай массив мәліметтерін алу үшін float*ptr=start_address; for(int i=0;i<size;i++) cout <<*ptr++; сілтеушілерін қолдануға болады. Бірақ та сілтеушілерді қиынырақ контейнерлерге қолданған қиынырақ екенін айта кеткен жөн. Мысалы, егер де контейнер элементтері жадыда тізбектеліп емес, сегменттеліп сақталса оларға рұқсат тәсілдері қиындайды. Бұл проблеманы шешудің бір жолы «интеллектуалдық сілтеушілер» класын құру болып табылады. Бұл класс объектілері, әдетте, қарапайым сілтеушілермен жұмыс жасайтын тәсілдерге қабық болады. ++  және * операторлары, контейнер элемнеттері тізбектелмей орналасып немесе орнын ауыстырып тұрса да олармен қалай жұмыс жасау керектігін біледі. Алдыңғы программаны басқаша жазсақ:

Class sum {private:float*ptr; public:float operator*() {}

float operator++() {} };

void main() { sum sptr=start_address; }

for(int i=0;i<size;i++) cout<<*ptr++; }

10.2 Зертханалық жұмысқа тапсырмалар

10.2.1 arr[]={5,2,1,2,3}  массивы берілген. Тізімді массив элементтерімен толтырыңыз, бүтін мәнді тізбек үшін итератор құрыңыз, тізім мәліметтерін экранға шығарыңыз.

10.2.2 Екі arr[]={5,2,1,2,3,0,3} және arr2[]={2,4,6} массивтері берілген. Int типті екі(d1 және d2) бағытта рұқсат құрыңыз. Мәліметтерді массивтан екі жақты рұқсатты кезекке ауыстырыңыз. Back_inserter итераторын қолдана

отырып d1-ді d2-нің соңына көшіріңіз де d2-нің нәтижесін экранға шығарыңыз.

10.2.3 Инициализацияланбаған float типті тізім құрыңыз, istream_iterator  итераторын қолдана отырып тізім элементтерінің мәндерін енгізіңіз. Ондағы cin конструктор аргументі және жиын соңын көрсетіңіз. сin- нан тізімге көшіріңіз. Тізім мәндерін экранға шығарыңыз.

10.2.4 №8 зертханалық жұмыстағы 8.2.3 мысалындағы cin жиынының орнына программаға арналған мәліметтер алынатын кіру файлын қолданыңыз.

10.3 Бақылау сұрақтары

10.3.1 Итераторлар не үшін қолданылады?

10.3.2 Итератор мен сілтеуші семантикасы бірдей ма?

10.3.3 Итератордың кез келген типіне қандай операциялар қолдануға болады?

10.3.4 Итератор түрлерін, оларға рұқсат етілген операциялар мен олардың қолданылу аясын атаңыз.

10.3.5 Қандай жағдайлар итераторларды қолдануға келмейді?

10.3.6 Итератор адаптерлері мен олардың қызметін атап шығыңыз.

 

Әдебиеттер тізімі 

1.  Подбельский В.В., Фомин С.С. Программирование на языке С++. Учебное пособие. –М.: Финансы и статистика, 2000.

2. Фридман А.Л. Язык программирования С++. Курс лекций. –М.: Интернет – Университет информационных технологий, 2003.

3. Лафоре Р. Объектно- ориентированное программирование в С++. Санкт- Петербург, 2003.

         4. Шиманович Е.Л. С/С++ в примерах и задачах. Мн.: Новое знание, 2004.

         5. Давыдов В.Г. Технология программирования С++.  Санкт- Петербург, 2005.

         6. Бимагамбетов Т.С. Объектно- ориентированное программирование на языке  С++. Методическое указание к выполнению лабораторных работ. Алматы. АИЭС, 2006. 

         7. Бимагамбетов Т.С. Программирование на языке Си++. Учебное пособие. Алматы. АИЭС, 2007. 

 

МАЗМҰНЫ 

Кіріспе                                                                                                            3

№8 Зертханалық жұмыс. Контейнерлер. Тізбектелген контейнерлер     4

№9 Зертханалық жұмыс. Алгоритмдер. Функционалдық объектілер     10

№10 Зертханалық жұмыс. Итераторлар. Жиындық итераторлар            13

Әдебиеттер тізімі                                                                                          17