Основи на програмирање

Size: px
Start display at page:

Download "Основи на програмирање"

Transcription

1 Универзитет Гоце Делчев - Штип Факултет за информатика Д-р Владо Гичев Основи на програмирање ноември 2007 Штип

2 I Програмирање и решавање на проблеми Основни фази во компјутерското програмирање Во денешно време компјутерите се составен дел во сите области на нашето живеење Името компјутер доаѓа од англискиот збор computer и може да се дефинира како: компјутер е електронски уред кој може да се програмира и кој може да процесира, чува и враќа податоци Целта на овој текст е накратко да ги покрие основните концепти на компјутерското програмирање Се поставува прашањето што се подразбира под поимот програмирање Човековото деjcтвување и неговите мисли се поврзани со логички низи од активности кои се вршат свесно или несвесно На пример, кога вртиме страница од книга ние несвесно извршуваме логичка низа од активности: 1 ја подигаме дланката; 2 ја поместуваме раката кон десната страна од книгата; 3 го фаќаме десниот горен агол од листот; 4 го свртуваме листот, така што можеме да читаме на другата страница; 5 ја тргаме раката од книгата Или друг пример Масовното производство се извршува преку операции кои се случуваат по точно определен редослед Од горепосоченото може да дефинираме: - програмирање е процес на планирање и извршување на одредени операции и настани; - компјутерско програмирање е процес на планирање на низа чекори кои компјутерот треба да ги следи; - компјутерска програма е низа од инструкции кои компјутерот треба да ги изврши За да напишеме компјутерска програма, ние мора да поминеме низ три фази кои содржат свои подфази 1 Фаза на решавање на проблемот: - анализа и спецификација или дефинирање на проблемот и разбирање што треба да врши решението; - генерално решение на проблемот (алгоритам), што значи развивање на логичка низа од чекори кои го решаваат проблемот; - верификација која подразбира следење на чекорите од алгоритамот за да се потврди дали решението навистина го решава проблемот 1

3 2 Фаза на имплементација: - конкретно решение (компјутерска програма), што значи преведување на алгоритамот во програмски јазик-кодирање; - тестирање кое се состои од оставање на компјутерот да ги врши инструкциите и да даде резултат Овој резултат се проверува рачно и ако има грешки повторно се анализираaт програмата и алгоритамот да се утврди од каде доаѓаат грешките и се прават корекции Откако програмата е напишана, влегува во третата фаза: одржување 3 Фаза на одржување: - користење на програмата; - одржување, што подразбира модификација на програмата, заради потребa од промени или корекции на грешки кои се појавуваат при неговото користење Горенаведените три фази, заедно го сочинуваат животниот циклус (животниот век) на програмата Во првата фаза, програмерот го анализира проблемот и развива генерално решение (алгоритам) Алгоритам претставува чекор-по-чекор (step-by-step) процедура за решавање на проблемот во конечен број чекори Програмскиот јазик претставува множество од правила, симболи и клучни зборови кои се употребуваат да се конструира компјутерска програма Освен горенаведените три фази, документацијата е важен дел од програмирањето Документацијата вклучува: пишани објаснувања на проблемот што се решава и организација на решението, коментари вметнати во програмата и кориснички прирачници кои објаснуваат како да се употребува програмата Во текот на животниот циклус на програмата, на неа може да работат повеќе луѓе и цел на документацијата е овие програмери да ја разберат вашата програма Значи, документацијата е пишан текст и коментари кои ја прават програмата разбирлива за луѓето што ја употребуваат и модификуваат Информации, податоци и програмски јазици Откако програмата е напишана, на компјутерот тpeбa да му се дадат информации, односно податоци кои се неопходни за да се реши проблемот Информација е кое било сознание кое може да се пренесе На пример, тврдењето квадратот е четириаголник чии страни се еднакви и заемно нормални е информација Податок (data) е информација во форма која компјутерот може да ја употребува На пример, според горенаведеното тврдење и според должината на 2

4 страната на квадратот како податок, компјутерот може да ја определи површината и периметарот на квадратот Порано како податоци во компјутерите најчесто се употребувале броеви и букви Освен овие типови на податоци, модерните компјутери процесираат и звук, слики и сл Секој вид на податок може да биде претставен со комбинација од цифрите 0 и 1 Ова е бинарна форма на претставување на податоците Значи, за разлика од децималниот броен систем (база-10), кој ги вклучува цифрите од 0 до 9 за претставување на броевите, бинарниот броен систем (база-2) ги вклучува цифрите 0 и 1 Зборот bit (binary digit) се однесува на единична цифра 0 или 1 и претставува мерка за информација На пример, од 10 бита можат да бидат претставени 10 2 (1024) различни шеми од 0 и 1 Byte е група од 8 бита со која можат да се претстават 2 8 (256) шеми од 0 и 1 Во компјутерот, секој карактер (на пр А,?, с) обично се претставува со byte Групите од 16, 32 и 64 бита се нарекуваат зборови Бинарниот броен систем, сè уште се употребува за претставување на податоците во компјутерот Шемите на битови кои претставуваат податоци варираат од компјутер до компјутер За среќа, во денешно време податоците се внесуваат во облик на броеви, букви и симболи, кои компјутерот автоматски ги конвертира во бинарна форма Сите податоци во компјутерот, било да се работи за инструкции или чисти податоци, се сместени во меморијата и се претставени во бинарна форма Чистите податоци (броеви, букви и сл) и инструкциите се разликуваат само по начинот на кој компјутерот ги употребува Значи, можно е компјутерот да ги процесира своите инструкции како податоци Единствен програмски јазик кај првобитните компјутери бил тн машински јазик Машинскиот јазик е јазик кој е составен од бинарно кодирани инструкции кои се употребуваат директно од компјутерот Бидејќи различни компјутери употребуваат различни бинарни кодови за секоја инструкција, машинскиот код за еден компјутер е различен од машинскиот код за друг компјутер, иако тие решаваат ист проблем За олеснување на работата на програмерите, подоцна бил развиен assembly јазикот За разлика од машинскиот јазик, инструкциите во assembly јазикот не можат да бидат извршени директно од компјутерот Едно од фундаменталните откритија во компјутерската наука е дека компјутерот може да ги процесира сопствените инструкции во форма на податоци Ова својство се употребува во асемблерот (assemblеr) и компајлерот (compiler) Асемблер (Assembler) е програма која го преведува асембли (assembly) јазикот во машински код Иако напредок во однос на машинскиот јазик, асембли (assembly) јазикот е повторно врзан за инструкциите на конкретниот компјутер Конечно, компјутерските 3

5 научници развија виши програмски јазици кои се полесни за употреба, бидејќи во нив инструкциите се блиски до англискиот јазик Примери за виши програмски јазици се C++, FORTRAN, COBOL, Ada и др За разлика од ниските програмски јазици (машински и assembly) во кои кодирањето зависи од конкретната машина, вишите програмски јазици се портабилни, што значи дека ист код напишан на виш програмски јазик може да се извршува на различни машини Ова е постигнато со стандардизација на вишите програмски јазици Компајлер (Compiler) е програма која го преведува вишиот програмски јазик во машински код Програмата напишана на виш програмски јазик се нарекува изворна програма Компајлерот ги третира инструкциите во програмата (инструкциите за влез на податоци, инструкциите за пресметување, инструкциите за излез и др) како влезни податоци и ја преведува изворната програма во машински јазик, наречена објектна програма (сл1) Значи, објектната програма е верзија на изворна програма во машински јазик I zvor na pr ogr ama Objekt na pr ogr ama Составни делови на компјутерот сл 1 Најголем број од компјутерите имаат шест основни компоненти: мемориска единица, аритметичко-логичка единица, контролна единица, влезни единици, излезни единици, периферни единици за чување на податоци Мемориската единица е внатрешна единица за чување и манипулирање на податоци Таа се состои од мемориски ќелии (мемориски локации) кои имаат свои интерни адреси 4

6 Делот од компјутерот што ги извршува инструкциите е наречен централна процесорска единица (CPU) и таа има две компоненти: аритметичко-логичка единица и контролна единица Аритметичко-логичката единица е компонента на централната процесорска единица која ги извршува аритметичките и логичките операции Контролната единица е компонента на централната процесорска единица која ги контролира акциите на другите компоненти, така што инструкциите (програмата) се извршуваат во точен редослед Влезно-излезните единици се дел од компјутерот кој прифаќа податоци кои треба да се процесираат (влез) и ги прикажуваат резултатите од тоа процесирање (излез) Компјутерите може да имаат повеќе уреди, односно единици прикачени на нив Сите од овие уреди се познати под едно име периферија Такви уреди се: скенери, ЦД-ром, ДВД-ром, модеми, дигитални камери, микрофони, слушалки итн Периферна единица е влезна, излезна или помошна единица за чување податоци која е прикачена на компјутерот Помошна единица за чување податоци (Auxiliary storage device) е единица (уред) која ги чува податоците надвор од главната меморија на компјутерот Физичките компоненти на компјутерот со еден збор се нарекуваат хардвер (hardware) Множеството од програми со кои располага компјутерот се нарекува софтвер (software) Оперативен систем е множество од програми кои ги управуваат сите компјутерски ресурси (текстот е лекториран) II Синтакса и семантика на C++ и процес на програмски развој Елементи на C++ програмите Во претходната поглавје кажавме дека потпрограмите ни овозможуваат одвоено да пишуваме делови од програмa Потпрограмите во C++ јазикот се нарекуваат функции и C++ програмата е збир од една или повеќе функции На пример, ако сакаме програмата да ни пресметува квадрат и куб на одреден природен број, програмата може 5

7 да се состои од три функции (сл21) Една главна функција (main) и две додатни функции: - Ssquare, која ќе пресметува квадрат на дадениот број и - Cube, која ќе пресметува трет степен (куб) на дадениот број сл 21 6

8 Програмскиот код во C++ за пресметување на квадрат и куб од бројот 27 е следниов (сл 22): сл 22 Во секоја од трите функции, инструкциите меѓу левата и десната заграда и го означуваат телото на функцијата Извршувањето на програмата секогаш започнува со првата инструкција во main функцијата Функциите Square и Cube се примери на функции кои враќаат вредност (value-returning functions) Карактеристика на функција која враќа вредност е таа да враќа само една вредност и тоа на местото од каде што е повикана Зборот int на почетокот на првата линија од функцијата Square - int Square (int n) покажува дека функцијата враќа целобројна вредност на местото од каде што се повикува, те Square(27) во функцијата main Главната функција, main, е исто така функција која враќа вредност и тоа 0, ако извршувањето поминало во ред, или друга вредност ако нешто при извршувањето било погрешно Оваа вредност main ја враќа на оперативниот систем 7

9 Синтакса и семантика Програмскиот јазик е множество од правила, симболи и специјални зборови кои се употребуваат при креирањето на програмата Постојат правила за синтаксата (граматика) и семантиката (логика) Синтакса - формални правила кои укажуваат како валидни инструкции се пишуваат во одреден програмски јазик Семантика - множество од правила кои го определуваат значењето (логиката) на инструкциите напишани во програмскиот јазик Идентификатор (име на нешто во програмата) во C++ мора да биде барем буква или долна црта ( _ ) кои можат, но не мораат, да бидат следени од низа букви, долни црти и цифри Следните се валидни програмерски дефинирани идентификатори во C++: suma_na_kvadrati, count, id_broj, PI, totalscore Следните се невалидни програмерски дефинирани идентификатори во C++ : 40_casa името почнува со нумерички карактер, Get Data се јавува недозволен, blank, карактер во името, 20-dena се јавува недозволен, -, карактер во името, cena_vo_$ се јавува недозволен, $, карактер во името, int резервиран збор во C++ Последниот пример е резервиран збор во C++ и програмерот не може да го употребува како име на идентификатор Податоци и типови на податоци Компјутерската програма оперира со податоци кои можат да се чуваат интерно во меморијата, надворешно на диск или лента, или да се внесуваат преку уред (како тастатура, скенер и др) Во C++ секој податок мора да биде од специфичен тип Типот на податокот определува како податокот е претставен во компјутерот и видовите на процесирање кои компјутерот може да ги врши врз него 8

10 Тип на податок Конкретно множество од податочни вредности, заедно со множество од операции на тие вредности Типовите на податоци кои се употребуваат често се дефинирани внатрешно во C++ Примери на овие стандардни (или built-in) типови се int (за целобројни броеви), float (за децимални броеви кои вклучуваат децимална точка) и char (за карактери) Освен овие стандардни типови, C++ им дозволува на програмерите да дефинираат нивни сопствени типови на податоци programmerdefined (или user-defined) типови Тип на податок char претставува стандарден тип на податок и опишува податоци кои се состојат од еден алфанумерички карактер-буква, цифра или специјален симбол: A a 3 $ + - % и др Секој карактер во C++ е ограничен со апострофи На пример, карактерот 3 и интегер бројот 3 се чуваат на различен начин во меморијата на компјутерот Вообичаена операција врз карактери е споредување на два карактера Така A е помало од B, 3 е помало од 8 итн Собирањето на два карактера е можна но невообичаена операција Тип на податок string (стринг) претставува низа од карактери затворени во наводници i На пример, следниве се стрингови во C++: "Problem Solving" "C++" "Programming and " " " Стрингот мора да биде испишан комплетно во една линија На пример, стрингот: овој стринг е невалиден, бидејќи е испишан на повеќе од една линија е невалиден, бидејќи почнува на една линија, а завршува на друга и компајлерот јавува грешка при компилација Наводниците не се дел од стрингот, но служат само да го разграничат стрингот од другите делови на C++ програмата Типот на податок string не е дел од C++ јазикот (не е built-in тип) Тој е програмски дефиниран тип на податок кој е предефиниран во C++ стандардна библиотека, која претставува голема колекција на претходно напишани функции и типови на податоци која секој C++ програмер може да ја користи Вообичаени операции на стрингови се: - определување на должина на стринг; - пребарување на стринг за конкретен карактер; - поврзување на два или повеќе стринга во еден 9

11 Именување на елемeнти: декларации Идентификаторите можат да се употребуваат за именување на константи и променливи Вредностите на константите не можат да се менуваат во текот на извршувањето на програмата, а вредностите на променливите можат Декларација е инструкција во програмата која го поврзува името (идентификаторот) со описот на елементот во C++ програмата Во декларацијата ние го именуваме идентификаторот и опишуваме што тој претставува На пример, декларацијата int count означува дека count е променлива од тип integer Кога се декларира променливата, компајлерот обезбедува нејзина локација во меморијата Значи, декларација е инструкција што го поврзува идентификаторот со константа, променлива, програмерски дефиниран тип на податок или функција, така што програмерот се повикува на тој елемент преку неговото име Декларациите за константи, променливи, програмерски дефинирани типови на податоци и функции се различни во C++ јазикот Променлива се дефинира како локација во меморијата, која се повикува преку идентификатор и која содржи вредност која може да се менува Следната инструкција декларира sredeninicijal да биде променлива од тип char: char sredeninicijal; Во еден ред може да се декларираат повеќе променливи од ист тип На пример: int count, ocena, zbir; што има ист ефект како и следниве три декларации: int count; int ocena; int zbir; Константи се единечните карактери (затворени во апострофи) и стрингови (затворени во наводници) Примери за константи се: A 8 $ Programming and Problem Solving with C++ Во C++ како и во математиката, константата е вредност која не се менува Кога користиме актуелна вредност на константата во програмата, велиме дека користиме литерална вредност или литерал 10

12 Литерална вредност е вредност на константата запишана во програмата Освен како литерал, константата во програмата може да се јави и како именувана (симболична) константа Во овој случај се декларира име на константа и во декларацијата се доделува вредноста Следното се декларации на именувани константи: const string STARS = "********"; const char BLANK = ' '; const string BOOK_TITLE = "Programming and Problem Solving with C++"; const string MESSAGE = "Error condition"; значи Добра програмерска практика е преку коментар да се опише што константата На пример: const float MAX_HOURS =400; // Maksimalen broj na normalni casovi vo nedelata const float OVERTIME =15; // Faktor za prekuvremena rabota Извршни инструкции Доделување Вредноста на променливата може да се постави или промени преку инструкцијата за доделување На пример, инструкцијата lastname = "Lincoln" доделува стринг "Lincoln" на променливата lastname Значи, инструкцијата за доделување е инструкција која ја доделува вредноста на изразот од десната страна, во променливата од левата страна на операторот = Variable = Expression ; Дадени декларации: string firstname; string middlename; string lastname; string title; char middleinitial; char letter; Следниве инструкции на доделување се валидни: firstname = "Abraham" ; middlename = firstname; middlename = "" ; lastname = "Lincoln"; title = "President"; middleinitial = ' '; 11

13 letter = middleinitial; а следниве не се валидни инструкции на доделување: middleinitial = A - стринг не може да се додели во променлива од тип карактер letter = firstname; Стринг не може да се додели во променлива од тип карактер firstname = Thomas; Thomas е недеклариран идентификатор Edison = lastname; Само променлива може да се појави од левата страна на = lastname = ; Изразот од десната страна на = е испуштен Стрингов израз Иако не може да се изврши аритметика на стрингови, типот на податок string (стринг) овозможува специјална операција наречена конкатенација, која како оператор користи + Резултат од конкатенацијата (поврзувањето) е нов string (стриинг) кој се состои од првиот string (стринг) на кој му е прилепен вториот string (стринг) На пример, по дадените инструкции: string booktitle; string phrase1; string phrase2; phrase1 = "Programming and "; phrase2 = "Problem Solving"; можеме да напишеме booktitle = phrasel + phrase2; при што вредноста која ќе се додели на booktitle е "Programming and Problem Solving" Очигледно е дека за конкатенацијата не важи комутативниот закон Така booktitle = phrase2 + phrase1; на booktitle ќе и ја додели вредноста "Problem SolvingPrograniming and " Output (Излез) Инструкцијата cout «"Hello"; на стандардниот излезен уред (обично монитор) ќе ги покаже карактерите Hello Променлива cout е предефинирана во C++ системите да означи output stream (излезен тек) Излезниот тек претставува бескрајна низа од карактери кои одат кон излезниот уред Добиениот излез од следниве две инструкции: cout «"The title is "; 12

14 cout «booktitle + ", 2nd Edition"; е ист со излезот од инструкцијата cout «"The title is " «booktitle + ", 2nd Edition"; Ако вредноста на booktitle е American History и во двата случаи како излез ќе добиеме The title is American History, 2nd Edition Ако во излезот сакаме да го прикажеме карактерот, на пример, ако сакаме излез Al "Butch" Jones тогаш инструкцијата во C++ е: cout «"Al \"Butch\" Jones"; Обично инструкциите за излез се проследени со идентификаторот endl кoj означува крај на линија На пример, излезот од: cout << Univerzitet \ Goce Delcev\ ; cout << Stip ; e Univerzitet Goce Delcev Stip a izlezot od: cout << Univerzitet \ Goce Delcev\ << endl; cout << Stip ; e Univerzitet Goce Delcev Stip Конструкција на програма C++ програмите се состојат од функции, од кои една функција мора да го носи името main Програмата, исто така, може да содржи декларации кои лежат надвор од која било функција Синтактичката шема на програмата и на функција се дадени на сликата што следува 13

15 Сл 23 Како што се гледа од сл23, функцијата се состои од глава (heading) и тело (body) на функцијата Следното е пример на програма со само една функција (main) Програмата започнува со коментар кој објаснува што тој работи Веднаш по коментарот се појавуваат следниве линии: #include <iostream> #include <string> using namespace std; #include линиите му наложуваат на C++ системот да ја вметне во нашата програма содржината на датотеките именувани како iostream и string Првата датотека содржи информации кои & требаат на C++ програмата за да направи излез Втората датотека содржи информации за програмерски дефинираниот тип на податок string (стринг) Потоа доаѓаат декларации на константи по кои следува функцијата main Првата линија во функцијата е heading на функцијата: резервираниот збор int, името на функцијата и потоа загради Телото на функцијата вклучува декларации на две променливи, a потоа следуваат извршни инструкции На крајот, функцијата main враќа 0 на оперативниот систем 14

16 Нешто повеќе за излезот Креирање празни линии Вертикалните празни линии се контролираат со користење на манипулаторот endl во излезната инструкција Видовме дека низа од излезни инструкции продолжува да пишува карактери во иста линија, додека endl не ја прекине линијата На пример, низата од излезни инструкции: cout «"Hi there, " «endl «endl; cout «"Lois Lane" «endl; креира output Hi there Lois Lane Како што се гледа со два endl манипулатори еден по друг, се креира празна линија на излезот Истиот излез ќе се добие со користење на следнава инструкција: cout «"Hi there, " «endl «endl «"Lois Lane" «endl; Вметнување бланко карактери во линијата Хоризонталните празни места во излезот можат да се контролираат со вметнување екстра-бланко карактери На пример, овој излез: 15

17 Може да се постигне преку инструкциите: cout << * * * * * * * * * << endl << endl; cout << * * * * * * * * * * << endl << endl; cout << * * * * * * * * * << endl << endl; За да се појават празните карактери на излезот, тие треба да бидат затворени во наводници На пример, инструкцијата: cout «'*' «' * ' ; дава излез * * додека cout «'*' «<< ' * ' ; дава излез * * III Нумерички типови, изрази и output Преглед на C++ типови на податоци Стандардните или built-in типови на податоци во C++ се организирани во едноставни типови, структуирани типови и адресни типови (сл 3-1 во референца 1) Оваа глава ги разгледува integral и floating типовите на податоци 16

18 Интегрални типови на податоци Типовите на податоци char, short, int и long се познати како интегрални типови (или integer типови), затоа што тие реферираат на integer вредности Во C++ наједноставна форма на integer вредност е низа од една или повеќе цифри: Запирки не се дозволени Минус знакот кој претходи на integer вредност го прави integer-от негативен: Исклучок е специјалниот тип на податоци unsigned int кој прима само позитивни целобројни вредности и нула Овие типови на податоци се чуваат во ќелии во меморијата, при што на следната слика (сл32) е илустрирана должината на ќелијата во зависност од типот на податокот Сл 32 Програмерите скоро секогаш користат декларација int за манипулирање со целобројни вредности Во исклучителни случаи, кога се процесираат многу големи броеви (кои се надвор од рангот на int типот), треба да се користи long декларацијата На некои персонални компјутери рангот на int вредностите е од до Почесто рангот на int вредностите е од до Ако програмата се обиде да пресмета вредност надвор од овој ранг, резултатот е integer overflow Floating-Point типови на податоци Floating-point (или floating) типовите се користат за претставување на децимални (real) броеви Floating-point броевите имаат целоброен дел и децимален дел 17

19 со децимална точка меѓу нив Може да се случи целобројниот или децималниот дел (но не двата) да се испуштени од бројот Еве неколку примери на float типови на податоци: Исто како и интегралните типови (сл5), така и float типовите имаат различна должина Така float е со најмала должина, поголем е double и најголема должина во меморијата зафаќа long double Floating-point вредностите во научна нотација се претставуваат со експонент На пример, наместо да напишеме 3504 x 1012, во C++ ние пишуваме 3504E12 E претставува exponent на база 10 Еве неколку примери на броеви во научна нотација: E E4 7E20 Декларации за нумерички типови На сличен начин како што деклариравме char и string типови, можеме да декларираме нумерички типови Декларација на именувани константи Во случај на декларации на именувани константи, литералите во декларацијата се нумерички наместо стрингови Во следните примери, првите четири се декларации на нумерички константи, а последните два се примери на константи од char и string типови Декларација на променливи Нумеричките променливи се декларираат на ист начин како char и string променливите, освен што користиме имиња на нумерички типови Следниве се валидни декларации на променливи: int radius; // Radius na krug float sum = 0; // Zbir inicijaliziran na 0 float strana; // Strana na kvardat 18

20 int ocena; double alpha; // Ocenka na studentot (od 6 do 10) 99 za kraj // Agol vo radijani Аритметички оператори и изрази Изразите се состојат од константи, променливи и оператори Следните се валидни аритметички изрази: alpha + 2 rate alpha rate alpha * num Основни (built-in) аритметички оператори во C++ се: + унарен плус - унарен минус + собирање - вадење * множење / делење (делење на децимални броеви Резултат: децимален број) (делење на цели броеви Резултат: цел број без остаток) 19

21 % модул (делење на цели броеви Резултат: остатокот од делењето) Унарен оператор Оператор што има само еден операнд Бинарен оператор Оператор што има два операнда Примери на аритметички изрази и нивни вредности: Во горните примери, операндите се литерални вредности Освен литерали, операндите можат да бидат и константи или променливи Примери: Во претпоследниот пример, променливата alpha се јавува од двете страни на инструкцијата за доделување, = Математички оваа равенка нема решение, но во програмирањето ваков вид на доделување се среќава многу често и значи: зголеми ја старата вредност на alpha за 1 и резултатот додели го на новата вредност на alpha Така што, ако alpha било 3, новата вредност на alpha ќе биде 4 20

22 Следува едноставна програма која користи аритметички изрази: Increment и Decrement оператори Освен горенаведените аритметички оператори C++ располага и со increment и decrement оператори: ++ Increment -- Decrement Овие се унарни оператори кои земаат една променлива како операнд Како операнди можат да се јават целобројни или децимални броеви и ефектот е да се додаде 1 на (или одземе 1 од) операндот На пример, ако вредноста на num е 8, инструкцијата num++ ; го зголемува num за 1 и по нејзино извршување вредноста на num е 9 Истиот ефект се постигнува со инструкцијата num = num + 1; но C++ програмерите го преферираат increment операторот ++ и -- операторите можат да бидат употребени или како префикс оператори ++num; 21

23 или postfix оператори num++ ; Двете од овие инструкции имаат ист ефект, те додаваат 1 на num C++ дозволува користење на ++ и -- во средина на поголем израз На пример: alpha = num++ * 3; Во овој случај postfix формата не дава ист резултат со prefix формата Сложени аритметички изрази Тука разгледуваме посложени изрази кои содржат повеќе од еден оператор и изразите кои содржат мешани типови на податоци Правила на приоритет Основните аритметички оператори (унарен +, унарен -, + за собирање, - за одземање, * за множење, / за делење и % за модул) се подредени на ист начин како и математичките оператори во поглед на приоритетите на извршување на операциите Највисок приоритетен степен: унарен + унарен - Среден степен: * / % Најнизок степен: + - Кога аритметичкиот израз има неколку оператори со ист приоритетен степен, извршувањето се врши од лево кон десно Следуваат неколку примери: Имплицитна и експлицитна конверзија на типовите на податоци Integer и floating-point вредностите се чуваат различно во меморијата на компјутерот Што се случува ако во аритметичкиот израз или во инструкцијата за доделување помешаме integer и floating-point вредности? Инструкција на доделување Ако имаме декларации: int someint ; float somefloat; тогаш изгледа дека инструкцијата за доделување somefloat = 12; 22

24 ќе внесе integer вредност 12 во somefloat, но тоа не е точно Компајлерот прво имплицитно (автоматски) го конвертира 12 во 120 и тогаш доделува 120 во somefloat Инструкцијата someint = 48; исто така предизвикува имплицитна конверзија, при што доделува вредност 4 на someint Имплицитната конверзија од float во integer е опасна, бидејќи може да доведе до погрешни резултати кога програмерот не сакајќи доделува float на integer somefloat = 3 * someint + 2; someint = 52 / somefloat - anotherfloat; Програмерот зa да ја нагласи намерата да прави конверзија, треба експлицитно да ја најави конверзијата На пример: somefloat = float(3 * someint + 2); someint = int(52 / somefloat - anotherfloat); Долните две инструкции доведуваат до ист резултат во someint someint = somefloat + 82; someint = int(somefloat + 82) Разликата е во тоа што во втората инструкција се гледа намерата на програмерот, а во првата инструкција не е јасно дали програмерот ја превидел имплицитната конверзија од float во integer Аритметички изрази Имплицитна конверзија се јавува и во изрази кои содржат мешан тип на податоци someint * somefloat 48 + someint - 3 Вакви изрази се нарекуваат изрази од мешан тип Израз од мешан тип е израз кој содржи операнди од различни типови на податоци Кога integer и floating-point вредност се поврзани со оператор, настанува имплицитна конверзија како што следува: 1 integer вредноста привремено се конвертира во floating-point вредност; 2 се извршува операцијата; 3 резултатот е floating-point вредност Повикување на функција и библиотечни функции Функции кои враќаат вредност (Value-Returning Functions) На почетокот од втората глава прикажавме програма која се состои од три функции: main, Square и Cube Да се задржиме на следната инструкција од програмата: 23

