Professional Documents
Culture Documents
Programiranje Mat Inf Gim 1 Mak
Programiranje Mat Inf Gim 1 Mak
Programiranje Mat Inf Gim 1 Mak
МИЛЕ ЈОВАНОВ
ЕМИЛ СТАНКОВ
ПРОГРАМИРАЊЕ
ЗА I ГОДИНА
МАТЕМАТИЧКО – ИНФОРМАТИЧКА
ГИМНАЗИЈА
Скопје, 2022
Ѓорѓи Јованчевски
Миле Јованов
Емил Станков
ПРОГРАМИРАЊЕ
УЧЕБНИК ЗА I ГОДИНА
Математичко-информатичка гимназија
Скопје, 2022
ПРОГРАМИРАЊЕ
УЧЕБНИК ЗА I ГОДИНА
Математичко-информатичка гимназија
Автори:
Ѓорѓи Јованчевски,
Миле Јованов,
Емил Станков,
Рецензенти:
Дејан Спасов
Билјана Пејовска
Викторија Доказа
Јазична редакција:
Виолета Јанушева
Јованка Јованчевска
Стручна редакција:
Џеваир Беќири
Уредник:
Елена Стефановска
Тамара Јовановиќ Нешовска
Издавач:
Министерство за образование и наука на Република Северна Македонија, ул.„Св.
Кирил и Методиј“ бр.54, 1000 Скопје.Со одлука број 26-304/1 од 08.07.2022 година на
Националната комисија за учебници, се одобрува употребата на овој учебник.
CIP:
Содржина
СОДРЖИНА
Вовед
1. ОСНОВИ НА ПРОГРАМИРАЊЕ 1
1.1 Алгоритми 3
Алгоритамски чекори 4
Вежби 5
1.2 Програми 5
Вежби 6
1.3 Претставување на алгоритмите 7
Структурирани алгоритми 9
Вежби 12
1.4 Програмирање 12
1.5 Програмски јазици 14
Виши програмски јазици 16
Вежби 21
1.6 Интегрирана околина за програмирање 22
Интегрирана околина за програмирање Code::Blicks 23
Вежби 27
1.7 Алгоритамски контролни структури 31
Редоследна контролна структура 31
1.8 Јазикот С++ 32
Елементи на јазикот С++ 33
Вежби 36
1.9 Податоци и променливи 37
Вежби 40
1.10 Типови податоци 41
Целоброен тип податоци 41
Знаковен тип податоци 43
Реален тип податоци 43
Логички тип податоци 45
1.11 Читање и печатење на податоци 46
Вежби 51
Резиме 54
i
ПРОГРАМИРАЊЕ
5. НИЗИ 155
5.1 Еднодимензионални низи 156
Решени задачи 164
Наредба for базирана на опсег 169
Вежби 170
Прашања 154
5.2 Сортирање на низа и класен шаблон vector 172
Вежби 175
5.3 Текстуални низи 176
Решени задачи 183
Шаблонот string 185
Вежби 187
5.4 Дводимензионални низи 188
Решени задачи 194
Вежби 198
Резиме 199
6. ДАТОТЕКИ 201
Влезни датотеки 204
Излезни датотеки 205
Влезно-излезни датотеки 206
Решени задачи 209
Вежби 218
Резиме 220
iii
ПРОГРАМИРАЊЕ
iv
Содржина
ДОДАТОК 331
А Основни типови податоци во С++ 331
Б Знаци ASCII 332
ЛИТЕРАТУРА 333
v
ПРОГРАМИРАЊЕ
vi
Вовед
Вовед
Овој учебник претставува почетен курс за изучување на програмира-
њето. Тој во целост ја следи и ја покрива Наставната програма за предметот
Програмирање од прва година за Математичко-информатичката гимназија и е
плод на богатото долгогодишно искуство на авторите во пренесување на веш-
тините за програмирање.
Учебникот ги опфаќа основите на алгоритамското изразување на про-
блемите преку посебен псевдојазик, како и кодирањето во програмскиот јазик
С++.
Изучувањето на програмирањето го започнуваме со запознавање со ал-
горитмите, програмите и текстуалното и графичкото претставување на алго-
ритмите.
За кодирање на алгоритмите во јазик што го разбира компјутерот, на-
правени се т.н. програмски јазици. Програмските јазици се состојат од конечно
множество наредби. Да се научат наредбите на кој било програмски јазик не е
воопшто тешко, тешко е да се смисли постапка (алгоритам) за решавање на
конкретен проблем. Затоа, е воведен псевдојазик на македонски со кој попри-
родно се изразуваат алгоритмите и основните алгоритамски контролни струк-
тури.
Во првата глава ученикот се запознава со програмскиот јазик С++, прво
со неговите основни елементи, како: променливите, типовите податоци, на-
редбите за читање и за печатење и структурата на програма во јазикот С++.
Во втората глава се објаснети основните алгоритамски контролни (уп-
равувачки) структури за контрола и управување со текот на извршување на ал-
горитмите: контролните структури за избор и контролните структури за пов-
торување. Тие се доволни за да се изрази секој алгоритам. Нивната имплемен-
тација е објаснета и илустрирана преку соодветните наредби во програмскиот
јазик С++.
Во третата глава е дадено објаснување за сложеноста на алгоритмите
и за видовите на сложеност и е потенцирано дека сè уште има проблеми за кои
нема ефикасни алгоритми.
Четвртата глава се однесува на расчленување на задачите (проблеми-
те) на подзадачи, кои се изразени со подалгоритмите и со потпрограмите –
функциите во програмскиот јазик С++.
Во петтата глава се ученикот се запознава со првите сложени струк-
тури на податоци, и тоа: еднодимензионалните низи, текстуалните низи, пове-
ќедимензионалните низи, како и нивната имплементација во програмскиот јазик
С++. Преку запознавање со низите, ученикот ќе се стекне со знаења кои ќе му
овозможат решавање на посложени алгоритамски проблеми.
vii
ПРОГРАМИРАЊЕ
Авторите
viii
1. Основи на програмирање
1. ОСНОВИ НА ПРОГРАМИРАЊЕ
Во оваа глава ќе се запознаете со следното:
Клучни зборови
1
ПРОГРАМИРАЊЕ
2
1. Основи на програмирање
1.1 Aлгоритми
Секој човек точно знае што треба да направи кога треба да си ја подготви
чантата за следниот ден, да се јави некому на телефон или да се сретне некаде со
пријателите. Но не е толку лесно да се инсталира кабелска телевизија, да се
пресмета волуменот на делот во машината за перење каде што се става облеката
или на делот за замрзнување во домашниот ладилник.
Човечките активности, во голем дел, можe да се извршат како редослед
од определен број одделни помали елементарни активности (активности за кои
не е потребно објаснување за да бидат извршени). За некои активности, тој ре-
дослед е сложен и тежок за паметење, па извршувањето не е воопшто лесно.
За да може еден изведувач да изврши дадена активност, тој треба да го
познава точниот редослед на елементарните активности што треба да се ис-
полнат. За таа цел, изведувачот треба да добие листа со инструкции за тоа какви
активности да преземе и по кој редослед. Таа листа со инструкции може да се
нарече алгоритам (англ. algorithm). Можеме да кажеме дека:
алгоритам е постапка од конечен број строго дефинирани дејства
(активности, операции) и точно зададен редослед за нивно извршување.
Поимот алгоритам ќе го објасниме подетално на примерот за наоѓање на
најголемиот број од три дадени броја. Можеме да ја примениме следнава пос-
тапка: ќе споредиме кои било два броја и поголемиот од нив ќе го споредиме со
третиот број. Поголемиот број при второто споредување е најголемиот од трите
броја.
Очигледно е дека постапката се состои од само две точно дефинирани
дејства (операции):
Споредување на кои било два броја и одредување на поголемиот.
Споредување на поголемиот број од првото споредување со третиот број
и одредување на поголемиот од нив.
За да се примени оваа постапка врз кои било три броја, потребно е тие да
бидат претходно зададени. Резултатот од постапката е најголемиот број. Тоа зна-
чи дека решавањето на некоја задача се состои во одредување на излезните
резултати со примена на одредена постапка – алгоритам врз влезните податоци.
Затоа, може да се рече дека:
алгоритам претставува постапка која се состои од конечно множество
точно дефинирани дејства (операции), применети врз влезните податоци по
строго пропишан редослед, со кои се доаѓа до излезни резултати.
Зборот алгоритам е земен од латинскиот јазик и претставува латински
превод на презимето Al‒Khwarizmi на арапскиот математичар од IX век Abu
Ja’far Muhammad ibn Musa al‒Khwarizmi, кој прв ги формулирал правилата за
извршување на четирите основни аритметички операции со арапски цифри.
3
ПРОГРАМИРАЊЕ
Алгоритамски чекори
4
1. Основи на програмирање
Вежби
Вежба 1.1.1
Опишете алгоритам за разговор на мобилен телефон кога каните
некого на роденденска забава. Претпоставете дека тој што го барате за-
должително ќе Ви се јави.
Вежба 1.1.2
Опишете ги сите познати алгоритми за копирање датотеки со
помош на Windows Explorer.
Вежба 1.1.3
Замислете дека дома имате интелигентен робот кој ги изведува
следните активности (со соодветната команда): „Земи лонец“, „Внима-
телно стави го над ринглата од шпоретот“, „Наполни го со вода“ „Земи
јајце од фрижидерот“, „Вклучи го шпоретот“, „Исклучи го шпоретот“,
„Почекај водата да зоврие“ и „Почекај точно 9 минути“.
Обидете се да напишете упатство (алгоритам) со кое роботот ќе
успее „тврдо“ да Ви свари 4 јајца на шпорет со една рингла. За да бидат
тврдо сварени јајцата, потребно е да се варат 9 минути од зовривањето на
водата.
1.2 Програми
Компјутерот не е способен за никаква самостојна работа. За да може ком-
пјутерот да изврши каква било работа, потребно е да му се зададат соодветни
наредби со кои се активира и се извршува некоја програма (англ. program). Ако
програмата е правилно напишана, компјутерот ќе ја изврши и ќе ги даде соод-
ветните резултати.
Целокупната работа на компјутерот се одвива под контрола на посебни
т.н. системски програми (англ. system programs), кои може да се поделат во три
групи:
Оперативни системи (англ. operating systems).
Контролни програми (англ. control programs).
Услужни програми (англ. utility programs).
Програмите кои извршуваат одредени работи за корисниците се нареку-
ваат апликативни програми (англ. application programs) или кориснички про-
грами (англ. user programs).
Сите апликативни програми кои ги имаме на нашиот компјутер решаваат
одредени задачи, односно со нив извршуваме одредена работа. На пример, поз-
нати апликативни програми се програмите од пакетот Мајкрософт офис (англ.
5
ПРОГРАМИРАЊЕ
Слика 1.2.1
Целокупниот софтвер е напишан со т.н. програми (англ. programs). Една
програма претставува текст кој компјутерот може да го разбере и изврши. Про-
грамите се пишуваат во некој програмски јазик (англ. programming language), кој
служи за комуникација меѓу човекот и компјутерот. Програмите се пишуваат со
наредби кои компјутерот треба да ги „разбере“ и, понатаму, да ги изврши оние
дејства кои се „искажани“ со тие наредби.
Сите апликативни програми кои ги имаме на нашиот компјутер решаваат
одредени задачи.
За некој да напише програма за решавање на одредена задача со помош
на компјутер, потребно е да знае да програмира.
Процесот на пишување програма е наречен програмирање (англ. pro-
gramming), а луѓето што ги пишуваат програмите (програмираат) се нарекуваат
програмери (англ. programmers).
Програмите може да се уредуваат (пишуваат и менуваат) со некој уреду-
вач на текст, да се паметат како датотеки и да се извршуваат.
Вежби
Вежба 1.2.1
Дајте пример за 3 програми кои се на Вашиот компјутер. Обидете
се да ги ставите во соодветната категорија од второто ниво на слика 1.3.
6
1. Основи на програмирање
Вежба 1.2.2
Обидете се да дадете пример за програма за секоја од наведените
програми од третото ниво на слика 1.3.
7
ПРОГРАМИРАЊЕ
po~etok
Слика 1.3.2 a, b, c
Алгоритамот за одредување на најголемиот
од трите дадени броја претставен графички со блок- ne
a>b
da
дијаграмот од слика 1.3.1 е даден на слика 1.3.3.
Претставувањето на алгортимите може да
биде и директно преку програмски јазик. Притоа, p b p a
алгоритамот го „изразуваме“, т. е. кодираме (англ.
code) со наредбите од некој програмски јазик. Така
кодираниот алгоритам со наредби од некој програм-
ne da
ски јазик се нарекува изворна програма (англ. sour- p>c
ce program). За да може да се изврши изворната про-
грама, таа мора да се преведе во извршна програ-
n c np
ма (англ. executive program).
На пример, разгледаниот алгоритам за наоѓа-
ње на најголемиот број од 3 дадени броја, кодиран
во програмскиот јазик C++ е даден на слика 1.3.4.
n
kraj
Слика 1.3.3
8
1. Основи на програмирање
Слика 1.3.4
По извршување на програмата, излезот е:
Структурирани алгоритми
Почеток
Крај
Активност
Избор (разгранување)
Спојување
Слика 1.3.7
11
ПРОГРАМИРАЊЕ
Вежби
Вежба 1.3.1
а) Наведете неколку можни дефиниции за алгоритам.
б) Кои се можните чекори за одредување на средната вредност на
три броја?
Вежба 1.3.2
Да се претстави текстуално и графички алгоритам за утврдување
дали природниот број n е парен или непарен.
Вежба 1.3.3*
Да се претстави текстуално и графички алгоритам за утврдување
дали три броја a, b и c може да бидат страни на триаголник.
Вежба 1.3.4*
Да се подредат три броја a, b и c по големина, од најмал до најго-
лем.
1.4 Програмирање
12
1. Основи на програмирање
13
ПРОГРАМИРАЊЕ
Машински јазик*1
1
Ознаката * значи дека оваа потточка е корисна, но не е неопходна за понатамошно раз-
бирање на материјалот. Ознаката ќе ја користиме и во дриги поднаслови.
14
1. Основи на програмирање
Mашински инструкции
101110001101011000010110 B8D616
1000111011011000 8ED8
101000000000000000000000 A00000
00000010000001100000000100000000 02060100
101110110001000010000000 BB1080
1000100000000111 8807
1011010001001100 B44C
1100110100100001 CD21
Слика 1.5.1
*
Симболички јазици
2
Мнемоника е техника за паметење.
15
ПРОГРАМИРАЊЕ
3
Кај програмските јазици најчесто се користи англиската азбука.
16
1. Основи на програмирање
Слика 1.5.3 а
17
ПРОГРАМИРАЊЕ
Слика 1.5.3 б
Вишите програмски јазици не зависат од машината на која ќе се извршува
некоја програма напишана со нив и затоа се нарекуваат машински независни
јазици. Затоа, при градбата на вишите програмски јазици, не се води сметка за
типот на компјутерот на кој ќе се извршуваат програмите напишани со нив, туку
се води сметка за типот на проблемот што се решава. Велиме дека тие се ориен-
тирани кон решавањето на одреден тип проблеми (економски, технички, статис-
тички итн.) и затоа, се нарекуваат проблемски ориентирани јазици.
Развојот на вишите програмски јазици започнал во 50-тите години од ми-
натиот век. Досега се развиени над 3 000 програмски јазици.
Во табела 1.5.1 е дадено хронолошки појавувањето на некои поважни
програмски јазици.
Година Јазик
1945 Машински
јазик
1950 Симболички
јазик
1955 Fortran
18
1. Основи на програмирање
19
ПРОГРАМИРАЊЕ
20
1. Основи на програмирање
Вежби
Вежба 1.5.1
Одговорете на следните прашања:
1. Објаснете ги фазите за решавање на некоја задача со помош на
компјутер.
2. Што треба да знаете за да можете да пишувате програми?
3. За кои програмски јазици сте слушнале?
4. Објаснете што е програмирање, а што програма.
5. Како се делат програмските јазици?
6. *Каков јазик е машинскиот јазик? Зошто не се програмира во него?
7. *Во кој броен систем се запишуваат машинските програми на
хартија?
8. *Дали е поедноставен машинскиот јазик или симболичките јазици?
9. *Како се нарекуваат системските програми што имаат задача да ги
преведуваат програмите од симболички на машински јазик?
10. На кои факти се должи масовното користење на вишите програмски
јазици?
11. Има ли разлика меѓу азбуката на природен и на програмски јазик?
12. Дали зборовите во вишите програмски јазици имаат значење?
13. Од што се состои речникот на еден виш програмски јазик?
14. Може ли една програмска наредба да се состои само од еден збор?
15. Како се нарекува програмата напишана на виш програмски јазик, а
како програмата преведена на машински јазик? Кои наставки ги
имаат соодветните датотеки?
16. Зошто велиме дека вишите програмски јазици се машински
независни јазици?
17. Наведете неколку виши програмски јазици.
21
ПРОГРАМИРАЊЕ
Уредувач на текст
Преведувач
Дибагер
Поврзувач
Стартување
Главен прозорец
а) Лента со менија
Лентата со менија се наоѓа во најгорниот дел на прозорецот, веднаш под
неговиот наслов. Во неа се наоѓаат менијата File, Edit, View, Search, Project, Bu-
ild, Debug, wxSmith, Tools, Plugging, Settings и Help. Секое мени содржи наредби
за околината и/или други менија. Значењето на повеќето од нив ќе биде разгледа-
но понатаму.
б) Ленти со алатки
Лентите со алатки (копчиња за стартување на најчесто користените ко-
манди на околината) се наоѓаат непосредно под лентата со паѓачки менија.
Алатките во околината за програмирање Code::Blocks се поделени во групи, во
зависност од нивното значење. Покажувањето и криењето на различните групи
алатки се реализира слично како во програмите на Microsoft Office, со избирање
на опцијата View -> Toolbars. Секоја група има свое име и ако пред името го има
знакот за штиклирање (), групата се гледа на екранот, а ако го нема тој знак,
таа не се гледа. Секоја алатка соодветствува на некои од командите на менито.
в) Работна површина
Во работната површина може да се наоѓаат потпрозорците на програмите
на околината. Најважните од нив се:
Прозорецот за уредувачот на текст. Во него може да има неколку стра-
ници, во зависност од тоа во колку програми работи програмерот во даде-
ниот момент. Името на програмата е напишано на натписот, кој се наоѓа
во горниот дел на страницата (види слика 1.6.1.). Натписот на страницата
која е активна во моментот е различен од натписите на другите страници.
Прозорецот за соопштенија. Во овој прозорец може да се отвори една од
повеќето страници. Во него се прикажуваат информации за преведување-
то, за поврзувањето, за стартувањето итн. Ако за време на преведувањето
бидат откриени грешки, тогаш тие се покажуваат во страницата Build
messages на овој прозорец.
Прозорецот за организација на работата на програмата.
Прозорците може да се затвораат, да се зголемуваат или намалуваат итн.
Уредувач на текст
25
ПРОГРАМИРАЊЕ
в) Барање и заменување
Вежби
Вежба 1.6.1
27
ПРОГРАМИРАЊЕ
28
1. Основи на програмирање
Додадете изворна датотека во проектот: File > New > File > C/C++ Source
и изберете C++ како програмски јазик. Потоа внесете го името на датотеката со
полната патека (на пример Vezhba1 – во соодветната папка каде што е проектот)
и не заборавајте да го вклучите „Add file to active project“.
За секој проект, треба да се постават следните опции:
„Project > Build Options... > Compiler Flags“.
Со ова креиравте еден проект кој во себе, засега, содржи една празна
датотека, која е спремна во неа да ја напишете Вашата прва програма.
29
ПРОГРАМИРАЊЕ
Вежба 1.6.2
#include <iostream>
using namespace std;
int main() {
cout << "Ova e primer za programa";
cout << "koja e napishana vo C++.";
cout << "So nea go probuvam CodeBlocks dali raboti!\n";
return 0;
}
Вежба 1.6.3
30
1. Основи на програмирање
31
ПРОГРАМИРАЊЕ
4
Класа е апстрактен тип на податок.
5
Апстрактен тип е замислен тип на податок. На пример, тип ученик.
32
1. Основи на програмирање
33
ПРОГРАМИРАЊЕ
34
1. Основи на програмирање
Значи, ако сакаме да се напише уште нешто на екранот, што може да на-
правиме? Едноставно под горната наредба (Ред 6 и Ред 7) ќе додадеме уште една
наредба „cout“ (Ред 6 b на слика 1.8.2):
cout << "Dali e se vo red? ";
Со извршување на ваквата програма на екран ќе добиеме:
Zdravo, kako ste?Dali e se vo red?
Доколку сакаме да има празно место помеѓу двете реченици, ќе мораме
да додадеме празно место на крајот на првата реченица или на почетокот на вто-
рата реченица. Доколку, пак, помеѓу споменатите две наредби (Ред 6 и Ред 6 b)
додадеме уште една наредба (во Ред 6 a):
cout << endl;
и ја извршиме ваквата програма, на екранот ќе добиеме:
Zdravo, kako ste?
Dali e se vo red?
Како што забележуваме, наредбата:
cout << endl;
го предизвикува следново: она што програмата ќе го отпечати во понатамошното
нејзино извршување, ќе се печати во нов ред (следниот ред по редот во кој е
испишано Zdravo, kako ste?).
Комплетната програма сега би изгледала вака:
// Prva C++ programa Red 0
#include <iostream> // Red 1
using namespace std; // Red 2
// Red 3
int main() // Red 4
{ // Red 5
cout << "Zdravo, kako ste? "; // Red 6
cout << endl; // Red 6 а
cout << "Dali e se vo red? "; // Red 6 b
return 0; // Red 7
} // Red 8
Слика 1.8.2
Трите наредби во програмата се наредени една под друга. Тие точно така
и ќе бидат извршени од компјутерот, прво едната, потоа втората, па третата, т. е.
наредбите ќе бидат извршени по редослед. Затоа и ваквата последователност од
наредби се нарекува „редоследна структура“.
Во наредбата cout можеме да комбинираме повеќе делови. На пример,
горните три наредби може да се спојат во една:
cout << "Zdravo, kako ste ? " << endl << "Dali e se vo red ? ";
Едноставно ги одделуваме деловите со <<.
Со наредбата cout, можеме да отпечатиме и броеви, па дури и вредности
на аритметички изрази. На пример, да ја разгледаме програмата на слика 1.8.3.
35
ПРОГРАМИРАЊЕ
Вежба 1.8.1
Во програмата на слика 1.8.3 погледнете ги наредбите за печате-
ње на екранот. Како се постигнува празно место помеѓу различните де-
лови од cout кои се печатат?
Вежба 1.8.2
Направете програма која ќе ги отпечати Вашето име и презиме, а
во вториот ред ќе го отпечати бројот на Вашите години.
Вежба 1.8.3
Поправете ја претходната програма да го отпечати бројот на ме-
сеци наместо бројот на години.
Вежба 1.8.4
Направете програма која ќе го отпечати резултатот од множењето
на 1 234 до 5 678. Проверете дали сте добиле точен резултат со помош на
калкулатор.
Вежба 1.8.5
Направете програма која ќе го отпечати резултатот од множењето
на 123 456 со 7 891 011. Што добивте како резултат? Дали тоа е точниот
резултат?
36
1. Основи на програмирање
Величини и податоци
6
Децималните броеви во програмските јазици се одделуваат со точка.
37
ПРОГРАМИРАЊЕ
Имиња на податоците
Типови податоци
38
1. Основи на програмирање
39
ПРОГРАМИРАЊЕ
Примери:
const int m = 3;
const int х = 10, у = 12;
const double pi = 3.1415;
const char da = 'D';
Ако не се наведе типот, се подразбира типот int.
Променливи податоци или скратено променливи се оние податоци чија
вредност (содржина на локацијата во меморијата на која се наоѓаат) може да се
менува за време на извршување на програмата.
Променливите податоци се декларираат со:
тип име;
или
тип име = вредност;
Последниов начин претставува истовремено декларација и иницијализа-
ција (доделување почетна вредност) на променлива.
Примери:
int i, j;
int m = 10, n = 17 ;
float e = 2.7182;
За да може да се користи во програмата, податокот мора да е дефиниран.
Тој се дефинира со доделување вредност при декларирање (со иницијализација)
или со наредбата за доделување.
Наредбата за доделување е:
име = вредност;
Пример
#include <iostream>
main()
{
short ed_cena, vkupno; /* Deklaracija na promenlivi */
short parcinja = 1000; /* Deklaracija so inicijalizacija*/
ed_cena = 50; /* Dodeluvanje vrednost */
}
Вежби
Вежба 1.9.1
За да ја отпечатиме вредноста на една променлива (да речеме
именувана со m), едноставно ја користиме наредбата cout << m;. Може-
ме да правиме и комбинации со текст и изрази, како во примерите во
претходните поглавја.
Направете 3 програми во кои ќе ги вклучите наредбите за декла-
рирање и иницијализирање наведени во последните три примери. Потоа,
40
1. Основи на програмирање
Вежба 1.9.2
Направете програма во која ќе декларирате и иницијализирате две
променливи со наредбата int a = 12, b = 7;. Потоа отпечатете ги
нивниот збир, разлика и производ во три последователни редови на
екранот.
Вежба 1.9.3
Нека е дефинирано:
int x;
float y;
char z;
x = 2; y = 5.8; z = 'P';
Со која наредба ќе се отпечатат вредностите на променливите x, y
и z, така што да бидат одвоени со по едно празно место, а потоа да се
премине во нов ред?
7
Количината на меморијата што ја зафаќаат типовите податоци може да варира од една
компјутерска платформа до друга.
41
ПРОГРАМИРАЊЕ
+ собирање
‒ одземање и негација
* множење
/ делење (реални броеви) и цел дел од количник (цели броеви)
% делење по модул (остаток од делење)
Операторот за делење / може да се користи за операнди со различни ти-
пови. Притоа, ако двата операнди се целобројни и резултатот ќе биде
целоброен. На пример:
10 / 4 = 2,
10 / 4.0 = 2.5
Примери:
7 / 3 = 2
205 / 20 = 10
205 % 20 = 5
‒25 % 3 = ‒1
7.0 / 4 = 1.7500
Со употреба на загради, се менува редоследот на извршување на опера-
циите одреден со приоритетите на операторите.
Примери:
(1 + 2 * (3 + 4)) % (5 ‒ 6)
(1 + 2 * 7) % (5 ‒ 6)
(1 + 14) % (‒1)
15 % (‒1)
0
Стандарден оператор за доделување вредност е = .
Примери:
int prvbroj, vtorbroj, ;
short int cifra;
...
prvbroj = (1 + 2 * 7) % (5 ‒ 6);
prvbroj = prvbroj + cifra;
vtorbroj = vtorbroj / cifra;
С++ го дозволува и следниов начин на доделување вредности:
x = (y = 10) * (z = 5) при што се добива x = 50
x = y = z = 20 при што се добива x = 20, y = 20, z = 20
Примери:
prvbroj += cifra; е исто што и prvbroj = prvbroj + cifra;
vtorbroj /= cifra; е исто што и vtorbroj = vtorbroj / cifra;
Податоците од знаковен тип може да имаат вредност кој било знак или
која било целобројна вредност. Тие може да бидат променливи или константни
податоци. Се декларираат со зборот char.
Примери:
char a;
char znak = '+';
const char evro = 'E';
char denar = 'd';
char ascii = 120;
Податоците од знаковен тип може да се третираат како кој било цело-
броен тип. Со нив може да се извршуваат аритметички операции, тие може да се
читаат, да се печатат и да се споредуваат.
Вредностите и опсегот на податоците од знаковен тип се дадени во
табела 1.10.2.
Тип Вредности Меморија
char ‒128... 127 8 бита
unsigned char 0... 255 8 бита
Табела 1.10.2
Реален тип податоци
43
ПРОГРАМИРАЊЕ
Податоците чија вредност може да биде или true или false се од логички
тип. Тие се декларираат со зборот bool.
Примери:
bool dane;
bool semafor = true;
Со податоците од логички тип може да се користат и логичките операто-
ри (функции):
&& логичко И (AND)
|| логичко ИЛИ (OR)
! логичко НЕ (NOT)
Со сите претходно наведени типови податоци може да се користат рела-
циските оператори:
< помало
<= помало или еднакво
> поголемо
>= поголемо или еднакво
== еднакво
!= различно
45
ПРОГРАМИРАЊЕ
Приоритет на операторите
8
Рутина е која било функција која може да се повикува и извршува каде било во програ-
мата.
46
1. Основи на програмирање
realenbroj = 456.78;
тогаш со наредбата:
cout << celbroj << realenbroj;
ќе се отпечати
123456.78
За разделување на отпечатените вредности се користат еден или повеќе
бланко знаци. Така, со следнава наредба
cout << celbroj << ʼ ‘ << realenbroj << endl;
ќе се отпечати:
123 456.78
endl е оператор за крај на линијата, т. е. служи за преминување во следната
линија. За печатење во нов ред, се користи и знакот '\n' .
На пример, со наредбата:
cout << celbroj << ʼ\n‘ << realenbroj << '\n‘;
или
cout << celbroj << endl << realenbroj << endl;
ќе се отпечати:
123
456.78
Неколку специфични знаци, кои имаат специјално значење кај наредбата
за печатење, се печатат со користење на т.н. излезни секвенци. Во следнава
табела се прикажани некои од излезните секвенци.
Излезна секвенца Опис
\“ печатење наводници
\\ печатење коса црта
\a печатење ѕвоно (аларм)
\n поставување на покажувачот на почетокот на
следната линија
\r поставување на покажувачот на почетокот
на тековната линија
\t поместување на покажувачот на следната
таб-позиција
Примери
Пример 1.11.1
Во следнава задача се разгледува едноставна програма во С++ за со-
бирање на два броја, во која ќе илустрираме некои од особините разгледани во
претходниот дел од текстот.
// Sobiranje na dva broja
#include <iostream>
using namespace std;
47
ПРОГРАМИРАЊЕ
int main()
{ // почеток на main()
int broj1; // deklaracija na celobrojnata
// promenliva broj1
cout << "Vnesete prv cel broj\n";
cin >> broj1; // citanje vrednost na broj1
int broj2, zbir; // deklaracija na celobrojnite
// promenlivi broj2 i zbir
cout << "Vnesete vtor cel broj\n";
cin >> broj2; // citanje vrednost na broj2
48
1. Основи на програмирање
Следната наредба:
cin >> broj1;
го користи стандардниот влезен поток cin и операторот >> за преземање пода-
тоци кои се внесуваат преку тастатурата како низа од знаци. Оваа наредба може
да се прочита како „cin го чита потокот од знаци кој се внесува преку тастатурата
и му го доделува на променливата broj1“. Во конкретниов случај, знаците кои се
внесуваат се цифри на бројот, цифрите се конвертираат во цел број и тој ѝ се
доделува на целобројната променлива broj1.
Линијата:
cout << "Zbirot e" << zbir << endl;
содржи една наредба cout за печатење на повеќе вредности. Пред секоја вред-
ност, се наведува операторот <<. Со првиот оператор, се печати (испраќа на
екран) текстот Zbirot e, а со вториот оператор се печати вредноста на промен-
ливата zbir. По третиот оператор, е наведена наредбата endl (скратено од end
line), со која покажувачот на екранот се поставува на почетокот од следниот ред.
Пример 1.11.2
Да се декларираат, внесат и отпечатат податоци од целоброен тип, реален
тип и знаковен тип.
#include <iostream>
using namespace std;
int main()
{
int x; // Deklaracija na podatok od celobroen tip
float y; // Deklaracija na podatok od realen tip
char z; // Deklaracija na podatok od znakoven tip
cout << "Vneseniot podatok od celobroen tip e: " << x << endl;
cout << "Vneseniot podatok od realen tip e: " << y << endl;
cout << "Vneseniot podatok od znakoven tip e: " << z << endl;
return 0;
}
49
ПРОГРАМИРАЊЕ
Пример 1.11.3
Следнава програма илустрира некоректно користење на променливата
vkupno бидејќи ѝ се доделува вредност која е поголема од опсегот на вредности
според декларацијата.
#include <iostream>
using namespace std;
int main()
{
short ed_cena, vkupno; /* Deklaracija na promenlivi */
short parcinja = 1000; /* Deklaracija so inicijalizacija*/
ed_cena = 50; /* Dodeluvanje vrednost */
vkupno = ed_cena * parcinja;
cout << "Vkupnata cena za " << parcinja;
cout << " parcinja e " << vkupno << endl;
return 0;
}
Излезот на оваа програма е:
Vkupnata cena za 1000 parcinja e ‒15536.
Пример 1.11.4
Даден е цел трицифрен број k. Да се напише програма во која преку
тастатурата се внесува бројот k и потоа се печати збирот на неговите цифри.
(На пример, за влез 543, на излезот се печати 12).
d = k / 10 % 10;
s = k / 100;
cout << e + d + s << endl;
return 0;
}
Вежби
Вежба 1.11.1
Нека е дефинирано:
int x;
float y;
char z;
Со која наредба ќе се внесат вредностите на променливите x, y и z?
Вежба 1.11.2
Да се решат следниве задачи:
1. Да се напише програма за пресметување на производот на два
внесени броја.
2. Пресметајте ја разликата на два внесени броја.
3. За четири броеви, внесени преку тастатурата, да се пресмета нивната
средна вредност.
4. Напишете програма која на екранот ќе го даде следниов излез:
* * * *
* *
* * * *
5. Напишете програма која на екранот ќе го даде следниов излез:
* * *
* *
* *
* * *
6. Напишете програма која на екранот ќе го даде следниов излез:
*
* *
* *
7. Напишете програма која за внесен трицифрен број ги печати секоја
од неговите цифри во посебен ред.
Пример:
Vnesi broj: 897
Cifrite se:
8
9
7
51
ПРОГРАМИРАЊЕ
Вежба 1.11.3
Од 1990 година, во организација на Здружението на информатича-
рите на Македонија, секоја година се одржуваат државни натпревари по
информатика. Во учебников ќе бидат наведени задачи од натпреварите
кои може да се решат со досегашните знаења.
Од стекнатите знаења во оваа глава, учениците се во можност да ги
решат следните задачи:
1. За даден интервал [а,b], најдете го збирот на сите непарни пози-
тивни броеви помеѓу а и b.
2. Најверната другарка на Стојче е Пуфи. Таа обожава да носи шноли во
својата коса и секогаш доаѓа на училиште со шноли во најмногу 3 бои
(жолта, црвена и сина). Стојче сака секогаш бројот на шноли кои ги
има Пуфи во косата да е делив со 3. Затоа, тој секогаш си носи бели
шноли и ѝ дава на Пуфи за да го направи вкупниот број на шноли де-
лив со 3. Бидејќи Стојче мора да има шноли и за наредните денови,
ако знаете по колку шноли има Пуфи во косата од секоја боја, пресме-
тајте му на Стојче колку најмалку бели шноли треба да ѝ даде на
Пуфи за да постигне вкупен број на шноли делив со 3.
3. Во една земја за формирање на влада коалицирале две партии: ПА и
ПБ. При формирањето на владата, било одлучено дека ќе има нај-
многу N министерства, подредени по значајност (М1, М2, М3...). Се-
кој член на партиите можел да предложи како да изгледа новата вла-
да. Предлогот вклучувал: број на министерства и во кое министер-
ство од која партија ќе биде министерот. Така, на пример, предлози
кои биле дадени се:
N = 3: М1 – ПА, М2 – ПБ, М3 – ПА;
N = 4: М1 – ПА, М2 – ПА, М3 –ПА, М4 – ПА;
N = 1: М1 – ПБ;
итн.
Бидејќи процесот на предлагање траел долго, биле дадени сите
можни предлози за големина на влада од 1 до N министри. Напишете
програма која, за дадено N, ќе пресметува колку различни предлози
биле дадени.
4. Иван ја игра својата омилена компјутерска игра, која има неколку
нивоа. Иван почнува од ниво 1 и треба да потроши P поени за да дој-
52
1. Основи на програмирање
53
ПРОГРАМИРАЊЕ
Резиме
54
2. Основни контролни структури
55
ПРОГРАМИРАЊЕ
Клучни зборови
do-while за-намалувај-до
for извршувај-додека
if Иницијализација
if-else Логички израз
switch Логички операции
while Неточно (false)
Ажурирање Оператор за декрементирање
ако-или-ако-инаку Оператор за инкрементирање
Повторување со броење на
ако-тогаш
циклусите
Повторување со излез на крајот од
ако-тогаш-инаку
циклусот
Алгоритамска контролнa
Повторување со излез на почетокот
структурa за повторување со излез
од циклусот
на почетокот од циклусот
Алгоритамска контролна
структура за избор од две Постфиксен
можности
Алгоритамска контролна
структура за избор од повеќе Прекин
можности
Алгоритамска редоследна
Префиксен
контролна структура
Вгнездување случај
Висечко else Точно (true)
Де Морганови закони Условен оператор ?:
додека-извршувај Циклично повторување
за-до-чекор циклус
за-зголемувај-до
56
2. Основни контролни структури
57
ПРОГРАМИРАЊЕ
Вежби
Вежба 2.1.1
Одредете ја вредноста на следните споредбени изрази:
а) 3 > 5;
б) 7 + 8 <= 3;
в) 9 + 4 == 8 + 5;
Која е нивната бројна вредност?
Вежба 2.1.2
Ако а и b се реални променливи со вредности 3 и 5.6, одредете ја
вредноста на следниве изрази:
!7
7 && а
(а * 0) && (b + 1)
(а * 0) || (b + 1)
!(а < b)
!(a > b)
!((a – b) * 3 && b)
Која е нивната бројна вредност?
58
2. Основни контролни структури
Слика 2.2.4
59
ПРОГРАМИРАЊЕ
Вежба 2.2.3
За следниве задачи да се напишат алгоритми со користење на ре-
доследната контролна структура и структурата за избор од две мож-
ности.
1. Да се пресметаат квадратот и кубот на природниот број n.
2. Да се пресметаат обиколката на кружницата и плоштината на кругот
со радиус r.
3. Да се прочита трицифрен природен број и да се отпечати средната
цифра.
4. Да се прочитаат три броја и да се утврди дали може да бидат страни
на триаголник.
5. Да се подредат три броја по големина.
6. Да се утврди дали природниот број n е парен или непарен.
7. Да се реши линеарната равенка: ax + b = 0.
8. Да се реши линеарната неравенка: ax + b > 0.
61
ПРОГРАМИРАЊЕ
Пример: Пример:
if (x < 0) int x;
xaps = –x; if (x)
cout << x << endl;
Забелешка:
Со чекори А ќе го означиме блокот чекори:
чекор А1;
...
чекор Ај;
Истото важи и за чекори Б, наредби А и наредби Б.
Ако некој од блоковите наредби А или наредби Б има само една наредба,
тогаш не мора да се стават заградите:
if (услов)
наредба 1;
else
наредба 2;
Контролните наредби за избор if и if-else може да се вгнездуваат една во
друга. Притоа, треба да се води сметка дека преведувачот во С++ секое else го
поврзува со претходното if. На пример, во следниот програмски сегмент, за a < b
нема ништо да се отпечати бидејќи else е врзано со второто if, а не со првото:
if (a > b)
if (a > c)
cout << "Najgolem broj e " << a;
62
2. Основни контролни структури
else
cout << "Najgolem broj ne e " << a;
Ова е наречено проблем на висечко else (англ. dangling-else problem).
Ако вгнездувањето се врши во else, се добива контролната структура
ако-или-ако-инаку.
Пример:
if (услов 1)
наредба 1;
else if (услов 2)
наредба 2;
else if (услов 3)
наредба 3;
else
наредба 4;
а
if (услов 1)
наредба 1;
else if (услов2)
{ наредба 2;
if (услов 3)
наредба 3;
}
else
наредба 4;
б
Горните два примери под а) и под б) се различни. Во случајот под а),
наредба 4 ќе се изврши само ако сите три услови не се исполнети, а во случајот
под б), кога не се исполнети првиот и вториот услов, независно дали е исполнет
третиот услов.
Рековме дека услов претставува логички израз кој може да има само две
вредности: true или false. Во него може да се користат релациските и логичките
оператори со кои се запознавме претходно.
Важат и Де Моргановите закони за:
дистрибуција на негацијата и И: !(m || n) дава !m && !n
дистрибуција на негацијата и ИЛИ: !(u && v) дава !u || !v
63
ПРОГРАМИРАЊЕ
Примери:
Пример 2.3.1
Да се провери дали зададен агол е остар или не.
алгоритам Агол
почеток
печати „Внесете агол во степени: “;
читај аlfa;
ако ((аlfa > 0) И (alfa < 90))
тогаш
печати „Аголот е остар.“;
инаку
печати „Аголот не е остар.“;
крај_ако {((alfa > 0) И (alfa < 90))
крај {Aгол}
#include <iostream>
using namespace std;
int main()
{
int alfa;
cout << "Vnesete agol vo stepeni: " << endl;
cin >> alfa;
if ((alfa > 0) && (alfa < 90))
cout << "Agolot e ostar. " << endl;
else
cout << "Agolot ne e ostar. " << endl;
return 0;
}
Пример 2.3.2
Да се провери дали зададен број е поголем, еднаков или помал од 5.
алгоритам Броеви
почеток
печати „Внесете број и притиснете Enter: “;
читај i;
ако i > 5
тогаш
печати „Бројот е поголем од 5. “;
печати „i = “, i;
64
2. Основни контролни структури
инаку
ако i < 5
тогаш
печати „Бројот е помал од 5.“;
инаку
печати „Бројот е еднаков на 5.“;
крај_ако {i < 5}
крај_ако {i > 5}
крај {Броеви}
#include <iostream>
using namespace std;
int main()
int i;
cout << "Vnesete broj i pritisnete Enter: " << endl;
cin >> i;
if (i > 5)
{
cout << "Brojot e pogolem od 5. " << endl;
cout << "i = " << i << endl;
}
else
if (i < 5)
cout << "Brojot e pomal od 5. " << endl;
else
cout << "Brojot e ednakov na 5. " << endl;
return 0;
}
Пример 2.3.3
Да се погоди кој број помеѓу 1 и 10 го замислил компјутерот.
алгоритам ПогодувањеБрој
почеток
zamislenBroj 7;
печати „Внесете број помеѓу 1 и 10: “;
читај broj;
ако broj = zamislenBroj
тогаш
печати „Браво, погодивте.“;
инаку
печати „Жалам, не погодивте.“;
печати „Замислениот број е: “;
65
ПРОГРАМИРАЊЕ
печати zamislenBroj;
крај_ако {broj = zamislenBroj}
крај {ПогодувањеБрој}
#include <iostream>
using namespace std;
int main()
{
int zamislenBroj = 7, broj;
cout << "Vnesete broj megju 1 i 10: " << endl;
cin >> broj;
if (broj == zamislenBroj)
cout << "Bravo, pogodivte. " << endl;
else
{
cout << "Zalam, ne pogodivte! " << endl;
cout << "Zamisleniot broj e ";
cout << zamislenBroj << endl;
}
return 0;
}
Пример 2.3.4
Да се одреди најголемиот од три дадени броја.
алгоритам НајголемБрој
почеток
печати „Внесете три различни броја: “;
читај a, b, c;
ако a > b
тогаш
ако a > c
тогаш
печати a;
инаку
печати c;
крај_ако {a > c}
инаку
ако b > c
тогаш
печати b;
инаку
печати c;
крај_ако {b > c}
66
2. Основни контролни структури
крај_ако {a > b}
крај {НајголемБрој}
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
cout << "Vnesete tri razlicni broja: " << endl;
cin >> a >> b >> c;
if (a > b)
if (a > c)
cout << a << endl;
else
cout << c << endl;
else
if (b > c)
cout << b;
else
cout << c;
return 0;
}
Условен оператор ?:
Условниот оператор се користи за претставување на едноставни наредби
if-else. Неговата синтакса е:
услов? израз Т : израз Н;
Прво се пресметува услов чија вредност може да биде true или false. Ако е
true, тогаш се пресметува израз Т, а ако е false се пресметува израз Н.
На пример:
if (m > n)
s = m – n;
else
s = n – m;
Програмскиот сегмент може да се запише и на следниов начин:
s = (m > n) ? (m – n) : (n – m);
Со следнава наредба ќе се отпечати „paren.“ ако променливата broj има
парна вредност, во спротивно ќе се отпечати „neparen.“.
cout << "Brojot " << broj << " e " << (broj % 2) ? "paren." :
"neparen.";
На пример, за broj = 5 ќе се отпечати:
Brojot 5 e neparen.
67
ПРОГРАМИРАЊЕ
Вежби
Вежба 2.3.1
Да се одговори на следниве прашања:
1. Од каков тип е изразот кај структурата за избор од две можности?
2. Која структура се добива со вгнездување на наредбите if-else?
Вежба 2.3.2
Да се најде грешката во следниов програмски сегмент:
if (x = a)
cout << x << " ima ista vrednost so a. " ;
else
cout << x << " ima razlicna vrednost od a. ";
Вежба 2.3.3
Да се утврди што ќе се отпечати при извршување на следниов
програмски сегмент:
int i = 0, n;
float a = 1;
char c = 'a';
a++;
if (c == a && i == 0)
n = 1;
else
n = 2;
cout << 'n = ' << n << endl;
Резултатот да се провери со вметнување на дадениот програмски
сегмент во програма и нејзино извршување.
Вежба 2.3.4
Да се напишат алгоритми со контролните структури за избор од
две можности ако-тогаш или ако-тогаш-инаку и програми со наредби-
те if или if-else.
1. За внесен агол помал од 180о и да се утврди дали е остар, прав или
тап.
2. Да се подредат три броја по големина во растечки редослед.
3. Да се најде најголемиот од три реални броја.
4. Да се утврди дали три цели броја можат да бидата страни на
триаголник.
5. Да се одреди дали некоја година е престапна.
68
2. Основни контролни структури
Вежба 2.4.2
За следниве задачи да се напишат алгоритми, со користење на
алгоритамската контролна структура за избор од повеќе можности
случај.
1. Да се внесе буква и да се утврди дали е голема или мала.
2. Да се внесе агол α и да се утврди дали е остар или тап.
3. Да се внесе природен број помал од 10 и да се отпечати дали е прост,
делив со 2, делив со 3 или совршен.
4. Да се внесат два броја и еден оператор: +, –, * или / и да се отпечати
резултатот од соодветната операција.
5. Да се отпечати следново мени:
1. Професор по македонски јазик
2. Професор по математика
3. Професор по информатика
4. Професор по физика
Потоа во зависност од внесениот број (еден од броевите 1, 2, 3, 4), да
се отпечати името на соодветниот професор.
70
2. Основни контролни структури
71
ПРОГРАМИРАЊЕ
switch (znak) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
cout << znak << endl;
break;
}
Примери
Пример 2.5.1
Да се внесе цифра меѓу 1 и 9 и да се отпечати дали е парна или непарна.
Ако не сме внеле цифра меѓу 1 и 9, да се даде коментар за грешен влез.
алгоритам Број
почеток
печати „Внесете број помеѓу 1 и 9: “;
читај broj;
случај broj
1, 3, 5, 7, 9:
печати „Внесовте непарен број.“;
2, 4, 6, 8:
печати „Внесовте парен број.“;
инаку
печати „Бројот не е меѓу 1 и 9.“;
крај_случај {broj}
крај {Број}
#include <iostream>
using namespace std;
int main() {
int broj;
cout << "Vnesete broj pomegju i i 9: ";
cin >> broj;
switch (broj) {
case 1:
case 3:
case 5:
case 7:
case 9:
cout << "Vnesen e neparen broj. " << endl;
72
2. Основни контролни структури
break;
case 2:
case 4:
case 6:
case 8:
cout << "Vnesen e paren broj." << endl;
break;
default:
cout << "Brojot ne e megju 1 i 9." << endl;
}
return 0;
}
Пример 2.5.2
Да се состави алгоритам со кој ќе се одреди бројот на денови за
внесен месец. Месеците се внесуваат со редниот број: 1, 2... 12.
алгоритам ДеновиВоМесец
почеток
печати „Внесете го редниот број на месецот: “;
читај meces;
случај mesec
1, 3, 5, 7, 8, 10, 12: печати „Месецот има 31 ден.“;
4, 6, 9, 11: печати „Месецот има 30 дена.“;
2: печати „Февруари во престапни години има 29
дена. Во сите останати има по 28 дена.“;
инаку: печати „Внесовте грешен број на месец.“;
крај_случај {mesec}
крај {ДеновиВоМесец}
Вежби
Вежба 2.5.1
Одговорете на следниве прашања:
1. Со кои наредби се реализирани контролните структури за избор во
C++?
2. Што ќе се отпечати како резултат од извршување на следниве
програмски сегменти:
a)
char znak;
znak = 'c';
switch( znak ) {
case 'a':
73
ПРОГРАМИРАЊЕ
case 'e':
case 'i':
case 'o':
case 'u':
cout << "Samoglaska." << endl;
break;
default:
cout << "Soglaska." << endl;
}
б)
char znak;
znak = 'a';
switch( znak ) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
cout << "Samoglaska." << endl;
break;
default:
cout << "Soglaska." << endl;
}
Вежба 2.5.2
Да се решат следниве задачи со користење на наредбата switch.
74
2. Основни контролни структури
75
ПРОГРАМИРАЊЕ
76
2. Основни контролни структури
Вежби
Вежба 2.6.1
Размислете и одговорете:
1. За кои типови проблеми се ко-
ристат алгоритамските кон-
тролни структури за повтору-
вање?
2. Која алгоритамска контролна
структура за повторување ќе ја
користиме доколку е можно
структурата да не се изврши
ниту еднаш? Зошто?
Вежба 2.6.2
Што работи следниов алго- Слика 2.6.4 б
ритамски сегмент:
додека r | k извршувај {r | k значи r го дели k без остаток}
печати r;
k k / r;
крај_додека { r | k }
Вежба 2.6.3
Што печати следниов алгоритам:
алгоритам Непознат
почеток
печати „Внесете број: “;
читај n;
s 0;
77
ПРОГРАМИРАЊЕ
i 1;
додека i n извршувај
печати „Внесете број: “;
читај x;
s s + x;
i i + 1;
крај_додека {i n}
печати s;
крај {Непознат}
Вежба 2.6.4
Да се напишат алгоритми за следниве задачи со користење на ал-
горитамската контролна структура додека-извршувај.
1. Да се пресмета аритметичката средина на природните броеви до n.
2. Да се пресмета сумата 1 + 4 + 7 + 11 +… + n.
3. Да се внесе природен број и да се утврди колку цифри има.
4. Да се пресмета збирот на цифрите на природниот број n.
5. Да се најде бројот кој ги има истите цифри со природниот број n, но
во спротивен редослед.
6. Да се најдат сите делители на природниот број n.
Пример:
Вредност на х пред Израз Вредност на Вредност на х по
пресметувањето изразот пресметувањето
5 ++х 6 6
5 х++ 5 6
5 х 4 4
5 х 5 4
Инкрементирањето или декрементирањето може да се смета како краток
запис на наредба за доделување, преку која на дадена променлива ѝ се доделува
вредност различна за 1 од нејзината дотогашна вредност.
Следнава програма илустрира употреба на оператор за инкрементирање:
#include <iostream>
using namespace std;
int main() {
int a, b, c;
a = b = c = 1;
cout << a << " " << b << " " << c << endl;
a = b + c++;
cout << a << " " << b << " " << c << endl;
a = b = c = 1;
a = b + ++c;
cout << a << " " << b << " " << c << endl;
return 0;
}
По извршување на програмата, излезот е:
1 1 1
2 1 2
3 1 2
Притоа, важи дека условот (услов) е логички израз кој може да има
вредност true или false. Условот (услов) се испитува пред почетокот на секој
циклус. Ако вредноста на условот (услов) е true (или е израз со вредност различна
79
ПРОГРАМИРАЊЕ
int main() {
int n;
int broj = 0;
int zbir = 0;
cout << "Vnesete go n = ";
cin >> n;
while (broj < n) {
++broj;
zbir += broj;
}
cout << "Zbirot na prvite " << n;
cout << " prirodni broevi e " << zbir << endl;
return 0;
}
По извршување на програмата, излезот е:
Vnesete go n = 7
Zbirot na prvite 7 prirodni broevi e 28
80
2. Основни контролни структури
Пример 2.7.2
Да се пресмета бројот на знаци во еден ред внесен текст.
Објаснување: За прекинување на повторувањето, честопати се користи
споредба со одреден знак или текст. Во следнава програма, повторувањето се
извршува додека вредноста на променливата znak е различна од знакот за крај на
линијата '\n'.
#include <iostream>
using namespace std;
int main() {
char znak;
cout << "Vnesete tekst: ";
int brojznaci = 0;
cin.get (znak);
while (znak != '\n') {
++brojznaci;
cin.get(znak);
}
cout << "Brojot na vneseni znaci e " << brojznaci << endl;
return 0;
}
Еден можен излез е:
Vnesi tekst: eden dva tri
Brojot na vneseni znaci e 12
Во програмата за читање на еден знак се користи посебна наредба
(функција) cin.get(). Разликата во однос на користење на наредбата cin е следна-
ва: со користење на наредбата cin << znak;, кога на корисникот ќе му се појави
курсорот кој му покажува да внесе знак, корисникот треба да внесе еден знак и
да притисне Enter или празно место за да може знакот да се внесе во меморија и
да се продолжи со извршување на програмата. Со користење на наредбата
cin.get(znak);, кога на корисникот ќе му се појави курсорот кој му укажува да
внесе знак, корисникот треба да внесе еден знак, без да притисне Enter или што
било друго. Знакот кој го внел ќе се внесе во меморијата и ќе се продолжи со
извршување на програмата. Еден совет кој треба да се запамети е: доколку е
можно, во иста програма да се користи само наредбата cin или само наредбата
cin.get(). Ова е важно за помалку искусните програмери затоа што комбинаци-
јата на овие две наредби може да предизвика некои странични ефекти.
Пример 2.7.3
Да се најде најголемиот заеднички делител за два природни броја.
Објаснување: Најголемиот заеднички делител (НЗД) за два броја може да
биде помалиот од нив ако се броевите деливи еден со друг, или првиот број по-
81
ПРОГРАМИРАЊЕ
int main() {
int nzd, a, b;
cout << "Vnesete dva prirodni broja: " << endl;
cin >> a;
cin >> b;
if (a < b)
nzd = a;
else
nzd = b;
while ((a % nzd != 0) || (b % nzd != 0))
nzd = nzd – 1;
cout << "Najgolem zaednicki delitel na " << a;
cout << " i " << b << " e " << nzd << endl;
return 0;
}
Излезот од извршување на програмата е:
Vnesete dva prirodni broja:
80
120
Najgolem zaednicki delitel na 80 i 120 e 40
Вежби
Вежба 2.7.1
Да се даде одговор на следниве прашања:
1. Која е општата синтакса на наредбата while?
2. Какви вредности може да прими условот во наредбата while?
Вежба 2.7.2
Да се најде грешката во следниов програмски сегмент:
x = 1;
while (x >= 0)
suma = suma + x;
82
2. Основни контролни структури
Вежба 2.7.3
Да се утврди што ќе се отпечати по извршување на следниов про-
грамски сегмент:
i = 0;
while (i < 10) {
i = i + 2;
cout << i << endl;
}
Вежба 2.7.4
Да се испечатат целите броеви од 1 до 20, со користење на на-
редбата while и контролна променлива i.
Вежба 2.7.5
Да се решат следниве задачи со користење на наредбата while:
1. Да се пресмета сумата на n цели броеви.
2. Да се пресмета производот на внесени цели броеви додека се внесува
број различен од нула.
3. Да се провери дали природниот број n е прост или не е.
4. Да се отпечатат сите прости броеви помали од природниот број n.
5. Да се претстави бројот n во бинарниот броен систем.
6. Да се пресмета вредноста на бројот e = 2.718281 со дадена точност ,
1 1 1 1
преку изразот e 1 ... (Точноста се постигнува
1! 2! 3! 4!
1
кога собирокот < ).
к!
7. Да се пресмета производот 1 2 3 … n.
8. Да се отпечатат буквите од абецедата од A до Z.
9. Да се пресмета збирот на броевите од a до b со чекор c, т. е.
вредноста на изразот a + (a + c) + (a + 2c) + (a + 3c) +…
10. Да се отпечати спротивниот број на природниот број n кој не завр-
шува со 0.
83
ПРОГРАМИРАЊЕ
Слика 2.8.3
84
2. Основни контролни структури
Примери
Пример 2.9.1
Да се најде збирот на првите n природни броеви.
85
ПРОГРАМИРАЊЕ
#include <iostream>
using namespace std;
int main() {
int n;
int broj = 1;
int zbir = 0;
cout << "Vnesete kolku broevi kje sobirate, n = ";
cin >> n;
do {
zbir += broj;
++broj;
} while (broj <= n);
cout << "Zbirot na prvite " << n << " prirodni broevi e ";
cout << zbir;
return 0;
}
По извршувањето на програмата, излезот е:
Vnesete kolku broevi kje sobirate, n = 10
Zbirot na prvite 10 prirodni broevi e 55
Пример 2.9.2
Да се пресмета вредноста на бројот e = 2.718281 со дадена точност ,
1 1 1 1
преку изразот e 1 ... (Точноста е постигната кога последниот
1! 2! 3! 4!
1
собирок ).
k!
алгоритам БројотЕ
почеток
печати „Внеси ја точноста за пресметување на бројот е (пр., 0.001)“;
читај ;
e 1;
i 1;
clen 1;
извршувај
clen clen / i;
e e + clen;
i i + 1;
додека clen >= ;
крај_извршувај
печати „Бројот е со точност “, , „ изнесува “, e;
крај {БројотЕ}
86
2. Основни контролни структури
#include <iostream>
using namespace std;
int main() {
int i;
double e, eps, clen;
cout << "Vnesete tocnost, eps = "; cin >> eps;
e = 1;
i = 1;
clen = 1;
do {
clen /= i;
e += clen;
i++;
}while (clen >= eps);
cout << "Brojot e so tocnost " << eps << " iznesuva " << e;
return 0;
}
Вежби
Вежба 2.9.1
Oдговорeтe на следниве прашања:
1. Која контролна структура се реализира со наредбата do-while?
2. Која е разликата помеѓу наредбата while и do-while?
Вежба 2.9.2
Да се утврди што извршува следниов програмски сегмент:
x = 1; i = 0;
do {
x++;
i += x;
}while (x <= 10);
Вежба 2.9.3
Да се утврди што ќе се отпечати како резултат на извршување на
следниов програмски сегмент:
i = 0;
do {
i += 2;
cout << i << endl;
}while (i < 5);
Вежба 2.9.4
Да се отпечатат сите цели броеви од 1 до 20, со користење на
наредбата do-while.
87
ПРОГРАМИРАЊЕ
Слика 2.10.12 а б
в
Слика 2.10.13
91
ПРОГРАМИРАЊЕ
На пример, алгори-
алгоритам ТаблицаМножење
тамот за таблицата за мно-
почеток
жење до 10 ќе изгледа како
на слика 2.10.14. за i 1 зголемувај до 10
печати „Множење со “, i ;
за j 1 зголемувај до 10
ipoj i j;
печати i, „ “, j, „ = “, ipoj;
крај_за {j}
крај_за {i}
крај {ТаблицаМножење}
Слика 2.10.14
Вежби
Вежба 2.10.1
Размислете и одговорете: Доколку знаеме колку пати треба да се
реализира некоја редоследна структура, која структура за повторување е
најверојатно дека ќе ја користиме?
Вежба 2.10.2
Што прави следниов алгоритамски сегмент:
zbir 0;
за broj 2 до 10 чекор 2
zbir zbir + broj;
крај_за {broj}
печати zbir;
Вежба 2.10.3
Што прави следниов алгоритамски сегмент:
zbir 0;
за broj 2 до 10 чекор 2
zbir zbir + broj;
печати zbir;
крај_за {broj}
Која е разликата меѓу претходните два алгоритамски сегменти?
Вежба 2.10.4
Покажете како треба да се модификуваат алгоритмите дадени на
сликите 2.10.8 и слика 2.10.10 за да се пресмета збирот на парните бро-
еви од 10 до 1.
92
2. Основни контролни структури
Вежба 2.10.5
За следниве задачи да се напишат алгоритми со користење на ал-
горитамските контролни структури: за-до-чекор, за-зголемувај-до или
за-намалувај-до.
1 1 1
1. Да се пресмета производот: 1 ... .
2 3 n
2. Да се пресмета збирот:
1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) +… + (1 + 2 +… + n).
3. Да се пресмета збирот:
(1 + 2 +… + n) + (2 + 3 +… + n) +… + (n – 1 + n) + n.
4. Да се најдат Питагорините броеви до 100. (Питагорини броеви се
тројките броеви (x, y, z) за кои важи x2 + y2 = z2) .
5. Да се најдат сите совршени броеви до 1 000. (Совршен број е оној кој
е еднаков на збирот на своите делители без самиот број).
6. Да се најдат сите пријателски броеви до 10 000. (Два броја се прија-
телски ако збирот на делителите на едниот број е еднаков на другиот
и збирот на делителите на другиот број е еднаков на првиот. Во
делители на бројот не спаѓа самиот број).
93
ПРОГРАМИРАЊЕ
int main() {
int n, broj, zbir = 0;
cin >> n;
for (broj = 1; broj <= n; broj += 2)
zbir += broj;
cout << "Zbirot na neparnite broevi do " << n << " e ";
cout << zbir << endl;
return 0;
}
Наредбата for дозволува иницијализација и ажурирање на повеќе промен-
ливи.
Во делот за иницијализација може да се иницијализираат повеќе промен-
ливи. Притоа, тие се одделуваат со запирки. Претходниот пример може да се на-
пише и на следниов начин:
#include <iostream>
using namespace std;
int main() {
int n, broj, zbir = 0;
cin >> n;
for (broj = 1, zbir = 0; broj <= n; broj += 2)
zbir += broj;
94
2. Основни контролни структури
cout << "Zbirot na neparnite broevi do " << n << " e ";
cout << zbir << endl;
return 0;
}
Условот (услов) може да биде кој било логички израз во кој може да се
користат релациски и логички оператори. На пример, услов во претходната про-
грама може да биде: broj <= n && (broj % 2 == 1). Програмата со овој услов ќе
биде:
#include <iostream>
using namespace std;
int main() {
int n, broj, zbir = 0;
cin >> n;
for (broj = 1, zbir = 0; ( broj <= n ) && ( broj % 2 == 1 ); broj += 2)
zbir += broj;
cout << "Zbirot na neparnite broevi do " << n << " e ";
cout << zbir << endl;
return 0;
}
Во делот за ажурирање може да се ажурираат повеќе променливи, при
што тие се одделуваат со запирки. На пример:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1, j = n; i <= n && j >= 1; ++i, – –j)
cout << i + j << endl;
return 0;
}
Делот за иницијализација и ажурирање може да биде и празен. Тоа е по-
кажано на следнава програма.
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int i = 1, j = n;
for (; i <= n && j >= 1;) {
++i;
95
ПРОГРАМИРАЊЕ
– –j;
cout << i + j << endl;
}
return 0;
}
Наредбите for може да се вгнездуваат една во друга:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j)
cout << i << " * " << j << " = " << i * j << "\t";
cout << endl << endl ;
}
}
Примери
Пример 2.11.1
Да се најдат сите Питагорини броеви помали од природниот број n.
Објаснување: Питагорини броеви се секоја тројка природни броеви x, y и
z што го задоволуваат равенството x2 + y2 = z2. (За да не се повторуваат тројките,
како на пр., 3, 4, 5 и 4, 3, 5, х ќе се менува од 1 до вредност не поголема од у, т. е.
n2
до (ако х = у) ).
2
алгоритам ПитагориниБроеви
почеток
печати „До кој природен број?“;
читај n;
n2
за x 1 зголемувај до
2
за y x зголемувај до n
z x 2 y 2 ;
ако z ≤ n И x2 + y2 = z2
тогаш
печати „Питагорина тројка: “, x, y, z;
крај_ако {z ≤ n И x2 + y2 = z2}
крај_за {y}
96
2. Основни контролни структури
крај_за {x}
крај {ПитагориниБроеви}
#include<iostream>
#include<cmath>
using namespace std;
int main() {
int n, x, y, z;
cout << „Do koj priroden broj: “;
cin >> n;
Пример 2.11.2
Да се најдат сите совршени броеви помали од природниот број n.
Објаснување: Природните броеви кои се еднакви на збирот на своите
делители, без самиот број, се нарекуваат совршени броеви. (На пример: 6, 28,
496...).
алгоритам СовршениБроевиДоN
почеток
печати „До кој број? “;
читај n;
печати „Совршени броеви до “, n, “ се: “;
за broj 2 зголемувај до n
zbir 0;
за delitel 1 зголемувај до broj
2
ако delitel | broj
тогаш
zbir zbir + delitel;
крај_ако {delitel | broj}
крај_за {delitel}
97
ПРОГРАМИРАЊЕ
int main() {
int n, broj, delitel, zbir;
cout << "Do koj broj, n = ";
cin >> n;
cout << "Sovrsheni broevi do " << n << " se: ";
for (broj = 1; broj < n; broj++) {
zbir = 0;
for (delitel = 1; delitel <= (broj / 2); delitel++) {
if (broj % delitel == 0)
zbir = zbir + delitel;
}
if (zbir == broj)
cout << broj << ", ";
}
return 0;
}
Вежби
Вежба 2.11.1
Да се одговори на следниве прашања:
1. Која контролна структура се реализира со наредбата for?
2. Што се врши во делот за иницијализација на наредбата for?
Вежба 2.11.2
Да се утврди што извршува следниов програмски сегмент:
for (x = 1, i = 0; x <= 10; x++)
i += x;
Вежба 2.11.3
Да се утврди што ќе се отпечати како резултат од извршување на
следниов програмски сегмент:
for (i = 0, j = 0; i < 5; i++, j– –)
cout << i + j << endl;
Вежба 2.11.4
98
2. Основни контролни структури
Вежба 2.11.5
Да се најде најмалиот заеднички содржател (НЗС) на два
природни броја.
Вежба 2.11.6
Да се напишат програми кои на екранот ќе ги отпечатат следниве
фигури:
...
*******
*****
***
*
***
*****
*******
...
д)
*****+
****++
***+++
**++++
*+++++
ѓ)
*****
* *
* *
* *
*****
е)
+*+*+
*****
+*+*+
*****
+*+*+
ж)
*
***
*****
*******
*****
***
*
100
2. Основни контролни структури
Резиме
101
ПРОГРАМИРАЊЕ
102
3. Сложеност на алгоритми
3. СЛОЖЕНОСТ НА АЛГОРИТМИ
Во оваа глава ќе се запознаете со следното:
Клучни зборови
103
ПРОГРАМИРАЊЕ
104
3. Сложеност на алгоритми
Табела 3.2
Од табела 3.2 се гледа дека за големи вредности на n, односот на вре-
мињата на извршување на алгоритмите d и b е константен и изнесува 5. Затоа,
можеме да напишеме дека Td(n) 5Tb(n), односно велиме дека временската сло-
женост на алгоритамот d е еднаква со временската сложеност на алгоритамот b.
Тоа се запишува како Td(n) O(n2), а се чита „големо О од n2“.
Ќе наведеме неколку примери. T(n) Сложеност
Поопшто, ако важи T(n) cf(n), ка- 3n – 10 O(n)
де f(n) е позната функција, а с константа, 3n2 – 10 O(n2)
велиме дека сложеноста на алгоритамот е 7n3 + 5n2 – 4n + 9 O(n3)
„големо О од f(n)“. Со други зборови, вре- n! O(n!)
мето на извршување T(n) асимптотски се
приближува кон функцијата f(n).
Буквата О доаѓа од зборот order (ред) на функцијата: n, n2, n3, logn, n! итн.
Нотацијата „големо О“ се користи за класификација на алгоритмите, според
најлошото време на извршување на алгоритмите.
Точната дефиниција на сложеност на алгоритам гласи:
Дефиниција:
T(n) = O(f(n)) за n ако c > 0 и n0,
така што ќе важи T(n) cf(n) за n > n0.
105
ПРОГРАМИРАЊЕ
Слика 3.1
Според сложеноста, алгоритмите може да се поделат на две групи:
Алгоритми со полиномна сложеност.
Алгоритми со експоненцијална сложеност.
Алгоритми со полиномна сложеност се оние за кои важи
T(n)
lim const 0 , P(n) = aknk + ak‒1nk‒1 +... + a0 , за некое k 0.
n P(n)
Тоа се запишува како T(n) = O(nk).
Ако важи lim T(n) тогаш алгоритамот има експоненцијална сложеност.
n P(n)
Според функцијата со која се изразува сложеноста, постојат следниве
видови сложеност на алгоритми:
Константна f(n) = constant
Линеарна f(n) = n
Логаритамска f(n) = log2n
Линеарно-логаритамска f(n) = n· log2n
Квадратна f(n) = n2
Степенска f(n) = nk (k > 2)
Експоненцијална f(n) = kn (k > 1)
Факториелна f(n) = n!
106
3. Сложеност на алгоритми
Слика 3.5
Пример:
Да се одреди сложеноста на алго-
ритамскиот сегмент даден на слика 3.6.
За секоја вредност на i од 1 до n,
внатрешното повторување ќе се изврши i
циклуси, односно:
за i = 1, j = 1 ‒ 1 циклус
за i = 2, j = 1, 2 ‒ 2 циклуси
за i = 3, j = 1, 2, 3 ‒ 3 циклуси Слика 3.6
...
за i = n, j = 1, 2, 3, 4... n ‒ n циклуси.
Вкупно 1 + 2 + 3 +…+ n = n(n + 1) / 2 циклуси, што е пропорционално со
n2 / 2, т. е. со n2. Значи, сложеноста е O(n2).
Алгоритми со квадратна сложеност се оние во кои има две вгнездени
контролни структури за повторување. Такви алгоритми се: сортирање низа со
истовремено наоѓање најголем и најмал елемент, бинарно барање елемент во
низа, сортирање низа со метода на меурче, печатење на таблицата за множење,
збир на елементите на дводимензионална низа, најголем (најмал) елемент во
дводимензионална низа, колку пати се јавуваат буквите од абецедата во низа и
други.
108
3. Сложеност на алгоритми
Слика 3.7
Логаритамска сложеност O(log2n)
Пример:
Да ја најдеме сложеноста на алгоритамот за пресметување на збирот на
низата 1 + 2 + 22 + 23 + 24 +… до елементот 2k < n, слика 3.8. Треба да одредиме од
колку циклуси се состои повторувањето. Од 2k < n, се добива k < log2n, односно
се извршуваат log2n циклуси, што значи дека сложеноста е O(log2n).
109
ПРОГРАМИРАЊЕ
Слика 3.8
Линеарно-логаритамска сложеност O(nlog2n)
110
3. Сложеност на алгоритми
Слика 3.9
Пример за алгоритам со експоненцијална сложеност (2n) е алгоритам за
наоѓање на бројот на подмножества од дадено множество.
Во следната табела се претставени подмножествата на дадено множество.
Множество Број Подмножества Број
елемент подмножеств
и а
{} 0 {} 1 = 20
{a} 1 {},{a} 2 = 21
{a, b} 2 {}, {a}, {b}, {a, b} 4 = 22
{a, b, c} 3 {}, {a}, {b}, {c}, {a, b}, {a, c}, {b, c}, {a, 8 = 23
b, c}
{a, b, c, d} 4 {}, {a}, {b}, {c}, {d}, {a, b}, {a, c}, {a, 16 = 24
d}, {b, c}, {b, d}, {c, d}, {a, b, c}, {a, b,
d}, {a, c, d}, {b, c, d}, {a, b, c, d}
... ... ... ...
{a, b, c, N 2n
d…}
Бројот на подмножества од множество со n елементи е 2n.
111
ПРОГРАМИРАЊЕ
Слика 3.10
Пример за алгоритам со факториелна сложеност (n!) е алгоритам за
наоѓање на бројот на пермутации од n елементи класа n.
Во следната табела се претставени пермутации на n елементи.
Множество Број Подмножества Број
елемент подмножеств
и а
{a} 1 {a} 1 = 1!
{a, b} 2 {a, b}, {b, a} 2 = 2!
{a, b, c} 3 {a, b, c}, {a, c, b}, {b, a, c}, {b, c, a}, 6 = 3!
{c, a, b}, {c, b, a}
{a, b, c, d} 4 {a, b, c, d}, {a, b, d, c}, {a, c, b, d}, 24 = 4!
{a, c, d, b}, {a, d, b, c}, {a, d, c, b}
{b, a, c, d}, {b, a, d, c}, {b, c, a, d},
{b, c, d, a}, {b, d, a, c}, {b, d, c, a}
{c, a, b, d}, {c, a, d, b}, {c, b, a, d},
{c, b, d, a}, {c, d, a, b}, {c, d, b, a}
{d, a, b, c}, {d, a, c, b}, {d, b, a, c},
{d, b, c, a}, {d, c, a, b}, {d, c, b, a}
... ... ... ...
{a, b, c, d...} n n!
Бројот на пермутации од n елементи класа n е n!.
112
3. Сложеност на алгоритми
Вежби
Вежба 3.1.1
Вежба 3.1.2
Да се одреди сложеноста на следниве алгоритамски сегменти:
brojac 0;
brojac 0; за i 1 зголемувај до n
за i 1 зголемувај до n за j 1 зголемувај до n
за j 1 зголемувај до i * i ако i = j
brojac brojac + 1; тогаш
крај_за {j} за k 1 зголемувај до n
крај_за {i} brojac brojac + 1;
а крај_за {k}
крај_ако {i = j}
крај_за {j}
крај_за {i}
б
brojac 0;
за i 1 зголемувај до n
за j 1 зголемувај до i * i
за k 1 зголемувај до j * j
brojac brojac + 1; brojac 0;
крај_за {k} за i 1 зголемувај до 3n
крај_за {j} за j 1 зголемувај до 4n
крај_за {i} ако i < j
тогаш
в за k 1 зголемувај до 5n
brojac brojac + 1;
крај_за {k}
крај_ако {i<j}
крај_за {j}
г крај_за {i}
113
ПРОГРАМИРАЊЕ
Резиме
114
4. Потпрограми - Функции
4. ПОТПРОГРАМИ – ФУНКЦИИ
Во оваа глава ќе се запознаете со следното:
Подалгоритми.
Програмирање одгоре надолу и модуларно програмирање.
Формални и вистински аргументи, параметри и аргументи.
Влезни параметри, излезни параметри, листа на параметри.
Функциски подалгоритми (функции) и процедурални подалгоритми
(процедури).
Аргументи пренесени по вредност.
Функции со повратна вредност.
Функции, библиотечни функции, кориснички дефинирани функции.
Дефиниција и декларација на корисничка функција со повратна вредност.
Функциски прототип.
Функциски потпис.
Влезни формални аргументи и излезни формални аргументи.
Функции без повратна вредност.
Референтни параметри, референцирање, референца, референтна
променлива.
Аргументи пренесени по референца.
Глобални, локални и статички променливи.
Хедер-датотеки, библиотечни функции: математички, функции за
генерирање случајни броеви, функции за работа со знаци и функции за
работа со стрингови.
115
ПРОГРАМИРАЊЕ
Клучни зборови
cmath Подалгоритам
cstdlib Подрачје на видливост
iomanip Подрачје на пристап
iostream Потпрограми
rand Програмирање одгоре надолу
random Процедурални подалгоритми
string Процедури
Аргумент на функција Лажни случајни броеви
Аргументи Рандомизација
Аргументи пренесени по вредност Референтна променлива
Аргументи пренесени по
Референтни параметри
референца
Библиотечни функции Референца
Вистински аргументи Референцирање
Влезни параметри Скриена променлива
Влезни формални аргументи Статичка променлива
врати Структурни алгоритми
Глобални променливи Формални аргументи
Живот на променлива Функции
Излезни параметри Функции без повратна вредност
Излезни формални аргументи Функции со повратна вредност
Кориснички дефинирани функции Функциски подалгоритми
Листа на параметри Функциски потпис
Локални променливи Функциски потпрограми
Модуларно програмирање Функциски прототип
Оператор за разрешување на
Хедер-датотека
подрачјето на видливост
Параметри
116
4. Потпрограми - Функции
4.1 Подалгоритми
1
Формалните аргументи го добиле името бидејќи тие немаат вредност, туку до-
биваат вредности само при повик за извршување на подалгоритамот.
118
4. Потпрограми - Функции
Функциските подалгоритми
2
Имињата на функциските подалгоритми ќе ги пишуваме на латиница.
3
Повикувач може да биде и друг подалгоритам.
119
ПРОГРАМИРАЊЕ
pogolem broj2;
крај_ако {broj1 > broj2}
врати pogolem;
крај {Pogolem}
Слика 4.2.1
Името на подалгоритамот е Pogolem(), а има два влезни параметри broj1 и
broj2.
Резултатот кој се пресметува во функцискиот подалгоритам се враќа со
чекорот
врати pogolem;
Секој функциски подалгоритам се повикува со чекор за доделување
променлива ImeNaPodalgoritamot (листа_на_аргументи);
или во друг чекор само со наведување на неговото име.
На пример, функцискиот подалгоритам од слика 4.1.2 може да се повика
со чекорот за доделување
p Pogolem(a, b);
Тој може да се повика и во чекорот за печатење
печати Pogolem(p, c);
За листата на аргументите и листата на влезните параметри важат след-
ните правила:
Бројот на аргументите е ист со бројот на параметрите.
Редоследот на аргументите е ист со редоследот на параметрите.
Типот на секој аргумент е ист или конвертибилен со типот на
соодветниот параметар.
При повикот на подалгоритамот Pogolem(broj1, broj2) со чекорот
p Pogolem(a, b);
вредностите на аргументите a и b се пренесуваат (копираат) во влезните пара-
метри broj1 и broj2 од дефиницијата на подалгоритамот. Резултатот од подал-
горитамот (поголемиот од броевите a и b) ѝ се доделува на променливата р.
При повикот на подалгоритамот Pogolem(broj1, broj2) со чекорот
n Pogolem(p, c);
прво се врши пренесување (копирање) на аргументите p и c во влезните пара-
метри broj1 и broj2, а резултатот од извршувањето на подалгоритамот (поголе-
миот од броевите p и c) ѝ се доделува на променливата n.
Процесот во кој вредностите на аргументите се пренесуваат во парамет-
рите се нарекува пренесување по вредност (англ. pass by value).
Сега можеме да го напишеме алгоритамот за наоѓање на најголемиот од
три дадени броја со повикување на функцискиот подалгоритам Pogolem(broj1,
broj2), како што е прикажано на слика 4.2.2.
алгоритам Најголем
почеток
читај a, b, c;
120
4. Потпрограми - Функции
p Pogolem(a, b);
n Pogolem(p, c);
печати n;
крај {Најголем}
Слика 4.2.2
Бидејќи во многу проблеми се бара решавање на исти задачи, пожелно е
за нив да се напишат подалгоритми. На пример, подалгоритми за: збирот на бро-
еви, производот на броеви, аритметичката средина, геометриската средина, НЗД,
НЗС, утврдување дали некој природен број е прост, најмал елемент во низа, нај-
голем елемент во низа итн.
Пример 4.2.1
Збирот на првите n природни броеви се јавува во повеќе задачи и затоа е
корисно да го напишеме како функциски подалгоритам, на пример, под име Zbir-
Od1DoN(n) (слика 4.1.4) и да го повикуваме каде што е потребно.
подалгоритам ZbirOd1DoN(n)
почеток
zbir 0;
broj 1;
повторувај
zbir zbir + broj;
broj broj + 1;
додека broj ≤ n;
крај_повторувај {broj ≤ n}
врати zbir;
крај {ZbirOd1DoN}
Слика 4.2.3
Со повикување на подалгоритамот ZbirOd1DoN(n), во алгоритамот од
слика 4.2.2 се пресметува збирот на првите n природни броеви, за n = 1, 2... m, и
тоа:
1
1+2
1+2+3
...
1 + 2 + 3 +... + m
алгоритам ЗбирДоM
почеток
печати „Внесете до кој природен број барате збир, m = “;
читај m;
за n 1 зголемувај до m
zbirNaPrirodniBroeviDoN ZbirOd1DoN(n);
121
ПРОГРАМИРАЊЕ
Забелешки:
Ако не се наведе типот (тип) на функцијата, се подразбира типот int.
Името (име) на функција (по конвенција) ќе го пишуваме како и
променливите4, т. е. со мала почетна буква. Ако името се состои од
повеќе збора, секој следен збор ќе го пишуваме со голема буква.
Листата на параметрите (листа_на_параметри) мора да ги содржи
типовите на параметрите, но не мора да ги содржи имињата.
Декларацијата на дадена функција завршува со знакот точка и запирка (;).
Декларацијата на функција се нарекува функциски прототип.
Со функцискиот прототип се опишува интерфејсот на функцијата, однос-
но се добиваат информации за бројот и типот на параметрите кои треба да бидат
познати пред да се повика функцијата, како и за типот на резултатот.
Ќе наведеме неколку примери за функциски прототипови на кориснич-
ките функции:
int mnozi(int m, int n); - име: mnozi
- параметри: m и n
- типот на резултатот е: int
float koren(float x); - типот на резултатот е: float
int pomal(int, int); - листа без имиња на параметрите
double f(int a, b); - неисправно, треба: double f(int a, int b);
long plostina(int a, int b); - типот на резултатот е: long
Делот од функцискиот прототип кој ги содржи името и листата на пара-
метрите се нарекува функциски потпис.
На пример, функциски потписи се:
mnozi(int m, int n);
koren(float b);
pomal(int, int);
stipendija(int a, float c);
plostina(int, int);
Функција со повратна вредност се повикува со наредба за доделување
променлива = име(листа_на_аргументи);
Листата на аргументи (листа_на_аргументи) и листата на параметри
(листа_на_параметри) на функцијата име мора да имаат:
ист број на аргументи и параметри,
ист редослед на аргументите и параметрите,
ист или конвертибилен тип5 на соодветните аргументи и параметри.
Ќе наведеме примери за повик на функции:
4
Имињата на функциите со повратна вредност може да се користат во изрази, а и
како аргументи на други функции, т. е. исто како и променливите.
5
Кога се врши автоматска конверзија на типот на аргументот во тип на парамета-
рот.
123
ПРОГРАМИРАЊЕ
Пример 4.2.2
Да се напише функција со повратна вредност за пресметување на најголе-
миот од три дадени броја.
.
Слика 4.2.5
124
4. Потпрограми - Функции
Слика 4.2.6
При извршување на следната наредба за доделување, во која повторно се
повикува функцијата pogolemBroj(), на променливата n ѝ се доделува вредноста
на поголемиот од броевите b и c,
n = pogolemBroj(p, c);
По извршување на оваа наредба, променливата n го содржи најголемиот
од броевите a, b и c.
Еден резултат од извршување на програмата е:
Вежби
Вежба 4.2.1
Напишете функција abs() која ќе ја пресметува апсолутната вред-
ност за даден цел број. Резултатот исто така треба да е цел број.
Вежба 4.2.2
Напишете функција која црта „крадратчиња“ со ѕвездички за да-
ден аргумент N.
126
4. Потпрограми - Функции
Вежба 4.2.3
Напишете функција zbirOd1DoN() која ќе го наоѓа збирот на бро-
евите од 1 до N и притоа ќе има помала сложеност на применетиот
алгоритам од оној претставен на слика 4.2.3.
Вежба 4.2.4
Да се напишат функциски подалгоритми и функции со повратна
вредност за следниве задачи:
1. Да се пресмета аритметичката средина на првите n природни броеви.
2. Да се пресмета периметарот на многуаголник, при што ќе се користи
функција со повратна вредност за пресметување на растојанието
меѓу две точки во рамнина.
3. Да се провери дали некој природен број е палиндром. (Палиндром е
оној број кој се чита исто и однапред и одназад).
4. Да се скрати дропката a (во која a и b се цели броеви) со делење на a
b
и b со нивниот НЗД. За наоѓање на НЗД на a и b, да се напише
посебна функција.
5. Да се најде најголемиот заеднички делител за n броеви. За наоѓање
на НЗД на два броја, да се напише посебна функција.
6. Да се пресмета бројот на цифрите на природниот број n.
7. Да се најде бројот на 0 (нули) и на 1 (единици) во голем декаден број,
чии цифри се само 0 или 1.
8. Да се најде разликата на два бинарни броја изразени како цели декад-
ни броеви чии цифри се само 0 или 1.
9. Да се провери дали природниот број n е совршен. (Совршени броеви
се оние кои се еднакви на збирот на своите делители без самиот
број).
10. Да се провери дали природниот број n е прост или не е. (Природниот
број р е прост ако е делив само со 1 и со самиот себеси).
127
ПРОГРАМИРАЊЕ
Процедурални подалгоритми
6
Во програмските јазици постојат различни начини за означување на влезните,
излезните и влезно-излезните параметри. Најчесто се означуваат со in, out и
inout.
128
4. Потпрограми - Функции
Пример 4.3.1
Да се напише процедурален подалгоритам за пресметување на збирот,
разликата, производот и количникот на два декадни броја.
129
ПРОГРАМИРАЊЕ
алгоритам АритметичкиОперации
почеток
печати „Внесете два природни броја: “;
печати „Прв број, a = “;
читај a;
печати „Втор број, b = “;
читај b;
печати „За внесените броеви “, a, „ и “, b, „ : “;
Операции(a, b, z, r, p, k);
печати „Збир = “, z“;
печати „Разлика = “, r“;
печати „Производ = “, p“;
печати „Количник = “, k“;
крај {АритметичкиОперации}
Слика 4.3.2
Во потточката 4.1 Подалгоритми спомнавме дека секој функциски
подалгоритам може да се изрази како процедурален ако се стави повратната
вредност како излезен параметар во листата на параметрите на процедуралниот
подалгоритам. Спротивното не важи, т. е. не може секој процедурален подалго-
ритам да се изрази како функциски.
Пример 4.3.2
Функцискиот подалгоритам за наоѓање на поголемиот од два броја (сли-
ка 4.2.1) да се дефинира како процедурален подалгоритам.
131
ПРОГРАМИРАЊЕ
Пример 4.3.4
Да се напишат главна функција и функција од типoт void за пресметува-
ње на квадратите и на квадратните корени на првите n природни броеви.
Слика 4.3.6
133
ПРОГРАМИРАЊЕ
Референтни параметри
134
4. Потпрограми - Функции
Слика 4.3.7
Примената на референците како референтни параметри во функциите без
повратна вредност, ќе ја објасниме на задачата за замена на вредностите на две
променливи. Според процедуралниот подалгоритам од слика 4.3.5, ќе напишеме
функција zamena() со референтни параметри, слика 4.3.8. За да знае преведува-
чот дека параметрите се референтни, пред нив се става знакот &.
void zamena(int &prv, int &vtor ) {
int pom;
pom = prv;
prv = vtor;
vtor = pom;
cout << "a = " << prv << " i b = " << vtor << endl;
}
Слика 4.3.8
Исто така, ако се користи прототипот на функцијата, треба да се означи
дека параметрите се референтни.
void zamena(int &, int &);
135
ПРОГРАМИРАЊЕ
Знакот & може да се стави каде било помеѓу типот и името на парамета-
рот:
int &prv int &prv int &prv
Програмата е дадена на слика 4.3.9.
Слика 4.3.9
Резултатот по извршување на програмата е:
zamena(a, b);
Притоа, бројот и редоследот на аргументите мора да одговара на бројот и
редоследот на параметрите. Но
типовите на аргументите кои се пренесуваат по вредност може да бидат
константи, променливи или изрази, чии типови се исти или конвертибил-
ни со типовите на соодветните вредносни параметри,
типовите на аргументите кои се пренесуваат по референца, мора да бидат
променливи (не константи или изрази) и тоа од ист тип како соодветните
референтни параметри.
При повикување на функција од типот void со референтни параметри, не
се креираат нови променливи за референтните параметри, како што се прави за
вредносните параметри. За време на извршувањето на функција од типот void ре-
ферентните параметри се третираат како други имиња за соодветните
аргументи од повикот. Тоа се пос-
тигнува така што на референтните
параметри им се доделува адресата
на соодветните аргументи. Затоа,
сите измени во референтните па-
раметри, всушност, се вршат врз
соодветните аргументи бидејќи
тие се различни имиња на иста ме-
мориска локација.
Скицата на слика 4.3.10 го
илустрира извршувањето на прог- Слика 4.3.10
рамата од слика 4.3.9.
Пример 4.3.5
Да се подредат три броја по големина.
Програмата е дадена на слика 4.3.11.
Слика 4.3.11
137
ПРОГРАМИРАЊЕ
Вежби
Вежба 4.3.1
Да се напишат процедурални подалгоритми и функции без пов-
ратна вредност за следниве задачи:
1 n=0
1 1 n=1
1 2 1 n=2
1 3 3 1 n=3
1 4 6 4 1 n=4
1 5 10 10 5 1 n=5
7
Оваа потточка е изборна.
139
ПРОГРАМИРАЊЕ
функцијата или само блокот помеѓу две загради {}. Видливоста започнува со
декларацијата на локалната променлива.
Параметрите на една функција се третираат како локални променливи во
целата функција. Исто така, локалните променливи во една функција се видливи
во сите вгнездени наредби, а локалните променливи декларирани во телото на
некоја наредба, не се видливи надвор од нејзиното тело.
За една променлива велиме дека е скриена (прекриена со друга промен-
лива) во некој блок или во цела функција ако не е видлива (не може да се корис-
ти) во тој блок или во таа функција. Тоа значи дека ако во подрачјето на видли-
вост на некоја променлива (на пример, int x = 1;) има блок (во наредба) во кој е
декларирана променлива со исто име (int x = 2;), во тој блок ќе биде видлива са-
мо променливата х со вредност 2.
Пример 4.4.1
Со овој пример ќе ја демонстрираме видливоста на променливите во една
програма.
Слика 4.4.1
Глобалните променливи живеат цело време додека се извршува програ-
мата.
141
ПРОГРАМИРАЊЕ
Пример 4.4.2
Во програмата од слика 4.4.2, функцијата f() се повикува 5 пати.
142
4. Потпрограми - Функции
Слика 4.4.2
Излезот по извршување на програмата е:
143
ПРОГРАМИРАЊЕ
Слика 4.4.3
144
4. Потпрограми - Функции
145
ПРОГРАМИРАЊЕ
<cstdlib>
Општа библиотека: контрола на програмата, случајни броеви,
сортирање, барање итн.
Математички функции
8
Овој број е основа на природните логаритми, а се нарекува Неперов број (John
Napier, XVII век, шкотски математичар).
146
4. Потпрограми - Функции
147
ПРОГРАМИРАЊЕ
Пример 4.4.1
Слика 4.4.1
148
4. Потпрограми - Функции
Пример 4.4.2
Слика 4.4.2
Излезот од програмата е:
149
ПРОГРАМИРАЊЕ
9
Постои константа RAND_MAX чија вредност може да се отпечати.
150
4. Потпрограми - Функции
10
ʼ\t‘ – хоризонтален табулатор, ʼ\n‘ – нова линија, ʼ\v‘– вертикален табулатор, ʼ\f‘–
нова страница, ʼ\r‘ ‒ претходна линија.
151
ПРОГРАМИРАЊЕ
Вежби
Вежба 4.5.1
Да се напише програма која ќе „замислува“ еден број меѓу 1 и 1 000 и ќе
му дава на корисникот до 10 можности да го погоди бројот. По секое погодува-
ње, програмата треба да отпечати една од следните пораки:
„Ne pogodivte. Brojot koj e zamislen e pogolem od brojot so koj probavte.“
„Ne pogodivte. Brojot koj e zamislen e pomal od brojot so koj probavte.“
„Ne pogodivte. Ja ispushtivte Vashata posledna shansa i so toa VE POBE-
DIV!“
„Pogodivte! Chestito! ME POBEDIVTE!“
Откако ќе ја завршите програмата, извршете ја неколкупати и обидете се
да го откриете бројот кој го замислил компјутерот. Дали може да смислите стра-
тегија за секогаш да победувате?
Резиме
153
ПРОГРАМИРАЊЕ
154
5. Низи
5. НИЗИ
Во оваа глава ќе се запознаете со следното:
Еднодимензионални низи.
Именувана константа (константна променлива).
Декларација и иницијализација на еднодимензионална низа,
иницијализирачка листа.
Наредба for базирана на опсег.
Сортирање на низа.
Класен шаблон vector.
Текстуални низи. Декларација и иницијализација.
Функции за работа со текстуални низи.
Класен шаблон string.
Дводимензионални низи – матрици.
Декларација и иницијализација на дводимензионална низа.
Пресметување на димензиите на низа.
Клучни зборови
Дводимензионална низа
Еднодимензионална низа
Иницијализација на низа
Иницијализирачка листа
Матрица
Наредба for базирана на опсег
Низа
Симболичка константа
155
ПРОГРАМИРАЊЕ
156
5. Низи
Примери
Пример 5.1.1
int a[5];
Низата a[] има 5 елементи и тоа: a[0], a[1], a[2], a[3] и a[4]. Типот на еле-
ментите на низата е int и на нив може да им се доделуваат само целобројни вред-
ности.
Пример 5.1.2
float br[25];
Низата br[] е од тип float и има 25 елементи. Општиот к-ти елемент се
означува со br[k], а индексот k може да има вредности 0, 1... 24. Значи, елемен-
тите се: br[0], br[1]... br[24].
Пример 5.1.3
string ime[15], prezime[30];
Се декларираат две низи ime[] и prezime[] чии елементи може да имаат
вредности само стрингови. За стринг ќе објасниме малку подолу.
Пример 5.1.4
const int BROJELEMENTI = 100;
char c[BROJELEMENTI];
Во примеров, бројот на елементи на низа c[] е претходно зададен како
именувана константа (англ. named constant), наречена и константна промен-
лива (англ. constant variable), BROJELEMENTI.
Пример 5.1.5
int k = 10;
float u[k];
Според стандардот на С++, оваа декларација e погрешна бидејќи бројот
на елементи мора да е константен. Сепак, при користење на актуелните околини
157
ПРОГРАМИРАЊЕ
Табела 5.1.1
Вредност на
Елемент
елементот
0 е индекс на првиот елемент на низата. d[0] ‒567
d[1] 8
d[2] 9
d[3] 72
d[4] 345
d[5] ‒78
d[6] 78
d[7] 9
d[8] 10
9 е индекс на последниот елемент на низата. d[9] 987
Индексот на елементите на дадена низа може да биде константа, промен-
лива или израз чија вредност е ненегативна и во опсег на индексите од 0 до n ‒ 1
(ако должината на низата е n). Така, за a = 7 и b = 2 елементот
d[ a + b ‒ 1 ]
всушност, е елементот d[8].
Внимавајте: Во C++, преведувачот нема да пријави грешка доколку
пристапите до елемент кој не се наоѓа во границите на низата (на пример, да се
обидете да пристапите до седмиот елемент на низа која има големина 5). Но
ваквите грешки може да предизвикаат проблем за време на извршување на
програмата (т.н. runtime error). Велиме „може“ бидејќи оперативниот систем ќе ја
„сруши“ Вашата програма само доколку се обидете да пристапите до меморија
која тој не ви ја доделил. Сепак, дури и да не се „сруши“ Вашата програма, таа
скоро сигурно нема добро да работи ако пристапувате до непостојни елементи од
низата.
158
5. Низи
Пример 5.1.6
Доделување вредности може да се врши посебно на секој елемент:
int a[10];
a[0] = 1; a[9] = 10; a[3] = ‒4; a[5] = 5;
Пример 5.1.7
Доделувањето вредности може да се врши и преку изрази во кои се прес-
метува вредноста на индексите на низата. На пример, ако елементот a[5] = 24, со
наредбите:
int c = 3;
int d = 2;
a[c + d] += 6;
на елементот a[5] му се зголемува вредноста за 6, т. е. неговата вредност сега ќе
биде 30.
Пример 5.1.8
Доделување вредности на елементите на низата може да се врши и при
декларирањето, т. е. со иницијализирачка листа.
int a[] = {5, ‒2, 7, ‒3, 6};
Вредностите на елементите ќе бидат: a[0] = 5, a[1] = ‒2, a[2] = 7, a[3] = ‒3,
a[4] = 6. Должината на низата (бројот на елементи) при ваква иницијализација ја
одредува самиот преведувач.
По декларацијата и иницијализацијата на низата
char bukvi[] = {'a', 'b', 'c'};
вредностите на елементите ќе бидат: a[0] = 'a', a[1] = 'b', a[2] = 'c'.
Пример 5.1.9
Ако има помалку вредности во иницијализирачката листа отколку што
има елементи во низата, останатите елементи на низата се иницијализираат на
нула.
Со следнава декларација и иницијализација
int nekoi[10] = {3, ‒1, 4};
елементите на низата ќе се иницијализираат со следните вредност: 3, –1, 4, 0, 0, 0,
0, 0, 0, 0. Нулите ги пополнува преведувачот.
159
ПРОГРАМИРАЊЕ
Слично, со
int nuli[100] = {};
се декларира низа од целобројни елементи под име nuli, при што сите елементи
се иницијализираат на 0.
Со декларацијата и иницијализацијата
char samoglaski[5] = {'a'};
експлицитно се доделува вредноста 'a' на нултиот елемент од низата, а сите
останати елементи автоматски се иницијализираат на празни места.
Забелешка: Во С++ нема автоматска иницијализација на низи. Мора
барем еден елемент да е иницијализиран, за потоа сите останати елементи да би-
дат иницијализирани.
Пример 5.1.10
Димензијата на низата може да се пресмета автоматски ако елементите се
зададени при иницијализација. При следната декларација и иницијализација
double ovie[] = {2.34, ‒5.67, 3.45, 7.89 };
не е зададена должината на низата, а ја одредува преведувачот, според зададе-
ниот број на елементи, т. е. низата ovie ќе има должина 4.
Слично, со декларацијата и иницијализацијата
string denovi[] = {"Pon","Vto","Sre","Cet","Pet","Sab","Ned"};
должината на низата denovi е 7.
Со следнава декларацијата и иницијализација
int cifri[] = {1, 2, 3, 4, 5};
се декларира низа со должина 5 и се иницијализираат сите елементи.
Од друга страна, со следнава декларација и иницијализација на низата
int v[5] = {1, 2, 4, 5, 6, 9};
се јавува синтаксичка грешка бидејќи има 6 иницијализирачки вредности, а низа-
та може да има најмногу 5 елементи.
Пример 5.1.11
Низите не може:
да се доделуваат една на друга:
int a[2] = {1, 2};
int b[2];
b = a; // neispravno
да се иницијализираат една со друга:
int c[2] = a; // neispravno
да се печатат само преку името1:
cout << a; // neispravno
да се споредуваат2:
if (a == b) // neispravno
1
Се печати адресата на низата.
2
Се споредуваат адресите на низите.
160
5. Низи
Пример 5.1.12
Во овој пример се користи претпроцесорската директива #define, со која
се дефинира симболичка константа DOLZINA чија вредност е 10, слика 5.1.1.
Слика 5.1.1
Програмата ги иницијализира првите два елементи на низата со вредност
1, а останатите со 0. Со наредбата for на елементите од третиот до десеттиот им
се доделуваат вредности по формула. (Која?)
Излезот при извршување на програмата е:
3
Се враќа покажувач на низата. За покажувачи ќе зборуваме подоцна.
161
ПРОГРАМИРАЊЕ
Слика 5.1.1
Пример 5.1.13
Програмскиот сегмент за читање елементи на целобројна низа од n еле-
менти a[]n е:
for (int i = 0; i < n; i++)
cin >> a[i];
Пример 5.1.14
Програмскиот сегмент за печатење елементите на низата b[]n е:
for (int i = 0; i < n; i++)
cout << a[i] << endl;
Пример 5.1.15
Програмскиот сегмент за наоѓање на збирот на елементите на низата од n
елементи c[]n е:
zbir = 0;
for (int i = 0; i < n; i++)
zbir += c[i];
Истиот програмски сегмент може да се користат и за пресметување на
производот на елементите на низата, само треба да се сменат наредбите:
zbir = 0; со proizvod = 1;
zbir += c[i]; со proizvod *= c[i];
Овие сегменти може да се користат за која било операција со елементите
на низата. Тие овозможуваат да пристапиме до секој од елементите на низата,
еден по еден, од првиот до последниот и да направиме некоја операција со него.
Овој процес се нарекува изминување на низа.
Пример 5.1.16
Во примерот на слика 5.1.2 се илустрирани декларација, иницијализација
и доделување вредности на елементите на низи од типот: int, float, char и string.
162
5. Низи
Слика 5.1.2
163
ПРОГРАМИРАЊЕ
Излезот од програмата е:
Решени задачи
Задача 5.1.1
Да се напишат алгоритам и програма со која секој елемент од бројната
низа a[]n ќе го промени знакот, + во – и – во +.
164
5. Низи
Слика 5.1.3
165
ПРОГРАМИРАЊЕ
Задача 5.1.2
Да се напише програма за наоѓање на најголемиот и на најмалиот еле-
мент во бројната низа а[]n, со посебни функции.
Слика 5.1.4
167
ПРОГРАМИРАЊЕ
168
5. Низи
169
ПРОГРАМИРАЊЕ
Примери
Пример 5.1.17
Програмскиот сегмент од Пример 5.1.15 за збир на елементите на низата
c[] може да се запише на следниов начин:
for(int broj: c)
zbir += broj;
Пример 5.1.18
Во Задача 5.1.2, наредбата for за збир на елементите:
for (i = 0; i < n; i++) {
zbir += k*a[i];
k = ‒k;
}
може да се напише и со наредбата for базирана на опсег:
for(double broj: a) {
zbir += k * broj;
k = ‒k;
}
Пример 5.1.19
За наоѓање на најмалиот или на најголемиот елемент во низа:
double najmal = a[0];
double najgolem = a[0];
for(auto broj: a) {
if(broj < najmal)
najmal = broj;
if(broj > najgolem)
najgolem = broj;
}
Вежби
Вежба 5.1.1
Решете ги следните задачи на тој начин што за секоја следна зада-
ча ќе го користите кодот од претходната задача, со мала измена/допол-
нување.
1. Иницијализирајте низа од 17 елементи уште при декларирањето.
Низата е: 1, 9, 22, 17, ‒4, 3, ‒1, 9, 12, 58, ‒7, 0, 4, 5, 33, 18, ‒55.
а) Отпечатете ги елементите од низата во еден ред, одделени со по
едно празно место.
170
5. Низи
Вежба 5.1.2
Да се напишат програми за следниве задачи:
1. Да се провери дали во бројната низа a[]n се наоѓа елемент со вредност
v.
2. Да се најде производот на елементите на целобројната низа a[]n.
3. Да се пресмета аритметичката (А) и хармониската (Н) средина на
бројната низа a[]n.
a1 a 2 ... a n n
A H
n 1 1 1
...
a1 a 2 an
4. Да се најде колку елементи од бројната низа a[]n имаат помала вред-
ност од v, а колку поголема.
5. Од низата броеви a[]n да се пресмета посебно збирот на парните и
збирот на непарните броеви.
6. Да се издвојат во посебни низи елементите на низата a[]n со парни
индекси и со непарни индекси.
7. Да се изврши циклично поместување на елементите на низа од знаци
a[]n за к места надесно или налево.
8. Да се формира нова низа c[]n, чии елементи се збир на соодветните
елементи на низите a[]n и b[]n, т. е. ci = ai + bi, за i = 0, 1... n – 1.
171
ПРОГРАМИРАЊЕ
Вежба 5.1.3
Одговорете на следните прашања:
1. Како се декларира еднодимензионална низа?
2. Од каков тип на податок треба да биде индексот на елементите на
еднодимензионална низа?
3. Ако е декларирана еднодимензионална низа
int a[10];
кои вредности може да ги прими индексот на елементите на низата?
4. На кои начини може да се врши доделување вредности на елементи-
те на еднодимензионална низа?
5. На кои начини може да се врши иницијализирање на елементите на
еднодимензионална низа?
6. Како се одредува димензијата на еднодимензионална низа?
7. Напишете ја синтаксата на наредбата for базирана на опсег.
173
ПРОГРАМИРАЊЕ
174
5. Низи
Вежби
Вежба 5.2.1
Решeте ги
следните задачи со
употреба на едноди-
мензионална низа и-
ли вектор. По пот-
реба, направете сор-
тирање на низата.
1. Напишете прог-
рама која ги на-
оѓа трите раз-
лични најголеми
броеви во една
низа.
2. Најдете го еле-
ментот кој се по-
јавува најголем
број пати во ни-
зата.
3. Напишете прог-
рама која ќе ги Слика 5.2.4
преуреди еле-
ментите на една низа која се состои од нули и единици, на тој начин
што прво ќе бидат сите нули, а потоа сите единици.
4. Напишете програма која ќе ги преуреди елементите на низата така
што прво ќе се бидат позитивните броеви, птоа нулите и на крајот
негативните броеви. Притоа, релативниот распоред на броевите
треба да е како во првата низа.
5. Најдете го најмалиот елемент кој се појавува парен број пати во ед-
нодимензионална низа.
Вежба 5.2.2
Денес правеле тест дел од учениците (n < 100) од еден клас. За
секој од нив го внесуваме неговиот реден број (< 1000) и резултатите на
тестот. Отпечатете ги редните броеви на 5-те ученици кои имале најдобар
резултат на тестот (< 100) и просечниот резултат на тие 5 ученици.
175
ПРОГРАМИРАЊЕ
Пример 5.3.1
По декларацијата на текстуалната низа
char ime[10];
се резервира меморија чии елементи немаат дефинирани вредности. На крајот на
текстуалната низа автоматски се поставува нулти знак.
? ? ? ? ? ? ? ? ? \0
0 1 2 3 4 5 6 7 8 9
Пример 5.3.2
Доделувањето вредности на текстуална низа најчесто се врши при
декларација и иницијализација, преку доделување на текстуална константа.
Притоа, секој елемент добива вредност и се поставува знакот за крај на низата.
Со следнава декларација и иницијализација
char ime[11] = "MAKEDONIJA";
текстуалната променлива ime[] во меморијата ќе зафаќа 11 бајти.
M A K E D O N I J A \0
0 1 2 3 4 5 6 7 8 9 10
Ако декларацијата е
char ime[10] = "MAKEDONIJA";
ќе се јави грешка
176
5. Низи
Пример 5.3.3
На елементите на текстуалната низа може посебно да им се доделуваат
вредности (знаци) кои се од типот char:
ime[0] = 'M';
ime[2] = 'C';
Пример 5.3.4
Со следнава декларација и иницијализација
char prezime[15] = "Jovancevski";
се декларира низата prezime[] со должина од 15 знаци (се резервира меморија од
15 бајти), а нултиот знак се става веднаш по доделената текстуална константа.
Содржината на преостанатите три бајти не е позната.
J o v a n c e V s K i \0 ? ? ?
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Пример 5.3.5
Ако не се знае должината на текстуалната низа, тогаш при иницијализа-
ција во меморијата, се резервира простор со должина еднаква на бројот на знаци
на низата плус еден бајт за нултиот знак '\0' за крај.
Со наредбата
char godina[] = "prva";
се декларира и иницијализира низа со должина 4, а во меморијата се резервираат
5 бајти.
p r v a \0
0 1 2 3 4
Пример 5.3.6
Текстуална низа може да се иницијализира и со иницијализирачка листа.
Следната иницијализација
char grad[]= {'S', 'k', 'o', 'p', 'j', 'e'};
не е правилна бидејќи нема нулти знак на крајот. При ваквата иницијализација,
мора да се внимава експлицитно на последниот елемент од текстуалната низа да
му се додели вредност '\0'. Правилна иницијализација би била:
char grad[] = {'S', 'k', 'o', 'p', 'j', 'e', '\0'};
Ако ја отпечатиме низата grad[] по првата иницијализација,
177
ПРОГРАМИРАЊЕ
Пример 5.3.7
Со текстуалните низа се вршат операции за споредување со користење
на релациските оператори, и тоа:
== еднакво
<> различно
< помало
> поголемо
<= помало или еднакво
>= поголемо или еднакво
Во следната наредба if
if(ime > prezime)
cout << "Imeto e pogolemo od prezimeto" << endl;
споредувањето на текстуалните низи ime[] и prezime[] се врши знак по знак,
според лексикографската вредност на знаците во абецедата, т. е. според вреноста
на знаците ASCII.
Следната наредба содржи логички израз формиран од елементи на тек-
стуалната низа grad[] и релациски оператори:
if(grad[0] == 'S' || grad[0] == 's')
cout << "Gradot zapocnuva na bukvata S ili s. ";
Забелешка: Треба да се нагласи разликата помеѓу знаковните константи
заградени со наводници "..." и со полунаводници ' '.
Вредноста 'j' претставува еден знак и има големина од еден бајт.
Вредноста "j" претставува текстуална низа од еден знак и зафаќа два бај-
ти во меморијата бидејќи завршува со нултиот знак '\0' и го има следниот из-
глед:
ј \0
0 1
178
5. Низи
Пример 5.3.8
Во програмата на слика 5.3.1 се покажани доделување, читање и печа-
тење на текстуална низа.
Слика 5.3.1
Излезот е:
Пример 5.3.9
Ако треба да се прочита текстуална низа која содржи и бланко знаци, то-
гаш се користи функцијата cin.getline(promenliva, dolzina), која е слична со функ-
цијата getline(cin, promenliva) за читање стрингови.
Во оваа функција, promenliva е името на текстуалната низа, а dolzina е
константа со која се задава должината (во знаци, т. е. бајти) на promenliva. Затоа,
promenliva ќе содржи dolzina – 1 знаци бидејќи последниот знак ќе биде нултиот
179
ПРОГРАМИРАЊЕ
знак. Тоа значи дека од внесената низа преку тастатурата ќе се прочитаат првите
dolzina – 1 знаци.
Ако во претходната програма (слика 5.3.1), место
cin >> vnesenaNiza;
се стави наредбата
cin.getline(vnesenaNiza, 12);
се резервира простор за низата vnesenaNiza од 12 знаци, а ќе се прочитаат првите
11 знаци внесени од тастатурата.
Излезот ќе биде:
Пример 5.3.10
На слика 5.3.2 е прикажано некоректно завршување на текстуална низа.
180
5. Низи
Слика 5.3.2
Пример 5.3.11
Текстуалната низа може да се внесе и знак по знак, слика 5.3.3.
Слика 5.3.3
181
ПРОГРАМИРАЊЕ
Излезот е:
Пример 5.3.12
Поради особината на текстуалните низи да завршуваат со специјалниот
знак '\0', должината на низата може да се определи преку наоѓање на нултиот
знак '\0' во низата. Тоа е илустрирано во следнава програма.
Слика 5.3.4
Излезот од оваа програма е:
182
5. Низи
Решени задачи
Задача 5.3.1
Да се провери дали некој збор е палиндром.
Слика 5.3.7
183
ПРОГРАМИРАЊЕ
Задача 5.3.2
Да се најде колку пати се јавува секој знак (што го има) во некој текст.
184
5. Низи
Слика 5.3.8
Шаблонот string
Слика 5.3.9
186
5. Низи
Вежби
Вежба 5.3.1
Да се напишат програми за следниве задачи со користење на тек-
стуални низи:
1. Да се најде спротивниот збор (текст) на даден збор (текст).
2. Да се одреди колку пати се наоѓа даден знак во текст.
3. Да се најдат сите имиња во даден текст. (Имињата се зборови кои
почнуваат со голема буква).
4. Во даден текст да се најде растојанието помеѓу два дадени збора.
(Растојанието е број на знаци помеѓу нив.)
5. Да се внесат n зборови и со спојување на секој збор на крајот на
претходниот со празно место меѓу нив, да се формира текстуална ни-
за.
6. Да се најде најдолгиот збор во дадена текстуална низа.
7. Да се одреди колку пати и на кои позиции започнува даден збор во
текстуална низа.
8. Да се избришат буквите кои се повторуваат последователно во даден
текст. (На пример: „Јас суум тукааа дојјден порраноо“, а треба „Јас
сум тука дојден порано“).
9. Да се изврши циклично поместување на знаците во текстуална низа
за к места налево или надесно.
10. Да се сортираат n имиња по абецеден редослед на првата буква.
Вежба 5.3.2
Да се даде одговор на следните прашања:
1. Како се декларира текстуална низа?
2. На кои начини може да се иницијализира текстуална низа?
3. Со кој знак мора да завршуваат текстуалните низи?
4. Што е погрешно во следната декларација?
char grad[]={'K', 'a', 'v', 'a', 'd', 'a', 'r', 'c', 'i'};
5. Ако текстуалната променлива jas треба да се иницијализира на
вредност „Jovanov“, колкава мора да биде нејзината најмала
димензија?
6. Како може да се додели вредност на текстуална низа?
7. Кои релациски оператори се користат при работа со текстуални
низи?
8. Ако вредноста на текстуалната низа која треба да се прочита се
состои од повеќе зборови, со која наредба треба да се прочита?
9. Со која функција се одредува должината на тeкстуална низа?
10. Со која функција се врши споредување на две текстуални низи? Кој
може да биде резултатот од споредувањето?
187
ПРОГРАМИРАЊЕ
Слика 5.4.1
Слично, оценките на учениците од еден клас по сите предмети (да прет-
поставиме 12) може да се прикажат со табела со две димензии, со редици (хори-
зонтално, прва димензија) и колони (вертикално, втора димензија).
1 2 3 4 5 6 7 8 9 10 11 12
Предмет → p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 Prosek
Ученик ↓
1 u1 3 4 5 2 3 4 3 4 5 3 3 2
2 u2 4 5 4 5 3 4 5 4 5 5 5 4
3 u3 5 5 5 5 2 4 4 4 4 2 4 5
… ...
Prosek
Слика 5.4.2
Овие податоци може да се запишат како дводимензионална низа, при
што едната димензија е ученици (u), а другата димензија е предмети (p). Значи,
секоја оценка во табелата има два индекси. Ако низата ја именуваме со o (скрате-
но од ocenki), тогаш вредностите на елементите на дводимензионалната низа се
188
5. Низи
189
ПРОГРАМИРАЊЕ
Примери
Пример 5.4.1
Со декларацијата
int a[3][4];
се декларира низата а[]3, 4 од 12 елементи, на кои првиот индекс им е 0, 1 или 2, а
вториот индекс им е 0, 1, 2 или 3. Оваа низа графички може да се прикаже со та-
бела со 3 редици и 4 колони:
колони
(втор индекс)
0 1 2 3
редици
0 1
0 ‒3 5
1 4 0
2 0 0
Пример 5.4.4
Со наредбата
int d[3][2] = {{‒3, 5 },{ 4, 1 },{ 7, ‒2 }};
се декларира и иницијализира низа од 3 редици (секоја редица се става во големи
загради) и 2 колони (секоја редица има по 2 елементи), според податоците од
иницијализирачката листа. Истата декларација може да се запише и попрегледно:
int d[3][2] = {
{‒3, 5},
{4, 1},
{7, ‒2}
};
0 1
0 ‒3 5
1 4 1
2 7 ‒2
Исто така, ако нема доволно елементи за иницијализирање на некоја ре-
дица, останатите елементи во неа се иницијализираат со 0:
int d[3][2] = {{‒3},{4, 1},{7}};
0 1
0 ‒3 0
1 4 1
2 7 0
Истите декларации и иницијализации може да се направат и со следниве
наредби
int d[][2] = {{‒3, 5},{4, 1},{7, ‒2}};
и
int d[][2] = {{‒3},{4, 1},{7}};
191
ПРОГРАМИРАЊЕ
Пример 5.4.5
Димензиите на низата може да се зададат и преку константи.
Со наредбите
const int m = 10;
const int n = 5;
float b[m][n];
се декларира дводимензионална низа со 10 редици и 5 колони, т. е. првиот
елемент е b[0][0], а последниот е b[9][4].
Но не мора да се користи целата низа b[m][n] елементи, туку може само
дел од неа. На пример, можеме да зададеме помали димензии на низата:
int redici = 4;
int koloni = 3;
и да се користи само делот b[redici][koloni].
Пример 5.4.6
Програмскиот сегмент за читање елементи на дводимензионалната низа
а[]m,n е:
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
cin >> a[i][j];
Пример 5.4.7
Програмскиот сегмент за печатење на дводимензионалната низа b[]m,n е:
192
5. Низи
Пример 5.4.8
Програмскиот сегмент за наоѓање на збирот на елементи на целобројната
дводимензионална низа c[]m,n е:
int zbir = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++)
zbir += c[i][j];
}
Пример 5.4.9
Со програмата од слика 5.4.3 се илустрирани декларација, иницијализа-
ција, читање и печатење на дводимензионална низа.
Слика 5.4.3
193
ПРОГРАМИРАЊЕ
Решени задачи
Задача 5.4.1
Да се отпечати таблицата множење до n.
Слика 5.4.4
194
5. Низи
Задача 5.4.2
Да се најдат најмалиот и најголемиот елемент во дводимензионална низа.
За читање, за печатење и за наоѓање на најмалиот и на најголемиот елемент да се
напишат посебни функции.
195
ПРОГРАМИРАЊЕ
Слика 5.4.5
196
5. Низи
197
ПРОГРАМИРАЊЕ
Вежби
Вежба 5.4.1
Да се напишат програми за следниве задачи :
1. Да се најде аритметичката средина на елементите на дводимензио-
налната низа a[]m,n.
2. Да се пресмета збирот на две дводимензионални низи со исти димен-
зии, c[]m,n = a[]m,n + b[]m,n (Збирот на i,j-тиот елемент е ci,j = ai ,j + bi ,j).
3. Да се формира дводимензионалнa низа a[][]n,n што ќе ги содржи бро-
евите од 1 до n2 во облик на змија. На пример, за n = 3, низата го има
следниот изглед:
1 2 3
6 5 4
7 8 9
4. Да се најдат максималните елементи по редици и минималните еле-
менти по колони во дводимензионална низа a[]m,n.
5. Да се најде посебно збирот на елементите на главната дијагонала и
збирот на елементите на споредната дијагонала на дводимензионал-
ната низа q[][]n,n
6. Да се најде збирот на елементите над главната дијагонала на дводи-
мензионалната низа a[]n,n.
7. Да се избришат i-тата редица и j-тата колоната од дводимензионал-
ната низа a[]m,n.
8. Да се пресмета збирот на елементите кои лежат на дијагоналите кои
минуваат низ елементот ai,j на дводимензионалната низа a[]m,n.
9. Да се заротираат колоните на дводимензионалната низа a[]m,n за к
места налево (или надесно).
1 4 9 16 25 …
10. Да се генерира следнава дводимензио- 2 3 8 15 24 …
нална низа a[]m,n. 5 6 7 14 23 ...
10 11 12 13 22 ...
17 18 19 20 21 ...
26 27 ... ... ... ...
198
5. Низи
Вежба 5.4.2
Да се даде одговор на следните прашања:
1. Како се декларира и иницијализира дводимензионална низа?
2. Како можеме да декларираме дводимензионална низа b[][] со 4
редици и 3 колони?
3. Дали во дефинираната низа b[][] во претходната задача постојат
елементите: b[3][4], b[4][3], b[0][4], b[0][3], b[3][0] и b[4][0]?
4. Нека е дадено
int a[5][5] = {1, 2, 3, 4, 5, 6, 7, 8};
Која е вредноста на елементот a[1][3]?
5. Ако е декларирано
double d[10][10];
каде е грешката во наредбава
d[5][10] = 4.55;
6. Што ќе отпечати следниов програмски сегмент:
int i, j, niza[5][5];
for(i = 0, j = 0; i < 5; i++, j++)
niza[i][j] = i + j;
for(i = 0, j = 0; i < 5; i++, j++)
cout << niza[ i ][ j ] << endl;
7. Да се напише програмски сегмент за читање на елементите на дводи-
мензионалната низа a[]m, n.
8. Да се напише програмски сегмент за печатење на дводимензионал-
ната низа a[]m, n.
Резиме
199
ПРОГРАМИРАЊЕ
200
6. Датотеки
6. ДАТОТЕКИ
Во оваа глава ќе се запознаете со следното:
Клучни зборови
201
ПРОГРАМИРАЊЕ
202
6. Датотеки
203
ПРОГРАМИРАЊЕ
Влезни датотеки
Типот на променливите за влезна датотека, т. е. за физичка датотека од
која само се читаат податоци е ifstream.
Декларирање на променлива за влезна датотека (име на логичка датотека)
се врши со
ifstream именапроменлива; // ime na logichka datoteka za chitanje
На пример:
ifstream datoteka;
ifstream vlezna, pomdat;
За да може да се читаат податоци од влезната (физичката) датотека, нејзе
мора да ѝ се придружи променлива од типот ifstream со
именапроменлива.open(именадатотека);
именапроменлива е името на променливата за влезната датотека (логич-
ката датотека),
именадатотека е името на физичката датотека,
open() е функцијата за отворање на датотеката, која е дефинирана во биб-
лиотеката <fstream>.
На пример, со
vlezna.open("Podatoci.dat");
се поврзува променливата за влезната датотека vlezna со физичката датотека
Podatoci.dat, односно се отвора физичката датотека Podatoci.dat за читање по-
датоци од неа.
Поврзувањето на променливата за влезната датотека со физичката датоте-
ка може да се направи и при нејзиното декларирање.
204
6. Датотеки
На пример:
ifstream vlezna("Podatoci.dat");
Името на физичката датотека може да зададе и преку терминал.
На пример:
ifstream vlezna;
char imeVlezna[10];
cout << "Vnesete go imeto na datotekata: ";
cin >> imeVlezna;
vlezna.open(imeVlezna);
Пред да се отвори некоја датотека за читање, пожелно е да се провери да-
ли постои таа датотека. На пример:
if (!vlezna) {
cout << "NE mozam da ja otvoram vleznata datoteka. \n";
exit(1); // Kraj na programata so pojava na greska.
}
Излезни датотеки
Типот на променливите за излезна датотека, т. е. за физичка датотека
од која само се читаат податоци е оfstream.
Декларирање на променлива за излезна датотека (логичка датотека) се
врши со
ofstream именапроменлива; // ime na logichka datoteka za zapisuvanje
На пример:
ofstream datIzlez;
ofstream izlezna, pomIzlez;
За да може да се запишат податоци во излезната (физичката) датотека,
нејзе мора да ѝ се придружи променлива од типот оfstream со
именапроменлива.open(именадатотека);
именапроменлива е името на променливата за излезната датотека,
именадатотека е името на физичката датотека,
open() е функција за отворање на датотеката, која е дефинирана во
библиотеката <fstream>.
На пример, со:
datIzlez.open("Rezultati.dat");
izlezna.open("IzleznaDatoteka.dat");
pomIzlez.open("pomosna.dat");
се поврзуваат секоја од променливите за излезната датотека (datIzlez, izlezna и
pomIzlez) со соодветните физички датотеки (Rezultati.dat, IzleznaDatoteka.dat и
pomosna.dat), односно се отвораат физичките датотеки за запишување податоци
во нив.
Поврзувањето на променливата за излезната датотека со физичката дато-
тека може да се направи и при нејзиното декларирање. На пример:
ofstream datIzlez("Rezultati.dat");
205
ПРОГРАМИРАЊЕ
Влезно-излезни датотеки
1
Најчесто се испитува дали сме успеале да отвориме излезна датотека на дискот за да
може да продолжиме со запишување во неа. Некогаш не е можно да се отвори за запишу-
вање од разни причини: немаме привилегија за запишување во папката во која сакаме да
ја запишеме датотеката, надворешниот диск е преполн, веќе постои датотеката и таа е
„read-only“ итн.
206
6. Датотеки
Пример 6.2
Отворање излезна датотека за запишување:
dat2.open("Vtora.dat", ios :: out);
Пример 6.3
Отворање датотека за допишување податоци во неа:
dat3.open("Treta.dat", ios :: app);
Пример 6.4
Параметрите за начинот на работа со датотеките може да се комбинираат
со операторот Или (|).
На пример, со
dat4.open("Cetvrta.dat", ios :: in | ios :: app);
датотеката се отвора за читање и за допишување податоци во неа.
207
ПРОГРАМИРАЊЕ
Слика 6.2
Сите записи се состојат од ист број и тип податоци, наречени полиња
(англ. fields), одделени со празно место. На пример, реченицата
Jovana Jovanovska zenski 14 134
има пет полиња, од кои полињата за име, за презиме и за пол се текстуални поли-
ња (стрингови), а другите две полиња се од целоброен тип.
Секој запис во датотеката завршува со маркер за крај на записот (англ.
end-of-record marker, EOR marker).
Исто така, секоја датотека завршува со маркер за крај на датотеката
(англ. end-of-file marker, EOF marker).
Најчеста организација на датотеките е секвенцијална и случајна2. Записи-
те во секвенцијалните датотеки (англ. sequential files) се организирани после-
дователно, еден по друг. Секој запис има свој претходник (освен првиот) и свој
следбеник (освен последниот). Затоа, за да се стигне до кој било запис, мора прво
да се пристапи до првиот запис од датотеката и понатаму да се поминат сите за-
писи до бараниот.
Записите во случајните датотеки (англ. random-access files) се органи-
зирани со т.н клуч (англ. key). Едно поле од записот се одредува како клуч и пре-
ку него се пристапува директно до записот со одреден клуч.
2
Случајните датотеки нема да ги обработуваме.
208
6. Датотеки
Затворање датотека
Датотека се затвора со функцијата close().
На пример:
vlezna.close();
Со оваа наредба се затвора датотеката по завршување на операциите со
неа.
Еднаш затворена датотека во апликацијата не се користи ниту како влез-
на ниту како излезна сè додека не се отвори повторно.
До затворање на датотека доаѓа и автоматски кога извршувањето на
апликацијата ќе излезе од подрачјето на користење (видливост) на логичката
датотека со која е поврзана физичката датотека.
Решени задачи
Задача 6.1
Следнава апликација креира излезна датотека, запишува податоци во неа,
ја затвора, потоа ја отвора како влезна датотека и од неа ги чита податоците и ги
печати на екранот во следната форма:
209
ПРОГРАМИРАЊЕ
Слика 6.3
210
6. Датотеки
Задача 6.2
Во задачава се покажува како може да се
ископира една датотека во друга знак по знак. Да-
тотеката од која се копира се чита знак по знак со
функцијата get(), слика 6.5. Потоа, датотеката во
која е ископирана првата, се копира на екранот од
мониторот, при што екранот се гледа како датоте-
ка со име cout. Бидејќи функцијата kopiranjeDa-
toteka() се користи и за копирање (печатење) на
стандардниот излез cout (која е променлива од ти-
пот ostream), првиот параметар на функцијата е од
типот ostream.
Влезната датотека може да се креира со кој
било уредувач на текст, најчесто Notepad или
WordPad, слика 6.4.
За копирање една датотека во друга е напи-
шана функцијата
kopiranjeDatoteka(ostream & izlezna, ifstream Слика 6.4
& vlezna)
чии аргументи се променливата за излез од типот ostream и променливата за влез
од типот ifstream. Бидејќи променливата за излез cout е од типот ostream, функ-
цијата може да се повикува и со
kopiranjeDatoteka (cout, vlezna);
Слика 6.5
211
ПРОГРАМИРАЊЕ
Задача 6.3
Да се формираат и спојат две текстуални датотеки.
Во програмата од слика 6.6 се спојуваат двете датотеки Tekst1.dat и
Tekst2.dat. За креирање на датотеките, се повикува функцијата kreiranjeDatoteka()
од типот void, во која се внесуваат записите како цели линии додека не се внесе
запис со една точка. Потоа, се отвора првата датотека Tekst1.dat за додавање (со
пaраметарот ios :: app) и на нејзиниот крај се додава втората датотека Tekst2.dat.
Ако се внесат двете датотеки Tekst1.dat и Tekst2.dat,
212
6. Датотеки
Слика 6.6
213
ПРОГРАМИРАЊЕ
Слика 6.7
214
6. Датотеки
215
ПРОГРАМИРАЊЕ
Задача 6.5
Да се напише програма за пресметување на
просечниот успех на ученик.
Слика 6.9
216
6. Датотеки
217
ПРОГРАМИРАЊЕ
Вежби
Вежба 6.1.1
Да се даде одговор на следните прашања:
1. Која библиотека од C++ треба да се вклучи за да се работи со дато-
теки?
2. Од кој тип се влезните, а од кој тип се излезните датотеки во С++?
3. Што е влезен поток, а што е излезен поток?
4. За што служи логичката датотека?
5. Кој е операторот за екстрахирање од влезен поток, а кој е за инсер-
тирање во излезен поток?
6. Што е потребно да се дефинира за да се отвори влезна датотека за
читање?
7. Што е потребно да се дефинира за да се отвори излезна датотека за
запишување?
8. Кои се карактеристиките на променливите за влезно-излезните дато-
теки? Од кој тип се тие променливи?
9. Како се отвора датотека за допишување во неа?
10. Како се врши контрола на начинот на отворање на влезно-излезна да-
тотека?
11. Кои модови за пристап до секвенцијалните датотеки постојат?
12. Како се задава името на физичката датотека преку тастатурата?
13. Кои се двете основни организации на датотеките?
14. Од што се состои записот во една датотека?
15. Со што завршува секоја датотека?
16. Која е разликата помеѓу секвенцијалните и случајните датотеки?
17. Со која функција се проверува крајот на датотеката?
18. Со која функција се чита цел запис?
19. Со која комбинација на копчиња се означува крајот на датотеката
при уредување со некој уредувач?
Вежба 6.1.2
Да се дополни Задача 6.5 така што датотеката да ги содржи и
предметите и оценките за еден ученик.
Вежба 6.1.3
Да се решат следните задачи:
1. Да се креираат датотека со предмети како во Задача 6.5 и датотека
со оценки за сите ученици од еден клас. Записите во датотеката со
оценки да содржат број во дневникот на ученикот и оценки по 12
предмети. Да се напише програма со која ќе се пресметаат средната
оценка на секој ученик и средната оценка на целиот клас.
218
6. Датотеки
219
ПРОГРАМИРАЊЕ
Резиме
220
7. Претставување на податоците во компјутерот
7. ПРЕТСТАВУВАЊЕ НА ПОДАТОЦИТЕ ВО
КОМПЈУТЕРОТ
Во оваа глава ќе се запознаете со следното:
Клучни зборови
221
ПРОГРАМИРАЊЕ
222
7. Претставување на податоците во компјутерот
0 0000 0 0
1 0001 1 1
2 0010 2 2
3 0011 3 3
4 0100 4 4
5 0101 5 5
6 0110 6 6
7 0111 7 7
8 1000 10 8
9 1001 11 9
10 1010 12 A
11 1011 13 B
12 1100 14 C
13 1101 15 D
14 1110 16 E
15 1111 17 F
Слика 7.1.1
Претворање на броевите од еден во друг броен систем
223
ПРОГРАМИРАЊЕ
Слика 7.1.3
За претворање на бинарните, окталните и хексадецималните броеви во
декадни, може да се искористи формулата (3). Според неа, на слика 7.1.4 е пока-
жано претворањето на бинарниот, окталниот и хексадецималниот број во дека-
ден.
224
7. Претставување на податоците во компјутерот
Слика 7.1.4
Претворање на декадните децимални броеви во бинарни,
октални и хексадецимални броеви и обратно*
225
ПРОГРАМИРАЊЕ
Слика 7.1.6
Претворањето на децималните бинарни броеви во декадни се врши по
формулата (3). На пример, претворањето на бројот 0.111012 е прикажано на
слика 7.1.7.
0.111012 = 1 · 2‒1 + 1 · 2‒2 + 1 · 2‒3 + 0 · 2‒4 + 1 · 2‒5 =
1 1 1 1 29 = 0.90625
0 10
2 4 8 32 32
Слика 7.1.7
По истата формула, може да се претвораат и броевите од другите бројни
системи. На слика 7.1.8 е покажано претворањето на окталниот децимален број и
на хексадецималниот децимален број во декаден децимален број.
0.7248 = 7 · 8‒1 + 2 · 8‒2 + 4 · 8‒3 = 0.875 + 0.03125 + 0.0078125 = 0.914062510
0.E8C16 = E · 16‒1 + 8 · 16‒2 + C · 16‒3 = 0.875 + 0.03125 + 0.0029296875 =
= 0.909179687510
Слика 7.1.8
Претворање на броевите меѓу бинарен, октален и
хексадецимален броен систем
226
7. Претставување на податоците во компјутерот
Вежби
Вежба 7.1.1
Вежба 7.1.2
227
ПРОГРАМИРАЊЕ
1
Вредноста на U зависи од технологијата на изработка на електронските кола.
228
7. Претставување на податоците во компјутерот
231
ПРОГРАМИРАЊЕ
n ‒ 1 n ‒ 2 n ‒3 5 4 3 2 1 0
0 0 0 0 0 0 0 0 … 0 0 0 0 0 0 0 0
n ‒ 1 n ‒ 2n ‒ 3 5 4 3 2 1 0
n
2 –1 1 1 1 1 1 1 1 … 1 1 1 1 1 1 1 1
0 − позитивен
S е битот за знакот на бројот. 𝑆={
1 − негативен
232
7. Претставување на податоците во компјутерот
16 bita
16 bita
0 00...00000 ‒16 11...10000
1 00…00001 ‒15 11…10001
2 00…00010 ‒14 11…10010
3 00…00011 ‒13 11…10011
4 00…00100 ‒12 11…10100
5 00…00101 ‒11 11…10101
6 00…00110 ‒10 11…10110
7 00…00111 ‒9 11…10111
8 00…01000 ‒8 11…11000
9 00…01001 ‒7 11…11001
10 00…01010 ‒6 11…11010
11 00…01011 ‒5 11…11011
12 00…01100 ‒4 11…11100
13 00…01101 ‒3 11…11101
14 00…01110 ‒2 11…11110
15 00…01111 ‒1 11…11111
Табела 7.2.4.1
Негативните броеви не се добиваат со едноставно ставање вредност 1 на
најзначајниот бит, туку како втор комплемент на позитивните броеви.
‒5 = 11011 од (+5 = 00101 (прв комплемент) 11010 + 1 11011)
При аритметичките операции со броевите ограничени во некој опсег од
n‒1
‒2 до 2n ‒ 1 ‒ 1, може да дојде до грешка, односно до т.н. преполнување (англ.
overflow) кога резултатот е надвор од опсегот. Тоа се случува кога резултатот е
помал од ‒2n ‒ 1 или поголем од 2n ‒ 1 ‒ 1.
На пример, за n = 8, опсегот на броевите е од ‒128 до 127. Во тој случај,
збирот на броевите 100 + 30 ќе се запише како негативен број, што се гледа од
собирањето на нивните бинарни записи. Нивниот збир е бројот 01100100
‒126 бидејќи збирот 10000010 е втор комплемент на бројот 126. + 00011110
10000010
Претставување на децималните броеви*
233
ПРОГРАМИРАЊЕ
10‒4 итн. Тоа значи дека децималната запирка можеме да ја ставиме каде било, а е
одредена со експонентот на бројот 10.
За бинарните броеви се користи експонент на бројот 2, така што општиот
облик на децимален бинарен број е M 2E, во кој M се нарекува мантиса, а E
експонент. На пример, децималниот бинарен број 11010.001 се запишува како
0.11010001 2101, со мантисата M = 0.110100012 и со експонентот E = 1012. Ако
бројот е 0.0001011012, тој се запишува како 0.101101 2‒11, т. е. со мантисата M =
0.1011012 и со експонентот E = ‒112. На ваков начин се обезбедува мантисата да е
1
помеѓу 0.10...0 M 0.11...1 , односно 2 ≤ М < 1.
Бидејќи по децималната точка секогаш има 1, велиме дека мантисата е
нормализирана и најчесто тој бит не се запишува.
Во персоналните компјутери се користи стандардот на организацијата
IEEE2, во кој мантисата се запишува со вредност 1 M 2, т. е. има вредност од
1.00... 0 до 1.11... 1, односно во облик 1 + F, во кој F е децималниот дел десно од
децималната точка и има вредност од 0.00… 0 до 0.11… 1. На овој начин скри-
ениот бит 1 се подразбира и не се запишува, а со тоа се обезбедува уште еден бит
повеќе за претставување на експонентот. Така, бројот 11010.1012 може да се за-
пише како 1.1010101 2100, т. е. со децималната мантиса F = 1010101 и со екс-
понентот E = 100. Значи, бројот го има обликот (1 + F) 2E.
Мантисата и експонентот се претставуваат во компјутерот, во зависност
од должината на зборовите. Ако компјутерот има w-битни зборови, тогаш прет-
ставувањето се врши како на слика 7.2.4.2. Ознаката S е битот за знакот на бро-
јот, и тоа 0 за позитивен и 1 за негативен број. Бројот на битови за експонентот E
е е, а m е бројот на битови за децималната мантиса F.
m+e m+e‒1 m m‒1 ... 2 1 0
S E + 2e ‒ 1 ‒ 1 F
1 бит e бита m бита
Слика 7.2.4.2
Бидејќи експонентот може да биде и негативен, се врши поместување за
2e ‒ 1 – 1 места, така што E + 2e ‒ 1 – 1 секогаш треба да биде позитивен број меѓу
00... 0 и 11... 1 со должина од е бита.
Во персоналните компјутери, според стандардот IEEE, во 32-битните
зборови експонентот има должина од 8 бита (e = 8), а децималната мантиса од 23
бита (m = 23). Тоа е т.н. претставување со обична точност.
Со двојна точност, броевите се претставуваат со 64-битни зборови. Екс-
понентот има 11 бита, додека децималната мантиса има 52 бита. Значи, со обич-
ната точност поместувањето на експонентот е за 27 – 1 = 127, а со двојната точ-
ност за 210 – 1 = 1023.
2
IEEE – Institute of Electrical and Electronics Engineers.
234
7. Претставување на податоците во компјутерот
235
ПРОГРАМИРАЊЕ
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
и тој е, всушност, најмалиот позитивен број што може да се претстави со дупли
збор. Значи, може да се претстават и сите броеви помеѓу 2‒126 и 2‒149.
За поголеми броеви и поголема точност се користи 64-битно претста-
вување, во кое експонентот се претставува со 11 бита, а мантисата со 52 бита.
Значи, најголемиот експонент е 1 023, а најмалиот експонент е –1 022. Најмалиот
позитивен број кој може да се претстави е 2‒1022 2.2 10‒308, а најголемиот е 21024
1.8 10308 .
Вежби
Вежба 7.2.1
Одговорете на следните прашања:
1. Зошто кај компјутерите се користи бинарниот броен систем?
2. Како се претставуваат знаците во компјутерот:
3. Што е код ASCII, а што Unicode?
4. Како се претставуваат сликите во компјутерот, а како звукот?
5. Што е пиксел?
6. Што е резолуција?
7. На кој начин се врши дигитализација на звукот во компјутерот?
8. Како се претставуваат целите броеви во компјутерот?
9. *Како се претставуваат децималните броеви во компјутерот?
Собирање
Основно правило при собирањето на две цифри во кој било бро- 175
ен систем е: ако збирот е поголем или еднаков на основата, тогаш од не- + 29
го се одзема основата и се пишува остатокот, а на погорната (полевата) 204
позиција се пренесува една единица. На пример, при собирање на брое-
236
7. Претставување на податоците во компјутерот
Одземање
237
ПРОГРАМИРАЊЕ
Знаеме дека во декадниот броен систем цели броеви се: ..., ‒ n , ‒ (n ‒ 1),...
‒ 3, ‒ 2, ‒ 1, 0, 1, 2, 3,... n ‒ 1, n,... Една од особините на целите броеви е дека
збирот на позитивен и негативен цел број со иста апсолутна вредност е 0, т. е.
+5 + (‒5) = 0, +21 + (‒21) = 0 итн.
Значи, и во бинарниот броен систем мора да важи оваа особина. Таа може
да се примени во случај кога ни е познат некој број и сакаме да го најдеме него-
виот спротивен број (со иста апсолутна вредност, но со спротивен знак). На при-
мер, ако е даден бројот
а = 101102, кој е бројот ‒а?
Поаѓајќи од правилото:
(+а) + (‒а) = 0,
можеме да пресметаме
(‒а) = 0 ‒ (+а), т. е. (‒а) = 00000 ‒ 10110.
Бидејќи од 0 не може да се одземе 1, треба да позајмиме 1 од погорната
позиција. Но бидејќи сите претходни цифри се 0, тогаш за да има од каде да по-
зајмиме, пред првата нула допишуваме 1.
Во конкретниов случај, со одземање со позајмување добиваме:
100000 Значи бројот (‒а) = 010102. 10110
‒ 10110 Ако го провериме условот (+а) + (‒а) добиваме: --------> + 01010
001010 Ако ја отфрлиме првата цифра 1, гледаме дека збирот е 100000
0.
Бидејќи бројот 100 000 = 25, заклучуваме дека спротивен (негативен број)
се добива со формулата
(‒a) = 2n – (+a)
во која n е бројот на битови на бројот (+а).
Добивањето на спротивен број (‒а) најчесто се врши на поедноставен (по-
лесен) начин. Прво се комплементира бројот (+а), така што единиците се замену-
ваат со нули, а нулите со единици. Така добиениот број се нарекува прв компле-
мент на (+а). Ако на него се додаде +1, ќе се добие број кој се нарекува втор
комплемент на (+а), кој е, всушност, (‒а).
На пример, за бројот (+а) = 10110 добиваме:
238
7. Претставување на податоците во компјутерот
Делење*
Множење и делење со 2
Вежби
Вежба 7.3.1
Пресметајте:
1. 100010 + 101100
2. 111 + 10001
3. 1100 + 10011
4. 10110111100 * 10
5. 10110111100 / 10
6. 10110111100 * 100
240
7. Претставување на податоците во компјутерот
Резиме
241
ПРОГРАМИРАЊЕ
242
8. Класи и објекти
8. КЛАСИ И ОБЈЕКТИ
Во оваа глава ќе се запознаете со следното:
Клучни зборови
243
ПРОГРАМИРАЊЕ
Слика 8.1.1
Ваквиот распоред на класите се нарекува хиерархија на класите (англ.
class hierarchy).
Друг пример е хиерархијата на класите на животни, а дел од неа е
прикажан на слика 8.1.2.
245
ПРОГРАМИРАЊЕ
Слика 8.1.2
На слика 8.1.3 е прикажана хиерархија на класите на геометриски форми.
Слика 8.1.3
Објектите од една класа се слични, ама не се еднакви, т. е. во една класа
нема два еднакви (идентични) објекти. На пример, ако класата Ucenici е класа на
сите ученици од едно училиште, во неа нема два исти објекти бидејќи нема два
идентични ученици.
Сите ученици имаат исти податоци, и тоа: име, презиме, година во која
учат, клас, број во дневникот, оценки итн. Значи, сите ученици се објекти со исти
карактеристики (атрибути), но со различни вредности на карактеристиките, раз-
лични имиња и/или презимиња, различни класови итн.
Вредностите на атрибутите на објектите се податоци: броеви, имиња, тек-
стови, слики и др.
На пример, ако ја има класата Pravoagolnik, атрибути на нејзините објекти
се страните dolzina и sirina. Но кои било два објекти правоаголници може да има-
ат различни вредности на атрибутите dolzina и sirina. На пример, ако именуваме
два објекти од класата Pravoagolnik како pravoagolnikEden и pravoagolnikDrug
(слика 8.1.4), гледаме дека вредностите на нивните атрибутите dolzina и sirina се
различни.
246
8. Класи и објекти
Слика 8.1.4
Се поставува прашањето: Како да се побара од некој објект да изврши
некоја акција? Тоа се прави така што треба да му испратиме некоја порака. На
пример, на кучето му „праќаме порака“, велејќи му „донеси го стапчето“, на ка-
валот со дување му „праќаме порака“ за да свири, преку копчето за вклучување
на радиото му „праќаме порака“ да работи, преку копчето Send „праќаме порака“
(до некој објект) да ја испрати електронската порака итн.
Објектите ги примаат пораките преку своите сетила (животните) или пре-
ку соодветни физички елементи (кај радиото, кај автомобилот и сл.) или преку
програмски елементи (копче, мени, наредба и сл.). Тие елементи формираат т.н.
интерфејс (англ. interface) на објектот. Интерфејсот на објектите претставува
„врска“ со околината, т. е. со други објекти.
За да одговори на одредена „порака“, објектот треба да изврши соодветна
акција. Сите акции кои може да ги изврши еден објект ја сочинуваат неговата
функционалност. Тоа значи дека за секоја акција, објектот извршува посебна
функција. На пример, за да лета птицата, треба да ги рашири крилјата и со нив да
замавнува. За да го донесе кучето фрленото стапче, треба да истрча до него, да го
земе и да се врати назад. За да се испрати електронска порака, апликацијата по-
викува соодветна програма и бара процесорот да ја изврши. За да ги дознаеме
плоштината и обиколката на некој правоаголник, треба да има функција за нивно
пресметување која треба да се повика и изврши итн.
За објектите: pravoagolnikEden и pravoagolnikDrug можеме, на пример, да
пресметаме: obikolka, plostina и dijagonala.
При која било акција што ја извршува објектот, се користат неговите ат-
рибути. Така, птиците за летање ги користат крилјата, кучињата за трчање ги ко-
247
ПРОГРАМИРАЊЕ
Слика 8.1.5
248
8. Класи и објекти
Pravoagolnik Krug
dolzina: double radius: double
sirina: double obikolka()
obikolka() plostina()
plostina() dijametar()
dijagonala()
Слика 8.1.6
1
Овие дијаграми се наречени UML-дијаграми, кратенка од Unified Modeling
Language, јазик за документирање и опис на компјутерски програми.
2
Функциите ќе ги запишуваме со името и мали загради на крајот за да се разли-
куваат од променливи со исто име.
249
ПРОГРАМИРАЊЕ
Вежби
Вежба 8.1.1
Да се одговори на следните прашања:
1. Што е објектно ориентирано програмирање (ООП) ?
2. Што претставува класа, а што објект во ООП?
3. Какви членки има класата во ООП?
4. Што е инстанца?
5. Што е класен дијаграм?
Вежба 8.1.2
Да се напише класен дијаграм за класата Triagolnik.
Пример 8.2.1
Да се дефинира класата Krug, според класниот дијаграм од слика 8.1.6 и
да се дефинира само една функција членка за пресметување на обиколката на
круг.
250
8. Класи и објекти
Слика 8.2.3
Еден излез од извршување на програмата е:
252
8. Класи и објекти
Слика 8.2.4
253
ПРОГРАМИРАЊЕ
Слика 8.2.5
3
Редоследот на функциите во една класа не е битен. Меѓутоа, логички е први да
бидат функциите со кои се поставуваат вредности на полињата на класата
(атрубутите на објектите), а потоа функциите за работа со полињата.
254
8. Класи и објекти
pravoagolnikEden
255
ПРОГРАМИРАЊЕ
Пример 8.2.3
Да се дефинира класата Uciliste и во неа да се напишат функции потребни
за работа со податоците за училиштето, според следниов класен дијаграм, слика
8.2.6.
Да се напише апликација (програма која содржи функција main()) за тес-
тирање на објекти од класата Uciliste.
Класата Uciliste е дадена на
Uciliste слика 8.2.7. Функциите за поставување
‒ imeNaUciliste: string податоци и земање податоци се слични
‒ imeNaMesto: string како и за класата Pravoagolnik. Да се
+ postaviImeNaUciliste(uciliste: string) потсетиме дека за да се користат функ-
+ postaviImeNaMesto(mesto: string) циите за управување со стрингови, пот-
+ zemiImeNaUciliste(): string ребно е да се вклучи соодветната биб-
+ zemiImeNaMesto(): string лиотека со наредбата
+ prikaziUciliste() #include <string>
Слика 8.2.6
Слика 8.2.7
256
8. Класи и објекти
Слика 8.2.8
Еден излез од програмата е:
257
ПРОГРАМИРАЊЕ
Слика 8.2.9
На пример, ако во главната функција од слика 8.2.8 ставиме наредби за
директен пристап до приватните податоци членови (слика 8.2.9), ќе добиеме
258
8. Класи и објекти
Слика 8.2.10
Ако приватните податоци членови на класата Uciliste од подрачјето
private: ги декларираме во подрачјето public:, тогаш со извршување на глав-
ната функција од слика 8.2.9, нема да се јават овие грешки бидејќи пристапот до
јавните членови е директен.
Вежби
Вежба 8.2.1
Внесете ги дадените примери со класите Krug и Pravoagolnik.
Пробајте да додадете по една функција членка и во двата примера и нив
да ги искористите во главната програма.
Вежба 8.2.2
Напишете класа Круг, во која ќе памтите податоци за круг (ради-
усот и координатите на центарот) и напишете функции членки преку кои:
1. ќе може да ја поставите вредноста за радиусот,
2. ќе може да ги поставите вредностите за координатите на центарот,
3. ќе може да го добиете периметарот на кружницата за да го отпечати-
те,
4. ќе може да ја добиете плоштината на кружницата за да ја отпечатите,
5. *ќе пресметате растојание од координатниот почеток до најблиската
точка на кружницата.
259
ПРОГРАМИРАЊЕ
Резиме
260
9. Динамички структури на податоци
Клучни зборови
261
ПРОГРАМИРАЊЕ
262
9. Динамички структури на податоци
9.1 Листи
1
*Линеарна поврзана листа е линеарна збирка од елементи наречени јазли, при што се-
кој елемент „покажува“ кон друг елемент (најчесто кон неговиот следбеник или прет-
ходник). Со тоа, на некој начин, одредени елементи се меѓусебно поврзани и оттаму доа-
ѓа терминот „поврзана“ листа. До поврзана листа се пристапува преку „покажувач“ кон
првиот јазол на листата. До секој следен јазол се пристапува преку врската која самиот
јазол ја содржи во себе, а е покажувач кон следен јазол. По конвенција, покажувачот врс-
ка во последниот јазол на листата е поставен на нула (0) за да се означи крајот на листата.
Во поврзана листа податоците се зачувуваат динамички – секој јазол се креира кога тоа е
потребно. Еден јазол може да содржи податоци од произволен тип, па дури и објекти од
други класи. Куповите и редовите (споменати подолу) се, исто така, линеарни податоч-
ни структури, па може да се разгледуваат и како верзии на линеарните поврзани листи
со одредени ограничувања.
Листите од податоци може да се зачуваат во низи, но поврзаните листи имаат не-
колку предности. Поврзаната листа е погодна кога бројот на податочни елементи кои тре-
ба да се претстават во даден момент е непредвидлив. Поврзаните листи се динамички, па
должината на листата може да се зголемува или намалува по потреба, а „стандардната“
низа во C++ има фиксирана големина уште за време на компајлирањето. Затоа, стандард-
ните низи може да се наполнат, а поврзаните листи стануваат полни само кога системот
има недоволно меморија за да ги задоволи побарувањата за динамичка алокација на ме-
морија.
265
ПРОГРАМИРАЊЕ
грешка. Исто така, пред да се земе елемент од купот, треба да се провери дали
купот е празен.
*На слика 9.2.1.2 е дадена програма со која купот се имплементира со
статичка низа, а е дефиниран како објект од класата Kup.
Слика 9.2.1.2
266
9. Динамички структури на податоци
267
ПРОГРАМИРАЊЕ
9.2.2 Ред
Слика 9.2.2.2
269
ПРОГРАМИРАЊЕ
270
9. Динамички структури на податоци
Вежби
Вежба 9.2.1
Одговорете на следните прашања:
1. Што е линеарна листа?
2. *Кои се разликите меѓу линеарна секвенцијална листа и линеарна по-
врзана листа?
3. Која е разликата меѓу линеарна секвенцијална листа и куп?
4. *Која е разликата меѓу линеарна поврзана листа и куп?
5. Која е разликата меѓу куп и ред?
Вежба 9.2.2
Напишете ги следните алгоритми:
1. Напишете алгоритам за инвертирање на низата [ai]n со користење
куп.
2. Напишете алгоритам за наоѓање на обратниот број на природниот
број n со користење куп.
3. Напишете алгоритам во кој ќе се изврши ротација на низа од букви
[ai]n за k-места налево со користење на ред.
Вежби
Вежба 9.3.1
Одговорете на следните прашања:
1. Што е функциски шаблон?
2. Зошто треба да се користат класни и функциски шаблони?
3. Што содржи стандардната библиотека на шаблони на С++?
9.4 Контејнери
Контејнер е збирка од шаблони и алгоритми кои имплементираат општи
структури на податоци. Контејнерот е објект кој содржи други објекти и овозмо-
жува пристап до нив со користење на итератори и функции/членки.
Во контејнерите се имплементирани најчесто користените структури на
податоци, како: низа (англ. array), куп (англ. stack), ред со еден и со два краја (ан-
гл. queue, англ. deque), еднаш и двапати поврзана листа (англ. forward_list, list),
множество (англ. set), мапа (англ. map) и други.
Контејнерите во библиотеката со контејнери се распределени во катего-
рии:
Секвенцијални контејнери (англ. sequence containers): array, vector, deque,
forward_list, list.
Адаптери за секвенцијални контејнери (англ. sequence container adapters):
stack, queue, priority_queue.
273
ПРОГРАМИРАЊЕ
Вежби
Вежба 9.4.1
Одговорете на следните прашања:
1. Што се контејнери како дел од STL?
2. Наведете ги типовите на контејнери во STL.
3. Потсетете се за класниот шаблон vector. Наведете некои функции/-
членки на vector.
2
Воведена во С++11.
3
Воведена во С++11.
274
9. Динамички структури на податоци
9.5 Итератори
Вежби
Вежба 9.5.1
Одговорете на следните прашања:
1. За што се користи итераторот?
2. Наведете 3 категории на итератори.
...
array <char, 4> z = {'a', 'b', 'c', 'd'};
array <char, 4> w = {'q', 'w', 'e', 'r'};
cout << " z = { ";
for(int k = 0; k < z.size(); k++)
cout << z.at(k) << ' ';
cout << "}\n";
cout << "\n Prv element vo nizata e " << z.front() << endl;
cout << "\n Posleden element vo nizata e " << z.back() << endl;
cout << "\n Maksimalen broj elementi vo nizata e " << z.max_size() <<
endl;
cout << "\n Dali e nizata prazna? (1 ‒ da, 0 ‒ ne) " << z.empty() <<
endl;
cout << "\n Dve nizi so ista dolzina moze da si gi zamenat sodrzinite
" << endl;
cout << " Pred zamenata: " << endl;
cout << "z";
pecatiNiza(z);
cout << "w";
pecatiNiza(w);
z.swap(w);
cout << "Po zamenata: " << endl;
cout << "z";
pecatiNiza(z);
cout << "w";
pecatiNiza(w);
277
ПРОГРАМИРАЊЕ
278
9. Динамички структури на податоци
279
ПРОГРАМИРАЊЕ
Сите елементи од STL, меѓу кои и класните шаблони (како vector), имаат
цела низа од функции кои се запишани во документацијата на STL. Многу од нив
не мора да ги знаете напамет, но добро е да знаете како да ги пронајдете во до-
кументацијата, можеби да се потсетите на нивната улога или да ја осознаете нив-
ната улога и да ги искористите на вистинско место во вистинско време. На при-
мер, vector ги содржи функциите: size(), empty(), push_back(), pop_back(), front(),
back() и begin() кои имаат константна сложеност О(1) и resize(), clear(), erase(),
insert() кои имаат линеарна сложеност O(N), која зависи од бројот на елементи во
векторот или од бројот на елементи кои се внесуваат или бришат од векторот.
Дел од овие функции ќе треба правилно да ги употребите при решавањето на за-
дачите од вежбите кои следат.
Вежби
Вежба 9.7.1
Напишете програма во која внесувате низа со N елементи – цели
броеви. Потоа, ја трансформирате низата на тој начин што за секои 2 еле-
менти од оригиналната низа (прв и втор, втор и трет...) пресметувате
280
9. Динамички структури на податоци
Вежба 9.7.2
Во едно училиште има N (< 10) паралелки во прва година. Во се-
која паралелка има по одреден број ученици (< 30). За секој ученик од се-
која паралелка го знаеме моменталниот просечен успех.
Директорот одлучил најслабите ученици од секоја паралелка да
ги префрли на местото на најслабиот ученик од следната паралелка и тоа:
од првата во втората, од втората во третата... од претпоследната во пос-
ледната и од последната во првата.
Напошете програма која ќе ги внесува податоците за учениците
по паралелки и потоа на излезот ќе отпечати како изгледа просекот на
учениците по промената. За секој клас да се отпечатат просекот по уче-
ник и просекот за целата паралелка.
На крајот на внесувањето податоци за секој клас се внесува 0.
Пример:
Влез:
3
3.4 4.2 5.0 5.0 4.2 2.1 4.8 0 (овде 2.1 се менува во следниот клас)
5.0 4.7 2.3 4.0 0 (овде 2.3)
3.4 4.2 5.0 3.4 4.2 1.8 2.5 0 (овде 1.8)
Излез:
P1: 3.4 4.2 5.0 5.0 4.2 1.8 4.8
P2: 5.0 4.7 2.1 4.0
P3: 3.4 4.2 5.0 3.4 4.2 2.3 2.5
prosek na P1: 4.057
prosek na P2: 3.975
prosek na P3: 3.571
281
ПРОГРАМИРАЊЕ
При декларирање на мапите (map <string, int> m), прво го наведуваме ти-
пот на клучот (во овој случај, string), а потоа типот на вредноста (во овој случај,
int). За користење на map, потребно е вклучување на <map>.
Постојат два начини за пристапување до елемент со одреден клуч: преку
наведување на клучот во загради '[kluch]' и преку користење на функцијата find().
Притоа, функцијата find() никогаш не резултира со менување на елементите во
мапата. Од друга страна, '[kluch]' ќе креира нов пар (клуч, вредност) во мапата
доколку таков клуч не постои. Ако го користиме функцијата count(), за да
изброиме колку парови во мапата имаат клуч со одредена вредност, резултатот
ќе биде 1 (доколку постои таков клуч) или 0 (доколку не постои таков клуч).
Кај мапите применливи се функциите: size(), empty(), begin() и end() кои
имаат константна сложеност O(1), функциите insert(), erase(), find(), count(),
lower_bound() и upper_bound() кои имаат логаритамска сложеност O(logN), како и
Функцијата clear() која има линеарна сложеност O(N).
Вежби
Вежба 9.8.1
На влез во програма добиваме информација за оценката што ја
имаат сите ученици од класот по Програмирање. Да се отпечатат оценки-
те на првите тројца, според абецеден редослед.
Пример:
Влез:
5
Pero 4
Tanja 5
283
ПРОГРАМИРАЊЕ
Andrej 3
Toni 2
Ana 4
Излез:
Ana 4
Andrej 3
Pero 4
284
9. Динамички структури на податоци
Вежби
Вежба 9.9.1
Напишете програма за инвертирање на низата [ai]n со користење
куп.
Вежба 9.9.2
Напишете алгоритам за наоѓање на спротивниот број на природ-
ниот број n со користење куп.
Вежба 9.9.3
Напишете програма во кој ќе се изврши ротација на низата од
букви [ai]n за k-места налево со користење на ред.
4
За да се користат најновите измени, дополнувања и нови функции во
MSVS2019, потребно е да се селектира:
Project > Properties > C/C++ > Language > C++ Language Standard >...
287
ПРОГРАМИРАЊЕ
Пример 9.10.1
Во овој пример ќе ги користиме функциските шаблони за печатење кон-
тејнер (низа, вектор), како и функцискиот шаблон sort() од библиотеката
<algorithm>.
#include <iostream>
#include <string>
#include <array>
#include <vector>
#include <iomanip>
usingname space std;
int main() {
const int n = 5;
array <int, n> a;
cout << "\nKontejner: array <int, n>" << endl;
citanjeContainer(a);
cout << "\nNesortirana niza:\t"; PecatenjeContainer(a);
sort(a.begin(), a.end());
cout << "Sortirana niza:\t\t"; PecatenjeContainer(a);
288
9. Динамички структури на податоци
Вежби
Вежба 9.10.1
Одговорете на следните прашања:
1. Наведете 3 категории на алгоритми од STL.
2. Објаснете преку пример како би се употребил алгоритамот find_if().
3. Објаснете преку пример како би се употребил алгоритамот repla-
ce_if().
4. Објаснете преку пример како би се употребил алгоритамот parti-
al_sort().
289
ПРОГРАМИРАЊЕ
Резиме
290
10. Алгоритми кај низи и графови
Клучни зборови
Тежински граф
Неориентиран граф
Теме
Пребарување граф прво по длабочина Функција на сортирање
Пребарување граф прво по широчина
291
ПРОГРАМИРАЊЕ
Слика 10.1.1.1
292
10. Алгоритми кај низи и графови
294
10. Алгоритми кај низи и графови
Слика 10.1.2.2
295
ПРОГРАМИРАЊЕ
296
10. Алгоритми кај низи и графови
297
ПРОГРАМИРАЊЕ
Пример
Во низата {4, 7, 12, 14, 16, 21, 32} го бараме елементот со вредност v = 16.
levo desno sredina a1 a2 a3 a4 a5 a6 a7
4 7 12 14 16 21 32
1 7 4 (= (1 + 7 + 1) / 2)
16 > 14 (= a4)
5 (= 4 + 1) 6 (= (5 + 7 + 1) / 2) 16 21 32
16 < 21 (= a6)
5 (= 6 – 1) 5 (= (5 + 5 + 1) / 2) 16
16 = 16 (= a5)
Програмата е дадена на слика 10.1.3.2.
Слика 10.1.3.2
298
10. Алгоритми кај низи и графови
299
ПРОГРАМИРАЊЕ
Вежби
Вежба 10.1.1
Преработете ги претходните програми за барање елемент во низа,
со користење на вектор наместо на низа. Таму каде што е потребно низа-
та да биде сортирана искористете соодветен алгоритам од STL.
Вежба 10.1.2
Напишете програма за бинарно барање на елемент во низа.
Вежба 10.1.3
Применете го алгоритамот binary_search() на несортирана низа.
Објаснете што сте забележале.
300
10. Алгоритми кај низи и графови
301
ПРОГРАМИРАЊЕ
Слика 10.2.1.1
Алгоритамот е даден на слика 10.2.1.2.
Од дрвото на споредби и од алгоритамот се гледа дека бројот на излезни
решенија е 6. Со подетална анализа, може да се заклучи дека за множество од n
елементи има вкупно n! излезни решенија. Затоа, овој алгоритам е многу неефи-
касен.
алгоритам СортирањеНаТриБроја
почеток
печати „Внесете три броја a, b и c: “;
читај a, b, c;
ако a < b
тогаш
ако b < c
тогаш
печати a, b, c
инаку
ако a < c
тогаш
печати a, c, b
инаку
печати c, a, b;
крај_ако {a < c}
крај_ако {b < c}
инаку
ако b > c
тогаш
302
10. Алгоритми кај низи и графови
печати c, b, a
инаку
ако a > c
тогаш
печати b, c, a
инаку
печати b, a, c;
крај_ако{a > c}
крај_ако {b > c}
крај_ако {a < b}
крај {СортирањеНаТриБроја}
Слика 10.2.1.2
10.2.2 Сортирање со наоѓање на најмалиот (или
најголемиот) елемент
303
ПРОГРАМИРАЊЕ
за i 1 зголемувај до n
2
за j i зголемувај до n – i – 1
ако aj < ai
тогаш
aj ai; {Razmena na sodrzinite}
крај_ако {aj < ai}
ако aj > an ‒ i ‒ 1
тогаш
aj an ‒ i ‒ 1; {Razmena na sodrzinite}
крај_ако {aj > an ‒ i ‒ 1}
крај_за {j}
крај_за {i}
печати „Сортирана низа: “;
ПечатењеНиза(n,a);
крај {СортирањеСоНаоѓањеНајголемИНајмалЕлемент}
Слика 10.2.2.1
Функцијата за сортирање е дадена на слика 10.2.2.2. Функциите citajNi-
za() и pecatiNiza() се исти како во програмите за секвенцијално и за бинарно ба-
рање.
...
Слика 10.2.2.2
Главната функција е дадена на слика 10.2.2.3.
Слика 10.2.2.3
304
10. Алгоритми кај низи и графови
Слика 10.2.3.1.3
Главната програма е дадена на слика 10.2.3.1.4. Во неа е вклучена библи-
отеката <chrono> со #include <chrono>, која содржи функција за читање на вре-
мето now() и функција за прикажување на времетраењето (периодот) duration().
Зборот auto се користи при декларација на променлива за означување
дека таа има автоматско времетраење. На пример, знаеме дека локалните про-
менливи имаат живот од нивното декларирање до крајот на блокот или функци-
јата. За да се потенцира тоа, во постарите верзии на С++ често променлива се де-
кларира со
auto int m = 10;
306
10. Алгоритми кај низи и графови
Во поновите верзии (од С++ 11)1, зборот auto има друго значење. Тој се
користи за автоматско одредување на типот на променливата, според типот на
податокот со кој е иницијализирана. На пример, со наредбите:
auto k = 5;
auto p = 12.345;
auto s = "Makedonija e vecna";
компајлерот заклучува дека променливата k е од типот int, p е од типот double, а s
е од типот string.
Во програмата од слика 10.2.3.1.4 се користи клучниот збор auto за авто-
матско одредување на типот на променливите pocetok, kraj и vreme, според типот
на податоците со кои се иницијализираат.
Функциите citajNiza() и pecatiNiza() се исти како во програмите за секвен-
цијално и за бинарно барање.
...
Слика 10.2.3.1.4
Еден излез од извршување на програмата е:
1
Клучниот збор auto има и други намени вградени во поновите верзии С++ 11 и С++ 14.
307
ПРОГРАМИРАЊЕ
инаку
БинарноБарањеПозиција(); {Најдена ј-та позиција}
за k m намалувај до j
bk + 1 bk; {Поместување на елементите}
крај_за {k} {од m-та до j-та поз. за 1 место десно}
bj t; {Вметнување на новиот елемент}
крај_ако{(m = 0) ИЛИ (t > bm)}
m m + 1; {Зголемување на димензијата}
крај_за {i}
печати „Сортирана низа: “;
за i 1 зголемувај до m
печати bi;
крај_за {i}
крај {СортирањеСоБинарноВметнување }
Слика 10.2.3.2.1
Функцијата за бинарно вметнување е дадена на слика 10.2.3.2.2.
Останатите функции и главната функција се исти како во програмата од
потточката 10.2.3.1 Сортирање со линеарно вметнување. Во главната функција
се повикува функцијата binarnoVmetnuvanje(a, m, a[i]);
...
...
Слика 10.2.3.2.2
309
ПРОГРАМИРАЊЕ
310
10. Алгоритми кај низи и графови
тогаш
ai ai ‒ 1 ; (Замена на вредностите)
zamena = „Да“;
крај_ако {ai < ai ‒ 1}
крај_за {i}
brojac brojac + 1;
додека brojac < n И zamena = „Да“;
крај_извршувај {brojac < n}
печати „Сортирана низа: “;
за i 1 зголемувај до n
печати ai;
крај_за {i}
крај {СортирањеСоМеурче}
Слика 10.2.4.1
Минувањето низ низата може да се врши од првиот до последниот
елемент или спротивно. Во алгоритамот на слика 10.2.4.1 минувањето се
врши одназад, т. е. од последниот кон првиот елемент. Со првото минува-
ње од последниот до вториот елемент, најмалиот елемент се доведува (ис-
пливува нагоре како меурче) на првата позиција. Со второто минување од
последниот до третиот елемент, вториот по големина елемент се доведува
(испливува нагоре како меурче) на втората позиција итн. На крајот се сор-
тираат последните два елементи од низата.
За забрзување на сортирањето, тоа се врши по повеќе патеки. Притоа,
бројот на патеките се намалува за половина додека не се дојде до една патека.
На пример, низата 7 1 9 8 2 4 3 може да се сортира по 3 патеки, и тоа:
311
ПРОГРАМИРАЊЕ
Пример 10.2.4.1
Да се сортира низа со алгоритамот сортирање со меурче по повеќе пате-
ки.
312
10. Алгоритми кај низи и графови
313
ПРОГРАМИРАЊЕ
314
10. Алгоритми кај низи и графови
Вежби
Вежба 10.2.1
Напишете функција која ќе имплементира алгоритам за сортира-
ње со наоѓање на најмалиот елемент. Искористете ја функцијата за да
сортирате низа внесена од стандарден влез.
Вежба 10.2.2
Со користење на кодот од Вежба 10.2.1, напишете функција која
ќе имплементира алгоритам за сортирање со наоѓање на најголемиот
елемент. Искористете ја функцијата за да сортирате низа која самите ќе ја
генерирате со функција за генерирање случајни броеви.
Вежба 10.2.3
Напишете програма за алгоритамот сортирање со кофи, според
објаснувањето во потточката 10.2.5.
Вежба 10.2.4
Истражете го алгоритамот Сортирање со броење (англ. Counting
sort). Напишете програма за овој алгоритам.
Вежба 10.2.5
Во една трафика се продаваат к (< 2 000) различни производи. За
секој од производите се знае неговата цена (цените се цели броеви во де-
нари и се помали од 50 000). Доаѓаат муштерии еден по еден и секој ку-
пува точно поеден производ.
Пред продавницата седи Марко и по ред ја запишува сумата која
ја плаќа секој од муштериите. На тој начин Марко формирал низа од цели
броеви. На крајот на денот, тој во низата запишал 0.
Напишете програма со која:
а) за даден број r ќе се отпечатат r највисоки цени кои се платени тој ден
од муштериите,
315
ПРОГРАМИРАЊЕ
10.3 Графови
2
Темата за графови е една од темите во овој учебник кои се основа на понапредното
програмирање. На веб-страната mendo.mk се обработени и дополнителни теми, а е даден
поинаков поглед на некои од темите кои се обработени тука. На учениците (особено на
оние кои учествуваат на натпреварите по Информатика) им советуваме да ги користат и
тие онлајн материјали. Делови од оваа тема се базирани на материјалот објавен таму.
316
10. Алгоритми кај низи и графови
317
ПРОГРАМИРАЊЕ
Слика 10.3.2.1
Вториот начин на кој може да се претстави еден граф е преку т.н. листи
на соседство. Замислете дека за секое теме во графот се чува по една листа во
која ни се запишани темињата до кои постои ребро. На пример, за графот со 5
темиња, тоа може да изгледа како на слика 10.3.2.2.
Слика 10.3.2.2
Со листите на соседство дадени на слика 10.3.2.2 имаме обележано дека
од темето 0 постојат ребра до темињата 2 и 3. Слично, од темето 2, постојат реб-
ра до темињата 0 и 4 итн. Од темето 1 не постојат ребра до ниту едно друго теме.
Доколку работиме со тежински графови, наместо листите да ни содржат само
броеви (како [2, 3]), тие може да се составени од пар од броеви, при што првиот
елемент ќе го означува темето до кое покажува реброто, а вториот број неговата
319
ПРОГРАМИРАЊЕ
тежина. На пример, [ (2, 5), (3, 7) ], со што имаме претставено дека од тоа теме
постои ребро до темето 2 (со тежина 5) и до темето 3 (со тежина 7). Се разбира,
како што споменавме и во претходната дискусија, тежините може да претставу-
ваат должина или некоја друга мерка. На пример, тежината може да претставува
проточност, т. е. колку литри вода може да се испраќаат по таа цевка во еден час
итн.
Во случај кога графот е неориентиран, кога ќе обележуваме дека постои
ребро од едно теме до друго (во листата), ќе запишеме и дека постои ребро од
тоа друго теме до првото. На пример, на слика 10.3.2.2, кај темето со индекс 0
имаме запишано дека од него постои ребро до темето 2, но и во листата на сосед-
ство за темето со индекс 2, ќе видиме дека постои ребро до темето 0. На овој
начин, алгоритмите кои ќе ги пишуваме ќе може едноставно да ги одредуваат
врските за да видат до кои темиња постојат ребра. За матрицата на соседство, ова
се сведува на запишување на истата вредност во елементите (i, j) и (j, i).
320
10. Алгоритми кај низи и графови
пат, а ако не е, тогаш означуваме дека тоа теме сме го посетиле и на купот ги
додаваме сите негови соседни темиња (темиња до кои има ребра).
Имплементацијата на овој алгоритам е дадена со следната програма,
слика 10.3.3.1:
Слика 10.3.3.1
Да ја разгледаме програмата. Забележете дека за претставување на графот
користиме листи на соседство (и тоа, N од нив, vector <int> G[N]). Следно, дефи-
ницијата за тоа ја имаме напишано надвор од функцијата DFS(start). Ова е многу
често при пишувањето на вакви програми бидејќи многу е веројатно дека ќе
имаме повеќе функции кои ќе ги повикуваме, па не сакаме да го наведуваме гра-
фот како параметар на секоја од нив. Се разбира, наместо N, треба да ставиме
некој цел број (на пример, 100), кој ќе ни биде однапред даден при решавањето
на разни проблеми. (Во практика веќе ќе знаеме колку градови има во некоја
држава и слично). Секој елемент од G[] соодветствува на листата на соседи на
соодветното теме со тој индекс: G[0], G[1], G[2] итн. Во функцијата што ја напи-
шавме, при разгледувањето на секое теме (node), можеме да ги разгледаме сите
негови соседни темиња, користејќи for(auto next: G[node]).
Во програмата, покрај G[] што ни служи за чување на листите на сосед-
ство, имаме и stack за чување на темињата кои треба да ги посетиме, како и visi-
321
ПРОГРАМИРАЊЕ
Пример 10.3.3.1
Дадени се бројот на неколку држави (до 100), како и листа од ребра кои
ќе означуваат дали постои гасовод помеѓу некои парови од нив. Сите гасоводи се
двонасочни (во проблемот кој ние ќе го решаваме), па графот ќе го гледаме како
да е неориентиран, т. е. како ребрата да немаат насока. Можно е да се случи овие
држави да се поделат во неколку групи кои меѓусебно не се поврзани. На при-
мер, ако дел од државите се наоѓаат на еден континент и постои гасоводен пат од
секоја држава до секоја друга, а дел од државите се на друг континент каде што
постои гасовод помеѓу нив, но не и до државите од првиот континент. За ваквите
изолирани групи ќе велиме дека се компоненти. Според терминологијата за гра-
фови, поврзана компонента е множество од темиња кои се меѓусебно поврзани,
т. е. постои пат помеѓу секои две од нив (преку едно или повеќе ребра).
Треба да се открие од колку компоненти е составен овој граф од држави.
Ова можеме да се реши со едноставно користење на функцијата DFS() од
слика 10.3.3.1. Имено, да замислиме дека сме ја повикале функцијата DFS() за
првото теме. Оваа функција, користејќи го алгоритамот, ќе ги обележи (во низата
visited[]) сите темиња кои се достапни со патишта. Ако по завршување на алго-
ритамот, откриеме теме во кое visited[i] = 0 (значи, не е посетено), ќе знаеме дека
тоа припаѓа на друга компонента, па ќе ја повикаме функцијата DFS() да ги обе-
лежи и темињата достапни оттаму. Слично, можеме со еден циклус for ова да го
направиме за сите темиња. Резултатот од алгоритамот ќе биде тоа што функци-
јата DFS() ќе ја повикаме онолку пати колку што имаме изолирани компоненти
во графот бидејќи нема да ја повикаме за некое теме што е веќе visited[i] = 1,
значи што е веќе посетено. Единствена промена што ќе треба да ја направиме во
однос на алгоритамот даден на слика 10.3.3.1, ќе биде да ја извлечеме низата
visited[N] надвор од функцијата DFS() бидејќи по нејзиното завршување ќе сака-
ме да знаеме кои темиња се веќе посетени и во функцијата main(). Комплетното
решение е дадено на слика 10.3.3.2.
323
ПРОГРАМИРАЊЕ
Слика 10.3.3.3
324
10. Алгоритми кај низи и графови
Пример 10.3.4.1
Дадено е едно дрво. Да се потсетиме дека дрво е неориентиран граф во
кој кои било две темиња се поврзани со точно еден пат. Дрвата не содржат цик-
луси и за нив знаеме дека бројот на ребра е за еден помал од бројот на темиња во
дрвото.
325
ПРОГРАМИРАЊЕ
0, сите негови директни соседи достапни преку едно ребро се од ниво 1, па сите
нивни соседи се од ниво 2 итн.
Овој проблем може едноставно да се реши со користење на алгоритамот
за пребарување по широчина (BFS) бидејќи тој ќе ги посети темињата по точниот
редослед по кој ни е нам потребно: најпрвин коренот, па сите темиња од ниво 1,
па сите темиња од ниво 2 итн. Единствено нешто на што треба да внимаваме е да
го зачуваме нивото на секое теме како што го откриваме – кога сме кај коренот,
да ги обележиме неговите соседи дека тие се од ниво 1, па кога сме кај темињата
од ниво 1 да ги обележиме нивните непосетени соседи дека тие се од ниво 2 итн.
Ова е реализирано со програмата дадена на слика 10.3.3.4.
...
Слика 10.3.3.4
326
10. Алгоритми кај низи и графови
Вежби
Вежба 10.3.1
Одговорете на следниве прашања:
1. Што е граф?
2. Што е теме, а што ребро во граф?
3. Која е разликата меѓу ориентиран и неориентиран граф?
4. Како може да се претстават графовите во компјутер?
Вежба 10.3.2
Разгледајте го објаснувањето поврзано со слика 10.3.2.1. Обидете
се да ги откриете и другите ребра запишани во матрицата кои не се
споменати во објаснувањето.
327
ПРОГРАМИРАЊЕ
Вежба 10.3.3
Со алгоритамот DFS да се утврди едно теме „папок“ на даден
граф. За едно теме велиме дека е „папок“ ако од него може да се стигне
до секое друго теме преку достапните ребра.
Вежба 10.2.4
Со алгоритамот DFS да се креираат матрица со димензии r x c и
даден елемент со неговите координати. Елементот да се постави на 0,
неговите соседи на 1, нивните соседи на 2 итн..
Пример:
Големина на матрицата: r = 9, c = 9.
Централни координати: (4, 4).
Излез:
444444444
433333334
432222234
432111234
432101234
432111234
432222234
433333334
444444444
Резиме
328
10. Алгоритми кај низи и графови
329
ПРОГРАМИРАЊЕ
330
ДОДАТОК
ДОДАТОК
331
ПРОГРАМИРАЊЕ
Б
цимално
цимално
цимално
Хексаде-
Хексаде-
Хексаде-
Хексаде-
ASCII
ASCII
ASCII
ASCII
Знак
Знак
Знак
Знак
0 0 NUL 32 20 (празно) 64 40 @ 96 60 `
1 1 SOH 33 21 ! 65 41 A 97 61 a
2 2 STX 34 22 " 66 42 B 98 62 b
3 3 ETX 35 23 # 67 43 C 99 63 c
4 4 EOT 36 24 $ 68 44 D 100 64 d
5 5 ENQ 37 25 % 69 45 E 101 65 e
6 6 ACK 38 26 & 70 46 F 102 66 f
7 7 BEL 39 27 ' 71 47 G 103 67 g
8 8 BS 40 28 ( 72 48 H 104 68 h
9 9 TAB 41 29 ) 73 49 I 105 69 i
10 A LF 42 2A * 74 4A J 106 6A j
11 B VT 43 2B + 75 4B K 107 6B k
12 C FF 44 2C , 76 4C L 108 6C l
13 D CR 45 2D - 77 4D M 109 6D m
14 E SO 46 2E . 78 4E N 110 6E n
15 F SI 47 2F / 79 4F O 111 6F o
16 10 DLE 48 30 0 80 50 P 112 70 p
17 11 DC1 49 31 1 81 51 Q 113 71 q
18 12 DC2 50 32 2 82 52 R 114 72 r
19 13 DC3 51 33 3 83 53 S 115 73 s
20 14 DC4 52 34 4 84 54 T 116 74 t
21 15 NAK 53 35 5 85 55 U 117 75 u
22 16 SYN 54 36 6 86 56 V 118 76 v
23 17 ETB 55 37 7 87 57 W 119 77 w
24 18 CAN 56 38 8 88 58 X 120 78 x
25 19 EM 57 39 9 89 59 Y 121 79 y
26 1A SUB 58 3A : 90 5A Z 122 7A z
27 1B ESC 59 3B ; 91 5B [ 123 7B {
28 1C FS 60 3C < 92 5C \ 124 7C |
29 1D GS 61 3D = 93 5D ] 125 7D }
30 1E RS 62 3E > 94 5E ^ 126 7E ~
31 1F US 63 3F ? 95 5F _ 127 7F DEL
332
ДОДАТОК
ЛИТЕРАТУРА
Deitel, P., Deitel, H.: C++20 for Programmers, Pearson, 3rd edition, 2020.
Deitel, P., Deitel, H.: C++ How to Program, Pearson, 10 edition, 2017.
Eckel, B.: Thimking in C++: Introduction to Standard C++, Vol.1, Prentice Hall,
2000.
http://gocmar.mk Компјутерска литература.
Јованчевски, Ѓ.: С++ Програмирање, универзитетски учебник, Гоцмар, Скопје
2018.
Јованчевски, Ѓ., Ацковска, Н., Стојчевска, Б, Јованов, М..: С++ Збирка
алгоритми и програми, универзитетски учебник, Гоцмар, Скопје 2017, 2007.
Јованчевски, Ѓ., Ацковска, Н., Стојчевска, Б, Јованов, М..: С++ Програмирање за
почетници, Гоцмар, Скопје 2011.
Јованчевски, Ѓ., Стојова, Р.: Програмски јазици, учебник за IV година гимназиско
образование, Гоцмар, Скопје 2009, 2006, 2004;
Јованчевски, Ѓ., Лазаревска, Ж.: Програмски јазици, учебник за III година
гимназиско образование, Гоцмар, Скопје 2009, 2006;
Јованчевски, Ѓ.: Информатика, учебник за I година гимназиско образование,
Гоцмар, Скопје 2009, 2002.
Јованчевски, Ѓ., Ацковска, Н., Стојчевска, Б.: С++ Основи на програмирање,
универзитетски учебник, Гоцмар, Скопје 2007.
Јованчевски, Ѓ.: Алгоритми и програми, Гоцмар, Скопје 1993.
Knuth, D.: The Art of Computer Programming, Volumes 1-4A, 1st Ed., Addison-
Wesley Professional, 2011.
Lippman, S., Lajoie, J., Moo, B.: C++ Primer, Addison Wesley Professional, 5
edition, 2012.
http://mendo.mk/ Систем за натпревари по информатика.
Sedgewick, R.: Algorithms in C++, 3th Ed., Addison Wesley Professional, 1998.
Sedgewick, R., Wayne, K.: Algorithms, 4th Ed., Addison Wesley Professional, 2011.
Stroustrup, B: The C++ Programming Language, 4th Ed., Addison Wesley
Professional, 2013.
333
ПРОГРАМИРАЊЕ
334