25 cout «" and the cube of 27 is " «Cube(27) «endl; Во оваа инструкција main му налага Cube да пресмета куб од 27 и да го врати резултатот назад на main Cube(27) е повик на функција Компјутерот привремено ја остава main функцијата да чека и ја стартува Cube функцијата Кога Cube ја завршува својата работа, компјутерот се враќа на main и продолжува таму каде што застанал Во горниот повик на функцијата, бројот 27 се нарекува аргумент (или актуелен параметар) Аргументот овозможува функцијата која се повикува да работи за различни вредности На пример, може да се напишат инструкции како: cout «Cube (4); cout «Cube(11); Листата на аргументи е начин да функциите комуницираат меѓу себе Некои функции како Square и Cube, имаат само еден аргумент во листата на аргументи Некои функции како main, немаат аргументи, а некои функции имаат два, три или повеќе аргументи во листата, кои се одделени со запирки Функциите кои враќаат вредност се користат во аритметички изрази на сличен начин како што се користат и променливите На пример: someint = Cube(2) * 10; Ова се неколку карактеристики на функциите кои враќаат вредност: Повикот на функцијата се користи во израз Тој не се појавува како издвоена инструкција во програмата Функцијата пресметува вредност која е на располагање за користење во изразот Функцијата враќа точно една вредност (резултат) Ни повеќе ни помалку Аргументот во функцијата не мора да биде литерал Тој може да биде променлива, константа и аритметички израз како: alpha = Cube(int1 * int1 + int2 * int2) ; Аргументот дури може да биде повик на функција На пример: alpha = Cube(Square(int1) + Square(int2)); Библиотечни функции 24

26 Следувaaт мал број на предефинирани функции кои се наоѓаат во некои стандардни библиотеки: Користењето на библиотечни функции е лесно Следувa програмски сегмент кој користи библиотечна функција: Void функции Досега, во оваа глава, разгледувавме само функции кои враќаат вредност Во C++ постојат и функции кои не враќаат вредност или тн void функции На пример: void CalcPay ( ) : CalcPay е пример на функција која не враќа вредност на својот повикувач Таа само извршува некоја акција и завршува Void функција се повикува различно valuereturning функција Повикувањето на void функција е од издвоена stand-alone инструкција 25

27 CalcPay (payrate, hours, wages) ; Значи, можеме да резимираме, Value-returning функција е функција која враќа една и само една вредност на својот повикувач и се повикува од израз Void функција (процедура) е функција која не враќа вредност на својот повикувач и се повикува од издвоена инструкција Форматирање на Output Да се форматира излезот значи да се контролира како тој се појавува на излезниот уред (монитор, принтер или датотека) Досега видовме како се генерираат празни редови и празни места во еден ред За понатамошна контрола на излезот користиме тн манипулатори C++ стандардната библиотека содржи многу манипулатори, но сега ние разгледуваме само пет: endl, setw, fixed, showpoint, and setprecision Манипулаторите endl, fixed и showpoint доажаат со претпроцесор инструкцијата #include <iostream> Другите два манипулатора, setw и setprecision, бараат вклучување на датотеката iomanip во претпроцесорот #include <iomanip>: #include <iostream> #include <iomanip> using namespace std; cout «setw(5) «somelnt; Манипулаторот setw е кратенка од "set width" и овозможува контрола колку позиции на карактери му се доделени на следниот податок што треба да оди на излез Аргументот на setw е integer израз наречен fieldwidth specification Следниот податок ќе биде десно подреден, пополнет со бланко позиции од лево за да се пополни fieldwidth спецификацијата На пример: 26

28 Сетирањето на ширината на полето е еднократна акција, додека следниот податок не отиде на излез По овој излез, ширината на полето се ресетира на 0, што значи прошири го полето само онолку колку што му треба на следниот податок што оди на излез cout «"Hi" «setw(5) «ans «num; полето се ресетира на 0 откако излезе ans Како резултат ние добиваме излез Hi Манипулаторот наречен fixed се користи со цел излезот да се појавува во децимален наместо во научен формат cout «fixed «38 * x; Ако на излез оди цел број, C++ не ја прикажува децималната точка На пример, вредноста 950 се покажува на излезот како 95 Манипулаторот showpoint обезбедува излез на број со децимална точка: cout «showpoint «floatvar; Манипулаторот setprecision го контролира бројот на децимални места на излезот На пример, може да се случи да излез од cout «"Tax is $" «price * 005; биде Tax is $ За да се прикаже бројот со две (заокружени) децимални места, инструкцијата за излез е cout «fixed «setprecision(2) «"Tax is $" «price * 005; Следуваат неколку примери со манипулатори: 27

29 Следната табела дава краток преглед на манипулаторите што ги разгледувавме во оваа глава: 28

30 (лекториран текст) IV Прогрaмски инпут Откако програмaта е напишана, треба да се предвиди на кој начин ќе се внесуваат податоците Лошо решение е ако податоците се директно внесени како литерали во програмата Тогаш за процесирање на различни влезни вредности, треба постојано да се менува програмата Приложување податоци во програмите Една од најголемите предности кај компјутерите е што програмата може да се употребува со различни групи на податоци За да се направи тоа, треба податоците да се чуваат посебно од програмата Тогаш инструкциите во програмата ги копираат вредностите од групата на податоци во променливите на програмата По доделување на вредностите на променливите, програмата може да изврши пресметувања (сл 41 преземена од сл 4-1 во референца 1) сл 41 Процесот на доделување вредности од надворешна група податоци се нарекува input (инпут) Податоците за програмата можaт да дојдат од влезен уред или од датотека која се наоѓа на некој периферен уред (најчесто диск) 29

31 Влезен тек и еxtraction оператор (») Влезниот тек (input stream) може да се сфати како бескрајна низа од карактери кои доаѓаат во програмата од влезниот уред The concept of a stream is fundamental to input and output in C++ За да користиме влезен или излезен тек треба да користиме препроцесорска директива: #include <iostream> Хедер (Header) датотеката iostream содржи дефиниција на два типа на податоци: istream и ostream Ова се типови на податоци кои претставуваат input и output тек респективно Хедер (Header) датотеката, исто така, содржи декларации како istream cin и ostream cout Како што веќе видовме, вредностите се праќаат на излез cout со користење на insertion (вметнувачки) operator («), што значи стави на : cout << 3 * price На сличен начин, влезните податоци се добиваат од cin со користење на extraction операторот (») или доби од : cin>> cost Кога компјутерот ја извршува оваа инструкција, тој го внесува следниот број кој е втипкан на тастатурата (на пример 425) и го чува во променливата cost Еxtraction операторот» има два операнда Од лево е влезниот тек (во наједноставен случај променливата cin) Десниот операнд е променлива во која се внесува влезниот податок Операторот» може да се користи неколку пати во една инструкција за input (внос) На пример, нема разлика меѓу инструкцијата: cin» length» width; и парот на инструкции: cin» length; cin» width; За разлика од податоците специфицирани во излезната инструкција, кои можат да бидат константи, променливи или изрази, податоците специфицирани во влезната инструкција треба да бидат имиња на променливи Кога бара следна влезна вредност во текот, операторот» ги скока (игнорира) тн whitespace карактери Whitespace карактери се бланко и одредени непринтабилни карактери, како на пример карактерот што означува крај на линија 30

32 По игнорирање на whitespace карактерите, операторот» добива податоци од влезниот тек Ако програмaта бара карактер од тип char, влезот застанува штом еден карактер е влезен Ако бараниот тип на податок е int или float, влезот застанува штом се појави несоодветен карактер за овој тип на податок Еве неколку примери: Читачки маркер и карактер за нова линија Секоја влезна линија има невидлив карактер за нова линија (end-of-line карактер) што му кажува на компјутерот каде една линија завршува и следната почнува За да ја најде следната влезна вредност, операторот» ја поминува границата на линијата преку end-of-line карактерот Карактерот за нова линија се генерира со притискање на копчето Return или Enter Исто така, овој карактер се генерира кога програмата користи endl манипулатор во инструкцијата за излез Овој карактер е nonprintable контролен карактер кој системот го препознава како значење за нова линија, без разлика дали се работи за input или output Во C++ програма, на newline 31

33 карактер се реферира со користење на два симбола \n, backslash и n без бланко меѓу нив На пример, карактер за нова линија може да додели на char променлива ch = '\n'; Карактер за нова линија може да се вметне директно во string, како и кој било принтабилен карактер: cout «"Hello\n"; Последната инструкција има ист ефект како инструкцијата: cout «"Hello" «endl; Следуваат неколку примери на програмски инструкции, вредност на променливите по извршена инструкција и позиција на маркерот во влезниот тек, пред и по извршувањето на инструкцијата во програмата Читање на char карактери со get функцијата Како што беше споменато, операторот» игнорира whitespace карактери (како бланко и карактери за нова линија) Да претпоставиме дека chl и ch2 се char променливи и програмaта ја извршува следнава инструкција: cin >> ch1 >> ch2 Ако влезниот тек се состои од R 1 тогаш операторот >> доделува 'R' на chl, го игнорира бланко карактерот и доделува 1' во ch2 Ако сакаме да направиме внос на бланко карактер во променлива од тип char горната инструкција не работи Типот на податок istream обезбедува алтернатива на читање на карактери преку get функцијата, која не ги игнорира whitespace карактерите Бидејќи оваа функција (метод во објектно-ориентираното програмирање) е вградена во типот на податок istream, таа се повикува на различен начин од функциите што ги разгледувавме досега и користи dot нотација Повикувањето на функцијата изгледа вака: cinget(somechar) Забележете дека повикувањето на get функцијата употребува синтакса на повикување на void функција Ефектот од горниот повик е внос на следниот карактер од влезниот тек во променливата која се јавува како аргумент (somechar) Овој карактер може да биде и непринтабилен карактер (на пример, бланко) Аргументот на get функцијата мора да биде променлива Користејќи ја get функцијата, ние сега можеме да ги внесеме сите три карактери од влезната линија: R 1 Ние можеме да користиме три последователни повикувања на get функцијата: cinget(ch1); cinget(ch2); cinget(ch3); или можеме да ги користиме следниве инструкции: cin» ch1; cinget(ch2); 32

34 cin» ch3; Освен get функцијата, влезниот тек има вградено и функција за прескокнување карактери Тоа е функција со два аргументa, која се повикува како во следниот пример: cinignore(200, '\n'); Првиот аргумент е int израз, а вториот char вредност Во овој пример, функцијата му кажува на компјутерот да ги игнорира (скокне) следните 200 input карактери или да ги игнорира карактерите до наоѓањето на карактер за нова линија (newline карактер) Валиден е условот што прв се исполнува Еве неколку примери кои користат char променлива и три int променливи i, j и k: Внос (читање) на string (стринг) податоци За внос на карактери во string (стринг) променлива, повторно може да се користи операторот» Од порано знаеме дека овој оператор ги игнорира whitespace карактерите На пример, ако имаме ваков програмски сегмент: string firstname; string lastname; cin» firstname» lastname; и влезниот тек (stream) изгледа вака: Mary Smith 18 тогаш влезната инструкција во програмскиот сегмент доделува четири карактери Mary во firstname, пет карактери Smith во lastname и го напушта влезниот тек како 18 Ако во стрингот сакаме да имаме празни (бланко) карактери, вносот со овој оператор е неуспешен Тогаш ја користиме функцијата getline Повикот на оваа функција изгледа вака: 33

35 getline(cin, mystring); Повикот на функцијата бара два аргумента Првиот е влезниот тек (овде cin) и вториот аргумент е string променлива Оваа функција не скока whitespace карактери и продолжува додека не го достигне end-of-line карактерот, \n Ова значи дека getline функцијата доделува цела влезна линија на вториот аргумент На пример за следниот сегмент: string inputstr; getline(cin, inputstr); и влезна линија Mary Smith 18 Резултатот од повикот на getline е сите 17 карактери од влезната линија (вклучувајќи и бланко карактери) да се доделуваат на inputstr, а читачкиот маркер се позиционира на следната линија Интерактивен Input/Output Интерактивна програма е програма во којa корисникот директно комуницира со компјутерот Корисникот за да внесе податоци во интерактивна програма, програмерот во својата програма треба да предвиди влезни промптови (input prompts) кои претставуваат пораки кои се јавуваат на мониторот и му појаснуваат на корисникот што треба да внесе Освен влезните промптови, програмерот во својата програма треба да предвиди тн echo printing што претставува прикажување на податоците кои корисникот ги внел, така што корисникот ќе направи контрола на својот внос пред податоците да се процесираат Во следниот програмски сегмент е прикажано правилно користење на промптови и echo printing: 34

36 Неинтерактивен Input/Output Општ пример на неинтерактивен I/O на големи компјутерски системи е batch процесирањето Овој метод е ефективен, кога програмата на внос или излез има голема количина на податоци Кога програмата треба да чита многу податоци, вообичаено е тие податоци да се внесат претходно во датотека на дискот Ова му овозможува на корисникот да нaправи промени или корекции во податоците пред да ja стартува програмата Ако програмата прави излез на голем број податоци, излезот се праќа во датотека или на брз печатар Програмите дизајнирани за неинтерактивен I/O не прикажуваат промптови Датотеки (Files) Датотека е именуван дел од периферниот уред кој чува збир на информации (на пример, програмски код кој е внесен преку едиторот) Информациите во датотеката обично се чуваат на периферен уред, најчесто диск Нашите програми можат да читаат податоци од датотека на ист начин како што читаат податоци од тастатура и можат да го пишуваат излезот во датотека на ист начин како што го пишуваат излезот на монитор Кога се работи за голема количина на влезни податоци, многу е полесно тие да се внесат преку едитор во датотека, отколку да се внесуваат интерактивно преку тастатура Исто така, кога програмата праќа голем број податоци на излез, излезот полесно се анализира кога се впишува во датотека, отколку да се гледа на монитор Користење на датотеки Ако сакаме нашата програма да користи датотеки, треба да направиме четири работи: 1 претпроцесорот треба да вклучи header file fstream; 2 да се декларираат датотечните текови (file streams ) што ќе бидат користени во програмата; 3 да се припреми секоја датотека за читање или впис со користење на вградената функција open; 4 да се специфицира името на датотечниот тек во секоја влезна или излезна инструкција 35

37 Вклучување (Including) на Header датотеката fstream Ова вклучување се постигнува со претпроцесорската директива: #include <fstream> Преку header датотеката fstream, C++ стандардната библиотека дефинира два типа на податоци, ifstream и ofstream (кои означуваат input file stream и output file stream) Сите istream операции за кои зборувавме: extraction операторот (»), get функцијата и ignore функцијата се исто така валидни за ifstream типот Исто така, сите ostream операции: insertion операторот («) и манипулаторите се валидни за ofstream типот Декларирање на датотечните текови (file streams) Во програмата stream се декларираат променливите на ист начин како што се декларира која било променлива Значи, прво се специфицира тип на податок и потоа име на променлива: int somelnt; float somefloat; ifstream infile; оfstream outfile; ifstream indata; ofstream outdata; // Holds map distances in inches // Holds walking distances in miles Забележете дека ifstream типот се однесува само за влезни, а ofstream типот само за излезни датотеки Значи не може да се чита и пишува во иста датотека Oтворање на датотеки Во нашиот пример, ние сакаме да читаме од датотека indata и да запишуваме во датотека outdata Релевантните датотеки се отвораат со следниве инструкции: indata open ("walkdat ); outdataopen("resultsdat"); Двете инструкции се однесуваат на повикувања на функции Во секој повик на функција, аргументот е литерален стринг затворен во наводници 36

38 Функцијата open прво ја поврзува stream променливата која се користи во програмата со физичката датотека на дискот Следната работа што ја прави open е во зависност од тоа дали датотеката е влезна или излезна Ако датотеката е влезна (input), open функцијата го поставува читачкиот маркер на првиот податок во датотеката Ако датотеката е излезна, open функцијата проверува дали датотеката веќе постои Ако датотеката не постои, open креира нова празна датотека, а ако веќе постои, open ја брише нејзината содржина и го поставува маркерот за впишување на почетокот на празната датотека Како вписот напредува, маркерот за пишување додава (допишува) податоци додека не заврши на крајот на датотеката Специфицирање на File Streams во Input/Output инструкциите Како што нагласивме, сите istream операции се исто така валидни за ifstream типот и сите ostream операции се валидни за ofstream типот Така, за да читаме од или впишуваме во датотека, сè што треба да направиме е во нашите влезни и излезни инструкции да ги замениме cin и cout со соодветните file текови (streams) На пример, можеме да ја напишеме следнава инструкција: indata>>distance1>>distance2>>distance3>>distance4>>scale; која му кажува на компјутерот да чита податоци од датотеката indata наместо од cin На сличен начин сите излезни инструкции наместо cout ќе впишуваат во outdata outdata<< Total mileage for the day <<totmiles<< miles << endl; Run-Time внос на име на датотека Aргументот што го употребувавме во open функцијата беше литерален стринг На пример: ifstream infile; infileopen("datafiledat"); Ако сакаме да ја направиме програмата пофлексибилна, име на датотека која постои на дискот можеме да внесеме во време на извршување на програмата (run-time) Општа техника е на корисникот да му се покаже промпт на кој тој ќе го впише името на датотеката Во принцип следниот код треба да го дозволи тоа: ifstream infile; string filename; cout «"Enter the input file name: "; cin» filename; infileopen(filename); // Compile-time error 37

39 Овој код генерира грешка во компилација Проблемот е во тоа што open функцијата не прима аргумент од тип string Функцијата open очекува аргумент од тип C string (така е наречен бидејќи потекнува од C јазикот) За да горниот код работи коректно, стринг променливата треба да се конвертира во C string Типот на податок string располага со value-returning функција по име c_str, која на стринг променлива може да се примени како што следува: filename c_str() Оваа функција враќа C string Примарната намена на c_str функцијата е да им дозволи на програмерите да повикуваат библиотечни функции кои очекуваат C strings како аргументи Користејќи ја c_str функцијата, ние можеме да го кодираме run-tirne влезот на името на датотеката како што следува: ifstream infile; string filename; cout «"Enter the input file name: "; cin» filename; infile open (filename c str ()) ; Пад на влезот Да претпоставиме дека извршуваме програма Програмата нè промптира да внесеме integer, а ние внесуваме некои букви преку тастатура Влезната операција паѓа поради невалидни податоци Во терминологијата на C++ велиме дека cin влегол во fail state Штом текот влезе во fail state секоја понатамошна I/O операција која го користи тој тек е null операција, те нема никаков ефект Но компјутерот не го прекинува извршувањето на програмата, туку ги врши инструкциите со претходните вредности на променливите Најчеста причина за пад на вносот е невалиден внос Честа причина е и непостоење на влезната датотека од која треба да се чита Да претпоставиме дека програмата има int променливи i, j и k, чии моментални вредности се 10, 20 и d 30 соодветно Програмата ги извршува следниве две инструкции: cin>>i>>j>>k; cout<< i: <<i<< j: << k: <<k; Ако на влез имаме: тогаш програмата дава output: i: 1234 j: 20 k: 30 38

40 Да анализираме што се случило Кога почнал да чита, на првиот податок cin влегол во fail state, бидејќи за читање на int тип наишол на До тогаш ја примил само новата вредност на i Откако влегол во fail state, секој обид за внос нема ефект и другите две променливи остануваат со старите вредности 39

41 (лекториран текст) V Услови, логички изрази и контролна структура - селекција Тек на контрола е редоследот по кој компјутерот ги извршува инструкциите во програмата Текот на контролата, нормално, е секвенцијален (сл 51) Тоа значи дека кога една инструкција е завршена, контролата преминува на следната инструкција во програмата сл 51 Кога сакаме текот на контролата да биде несеквенцијален, ние користиме контролни структури кои претставуваат специјални инструкции кои ја предаваат контролата на инструкцијата, поинаква од онаа инструкција која доаѓа следна во програмата Контролна структура е инструкција која се користи да го промени секвенцијалниот тек на контролата Селекција Контролната структура селекција (или разгранување) ја користиме кога сакаме компјутерот да избере меѓу алтернативни акции Правиме тврдење (assertion) кое е или точно (true) или погрешно (false) Ако тврдењето е точно (true), компјутерот извршува една инструкција (statement), ако е погрешно (false), тогаш извршува друга инструкција (сл 52) Способноста на компјутерот да решава проблеми е резултат на неговата способност да прави одлуки и извршува различни низи од инструкции 40

42 сл 52 Услови и логички изрази Поставувањето прашања во C++ се сведува на составување на тврдења кои се точни или погрешни Компјутерот го цени (evaluates) тврдењето да провери дали е точно (true) или погрешно (false) Тип на податок (bool) Во C++ типот на податок bool е built-in и се состои од само две вредности, константите true (точно) и false (погрешно) Клучниот збор bool е кратенка од Boolean и вредностите од овој тип се користат за тестирање на услови во програмата, така што компјутерот може да направи одлука Накратко bool податокот е поврзан со контролната структура - селекција Променливите од типот bool се декларираат како променливите од другите прости типови: bool dataok; //True if the input data is valid bool done; // True if the process is done bool taxable; // True if the item has sales tax Логички изрази Во програмските јазици, тврдењата имаат форма на логички изрази (тн Boolean изрази) Како што аритметичкиот израз е составен од нумерички вредности и операции, логичкиот израз се состои од логички вредности и операции Секој логички израз има една од двете вредности: true или false Ова се неколку примери на логички изрази: - Boolean променлива или константа; - израз по кој следи релационен оператор по кој следи израз; 41

43 - логички израз по кој следи логички оператор по кој следи логички израз Наједноставен логички израз е само променлива или константа од типот bool Променлива од типот bool може да прими само две вредности true или false На пример, ако dataok е декларирана како променлива од типот bool, тогаш dataok = true е валидна инструкција на доделување Релациони оператори Друг начин за доделување вредност на Boolean променлива е таа да се сетира еднаква на резултатот на споредување два израза со релационен оператор Релационите оператори ја тестираат врската меѓу две вредности Во следниот програмски сегмент, lessthan е Boolean променлива, а i и j се int променливи: cin» i» j ; lessthan = (i < j); // Споредува i и j со "помало од" // релационен оператор и доделува //true или false на lessthan Следното се релации кои можеме да ги тестираме во C++: = = Equal to (еднакво на)! = Not equal to (не е еднакво на) > Greater than (поголемо од) < Less than (помало од) >= Greater than or equal to (поголемо од или еднакво на) <= Less than or equal to Израз по кој следува релационен оператор, а по него повторно израз се нарекува релационен израз Резултатот на релационен израз е од типот bool На пример, ако x е 5, а y е 10, сите од следниве изрази имаат вредност true: x!= y y > x x < y y >= x x <= y Освен нумерички вредности, може да се споредуваат и карактери Ако x е 'M' и y е 'R', Вредноста на изразот x < y е true, бидејќи 'M' доаѓа пред 'R' во абецедата и во ASCII (American Standard Code for Information Interchange) множеството на карактери 42

44 Од друга страна, во ASCII големите букви доаѓаат пред малите Така: 'M' < 'R' и m < r имаат вредност true, но 'm' < 'R има вредност false Секогаш треба да се споредуваат податоци од ист тип Кога се споредуваат различни типови на податоци, тоа треба да биде наведено со експлицитна конверзија somefloat >= float(somelnt) Ако се споредуваат bool вредности со нумерички вредности, компјутерот имплицитно ја конвертира вредноста false во 0, и true во 1 Значи, ако boolvar е bool променлива изразот boolvar < 5 добива вредност true, затоа што и 0 и 1 се помали од 5 Следуваат примери: Треба да се внимава како релационен оператор место = =, по грешка не се стави операторот за доделување = Овие два оператора имаат многу различни ефекти во програмата Споредување на стрингови Како операнди на релациониот оператор можат да се јават два стринг објекта (константи или променливи), како: mystring < yourstring или стринг објект и C string: mystring >= "Johnson" Меѓутоа, ако и двата операнда се од тип C string, ќе се добијат неточни резултати Споредувањето на стрингови ја следи редоследната низа во множеството на карактери (на пример ASCII ) Кога компјутерот ја тестира врската меѓу два стринга, тој почнува од првите карактери на стринговите, aко се еднакви, продолжува да ги 43

45 споредува вторите карактери итн Тестирањето завршува кога двата карактерa не се еднакви или кога и крајните карактери се еднакви Ако сите карактери се еднакви, тогаш и стринговите се еднакви, инаку стрингот кај кој карактерот е помал во ASCII е помал стринг На пример: Ако се споредуваат два стринга со различна должина, при што карактерите на пократкиот и подолгиот стринг до крајот на пократкиот стринг се еднакви, тогаш пократкиот стринг се евалуира како помал На пример, за word2 = Small изразот word2 < "Smaller" има вредност true Логички оператори Во математиката, логичките оператори AND, OR и NOT земаат логички изрази како операнди C++ користи специјални симболи за логички оператори: && (за AND), за OR) и! (за NOT) Со комбинирање на релациони оператори со логички оператори, може да се направат посложени тврдења На пример, сакаме да определиме дали резултатот од испит е поголем од 90 и резултатот од колоквиум е поголем од 70 Во C++, ние би го напишале изразот (тврдењето на овој начин): finalscore>90 && midtermscore> 70 Операторите && и секогаш се појавуваат меѓу два изразa, те тие се бинарни оператори Операторот NOT (!) е унарен оператор и тој зема само еден операнд Тој претходи на единичен логички израз и дава спротивен резултат од евалуацијата на изразот Ако (grade == 'A' ) е false, тогаш! (grade == 'A' ) е true Со NOT можеме да го менуваме значењето на тврдењето На пример:!(hours > 40) 44

46 е еквивалентно на hours <= 40 Следниве изрази се еквивалентни (изразите од левата колона со соодветните изрази од десната колона) Забележете го шаблонот: левиот израз е ист со десниот со додаден унарен оператор! како и релациони и логички оператори сменети во спротивни ( = = наместо! = и наместо &&) Логички оператори можат да оперираат на резултати од споредувања Исто така, може да оперираат на променливи од типот bool На пример, наместо евалуирање на сложениот израз: iselector = (age >= 18 && district == 23, може да се користат два меѓурезултата со вклучување на две дополнителни Boolean променливи, isvoter и isconstituent: isvoter = (age >= 18) ; isconstituent = (district == 23); iselector = isvoter && isconstituent Двете табели подолу ги прикажуваат резултатите од применување на операторите: && и врз логички изрази (претставени овде со Boolean променливи x и y) 45

47 Евалуација по скратена постапка Табела 51 Го разгледуваме логичкиот израз: i == 1 && j > 2 Некои програмски јазици користат полна евалуација на логичките изрази Со полната евалуација компјутерот прво ги евалуира двата подизраза (i == 1 и j > 2) пред да оперира со && операторот и да добие краен резултат За разлика од полната, C++ користи скратена (или условна) евалуација на логичките изрази Евалуацијата се врши од лево кон десно и компјутерот престанува да го евалуира изразот штом ја дознае вистинската вредност на целиот израз На пример, AND (&&) операторот запира со евалуација ако првиот израз што го евалуира е false (табела 51) Во последниот пример, ако i = 9 со евалуација на подизразот i = = 1, како false, целиот израз е false При евалуација на израз со OR ( ) оператор, ако вредноста на подизразот е true, јасно е дека целиот израз е true (табела 51) На пример: c <= d e==f Ako c <= d јасно е дека целиот претходен израз е true Приоритет на оператори Во следната листа е прикажан редоследот на приоритети на аритметички релациони и логички оператори 46

48 Како што може да се забележи во листата, унарните оператори имаат највисоко ниво на приоритет и тие оперираат први во изразот Најнизок приоритет има операторот доделување и тој оперира последен Операторите на исто ниво на приоритет се претставени во иста линија и приоритетот кај нив е од лево кон десно Релациони оператори со Floating-Point типови Досега зборувавме само за споредување на int, char и string вредности Тука разгледуваме float променливи Не споредувајте еднаквост на floating-point броеви Поради тоа што мали грешки најверојатно можат да се појават во најмалите (најдесните) децимални места при аритметичко оперирање со децимални броеви, ретко се случува два децимални броја да бидат еднакви На пример, го разгледуваме следниот сегмент кој користи две float променливи именувани оnethird и x: onethird = 10 / 30; x = onethird + onethird + onethird; Во овој момент очекуваме x = 1, односно евалуацијата на x = = 1 да е true Но поради лимитирана машинска прецизност, многу е веројатно дека вредноста на x не е 1, туку некој број како Затоа, тврдењето x = = 1 е false Кога се оперира со = = на децимални броеви, исправно е наместо тврдењето r = = s да се евалуира тврдењето fabs(r - s) <= tol, каде што r и s се кои било floating-point броеви, а tol е толеранција која зависи од природата на проблемот и обично е многу мал floating-point број (на пример, tol = 00001) If Инструкција If инструкцијата е основна контролна структура што овозможува разгранување на текот на контролата Со неа можеме да поставиме прашање и избереме пат на акцијата: ако (if) одреден услов постои тогаш (then) изврши една акција инаку (else) изврши друга акција Во време на извршување на оваа инструкција, компјутерот извршува само една од две акции If-Then-Else форма 47

49 Во C++, If инструкцијата може да се јави во две форми: If-Then-Else форма и If- Then форма Let's look first at the If-Then-Else Here is its syntax template: If инструкција (If-Then-Else форма) if ( Израз ) Statement1A else Statement1B Вредноста на израз е од тип bool Во време на извршувањето (run time), компјутерот го евалуира изразот Ако вредноста е true, компјутерот ја извршува инструкцијата StatementlA Ако вредноста е false, се извршува StatementlB StatementlA често се нарекува then-клаузула; StatementlB, else-клаузула Сликата 5-3 го илустрира текот на контролата на If-Then-Else На сликата, Statement2 е следната инструкција која што следува по целата If инструкција сл 53 If-Then-Else формата не го користи зборот then Значи, then клаузулата (Statement1A) доаѓа веднаш по условот Следниот програмски сегмент прикажува како се пишува If инструкцијата во програмата if (hours <= 400) pay = rate * hours; else pay = rate * (400 + (hours - 400) * 15); cout «pay; 48

50 Од аспект на инструкциите на компјутерот, горниот код вели: Ако часовите се помалку или еднакви на 40, пресметај регуларна плата и печати плата, но ако часовите се повеќе од 40, пресметај регуларна плус прекувремена плата и печати плата Инструкцијата за излез (печатење на монитор) е инструкција која не припаѓа на контролната структура Сликата 5-4 го покажува текот на контролата на оваа If инструкција Сл 54 Следниот програмски сегмент е превенција од делење со 0 if (divisor!= 0) result = dividend / divisor; else cout «"Division by zero is not allowed" «endl; Блокови (композитни инструкции) Во последниот пример, да претпоставиме дека кога именителот е 0 сакаме да направиме две работи: да испечатиме порака за грешка и да доделиме на променливата result вредност 9999 Ни требаат две инструкции во иста гранка, но изгледа дека синтаксата нè лимитира само на една инструкција Ние сакаме низа од инструкции во else-клаузулата За да го постигнеме тоа, низата од инструкции ја затвораме во големи загради и формираме блок (композитна инструкција) 49

51 инструкција 1 инструкција 2 кого компајлерот го третира како една инструкција За нашиот пример: if (divisor!= 0) result = dividend / divisor; еlse cout «"Division by zero is not allowed" «endl; result = 9999; If-Then Форма Некогаш се среќаваме со проблеми во кои ако одреден услов е исполнет треба да извршиме некоја акција, а ако не не треба да извршиме ништо Со други зборови, сакаме компјутерот да ја прескокне низата од инструкции ако одреден услов не е задоволен Ова може да се направи ако ја оставиме else гранката празна: if (a <= b) c = 20; else ; Подобар начин е да го испуштиме else делот Во овој случај ја добиваме If-Then формата на If инструкцијата Синтаксата изгледа вака: If инструкција (If-Then форма) if (Израз) Инструкција 50

52 Сл 55 Следното е пример за If-Then > if (age < 18) cout «"Not an eligible "; cout «"voter" «endl Како што имавме случај со двете гранки на If-Then-Else, и гранката во If-Then може да биде блок На пример, пишуваме програма за пресметување на данок на личен доход Една од линиите на формуларот кажува Извади го износот на линија 23 од износот на линија 17 и внеси го резултатот на линија 24 Ако резултатот е негативен внеси 0 и означи го полето 24А Овде можеме да ја користиме If-Then формата: result = line17 - Iine23; if (result < 00) cout «"Check box 24A" «endl; result = 00; Iine24 = result; Што ќе се случи ако ги испуштиме левата и десна заграда во горниот код? result = line17- Iine23; // Incorrect version if (result < 00) cout «"Check box 24A" «endl; result = 00; Iine24 = result; И покрај индентацијата (вовлекување на инструкциите во then клаузулата,) компајлерот ја зема оваа клаузула како клаузула со една инструкција, бидејќи не е затворена во блокови Ако резултатот е негативен (помал од 0), програмата работи добро Но ако почетниот резултат е позитивен, компјутерот ја скока then клаузулата и продолжува на инструкцијата по If инструкцијата Тоа е инструкцијата за доделување 51

53 која го сетира резултатот на 0 Така резултатот постојано добива вредност 0, без разлика што е неговата пресметана вредност Вгнездени If инструкции Не постојат ограничувања кои инструкции можат да бидат во If структурата, If во If е валидно If во If во If, исто така Кога ставаме If во If, ние креираме вгнездена контролна структура (nested control structure) Главно, секој проблем кој вклучува повеќенасочна гранка multiway branch (повеќе од два алтернативни патишта) може да биде кодиран користејќи вгнездени If инструкции На пример, за да испечатиме име на месец ако е даден неговиот реден број ние треба да користиме низа од невгнездени If инструкции: if (month == 1) cout «"January"; if (month == 2) cout «"February"; if (month == 3) cout «"March"; if (month == 12) cout «"December"; Со ова решение, контролата мора да помине низ целата низа од If инструкции, а исто така повеќе од една алтернатива (повеќе од еден услов) можат да бидат задоволени Со користење на вгнезден If имаме: if (month == 1) cout «"January"; elseif (month ==2) cout «"February"; elseif (month ==3) cout «"March"; elseif (month ==4) // Nested If // Nested If // Nested If Со оваа варијанта, If структурата се прекинува кога условот е задоволен, а со тоа се прифаќа само една алтернатива Припадност на else клаузулата во вгнезденa If структура 52

54 Кога имаме вгнезден If се поставува прашањето на кое If припаѓа else клаузулата На пример, во следниот код: if (average < 700) if (average < 600) cout «"Failing"; else cout «"Passing but marginal"; If се појавува двапати, а else само еднаш Правило е дека кога нема присуство на блок инструкција, else припаѓа на првото претходно if кое не е спарено со else Ако во последниот програмски сегмент сакаме else да се однесува на надворешното if, тогаш надворешната if-then клаузула треба да се претвори во блок: if (average >= 600) // Correct version if (average < 700) cout «"Passing but marginal"; else cout «"Failing"; Овој програмски сегмент семантички е идентичен со претходниот 53

55 VI/ Циклус (Looping) Во претходната глава наведовме дека текот на контрола во програмот може да се разликува од физичкиот редослед на инструкциите Физичкиот редослед е редослед во кој инструкциите се јавуваат во програмот Редоследот во кој ние сакаме инструкциите да се извршуваат се нарекува логички редослед If инструкцијата е еден начин кој го прави логичкиот редослед различен од физичкиот редослед Контролната структура циклус е друг начин Циклусот извршува една или повеќе инструкции повеќе пати, се додека еден или група услови не се исполнети Циклус (Loop) е контролна структура која предизвикува една или група од инструкции да се извршуваат повторливо While инструкција While инструкцијата како и If инструкцијата, тестира услов while ( Expression ) Statement while (inputval!= 25) cin» inputval; While инструкцијата е контролна структура циклус (looping) Инструкцијата што треба да се изврши секој пат при поминувањето на циклусот се вика тело на циклусот Во горниот пример, тело на циклусот е влезната инструкција која чита вредност за inputval While инструкцијата наложува да се извршува читањето на inputval повторно и повторно се додека влезната вредност не е еднаква на 25 Како и во условот на If инструкцијата, условот во While инструкцијата може да биде израз од било кој тип на податок Скоро секогаш условот е логички (Boolean) израз Ако не е, неговата вредност имплицитно се конвертира во тип bool 54

56 (вредност 0 false и ненулта вредност true) While инструкцијата кажува "Ако вредноста на изразот е true, изврши го телото на циклусот и оди назад да го провериш условот повторно Ако вредноста на изразот е false скокни го телото и изврши ја првата инструкција после циклусот" Значи циклусот се извршува повторливо, се додека изразот кој се тестира е true Секако, ако изразот е false уште на влезот во циклусот, телото нема да се изврши ниту еднаш Сликата 61 го покажува текот на контролата на While инструкцијата, каде Statementl е тело на циклусот и Statement2 е инструкција која следи после циклусот сл 61 Телото на циклусот може да биде композитна инструкција (блок), што ни дозволува да извршуваме било која група на инструкции повторливо Најчесто ние користиме while циклуси во следна форма: while (Expression) : If се користи да избере акција меѓу повеќе опции, додека while се користи да повторува одредена акција Секој премин на контролата, низ телото на циклусот се вика итерација На следната сл62 е прикажана разликата во текот на контролата за If-Then и за While структурата 55

57 Циклуси кои користат While инструкција Во решавањето на проблеми, можеме да се сретнеме со два главни типови на циклуси: циклуси контролирани од бројач, кои го извршуваат телото конкретен број на пати, и циклуси контролирани од настан кои го повторуваат телото додека нешто не се случи во циклусот Циклуси контролирани од бројач Овие циклуси користат променлива која го контролира циклусот во тестот на циклусот Пред да влеземе во циклус контролиран од бројач, ние мора да ја иницијализираме контролната променлива на бројачот и да ја тестираме Потоа како дел на секоја итерација на циклусот, мора да ја инкрементираме (зголемиме за 1) контролната променлива на циклусот На пример: loopcount =1; // Inicijalizacija while (loopcount <= 10) // Test // Akcii koi se povtoruvaat loopcount = loopcount + 1; // Incrementacija Овде loopcount е контролна променлива на циклусот Таа се иницијализира (поставува) на 1 пред влезот во циклусот While инструкцијата тестира израз loopcount <= 10 и го извршува телото на циклусот се деодека изразот е true Точките во телото на циклусот означуваат низа од инструкции кои се треба да се повторуваат Последната инструкција во телото на циклусот е инкрементација која ја зголемува loopcount со додавање 1 на нејзината претходна вредност Обично за инкрементација на променливата за 1, место последната инструкција во блокот се користи познатиот оператор за инкремаентација ++, така да loopcount = loopcount + 1; обично се пишува како loopcount++; Последните две инструкции се еквивалентни и имаат исти ефект го зголемуваат loopcount за 1 56

58 При дизајнирање на циклуси, програмерот треба да провери дали условот што треба да се тестира е поставен коректно, пред While инструкцијата да почне Програмерот исто така треба да тестира дека условот се менува внатре во циклусот така да на крај постане false, инаку лциклусот никогаш нема да заврши loopcount = 1; < Променливата loopcount мора да биде иницијализирана while (loopcount <= 10) loopcount++; < loopcount мора да биде инкрементирана Циклус кој никогаш не завршува се вика бесконечен (infinite) loop бидејќи теоретски циклусот ќе трае вечно Во горниот код, ако се испушти последната инструкција ќе се добие бесконечен циклус затоа што loopcount е секогаш еден и While изразот е секогаш true Телото на горниот циклус ќе се изврши 10 пати Ако сакаме телото да се изврши 11 пати, треба или да го иницијализираме бројачот на 0, или во While изразот 10 да го замениме со 11 Циклуси контролирани од настан Постојат неколку вида на циклуси контролирани од настан: sentinelконтролирани, end-of-file-контролирани и flag-контролирани циклуси Во сите од овие циклуси, условот за прекин зависи од некој настан кој се случува додека телото на циклусот се извршува Sentinel-контролирани циклуси Циклусите често се користат да читаат и процесираат долги листи од податоци Секој пат кога телото на циклусот се извршува, нов податок се чита и процесира Често некоја специјална податочна вредност, наречена sentinel или trailer вредност, се користи за да му сигнализира на програмот дека нема повеќе податоци за процесирање Циклусот се извршува се додека вредноста на податокот што се чита не е sentinel Циклусот завршува кога програмот препознае sentinel Со други зборови, читањето на sentinel вредност е настан кој го контролира извршувањето на циклусот Sentinel вредност мора да биде нешто што никогаш не се појавува во нормалниот влез На пример, ако програмот чита календарски датуми, February 31 може да се користи како sentinel вредност: cin» month» day; // Procitaj podatok Primarno citanje while (! (month == 2 && day ==31) ) 57

59 : // Procesiraj cin» month» day; // Procitaj sleden podatok Овој програмски сегмент работи коректно Првата група податоци е вчитана и ако не е sentinel, се процесира На крајот на циклусот, следната група на податоци се вчитува и одиме назад на следен тест Ако новата група на податоци не е sentinel, се процесира исто како и првата Кога sentinel вредност е прочитана, While изразот станува false и циклусот завршува (без да ја процесира sentinel вредноста) Многу пати самиот проблем ја диктира sentinel вредноста На пример, ако проблемот не дозволува вредноста на податокот да биде 0, тогаш sentinel вредноста треба да биде 0 Некогаш комбинација на вредности е невалидна Комбинацијата February и 31 како датум е таков случај Некогаш рангот на вредности (на пример негативни броеви) е sentinel Кога се процесираат карактери, newline карактерот ( ' \n ' ) често служи како sentinel Следниот пример е програмски сегмент кој ги чита и ги печати сите карактери во влезната линија (inchar е од тип char): cinget (inchar) ; // Procitaj go prviot karakter while (inchar!= '\n') cout «inchar; // Echo print cinget (inchar) ; // Procitaj go sledniot karakter Кога бираме вредност што ќе ја користиме како sentinel, што се случува ако не постојат невалидни податочни вредности? Тогаш можеме да внесуваме дополнителни вредности во секоја итерација чија цел е да сигнализираат крај на податоците На пример во следниот програмски сегмент: cin» datavalue» sentinel; // Vcitaj ja prvata vrednost while (sentinel == 1) : // Procesiraj cin» datavalue» sentinel; // Vcitaj ja slednata vrednost Втората вредност во секоја линија служи како sentinel и се користи да сигнализира дали има уште податоци што треба да се вчитуваат Во оваа група на податоци кога sentinel вредноста е 0, нема повеќе податоци, а кога е 1 има уште податоци кои чекаат да бидат прочитани Податоци Sentinel вредности 58

60 Во глава 5 зборувавме за честа грешка од користење на оператор на доделување (=) наместо релационен оператор (==) во If услов Истата оваа грешка може да се случи при пишување на While инструкција Да видиме што ќе се случи со претходниот пример ако користиме погрешен оператор: cin» datavalue» sentinel; while (sentinel =1) : cin» datavalue» sentinel; // Whoops Оваа грешка креира бескраен циклус While изразот сега е израз на доделување, а не релационен израз Вредноста на изразот е 1 (во тестот на циклусот интерпретиран како true затоа што е ненулти), и неговиот страничен ефект е да стави 1 во sentinel, заменувајќи ја вредноста на која беше сетирана променливата Бидејќи While изразот е секогаш true, цилусот никогаш не завршува End-of-File-контролирани циклуси Видовме дека влезниот тек (cin или текот на влезна датотека) паѓа (оди во fail состојба) ако: (a) наиде на неприфатлив влезен податок, (b) програмот се обиде да отвори непостоечка влезна датотека, (c) програмот се обиде да чита преку маркерот end-of-file Овде го разгледуваме третиот од горните услови Откако програмот го прочитал последниот податок од влезната датотека, компјутерот е кај крајот на датотеката (EOF) Во овој момент состојбата на текот е во ред Но ако се обидеме да читаме следен податок, текот паѓа (оди во fail state) За да напишеме циклус кој внесува непознат број на податоци, можеме да го користиме паѓањето на влезниот тек како форма на sentinel 59

61 Во глава 5 беше опишано како да се тестира состојбата на I/O тек Во логички израз го користиме името на текот како Boolean променлива: if (infile) Во тест како овој резултатот е true ако последната извршена влезна операција успеала, а false ако паднала Во While инструкција, тестирање на состојба на текот работи на истиот начин Да претпоставиме дека имаме датотека која содржи integer вредности Ако во нашиот програм indata е името на датотечниот тек, следното е циклус кој чита и ехо ги печати сите вредности во датотеката: indata» intval; while (indata) cout «intval «endl; indata» intval; // Читај ја првата вредност // Додека влезот е успешен // Ехо-печати ја влезната вредност // Читај ја следната вредност Кога пишуваме EOF-контролирани циклуси како горниот, очекуваме дека крајот на датотеката е причина за пад на текот Но треба да имаме на ум дека било која влезна грешка предизвикува пад на текот Горниот циклус може да се прекине на пример ако влезот падне поради невалидни карактери во влезните податоци Овој факт ја потенцира важноста на ехо излезот Тој ни помага да верифицираме дека сите податоци се вчитани коректно EOF-контролираните циклуси се слични на sentinelконтролираните циклуси во тоа што програмот не знае однапред колку податоци треба да бидат прочитани Во случај на sentinel-контролирани циклуси, програмот чита додека не наиде на sentinel вредност Со EOF-контролирани циклуси програмот чита додека не наиде на крајот на датотеката Се поставува прашање дали може да се користи EOF-контролиран циклус кога читаме од стандарден влезен уред преку cin тек наместо од датотека Различни системи користат различни карактери да симулираат EOF Во UNIX оперативниот систем, овој карактер е Ctrl-D Во MS-DOS оперативниот систем, аналог на end-of-file е Ctrl-Z Други системи користат слични контролни карактери Следното е програмски сегмент кој тестира EOF на cin тек во UNIX: cout «"Vnesi integer (ili Ctrl-D za kraj): "; cin» somelnt; while (cin) 60

62 cout «somelnt «" dupliciran e " «2 * somelnt «endl; cout «"Sleden broj (ili Ctrl-D za kraj): "; cin» somelnt; Flag-контролирани циклуси Flag ( знаме) е Boolean променлива која се користи да го контролира логичкиот тек на програмот Ние можеме да ја иницијализираме Boolean променливата на true пред While циклусот, а потоа, кога сакаме да го прекинеме циклусот, ја ресетираме на false На пример следниот код чита и сумира вредности додека влезната вредност е позитивна: sum = 0; nonnegative = true; // Inicijaliziraj zname while (nonnegative) cin» number; if (number < 0) // Testiraj vlezna vrednost nonnegative = false; // Smeni ja vrednosta na znameto ako nastanot se pojavil else sum = sum + number; Горниот код може да се напише и на алтернативен начин, кога знамето се иницијализира на false а во тестот се користи операторот за негација! На пример: sum = 0; negative = false; // Inicijaliziraj zname while (!negative ) cin» number; if (number < 0) // Testiraj vlezna vrednost negative = true; // Setiraj zname ako se pojavil nastan else sum = sum + number; Телото на циклусот мора да изврши одредена задача за да циклусот биде корисен Следните три примери ја покашуваат примената на циклусите во броење, сумирање и паметење на претходна вредност Ова се задачи кои често се користат во циклуси 61

63 Следниот програмски сегмент ги брои карактерите во влезниот тек до појавата на карактерот count = 0; // Inicijaliziraj brojac cinget(inchar); // Citaj go prviot karakter while (inchar!= ' ') count++; // Zgolemi go brojacot cinget(inchar); // Citaj go sledniot karakter Овој програмски сегмент е sentinel-контролиран каде како sentinel се користи карактерот Променливата count во овој пример се нарекува итерациски бројач бидејќи нејзината вредност е еднаква на бројот на итерации Итерациски бројач е променлива која се зголемува за 1 со секоја итерација Друга честа задача која се решава со циклуси е сумирање Следниот пример ги чита и собира првите 10 броеви од влезниот тек sum =0; // Inicijaliziraj ja sumata count =1; while (count <= 10) cin» number; // Vnesi vrednost sum = sum + number; // Dodaj ja vrednosta na sumata count++; Приметете дека ова е циклус контролиран од бројач бидејќи во програмот е јасно наведено дека треба да се превземаат и сумираат точно првите 10 броеви од влезниот тек Да погледнеме уште еден пример Сакаме да ги броиме и собираме првите 10 непарни броеви Треба да го тестираме секој број за да видиме дали е парен или непарен За ова користиме modulus оператор Ако number % 2 е 1, number е непарен; инаку е парен Ако влезната вредност е парен број, не превземаме акција, инаку додаваме 1 на бројачот и ја додаваме вредноста во сумата Овде користиме flag за контрола на циклусот, заради тоа што бројачот не соодветствува на бројот на премини низ телото на циклусот Во програмскиот сегмент сите променливи се од тип int освен знамето (flag) lessthanten кој е од тип bool count =0; // Inicijaliziraj go brojacot na nastan sum =0; // Inicijaliziraj ja sumata 62

64 lessthanten = true; while (lessthanten) cin» number; if (number % 2 == 1) count++; sum = sum + number; lessthanten = (count <10) ; // Inicijaliziraj go znameto // Procitaj ja slednata vrednost // Dali e brojot neparen // Da Zgolemi go brojacot // Dodaj ja vrednosta na suma // Azuriraj go lessthanten Бројачот во овој пример е бројач на настани Значи Бројач на настани е променлива која се инкрементира секој пат кога се појави одреден настан Некогаш сакаме да ја памтиме претходната вредност на променливата Да претпоставиме дека сакаме нашиот програм да одреди колку пати е користен нееднакво операторот (! =) во датотека која содржи C++ програм Ние можеме да го направиме тоа со броење колку пати извичник (!) проследен со знак еднакво (=) се појавува во датотеката Еден начин да го направиме ова е да ја читаме влезната датотека карактер по карактер, следејќи ги актуелниот и претходниот карактер 63

65 Горниот програм дефинира две променливи од тип char, една од тип int и една од тип ifstream Прво, со методот open програмот на влезниот тек infile ја доделува постоечката датотека myfiledat Ако отварањето не успее, програмот се прекинува со издавање на порака Ако отварањето успее, се иницијализира бројачот и се врши иницијално читање на првите два карактера Циклусот е end-of-file контролиран Бараниот настан се случува кога ќе се појави комбинација од карактери! и = Тогаш бројачот се зголемува за 1 Последните две инструкции во циклусот се: - доделување на актуелниот карактер (currchar) на претходниот карактер (prevchar) и - читање на следен карактер Кога ќе биде достигнат EOF маркерот, циклусот излегува и се печати бројот на појавувања на операторот содржан во променливата count 64

66 VII Функции Функционална декомпозиција и void функции Да се потсетиме дека C++ јазикот работи со два вида на потпрограми (функции): - функции кои враќаат вредност (value returning) функции и - функции кои извршуваат некоја задача и не враќаат вредност - void функции Програмата кој ја повикува функцијата (повикувач) го користи името на value returning функцијата и листата на аргументи во израз На пример: y = 38 * sqrt(x); Спротивно, void функцијата не враќа вредност на својот повикувач Ниту таа се повикува од израз, туку повикот се јавува како комплетна инструкција во повикувачот Пишување на модули како void функции Разгледуваме програма која користи наједноставна void функција Сакаме да напишеме програма која ќе ја прикажува следнава порака на мониторот: ************************ ************************ Ova e proba na void funkcija! ************************ ************************ ************************ ************************ Алгоритамот изгледа како што следи: Main степен 0 Впиши две линии на ѕвездички Впиши Ova e proba na void funkcija! Впиши четири линии на ѕвездички Print 2 lines степен 1 Впиши ************************ Впиши ************************ Print 4 lines Впиши ************************ Впиши ************************ Впиши ************************ Впиши ************************ Ако ги напишеме двата модула кои се на прв степен од модуларната програма како void функции, тогаш нашата програма е како што следува: 65

67 //************************************************************************ // Test programа // Ovаа programа koristi dve void funkcii i pecati Ova e proba na void funkcija! //************************************************************************ #include <iostream> using namespace std; void Print2Lines(); void Print4Lines(); // Prototipovi (deklaracii) na funkcii int main() Print2Lines(); // Povik na funkcija cout << Ova e proba na void funkcija! << endl; Print4Lines(); // Povik na funkcija return 0; //************************************************************************ void Print2Lines() // Function heading // Ovaa funkcija pecati dve linii od zvezdicki cout << ************************ << endl; cout << ************************ << endl; //************************************************************************ void Print4Lines() // Function heading // Ovaa funkcija pecati dve linii od zvezdicki cout << ************************ << endl; cout << ************************ << endl; cout << ************************ << endl; cout << ************************ << endl; Во тест програмата, двете инструкции пред main функцијата се нарекуваат функциски прототипови Овие инструкции се неопходни, бидејќи правилото во C++ е прво да се декларираат идентификаторите пред да се користат Значи, ние мора да го информираме компајлерот однапред дека Print2Lines и Print4Lines се имиња на функции кои не враќаат вредност и немаат аргументи Оваа програма може да се 66

68 напише и со само една функција, која како аргумент ќе го користи бројот на линии кои треба да се печатат Еве ја таа верзија: //************************************************************************ // Test_1 programа // Ovаа programа koristi една void funkcија i pecati Ova e proba na void funkcija! //************************************************************************ #include <iostream> using namespace std; void PrintLines(int); // Prototip na funkcija int main() PrintLines(2); // Povik na funkcija cout << Ova e proba na void funkcija! << endl; PrintLines(4); // Povik na funkcija return 0; //************************************************************************ void PrintLines(int numlines) // Function heading // Ovaa funkcija pecati linii od zvezdicki, pri sto // numlines specificira kolku linii da se pecatat int brojac; // Promenliva za loop brojac = 1; while (brojac <= numlines) cout << ************************ << endl; brojac++; Во функцискиот heading на PrintLines е вклучена параметарска декларација Како што беше наведено претходно, две функции комуницираат меѓусебе преку аргументи Параметар е променлива декларирана во функцискиот heading Исто така, се нарекува формален аргумент или формален параметар 67

69 Аргумент е променлива или израз кој се користи во повикот на функција Исто така, се нарекува актуелен аргумент или актуелен параметар Во Test_1 програмата аргументот во првиот повик на функцијата PrintLines е литералната вредност 2, а во вториот повик литералната вредност 4 Параметарот во PrintLines функцијата е променливата numlines Кога контролата на програмата преминува на функцијата PrintLines, параметарот numlines се иницијализира на вредност 2 Во PrintLines циклусот контролиран од бројач се извршува двапати и контролата се враќа на main При вториот повик, аргументот е 4 и циклусот во PrintLines се извршува четири пати по што контролата се враќа во main функцијата Од ова доаѓаме до заклучок дека предноста од користење на функции е во тоа што тие можат да се извршуваат од различни места на main Ова заштедува напор и време во кодирањето Да ја разгледаме функцијата main Веднаш е очигледна функционалната декомпозиција и во двете верзии Дури и на некој кој не знае која е дефиницијата на PrintLines, разгледувајќи ја само main ќе му биде јасно дека програмата печати 2 линии па печати порака и печати 4 линии Синтакса и семантика на void функциите Моделот (template) за повикување на void функција е следниов: Име на функција (Листа на аргументи); Листата на аргументи може да биде празна ( ) или да има еден или повеќе аргументи Повикот на void функција е инструкција која ја префрла контролата на void функцијата Во C++ оваа инструкција е името на функцијата, следено од листа на аргументи Ако има два или повеќе аргументи во листата, тие треба да бидат разделени со запирки Кога се извршува повикот на функцијата, аргументите се доделуваат на параметрите во согласност со нивната позиција и контролата се префрла на првата извршна инструкција во телото на функцијата Кога последната инструкција во функцијата е извршена, контролата се враќа на местото од каде функцијата беше повикана Декларации и дефиниции на функции Декларацијата на функцијата му го соопштува на компајлерот: името на функцијата, типот на податокот на вредноста која функцијата ја враќа (или void или тип на податок како int или float) и типовите на податоците на параметрите кои функцијата ги користи 68

70 Во Test_1 програмата се прикажани вкупно три декларации на функции Првата декларација, коментирана како прототип на функција, не го вклучува телото на функцијата Останатите две декларации за main и PrintLines функциите, вклучуваат тела на функциите Функциската декларација во која не е вклучено телото на функцијата се нарекува функциски прототип, а декларациите кои вклучуваат и тело на функција се нарекува функциска дефиниција Функциски прототип (за void функција) Шаблонот (template) за прототип на void функција е следниов: void Име на функција (листа на параметри); Сè што е bold во шаблонот е обврзувачко да се наведе во прототипот, а сè што е во Italic е опционо (необврзувачко) Значи листата на параметри може да биде празна, но заградите се обврзувачки Како што може да се види од шаблонот, во прототипот нема вклучено тело (body) на функцијата и декларацијата завршува со точка-запирка карактер Ако во листата има аргументи, шаблонот за листата на аргументи е: тип на податок & име на променлива, тип на податок& име на променлива Амперсанд карактерот (&) прикачен на типот на податок, означува дека променливата во функцијата е проследена со референца што значи како вредноста на променливата се менува во функцијата, така се менува и нејзината вредност во повикувачот За ова ќе зборуваме подоцна Во прототипот на функцијата, листата на параметри мора да ги специфицира типовите на податоците на параметрите, а нивните имиња се опциони На пример: Void DoSomething (int, float); или Void DoSomething (int dolzina, float agol); И двата прототипа се исправни C++ инструкции Во втората варијанта компајлерот ги игнорира имињата на променливите Функциска дефиниција (за void функција) Шаблонот (template) за дефиниција на void функција е следниов: Void име на функција (листа на параметри) instrukcija 69

71 Од шаблонот се гледа дека функцискиот heading не завршува со карактерот; како што тоа е случај со функцискиот прототип Исто така, листата на параметри мора да ги вклучи имињата на параметрите покрај нивните типови Параметрите во листата може да бидат напишани во една линија или секој параметар во посебна линија Следното е template за листа на параметри во функциската дефинција: тип на податок & име на променлива, тип на податок & име на променлива, Локални променливи Локална променлива е променлива декларирана во блок на која не може да & се пристапи од место надвор од блокот Затоа што телото на која било функција е блок, која било функција може да вклучи декларација на променлива во своето тело Овие променливи се локални променливи, бидејќи на нив може да им се пристапи само внатре во блокот На пример, ако пробаме да печатиме вредност на локална променлива од друга функција, компајлерот ќе пријави грешка За разлика од локалните променливи, променливите декларирани надвор од која било функција се нарекуваат глобални променливи Локалните променливи заземаат простор во меморијата само додека функцијата се извршува Во моментот кога се повикува функцијата, се креира мемориски простор за нејзините локални променливи Кога функцијата завршува и контролата се враќа назад на повикувачот локалните променливи се уништуваат Значи при секој повик на функцијата, нејзините локални променливи стартуваат со недефинирани вредности За да се заштитиме од несакани резултати, мора да ги иницијализираме локалните променливи внатре во самата функција Следниот програмски сегмент илустрира функциска декларација и декларација на локални променливи: #include <iostream> using namespace std; void TryThis( int, int, float); // Funkciski prototip int main( ) int int1; int int2; // Funkciska definicija // Lokalni promenlivi za main 70

72 float somefloat; TruThis (int1, int2, somefloat); // Povik na funkcija so tri argumenti void TryThis ( int param1, int param2, float param3) int i; float x; // Funkciska definicija so tri parametri // Lokalni promenlivi za TryThis Return инструкција Функциите кои враќаат вредност на повикувачот, враќањето на вредност го вршат преку return инструкцијата Така main враќа вредност 0 или некоја друга вредност на оперативниот систем Void функциите не враќаат вредност Контролата се враќа од функцијата на повикувачот по извршување на последната инструкција во телото на функцијата Алтернативно, постои втора форма на return инструкцијата и таа изгледа вака: return; Оваа инструкција е валидна само за void функциите Може да се појави каде било во телото на функцијата и предизвикува контролата веднаш да ја напушти функцијата и да се врати на нејзиниот повикувач На пример: Void SomeFunc ( int n ) if (n > 50) cout << Vrednosta e nadvor od rangot ; return; n = 412 * n; 71

73 cout << n; Во овој пример има два начина контролата да ја напушти функцијата Прво, вредноста на n се тестира и ако n > 50, функцијата печати порака и веднаш ја напушта функцијата Ако n е помало или еднакво на 50, then клаузулата на if инструкцијата се прескокнува, се извршува инструкцијата на доделување и последната инструкција, излез на монитор, по што контролата ја напушта функцијата и се враќа на нејзиниот повикувач (caller) Друг начин на кодирање на оваа функција е If Then Else структурата: Void SomeFunc ( int n ) if (n > 50) cout << Vrednosta e nadvor od rangot ; else n = 412 * n; cout << n; Оваа верзија е single-entry, single-exit пристап, што значи контролата влегува во функцијата само во една точка (првата извршна инструкција) и излегува само од една точка (крајот на телото на функцијата) Параметри C++ поддржува два вида на параметри: вредносни параметри и референтни параметри Со вредносен параметар, кој се декларира без амперсанд (&) на крајот од името на типот на податок, функцијата прима копија од вредноста на аргументот Со референтен параметар, кој се декларира со додавање на амперсанд на името на типот на податок, функцијата прима локација (мемориска адреса) на аргументот од повикувачот На пример: Void Primer(int& param1, // Referenten parametar int param2, // Vrednosen parametar float param3) // Vrednosen parametar 72

74 Кога се користат едноставни типови на податоци како: int, char, float итн, вредносен параметар е default (претпоставен) вид на параметар Вредносни параметри Во Тest_1 програмата, функцискиот heading на PrintLines функцијата е void PrintLines( int numlines ) Параметарот numlines е вредносен параметар, затоа што името на неговиот тип на податок (int) не завршува со & Ако функцијата се повикува со користење на аргумент linecount, PrintLines(lineCount); тогаш параметарот numlines prima kopija od vrednosta na linecount Во овој момент има две копии на податокот, една во аргументот linecount и една во параметарот numlines Ако инструкција внатре во функцијата PrintLines ја смени вредноста на параметарот numlines, оваа промена не се пренесува на аргументот linecount (постојат две копии на податокот) Значи, со користење на вредносни параметри се исклучува можноста од ненамерна промена на аргументот Како вредносни аргументи можат да се појават константи, променливи, па дури и комплицирани изрази За PrintLines функцијата сите следни повици се валидни: PrintLines(3); PrintLines(lineCount); PrintLines(2*abs(10-someInt)); Мора да има ист број на аргументи во повикот на функцијата, колку што има параметри во функцискиот heading Исто така, секој аргумент треба да има ист тип на податок како параметарот на истата позиција Видовме дека вредносните параметри не ја менуваат вредноста на аргументот во повикувачот Исто како и локалните променливи, вредносните параметри се уништуваат кога функцијата ја враќа контролата Ако сакаме да ја зачуваме и вратиме новата вредност на аргументот добиена во функцијата, наместо вредносни ние треба да употребуваме референцни параметри Референцни параметри Референцен параметар е параметар кој се декларира со додавање на амперсанд & на името на типот на податок Во овој случај, функцијата може да ја смени вредноста на аргументот Во овој случај при повик на функцијата, таа прима мемориска адреса на аргументот, а не копија од неговата вредност Има само една копија од информацијата и таа се користи и од повикувачот и од повиканата функција Да погледнеме еден пример Алгоритамот (дизајнот) е: 73

75 main ниво 0 Добивање податок за температура Печатење на активноста Get temperature Промптирање на корисникот да ја внесе температурата ниво 1 Читање на температурата Echo print на температурата Print activity ниво 1 Печати Препорачана активност е if temperature > 30 print plivanje else if temperature > 15 print tenis else if temperature > 0 print golf else if temperature > -15 print skijanje else print sedenje doma Следното е програмски код на горенаведениот дизајн: //*********************************************************** // Activity program // Ovаа programа ja prikazuva soodvetnata aktivnost za dadena temperatura //*********************************************************** #include <iostream> using namespace std; void GetTemp( int& ); void PrintActivity ( int ); // funkciski prototipovi int main ( ) int temperature; GetTemp (temperature); // nadvoresna temperaturа // povik na funkcija 74

76 PrintActivity (temperature); return 0; // povik na funkcija //*********************************************************** void GetTemp ( int& temp ) // referencen parameter // Ovaa funkcija promptira (prasuva) za vnos na temperature, // cita vnos vo temperature i echo prints temperature cout << Vnesi nadvoresna temperature: << endl; cin >> temp; cout << Momentalnata temperature e << temp << endl; //*********************************************************** void PrintActivity ( int temp ) // vrednosen parametar // Za dadena vrednosta na temp, ovaa funkcija pecati poraka // koja indicira soodvetna aktivnost cout << Preporacana aktivnost e ; if (temp > 30) cout << plivanje << endl; else if (temp > 15) cout << tenis << endl; else if (temp > 0) cout << golf << endl; else if (temp > -15) cout << skijanje << endl; else cout << sedenje doma << endl; Во оваа програма аргументите во двата функциски повика имаат име temperature Параметарот во GetTemp е референцен параметар со име temp, а параметарот во PrintActivity е вредносен параметар, исто така, со име temp 75

77 Главната функција, main, & кажува на GetTemp каде да ја стави температурата со давање (пренесување) на мемориската локација на променливата temperature при повикот на функцијата Овде мора да користиме референцен параметар, за да функцијата GetTemp знае каде во меморијата да ја постави вредноста на температурата Во PrintActivity имаме вредносен параметар Кога PrintActivity се повикува, main праќа копија од вредноста на променливата temperature со која PrintActivity работи Во овој случај е оправдано да се користи вредносен параметар, затоа што логиката на PrintActivity е само да ја користи како влез, а не ja менува вредноста на temperature VIII Домен и животен век на функции Како програмата станува поголема и покомлицирана, се зголемува бројот на идентификаторите во програмата Некои од овие идентификатори ги декларираме во блоковите Други идентификатори, на пример имиња на функции, ги декларираме надвор од кој било блок Во оваа глава ги испитуваме правилата по кои функцијата може да пристапи на идентификатори кои се декларирани надвор од нејзиниот блок Домен на идентификаторите Како што видовме во претходната глава, локални променливи се оние кoи ce декларирани во блок, како на пример во тело на функција На локалните променливи не може да им се пристапи од локација надвор од блокот што ги содржи Истото правило на пристап се однесува и на именуваните константи На локалните константи може да им се пристапи само во блокот во кој се декларирани Кој било блок, не само телото на функција, може да содржи декларации на променливи и константи Во следниот пример, if инструкцијата содржи блок кој декларира локална променлива n if (alpha > 3) 76

78 int n; cin >> n; beta = beta + n; Како со која било локална променлива, на променливата n не може да & се пристапи од која било инструкција надвор од блокот кој ја содржи декларацијата на променливата Домен е регионот од програмскиот код каде е легално да се користи идентификаторот Доменот на идентификаторот може да биде локален и глобален Локалниот домен на идентификаторот деклариран во блок се протега од местото на декларација до крајот на тој блок Глобалниот домен на идентификаторот деклариран надвор од која било функција се протега од местото на декларација до крајот на целата датотека која го содржи програмскиот код C++ функцијата има глобален домен Штом името на функцијата е декларирано, функцијата може да биде повикана од која било друга функција во програмата Во C++ не постои локална функција те не смее да се вгнезди дефиниција на функција во друга функција Глобални променливи и константи се оние декларирани надвор од сите функции На пример: int gama; // Globalna promenliva int main ( ) gama = 3; void SomeFunc ( ) gama = 5; Во горниот програмски сегмент, на глобалната променлива gama може да & се пристапи директно со инструкции во main и SomeFunc Кога функцијата декларира локален идентификатор со исто име како и глобалниот идентификатор, локалниот идентификатор има предност во функцијата На пример: #include <iostream> 77

79 using namespace std; void SomeFunc( float ); const int a = 17; // Globalna konstanta int b; // Globalna promenliva int c; // Globalna promenliva int main ( ) b = 4; // Dodeluvanje vrednost na globalna b c = 6; // Dodeluvanje vrednost na globalna c SomeFunc(428); return 0; void SomeFunc( float c ) float b; b = 23; // Dodeluvanje vrednost na lokalna promenliva b cout << a = << a; // Pecati globalno a (17) cout << b = << b; // Pecati lokalno b (23) cout << c = << c; // Pecati lokalno c formalen parameter (428) Во овој пример, функцијата SomeFunc & пристапува на глобалната константа a, но декларира своја локална променлива b и параметар c Излезот ќе биде: a = 17 b = 23 c = 428 Локалната променлива b има предност во однос на глобалната променлива b и параметарот c има предност во однос на глобалната променлива c Освен локалниот и глобалниот пристап, C++ дефинира што се случува кога блоковите се вгнездени во други блокови Сè што е декларирано во блок кој содржи вгнезден блок е нелокално за внатрешниот блок Така глобалните идентификатори се нелокални за сите блокови во програмата Нелокален идентификатор во однос на даден блок е идентификатор деклариран надвор од тој блок Правила на домен Правилата на домен на идентификатори се: 1 Името на функција има глобален домен Функциските дефиниции не можат да бидат вгнездени во функциски дефиниции 78

80 2 Доменот на функциски параметар е идентичен со доменот на локална променлива декларирана во најнадворешниот блок на телото на функцијата 3 Доменот на глобална променлива или константа се протега од нејзината декларација до крајот на датотеката, освен ако не настане правилото 5 4 Доменот на локална променлива или константа се протега од нејзината декларација до крајот на блокот во кој е декларирана Овој домен вклучува вгнездени блокови, освен ако не настане правилото 5 5 Доменот на идентификаторот не вклучува вгнезден блок кој содржи локално деклариран идентификатор со исто име Локалните идентификатори со исто име имаат предност Во следниот пример се илустрирани правилата за домен на идентификатори: #include <iostream> using namespace std; void Block1( int, char& ); void Block2( ); int a1; char a2; // Globalna promenliva // Druga globalna promenliva int main( ) // ********************************************************************** void Block1( int a1, // Sprecuva pristap na globalnata a1 char& b2 ); // Ima ist domen kako c1 i d2 int c1; // Lokalna promenliva za Block1 int d2; // Druga lokalna promenliva za Block1 // ********************************************************************** void Block2( ) int a1; // Go sprecuva pristapot kon globalnata a1 int b2; // Lokalna promenliva za Block2; nema konflikt // so b2 vo Block1 79

81 while ( ) // Block3 int c1; // Lokalna promenliva za Block3; nema konflikt so // c1 vo Block1 int b2; // Go sprecuva nelokalniot pristap kon b2 vo Block2 // Nema konflikt so b2 vo Block1 Животен век на променлива Животниот век на идентификатор е временскиот период во текот на извршување на програмата за која на идентификаторот му е доделен мемориски простор Локалната променлива добива мемориски простор во моментот кога контролата влегува во функцијата Додека функцијата се извршува, локалните променливи се живи Кога функцијата завршува, на локалната променлива & се одзема меморискиот простор Во случај на глобални променливи, меморискиот простор се доделува само еднаш (кога програмата почнува да се извршува) и се одзема само еднаш (кога целиата програма завршува) Во C++ автоматска променлива е онаа на која & се доделува (allocate) мемориски простор при влез во блокот, а и се уништува (deallocate) меморискиот простор при излез од блокот Статичка променлива е онаа чиј мемориски простор останува доделен сè додека трае програмата За да декларираме статичка променлива, го користиме резервираниот збор static, како што е наведено во примерот: void SomeFunc( ) float SomeFloat; // Se unistuva koga izvr[uvaweto na funkcijata zavrsuva static int someint; // Ja zadrzuva vrednosta pri sekoj povik na funkcijata 80

82 Обично е подобро да се декларира локална статичка променлива, отколку да се користи глобална променлива Како и кај глобалната променлива, меморијата на статичката променлива е доделена за целото време на извршување на програмата За разлика од глобалната променлива, доменот на статичката променлива е локален и на неа не може да & се пристапува од друг блок Иницијализација во декларација Обично во нашите програми, прво ја декларираме променливата, а потоа во посебна инструкција & доделуваме иницијална вредност C++ дозволува декларацијата и иницијализацијата да се вршат само со една инструкција Иницијализацијата извршена на овој начин се нарекува иницијализација во декларација На пример: int sum = 0; Автоматска локална променлива се иницијализира со конкретна вредност секојпат кога контролата влезе во блокот каде што е променливата На пример: Void SomeFunc( int someparam ) int i = 0; // Se inicijalizira sekojpat pri vlez na kontrolata int n = 2 * someparam+3 // Se inicijalizira sekojpat pri vlez na kontrolata Обратно, иницијализацијата на статичка променлива, без разлика дали е глобална или локална, експлицитно декларирана со резервираниот збор static, се случува само еднаш и тоа во моментот кога контролата првпат ја извршува декларацијата Следното е пример во кој две локални статички променливи се иницијализираат само еднаш (првиот пат кога е повикана функцијата) Void AnotherFunc( int param ) static char ch = A ; static int m = param + 1; // Se inizijalizira samo pri prviot vlez // Se inizijalizira samo pri prviot vlez 81

83 Иако иницијализацијата & дава на променливата почетна вредност, променливата може да се менува во текот на извршување на програмата Дизајнирање на врската (interface) меѓу две функции и странични ефекти Протокот на податоци низ интерфејсот на две функции (кога една функција повикува друга функција) може да се јави во три форми и тоа: - влез на податоци во функцијата која се повикува; - излез на податоци од функцијата која се повикува; - влезно-излезни податоци во (од) функцијата која се повикува Секој податок што е влезен треба да биде кодиран како вредносен параметар Податоците во другите две категории (излезни и влезно-излезни) мора да бидат кодирани како референцни параметри Единствениот начин повиканата функција да ги депонира резултатите во функцијата-повикувач е да ги има адресите на аргументите Илустративно, начинот на комуникација на аргументите е прикажан во следнава табела: Проток на податок за параметарот на повиканата функција Влезен (податок кој влегува) Излезен (податок кој излегува) Влезно-излезен (податок кој влегува во функцијата, се процесира и излегува) Механизам на проследување на аргументи По вредност По референца По референца Влезно-излезните објекти кои управуваат со текот на податоци (датотеки, cin, cout) мора да бидат проследени по референца Страничен ефект е кој било ефект од една функција врз друга, кој не е дел од експлицитно дефинираниот интерфејс меѓу двете функции Страничните ефекти некогаш се предизвикани од комбинација на референцни параметри и невнимателно кодирање во функцијата На пример, инструкцијата за доделување доделува привремен резултат во некој од референцните параметри со што ја менува вредноста на аргументот и во функцијатаповикувач За да се заштитиме од вакви несакани ефекти, влезниот параметар треба да прима аргументи проследени по вредност, а не по референца Страничен ефект може да се појави и кога функцијата пристапува на глобална променлива Грешка во функцијата може да предизвика вредноста на глобалната 82

84 променлива да биде променета на неочекуван начин, предизвикувајќи грешки и во други функции кои & пристапуваат на глобалната променлива Симптомите од грешка поради страничен ефект (side effect) обично водат во погрешен правец, бидејќи грешката се појавува во еден дел од програмата, а фактички е предизвикана во друг дел За да се избегнат вакви грешки, единствениот надворешен ефект што функцијата треба да го има е да ја пренесе информацијата преку добро структуиран интерфејс на листа на параметри (сл 81) Ако функциите пристапуваат на нелокални променливи само преку нивните листи на параметри и ако сите чисто влезни параметри се вредносни параметри, тогаш секоја функција е суштински изолирана од другите делови на програмата и не можат да се појават штетни странични ефекти 83

85 main i drugi f unkci i strani ~ni ( tetni ) ef ekti Li st a na paramet ri Komuni kaci ski i nterf ejs ti pi ~na f unkci ja sl 81 За разлика од глобалните променливи кои не се препорачуваат поради страничните ефекти, се препорачува именуваните константи да се декларираат глобално Предноста е во тоа што при одржување на програмата, вредноста на константата се менува само на едно место Од друга страна, константите како податоци што не се менуваат, не можат да предизвикаат штетни странични ефекти 84

86 Функции кои враќаат вредност (Value-Returning Functions) Претходно се сретнавме со функции кои враќаат вредност Такви функции се функциите од стандардната библиотека на C++: sqrt, abs, fabs и други Од перспектива на функцијата-повикувач, главната разлика меѓу функцијата која враќа вредност и void функцијата е начинот на кој тие се повикуваат Повикот на void функција е комплетна инструкција, додека повикот на функција која враќа вредност е дел од израз Од перспектива на дизајн, функциите кои враќаат вредност се користат кога треба да се врати само еден резултат од функцијата Како пример да погледнеме функција која за даден датум го пресметува и враќа редниот број на денот во годината во ранг за прост година или за престапна година int Day( /* in */ int month, // Broj na mesecot 1-12 /* in */ int dayofmonth // Den vo mesecot 1-31 /* in */ int year ) // Godina na pr 2007 int correction = 0; // korekcionen faktor za prestapna godina i za // meseci so razlicna dolzina // Test za prestapna godina if (year % 4 == 0 && (year % 100!= 0 year % 400 == 0) if (month >= 3) // Ako datumot e po 29 fevruari correction = 1; // dodaj eden za prestapna godina // Korekcija za meseci so razlicna dolzina if (month == 3) correction = correction 1; else if (month == 2 month == 6 month == 7) correction = correction + 1; else if (month == 8) correction = correction + 2; else if (month == 9 month == 10) correction = correction + 3; else if (month == 11 month == 12) correction = correction + 4; return (month 1) * 30 + correction + dayofmonth; 85

87 Првата работа која може да се забележи е дека дефиницијата на функцијата личи на дефиниција на void функција, освен што насловот (heading) започнува со тип на податок (во овој случај int) наместо зборот void Втора работа по која се разликуваат овие два вида на функции е return инструкцијата, која е присутна во секоја функција која враќа вредност Во овој случај return инструкцијата на крајот од функцијата ја враќа вредноста на integer изразот кој следува по клучниот збор return Функцијата која враќа вредност, вредноста ја враќа не преку параметар, туку преку инструкцијата return Типот на податок кој е прв збор во насловот на дефиницијата на функцијата се нарекува тип на функцијата и тој го претставува типот на податок на резултатот вратен од функцијата Шаблонот (template) за функција која враќа вредност е: Тип на податок - Име на функција ( Листа на параметри ) Како што се гледа од шаблонот, типот на податок е опционен (необврзувачки) и ако е испуштен во насловот на дефиницијата, по default се усвојува int Лоша програмерска пракса е да се испушта типот на податок Листата на параметри се дефинира, исто како и кај void функциите Параметрите, ако постојат, се раздвојуваат со запирки Заградите се задолжителни дури и ако нема параметри Еве неколку примери на функции кои враќаат вредност Следната функција пресметува и враќа каде x и n се целобројни вредности n x int Power ( /* in */ int x, // Osnova na stepen /* in */ int n) // Eksponent // Ovaa funkcija presmetuva x na stepen n // Preduslov: n >= 0 && ( x na n ) <= INT_MAX // Rezultat: Vrednosta na funkcijata == x na n int result; // Cuva rezultat result = 1; 86

88 while (n > 0) result = result * x; n--; return result; Следната функција пресметува факториел По дефиниција n! 1 2 n и 0! = 1 Int Factorial( /* in */ int n ) // Broj cij faktoriel sakame da go presmetame // Ovaa funkcija presmetuva n! // Preduslov: n >=0 && n! <= INT_MAX // Rezultat: Vrednost na funkcijata == n! int result; // Cuva proizvodi result = 1; while (n > 0) result = result * n; n--; return result; Повикот на функцијата Factorial може да биде следниов: combinations = Factorial (n) / (Factorial (m) * Factorial (n-m)); Дизајнирање на врската (interface) и странични ефекти Бидејќи функциите кои враќаат вредност враќаат само една вредност, постои само еден податок кој е излезен Сите други податоци од интерфејсот се влезни Враќање на повеќе од еден податок од функцијата со модификување на листата на 87

89 параметри е страничен ефект и не е препорачливо да се прави Ако функцијата треба да враќа повеќе од една вредност, тогаш треба да се користи void функција Исклучок од оваа констатација е кога во функцијата треба да се предаде тек (stream) за да функцијата го тестира неговиот статус C++ дозволува тек (од датотека или од тастатура) да се пренесе само како референцен аргумент Се поставува прашање кога да се користи функција која враќа вредност, а кога void функција Еве неколку препораки: 1 ако модулот треба да врати повеќе од една вредност или треба да модификува некој од аргументите на функцијата повикувач (caller) користите void функција; 2 ако модулот мора да изврши I/O не користете функција која враќа вредност; 3 ако модулот треба да врати само една вредност и таа вредност е од тип bool, функција која враќа вредност е соодветна; 4 ако модулот треба да врати само една вредност и таа вредност треба да биде веднаш користена во израз, функција која враќа вредност е соодветна; 5 кога не сте сигурни кој вид функција да употребите, користете void функцијa; 6 ако и void функцијатa и функцијатa која враќа вредност се прифатливи, користете ја онаа со која се чувствувате посигурни 88

90 IX/ Дополнитени контролни структури Во претходните глави ги разгледавме C++ инструкциите за секвенца, селекција, циклус и подпрограми функции Во некои случаи разгледавме повеќе варијанти за имплементирање на овие структури На пример селекцијата може да биде имплементирана со повеќе варијанти на If структурата, If-Then, If-Then-Else, If-Then- Else If Во оваа глава воведуваме пет нови инструкции кои се згодни за програмирање Switch Инструкција Switch инструкцијата е контролна структура селекција која ни овозможува да листаме поголем број на разгранувања на текот на контролата Switch е сличен со вгнездената If инструкција Вредноста на switch изразот израз чија вредност се споредува со лабелите прикачени на гранките, определува која гранка ќе се извршува На пример: Во овој пример, letter е switch изразот Инструкцијата може да се чита "Ако letter е 'X', изврши ја Statementl и излези од Switch инструкцијата, продолжувајќи со Statement5 Ако letter е 'L' или 'M', изврши ја Statement2 и продолжи со Statement5 Ако letter е S', изврши ја инструкцијата Statement3 и продолжи со Statement5 Ако letter не е ниеден од споменатите карактери, изврши ја Statement4 и продолжи со Statement5" Break инструкцијата предизвикува моментален излез од Switch инструкцијата Понатаму ќе видиме што се случува ако ја изоставиме Break инструкцијата Switch изразот е израз чија вредност определува која switch лабела е селектиран Switch изразот не може да биде floating-point или string израз Синтактичкиот шаблон за Switch изразот е: 89

91 IntegralOrEnumExpression е израз од integral тип - char, short, int, long, bool или од enum тип (за enum тип ќе зборуваме во следната глава) Опционата SwitchLabel пред инструкција (Statement) е или case лабела или default лабела: Во case лабелата, ConstantExpression е integral или enum израз чии операнди мора да бидат литерали или именувани константи Следното се примери на константни integral изрази (каде CLASS_SIZE е именувана константа од тип int): Типот на податок на ConstantExpression ако е потребно имплицитно се конвертира (коерцира), за да биде ист со типот на податок на switch изразот Во нашиот воведен пример кој ја тестира вредноста на letter, следниве се case лабели: case 'X' : case 'L' : case 'M : case 'S' : 90

92 Како што покажува примерот, на една инструкција може да и претходат повеќе лабели Секоја case вредност може да се појави само еднаш во дадена Switch инструкција Исто така може да има само една default лабела во Switch инструкцијата Текот на контролата во Switch инструкцијата оди на следен начин Прво се евалуира switch изразот Ако оваа вредност се совпаѓа со една од вредностите за case лабелите, контролата оди на инструкцијата кој следува после соодветната лабела Од таму контролата продолжува секвенцијално додека не биде прекината или со Break инструкција или со крајот на Switch инструкцијата Ако вредноста на switch изразот не се совпаѓа со ниту една case вредност тогаш ако постои default лабела контролата оди на таа лабела, а ако нема default лабела сите инструкции во Switch се прескокнуваат и контролата едноставно продолжува на инструкцијата која ја следи целата Switch инструкцијата switch (grade) case A : case B : case C : case D : case F : cout << Good work ; break; cout << Average work ; break; cout << Poor work ; numberintrouble++; break; // Ne e neophoden Горниот програмски сегмент подразбира дека валидни карактери за grade се A, B, C, D и F и не води сметка за погрешен внос на карактер Следниот код извршува и контрола на содржината на grade: switch (grade) case A : case B : case C : case D : case F : cout << Good work ; break; cout << Average work ; break; cout << Poor work ; 91

93 default : numberintrouble++; break; cout << grade << Ne e validna opisna ocena break; Switch контролата се применува за определување на контролата на текот кога постојат повеќе од две алтернативи Да се потсетиме дека истото го прави и If- Then-Else-If контролата Последниот програмски сегмент со If-Then-Else-If варијантата изгледа вака: if (grade == A grade == B ) cout << Good work ; else if (grade == C ) cout << Average work ; else if (grade == D grade == F ) cout << Poor work ; numberintrouble++; else cout << grade << Ne e validna opisna ocena ; Што се случува ако во претпоследниот програмски сегмент ја испуштиме секаде инструкцијата break Тогаш го имаме следниов код: switch (grade) case A : case B : case C : case D : case F : default : cout << Good work ; cout << Average work ; cout << Poor work ; numberintrouble++; cout << grade << Ne e validna opisna ocena 92

94 Ако вредноста на grade во горниот пример е A, ќе го имаме следниов излез: Good workaverage workpoor workane e validna opisna ocena Do-While инструкција Do-While инструкцијата е контролна структура циклус во која условот на циклусот се тестира на крајот (дно) на циклусот Овој формат гарантира дека телото на циклусот се извршува барем еднаш Синтактичкиот шаблон за Do-While е следниот: do Statement; while (Expression); Statement е или единечна инструкција или блок Исто така треба да се примети дека dowhile завршува со точка-запирка карактер (;) Разгледуваме неколку примери решени со while и do-while варијанта: while варијанта do-while варијанта DataFile >> inputchar; While (inputchar!= ) DataFile >> inputchar; do datafile >> inputchar; while (inputchar!= ); Во горниот пример while варијантата бара примарно читање за да го евалуира while изразот, додека во do-while првото читање се врши внатре во циклусот пред евалуацијата која е на крајот од циклусот Сега разгледуваме програмски сегмент кој контролира корисникот во интерактивен програм да не внесе негативен број Се додека корисникот не внесе позитивен број програмот го враќа назад на внос Вакви одбранбени механизми често се применуваат во пракса While варијанта: cout << Vnesete pozitiven cel broj: ; cin >> broj; while (broj <= 0) cout << Brojot mora da bide pozitiven << endl; cout << Vnesete pozitiven cel broj: ; cin >> broj; 93

95 Do-while варијанта: do cout << Vnesete pozitiven cel broj: ; cin >> broj; if (broj <=0) cout << Brojot mora da bide pozitiven << endl; while ( broj <= 0); Разликата меѓу овие две варијанти е во тоа што за while варијантата мора два пати да се напише промпт и инструкција за внос, додека во do-while, промптот и инструкцијата за внос се пишуваат само еднаш, но евалуација се врши два пати Do-While може да се користи за имплементација на циклус контролиран од бројач ако однапред знаеме дека телото на циклусот ќе се изврши барем еднаш Следните се две верзии на циклус кој сумира броеви од 1 до n While варијанта: Do-While варијанта: sum = 0; sum = 0; counter = 1; counter = 1; while (counter <=n) do sum = sum + counter; sum = sum + counter; counter++; counter++; while (counter <=n); Do-While варијантата е иста со While варијантата за сите позитивни вредности на n За n = 0, While варијантата нема да се изврши и вредноста на sum останува 0 и после циклусот Do-While варијантата се извршува еднаш и вредноста на sum после извршувањето на циклусот е 1 94

96 For инструкција Во C++ For инструкцијата е фактички компактна форма на while инструкцијата Компајлерот фактички ја преведува For инструкцијата во еквивалентен while циклус како што е прикажано на сл 81 Сл 81 Синтактичкот шаблон е следниов Expressionl е While условот InitStatement може да биде едно од следниве: null инструкција (само точка-запирка карактер), инструкција за декларација (која секогаш завршува со точка-запирка), или израз кој завршува со точка-запирка Значи секогаш има карактер (; ) пред Еxpressionl Најчесто For инструкцијата е напишана така да InitStatement ја иницијализира променливата која го контролира циклусот и Expression2 ја инкрементира или декрементира променливата која го контролира циклусот Следните два циклуса се извршуваат по 50 пати: for (loopcount = 1; loopcount <= 50; loopcount++) 95

97 for (loopcount = 50; loopcount >= 1; loopcount--) Како и другите контролни структури и For циклусите може да се вгнездуваат На пример цикличната структура: for (i = 1; i <= 7; i++) for (j = 1; j <= i; j++) cout << j; cout << endl; ќе го даде следниов излез: Break и Continue Инструкции Break инструкцијата која ја видовме кај Switch контролната структура, исто така се користи со циклуси Таа предизвикува моментален излез од највнатрешната вгнездена структура (Switch, While, Do-While, или For инструкција во која се појавува) Значи ако break е во циклус кој е вгнезден во друг циклус, контролата излегува од внатрешниот циклус, но не и од надворешниот Еден од најчестите случаи на користење break со циклус е да се дизајнира бесконечен циклус Да претпоставиме дека треба да внесеме 10 пара од цели броеви, да 96

98 извршиме валидација на податоците и да пресметаме квадратен корен од сумата на секој пар броеви Да претпоставиме дека првиот број од секој пар мора да биде помал од 100, а вториот мора да биде поголем од 50 Исто така после секој влез сакаме да ја тестираме состојбата на влезниот тек за EOF Следното е кодот кој ги озвршува сите овие работи: loopcount = 1; while (true) cin >> num1; if (!cin num1 >= 100 ) break; cin >> num2; if (!cin num2 <= 50 ) break; cout << sqrt(float(num1+num2)) << endl; loopcount++; if (loopcount > 10) break; Овој циклус содржи три различни точки на излез кога некој од трите услови: 1 состојбата на влезниот тек е false или num1 >= 100, 2 состојбата на влезниот тек е false или num2 < 50, 3 loopcount добил вредност 11 е исполнет Алтернатива на овој дизајн е дизајнот со вгнездена If контрола кој ги тестира горе наведените услови на излез Ваквата If контрола е посложена и затоа дизајнот со бесконечен циклус и break бара пишување на помалку код и е помалку подложен на грешки Continue инструкцијата се користи поретко За разлика од break инструкцијата која и наложува на контролата моментален излез од циклусот во кој се наоѓа break, continue инструкцијата не го прекинува циклусот, туку само наложува прескокнување на инструкциите после continue и враќање на while тест изразот 97

99 X Прости типови на податоци Вградени (Built-In) и кориснички дефинирани (User-Defined) Вградени (built-in) типови на податоци Прост (атомски) тип на податок е тип на податок во кој секоја вредност е атомска (неделива) Друг начин на опис на прост тип е дека тоа е тип кај кој само една вредност може да биде поврзана со променлива од тој тип Обратно, структуиран тип е оној кај кој цело множество на вредности е поврзано со една променлива од тој тип На пример, променлива од тип string претставува множество од карактери на кои им е дадено едно име На сл 101 е прикажан дел од сл 3-1 кој ги вклучува само простите типови на податоци p r o s t i t i p o v i i n t e g r a l f l o a t i n g char short int long bool enum float double long double слика 101 Типот enum не е прост тип како int и float, но тоа е механизам со кој може да се дефинираат прости кориснички дефинирани типови на податоци Integral и floatingpoint типовите едноставно реферираат на целобројни и децимални броеви со различни должини Во C++ должините се мерат во бајтови (bytes) Постои функција sizeof (datatype) која ја дава должината на одреден тип на податок (datatype) Должините на типовите на податоци зависат од машината и различни компјутери може да дадат различен резултат 98

100 од функцијата sizeof, иако аргументот е ист Покрај овие варијации, C++ гарантира дека следниве тврдења се точни: 1 sizeof(char) sizeof(short) sizeof(int) sizeof(long) 1 sizeof(bool) sizeof(long) sizeof(float) sizeof(double) sizeof(long double) char e najmalku 8 bita dolg short e najmalku 16 bita dolg long e najmalku 32 bita dolg Интегрални типови Рангови на вредности Ранговите на вредности се machine-dependant (различни за различни машини) Следниве вредности се однесуваат на една конкретна машина Тип Должина Минимална вредност Макс вредност податок (бајти) char unsigned char short unsigned short int unsigned int long unsigned long Во C++ системите постои header датотека climits од која може да се определат минималната и максималната должина На пример: #include <climits> using namespace std; cout << Max long = << LONG_MAX << endl; cout << Min long = << LONG_MIN << endl; Литерални константи Во C++ валидни bool константи се true и false Целобројните константи можат да бидат специфицирани во три бази: децимална (база 10), октална (база 8) и хексадецимална (база 16) Како што децималниот броен систем има 10 цифри (од 0 до 9), окталниот броен систем има 8 цифри (од 0 до 7), а хексадецималниот систем се 99

101 состои од 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, кои одговараат на децималните вредности од 0 до 15 Во овој курс, ние оперираме само со децималната база Floating-point типови Рангови на вредности Во табелата што следува се дадени ранговите на вредности на трите floating-point типови За секој тип се дадени минималната позитивна вредност (број многу близок до 0) и максималната вредност Негативните вредности имаат ист ранг со негативни вредности Тип Должина Мин позитивна вредност Макс вредност податок (бајти) float 4 34Е-38 34Е+38 double 8 17Е Е+308 long double 10 34Е Е+4932 Ранговите се зависни од машината и овие вредности се однесуваат за конкретна машина Во C++ системите постои header датотека cfloat од која може да се определат минималните и максималните должини на floating-point типовите на податоци Литерални константи Floating-point константите во C++ се од тип double (double precision) Ако во float променлива се додели литерална константа, настанува имплицитна конверзија од double во float Ако инсистираме константата да биде од тип float, тогаш на крајот од константата прикачуваме f или F Следната табела прикажува константи од различни тпови Константа Тип Забелешка 683 double По default floating-point константите се од тип double 683F float Експлицитните float константи завршуваат со F 683L long double long double константите завршуваат со L 435E-9 double Експоненцијална нотација со значење 435x10-9 Други C++ оператори Освен основните, C++ располага со огромен број други оператори кои ретко се среќаваат во другите програмски јазици Овде наведуваме неколку: - комбинирани оператори на доделување + = додај и додели 100

102 - = извади и додели * = помножи и додели / = подели и додели % = пресметај модул и додели << = помести лево и додели >> = помести десно и додели - инкремент и декремент оператори + + пре-инкремент нпр ++ i + + пост-инкремент нпр i пре-декремент нпр -- j - - пост-декремент нпр j -- Bitwise оператори (главно за манипулирање со битови и мемориски адреси) << лево поместување >> десно поместување & bitwise AND bitwise OR ^ bitwise EXCLUSIVE OR ~ complement Други оператори ( ) cast sizeof должина на операнд (или тип на податок) во бајти? : условен оператор Оператор на доделување и изрази на доделување C++ има неколку оператори на доделување Знакот = е основен оператор на доделување Кога овој оператор се комбинира со своите два операнда, се формира израз на доделување Секој израз на доделување има вредност и страничен (side) ефект На пример: delta = 2 * 12 има вредност 24 и страничен ефект ставање на таа вредност во delta Во C++ кој било израз станува инструкција кога ќе се додаде знакот точказапирка (;) Сите следни примери се C++ инструкции: 23; 2 * (alpha + beta); delta = 2 * 12; Првите две инструкции немаат никаков ефект на извршување на програмата и се бескорисни Третата инструкција е корисна, бидејќи има страничен ефект ставање вредност 24 во променливата delta 101

103 Значи, израз на доделување е C++ израз со (1) вредност и (2) страничен ефект на ставање на вредноста во мемориска локација; инструкција на доделување е инструкција формирана со додавање на знакот ; на крајот од изразот Освен основниот оператор за доделување =, во C++ има неколку комбинирани оператори (+=, -=, *=, /= и др) кои како страничен ефект имаат доделување На пример: Инструкција Еквивалентна инструкција i += 5 i = i+5 flvar *= 1 x flvar = flvar * (1 x) Комбинираните оператори на доделување имаат и добри и лоши страни Од една страна го скратуваат кодирањето, а од друга страна не се толку прегледни како нивните еквивалентни инструкции Инкремент и декремент оператори Операторите инкремент и декремент (++ и --) оперираат само на променливи Да претпоставиме дека променливата brojac содржи вредност 8 Изразот ++brojac означува преинкрементирање Прво се извршува страничниот ефект инкрементирање на brojac, така што резултантната вредност на изразот е 9 Изразот brojac++ означува постинкрементирање Вредноста на изразот е 8 и потоа се случува страничниот ефект инкрементирање на brojac Следниот код ја илустрира разликата меѓу пре- и постинкрементирање: int1 = 14; int2 = ++int1; // Во овој момент int1 има вредност 15 и int2 има вредност 15 int1 = 14; int2 = int1++; // Во овој момент int1 има вредност 15, а int2 има вредност 14 Cast (експлицитна конверзија) операција Кога оперира со мешани типови на податоци во: инструкциите за доделување во изразите, во трансфер на аргументи и во враќање на вредност на функција, C++ врши имплицитна конверзија (coercion) Наместо да се потпираме на имплицитната конверзија, беше препорачано типовите на податоци да се конвертираат експлицитно во самиот израз (casting) со што 102

104 програмерот укажува на својата намера да го конвертира типот на податок Во C++ операцијата casting може да има две форми На пример: intvar = int(floatvar); // Функциска нотација intvar = (int) floatvar; // Префикс нотација Потребно е типот да биде во загради C++ програмерите обично ја користат функциската нотација, но таа има едно мало ограничување Имено, не може да се користи кога името на типот на податоци се состои од повеќе од едно име На пример: myvar = unsigned int (somefloat); // ова е погрешно myvar = (unsigned int) somefloat; // ова е точно Sizeof оператор Ова е унарен оператор кој ја дава должината на неговиот операнд во бајтови Операндот може да биде име на променлива sizeof someint Или име на тип на податок затворен во загради sizeof (float) На конкретна машина може да се најдат должините на различни типови на податоци со користење на следниов код: cout << Size of a short is << sizeof (short) << endl; cout << Size of an int is << sizeof (int) << endl; cout << Size of a long is << sizeof (long) << endl; Условен (conditional) оператор? : Овој оператор, за разлика од унарните и бинарните оператори кои оперираат на еден или два операнди респективно, е тринарен оператор, односно оперира врз три операнди Неговата синтакса е: Izraz1? Izraz2 : Izraz3 Прво компјутерот го евалуира Izraz1 Ако вредноста на евалуацијата е true, тогаш вредноста на целиот израз е вредноста на Izraz2 Инаку вредноста на целиот израз е вредноста на Izraz3 Значи, само еден од Izraz2 и од Izraz3 се оценува) Класичен пример за примена на овој оператор е во променлива max да се стави поголемата вредност од вредностите на две променливи a и b Користејќи if инструкција овој проблем го решаваме со следниов код: if (a > b) max = a; 103

105 else max = b; Со користење на? : операторот, можеме да ја користиме следнава инструкција на доделување: max = (a > b)? a : b; Еве уште еден пример Апсолутната вредност на број x е дефинирана како: x ako x 0 x x ako x 0 За да ја пресметаме апсолутната вредност на променлива x и да ја сместиме во променлива y, можеме да користиме условен оператор како што следува: y = (x >= 0)? x : -x; Податоци од тип char Видовме дека во променлива од тип char можеме да чуваме карактери како A, е 3 и др Но од друга страна, типот char е интегрален тип и во него можеме да чуваме и податоци од целоброен тип како: char counter; counter = 3; Се поставува прашање како компјутерот ја знае разликата меѓу целоброен тип и карактер кога податоците се сместени во мемориската ќелија За компјутерот не постои разлика Секој карактер има два вида на репрезентација: - екстерна репрезентација е принтабилна (карактер) форма на вредноста на податокот - интерна репрезентација е форма во која вредноста на податокот се чува внатре во мемориската единица Да ги споредиме инструкциите: ch = A ; ако машината користи ASCII карактер сет, компајлерот ја преведува константата A во цел број 65 Така можеме да напишеме ch = 65; Горните две инструкции имаат ист ефект: доделување 65 во ch Меѓутоа, втората инструкција не се препорачува, бидејќи на машина која користи друг карактер сет целобројната константа означува друг карактер 104

106 Да погледнеме уште еден програмски сегмент: // Овој пример претпоставува користење на ASCII карактер сет int someint = 97; char somechar = 97; cout << someint << endl; cout << somechar << endl; Кога овие инструкции ќе се извршат, излезот е: 97 а Значи, иако двете променливи интерно содржат вредност 97, типот на податок ја определува принтабилната (екстерна) вредност на двата карактерa Следниот код ги печати карактерите од А до G: for ( ch = A ; ch <= G ; ch++) cout << ch; Множествата од карактери (character set) вклучуваат како принтабилни, така и контролни (непринтабилни) карактери Ако гледаме во ASCII табелата на карактери, може да се забележи дека принтабилни карактери се оние со целобројни вредности во интервалот меѓу 32 и 126 Останатите карактери (од 0 до 31 и карактерот 127) се контролни карактери За да ги приспособи контролните карактери за користење, C++ воведува втора форма на char константа, escape sequence Escape sequence (escape секвенца) се состои од backslash (\) и еден или повеќе карактери Следниве се контролни (непринтабилни) карактери во C++: \n Нова линија \t Хоризонтален tab \v Вертикален tab \b Backspace \r Carriage return \f Form feed \a Alert (ѕвоно или beep) \\ Backslash \ Апостроф \ Наводници \0 Нулти карактер (сите битови се 0) cout << \a ; На пример, извршувањето на инструкцијата ќе предизвика звук beep 105

107 Is функции и конвертирање од мали во големи букви и обратно Во header датотеката <cctype> има вградено повеќе кориснички функции кои вклучуваат манипулирање со карактери Такви се is функциите: isalnum(ch) isalpha(ch) iscntrl(ch) isdigit(ch) islower(ch) isupper(ch) Сите овие функции се функции кои враќаат вредност Тие за аргумент земаат карактер (char), а враќаат целобројна вредност (int) Ако вредноста која ја враќа функцијата е цел број различен од 0, вредноста на изразот кој се евалуира е true, а ако е 0 вредноста на изразот е false Овие функции често се употребуваат при контрола на внос и евалуација на логички изрази На пример, следната функција контролира дали внесениот карактер е нумерички и ако е, го претвoра во тип на податок integer #include <cctype> using namespace std; void GetNum (/*out */ int& numval) char inpch; bool nenum = false; do cout << Vnesi cel broj od 1 do 5: ; cin >> inpch; if (! isdigit (inpch)) nenum = true; else numval = int (inpch 0 ); if ( numval < 1 numval > 5) // Vneseniot karakter ne e numericki 106

108 rangot nenum = true; // Karakterot e cifra, no ne e vo if (nenum) cout << Nevaliden broj Probajte povtorno << endl; while (nenum); Освен is (ch) функциите, header датотеката <cctype> ги содржи функциите toupper(ch) и tolower(ch) Функцијата toupper(ch) за аргумент зема карактер и враќа: - еквивалентен uppercase (голема буква) карактер ако ch е lowercase (мала буква) карактер; - го враќа аргументот ch ако ch не е lowercase (мала буква) карактер Функцијата tolower(ch) за аргумент зема карактер и враќа: - еквивалентен lowercase (мала буква) карактер ако ch е uppercase (голема буква) карактер; - го враќа аргументот ch ако ch не е uppercase (голема буква) карактер Пристап на карактер во стринг Ако е даден string објект (константа или променлива) може да се пристапи до карактер од тој стринг ch = inputstr[2] на ch и го доделува третиот карактер од стрингот inputstr (тука треба да се внимава на фактот дека во C++ првиот карактер на стрингот одговара на индекс 0) На пример, во некој дел од кодот, корисникот треба да одговори со Da или Ne Притоа корисникот може да го внесе одговорот со сите комбинации од мали или големи букви Една од можностите е секоја комбинација од одговорот да се испитува со долга if контролна структура Друго поелегантно решение е да се испитува само првиот внесен карактер и изгледа вака: string inputstr; cout << Vnesete Da ili Ne: ; cin >> inputstr; // Prompt // Korisnikot vnesuva podatok // toupper go pretvora prviot karakter vo if (toupper (inputstr[0]) == D ) golema // bukva i ispituva dali e D 107

109 else if (toupper (inputstr[0]) == N ) // ako ne e D toupper go pretvora prviot karakter // vo golema bukva i ispituva dali e N else PrintErrorMsg( ); // Prviot karakter ne e ni D ni N // Otpecati greska Кориснички-дефинирани прости типови Една од предностите на C++ е што му дозволува на програмерот да креира свои типови на податоци Typedef инструкција Оваа инструкција дозволува да се внесе ново име за постоечки тип на податок Синтаксата е: typedef - Постоечко име на податок - Ново име на податок Пред да bool типот на податок стане вграден во C++, многу програмери користеле код сличен на следниот за да симулираат Boolean тип: typedef int Boolean; const int TRUE = 1; const int FALSE = 0; Boolean dataok; dataok = TRUE; Во овој код, typedef инструкцијата му наложува на компајлерот за секоја појава на зборот Boolean да го стави типот на податок int Енумератион тип на податок C++ му дозволува на корисникот да дефинира нов прост тип на податок со листање на литерални вредности кои го сочинуваат доменот на типот Овие литерални вредности мора да бидат идентификатори, а не броеви Идентификаторите се разделени со запирка и листата е затворена во големи загради Овој тип на податок, дефиниран на овој начин, се нарекува enumeration тип На пример: 108

110 enum Days SUN, MON, TUE, WED, THU, FRI, SAT; Оваа декларација креира нов тип на податок по име Days Ова е нов тип на податок и е различен од кој било постоечки тип Вредностите во типот на податок Days - SUN, MON, TUE, се нарекуваат енумератори Овие вредности се поодредени така што SUN < MON < TUE < Бидејќи енумераторот мора да биде C++ идентификатор, следниве декларации се погрешни: enum Vowel A, E, I, O, U ; // идентификаторот мора да почне со буква или _ enum Places 1 st, 2 nd, 3 rd ; // идентификаторот мора да почне со буква или _ Да претпоставиме дека правиме програма за ветеринарна станица и сме креирале тип Animals Декларираме две променливи од овој тип како што следува: enum Animals GLODAR, MACKA, KUCE, PTICA, VLEKAC, KONJ, KRAVA, OVCA; Animals inpatient; Animals outpatient; Да разгледаме неколку операции кои можат да бидат извршени на променливи од enumeration тип Доделување inpatient = DOG; outpatient = inpatient; Горните две инструкции на доделување се валидни, бидејќи на променлива од тип Animals & се доделува: во првиот случај, литерална вредност од доменот на типот на податок Animals, а во вториот случај, променлива од тип Animals Следната инструкција не е валидна: inpatient = 2; Имплицитна конверзија (coercion) е дозволена од enumeration во integer тип Обратната имплицитна конверзија (од integer во enumeration тип) не е дозволена Така: someint = DOG; // дозволено inpatient = 2; // грешка Инкрементација Да претпоставиме дека сакаме да ја зголемиме вредноста на inpatient, така што inpatient ја добие следната вредност во доменот на Animals Пишуваме инструкција inpatient = inpatient + 1; // Погрешно Горната инструкција е погрешна од следнава причина: изразот од десната страна е во ред, бидејќи ќе настапи имплицитна конверзија од enumeration во integer 109

111 тип и десната страна има вредност од тип integer Кога оваа вредност треба да & се додели на променливата од левата страна, треба да настапи имплицитна конверзија од integer во enumeration тип на податок, а тоа не е валидно Бидејќи инкремент операцијата е еквивалентна на горниот израз, од истите причини inpatient++ е невалидно За да ја избегнеме несаканата коерција (имплицитна конверзија), користиме експлицитна конверзија како што следува: inpatient = Animals(inPatient + 1); // Точно Инкрементирањето на променлива е посебно корисно во циклуси На пример: for (patient = GLODAR; patient <= OVCA; patient=animals(patient + 1)) вака креираниот циклус е валиден Единствено треба да се има предвид дека по завршувањето на циклусот, променливата patient е надвор од рангот Ако сакаме повторно да ја користиме променливата patient мора да & доделиме вредност која е во рангот на типот Animals Споредување Кога се споредуваат две вредности, релацијата се определува врз основа на нивниот редослед во листата на енумератори На пример, изразот: inpatient <= PTICA ќе има вредност true ако inpatient има вредност GLODAR, MACKA, KUCE или PTICA Вредности од тип enumeration може да се користат во switch инструкција: switch (inpatient) case GLODAR : case MACKA : case KUCE : case PTICA : cout << Metalen kafez ; break; case VLEKAC : cout << Staklen kafez ; break; case KONJ : case KRAVA : case OVCA : cout << Stala ; Влез и излез Влезно-излезниот тек (stream) е дефиниран само за основните типови на податоци (int, float, char итн) Вредностите на типовите enum мора да одат на внос и 110

112 излез индиректно На пример, програмaтa може да го чита видот на животно како стринг и потоа да му додели една од константите во enum типот На пример: #include <cctype> #include <string> string animalname; cin >> animalname; switch (toupper(animalname[0])) case G : inpatient = GLODAR; break; case M : inpatient = MACKA; break; case K : if (toupper(animalname[1] = = U ) inpatient = KUCE; else if (toupper(animalname[1] = = O ) inpatient = KONJ; else inpatient = KRAVA; break; case P : inpatient = PTICA; break; case V : inpatient = VLEKAC; break; default : inpatient = OVCA; break; Враќање на вредност на функција Претходно напишавме switch инструкција за да конвертираме стринг во вредност од тип Animals Сега пишуваме функција која враќа вредност од тип Animals Animals StrtoAnimal ( /*in*/ string str ) switch (toupper(str[0])) case G : return GLODAR; 111

113 case M : return MACKA; case K : if (toupper(str[1] = = U ) return KUCE; else if (toupper(str[1] = = O ) return KONJ; else return KRAVA; case P : return PTICA; case V : return VLEKAC; default : return OVCA; Во оваа функција улогата на break инструкцијата ја презема return инструкцијата Повикот на функцијата StrtoAnimal од main се врши како што следува: enum Animals GLODAR, MACKA, KUCE, PTICA, VLEKAC, KONJ, KRAVA, OVCA; Animals StrtoAnimal (string); int main( ) Animals inpatient; Animals outpatient; string inputstr; cin >> inputstr; outpatient = StrtoAnimal (inputstr); Кориснички дефинирани header датотеки Често одреден кориснички дефиниран тип на податок може да биде користен во повеќе програми Така, податокот: enum Months JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER 112

114 ; чиј ранг се имињата на месеците во годината, може да се користи во повеќе програми Наместо во секојa програмa да го дефинираме овој тип на податок, пpaктичнo е тој да се чува во посебна датотека, да речеме monthsh Потоа со користење на #include директивата, оваа датотекa може да се вклучи во којa било програмa на сличен начин како и системските header датотеки iostream, cmath и други Вклучувањето на нашата датотека би било со директивата: #include monthsh Во овој случај препроцесорот ја бара датотеката во актуелниот програмски директориум 113

115 XI Структуpирани типови на податоци Во третата глава на сл 31 беа илустрирани типовите на податоци кои се среќаваат во C++ Во оваа глава ќе ги разгледаме структуpираните типови на податоци: struct и union Едноставни спрема структуpирани типови на податоци Во претходната глава ние испитувавме едноставни или атомски типови на податоци Вредноста на едноставните типови на податоци не може да биде разбиена на помали делови На пример, секоја int вредност е цел број кој не може да биде понатаму декомпониран Спротивно, структуpиран тип на податок е таков податок во кој секоја вредност е множество од компонентални делови Целото множество од вредности има единствено име, а на секоја компонента од множеството може да & се пристапи индивидуалнопример на структуиран тип на податок во C++ е типот на податок string, кој претставува множество од карактери На секоја од компонентите на стрингот може да & се пристапи индивидуално со користење на израз, како на пример mystring[3], кој му пристапува на карактерот кој се наоѓа на позиција 3 во стрингот Простите типови на податоци (built-in или кориснички дефинирани) претставуваат компоненти на структуираните типови на податоци Слогови (C++ struct) Слогот е хетероген структуpиран тип на податок Под зборот хетероген подразбираме дека индивидуалните компоненти од слогот можат да бидат од различни типови на податоци Секоја компонента на слогот се нарекува поле (field) на слогот и секое поле во состав на слогот си има свое име Слогот се нарекува структура, а секое поле од слогот се нарекува член (member) на структурата Секој член на структурата има име на членот Record (structure во C++) е структуpиран тип на податок со постојан број на компоненти на кои може да им се пристапи по име Компонентите можат да бидат хетерогени (со различен тип на податок) Field (member во C++) е компонента на структурата Синтактичкиот шаблон за декларација на структура во C++ е: struct TypeName MemberList ; 114

116 каде TypeName е идентификатор кој дава име на новодефинираниот тип на податок, а MemberList е дефиниран како: DataType MemberName; DataType MemberName; Како што се гледа, синтаксата на листата од членови MemberList е идентична со низа од декларации на променливи Како пример користиме struct за да опишеме студент на одреден предмет Во слогот сакаме да ги чуваме: името и презимето, просекот пред ислушувaњето на предметот, оценката од задачи од програмирање, оценката на квизови (кратки тестови), оценката од краен испит и оценката за предметот // Deklaracii na tipovi enum GradeType (A, B, C, D, F); struct StudentRec string firstname; string lastname; float gpa; // Grade point average int programgrade; int quizgrade; int finalexam; GradeType coursegrade; ; // Deklaracii na promenlivi StudentRec firststudent; StudentRec student; int grade; Од примерот и од синтактичкиот шаблон треба да се забележи дека struct декларацијата завршува со карактер точка-запирка (;) FirstName, lastname, gpa, programgrade, quizgrade, finalexam и coursegrade се имиња на членови во struct типот StudentRec Ниеден од овие членови на структурата не е поврзан со мемориска 115

117 локација, сè додека променлива од тип StudentRec не е декларирана StudentRec е само шаблон за struct (сл 111) firststudent и student се променливи од тип StudentRec gpa programgrade quizgrade finalexam coursegrade firstname lastname сл 111 Пристапување до индивидуални компоненти За да се пристапи до индивидуален член на struct променлива, прво се наведува името на променливата проследено со точка и потоа името на членот Ваквиот израз се нарекува селектор на членот (member selector) Синтактичкиот шаблон е следниот: StructVariableMemberName Оваа синтакса за селектирање индивидуални компоненти на struct, често се нарекува dot нотација За да пристапиме на просекот на првиот студент, gpa, правилна синтакса е: firststudentgpa За да пристапиме на резултатот од испит на некој студент, синтаксата е: StudentfinalExam Member selector е израз кој се користи да пристапи на компонентите на struct променлива Тој се состои од име на struct променлива и име на член на структурата разделени со точка Компонентата од структурата на која & е пристапено со member selector се третира како која било променлива од ист тип Може да биде користена во изрази на доделување, како аргумент во функција итн Со следниот програмски сегмент ќе ја демонстрираме примената на member selector Користејќи ја нашата променлива student, следниот сегмент чита оценка од краен испит; прави збир од оценката од програма, оценката од квиз и оценката од краен испит и потоа доделува описна оцена на резултатот cin >> studentfinalexam; grade = studentfinalexam + studentprogramgrade + 116

118 studentquizgrade; if (grade >= 900) studentcoursegrade = A ; else if (grade >= 800) studentcoursegrade = B ; Агрегатни операции на структури Освен пристапување на индивидуални компоненти на struct променлива, во некои случаи можеме да користиме агрегатни операции Агрегатна операција е операција на структура на податоци како целина, спротивно на операција на индивидуалните компоненти на структурата на податоци Следнава табела ги дава агрегатните операции кои се дозволени врз struct променливи Агрегатна операција Дали е дозволена на struct? I/O Доделување Аритметичка Споредување Функциски аргумент Враќање (return) како функциска вредност Не Да Не Не Да по вредност и по референца Да Во согласност со табелата, доделувањето е дозволено со тоа што двете променливи мора да бидат од ист тип На пример, за следниве декларации: StudentRec student; StudentRec anotherstudent; инструкцијата anotherstudent = student; ја копира целата содржина од struct променливата student на променливата anotherstudent член по член Од друга страна, агрегатните I/O (влезно-излезни) операции не се дозволени: cin >> student; // Ne e dozvoleno Struct променливата мора да се внесува и печати член по член На пример: cin >> studentfirstname; // Dozvoleno cin >> studentlastname; 117

119 Предавањето на struct тип како функциски аргумент е дозволена агрегатна операција На пример, сакаме да провериме дали оценката на студентот на конкретниот предмет се совпаѓа со неговиот просек (grade point average-gpa) За таа цел, од неговиот слог треба да го отчитаме неговиот просек и да го заокружиме на цел број На 4 одговара А, на 3 одговара B, на 2 одговара C, на 1 одговара D и на 0 одговара F Овој проблем го решаваме со функција која како аргумент користи променлива од тип StudentRec, а враќа bool вредност true или false bool Consistent ( /* in */ StudentRec astudent) int roundedgpa = int (astudentgpa+05) switch (roundedgpa) case 0 : return (astudentcoursegrade == F ); case 1 : return (astudentcoursegrade == D ); case 2 : return (astudentcoursegrade == C ); case 3 : return (astudentcoursegrade == B ); case 4 : return (astudentcoursegrade == A ); Декларирањето на struct тип и декларирањето на една или повеќе променливи од тој тип може да биде извршено во само една инструкција како: struct StudentRec string firstname; string lastname; firststudent, student; Struct Исто така, ако се испушти името на типот (struct ) се формира анонимен тип: int firstmember; float secondmember; 118

120 somevar; Овде somevar е променлива од анонимен тип Други променливи од овој тип не можат да бидат декларирани, бидејќи типот нема име Тоа значи дека somevar не може да учествува во ниту една агрегатна операција Хиерархиски слогови Хиерархиски слог (record) е слог во кој барем една од компонентите сама за себе е слог На пример, продавница за машини чува информации за сите свои машини За секоја машина постои описна информација, како: идентификационен број, опис на машината, датум на купување и цена Исто така, постои статистичка информација која вклучува: број на денови вон погон, честота на расипување и датум на последен сервис Прво да го погледаме нехиерархискиот слог: struct MachineRec int idnumber; string description; float failrate; int lastservicedmonth; int lastservicedday; int lastservicedyear; int downdays; int purchasedatemonth; int purchasedateday; int purchasedateyear; float cost; ; Типот MachineRec има 11 членови Поради многуте детали, тешко е брзо да се оцени што претставува слогот Со реорганизирање во хиерархиски слог, добиваме подобра слика што претставува слогот Можеме да ги поделиме информациите во две групи: информации кои се менуваат и информации кои не се менуваат Исто така, 119

121 постојат два датума кои треба да се чуваат Ова нè наведува да декларираме два нови типа и тоа тип што ќе манипулира со датуми: struct DateType int month; int day; int year; ; и тип на податок кој ги опишува статистичките податоци: struct StatisticsType float failrate; DateType lastserviced; int downdays; ; така што, главниот слог ги вклучува двата горенаведени типa на податоци: struct MachineRec int idnumber; string description; StatisticsType history; DateType purchasedate; float cost; ; MachineRec machine; На овој начин, содржината на слогот е поочигледна На компонентите на слогот им се пристапува на сличен начин како кај нехиерархиски слогови со dot нотација На пример, machinepurchasedate machinepurchasedatemonth machinehistorylast Servicedyear ; 120

122 XII Низи (Arrays) Во многу проблеми, структурите на податоци имаат многу компоненти кои е тешко да се процесираат, ако секоја од компонентите има различно име Во оваа глава разгледуваме типови на податоци низи Еднодимензионални низи Ако сакаме да внесеме 1000 целобројни вредности кои сакаме да ги печатиме во обратен редослед од редоследот на внесувањето, можеме да ја напишеме следнава програма: //************************************************************************ // ReverseNumbers program //************************************************************************ #include <iostream> using namespace std; int main( ) int value0; int value1; int value2; int value999; cin >> value0; cin >> value1; cin >> value2; cin >> value999; cout << value999 << endl; cout << value998 << endl; cout << value997 << endl; cout << value0 << endl; return 0; Оваа програма има преку 3000 линии (1000 за декларации за внос за излез) и во него се користат 1000 променливи Очигледно е дека имињата на променливите се слични и тие се од ист тип Би било практично ако ставиме број во променлива-бројач и користиме For циклуси кои одат од 0 до 999 и потоа од 999 назад 121

123 до 0 На пример, ако името на бројачот е number, можеме да замениме горните 2000 I/O инструкции со следните 4 линии од код: for (number = 0; number < 1000; number++) cin >> value[number]; for (number = 999; number >= 0; number--) cout << value[number] << endl; Овие четири линии од код се коректни во C++, ако гo декларираме value да биде еднодимензионална низа која е множество од променливи од ист тип, при што првиот дел од името на променливата е ист, по што следува индекс затворен во средни загради Декларацијата на еднодимензионална низа е слична со декларацијата на проста променлива, со еден исклучок: мора да се декларира должината на низата За горниот пример: int value[1000]; Оваа декларација креира низа од 1000 компоненти, сите од тип int Првата компонента има вредност на индексот 0, втората компонента 1 и така натаму сè до последната компонента која има индексна вредност 999 Следува комплетниот код на ReverseNumbers програмата кој користи низа //************************************************************************ // ReverseNumbers program //************************************************************************ #include <iostream> using namespace std; int main( ) int value[1000]; int number; for (number = 0; number < 1000; number++) cin >> value[number]; for (number = 999; number >= 0; number--) cout >> value[number] << endl; return 0; 122

124 Како структура на податоци, низата се разликува од struct во две суштински карактеристики: 1 низата е хомогена структура на податоци (сите компоненти се од ист тип на податоци), додека struct е хетерогена структура (нејзините компоненти може да бидат од различни типови на податоци); 2 на компонента на низата се пристапува преку позицијата на компонентата во низата, додека на компонента во struct се пристапува со dot нотација преку името на членот Декларирање на низи Еднодимензионална низа е структуирано множество од компоненти (елементи на низата) на кои може да им се пристапи индивидуално со специфицирање на позицијата на компонентата преку индексот Синтактичкиот шаблон за декларирање на еднодимензионална низа е: Тип на податок- Име на низа [ConstIntIzraz] Компонентите на низата може да бидат од каков било тип на податок, но овде ние разгледуваме само компоненти од прости типови на податоци ConstIntIzraz е целоброен (интегер) израз составен само од литерали или именувани константи Тој мора да има вредност поголема од 0 Ако вредноста на ConstIntIzraz е n рангот на вредности на индексот е 0 до n-1, а не од 1 до n На пример, декларациите: float angle[4]; int testscore[10]; креираат низи прикажани на следната слика (сл 121): 123

125 angle[0] angle[1] angle[2] angle[3] angle testscore[0] testscore[1] testscore[2] testscore[3] testscore[4] testscore[5] testscore[6] testscore[7] testscore[8] testscore[9] testscore sl 121 Низата angle има четири компоненти, секоја од нив со можност да чува една float вредност Низата testscore има вкупно десет компоненти, сите од тип int Пристап на индивидуални компоненти За да пристапиме на компонента од низа, го пишуваме името на низата по кое следи израз во средни загради Вредноста на изразот специфицира на која компонента сакаме да & пристапиме Синтактичкиот шаблон за пристап кон компонента на низа е: Име на низа [IndexIzraz] IndexIzraz може да биде константа, променлива, аритметички израз или повик на функција Изразот мора да резултира со целобројна вредност, инаку настанува имплицитна конверзија (коерција) во интегер Наједноставна вредност на IndexIzraz е константа Користејќи ја angle низата, секвенцата на инструкции за доделување: angle[0] = 493; angle[1] = -152; angle[2] = 05; angle[3] = 167; ги полни компонентите на низата (сл122) 124

126 angle angle[0] 493 angle[1] -152 angle[2] angle[3] sl 122 Секоја компонента на низата, на пример angle[2], може да биде третирана на ист начин како која било проста променлива од тип float На пример: angle[2] = 96; cin >> angle[2]; cout << angle[2]; y = sqrt(angle[2]); x = 68 * angle[2] + 75; доделување на вредност вчитување вредност во неа печатење на нејзината вредност аргумент на функција користење во аритметички израз Да ги погледнеме индексните изрази кои се покомплицирани од константите Да претпоставиме дека сме декларирале низа од 1000 елементи од int вредности со инструкцијата int value[1000]; и ги извршуваме следниве две инструкции: value[counter] = 5; if (value[number + 1] % 10!= 0) Во првата инструкција на компонентана низата е доделен бројот 5 Ако counter е 0, бројот 5 е доделен на првата компонента од низата Ако counter е 1, бројот 5 се доделува на втората компонента од низата итн Во втората инструкција, изразот number + 1 селектира компонента од низата Компонентата на која & е пристапено се дели со 10 и се проверува дали остатокот е 125

127 ненулти Ако number + 1 е 0, ја тестираме првата компонента од низата, ако number + 1 е 1 ја тестираме втората компонента итн String класата дозволува пристап на индивидуални карактери во стрингот: string astring; astring = Hello ; cout << astring[1]; // Pecati e Иако личи на низа, типот на податок string е класа Користејќи ја C++ техниката operator overloading, на операторот [ ] му дава друго значење селектирање на компонента на стринг, покрај неговото стандардно значење селектирање на елемент на низа Индекси надвор од границите на низата Нека е дадена декларацијата float alpha[100]; Рангот на вредности на индексот е 0 до 99 Ако извршиме инструкција alpha[i] = 624; кога i е помало од 0 или i е поголемо од 99, тогаш пристапуваме кoн мемориска локација надвор од низата C++ не проверува дали индексот на низата е во декларираните граници На пример, ако i = 100 во горната инструкција, компјутерот доделува 624 во мемориската локација која следува по крајот на низата и со тоа ја уништува вредноста која била содржана на таа локација Индекс на низата надвор од граници е вредност на индексот во C++ кој е или помал од 0 или поголем од должината на низата 1 Алгоритмите кои процесираат низи често користат For циклуси за процесирање на елементите еден по еден Следувa алгоритам кој ги сетира на 0 стоте елементи од низата alpha (i е int променлива): for (i = 0; i < 100; i++) alpha[i] = 00; Иницијализирање на низа во декларација int delta = 25; Видовме дека C++ дозволува иницијализирање на променлива во декларација: 126

128 Вредноста 25 се нарекува иницијализатор Исто така, може да се иницијализира низа во декларација, користејќи специјална синтакса за иницијализаторот Се специфицира листа на иницијални вредности за елементите на низата, елементите се разделуваат со, и листата се затвора во големи загради: int age[5] = 23, 10, 16, 37, 12; Во оваа декларација, age[0] се иницијализира на 23, age[1] на 10 итн Ако во горниот пример се специфицираат повеќе од пет вредности, компајлерот ќе сигнализира синтактичка грешка Ако се специфицираат помалку од пет вредности, останатите елементи се иницијализираат на 0 Статичка низа (било да е глобална или декларирана како static во блок) се иницијализира само еднаш Автоматска низа (локална недекларирана како static) се реиницијализира секојпат кога контролата минува низ декларацијата Интересна карактеристика на C++ e дека е дозволено да се изостави должината на низата кога таа се иницијализира во декларација: float temperature[ ] = 00, 11237, 986; Компајлерот ја открива должината според бројот на иницијални вредности во листата Агрегатни операции на низи Во претходната глава дефиниравме агрегатни операции како операции на структури на податоци како целина C++ не дозволува агрегатни операции на низи За декларациите: int x[50]; int y[50]; не е дозволено агрегатно доделување: x = y; // Nedozvoleno Доделувањето се врши компонента по компонента: for (index = 0; index < 50; index++) x[index] = y[index]; Не е дозволено агрегатно споредување: if (x == y) // Nedozvoleno Ниту извршување на агрегатни I/O на низи: cout << x; // Nedozvoleno Не се дозволени никакви агрегатни аритметички операции: x = x + y; // Nedozvoleno 127

129 Конечно, не е дозволено да се врати цела низа како вредност од функција која враќа вредност: return x; // Nedozvoleno Единствена агрегатна операција што може да се изврши врз низа е да се предаде низата како аргумент на функција Тогаш функцијата добива пристап на целата низа Примери на декларирање и пристапување на низи Како прв пример, разгледуваме број на жители во една зграда која има 100 станови const int BUILDING_SIZE = 100; // Broj na stanovi int occupants[building_size]; // occupants[i] e broj na stanari vo stan i-1 int totaloccupants; // Vkupen broj na stanari vo zgradata int counter; // brojac na ciklusot i indeksna promenliva На пример, ако occupants[0] = 3 кажува дека во првиот стан има 3 станари, occupants[1] = 5 кажува дека во вториот стан живеат 5 станари итн Ако овие вредности се чуваат во низа, тогаш следниот сегмент го пресметува вкупниот број на станари во зградата: totaloccupants = 0; for (counter = 0; counter < BUILDING_SIZE; counter++) totaloccupants = totaloccupants + occupants[counter]; Може да се забележи дека интервалот на counter е од 0 до 99, при што се кумулира бројот на станарите од првиот стан (counter = 0) до последниот (стоти) стан (counter = 99) Најчесто индексот во низата е од тип int Меѓутоа C++ дозволува користење и на enumeration тип на податок Следниот пример прикажува низа во која индексите се вредности од enumeration тип enum Drink ORANGE, COLA, BEER, APPLE, CHERRY, LEMON; float salesamt[6]; // Niza od 6 float broevi koja se indeksira so tip Drink Drink flavor; // Promenliva za indeks 128

130 Енумераторите ORANGE, COLA,, LEMON имаат интерна интегер репрезентација од 0 до 5, salesamt е низа од 6 float вредности кои означуваат цена на секој вид на пијалак Следниот код ги печати цените кои се содржат во низата for (flavor = ORANGE; flavor <= LEMON; flavor = Drink( flavor + 1 )) cout << salesamt[flavor] << endl; Во последниот пример разгледуваме низа од описни оценки (A, B, C, D, F) на 10 студенти const int NUM_STUDENTS = 10; char grade [NUM_STUDENTS]; // Niza od 10 oceni int idnumber; Следуваат неколку примери кои покажуваат како низата може да се користи cin >> grade[2]; // Go cita sledniot printabilen karakter i go smestuva vo element od //nizata so indeks 2 grade[3] = A ; // Dodeluva karakter A na element od nizata so indeks 3 IdNumber = 5; // Dodeluva 5 na indeksnata promenliva idnumber Grade[idNumber] = C // Dodeluva karakter C na komponenta od nizata indeksirana so // idnumber (vo ovoj slucaj 5) for (idnumber = 0; idnumber < 10; idnumber++) cout << grade[idnumber]; // Za ovoj ciklus izlezot moze da bide // FBCAFCAACB for (idnumber = 0; idnumber < 10; idnumber++) cout << Student << idnumber << Grade << grade[idnumber] << endl; // Za ovoj ciklus izlezot e pocitliv Во последниот пример излезот би бил: Student 0 Grade F Student 1 Grade B Student 9 Grade B 129

131 Предавање на низи како аргументи По default (ако не е наведено со &) променливите од прости типови се пренесуваат по вредност Ако сакаме во функцијата да ја промениме вредноста на променливата, ја пренесуваме по референца (прикачуваме & на типот на податок на променливата во листата на параметри на функцијата) На пример: int SomeFunc( float param1, // Prenos po vrednost char& param2) // Prenos po referenca Низите како аргументи секогаш се пренесуваат по референца и притоа не се користи знакот & за да реферира дека низата се пренесува по референца Кога низата се пренесува како аргумент, нејзината базна адреса (base address), која е мемориска адреса на првиот елемент од низата, се испраќа на функцијата Тогаш функцијата знае каде е лоцирана актуелната низа која ја испраќа повикувачот и може да пристапи на секој елемент од низата Следната е C++ функција која сетира на нула float низа со произволна должина: Void ZeroOut( /*out*/ float arr[], /*in*/ int numelements) int i; for (i = 0; i < numelements; i++) arr[i] = 00; Во листата на параметри, декларацијата на arr не вклучува должина на низата Дури и да се вклучи должина, компајлерот ја игнорира Компајлерот го интересира само дали arr е низа, а не и нејзината должина За да работи циклусот во функцијата, мора како аргумент да се пренесе уште еден аргумент кој го означува бројот на елементи во низата numelements Повикувачкиот код може да ја повика ZeroOut за float низа со која било должина Следниот код ја повикува функцијата да сетира на 0 две низи со различни должини void ZeroOut (float[ ], int); // Prototip na funkcijata 130

132 int main( ) float velocity[30]; float refractionangle[9000]; ZeroOut(velocity, 30); ZeroOut(refractionAngle, 9000); Со прости променливи, пренесувањето на аргумент по вредност ја штити вредноста на променливата во повикувачот од несакана промена во функцијата Низите мора да се пренесуваат по референца За да се заштити низата во повикувачот од несакани промени, во функцијата таа се декларира како константа На пример, следната функција копира една низа во друга void Copy( /*out*/ int destination[], /*in*/ const int source[], /*in*/ int size) int i; for (i = 0; i < size; i++) destination[i] = source[i]; Зборот const гарантира дека кој било обид да се промени содржината на source низата ќе резултира со грешка при компилација Низи од слогови Како пример, да дефинираме книга за оценки, која претставува множество од слогови (записи) на студенти како што следува: const int MAX_STUDENTS = 150; enum GradeType A, B, C, D, F; struct StudentRec 131

133 string stuname; float gpa; int examscore[4]; GradeType coursegrade; ; StudentRec gradebook[max_students]; Елемент од gradebook е селектиран со индекс На пример, gradebook[2] е третата компонента од низата gradebook Секоја компонента од gradebook е слог (struct) од тип StudentRec За да пристапиме на coursegrade на третиот студент го користиме следниов израз: GradeBook[2]courseGrade Компонентата на слогот gradebook[2]examscore е низа За да пристапиме на првата компонента од низата, пишуваме: GradeBook[2]examScore[0] Следниот код ги печати имињата на секој студент: for (count = 0; count < MAX_STUDENTS; count++) cout << gradebook[count]stuname << endl; Дводимензионални низи Дводимензионалните низи се користат за претставување елементи во табели со редови и колони На компонента во дводимензионалните низи може да се пристапи со специфицирање на индексите на редот и на колоната во кои се наоѓа елементот Дводимензионална низа е множество од компоненти, сите од ист тип структуирани во две димензии На секоја компонента & се пристапува со пар на индекси кои ја претставуваат локацијата на елементот Синтактичкиот шаблон за декларирање на дводимензионална низа е: Тип на податок Име на низа [ConstIntExpression] [ConstIntExpression] На пример: const int NUM_ROWS = 100; const int NUM_COLS = 9; float alpha [NUM_ROWS] [NUM_COLS]; 132

134 Овој пример ја декларира alpha како дводимензионална низа (матрица) на која сите компоненти се од тип float Инструкцијата alpha[0] [5] = 364; доделува вредност 364 на елементот во ред 0 и колона 5 Да погледнеме неколку примери int hitemp [52] [7]; е декларација за матрица со 52 реда и 7 колони Нека редовите ги претставуваат неделите во годината, а колоните деновите во неделата Во секое поле од матрицата се чува највисоката температура во соодветниот ден Ако сакаме да ги печатиме највисоките температури во деновите од третата недела од годината, тоа го постигнуваме со следниов код: int hitemp [52] [7]; int day; for (day = 0; day < 7; day++) cout << << hitemp[2] [day]; Како следен пример разгледуваме матрица чии индекси се енумератори enum Colors RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET; enum Makes FORD, TOYOTA, HYUNDAI, JAGUAR, CITROEN, BMW, FIAT, SAAB; const int NUM_COLORS = 7; const int NUM_MAKES = 8; float crashrating[num_colors] [NUM_MAKES]; //Verojatnost na sudir vo funkcija od //boja i model crashrating [BLUE] [JAGUAR] = 083; crashrating [RED] [FORD] = 019; Процесирање на дводимензионални низи Процесирање или пристапување на податоци во матрица може да се врши на еден од следниве четири начина: - случаен (random) пристап; - пристап по редови; - пристап по колони; - пристап по цела матрица Случаен пристап имаме кога пристапуваме на случаен елемент од матрицата со давање произволни вредности на индексите Разгледуваме четири примери на процесирање на матрица: 133

135 1 сумирање на редови; 2 сумирање на колони; 3 иницијализација на матрицата со нули; 4 печатење на матрица Пред да ги разгледаме овие програмски сегменти, декларираме некои заеднички константи и променливи: const int NUM_ROWS = 50; const int NUM_COLS = 50; int arr[num_rows] [NUM_COLS]; int row; int col; int total; // Dvodimenzionalna niza // indeks za red // indeks za kolona // promenliva za sumata Сумирање редови Ако сакаме да направиме сума од елементите во четвртиот ред од матрицата, тоа го правиме со следниот сегмент: total = 0; for (col = 0; col < NUM_COLS; col++) total = total + arr[3] [col]; cout << Row sum << total << endl; Ако сакаме да направиме суми за два реда, третиот и четвртиот, тоа го правиме со вгнезден циклус: for (row = 2; row < 4; row++) total = 0; for (col = 0; col < NUM_COLS; col++) total = total + arr[row] [col]; cout << Row sum: << total << endl; На ваков начин може да се сумираат сите редови од матрицата Ако сакаме да сумираме елементи во редови од блок матрица со димензии (rowsfilled, colsfilled), тоа го изведуваме на следниов начин: for (row = 0; row < rowsfilled; row++) total = 0; 134

136 for (col = 0; col < colsfilled; col++) total = total + arr[row] [col]; cout << Row sum: << total << endl; Сумирање на колони Ако сакаме да ги сумираме колоните од една блок матрица со димензии (rowsfilled, colsfilled), тоа го вршиме на следниов начин: for (col = 0; col < colsfilled; col++) total = 0; for(row = 0; row < rowsfilled; row++) total = total + arr[row] [col]; cout << Column sum: << total << endl; Во овој случај, обратно од претходниот, надворешниот циклус ги контролира колоните, а внатрешниот редовите Иницијализирање на матрица Ако матрицата е со мали димензии, наједноставно е таа да се иницијализира во декларацијата За да иницијализираме матрица од два реда и три колони да изгледа вака: можеме да ја користиме следнава декларација: int arr[2] [3] = 14, 3, -5, 0, 46, 7 Во оваа декларација иницијализаторската листа се состои од два елемента, од кои секој е иницијализаторска листа Првата внатрешна иницијализаторска листа го иницијализира првиот ред, а втората листа го иницијализира вториот ред Ако матрицате е голема, непрактично е да се иницијализира во декларација На пример, ако матрицата е 100 реда со 100 колони, и вредностите се различни, најзгодно е 135

137 да се внесат во датотека од каде ќе се отчитуваат во run-time Ако вредностите се исти, вообичаен пристап е да се користи вгнезден циклус Ако сакаме да ги сетираме на 0 сите елементи од (NUM_ROWS, NUM_COLS) матрица, постапуваме на следниов начин: for (row = 0; row < NUM_ROWS; row++) for (col = 0; col < NUM_COLS; col++) arr[row] [col] = 0; Печатење на матрица Ако сакаме да отпечатиме матрица по еден ред во линија имаме: #include <iomanip> // Za setw( ) for (row = 0; row < NUM_ROWS; row++) for (col = 0; col < NUM_COLS; col++) cout << setw(15) << arr[row] [col]; cout << endl; Пренесување на матрица како аргумент Кога дводимензионална низа (матрица) се пренесува како аргумент, повторно базната адреса на матрицата на повикувачот се испраќа на функцијата, но не може да не се наведе должината на двете димензии Може да не се наведе должината на првата димензија (број на редови), но мора да се наведе должината на втората димензија (број на колони) Ова е така, затоа што матрицата во меморијата се чува во еднодимензионална низа На пример, ако имаме матрица beta за да го лоцира beta[1] [0], функцијата мора да го знае бројот на колони Така ако бројот на колони е 4, beta[1] [0] ќе дојде на на петтата локација сметајќи ја базната адреса како прва локација Значи во декларацијата на параметарот за матрица, секогаш треба да биде наведена втората димензија На пример: void AnotherFunc (/* inout */ int beta[ ] [4]) 136

138 Понатаму, бројот на колони на матрицата која повикувачот ја праќа на функцијата, мора да биде еднаков со бројот на колони на параметарот во функцијата За да се избегнат проблемите со несогласување на должините на аргументите и параметрите, се користи инструкцијата typedef, која дефинира тип дводимензионална низа и потоа да ги декларира и аргументот и параметарот да бидат од тој тип На пример: const int NUM_ROWS = 10; const int NUM_COLS = 20; typedef int ArrayType[NUM_ROWS] [NUM_COLS]; typedef инструкцијата наложува каде да се појави податокот ArrayType да биде заменет со int Следната функција доделува иницијална вредност на сите елементи од матрица со број на колони еднаков со NUM_COLS void Initialize (/*out*/arraytype arr, // Matrica koja treba da se inicijalizira /*in*/ int initval) // Inicijalna vrednost int row; int col; for (row = 0; row < NUM_ROWS; row++) for (col = 0; col < NUM_COLS; row++) arr[row] [col] = initval; 137

139 (lektoriran tekst) XV Поинтери, динамички податоци и референцни типови Поинтерите и референцните типови на податоци се атомски типови на податоци, но поради нивната намена се нарекуваат адресни типови на податоци и се водат посебно од другите атомски (прости) типови на податоци, како што се: integral, enum и float Променлива од еден од овие два типа на податоци не содржи вредност, туку мемориска адреса на друга променлива Адресните типови имаат две главни намени: - тие можат да ja направат програмaтa поефикаснa во смислa на брзинатa и користењeтo на меморијатa и - можат да бидат користени за конструирање на комплексни типови на податоци Поинтери Поинтер тип на податок е атомски тип на податок кој се состои од неограничено множество од вредности кои адресираат или покажуваат на локација на променлива од даден тип Меѓу операциите дефинирани на поинтери, можат да се наведат операциитe на доделување и тестирање за еднаквост Поинтер променливи Зборот pointer не се користи во декларирање на поинтер променлива Наместо него се користи симболот * Декларацијата: int* intptr означува дека intptr е променлива која содржи адреса на int променлива Следните се синтактички шаблони за декларирање на поинтер променлива: Тип на податок* променлива; Тип на податок *променлива1, *променлива2, ; Синтактичкиот шаблон покажува две форми, едната за декларирање на една променлива и втората за декларирање на повеќе променливи во една декларација Во првата форма за компајлерот е сеедно каде ѕвездичката е поставена, така што следниве две декларации се еквивалентни: int* intptr; int *intptr; 138

140 Во согласност со синтактичкиот шаблон, ако се декларираат повеќе променливи во една инструкција, на почетокот од името на секоја од променливите треба да се прикачи ѕвездичка Инаку, само првата променлива ќе биде третирана како поинтер променлива На пример декларацијата: int* p, q е еквивалентна на int* p; int q За да се избегнат грешки, најсигурно е секоја променлива да се декларира во посебна инструкција Ако се дадени декларациите: int beta; int* intptr можеме да направиме intptr да покажува на beta со користење на унарниот оператор & intptr = β Со оваа инструкција, мемориската адреса на beta се доделува на поинтер променливата intptr Да претпоставиме дека intptr и beta се лоцирани во мемориските адреси 5000 и 5008 респективно Со последната инструкција, мемориската адреса на beta (5008) се доделува на поинтер променливата intptr Ова доделување илустративно е прикажано на следната слика (сл 151) Бидејќи во општ случај мемориските адреси не му се познати на програмерот, односот меѓу поинтерот и променливата на која тој покажува се илустрира со правоаголници и стрелки како на слика 152 A dr esa Memor i ja I me na pr omenl i va intptr 5008 beta sl

141 intptr b e ta sl 152 За да се пристапи на променлива кон која покажува поинтерот, користиме унарен * оператор и операцијата се нарекува дереференцирање Така изразот *intptr ја означува променливата кон која покажува поинтерот Во нашиот пример intptr покажува на beta и инструкцијата *intptr = 28 го дереференцира intptr и доделува вредност 28 на beta Оваа инструкција претставува индиректно адресирање на beta Машината прво пристапува на поинтерот intptr, потоа ја користи неговата содржина да ја лоцира beta Обратно, инструкцијата beta = 28 претставува директно адресирање на beta Директното адресирање е како отворање на поштенско сандаче (на пример сандаче 15) и наоѓање на пакет, додека индиректното адресирање е како отворање на поштенско сандаче и наоѓање порака која кажува дека пакетот е во поштенско сандаче 23 Директно адресирање е пристапување на променливата во еден чекор со користење име на променливата Индиректно адресирање е пристапување на променливата во два чекорa со користење на поинтер кој ја дава локацијата на променливата Продолжувајќи со нашиот пример, имајќи ја предвид сл 151, инструкциите: *intptr = 28; cout << intptr << endl; cout << *intptr << endl; ќе дадат излез:

142 поинтер: Разгледуваме програмски сегмент кој вклучува повеќе променливи од тип enum ColorType RED, GREEN, BLUE; struct PatientRec int idnum; int height; int weight; ; int alpha; ColorType color; PatientRec patient; int* intptr = α ColorType* colorptr = &color; PatientRec* patientptr = &patient; Променливите intptr, colorptr, patientptr се поинтер променливи кои покажуваат кон променливи од различен тип Изразот *intptr ја означува променливата кон која покажува intptr Променливата кон која покажува intptr може да содржи која било целобројна (интегер) вредност Изразот colorptr означува променлива од тип ColorType Таа може да ги содржи само вредностите RED, GREEN или BLUE Изразот patientptr означува struct променлива од тип PatientRec Изразите (*patientptr)idnum, (*patientptr)height и (*patientptr)weight означуваат idnum, height и weight членови на *patientptr Може да се забележи дека кај изразите за пристап на членови во слог, дереференцирањето на слогот (struct) се става во загради по што следува dot нотацијата за пристап на член од слогот Заградите се неопходни, бидејќи dot операторот има повисок приоритет на извршување од дереференцирањето Така *patientptrweight би било интерпретирано погрешно како *(patientptrweight) Освен dot операторот, C++ располага со алтернативен оператор за селектирање на членови во слогови, унии и класи Тоа е -> или arrow операторот По дефиниција: PointerIzraz -> Ime na Clen е еквивалентно на (*PointerIzraz)Ime na Clen Значи: 141

143 patientptr -> weight е еквивалентно со (*patientptr)weight Се поставува прашање која од горните две варијанти да се користи при селекција на членови на структури Се препорачува dot нотацијата да се користи кога левиот операнд е структура, класа или унија, а arrow нотацијата кога левиот операнд е поинтер кон променлива од тип структура, класа или унија Ако имаме декларирано низа од поинтери кои покажуваат на низа од тип PatientRec PatientRec* patptrarray[20]; тогаш изразот patptrarray[3] -> idnum му пристапува на идентификациониот број на четвртиот пациент Следните инструкции се валидни: *intptr = 250; *colorptr = RED; patientptr -> idnum = 3245; patientptr -> height = 64; patientptrarray[3] -> idnum = 6356; patientptrarray[3] -> height = 73; patientptrarray[3] -> weight = 185; Поинтер изрази Порано видовме дека аритметичките изрази можат да содржат променливи, константи, оператори, симболи и загради Слично и поинтер изразите се составени од поинтер променливи, поинтер константи одредени дозволени оператори и загради Во C++ постои само една дозволена литерална поинтер константа: вредноста 0 Поинтер константата 0, наречена null pointer покажува кон ништо Инструкцијата: intptr = 0; доделува null pointer во intptr Оваа инструкција не предизвикува intptr да покажува кон мемориска локација 0 Null поинтерот не покажува кон ниту една мемориска адреса и затоа шематски го означуваме со следниот знак: intptr 142

144 Наместо користење на константата 0, повеќе програмери ја користат именуваната константа NULL која доаѓа од стандардната header датотека cstddef: #include <cstddef> intptr = NULL; Како што е случај со другите именувани константи, идентификаторот NULL ја прави програмата подокументирана Грешка е да се дереференцира null поинтер, затоа што тој не покажува кон никаква мемориска локација Тој се користи само како специјална вредност која програмата може да ја тестира како: if (intptr == NULL) DoSomething ( ); Иако 0 е единствена литерална константа од тип поинтер, постои друг поинтер израз кој може да се цени како како константен поинтер израз, а тоа е име на низа без индексни загради Вредноста на овој израз е базната адреса на низата Дадени декларации: int arr[100]; int* ptr; Инструкцијата на доделување ptr = arr; има ист ефект како и ptr = &arr[0]; Овие две инструкции ја доделуваат базната адреса на arr во ptr Име на низа без загради е поинтер израз Да го разгледаме кодот кој ја повикува функцијата ZeroOut за да ги сетира на 0 компонентите на низа чија должина е дадена како втор аргумент на функцијата: int main( ) float velocity[30]; ZeroOut (velocity, 30); Во функцискиот повик, името на низата без загради е поинтер израз Вредноста на овој израз е базната адреса на низата velocity Оваа адреса се испраќа на функцијата 143

145 Ние можеме да ја напишеме функцијата ZeroOut на еден од два начина Првиот начин ни е познат од порано декларирање на првиот параметар како низа со неспецифицирана должина Void ZeroOut (/* out */ float arr[ ], /* in */ int size) int i; for (i = 0; i < size; i++) arr [i] = 00; Алтернативно, првиот параметар може да го декларираме како float*, затоа што параметарот ја зема адресата на float променлива (адресата на првиот елемент од низата) Void ZeroOut (/* out */ float* arr, /* in */ int size) // Teloto na funkcijata e isto kako vo prethodniot primer Како и да го декларираме првиот параметар во функцијата, резултатот е ист за C++ компајлерот Во ZeroOut функцијата arr е проста променлива која покажува на почетокот на актуелната низа од повикувачот (сл153) Иако arr е поинтер променлива во ZeroOut функцијата, уште можеме да прикачиме индексен израз на името arr: arr[i] = 00; Индексирањето на поинтер променлива е можно поради следното правило во C++: Индексирањето е валидно за кој било поинтер израз, не само за име на низа (меѓутоа, индексирање на поинтер има смисла само ако поинтерот покажува на низа) 144

146 main f unkci ja [0] [1] [2] velocity ZeroOut f unkci ja arr size sl 153 Следната табела ги листа најчестите операции кои можат да бидат применети на поинтери: Оператор Значење Пример Забелешка = Доделување ptr = &somevar; Освен за null pointer ptr1 = ptr2; Двата операндa мора ptr = 0; да бидат од ист тип * Дереференцирање *ptr ==,!=, <, Релациони ptr1 == ptr2 Двата операндa мора <=, >, >= оператори да бидат од ист тип! Логичко не!ptr Резултатот е true, ако операндот е 0 (null pointer), инаку e false [ ] Индекс или ptr[4] Индексиран поинтер треба супскрипт да покажува на низа -> Селекција на ptr -> height Селектира член од struct, член класа или унија кон кои покажува поинтерот На пример, логичко не (!) може да биде користено да тестира за null поинтер: if (!ptr ) 145

147 DoSomething( ); што е еквивалентно со if (ptr == NULL) DoSomething( ); Треба да се има на ум дека операциите во горната табела се однесуваат на поинтери, а не на променливи на кои поинтерите покажуваат На пример, ако intptr1 и intptr1 се поинтер променливи од тип int*, тестот: if ( intptr1 == intptr2) споредува поинтери, а не променливи на кои тие покажуваат Со други зборови споредуваме адреси, а не интегер вредности Ако сакаме да ги споредуваме променливите на кои покажуваат поинтерите, инструкцијата е: if ( *intptr1 == *intptr2) Постојат и други операции врз поинтери како ++, --, +, -, +=, -= Овие се оператори на поинтери кои покажуваат на низа На пример, изразот ptr++ предизвикува поинтерот да покажува на следниот елемент од низата, ptr + 5 покажува на елемент од низата кој е за 5 елементи над елементот од низата на кој претходно покажувал поинтерот итн Динамички податоци Во претходниот текст опишавме две категории на податоци во C++: статички и автоматски податоци Стаички податоци се глобалните променливи и локалните променливи кои експлицитно се декларирани со клучниот збор static Животниот век на статичките променливи е ист со животниот век на програмата Сите други локални променливи се автоматски податоци и се уништуваат кога контролата го напушта блокот во кој се декларирани Со помош на поинтерите, C++ обезбедува трета категорија на податоци: динамички податоци Динамички податоци се променливи креирани за време на егзекуција на програмата со помош на специјални операции Во C++ овие операции се new и delete Операцијата new има две форми, една за алоцирање на единечна променлива и една за алоцирање на низа Следното е синтактички шаблон: new DataType new DataType [IntExpression] Првата форма се користи за креирање на единечна променлива од тип DataType Втората форма креира низа чии елементи се од тип DataType, при што бројот на 146

148 елементи на низата е даден со IntExpression Следното се примери кои ги даваат двете форми: int* intptr; char* namestr; intptr = new int; na namestr = new Char[6]; bazna // Kreira promenliva od tip int i ja dodeluva nejzinata adresa // intptr // Kreira niza od 6 char elementi i ja dodeluva nejzinata // adresa na namestr Операторот new прави две работи: креира неиницијализирана променлива (или низа) од бараниот тип и враќа поинтер на оваа променлива (или на базната адреса на низата) Променливите креирани со new се наоѓаат во слободниот дел на меморијата (heap) кој е резервиран за динамички променливи Динамичката променлива е неименувана и не може да биде директно адресирана Таа мора да биде индиректно адресирана преку поинтер вратен од new операторот #include <cstring> // Za funkcija strcpy( ) int* intptr = new int; char* namestr = new char[6]; *intptr = 357; strcpy(namestr, Ben ); Библиотечната функција strcpy бара два аргумента кои претставуваат базни адреси на две char низи За првиот аргумент, ја пренесуваме базната адреса на динамичката низа во слободната меморија, а за вториот аргумент компајлерот ја пренесува базната адреса на неименуваната локација, каде C стрингот Ben е лоциран Следниве слики (154а и 154b) го илустрираат горниот код 147

149 a) int* intptr = new int; char namestr = new char[6]; Free store intptr? namestr [0] [1] [2] [3] [4] [5]?????? b) *intptr = 357; strcpy(namestr, "Ben"); intptr 357 Free store namestr [0] [1] [2] [3] [4] [5] 'B' 'e' 'n' '\0'?? sl 154 Динамичките податоци можат да бидат уништени во кое било време на егзекуцијата на програмата, кога веќе нема потреба од нив Операторот delete се користи да уништи динамичка променлива И овој оператор има две форми во зависност од тоа дали брише единечна променлива или низа Синтактичкиот шаблон е: delete Pointer delete [ ] Pointer Користејќи го претходниот пример, можеме да ги уништиме (деалоцираме) динамичките податоци на кои покажуваат intptr и namestr со инструкциите: delete intptr; delete [ ] namestr; По извршување на овие инструкции, вредностите на intptr и namestr се недефинирани Тие можат, но и не мораат уште да покажуваат на деалоцираните податоци Пред да ги користиме овие поинтери повторно, мора да им се доделат нови вредности (те да им се доделат нови мемориски адреси) Операцијата delete не го брише поинтерот Таа ја брише променливата на која покажува поинтерот Кога се користи операторот delete, треба да се имаат на ум две работи: 1 извршување delete на null поинтер е безефектна инструкција; 2 операторот delete мора да се приложи само на поинтер вредност која била добиена претходно од new операторот Второто правило е важно Ако се приложи delete на произволна мемориска адреса, која не е во слободната меморија, резултатот е недефиниран Конечно, треба да се има на ум дека причината за користење на динамички податоци е да се заштеди 148

150 мемориски простор Затоа е важно по завршувањето на користење на динамичката променлива таа да биде избришана Ако се чуваат динамичките променливи кога веќе не се потребни, настанува ситуација наречена протекување на меморијата (memory leak) Ако ова се случува често, може да останеме без меморија Да погледнеме уште еден пример на користење на динамички податоци int* ptr1 = new int; int* ptr2 = new int; // Kreira dinamicka promenliva // Kreira dinamicka promenliva *ptr2 = 44; *ptr1 = *ptr2; ptr1 = ptr2; delete ptr2; // Dodeluva vrednost na dinamicka promenliva // Kopira edna dinamicka promenliva vo druga // Kopira eden pointer vo drug // Unistuva dinamicka promenliva Секоја инструкција од овој пример е графички поткрепена на сл 155 На сл 155d, по извршување на претпоследната инструкција од горниот програмски сегмент, може да се забележи дека променливата на која претходно покажуваше ptr1 е уште присутна Меѓутоа, на неа не може да & се пристапи, бидејќи не постои поинтер кој покажува (реферира) на неа Ваква изолирана променлива се нарекува непристапен објект и е причина за мемориско течење (memory leak) Исто така, на сл 155е може да се забележи дека по последната инструкција ptr1 покажува на променлива која повеќе не постои Ваков поинтер се нарекува висечки поинтер Ако програмата подоцна се обиде да го дереференцира ptr1, резултатот е непредвидлив Непристапен објект е динамичка променлива во слободниот мемориски простор на која не реферира ниеден поинтер Висечки поинтер е поинтер кој покажува на променлива која веќе е уништена (деалоцирана) 149

151 a) int* ptr1 = new int; int* ptr2 = new int; ptr1? ptr2? INICIJALNI USLOVI d) ptr1 = ptr2; ptr1 ptr2 *ptr1? *ptr2? ptr1 ptr b) *ptr2 = 44; ptr1 ptr2 *ptr1? *ptr2 44 ptr1 ptr2 e) delete ptr2; 44 c) *ptr1 = *ptr2; ptr1 *ptr1 44 ptr2 *ptr2 44 sl 155 Непристапниот објект и висечкиот поинтер се логички грешки За да се избегнат овие несакани појави во горниот код, треба да се вметнат две нови инструкции како што следува И овој код графички е поткрепен на сл 156 int* ptr1 = new int; int* ptr2 = new int; *ptr2 = 44; *ptr1 = *ptr2; delete ptr1; // Izbegnuva formiranje na nepristapen objekt 150

152 ptr1 = ptr2; delete ptr2; ptr1 = NULL; // Izbegnuva formiranje na visecki pointer ptr1? ptr2? INICIJALNI USLOVI d) delete ptr1 ptr1? ptr2 *ptr2 a) int* ptr1 = new int; int* ptr2 = new int; ptr1 *ptr1 e) ptr1 = ptr2; ptr1? ptr2 *ptr2? ptr2 *ptr1 *ptr2 44 b) *ptr2 = 44; ptr1 *ptr1? f) delete ptr2; ptr1 ptr2 *ptr2 44 ptr2? c) *ptr1 = *ptr2; ptr1 *ptr1 g) ptr1 = NULL; ptr1 44 ptr2 *ptr2 ptr2 44 sl 156 Референцни типови Исто како и поинтер променливите, референцните променливи содржат адреси на други променливи Изразот int& intref; декларира дека intref е променлива што може да содржи адреса на int променлива Следува синтактички шаблон за декларирање на референцна променлива: Тип на податок& Променлива; Тип на податок &Променлива, &Променлива,; 151

153 Иако и референцните променливи и поинтерите содржат адреси на податочни објекти, има две фундаментални разлики Прво, операторот за дереференцирање (*) и операторот за доделување адреса (&) не се користат со референцни променливи По декларирање на референцна променлива, компајлерот ја дереференцира секоја појава на таа референцна променлива Оваа разлика е илустрирана со следниот пример: Користење на референцна променлива Користење на поинтер променлива int gamma = 26; int gamma = 26; int& intref = gamma; int* intptr = γ // intref pokazuva na gamma // intptr pokazuva na gamma intref = 35; *intptr = 35; // gamma ==35 // gama == 35 intref = intref + 3; *intptr = *intptr + 3; // gamma == 38 // gamma == 38 Како што може да се забележи, сè што се работи на intref, фактички се случува на gamma Втора разлика меѓу референцна и понтер променлива е дека компајлерот ја третира референцната променлива како константен поинтер Значи, единствена операција што се случува на референцна променлива е нејзината иницијализација Во овој контекст, C++ ја дефинира иницијализацијата како: a) експлицитна иницијализација во декларација; b) имплицитна иницијализација со предавање на аргумент на параметар; c) имплицитна иницијализација со враќање на вредност на функција На пример, инструкцијата: intref++; не ја инкрементира променливата intref, туку променливата кон која intref покажува, затоа што компајлерот имплицитно ја дереференцира секоја појава на името intref Референцен тип е прост (атомски) тип на податок кој се состои од неограничено множество на вредности од кои секоја е адреса на променлива од дадениот тип Единствена операција дефинирана на референцна променлива е иницијализација, по која секоја појава на променливата имплицитно се дереференцира Вообичаено користење на референцните променливи е да предадат ненизови аргументи по референца Да претпоставиме дека програмерот сака да ја промени содржината на две float променливи со повикот на функција: Swap( alpha, beta); Постојат две опции за дизајнирање на функцијата Swap 152

154 Првата опција е функцијата повикувач да ги прати мемориските адреси нa alpha и beta експлицитно Swap(&alpha, &beta); при што функцијата мора да ги декларира параметрите да бидат поинтер променливи: void Swap (float* px, float* py) float temp = *px; *px = *py; *py = temp; Втората опција е да се користат референцни променливи за да се елиминира потребата од експлицитно дереференцирање: void Swap (float& x, float& y) float temp = x; x = y; y = temp; Во овој случај, функцискиот повик не бара оператор & за аргументите: Swap (alpha, beta); Kompajlerot implicitno generira kod da gi prati adresite, a ne содржината na alpha и beta 153

C++ Programming: From Problem Analysis to Program Design, Fifth Edition. Chapter 3: Input/Output

C++ Programming: From Problem Analysis to Program Design, Fifth Edition. Chapter 3: Input/Output C++ Programming: From Problem Analysis to Program Design, Fifth Edition Chapter 3: Input/Output Objectives In this chapter, you will: Learn what a stream is and examine input and output streams Explore

More information

C++ Input/Output: Streams

C++ Input/Output: Streams C++ Input/Output: Streams 1 The basic data type for I/O in C++ is the stream. C++ incorporates a complex hierarchy of stream types. The most basic stream types are the standard input/output streams: istream

More information

Melbourne 21st - 30th September. Perth 6th October. Newcastle 6th October. Auckland 13th - 14th October. Sydney 24th - 25th November

Melbourne 21st - 30th September. Perth 6th October. Newcastle 6th October. Auckland 13th - 14th October. Sydney 24th - 25th November MFF2012_A2_poster.indd 2 9/16/2012 9:54:24 PM Australasian premiere of Milcho Manchevski s award winning masterpiece Mothers Melbourne 21st - 30th September Perth 6th October Newcastle 6th October Auckland

More information

Implementation of Supply Chain Management (SCM) in pharmaceutical company, general principles and case study

Implementation of Supply Chain Management (SCM) in pharmaceutical company, general principles and case study Macedonian pharmaceutical bulletin, 60 (2) 75-82 (2014) ISSN 1409-8695 UDC: 658.86/.87:661.12 Case study Implementation of Supply Chain Management (SCM) in pharmaceutical company, general principles and

More information

Simple C++ Programs. Engineering Problem Solving with C++, Etter/Ingber. Dev-C++ Dev-C++ Windows Friendly Exit. The C++ Programming Language

Simple C++ Programs. Engineering Problem Solving with C++, Etter/Ingber. Dev-C++ Dev-C++ Windows Friendly Exit. The C++ Programming Language Simple C++ Programs Engineering Problem Solving with C++, Etter/Ingber Chapter 2 Simple C++ Programs Program Structure Constants and Variables C++ Operators Standard Input and Output Basic Functions from

More information

Basics of I/O Streams and File I/O

Basics of I/O Streams and File I/O Basics of This is like a cheat sheet for file I/O in C++. It summarizes the steps you must take to do basic I/O to and from files, with only a tiny bit of explanation. It is not a replacement for reading

More information

SEIZURES AFTER USE AND ABUSE OF TRAMADOL. University Toxicology Clinic, Skopje, R. Macedonia 2. University Neurology Clinic, Skopje, R.

SEIZURES AFTER USE AND ABUSE OF TRAMADOL. University Toxicology Clinic, Skopje, R. Macedonia 2. University Neurology Clinic, Skopje, R. Prilozi, Odd. biol. med. nauki, MANU, XXXIII, 1, s. 313 318 (2012) Contributions, Sec. Biol. Med. Sci., MASA, XXXIII, 1, p. 313 318 (2012) ISSN 0351 3254 UDC: 615.212.3.065:616.853 CASE REPORT SEIZURES

More information

Answers to Selected Exercises

Answers to Selected Exercises DalePhatANS_complete 8/18/04 10:30 AM Page 1049 Answers to Selected Exercises Chapter 1 Exam Preparation Exercises 1. a. v, b. i, c. viii, d. iii, e. iv, f. vii, g. vi, h. ii. 2. Analysis and specification,

More information

THREE PERIODS OF HEALTH SYSTEM REFORMS IN THE REPUBLIC OF MACEDONIA (1991 2011)

THREE PERIODS OF HEALTH SYSTEM REFORMS IN THE REPUBLIC OF MACEDONIA (1991 2011) Prilozi, Odd. biol. med. nauki, MANU, XXXIII, 2, s. 175 189 (2012) Contributions, Sec. Biol. Med. Sci., MASA, XXXIII, 2, p. 175 189 (2012) ISSN 0351 3254 UDK: 614.2:005.591.4(497.7)"1991/2011" THREE PERIODS

More information

70 th fiaf Congress 04 th 10 th May 2014. Skopje. Newsletter No.2

70 th fiaf Congress 04 th 10 th May 2014. Skopje. Newsletter No.2 Newsletter No.2 70 th fiaf Congress 04 th 10 th May 2014 Skopje Министерство за култура на Република Македонија Ministry of Culture of the Republic of Macedonia Кинотека на Македонија Cinematheque of Macedonia

More information

EX.VTP.MK.02.01 FAVV-AFSCA 1/5

EX.VTP.MK.02.01 FAVV-AFSCA 1/5 ВЕТЕРИНАРНО ЗДРАВСТВЕН СЕРТИФИКАТ ЗА МЕСО ОД ЖИВИНА ЗА УВОЗ ВО РЕПУБЛИКА МАКЕДОНИЈА Health Certificate for meat of poultry (POU) for dispatch to the Republic of Macedonia Certificat sanitaire pour les

More information

Member Functions of the istream Class

Member Functions of the istream Class Member Functions of the istream Class The extraction operator is of limited use because it always uses whitespace to delimit its reads of the input stream. It cannot be used to read those whitespace characters,

More information

Parte I: Informazioni sulla partita spedita /Дел I: Детали за испратената пратка

Parte I: Informazioni sulla partita spedita /Дел I: Детали за испратената пратка CERTIFICATO VETERINARIO ВЕТЕРИНАРНО ЗДРАВСТВЕН СЕРТИФИКАТ Health Certificate MP-PR/ MP-PR per i prodotti a base di carne e stomaci, vesciche ed intestini trattati destinati all esportazione verso la Repubblica

More information

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement? 1. Distinguish & and && operators. PART-A Questions 2. How does an enumerated statement differ from a typedef statement? 3. What are the various members of a class? 4. Who can access the protected members

More information

Lab 2 - CMPS 1043, Computer Science I Introduction to File Input/Output (I/O) Projects and Solutions (C++)

Lab 2 - CMPS 1043, Computer Science I Introduction to File Input/Output (I/O) Projects and Solutions (C++) Lab 2 - CMPS 1043, Computer Science I Introduction to File Input/Output (I/O) Projects and Solutions (C++) (Revised from http://msdn.microsoft.com/en-us/library/bb384842.aspx) * Keep this information to

More information

7.7 Case Study: Calculating Depreciation

7.7 Case Study: Calculating Depreciation 7.7 Case Study: Calculating Depreciation 1 7.7 Case Study: Calculating Depreciation PROBLEM Depreciation is a decrease in the value over time of some asset due to wear and tear, decay, declining price,

More information

Ubuntu. Ubuntu. C++ Overview. Ubuntu. History of C++ Major Features of C++

Ubuntu. Ubuntu. C++ Overview. Ubuntu. History of C++ Major Features of C++ Ubuntu You will develop your course projects in C++ under Ubuntu Linux. If your home computer or laptop is running under Windows, an easy and painless way of installing Ubuntu is Wubi: http://www.ubuntu.com/download/desktop/windowsinstaller

More information

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program. Name: Class: Date: Exam #1 - Prep True/False Indicate whether the statement is true or false. 1. Programming is the process of writing a computer program in a language that the computer can respond to

More information

The University of Alabama in Huntsville Electrical and Computer Engineering CPE 112 01 Test #4 November 20, 2002. True or False (2 points each)

The University of Alabama in Huntsville Electrical and Computer Engineering CPE 112 01 Test #4 November 20, 2002. True or False (2 points each) True or False (2 points each) The University of Alabama in Huntsville Electrical and Computer Engineering CPE 112 01 Test #4 November 20, 2002 1. Using global variables is better style than using local

More information

Passing 1D arrays to functions.

Passing 1D arrays to functions. Passing 1D arrays to functions. In C++ arrays can only be reference parameters. It is not possible to pass an array by value. Therefore, the ampersand (&) is omitted. What is actually passed to the function,

More information

Appendix K Introduction to Microsoft Visual C++ 6.0

Appendix K Introduction to Microsoft Visual C++ 6.0 Appendix K Introduction to Microsoft Visual C++ 6.0 This appendix serves as a quick reference for performing the following operations using the Microsoft Visual C++ integrated development environment (IDE):

More information

LEAD DISTRIBUTION IN SOIL DUE TO LITHOGENIC AND ANTHROPOGENIC FACTORS IN THE BREGALNICA RIVER BASIN

LEAD DISTRIBUTION IN SOIL DUE TO LITHOGENIC AND ANTHROPOGENIC FACTORS IN THE BREGALNICA RIVER BASIN 289 Geologica Macedonica, Vol. 29, No. 1, pp. 53 61 (2015) GEOME 2 In print: ISSN 0352 1206 Manuscript received: Април 1, 2015 On line: ISSN 1857 8586 Accepted: Април 30, 2015 UDC: 504.3:622.343.445(497.73)

More information

C++ Language Tutorial

C++ Language Tutorial cplusplus.com C++ Language Tutorial Written by: Juan Soulié Last revision: June, 2007 Available online at: http://www.cplusplus.com/doc/tutorial/ The online version is constantly revised and may contain

More information

Compiler Construction

Compiler Construction Compiler Construction Lecture 1 - An Overview 2003 Robert M. Siegfried All rights reserved A few basic definitions Translate - v, a.to turn into one s own language or another. b. to transform or turn from

More information

Fondamenti di C++ - Cay Horstmann 1

Fondamenti di C++ - Cay Horstmann 1 Fondamenti di C++ - Cay Horstmann 1 Review Exercises R10.1 Line 2: Can't assign int to int* Line 4: Can't assign Employee* to Employee Line 6: Can't apply -> to object Line 7: Can't delete object Line

More information

A brief introduction to C++ and Interfacing with Excel

A brief introduction to C++ and Interfacing with Excel A brief introduction to C++ and Interfacing with Excel ANDREW L. HAZEL School of Mathematics, The University of Manchester Oxford Road, Manchester, M13 9PL, UK CONTENTS 1 Contents 1 Introduction 3 1.1

More information

Formatting Numbers with C++ Output Streams

Formatting Numbers with C++ Output Streams Formatting Numbers with C++ Output Streams David Kieras, EECS Dept., Univ. of Michigan Revised for EECS 381, Winter 2004. Using the output operator with C++ streams is generally easy as pie, with the only

More information

An Incomplete C++ Primer. University of Wyoming MA 5310

An Incomplete C++ Primer. University of Wyoming MA 5310 An Incomplete C++ Primer University of Wyoming MA 5310 Professor Craig C. Douglas http://www.mgnet.org/~douglas/classes/na-sc/notes/c++primer.pdf C++ is a legacy programming language, as is other languages

More information

Chapter One Introduction to Programming

Chapter One Introduction to Programming Chapter One Introduction to Programming 1-1 Algorithm and Flowchart Algorithm is a step-by-step procedure for calculation. More precisely, algorithm is an effective method expressed as a finite list of

More information

Pemrograman Dasar. Basic Elements Of Java

Pemrograman Dasar. Basic Elements Of Java Pemrograman Dasar Basic Elements Of Java Compiling and Running a Java Application 2 Portable Java Application 3 Java Platform Platform: hardware or software environment in which a program runs. Oracle

More information

1. The First Visual C++ Program

1. The First Visual C++ Program 1. The First Visual C++ Program Application and name it as HelloWorld, and unselect the Create directory for solution. Press [OK] button to confirm. 2. Select Application Setting in the Win32 Application

More information

El Dorado Union High School District Educational Services

El Dorado Union High School District Educational Services El Dorado Union High School District Course of Study Information Page Course Title: ACE Computer Programming II (#495) Rationale: A continuum of courses, including advanced classes in technology is needed.

More information

The C++ Language. Loops. ! Recall that a loop is another of the four basic programming language structures

The C++ Language. Loops. ! Recall that a loop is another of the four basic programming language structures The C++ Language Loops Loops! Recall that a loop is another of the four basic programming language structures Repeat statements until some condition is false. Condition False True Statement1 2 1 Loops

More information

Answers to Review Questions Chapter 7

Answers to Review Questions Chapter 7 Answers to Review Questions Chapter 7 1. The size declarator is used in a definition of an array to indicate the number of elements the array will have. A subscript is used to access a specific element

More information

The little endl that couldn t

The little endl that couldn t This is a pre-publication draft of the column I wrote for the November- December 1995 issue of the C++ Report. Pre-publication means this is what I sent to the Report, but it may not be exactly the same

More information

Object-Oriented Programming in Java

Object-Oriented Programming in Java CSCI/CMPE 3326 Object-Oriented Programming in Java Class, object, member field and method, final constant, format specifier, file I/O Dongchul Kim Department of Computer Science University of Texas Rio

More information

C++ Essentials. Sharam Hekmat PragSoft Corporation www.pragsoft.com

C++ Essentials. Sharam Hekmat PragSoft Corporation www.pragsoft.com C++ Essentials Sharam Hekmat PragSoft Corporation www.pragsoft.com Contents Contents Preface 1. Preliminaries 1 A Simple C++ Program 2 Compiling a Simple C++ Program 3 How C++ Compilation Works 4 Variables

More information

C++ Outline. cout << "Enter two integers: "; int x, y; cin >> x >> y; cout << "The sum is: " << x + y << \n ;

C++ Outline. cout << Enter two integers: ; int x, y; cin >> x >> y; cout << The sum is:  << x + y << \n ; C++ Outline Notes taken from: - Drake, Caleb. EECS 370 Course Notes, University of Illinois Chicago, Spring 97. Chapters 9, 10, 11, 13.1 & 13.2 - Horstman, Cay S. Mastering Object-Oriented Design in C++.

More information

While Loop. 6. Iteration

While Loop. 6. Iteration While Loop 1 Loop - a control structure that causes a set of statements to be executed repeatedly, (reiterated). While statement - most versatile type of loop in C++ false while boolean expression true

More information

THE POSSIBILITY OF EDUCATION ABOUT RELIGIOUS CULTURE IN PUBLIC SCHOOLS

THE POSSIBILITY OF EDUCATION ABOUT RELIGIOUS CULTURE IN PUBLIC SCHOOLS Originalni naučni rad Inoue Nobutaka 1 UDK: 37.032:2(520) THE POSSIBILITY OF EDUCATION ABOUT RELIGIOUS CULTURE IN PUBLIC SCHOOLS I Recent Argument on Religious Education in Japan Arguments on religious

More information

Sequential Program Execution

Sequential Program Execution Sequential Program Execution Quick Start Compile step once always g++ -o Realtor1 Realtor1.cpp mkdir labs cd labs Execute step mkdir 1 Realtor1 cd 1 cp../0/realtor.cpp Realtor1.cpp Submit step cp /samples/csc/155/labs/1/*.

More information

Comp151. Definitions & Declarations

Comp151. Definitions & Declarations Comp151 Definitions & Declarations Example: Definition /* reverse_printcpp */ #include #include using namespace std; int global_var = 23; // global variable definition void reverse_print(const

More information

CpSc212 Goddard Notes Chapter 6. Yet More on Classes. We discuss the problems of comparing, copying, passing, outputting, and destructing

CpSc212 Goddard Notes Chapter 6. Yet More on Classes. We discuss the problems of comparing, copying, passing, outputting, and destructing CpSc212 Goddard Notes Chapter 6 Yet More on Classes We discuss the problems of comparing, copying, passing, outputting, and destructing objects. 6.1 Object Storage, Allocation and Destructors Some objects

More information

! " # $ %& %' ( ) ) *%%+, -..*/ *%%+ - 0 ) 1 2 1

!  # $ %& %' ( ) ) *%%+, -..*/ *%%+ - 0 ) 1 2 1 !" #$%&%'())*%%+,-..*/*%%+- 0 )12 1 *!" 34 5 6 * #& ) 7 8 5)# 97&)8 5)# 9 : & ; < 5 11 8 1 5)=19 7 19 : 0 5)=1 ) & & >) ) >) 1? 5)= 19 7 19 : # )! #"&@)1 # )? 1 1#& 5)=19719:# 1 5)=9 7 9 : 11 0 #) 5 A

More information

Integrating the C++ Standard Template Library Into the Undergraduate Computer Science Curriculum

Integrating the C++ Standard Template Library Into the Undergraduate Computer Science Curriculum Integrating the C++ Standard Template Library Into the Undergraduate Computer Science Curriculum James P. Kelsh [email protected] Roger Y. Lee [email protected] Department of Computer Science Central

More information

What is a Loop? Pretest Loops in C++ Types of Loop Testing. Count-controlled loops. Loops can be...

What is a Loop? Pretest Loops in C++ Types of Loop Testing. Count-controlled loops. Loops can be... What is a Loop? CSC Intermediate Programming Looping A loop is a repetition control structure It causes a single statement or a group of statements to be executed repeatedly It uses a condition to control

More information

Chapter 9 Text Files User Defined Data Types User Defined Header Files

Chapter 9 Text Files User Defined Data Types User Defined Header Files Chapter 9 Text Files User Defined Data Types User Defined Header Files 9-1 Using Text Files in Your C++ Programs 1. A text file is a file containing data you wish to use in your program. A text file does

More information

Lecture 3. Arrays. Name of array. c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] Position number of the element within array c

Lecture 3. Arrays. Name of array. c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] Position number of the element within array c Lecture 3 Data structures arrays structs C strings: array of chars Arrays as parameters to functions Multiple subscripted arrays Structs as parameters to functions Default arguments Inline functions Redirection

More information

COSC 181 Foundations of Computer Programming. Class 6

COSC 181 Foundations of Computer Programming. Class 6 COSC 181 Foundations of Computer Programming Class 6 Defining the GradeBook Class Line 9 17 //GradeBook class definition class GradeBook { public: //function that displays a message void displaymessage()

More information

Flow-Based Anomaly Intrusion Detection System Using Two Neural Network Stages

Flow-Based Anomaly Intrusion Detection System Using Two Neural Network Stages UNIVERSITY OF BELGRADE FACULTY OF ELECTRICAL ENGINEERING Yousef H. Abuadlla Flow-Based Anomaly Intrusion Detection System Using Two Neural Network Stages Doctoral Dissertation Belgrade, 2014 UNIVERZITET

More information

The Payroll Program. Payroll

The Payroll Program. Payroll The Program 1 The following example is a simple payroll program that illustrates most of the core elements of the C++ language covered in sections 3 through 6 of the course notes. During the term, a formal

More information

On Supervised and Unsupervised Discretization 1

On Supervised and Unsupervised Discretization 1 БЪЛГАРСКА АКАДЕМИЯ НА НАУКИТЕ. BULGARIAN ACADEMY OF SCIENCES КИБЕРНЕТИКА И ИНФОРМАЦИОННИ ТЕХНОЛОГИИ Том 2, 2 CYBERNETICS AND INFORMATION TECHNOLOGIES Volume 2, No 2 София. 2002. Sofia On Supervised and

More information

Chapter 2: Elements of Java

Chapter 2: Elements of Java Chapter 2: Elements of Java Basic components of a Java program Primitive data types Arithmetic expressions Type casting. The String type (introduction) Basic I/O statements Importing packages. 1 Introduction

More information

Using C++ File Streams

Using C++ File Streams Using C++ File Streams David Kieras, EECS Dept., Univ. of Michigan Revised for EECS 381, 9/20/2012 File streams are a lot like cin and cout In Standard C++, you can do I/O to and from disk files very much

More information

Appendix M: Introduction to Microsoft Visual C++ 2010 Express Edition

Appendix M: Introduction to Microsoft Visual C++ 2010 Express Edition Appendix M: Introduction to Microsoft Visual C++ 2010 Express Edition This book may be ordered from Addison-Wesley in a value pack that includes Microsoft Visual C++ 2010 Express Edition. Visual C++ 2010

More information

Scanner sc = new Scanner(System.in); // scanner for the keyboard. Scanner sc = new Scanner(System.in); // scanner for the keyboard

Scanner sc = new Scanner(System.in); // scanner for the keyboard. Scanner sc = new Scanner(System.in); // scanner for the keyboard INPUT & OUTPUT I/O Example Using keyboard input for characters import java.util.scanner; class Echo{ public static void main (String[] args) { Scanner sc = new Scanner(System.in); // scanner for the keyboard

More information

Computer Programming C++ Classes and Objects 15 th Lecture

Computer Programming C++ Classes and Objects 15 th Lecture Computer Programming C++ Classes and Objects 15 th Lecture 엄현상 (Eom, Hyeonsang) School of Computer Science and Engineering Seoul National University Copyrights 2013 Eom, Hyeonsang All Rights Reserved Outline

More information

Subject Name: Object Oriented Programming in C++ Subject Code: 2140705

Subject Name: Object Oriented Programming in C++ Subject Code: 2140705 Faculties: L.J. Institute of Engineering & Technology Semester: IV (2016) Subject Name: Object Oriented Programming in C++ Subject Code: 21405 Sr No UNIT - 1 : CONCEPTS OF OOCP Topics -Introduction OOCP,

More information

Learning Computer Programming using e-learning as a tool. A Thesis. Submitted to the Department of Computer Science and Engineering.

Learning Computer Programming using e-learning as a tool. A Thesis. Submitted to the Department of Computer Science and Engineering. Learning Computer Programming using e-learning as a tool. A Thesis Submitted to the Department of Computer Science and Engineering of BRAC University by Asharf Alam Student ID: 03101011 Md. Saddam Hossain

More information

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON PROBLEM SOLVING WITH SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON Addison Wesley Boston San Francisco New York London

More information

5 CLASSES CHAPTER. 5.1 Object-Oriented and Procedural Programming. 5.2 Classes and Objects 5.3 Sample Application: A Clock Class

5 CLASSES CHAPTER. 5.1 Object-Oriented and Procedural Programming. 5.2 Classes and Objects 5.3 Sample Application: A Clock Class CHAPTER 5 CLASSES class head class struct identifier base spec union class name 5.1 Object-Oriented and Procedural Programming 5.2 Classes and Objects 5.3 Sample Application: A Clock Class 5.4 Sample Application:

More information

Mechanics ISSN 1312-3823 Transport issue 3, 2011 Communications article 0553

Mechanics ISSN 1312-3823 Transport issue 3, 2011 Communications article 0553 Mechanics ISSN 1312-3823 Transport issue 3, 2011 Communications article 0553 Academic journal http://www.mtc-aj.com CALYPSO ELECTRONIC TICKETING TECHNOLOGY: THE CONTACTLESS STANDARD FOR A MODERN TRANSPORT

More information

Introduction to Java

Introduction to Java Introduction to Java The HelloWorld program Primitive data types Assignment and arithmetic operations User input Conditional statements Looping Arrays CSA0011 Matthew Xuereb 2008 1 Java Overview A high

More information

Building Java Programs

Building Java Programs Building Java Programs Chapter 3 Lecture 3-3: Interactive Programs w/ Scanner reading: 3.3-3.4 self-check: #16-19 exercises: #11 videos: Ch. 3 #4 Interactive programs We have written programs that print

More information

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas CS 110B - Rule Storage Classes Page 18-1 Attributes are distinctive features of a variable. Data type, int or double for example, is an attribute. Storage class is another attribute. There are four storage

More information

Building Java Programs

Building Java Programs Building Java Programs Chapter 3 Lecture 3-3: Interactive Programs w/ Scanner reading: 3.3-3.4 self-check: #16-19 exercises: #11 videos: Ch. 3 #4 Interactive programs We have written programs that print

More information

Topics. Parts of a Java Program. Topics (2) CS 146. Introduction To Computers And Java Chapter Objectives To understand:

Topics. Parts of a Java Program. Topics (2) CS 146. Introduction To Computers And Java Chapter Objectives To understand: Introduction to Programming and Algorithms Module 2 CS 146 Sam Houston State University Dr. Tim McGuire Introduction To Computers And Java Chapter Objectives To understand: the meaning and placement of

More information

Informatica e Sistemi in Tempo Reale

Informatica e Sistemi in Tempo Reale Informatica e Sistemi in Tempo Reale Introduction to C programming Giuseppe Lipari http://retis.sssup.it/~lipari Scuola Superiore Sant Anna Pisa October 25, 2010 G. Lipari (Scuola Superiore Sant Anna)

More information

Data Structures using OOP C++ Lecture 1

Data Structures using OOP C++ Lecture 1 References: 1. E Balagurusamy, Object Oriented Programming with C++, 4 th edition, McGraw-Hill 2008. 2. Robert Lafore, Object-Oriented Programming in C++, 4 th edition, 2002, SAMS publishing. 3. Robert

More information

QUIZ-II QUIZ-II. Chapter 5: Control Structures II (Repetition) Objectives. Objectives (cont d.) 20/11/2015. EEE 117 Computer Programming Fall-2015 1

QUIZ-II QUIZ-II. Chapter 5: Control Structures II (Repetition) Objectives. Objectives (cont d.) 20/11/2015. EEE 117 Computer Programming Fall-2015 1 QUIZ-II Write a program that mimics a calculator. The program should take as input two integers and the operation to be performed. It should then output the numbers, the operator, and the result. (For

More information

Assessing the Sensitivity of the Artificial Neural Network to Experimental Noise: A Case Study

Assessing the Sensitivity of the Artificial Neural Network to Experimental Noise: A Case Study Assessing the Sensitivity of the Artificial Neural Network to Experimental Noise: A Case Study Miloš J. Madić PhD Student University of Niš Faculty of Mechanical Engineering Velibor J. Marinković Full

More information

Illustration 1: Diagram of program function and data flow

Illustration 1: Diagram of program function and data flow The contract called for creation of a random access database of plumbing shops within the near perimeter of FIU Engineering school. The database features a rating number from 1-10 to offer a guideline

More information

Simple Image File Formats

Simple Image File Formats Chapter 2 Simple Image File Formats 2.1 Introduction The purpose of this lecture is to acquaint you with the simplest ideas in image file format design, and to get you ready for this week s assignment

More information

Syllabus OBJECT ORIENTED PROGRAMMING C++

Syllabus OBJECT ORIENTED PROGRAMMING C++ 1 Syllabus OBJECT ORIENTED PROGRAMMING C++ 1. Introduction : What is object oriented programming? Why do we need objectoriented. Programming characteristics of object-oriented languages. C and C++. 2.

More information

Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T)

Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T) Unit- I Introduction to c Language: C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating

More information

Introduction to Java. CS 3: Computer Programming in Java

Introduction to Java. CS 3: Computer Programming in Java Introduction to Java CS 3: Computer Programming in Java Objectives Begin with primitive data types Create a main class with helper methods Learn how to call built-in class methods and instance methods

More information

Binary storage of graphs and related data

Binary storage of graphs and related data EÖTVÖS LORÁND UNIVERSITY Faculty of Informatics Department of Algorithms and their Applications Binary storage of graphs and related data BSc thesis Author: Frantisek Csajka full-time student Informatics

More information

ANALYSIS Egg Database Analysis Tools

ANALYSIS Egg Database Analysis Tools 1 ANALYSIS INTRODUCTION 1 1. Introduction. ANALYSIS Egg Database Analysis Tools by John Walker http://www.fourmilab.ch/ This program is in the public domain. This program implements frequently-performed

More information

9 Control Statements. 9.1 Introduction. 9.2 Objectives. 9.3 Statements

9 Control Statements. 9.1 Introduction. 9.2 Objectives. 9.3 Statements 9 Control Statements 9.1 Introduction The normal flow of execution in a high level language is sequential, i.e., each statement is executed in the order of its appearance in the program. However, depending

More information

Myocardial Bridges: A Prospective Forensic Autopsy Study

Myocardial Bridges: A Prospective Forensic Autopsy Study DOI: 10.2298/SARH1504153M ОРИГИНАЛНИ РАД / ORIGINAL ARTICLE UDC: 616.12-007.2-091.5 153 Myocardial Bridges: A Prospective Forensic Autopsy Study Jelena Micić-Labudović 1, Tatjana Atanasijević 1, Vesna

More information

Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is

Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is Multichoice Quetions 1. Atributes a. are listed in the second part of the class box b. its time is preceded by a colon. c. its default value is preceded by an equal sign d. its name has undereline 2. Associations

More information

EP241 Computer Programming

EP241 Computer Programming EP241 Computer Programming Topic 10 Basic Classes Department of Engineering Physics University of Gaziantep Course web page www.gantep.edu.tr/~bingul/ep241 Sep 2013 Sayfa 1 Introduction In this lecture

More information

A Summary of Operator Overloading

A Summary of Operator Overloading A Summary of Operator Overloading David Kieras, EECS Dept., Univ. of Michigan Prepared for EECS 381 8/27/2013 Basic Idea You overload an operator in C++ by defining a function for the operator. Every operator

More information

PROGRAMMING IN C PROGRAMMING IN C CONTENT AT A GLANCE

PROGRAMMING IN C PROGRAMMING IN C CONTENT AT A GLANCE PROGRAMMING IN C CONTENT AT A GLANCE 1 MODULE 1 Unit 1 : Basics of Programming Unit 2 : Fundamentals Unit 3 : C Operators MODULE 2 unit 1 : Input Output Statements unit 2 : Control Structures unit 3 :

More information

Changes in Subgingival Microflora after Placement and Removal of Fixed Orthodontic Appliances

Changes in Subgingival Microflora after Placement and Removal of Fixed Orthodontic Appliances DOI: 10.2298/SARH1406301Z ОРИГИНАЛНИ РАД / ORIGINAL ARTICLE UDC: 616.314-089.28-06 ; 616.314-008.8:579.8 301 Changes in Subgingival Microflora after Placement and Removal of Fixed Orthodontic Appliances

More information

Reading and Writing PCD Files The PCD File Format The Grabber Interface Writing a Custom Grabber PCL :: I/O. Suat Gedikli, Nico Blodow

Reading and Writing PCD Files The PCD File Format The Grabber Interface Writing a Custom Grabber PCL :: I/O. Suat Gedikli, Nico Blodow PCL :: I/O Suat Gedikli, Nico Blodow July 1, 2011 Outline 1. Reading and Writing PCD Files 2. The PCD File Format 3. The Grabber Interface 4. Writing a Custom Grabber global functions in the namespace

More information

Course notes Standard C++ programming

Course notes Standard C++ programming Department of Cybernetics The University of Reading SE2B2 Further Computer Systems Course notes Standard C++ programming by Dr Virginie F. Ruiz November, 03 CREATING AND USING A COPY CONSTRUCTOR... 27

More information

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C Embedded Systems A Review of ANSI C and Considerations for Embedded C Programming Dr. Jeff Jackson Lecture 2-1 Review of ANSI C Topics Basic features of C C fundamentals Basic data types Expressions Selection

More information

J a v a Quiz (Unit 3, Test 0 Practice)

J a v a Quiz (Unit 3, Test 0 Practice) Computer Science S-111a: Intensive Introduction to Computer Science Using Java Handout #11 Your Name Teaching Fellow J a v a Quiz (Unit 3, Test 0 Practice) Multiple-choice questions are worth 2 points

More information

MANAGING CUSTOMER RELATIONSHIPS IN PRIVATE HEALTH CARE FACILITIES - A STUDY WITH REFERENCE TO GREATER NOIDA CITY OF UTTAR PRADESH

MANAGING CUSTOMER RELATIONSHIPS IN PRIVATE HEALTH CARE FACILITIES - A STUDY WITH REFERENCE TO GREATER NOIDA CITY OF UTTAR PRADESH www.sjm06.com Serbian Journal of Management 6 (1) (2011) 27-42 Serbian Journal of Management MANAGING CUSTOMER RELATIONSHIPS IN PRIVATE HEALTH CARE FACILITIES - A STUDY WITH REFERENCE TO GREATER NOIDA

More information

Objective-C Tutorial

Objective-C Tutorial Objective-C Tutorial OBJECTIVE-C TUTORIAL Simply Easy Learning by tutorialspoint.com tutorialspoint.com i ABOUT THE TUTORIAL Objective-c tutorial Objective-C is a general-purpose, object-oriented programming

More information

C PROGRAMMING FOR MATHEMATICAL COMPUTING

C PROGRAMMING FOR MATHEMATICAL COMPUTING UNIVERSITY OF CALICUT SCHOOL OF DISTANCE EDUCATION BSc MATHEMATICS (2011 Admission Onwards) VI Semester Elective Course C PROGRAMMING FOR MATHEMATICAL COMPUTING QUESTION BANK Multiple Choice Questions

More information

13 Classes & Objects with Constructors/Destructors

13 Classes & Objects with Constructors/Destructors 13 Classes & Objects with Constructors/Destructors 13.1 Introduction In object oriented programming, the emphasis is on data rather than function. Class is a way that binds the data & function together.

More information

Keil C51 Cross Compiler

Keil C51 Cross Compiler Keil C51 Cross Compiler ANSI C Compiler Generates fast compact code for the 8051 and it s derivatives Advantages of C over Assembler Do not need to know the microcontroller instruction set Register allocation

More information

MS ACCESS DATABASE DATA TYPES

MS ACCESS DATABASE DATA TYPES MS ACCESS DATABASE DATA TYPES Data Type Use For Size Text Memo Number Text or combinations of text and numbers, such as addresses. Also numbers that do not require calculations, such as phone numbers,

More information