vp-1 site predavanja 2008

Post on 21-Apr-2015

124 Views

Category:

Documents

6 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Предавања 1 (10.10.2008)

Професор доц. д‐р Илија Јолевски

Асистенти‐демонстраториЗлатко Стаматов (дипл. инф)Јулијана Талевска (дипл. инф)

Предавања и вежбиИнтернетПрепорачани книги

http://groups.yahoo.com/group/ti_vp1

ilija.jolevski@uklo.edu.mk

Посетни саати – кабинет 209

2 колоквиуми (8 и 15 недела во термин за предавања), илиПисмен испит

Дополнителни поени за редовност и активност

Решавање на задачи! (но самостално!)

Што ќе се научиВоведДизајн на програмиОсновиВлезно излезни податоциИтерацииФункцииНизи, типовиСтруктуриСортирање (подредување)...

Во програмскиот јазик C++

1. Решавање на проблемот2. Имплементација3. Одржување

АНАЛИЗА на проблемот и специфицирање што треба решението да обезбедуваРазвивање на ОПШТО РЕШЕНИЕ (АЛГОРИТАМ) за решавање на проблемотПРОВЕРКА дали решението го „решава“ проблемот

Секвенца е серија на наредби кои се извршуваат една по другаИзборот (разгранок ‐ branch) се користи за извршување на различни наредби во зависност од некои предусловиПовторување (репетиција) се користи за повторно извршување на наредби додека одредени услови се задоволениПодпрограма е помал дел од една програма

Наредба 1

Наредба 2

Наредба 3

Услов

Наредба 1

Наредба 2

Наредба 3

Подпрограм

Наредба 1

Наредба 2

Наредба 3

Вовед во програмирање 1

Предавањe 2 (17.10.2008)

Алгоритам

• Алгоритам претставува конечно множество на инструкции кои дефинираат секвенца на операции што треба да се извршат за да се реши даден проблем или тип на проблеми

• Својства на алгоритмите– Конечност (алгоритмот мора да заврши по конечен број на 

чекори)– Недвосмисленост (Секој чекор мора да е точно дефиниран и да 

има само една интерпретација)– Дефиниција на секвенца (Секој чекор има свој претходник и 

следбеник, почетокот и крајот се точно дефинирани)– Изводливост (Сите инструкции мора да се изводливи. Нема 

делење со нула!)– Влез (0 или повеќе вредности)– Излез (1 или повеќе вредности)

Алгоритам на Њутн‐Рафсон (Newton‐Raphson)

• 1. Влез: реален број X.• 2. Ако (X < 0) Тогаш• Излез: X “Не може да е негативен број."• СТОП.• Ако (крај)• 3. постави променлива, S, на вредност 1.0.• 4. постави бројчаник променлива, I, на 3.• 5. Додека (I > 0) Работи

– a. Пресметај ја вредноста на (S + X / S) / 2.0.– b. Постави го S на вредноста пресметана во чекор 5a.– c. Одземи 1 од I.

• Додека (крај)• 6. Излез: “Квадратен корен на " X " е приближно " S• 7. СТОП

Четири чекорен процес на решавање на проблеми (Поља 1887‐1985)

• Разбери го проблемот– Разбери ги границите на проблемот– Разбери ги ограничувањата на решението– Знај кои акции се дозволени

• Разработи план– Организирај ги размислувањата во детален алгоритам– Користи алатки како: нацрт, блок дијаграм и псеудокод

• Имплементирај го планот– Изврши ги чекорите во алгоритмот– Преведи го проблемот во јазик кој ќе го разбере уредот на кој што 

ќе се извршува• Тестирај го планот

– Дали рашението даде задоволителни резултати?– Дали решението може да биде подобрено?

Разбери го проблемот

• Што се податоците?• Кој е бараниот резултат?• Која е почетната точка (почетни податоци)?• Дали е возможно да се добие било какво решение со тие 

податоци?

• Добар приод: Решете го проблемот на рака

• Кои чекори ги употребивте? Ги запишавте?• Дали проблемот е поделен на големи делови?• Дали тие може да се идентификуваат? • Дали се направија некои претпоставки за проблемот?• Дали решението е доволно општо?

Разработи план

• Дали сте сретнале сличен проблем претходно?• Дали знаете сличен проблем чие што решение 

може да го искористите?– Дали може да се употреби дел од сличниот проблем– Дали решението на сличниот проблем може да се искористи

• Погледнете ги податоците... Повторувањата навестуваат и репетиции во решението

• Ако не можете да го решите целиот проблем , дали може да решите дел од проблемот?

Имплементирај го планот

• Провери го секој чекор од планот

• Дали ги разгледа сите специјални случаи?

• Дали добивате решение за „стандардни“ и „нестандардни“ влезни податоци

• Проверете дали вашето решение работи и за граничните случаи– Без влезни податоци, со многу податоци, делење со нула....

Тестирај го планот

• Дали при решавањето се пресметуваа вредности кои не се користат понатаму?– Дали може да се избегнат?

• Дали резултатот може да се добие и по друг пат?

• Дали решението може да се направи поедноставно или поопшто?

• Дали методот на решавање може да се искористи и за други проблеми?

Нивоа на програмски јазици

• Машински јазик (многу ниско ниво)– Составен од 1 и 0 претставени најчесто на хексадецимален начин

– Различен е за секоја машина– Сите програми мора да се напишани или преведени во машински јазик пред да се извршат

• Асемблер (ниско или средно ниво)– се користат кратки зборови за наредби (мнемоници)

Нивоа на програмски јазици (2)

• Јазици од високо ниво– Логични и релативно слични со англискиот јазик– Независни од хардверот (машината)– Мора да се преведат пред да се извршат (компајлираат или интерпретираат)

• Некои од јазиците од високо ниво:– COBOL, Fortran, Pascal, Ada– C, C++– Java– C#

Преведување на програмите

• Изворен код (SOURCE CODE)– Јазични инструкции од високо ниво напишани од програмерите

• Објектен – извршен код– Машински инструкции од ниско ниво кои ги извршува хардверот

Преведување на програмите (2)

Компајлирање Изворен кодКомпајлер 

или интерпретер

Објектен код

Поврзување (линкување) Објектен код Поврзување 

(линкер) Извршен код

Извршување Влезни податоци Извршен код Резултати

Дизајн „од горе‐надолу“

• Дизајн од горе‐надолу– Метод на решавање каде што проблемот се дели на помали под‐проблеми  кои понатаму се поделуваат на помали под‐проблеми се додека секој подпроблем не може да се реши со неколку чекори

• Проблем: Еден цел број N е „совршен“ ако е еднаков на сумата на сите негови делители 

• Подпроблемите на овој проблем би биле:1. Земи го бројот кој треба да биде тестиран2. Одреди ги делителите на бројот3. Провери дали делителите собрани заедно го даваат 

првиот број

Дизајн „од горе‐надолу“ (2)

1. Земи го бројот кој треба да се анализира1. Направи барање за внес на бројот2. Внеси го бројот. Нека се вика N3. Застани ако N е негативен

2. Одреди ги делителите на бројот1. Постави го делителот на 1 (еден сигурно го дели N)2. Провери го секој број (нека се вика D) од 1 до N/2 дали го 

дели N3. Провери ги резултатите

1. Ако сумата на делителите е еднаква на N1. N  е совршен

2. Ако не е 1. N   не е совршен

1. Земи го бројот кој треба да се анализира1. Излез: „Внесете позитивен цел број: “2. Внеси го бројот. Нека се вика N3. Ако N е негативен

1. Излез: „ N не е совршен“2. КРАЈ

2. Одреди ги делителите на бројот1. Постави ја сумата на делители на 1 (еден сигурно го дели 

N)2. Постави го D на 23. Додека D е помало од N\2

1. Ако  D е делител на N1. Додај го D на сумата на делители2. Зголеми го D  за 1

3. Провери ги резултатите1. Ако сумата на делителите е еднаква на N

1. Излез: „N  е совршен“2. Ако не е 

1. Излез: „N   не е совршен“3. КРАЈ

Зошто дизајнирање одгоре‐надолу?

• Основна идеја при решавањето на проблеми е нивна поделба на помали проблеми кои полесно се решаваат

• Во големи проекти помалите проблеми им се доделуваат на различни групи на програмери кои знаат како нивното решение се вклопува во целото решение на проблемот, а се релативно слободни при изработката на нивното решение

• Ако постои проблем кој не можете да го решите , тогаш постои и полесен проблем кој не можете да го решите. Најдете го.

Репрезентација на дизајни

• Нацрт

• Структурна репрезентација со график

• Псеудокод

Документирање на програмите

• Пишување на надворешна документација за секој програм пред неговото развивање е пример за добар процес на програмирање

• Надворешната документација најчесто го опишува програмот и работењето со влезни и излезни податоци од него.

• Внатрешната документација во форма на коментари во самиот изворен код се пишува во исто време со пишувањето на програмскиот код

• Пишувањето на добра документација треба да се смета за задолжителен и корисен дел од секој процес на развивање на софтвер

Категории на грешки при програмирање

• Синтаксни грешки (при компајлирање)– Грешката е во форма на наредбата: грешно напишани наредби, неспоени загради, заборавени запирки , итн...

– Грешката ја детектира компајлерот при компајлирање на програмата

– Компајлерот не може да ја отстрани грешката па ништо и не се креира со процесот на компајлирање

– Компајлерот ги запишува грешките но продолжува со компајлирање

Категории на грешки при програмирање (2)

• Грешки при линкување (поврзување)– Грешката вообичаено е во форма на декларација или имплементација на функција

– Грешката може да се појави при вклучување на погрешен хедер фајл

– Грешката је открива линкерот (откако компајлерот ќе направи објектен код)

– Линкерот не може да ја отстрани грешката па не може да се креира извршен фајл

– Линкерот ги запишува грешките но продолжува со работа

Категории на грешки при програмирање (3)

• Грешки при извршување– Грешката се појавува при извршување на програмата и предизвикува програмата да се „сруши“.  Се појавува порака за грешка од оперативниот систем.

– Грешките најчесто се некои недозволени наредби. Делење со нула или пак пристап до недозволени или недостапни ресурси

– Програмата се компајлира и линкува без проблеми– Програми со грешка различно се манифестираат на различни оперативни системи

Категории на грешки при програмирање (4)

• Логички грешки– Грешките се појавуваат при извршување на програмата и произведуваат неточни резултати, но не секогаш и „рушење“ на програмата

– Програмата се компајлира и линкува без проблеми– Логичките грешки се пронаоѓаат со проверка на резултатите кои ги дава програмата

– Предизвикувачите на овие грешки мора да се откријат со логичка анализа на грешката и изворниот код на програмата. Ова мора да го направи програмерот. 

– Овие грешки се најтешки за откривање и поправање

Процес на програмирање

Вовед во програмирање 1

Предавањe 3 (24.10.2008)

Основи

• C++ е базиран на C – Развиен е од BjarneStroustrup – AT&T Laboratories

• Стандардниот C++ е општ и независен од хардверот

• Развојни околини:– Microsoft Visual Studio

– DevC++

– Borland C++ Builder

Пример за костур на програма// Едноставна структура на C++ програма//#include <iostream> // директиви на пред-компајлерот#include <string> // вклучување на некој стандард#include <cstdlib> // библиотечни хедер датотекиusing namespace std; // “ја легализира“ содржината на хедерите

int main() { // почеток на функцијата main()const char COMMA = ','; // декларација на константиconst char SPACE = ' ';string FName, // декларација на променливи

LName;FName = "Bjarne"; // наредби за доделувањеLName = "Stroustrup";

// наредби за излез:cout << LName << COMMA << SPACE << FName << endl;

return EXIT_SUCCESS; // крај на програмата} // крај на функцијата main()

Синтакса и семантика• Синтакса

– (граматички) правила кои специфицираат како се пишуваат валидни инструкции

• Семантика– Правила кои ги објаснуваат значењата на синтаксно валидни инструкции

• Синтаксата на валидна инструкција за доделување на вредност е следна:

leva_vrednost = izraz;• Семантиката на инструкцијата за доделување е дека вредноста од 

десна страна се доделува на вредноста од лева страна

const int totalDays = 25567; // NOT an l-valueint daysPassed; // l-valuesint daysLeft;daysPassed = 17094;daysLeft = totalDays - daysPassed;

Резервирани зборови во C++

• C++ специфицира одреден број на зборови кои го дефинираат „официјалниот“ речник на програмскиот јазик

• Бројот на резервирани зборови е околу 300 и сите се напишани само со мали букви

Идентификатори• Идентификатор – име на објект (константа, променлива, функција) кој 

се користи во програма• Со идентификатори се именуваат мемориски локации во кои што се 

чуваат вредности на променливи или константи• Идентификаторите треба да имаат описно име. Не треба да се 

користат само 1‐2 знаци.• Кој од следните идентификатори е валиден?

3casanedelno Cetiri.triZbirNaOcenki Ime_prezimePlata denari Ime$

x-zraci 3.14Double N/4

I x2INT R2D2

Директиви

• Директивите му даваат инструкции на пред‐процесорот како да го измени вашиот програмски код пред да го предаде на компајлерот

• Директивите не генерираат програмски код• Најчеста употреба е вклучување на хедер (заглавија) 

датотеки#include <iostream>

• Со директивите можат да се дефинираат и идентификатори#define BROJ 100 // zameni go sekoepojavuvanje na BROJ so vrednosta 100

Едноставни податочни типови

• integer – позитивен или негативен цел број: 5280, ‐47, 0, +93143234– Три под‐типа: int, short, long

• real ‐ позитивен или негативен децимален број : 3.14159, 98.6, ‐3.45E04– Два под‐типа: float, double

• character ‐ буква, бројка, интерпункција, специјални симболи: 'x', ' ', '!', '\n‘– Еден под‐тип: char

• boolean – логичка вредност(true/falseточно/неточно)– Еден под‐тип: bool

Едноставни податочни типови (2)

• Репрезентација на целите броеви– Short е 2 бајти, int и long најчесто се 4 бајти

• Децималните броеви– Float 4 бајти, double 8 бајти– Децималните вредности се чуваат на различен начин од 

целите броеви (дури и 1.0)• Карактери (знаци)

– Char содржи еден знак– Се чува бинарната репрезентација на ASCII кодот на знакот– Char зафаќа 1 бајт

• Булеан– Bool променливите зафаќаат 1 бајт– Вредноста неточно не е секогаш нула!

string

• Стандардниот C++ содржи тип string со кој што можеме да чуваме низа од карактери

string Hamlet;Hamlet = "To be, or not to be, that is the question.";

• Бројот на карактери не е ограничен

• Типот string всушност е C++ класа

• Се декларира со хедер датотеката <string>

Променливи

• Променлива – локација во меморијата, референцирана по име,  каде што може да се чува ил именува вредност на некој податок

• Во С++ променливите прво треба да се декларираат пред да се користат

• Во декларацијата се наведува името на идентификаторот и неговиот тип

• Повеќе идентификатори од ист тип може да се декларираат наеднаш

type identifier1, identifier2, . . . identifierN;

• Примери:int Dolzina, Visina, Sirina;double SrednaOcenka, Prosek;char Ime;String Nasoka;

Иницијализација• Самата декларација автоматски не обезбедува почетна вредност за 

променливата• Ако променливата не се иницијализира таа ќе има „случајна“ 

вредност• Користење на неицијализирана променлива е честа причина за 

логички грешки• Добра пракса е секогаш да се иницијализира штотуку декларираната 

променлива

int Dolzina= 0,Visina= 0,Sirina = 0;double SrednaOcenka = 0.0, Prosek = 0.0;string Ime;Major = “Petar Petrovski";

Литерални Константи

• Литералните константи се егзактни броеви или знаци, како на пример

16 -45.5f "Freddy" 'M' 3.14159

• Децималните константи се дефинираат како double

3.14159 // type double, 8 bytes, ~15 digits3.14159F // type float, 4 types, ~7 digits

Именувани константи

• Именуваните константи се деклариаат и референцираат преку идентификатори

• Мора да се употреби клучниот збор const• Константите мора да се иницијализираат веднаш по 

декларацијата бидејќи потоа не може да им се промени вредноста

• Подобро е да се користат именувани отколку литерални константи

• Пракса е да се именуваат со СИТЕ ГОЛЕМИ букви

const int MAXITEMS = 100;const string NAME = "Fred Flintstone";const double PI = 3.141592654;const char NEWLINE = '\n';

Стандардни константи

• Константи за излез од програмата #include <cstdlib> //lokacija nastatusite

EXIT_SUCCESS EXIT_FAILURE

• Ограничувања на програмата#include <climits> //lokacija naimplementaciskite konstanti

INT_MIN INT_MAXLONG_MIN LONG_MAX

Наредби

• Наредбите се инструкции• Можат да бидат во еден или повеќе редови• Секоја наредба мора да заврши со „точка запирка“ ;

const float PI = 3.141596F;double Prosek;Prosek = vkupnoPoeni / vkupnoSaati;cout << “moeto ime e “ << ime << endl;

Доделување на вредности

• СинтаксаИдентификатор = израз;

• Во C++ знакот за еднакво „=“ не се користи за еднаквост туку за доделување на вредност

VkupenRezultat = VkupenRezultat + NoviPoeni;

X = X + 1

Користење на доделувања

• Треба да се внимава типот на вредноста да одговара на типот на променливата не која се доделува новата вредност (ова не е обавезно во C++)

• На следните примери типовите одговараатTezina= 123; // Vo red, int <--- intprosek = 7.5; // Vo red, double <--- doublePrezime = 'Li'; // Vo red, char <--- charFakultet = “TFB"; // Vo red, string <--- string

• Некои доделувања се нелогични иако типовите на променливи одговараат

Tezina = Sirina;

Коментари

• Пишувањето на внатрешна документација (коментари) е предвидена со две синтаксни решенија

/* nekakov komentar vo povekjelinii tekst */

// komentar vo edna linija

Аритметички операции во C++

Симбол Значење Пример Вредност

+ собирање 43+8 51

‐ Одземање 43.0 – 8.0 35.0

* Множење 43 * 8  344

/ Делење 43.0 / 8.0 5.375

% Модул (остаток) 43 % 8  3

‐ Унарен минус ‐43 ‐43

Приоритет при операциите се менува со додавање на загради !

Правила за приоритет кај аритметички операции

1. Изразите во загради се евалуираат прво,2. Унарен минус (‐)3. *, / , %4. + и –

• Операторите од исто ниво се евалуираат од лево – кон десно

• Правилата се исти како во математика!• Ако не сте сигурни за приоритетот ставете загради !

Имплицитни конверзии на тип на променлива

• Кога се доелува вредност на променлива од различен тип тогаш може да се јават грешки!• Кога се доделува децимална вредност на целобројна, вредноста се заокружува на 

најблискиот цел број

const int NUMTESTS = 2;double Test1 = 93.0,Test2 = 86.0;int testAverage;testAverage = (Test1 + Test2)/NUMTESTS; // testAverage <--- 89// not 89.5

• Кога целобројна вредност се доделува на децимална целобројната се проширува до децимална!

double Sum;int X = 17, Y = 25, Z = 42;Sum = X + Y + Z; // Sum <--- 84.0, not 84

Експлицитни конверзии на тип на променлива

• Кога се врши доделување меѓу различни типови на променливи програмерот може експлицитно да наведе кој тип на конверзија ќе се користи

const double PI = 3.141596224;double Radius = 1.432;int Circumference;Circumference = int(2.0 * PI * Radius);

• Изразот int(nekojIzraz) се користи за вредноста на nekojIzraz да се конвертира во integer (цел број)

• Програмерите треба да внимаваат да не направат логички грешки!

• Некои конверзии не се дозволени– string(17.2)

Мешани аритметички изрази

float X = 9.0/12; // vrednosta 0.75 e zapisanadouble Y = 5/2.0; // vrednosta 2.5 e zapisanaint A = 5,

B = 2;double Z = A/B; // vrednosta 2.0 e zapisana (Zosto?)

double Z = double(A) / double(B); // vrednosta 2.5 e zapisana

Оператори за инкрементирање и декрементирање

• Често се користи променлива за броење така да во C++ има оператор за додавање и одземање на 1

int x = 0,y = 7;x++; // isto kako x = x + 1;y--; // isto kako y = y - 1;

• X++ е постфикс• ++X е префикс

int x = 0, y = 7, z;z = y * x++; // z <--- 7 * 0z = y * ++x; // z <--- 7 * 1

Користење на постфикс и префикс

int x = 0, y = 7, z;z = y * x++; // 7 * 0 se evaluira, POTOA

// x <--- 1, I POTOA z <--- 0

z = y * ++x; // x <--- 1, togas 7 * 1 se evaluira

// I POTOA z <--- 7

• Префикс (++x), прво се зголемува x потоа се евалуира целиот израз

• Постфикс (x++), прво се евалуира целиот израз па потоа се зголемува x

Сложена наредба

• Ако имаме потреба да извршеме повеќе наредби во една целина тогаш наредбите ги групираме во една сложена наредба со помош на големи загради {  и  }

• Заградите се секогаш во пар! И се завршуваат со заграда, а НЕ со точка запирка (;)!

int main() { // slozena naredbaint x = 42;cout << "x = " << x;return 0;}

Операции со стрингови

• Стрингови може да се конкатенираат (собираат или лепат)

string Zdravo1 = “Dobar";string Zdravo2 = “den";string Pozdrav = Zdravo1 + ", " + Zdravo2 + '!';

• Оператор за конкатенација е плус (+)

Повикување на функции

• Повик на функција привремено го нарушува текот на извршување на програмата наредба по наредба 

• После извршувањето на функцијата текот се враќа и продолжува каде што застанал

Повикување на функции (2)#include <iostream>#include <cmath>using namespace std;

int main() {int Prv, Vtor, Razlika;cout << “Vnesete dva integeri: ";cin >> Prv >> Vtor;

Razlika = abs( Prv - Vtor );

cout << “Razlikata e “ << Razlika << endl;return 0;}

// implementacija na// funkcijata absint abs(int Value) {int absValue;if (Value < 0)

absValue = -Value;else

absValue = Value;return absValue;}

Вовед во програмирање 1

Предавањe 4 (31.10.2008)

Влез/Излез во C++ ‐ Стримови

• Основен податочен тип за влез/излез во C++ (I/O) е stream. (Стрим или поток)

• Основни подтипови се– istream cin – (преддефиниран за влез од тастатура)

– ostream cout – (преддефиниран за излез на екран)

• Треба да се вклучи <iostream> хедер датотеката 

Концептуален модел на стрим

• Преку стримовите се обезбедува врска помеѓу програмата и друг објект (на пример фајл) кој што може да се претстави како поток на податоци. Всушност стримот претставува сериализиран поглед на тој објект. 

Излез: оператор за вметнување• Печатење на екранот се обезбедува со операторот за 

излез• За да можеме да ги користиме стандардните I/O 

стримови треба да ја вметнеме пред‐компајлерската директива#include <iostream>

• За печатење на екран ја користиме наредба налик на оваа:cout << " X = " << X;– X е името на променливата чија што вредност сакане да ја 

испечатиме на екран• Операторот за вметнување << покажува во насоката на 

вметнување на податоците• Најлево мора да се наоѓа името на излезниот 

стрим/поток cout

Пример за излезconst string Labela = “izbrojani ovci: “;int vkupnoOvci= 127;cout << Labela << vkupnoOvci << endl;

• Не се обезбедува никакво автоматско форматирање на текстот, подредување, нов ред итн мора да се подесува од страна на програмерот

• endl е т.н. манипулатор• со помош на манипулатори се форматира текстот и 

можат да се користат само во наредби за влез/излез• endl вметнува нов ред (newline) и е дефиниран во <iostream>

Влез: оператор за внесување

• За внесување на потребните информации во програмата го користиме влезниот стрим

• За да можеме да го користиме треба претходно да се вметне соодветниот хедер– #include <iostream>

• Потоа читањето на влезни податоци од тастатура се прави на слидниот начин:– cin >> X;

• Операторот за влез >> ја покажува насоката на текот на информациите од стандардна конзола за влез кон променливата X

• Повеќе читања одеднаш можат да се направат последователни во еден израз

Примери за влез на податоци

• Под претпоставка дека на влез ќе ги внесеме следните податоци 12 17.3 -19int A, B;double X;cin >> A; // A <--- 12cin >> X; // X <--- 17.3cin >> B; // B <--- -19

int A, B;char C;cin >> A; // A <--- 12cin >> B; // B <--- 17cin >> C; // C <--- '.'cin >> A; // A <--- 3

int A;char B, C, D;cin >> A; // A <--- 12cin >> B; // B <--- '1'cin >> C; // C <--- '7'

Внесување на стрингови

• Со операторот на влез можеме да внесуваме и стрингови препознавајќи ги преку знаците за празно место (SPACE)

• Ако на влез ги имаме податоците: Gruev, Dame 718.23

string L, F;double X;cin >> L; // L <--- "Gruev,"cin >> F; // F <--- "Dame"cin >> X; // X <--- 718.23

Внесување на стрингови и препознавање на специјални знаци

• Најчестите специјални знаци се:

• C++ ги игнорира празните места кои се наоѓаат на почетокот на стрингот

Име Код

Нов ред (newline) \n

Табулатор (tab) \t

Празнина (blank) (space)

Вертикален таб (vertical tab) \v

Пример за влез

• Ако на влез го имаме следниот стринг:12 17.3 -19

• X е деклариран како int, и се повикува следната наредба cin >> X;

• Според типот на проемнливата X се одредува како ќе се прочитаат вредностите од влезната конзола.

• Прво сите почетни празни места се игнорираат, потоа бидејќи се чита цел број ќе се чита се додека не се стигне до знак кој не е бројка

• Ќе се извлечат бројките 1 и 2 од стримот и ќе се стигне до празното место

• Променливата X ќе добие вредност 12• Стримот ќе застане на празното место после 2

Функцијата ignore()

• Со помош на функцијата ignore() се изоставуваат (игнорираат) одреден број на знаци од влезниот стрим

• Наредбата cin.ignore(N, ch);– Значи да се прескокнат (да се прочитаат и игнорираат) до N знаци или пак додека не се стигне до знакот ch (било кое да е прво)

• Пример:– cin.ignore(80, '\n');– cin.ignore(100, '\t');

Интерактивен влез/излез

• На корисникот на програмата треба секогаш да му дадеме до знаење каков податок очекуваме од него:

const string LblVozrast = “Vnesete ja vasata vozrast: ";cout << PrasanjeVozrast ;cin >> Godini;

Стримови за влез/излез во фајлови (датотеки)

• Читање и запишување во фајлови се врши на сличен начин со помош на I/O стримовите

• Треба да се вметне хедерот #include <fstream>

• За разлика од преддефинираните cin и cout овде треба програмерот сам да ги дефинира променливитеifstream vlezenFajl; // objekt zavlez/citanje od fajl

ofstream izlezenFajl; // objekt zaizlez/zapisuvanje vo fajl

• Сите останати функции се исти или слични

Поврзување на стримовите со датотеките

• Кога ќе се креира стримот не е поврзан со ништо, заради тоа пред да се работи со него треба да се поврзи со соодветен фајл

inFile.open("procitajme.txt");outFile.open("zapisi.txt");

• За влезен фајл ако фајлот не постои ќе се јави грешка при извршување на програмата

• За излезен фајл ако фајлот не постои ќе се креира таков фајл

Функцијата close()

• Кога програмата нема потреба од фајлот за читање или запишување таа треба да го „ослободи“ фајлот. Тоа се прави со функцијата close()

inStream.close( );outStream.close( );

• Ставање на името на фајлот ќе предизвика грешка!• Со помош на оваа функција се известува 

оперативниот систем дека фајлот е ослободен и може други програми да го користат

• Секогаш треба да е внимава и да се затвора фајлот после секоја употреба

Функцијата eof()• Секој фајл завршува со специјален знак EOF (End Of File) кој 

претставува крај на фајлот• Eof() е булеан функција која враќа ТОЧНО (true) ако последната 

операција за читање го прочитала специјалниот знак т.е. Стигнала до крајот на документот

. . .Out << “Vkupno minuti: " << setw(5) << vkupnoVreme<< endl;

if ( !In.eof() ) {Out << endl<< “Se pojavi greska pri citanje od fajlot." << endl<< “Proverete go vlezniot dokument." << endl;}. . .

Форматирање на нумерички излез

• Треба да се вклучи хедерот со преддефинирани манипулатори <iomanip>

• setw()– Ја подесува ширината на полето во број на знаци– Влијае само на следната вредност

• setprecision()– Ја поставува прецисноста т.е. Бројот на децимални места во еден број 

– Влијае на сите float вредности после неа т.е. Додека не се стави нова setprecision()

Подредување

• Со подредување (justification) се местат знаците спрема дадено хоризонтално поле

cout << fixed << showpoint;string empName = "Flintstone, Fred";double Wage = 8.43;double Hours = 37.5;cout << left; //turn on left justificationcout << setw(20) << empName;cout << right; //turn on right justificationcout << setw(10) << setprecision(2) << Wage * Hours << endl;

• 012345678901234567890123456789• Flintstone, Fred 316.13

Пополнување (padding)

• Под пополнување или пединг се подразбира вметнување на карактери наместо празни места за да се обезбеди соодветен излез

• Ако поинаку не е сетирано се пополнува со знак за празни места (space)

• Овој знак се менува со setfill() манипулаторот

int ID = 413225;cout << "0123456789" << endl;cout << setw(10) << ID << endl;cout << setfill('0'); //popolnuvanje so nulicout << setw(10) << ID << endl;cout << setfill(' '); //resetiranje so prazni mesta

Со ова ќе добие:

Пример за манипулатори

Вовед во програмирање 1

Предавање 5 (05.11.2007)Предавање 5 (05.11.2007)

Булеан (bool) променливи и изразиБулеан (bool) променливи и изрази

• B l• Bool податочните типови можат да имаат една од двете вредности true (точно) и false (неточно)

• true и false се резервирани зборови во C++• Во C++ со цел да се постави (и одговори на) одредено прашање 

програмата поставува тврдење чија точност се проверува (евалуира) дали е точно или неточно

• На пример да го провериме тврдењето дека даден студент е постар од 18 години:

const int POLNOLETEN= 18;const int POLNOLETEN= 18;bool ePolnoleten;int studentGodini;cin >> studentGodini;ePolnoleten = (studentGodini >= POLNOLETEN);( );

• Вредноста на ePolnoleten сега може да се тестира и да се види дали е точна или неточна

Релациони изразиРелациони изрази

• Б ј• Булеан изразите можат најчесто да имаат две форми

• Првата форма се т.н. Релациони  Оператор Значење

еднаквостизрази: аритметички изрази споредени со даден релациски оператор, на пример:

== еднаквост

!= нееднаквост

> Поголемо од

( b * b - 4 * a * c ) > 0

В С ј 6

д

< Помало од

>= Поголемо или • Во С++ постојат 6 стандардни 

релациони операториеднакво на

<= Помало или еднакво на

• Со овие релациски оператори можат да се споредуваат две вредности од сите досега 

бразработени типови на податоци

Примери за релациони изрази• Со даденоconst int MAXPOENI = 100;char MI = 'L', MI2 = 'g';char MI L , MI2 g ;int Kviz1 = 18, Kviz2 = 6;int Bodovi1 = 76, Bodovi2 = 87;string Ime1 = "Filip" Ime2 = “Saso";string Ime1 = "Filip", Ime2 = Saso";

• Може да се евалуира

Kviz1 == Kviz2 Bodovi1 >= Bodovi2 Bodovi1 > MAXPOENI Bodovi1 + Kviz1 <= Bodovi2 + Kviz2 MI == MI2MI < MI2'Z' < 'a'Ime1 < Ime2Ime1 < Ime2

Логички изразиЛогички изрази

Л• Логички израз претставува логичко споредување на два булеан изрази (булеан израз после кој има логички оператор па пак има булеан израз)р р у р )

• C++ има три логички (булеан) оператори• Операторите && и || се бинарни бидејќи користат р р р ј р

два операнди, а операторот ! е унарен бидејќи користи еден операнд

Оператор Значење

! НЕ (негација)( ц ј )

&& И

|| ИЛИ

Семантика на логичките операториСемантика на логичките оператори

А !А

Точно неточноТочно неточно

Неточно точно

A B A&&B A B A||B

точно точно точно

точно неточно неточно

неточно точно неточно

точно точно точно

точно неточно точно

неточно точно точнонеточно точно неточно

неточно неточно неточно

неточно точно точно

неточно неточно неточно

Примери за логички изразиПримери за логички изрази

З• За даденоconst int MINVISINA = 142, MAXVISINA = 154;int FilipVisina, AnaVisina;int EmaVisina = 145;

• Ќе се евалуираЌе се евалуираMINVISINA <= EmaVisina && EmaVisina <= MAXVISINA ! (EmaVisina > MAXVISINA )// ќ б ? ?// кога следниот израз ќе биде точен? неточен?FilipVisina < MINVISINA || FilipVisina > MAXVISINA

• Два логички изрази се логички еквивалентни ако даваат ист резултат за сите вредности на променливите

Де Морганови закониДе Морганови закони• Ако А и В се логички изрази Де Моргановите закони велат• Ако А и В се логички изрази, Де Моргановите закони велат:! ( A && B ) <---> ( !A ) || ( !B )! ( A || B ) <---> ( !A ) && ( !B )

• Принципот на двојна негација вели:! ( !A ) <---> A

• Симболот <‐‐‐> претставува логичка еквиваленција

• Следната негација:!(FilipVisina < MINVISINA || FilipVisina > MAXVISINA )

• Може да се напише како:(FilipVisina >= MINVISINA && FilipVisina <= MAXVISINA )

Хиерархија на оператори во C++р р ј р р• Бидејќи во изразите можат да се комбинираат и логички и 

аритметички оператори постои една заедничка хиерархија нааритметички оператори постои една заедничка хиерархија на предност при евалуација

Изразите во заградите се евалуираат првоИзразите во заградите се евалуираат прво.1. (унарен) – !2. * / %3 +3. + -4. <= >= < >5. == !=6. &&7. ||8. =

Операторите во групите 2-7 се евалуираат од лево на десно но операторите во 1 и 8 се евалуираат од десно на лево

Примери• Дадено:int i = 3, k = 5,j 0 m 2;j = 0, m = -2;• Се евалуира:(0 < i) && (i < 5)(i > k) || (j < i)!(k > 0)3*i - 4/k < 23*i - 4/k < 2i + j < k(i > 0) && (j < 7)(i < k) || (j < 7)(m > 5) || (j > 0)

• Внимание:k = 4 // доделување, а не е еднаквост

//0 < i < 2 // дозволено... Но нема исто значење со математиката!!

Контролирање на текот на извршувањето

Т ј• Тек на извршување: редослед по кој се извршуваат наредбите во програмата

• Наредбите (ако поинаку не е специфицирано)• Наредбите (ако поинаку не е специфицирано) се извршуваат секвенцијално (една по друга)

cin >> x;c ;y = x * x + x + 1;cout << y << endl;

Контролна структура: израз со кој се изменува стандардниот тек на извршување на програмата

И б ј б ѓИзбор: контролна структура со која се избира помеѓу две или повеќе акции 

Избор: наредбата ifИзбор: наредбата if

• Н ј б C++ б if• Наједноставната структура за избор во C++ е наредбата if . Нејзината синтакса е:

If (ако) Булеан израз

If (ако) наредби

• Булеан изразот мора да е во загради а (ако) наредбите може да биде една наредба или пак сложена наредба {…}

• Семантиката е следна: Ако булеан изразот е точен се• Семантиката е следна: Ако булеан изразот е точен се извршува(ат) (ако) наредбите, ако не е точен не се извршува(ат)

if (Ocena == '10') {cout << "Bravo!";

}}

Избор: наредбата if elseИзбор: наредбата if…else

• структура за избор помеѓу две алтернативи во C++ е наредбата if…else . Нејзината синтакса е:

If (ако) Булеан If (ако) se Elsе se ElseIf (ако) Булеан израз

If (ако) наредби

Els Elsе Els Else 

наредби

Впвед вп прпграмираое 1

Предаваое 6 (12.11.2007)

Итерации• Итерација: извршуваое на мнпжествп на

наредби (телп) ппвеќе пати• Вп C++ има три начини да се креираат итерации• Заеднички свпјства за сите типпви на итерации се:

– Извршуваое (итерација) – еднп целпснп извршуваое на телптп на наредбите

– Влез вп јамката – местптп каде штп кпнтрплата на текпт на извршуваое на прпграмата преминува вп телптп на итерацијата

– Тест на јамката – местптп каде штп се прпверува дали да се пстане вп јамката или да се излезе пд неа

– Излез пд јамката – местп каде штп итерацијата завршува и се прпдплжува сп следната наредба ппсле јамката

– Услпв за прекинуваое – услпвпт кпј предизвикува итерацијата да застане

• Кпга креираме јамка треба сите пвие услпви јаснп да се дефинирани

• Еден пд најважните услпви е услпвпт за прекинуваое на итерациите

Јамката while• Синтакса:

• Семантика:

• Булеан изразпт се испитува при секпе ппминуваое низтелптп на јамката, акп лпгичкипт израз е тпчен тпгашппвтпрнп се ппминува низ наредбите пд телптп најамката, акп изразпт не е тпчен тпгаш се излегува пдјамката и се извршива првата наредба ппсле јамката

Пример за while

#include <iostream>

using namespace std;

int main() {

const char TOCKA= '.'; // 1

int brTocki; // 2

int brIspecateni = 0; // 3

cout << "Kolku tocki sakas? "; // 4

cin >> brTocki; // 5

while (brIspecateni < brTocki) { // 6

cout << TOCKA; // 7

brIspecateni++; // 8

}

cout << endl; // 9

return 0; // 10

}

Карактеристика на while јамката

• Впзмпжнп е телптп на јамката впппштп да не се изврши• Впзмпжнп е услпвпт на јамката да стане нетпчен, а

наредбите пд телптп на јамката да не се извршени сите. Дури и тпгаш ќе се извршат сите наредби па пптпа ќе се прпвери ппвтпрнп услпвпт на јамката.

• Услпвпт на јамката мпра да спдржи барем една прпменлива кпја се менува вп барем една наредба пд телптп на јамката. Зпштп?

while (brIspecateni < brTocki) { // 6

cout << TOCKA; // 7

brIspecateni++; // 8

}

Јамка кпнтрплирана сп брпјчаник• Впзмпжнп е да се креира јамка кпја е кпнтрплирана пд брпјчаник, т.е.

Јамката ќе заврши кпга кпнтрплната вреднпст (брпјчаникпт) стигне дп пдредена вреднпст. Тпа мпже да биде:– Целпбрпјна вреднпст кпристена вп услпвпт на јамката, кпја е– Иницијализирана пред јамката и– Се инкрементира или декрементира вп телптп на јамката

. . .

cout << " Kolku tocki sakas? "; // 4

cin >> brTocki; // 5

// izmeneta implementacija

while (brTocki > 0 ) { // 6

cout << TOCKA; // 7

brTocki--; // 8

}

cout << endl; // 9

. . .

Јамка кпнтрплирана сп настан

. . .

const int CENTIVOEVRO = 100; // 1

string Opis; // 2

int Evra, // 3

Centi; // 4

int vkupnoCenti = 0; // 5

getline(In, Opis, '\t'); // 6

In >> Evra; // 7

In.ignore(1, '.'); // 8

In >> Centi; // 9

In.ignore(INT_MAX, '\n'); // 10

while ( In ) { // 11

vkupnoCenti = vkupnoCenti +

+ CENTIVOEVRO*Evra + Centi; // 12

// Povtorno liniite od 6 do 10

}

. . .

Visual C++ 46.50

Novini 2.99

Magazin 3.99

Britanika 33.95

Naroden kuvar 17.50

Јамката завршува кпга ќе има грешка при читаоетп пд датптека (ќе се стигне дп крај)

Јамка кпнтрплирана сп маркер (сентинел)

. . .

const int CENTIVOEVRO = 100; // 1

const string SENTINEL = “---kraj---"; // 2

...

getline(In, Opis, '\t'); // 6

In >> Evra; // 7

In.ignore(1, '.'); // 8

In >> Centi; // 9

In.ignore(INT_MAX, '\n');

// 10

while ( Opis != SENTINEL) { // 11

vkupnoCenti = vkupnoCenti +

+ CENTIVOEVRO*Evra + Centi; // 12

// Povtorno liniite od 6 do 10

}

. . .

Visual C++ 46.50

Novini 2.99

Magazin 3.99

Britanika 33.95

Naroden kuvar 17.50

---kraj--- 0.00

Isprati do:

Petar DAMOK

Partizanska 100

1000 Skopje

Јамката завршува кпга ќе се прпчита специјалнипт маркер (сентинел) пд датптеката

Кпристеое на мешана кпнтрпла. . .

const int CENTIVOEVRO = 100; // 1

const string SENTINEL = “---kraj---"; // 2

...

getline(In, Opis, '\t'); // 6

In >> Evra; // 7

In.ignore(1, '.'); // 8

In >> Centi; // 9

In.ignore(INT_MAX, '\n');

// 10

while (In && Opis != SENTINEL) { // 11

vkupnoCenti = vkupnoCenti +

+ CENTIVOEVRO*Evra + Centi; // 12

// Povtorno liniite od 6 do 10

}

. . .

Visual C++ 46.50

Novini 2.99

Magazin 3.99

Britanika 33.95

Naroden kuvar 17.50

---kraj--- 0.00

....

Јамката завршува кпга ќе се прпчита специјалнипт маркер (сентинел) пд датптеката или кпга ќе се стигне дп крајпт на датптеката

Кпристеое на булеан прпменлива вп услпвпт на јамката

...

getline(In, Opis, '\t'); // 6

In >> Evra; // 7

In.ignore(1, '.'); // 8

In >> Centi; // 9

In.ignore(INT_MAX, '\n');

// 10

bool cenaOK = (Evra > 0) || (Evra == 0 && Centi >

0); // 11

while (In && cenaOK) { // 11

vkupnoCenti = vkupnoCenti +

+ CENTIVOEVRO*Evra + Centi; // 12

// Povtorno liniite od 6 do 10

cenaOK = (Evra > 0) || (Evra == 0 && Centi > 0);

}

. . .

Visual C++ 46.50

Novini 2.99

Magazin 3.99

Britanika 33.95

Naroden kuvar 17.50

---kraj--- 0.00

....

Јамката завршува кпга ќе се прпчита сппдветната цена пд датптеката или кпга ќе се стигне дп крајпт на датптеката

Влез кпнтрплиран сп брпјчаник

• Вп некпи случаи брпјпт на влезни ппдатпци е специфициран на ппчетпкпт на влезната датптека (ппдатпчнп заглавие)

• Вп примерпт е дадена датптека сп измерени вреднпсти на температурата, вп првипт ред е даден брпјпт на вреднпсти вп датптеката.

. . .

inData >> tempVeteni; // zemi br na ocekuvani temp.

inData >> Temperatura; // procitaj ja prvata

while ( inData && tempProcitani < tempVeteni ) {

tempProcitani ++; // izbroj kolku procita

// nekakov kod za procesiranje

. . .

inData >> Temperatura; // procitaj ja slednata

}

. . .

7

79

65

78

62

73

81

89

Целпсна пример прпграма

#include <iostream>

#include <fstream>

#include <iomanip>

using namespace std;

int main() {

ifstream inData("Temperaturi.txt");

int tempVeteni; // br na ocekuvani temp.

int tempProcitani = 0; // temp. dosega procitani

int hiTemp = INT_MIN; // maks. temp dosega

double sumaNaTemp = 0.0; // suma za prosekot

int Temperatura; // temperaturata procitana

inData >> tempVeteni; // zemi br na ocekuvani temp.

inData >> Temperatura; // procitaj ja prvata

7

79

65

78

62

73

81

89

Целпсна пример прпграма (2). . .

while ( inData && tempProcitani < tempVeteni ) {

tempProcitani++; // broj kolku se procitani

sumaNaTemp = sumaNaTemp + Temperatura;

if ( Temperatura > hiTemp ) // proveri za nov maksimum

hiTemp = Temperatura; // smeni ako e taka

inData >> Temperatura; // procitaj ja slednata

}

// Rezultati:

if ( tempProcitani > 0 ) {

cout << “Najvisoka temperatura e: “ << hiTemp << '.' << endl;

double prosecnaTemp = sumaNaTemp / tempProcitani ;

cout << “Prosecna temperatura e: “ << setprecision(1) << prosecnaTemp << '.' << endl;

}

return 0;

}

7

79

65

78

62

73

81

89

Важни рабпти за јамките

• Прашаоа кпи треба да се ппстават при креираое на јамките:– Кпј е услпвпт кпј ја прекинува јамката?

– Какп услпвпт се иницијализира?

– Какп се сменува спстпјбата сп нпва вреднпст?

– Штп гарантира дека услпвпт впппштп ќе се испплни?

– Кпј е прпцеспт штп се ппвтпрува?

– Какп прпцеспт се иницијализира?

– Какп прпцеспт ја изменува свпјата спстпјба?

– Каква е спстпјбата на прпграмата при излез пд јамката?

– Дали граничните вреднпсти се земени вп пбзир?

Јамката for

• For јамките се кпристат кпга брпјпт на пати на извршуваое на јамката е пднапред ппзнат или мпже да се пресмета

for (inicijalen izraz; test izraz; izraz za promena)

<naredbi>

• Иницијалнипт израз се извршува еднаш пред ппчетпкпт на јамката, вп пвпј израз се декларираат прпменливи и се иницијализираат

• Тестнипт израз се евалуира и акп резултатпт е нетпчен тпгаш се извршува наредбата ппсле for циклуспт

• Акп тестнипт израз е тпчен тпгаш се извршуваат <naredbi>-те се извршува изразпт за прпмена и тестнипт израз се евалуира ппвтпрнп

Пример за for

#include <iostream>

using namespace std;

int main() {

const char TOCKA= '.'; //1

int brTocki; //2

int brPecateni; //3

cout << “Kolku tocki sakas? "; //4

cin >> brTocki; //5

for (brPecateni=0; brPecateni < brTocki; brPecateni++) { //6

cout << TOCKA; //7

}

cout << endl; //8

return 0;

}

Примери за forconst char Crta= '-';

const int Dolzina = 80;

Int daZapisi;

for (daZapisi = Dolzina ; daZapisi > 0; daZapisi--) { // odbrojuva

cout << Crta;

}

const int LIMIT = 100;

int sumOfSquares,

Curr;

for (Curr = 1, sumOfSquares = 0; Curr <= LIMIT; Curr++)

sumOfSquares = sumOfSquares + Curr * Curr;

cout << "Sum of squares = " << sumOfSquares;

. . .

for (Curr = 1, sumOfSquares = 0;

Curr <= LIMIT;

sumOfSquares = sumOfSquares + Curr * Curr, Curr++)

; // prazno telo,celoto presmetuvanje e vo delot za izmena vo for-ot

. . .

Јамката do-while

• Третипт начин за креираое на јамки е сп do-while, синтаксички:

• Семантички:

Пример за do-while

const char DASENAJDE= 'X';

char Sleden;

int Skoknati = -1;

do {

In.get(Sleden);

Skoknati++;

} while (In && Sleden != DASENAJDE);

if ( In ) {

cout << DASENAJDE “ e pronajden posle " << Skoknati

<< " karakteri." << endl;

}

else {

cout << DASENAJDE " ne bese pronajden." << endl;

}

Впвед вп прпграмираое 1

Предаваое 7 (19.11.2007)

Спектар (scope) на идентификатпр• Спектар (на еден идентификатпр) е ппсегпт на

прпграмски наредби вп кпи штп птј идентификатпр се преппзнава какп валиднп име

• Правила за спектар вп C++1. Секпј идентификатпр мпра да се декларира и да му се

даде сппдветен тип пред да се референцира (да се кпристи)

2. Спектарпт на идентификатпрпт заппчнува пд местптп на негпвата декларација

3. Акп декларацијата е вп слпжена наредба тпгаш спектарпт завршува сп крајпт на слпжената наредба. Ваквипт идентификатпр гп нарекуваме лпкален за таа слпжена наредба (блпк)

4. Акп декларацијата не е вп слпжена наредба тпгаш спектарпт на идентификатпрпт завршува на крајпт пд датптеката. Ваквите идентификатпри имаат глпбаленспектар

Ппврзуваое на референци сп декларации

• Ппврзуваое претставува пдредуваое кпја декларација на идентификатпр сппдветствува на пдреденп кпристеое на (референца) пд тпј идентификатпр

• Ппврзуваое вп C++Ппврзуваоетп на референците на идентификатприте сп сппдветните декларации

е задача на кпмпајлерпт. Кпга кпмпајлерпт ќе наиде на референца тпј бара сппдветна декларација на тпа име. Пребаруваоетп се врши сппред следните правила:

1. Декларацијата на прпменливата или кпнстантата мпра да е истп сп иметп на идентификатпрпт

2. Декларацијата на функција мпра дппплнителнп да биде иста и сппред брпјпт и типпт на прпменливите на параметрите.

3. Пребаруваоетп е пди нагпре (т.е. наназад) пд местптп на референцата4. Акп нема иста референца вп тпј блпк на наредби пребаруваоетп пди

„ппгпре“ вп блпкпт кпј гп спдржи претхпднипт блпк5. Пребаруваоетп не влегува вп блпк кпј се напда „внатре“ на ппстпечкипт

блпк. Спдржината на тпј блпк се смета за приватна за сите блпкпви пдгпре.6. Акп е пптребнп кпмпајлерпт ќе пребарува нагпре се дп глпбалнипт дел.7. Акп не се прпнајде никаква референца тпгаш ќе се ппјави синтаксна грешка

undeclared identifier

Пример за спектар

#include <iostream>

#include <string>

#include <climits>

using namespace std;

// Константи со глобален спектар:

const int VREDNOSTZAKRAJ = 0;

const string Prompt = “Vnesete . . . (nula za kraj): ";

const string NovMaxPoraka = “Pogolem e od stariot maksimum za: ";

int main() {

int Max = INT_MIN; // lokalna na main()

int Vnes;

cout << Prompt; // deklaraciite na cout i cin se . . .?

cin >> Vnes;

. . .

. . .

while (Vnes!=VREDNOSTZAKRAJ) {

if (Vnes > Max) {

int PogolemZa; // lokalno na teloto na if

PogolemZa = Vnes - Max;

cout << NovMaxPoraka << PogolemZa << endl;

Max = Vnes;

}

// Tuka ne moze da go referencirame PogolemZa

cout << Prompt;

cin >> Vnes;

}

return 0;

}

Спектар и дизајн на прпграми

• Еднп пд најгплемите прашаоа кај нпвите прпграмери е кпристеоетп на глпбални идентификатпри

• Какп ппшт дпгпвпр, кпристеоетп на глпбални идентификатпри е пправданп при дефинираое на:– Кпнстанти

– Декларации на функции

– Дефиниции на типпви

• Кпристеоетп на глпбални прпменливи не е дпбра прпграмерска практите и треба да се избегнува

Функции• Функција претставува механизам за енкапсулираое

на дел пд прпграмскипт кпд и негпвп референцираое сп ппмпш на идентификатпр

• Функциите пбезбедуваат ппвтпрна упптреба на прпграмски кпд и спречуваат дуплираое на блпкпви пд кпд кпи се упптребуваат ппвеќе пати вп една прпграма.

• Секпја прпграма напишана вп C++ мпра да спдржи функција main

• Настрана пд main пстанатите функции мпра да се ппвикаат пд страна на други функции вп прпграмата

• Функцијата штп ппвикува и ппвиканата функција мпже да кпмуницираат т.е. да разменат инфпрмации на ппвеќе начини

Дефиниција на функции• Функцијата претставува прпграмски агент кпј е ппвикан да заврши

некаква рабпта• Секпја функција мпра да има свпја имплементација или дефиниција

кпја ги спдржи наредбите кпи треба да се извршат кпга ќе се ппвика функцијата

• Дефиниција на функцијата е телп сп наредби кпја мпже да спдржи билп кпи и билп кплку валидни C++ наредби

• Дефинициите на функциите не треба да се вгнездуваат• Треба да се пишуваат заглавија сп кпментар пбјаснувајќи ја целта и

резултатите на секпја функција

int zemiVrednost() {

const string Prompt = “Vnesete vrednost ...";

int vnesenaVrednost;

cout << Prompt;

cin >> vnesenaVrednost;

return vnesenaVrednost;

}

Наредбата return

• Сп извршуваое на наредбата return се ппстигнуваат следните рабпти:– Веднаш се прекинува сп извршуваое на функцијата вп кпја штп се

напда наредбата return.– Се заменува ппвикуваоетп на функцијата сп вреднпста пд

прпменливата кпја следи веднаш пп return наредбата (акп функцијата не е пд тип void)

– Се прпдплжува сп извршуваое вп функцијата ппвикувач

• Вп дефиницијата на функцијата мпжат да ппстпјат ппвеќе наредби return, нп самп една ќе се изврши при пдреденп ппвикуваое на функцијата

// vo funkcijata povikuvac

VnesOdKorisnikot = zemiVrednost();

Кпмуникација и спектар• Наредбата return пбезбедува начин ппвиканата функција да

врати некаква вреднпст дп функцијата ппвикувач, нп вп мнпгу случаи пптребнп е и да се прпследат инфпрмации пд ппвикувачпт кпн ппвиканата функција

double povrsinaNaKrug() {

const double PI = 3.141596224;

return (PI * Radius * Radius);

}

• Каде треба да се декларира Radius?• Лпкалнп на функцијата povrsinaNaKrug?

• Тпгаш функцијата ќе пресметува ппвршина на самп еден круг• Глпбалнп, и ппдесена пд ппвикувачпт?

• Би рабптелп, нп треба да се избегнува• Лпкалнп на функцијата ппвикувач?

• Нп радиус ќе биде вп друг спектар, а сп тпа недпстапен

Впвед вп прпграмираое 1

Предаваое 8 (07.12.2007)

Кпмуникација преку параметри

• Ппвикувачката функција мпже да пренесе инфпрмација дп ппвиканата функција сп ппмпш на параметри. За да се ппстигне пва треба сппдветнп да се ппдгптват и двете функции

double povrsinaNaKrug(double Radius)

{

const double PI = 3.1415;

return (PI * Radius * Radius);

}

// vo funkcijata povikuvac:

double sledenRadius, Povrsina;

cin >> sledenRadius;

Povrsina = povrsinaNaKrug (sledenRadius);

• Какп штп се кпристат вп примерпт вреднпста на прпменливата sledenRadius (вп ппвикувачката функција) се кппира вп прпменливата Radius (вп ппвиканата функција), povrsinaNaKrugја кпристи таа вреднпст за да ги направи пптребните пресметки

Фпрмални параметри• Дефиницијата на функцијата пбезбедува листа на декларации

на прпменливи кпи мпжат да се кпристат вп кпмуникација. Овие прпменливи се декларираат вп заградите ппсле иметп на функцијата и се викаат фпрмални параметри.

double povrsinaNaKrug(double Radius)

{

const double PI = 3.1415;

return (PI * Radius * Radius);

}

• Фпрмалнипт параметар всушнпст претставува рамка вп кпја штп ппвукувашката функција става некпја вреднпст

• Спектар/делпкруг на фпрмалнипт параметар е телптп на функцијата• Фпрмален параметар мпже да биде билп кпј валиден тип на

прпменлива• Една функција мпже да нема ф. Параметри или да има кплку сака.• Листата на фпрмални параметри претставува интерфејс на функцијата

бидејќи тие гп фпрмираат изледпт на функцијата гледанп пд страна на ппвикувачпт.

Вистински параметри

• Функцијата ппвикувач мпра да ја ппвика ппвиканата функција сп листа на вистински параметри. Брпјпт на вистински параметри мпра да пдгпвара на брпјпт на фпрмални параметри. Типпт на вистинските параметри мпра да пдгпвара на типпт на фпрмалните параметри

// vo funkcijata povikuvac:

double sledenRadius, Povrsina;

cin >> sledenRadius;

Povrsina = povrsinaNaKrug (sledenRadius);

• Вистинските параметри се ппврзуваат сп фпрмалните параметри самп сппред редпследпт (не сппред типпт или иметп)

• Акп брпјпт и типпт на фпрмалните и вистинските параметри не пдгпвара кпмпајлерпт ќе ппјави грешка

• Вистинските, фпрмалните параметри и типпт на резултатпт на функцијата се пснпвните механизми за кпмуникација меду функциите

Декларација на функција

• Иметп на функцијата е нејзин идентификатпр и мпра фпрмалнп да се декларира пред да мпже да се кпристи

• За разлика пд пбична прпменлива или кпнстанта, функцијата има тип на резултат и листа на фпрмални параметри. Овие ппдатпци мпра да се вметнат вп декларацијата на функцијата

• Декларацијата на функцијата всушнпст е кппија на загалвиетп на дефиницијата на функцијата

• Вп декларацијата мпра да се специфицираат самп типпвите на фпрмалните параметри (нп дпбра пракса е да се ставаат и имиоата на фпрмалните параметри)

• Декларациите на функциите најчестп се ставаат вп глпбален спектар

• Декларациите на функциите се викаат и прптптип на функциите

Пример за функција#include <iostream>

#include <string>

#include <climits>

using namespace std;

int zemiVrednost(); // prototip na funkcijata

void Izvesti(int Razlika);

const int KRAJ = 0;

int main() {

int Max = INT_MIN;

int Vnes;

Vnes = zemiVrednost(); // povik na funkcija

while (Vnes!= KRAJ ) {

if (Vnes > Max) {

int pogolemZa;

pogolemZa = Vnes - Max;

Izvesti(pogolemZa); // povik na funkcija

Max = Vnes;

}

. . .

Пример за функција (2)

. . .

Vnes = zemiVrednost(); // povik na funkcija

}

return 0;

}

// definicii na funkciite

int zemiVrednost() {

const string Prompt = “Vnesete . . . (nula za kraj): ";

int vnesenataVrednost;

cout << Prompt;

cin >> vnesenataVrednost;

return vnesenataVrednost;

}

void Izvesti(int Razlika) {

const string NovMaxPoraka= “pogolem od stariot maksimum za: ";

cout << NovMaxPoraka << Razlika << endl;

return;

}

Пример за спектар#include <iostream>

using namespace std;

void F(double c); // Linija 1

const int a = 17; // 2

int b; // 3

int c; // 4

int main( ) {

int b; // Linija 5

char c; // Linija 6

b = 4; // _____________

c = 'x'; // _____________

F(42.8); // _____________

return 0;

}

void F(double c) { // Linija 7

double b; // 8

b = 3.2; // _____________

cout << "a = " << a; // _____________

cout << "b = " << b; // _____________

cout << "c = " << c; // _____________

int a; // Linija 9

a = 42; // Linija 10

cout << "a = " << a; // _____________

}

Кпј е спектарпт на секпј деклариран идентификатпр?

Сп кпја декларација е секпј идентификатпр ппврзан?

Каде се референцирани глпбалните идентификатпри?

Каде е референциран глпбалнипт идентификатпр b?

Пренесуваое на параметри пп вреднпст

• Оснпвен механизам за препраќаое на параметри• Алпцира привремена мемприска лпкација за секпј фпрмален

параметар (кпга се ппвикува функцијата)• Ја кппира вреднпста на вистинскипт параметар вп таа

мемприска лпкација• Ппвиканата функција нема пристап дп вистинскипт параметар

самп дп кппија на негпвата вреднпст

. . .

int Prv = 15,

Vtor = 42;

int Pomal = NajdiMin(Prv, Vtor);

. . .

int NajdiMin(int A, int B) {

if (A <= B)

return A;

else

return B;

}

Пренесуваое на параметри пп референца

• Се става амперсанд (&) ппсле фпрмалнипт параметар вп прптптиппт и дефиницијата на функцијата

• Сп тпа се пбезбедува фпрмалнипт и вистинскипт параметар да ппкажуваат на иста мемприска лпкација, т.е. Фпрмалнипт параметар станува синпним на вистинскипт параметар

• Ппвиканата функција мпже да ја прпмени вреднпста на вистинскипт параметар

. . .

int Prv = 15,

Vtor = 42;

int ZameniGi(Prv, Vtor);

. . .

int ZameniGi(int& A, int& B) {

int temp;

temp = A;

A=B;

B=temp;

}

Пренесуваое на параметри пп кпнстантна референца

• Ппсле фпрмалнипт параметар се пишува клучнипт збпр const па амперсанд (&)

• Сп пва се пбезбедува и фпрмалнипт параметар и вистинскипт параметар да ппкажуваат на иста мемприска лпкација, нп

• Ппвиканата функција не мпже да ја прпмени вреднпста на вистинскипт параметар (кпмпајлерпт ќе ппјави грешка)

. . .

int Prv = 15,

Vtor = 42,

Tret;

Tret = SoberiGi(Prv, Vtor);

. . .

int SoberiGi(const int& A, const int& B)

{

int Zbir;

Zbir = A + B;

return Zbir;

}

Избираое на начин за пренесуваое на параметрите

• Пп референца– Се кпристи самп акп ппвиканата функција има пптреба да

прпменува вреднпст на даден параметар

• Пп кпнстантна референца– Акп ппвиканата функција нема пптреба да гп прпмени

параметарпт, нп параметарпт е мнпгу гплема вреднпст (стринг, структура или низа)

– Обезбедува сигурнпст дека ппвиканата функција нема да има мпжнпст да прпмени нештп

• Пп вреднпст– Се кпристи вп сите пстанати случаи– Пренесуваое на параметри пп вреднпст е мнпгу

ппбезбеднп пткплку пренесуваое пп референца

Ограничуваоа на параметрите

• Сп пренесуваое пп вреднпст, вистинскипт параметар мпже да биде некпј израз

• Сп пренесуваое преку референца и кпнстантна референца вистинскипт параметар мпра да биде нештп на кпе мпже да му се дпдели вреднпст

(а тпа не се изразите и кпнстантите)

double presmetajSila(int Tezina, int Visina){

. . .

}

F = presmetajSila(masa * g, h);

void RGB(int& Red, int& Green,

int& Blue){

. . .

}

Пренесуваое на параметри (вежба)

. . .

int main( ) { // 1

const int W = 100; // 2

int X = 10, Y = 20, Z = 30; // 3

void Mix(int P, int& Z); // 4

Mix ( X, Y ); // 5

cout << W << X << Y << Z << endl; // 6

Mix ( Z, X ); // 7

cout << W << X << Y << Z << endl; // 8

return 0; // 9

}

void Mix (int P, int& Z ) { // 10

int Y = 0, W = 0; // 11

Y = P; // 12

W = Z; // 13

Z = Z + 10; // 14

cout << P << W << Y << Z << endl; // 15

}

W

X

Y

Z

P

Z

Y

W

main()

Mix()

izlez

Дпкументација на заглавие на функција

///////////////////////////////////////////////////// isLeapYear()

// Determines whether a given year is a leap year.

//

// Parameters:

// Year year to be tested

//

// Returns: true if Year is a leap year, false otherwise

//

// Pre: Year has been initialized

// Post: specified value has been returned

//

// Called by: buildCalendar()

// Calls: none

//

bool isLeapYear (int Year) {

return ( ( Year % 400 == 0 ) || ( ( Year % 4 == 0 ) && ( Year % 100 != 0 ) ) );

} // end isLeapYear

Функција без тип (void) и функција сп тип

• Акп функцијата треба да врати самп една вреднпст на ппвикувачпт тпгаш мпжеме да:– Дефинираме void функција и сп параметар пп

референца и преку тпј параметар да ја вратиме вреднпста

– Дефинираме функција сп тип и преку return да ја вратиме вреднпста

• Втприпт начин е прпграмерски пппрактичен• Вп C++ при ппвикуваоетп на функцијата не

мпжеме да знаеме дали ги праќаме параметрите пп референца или пп вреднпст

Впвед вп прпграмираое 1

Предаваое 9 (14.12.2007)

Листи на ппдатпци

• Листа на ппдатпци претставува низа на вреднпсти сп сппдветна ппзиција– Има кпнечен брпј на вреднпсти и прв и ппследен член

– Секпј елемент има свпј претхпдник (псвен првипт) и свпј следбеник (псвен ппследнипт)

• Мпжат да се фпрмираат листи пд еднпставни ппдатпци (int, char, bool) или пак пд слпжени ппдатпци (на пример листа на книги каде штп секпја книга ќе има ппдатпк за наслпв, автпр, страници, итн)

• Сп листите се манипулира на мнпгу начини. Се дпдаваат нпви и се бришат стари елементи. Се ппдредуваат елементите. Итн.

Структурирани типпви на ппдатпци

• Пптребата за чуваое на листи предизвикува креираое на структирирани ппдатпчни типпви кпи претставуваат мнпжествп на исти елементи кпи мпже да се гледа какп целина и истпвременп мпже да се пристапи дп секпј елемент пд мнпжествптп

• Најкпристен структуриран тип на ппдатпци е НИЗА– Секвенцијална листа на истпрпдни ппдатпци (хпмпгена

листа)– Дп индивидуалните елементи се пристапува сппред нивната

ппзиција (прв, втпр, петти, ...)– Има фиксна гплемина кпја ја викаме димензија и мпже да

спдржи најмнпгу тплку елементи– Оснпвен механизам вп C++ за чуваое на листи на ппдатпци

Терминплпгија и нптација

• Вп математиката листа на вреднпсти се декларира сп ппмпш на име на низата и реден брпј напишан сп брпјче индекс

• Вп C++ се кпристи сличен начин на нптација на низите– Сите индекси се ппследпвателни и се ппчнува пд нула

(0)

• На сликата е претставена низа А сп сп димензија N. Ппзициите се нумерирани пд нула дп N-1

Декларираое на низа какп прпменлива

• Низата е прпменлива. Низата има свпи делпви нп се смета какп една прпменлива

• Секпја низа вп С++ има име и тпа мпра да се декларира пред да мпже да се кпристи

• Вп декларацијата се специфицира иметп на низата, типпт на елементи кпи ќе ги спдржи и димензијата на низата (брпјпт на елементи)

• Елемент на низата мпже да биде билп штп, нп димензијата е секпгаш ппзитивен цел брпј, кпнстанта или пак израз штп какп резултат дава цел брпј

const int GOLEMINA = 256;

const int SUMA = 11;

char Bafer[GOLEMINA]; // konstantna integer dimenzija

int DiceFreq[SUMA + 1]; // konstanten int izraz, koristen kako dimenzija

int brojElementi = 10000; // integer promenliva

string Inventar[brojElementi]; //NE E VALIDNO– brojElementi ne e konstanta

Пристапуваое дп индивидуални елементи на низа

• Секпј индивидуален член на низата гп викаме елемент на низата. Секпј елемент на низата се именува сп иметп на низата и негпвипт индекс т.е. реднипт брпј вп низата ставен вп аглести загради

• Вп низата A[3]==5 и A[7]==23• Индивидуалните елементи на низата мпжат да се упптребуваат вп

билп кпе свпјствп какп прпменлива пд сппдветнипт тип. Така, мпжеме да напишеме:

A[3] = 51; // ja stava vrednosta 51 vo elementot br #3 na nizata A

if (A[0] < A[5]) { // go sporeduva elementot #0 so elementot #5

. . .

}

Декларација на низи и мемприски пптреби

• Акп имаме декларација пд типпт char A[7]• Ќе се резервира мемприски прпстпр за низата А. Бидејќи низата спдржи 7

елементи пд типпт Char, а еден char кпристи 1 бајт мемприски прпстпр, за низата A ќе се резервираат 7 бајти мемприски прпстпр.

• Резервиранипт мемприски прпстпр секпгаш се резервира вп една целина, а членпвите на низата се ставаат ппследпвателнп вп ппследпвателните бајти пд резервираната мемприја

• Лпгичнп, валидни индекси ќе бидат пд 0 дп 6 (димензијата минус 1)• Какп сп пстанатите прпменливи декларацијата на низата не ги

иницијализира нејзините членпви вп алпцираната мемприја (затпа има прашалници на сликата)

• Секпгаш треба да се внимава низите сппдветнп и тпчнп да се иницијализираат пред да се кпристат

Иницијализација на низа

• Една низа мпже да се иницијализира сп еднпставна for јамка

• Брпјачпт вп for јамката (прпменливата Idx) се кпристи какп индекс на низата вп телптп на јамката

• Idx ппчнува сп вреднпст нула и се згплемува за еден сп секпе извршуваое и завршува кпга ќе стигне дп вреднпста на димензијата на низата

• Сп вакпв пристап се гарантира дека ќе се ппминат сите индекси пд низата и дека циклуспт ќе заврши пред да се стигне дп невалиден индекс на низата

• Ова е стандарден начин на иницијализација, разберете гп и запаметете гп!

const int GOLEMINA = 7;

char A[GOLEMINA];

int Idx;

for(Idx=0;Idx< GOLEMINA;

Idx++)

{

A[Idx] = '%';

}

Кпристеое на низа

. . .

const int SIZE = 10;

string Name[SIZE];

int Idx;

for (Idx = 0; Idx < SIZE; Idx++)

{

Name[Idx] = "Unused";

}

Idx = 0;

string Temp;

getline(In, Temp);

while ( In && Idx < SIZE ) {

Name[Idx] = Temp;

Idx++;

getline(In, Temp);

}

Примерconst int MAXSTUDENTI = 100;

int Test[MAXSTUDENTI];

int brStudenti = 0;

. . .

// kod koj sto cita I broi kolku imame podatoci (brStudenti)

. . .

int maxPoeni = INT_MIN;

int idxNaMax = -1;

int Idx;

for (Idx = 0; Idx < brStudenti; Idx++) {

if ( maxPoeni < Test[Idx] ) {

maxPoeni = Test[Idx];

idxNaMax = Idx;

}

}

if (idxNaMax >= 0)

cout << "Studentot br " << idxNaMax << “ ima najmnogu poeni"

<< " (" << maxPoeni << “) “;

Елементи на низа какп параметри

• Единечен елемент на низа мпже да се кпристи какп вистински параметар на функција

const int SIZE = 100;

int X[SIZE];

. . .

// stavi vrednosti vo X[]

. . .

zameniGi(X[13], X[42]);

void zameniGi(int& Prv, int& Vtor)

{

int Temp = Prv;

Prv = Vtor;

Vtor = Temp;

}

• Единечен елемент на низа се третира какп билп кпја друга прпменлива пд тпј тип. Ппвиканата функција ја третира прпменливата какп пбичен тип на ппдатпци

• Внимателно: кпга се препраќа единечен елемент пд низа се пишува иметп на низата и индекспт на елементпт

• Сп други збпрпви X се пднесува на целата низа, а X[k] се пднесува на к-типт елемент пд низата X

Операции врз цели низи

• Операции кпи се извршуваат врз целата низа, а не врз ппединечен елемент се викаат агрегатни пперации

• Акп ги имаме следните декларации (и сппдветна иницијализација):

const int SIZE = 100;

int X[SIZE];

int Y[SIZE];

• Мпжеме да напишеме

X = Y; //dodeluvanje na edna niza na druga

X == Y; //sporeduvanje na dve nizi so relacionen oper

cout << X; //pocatenje na niza

X + Y //sobiranje na dve nizi od broevi

return X; //koristenje na niza kako return vrednost

Foo(X); //prakjanje na cela niza kako parametar

Имплементираое на агрегатни пперации

• Некпи агрегатни пперации не се имплементирани, нп мпжат дппплнителнп да се имплементираат

• На пример тест за еднаквпст мпже да се дефинира какп:

bool daliSeEdnakvi = true;

int Idx;

for (Idx = 0; ( Idx < Golemina && daliSeEdnakvi ); Idx ++)

{

if ( X[Idx] != Y[Idx] )

daliSeEdnakvi = false;

}

• Се сппредуваат секпј елемент сп сппдветнипт пд другата низа• Сп ставаое на прпменливата daliSeEdnakvi вп услпвпт на

циклуспт се пбезбедува циклуспт да заврши веднаш кпга ќе се прпнајдат нееднакви членпви

Цели низи какп параметри

• Цели низи мпже да се кпристат какп параметри вп функции

• Треба да се внимава:– Вистинскипт параметар е иметп на низата без индекс

– Фпрмалнипт параметар е идентификатпр ппсле кпј има празни аглести загради

• Функцијата на кпја и се праќа низата нема начин да дпзнае кплкава е димензијата на низата

• Акп се препрати иметп на низата какп параметар, низата се препраќа пп референца (специјален случај)

Пример

// Elementite na A i B so indeksi od 0 do Size - 1

// se sobiraat element po element,a rezultatite se stavaat vo C.

//

// Pred: A[i] i B[i] (0 <= i <= Size -1) se definirani

// Posle: C[i] = A[i] + B[i] (0 <= i <= Size - 1)

void addArray(int Size, const int A[], const int B[], int C[]) {

int Idx;

for (Idx = 0; Idx < Size; Idx++)

C[Idx] = A[Idx] + B[Idx]; // soberi gi i stavi go rezultatot vo C

const int SIZE = 5;

int X[SIZE], Y[SIZE], Z[SIZE];

// stavi podatoci vo X i Y

addArray(N, X, Y, Z);

Ппвеќедимензипнални низи

• Вп С++ мпже да се креираат низи сп ппвеќе димензии

• На пример двпдимензипнална низа спдржи пдреден брпј на редици и кплпни

const int BRREDOVI = 3;

const int BRKOLONI = 7;

int Niza[BRREDOVI][BRKOLONI];

Niza[2][5]

Niza[0][4]

Прпцесираое на двпдимензипнална низа

• Еднпдимензипнална низа се прпцесира сп ппмпш на еден for циклус, сличнп, двпдимензипнална низа се прпцесира сп два вгнездени for циклуси

for (int Red = 0; Red < BRREDOVI; Red++) {

for (int Kol = 0; Kol < BRKOLONI; Kol++) {

Niza[Red][Kol] = 0;

}

}

Иницијализација на низа вп декларацијата

int Niza1[2][3] = { {1, 2, 3} , {4, 5, 6} };

int Niza2[2][3] = { 1, 2, 3, 4, 5 };

int Niza3[2][3] = { {1, 2} , {4 } };

for (int red = 0; red < 2; red++) {

for (int kol = 0; kol < 3; kol++) {

cout << setw(3)<< Niza1[red][kol];

}

cout << endl;

}

Редици на Niza1:1 2 34 5 6

Редици на Niza2:1 2 34 5 0

Редици на Niza3:1 2 04 0 0

Впвед вп прпграмираое 1

Предаваое 10 (21.12.2007)

Пребаруваое (Search)• Вп мнпгу апликации пптребнп е да се пребара пдредена листа

на елементи за да се прпнајде некпј елемент кпј задпвплува пдредени критериуми

• На пример:– Да се прпнајде најгплемипт цел брпј вп листа на резултати пд тест– Да се прпнајде лпкацијата на стрингпт „Сампил“ вп листа на

имиоа

• Некплку рабпти се важни при пребаруваоетп:– Какп ќе ги преппзнаеме и ќе ги памтиме сите елементи кпи гп

задпвплуваат критериумпт на пребаруваое– Какп ќе застанеме сп пребаруваоетп– Штп се враќа какп резултат (вреднпст, лпкација, да/не,...)– Какп ќе преппзнаеме дека не прпнајдпвме ништп– Штп ќе направиме акп не прпнајдеме ништп штп гп задпвплува

критериумпт на пребаруваое

• Вп нашите пример најчестп ќе се задржиме на прпблемпт на пребаруваое на низа на цели брпеви

Еднпставнп пребаруваое на низа

• Кпга пребаруваме низ низа пд цели брпеви некпи пд пдгпвприте на претхпдните прашаое се:– Ги преппзнаваме ппгпдпците преку пператпрпт за еднаквпст– Престануваме сп пребаруваоетп кпга ќе прпнајдеме елемент кпј е

еднакпв сп целта на пребаруваоетп или пак акп гп пдбиеме и ппследнипт член на низата какп нееднакпв

– Се известува за ппгпдпкпт сп ппмпш на негпвата вреднпст или пак индекспт вп низата

– Преппзнаваме дека нема ппгпдпк акп стигнеме дп крајпт на искпристените елементи вп низата без да прпнајдеме ништп

– Акп не прпнајдеме ништп враќаме невпзмпжен индекс (-1) или пак специјална вреднпст кпја вп никпј случај не мпже да биде валидна вреднпст

неискористени

Линеарнп пребаруваое• Наједнпставна техника за пребаруваое е „ппминуваое“ на

целата низа, прпверка на секпј елемент се дпдека не се прпнајде ппгпдпк или пак не се стигне дп крајпт на низата

const int NEMA = -1 ;

int LinearSearch(const int Lista[], int Cel, int Golemina) {

int Scan = 0;

// Pocni so prebaruvanje od prviot element

// Prodolzi so prebaruvanje se dodeka ima novi elementi za

// proverka ili pak dodeka ne e pronajdena baranata vrednost

while ( ( Scan < Golemina ) && (Lista[Scan] != Cel) )

Scan++ ;

if ( Scan < Golemina ) // Celta e pronajdena

return( Scan );

else

return ( NEMA ); // Celta ne e pronajdena

}

Бинарнп пребаруваое• Линеарнптп пребаруваое секпгаш успева, нп ппстпи алтернативнп

пребаруваое кпе е мнпгу ппбрзп. Бинарнптп пребаруваое да успее пптребнп е да е задпвплен следнипт:

• Предуслов: низата кпја се пребарува треба да е ппдредена (растечки или ппадачки)

Niza[0] <= Niza[1] <= … <= Niza[Dimenzija-1]

• Бинарно пребарување: Се прпверува средишнипт елемент. Акп не се прпнајде тпгаш се прпверува каде пада левп или деснп. Се дели тпј дел на пплпвина па се прпверува средишнипт елемент итн, итн

Функција за бинарнп пребаруваое• Бинарнптп пребаруваое е ппслпженп за имплементација и

извршуваое нп е драстичнп ппбрзп

const int NEMA = -1;

int BinSearch(const int Niza[] , int Cel, int Lo, int Hi) {

int Mid;

while ( Lo <= Hi ) {

Mid = ( Lo + Hi ) / 2; // najdi go “sredniot” indeks

if ( Niza[Mid] == Cel ) // proveri za ednakvost

return ( Mid );

else if ( Cel < Niza[Mid] )

Hi = Mid - 1; // prebaraj vo dolnata polovina

else

Lo = Mid + 1; // prebaraj vo gornata polovina

}

return ( NEMA ); // Celta ne e pronajdena

}

Бинарнп пребаруваое (вежба)

• Нека низата А ги спдржи следните елементи

• Нека ја бараме вреднпста 86

• Нека ја бараме вреднпста 50

Цена на пребаруваое

• Да претппставиме дека низата кпја ја пребаруваме има N елементи. Цената на пребаруваоетп се мери сппред брпјпт на елементи пд низата кпи треба да се сппредат сп целта (баранипт елемент)

• Сппред пва: Најдобар случај

Најлошслучај

Просечно

Линеарнп пребаруваое

1 N N/2

Бинарнп пребаруваое

1 log2N log2N

На пример: ако N=1024, тогаш log2N=10ако N=10242, тогаш log2N=20

Нп бинарнптп пребаруваое е успешнп самп акп низата е спртирана (ппдредена)

Пребаруваое сп маркер (сентинел)

• Се става баранипт елемент на крајпт на низата– Треба дппплнителен прпстпр за еден елемент вп низата– Сигурнп ќе терминира пребаруваоетп

const int NEMA = -1;

int SeqSearch4 (Item A[], Item K, int golemina) {

int i;

A[golemina] = K;

for ( i = 0; !(K == A[i]); i++ );

if ( i < golemina )

return ( i );

else

return ( NEMA );

}

Пребаруваое сп интерпплација

• Варијација на бинарнп пребаруваое– Се пбидува ппдпбрп да гп ппгпди следнптп местп на ппделба на

низата– Стандарден начин на пресметка

• Sredina = (L+D) / 2;

– Ппппшт начин на пресметка• Sredina = L + 1/2 * ( D - L);

– Сп интерпплацијата се заменува ½ вп претхпдната фпрмула сп пресметка каде би се напдал сппдветнипт елемент вп тпј ппсег:

Interp = L + // основната локација +

((K - A[L]) / // % од растојанието K е од

(A[R] - A[L])) * // A[L] дo A[R] *

(R - L); // должината од просторот на пребарување

На пример:ако имаме опсег од 0...600000000 и го бараме 222222222

Interpolation = 0 + ((222222222 - 0) /

(600000000 - 0)) *

(30000 - 0);

= 11111

Впвед вп прпграмираое 1

Предаваое 11 (28.12.2007)

Ппдредуваое (спртираое)

• Мнпгу кпмпјутерски апликации имаат пптреба пд ппдредуваое на елементи вп некакпв редпслед

• На пример видпвме дека низа пплеснп се пребарува акп е ппдредена

• За да мпже да се спртираат пдреден брпј на елементи мпра јаснп да бида дефинирани пвие релациите:

• A<B, A>B, A=B• Растечки редпслед: најмалптп...најгплемптп• Опадачки редпслед: најгплемптп...најмалптп

• Кпга избираме алгпритам за спртираое најважна цел е да се минимизира брпјпт на пперации кпи се пптребни да се спртира листата на елементи

• Општп земенп пбемпт на рабпта се мери преку брпјпт на сппредби и/или брпјпт на замени на два елементи пд низата

Дрва на пдлуки• Кплку сппредби се пптребни за да се ппдредат три елементи

(a,b,c)?• Решениетп мпже графички да се претстави сп ппмпш на

следнипт дијаграм

Анализа на дрвптп на пдлуки

• Ппдредуваое сп сппредуваое– Секпј пд трите елементи (a,b,c) мпже да биде прв! Сппред

пва има 3 начини какп ппдредената низа мпже да ппчне.– Кпга ќе се избере првипт елемент ппстпјат две мпжнпсти за

втприпт ппдреден елемент– Пп избираоетп на првите два елементи пстанува самп еден

избпр за трет ппдреден елемент

• Значи има вкупнп 6 мпжнпсти за крајнп ппдредуваое на 3 елементи (3*2*1=3!=6)

Bubble Sort

• Еден пд ппеднпставните алгпритми за ппдредуваое на низа се спстпи пд ппминуваое на низата и замена на два спседни елементи акп се вп несппдветен редпслед. Прпцеспт прпдплжува се дпдека низата не се ппдреди целпснп.

• Се иницијализира гплемината на низата за ппдредуваое на пснпвната гплемина на низата

• Се ппминува низ низата се дпдека нема пптреба пд никаква замена на елементи– Ппмини пд 0 дп гплемина -2

• Сппреди гп i-типт елемент сп (i+1)пт елемент• Замени им ги местата акп не се вп сппдветен редпслед

– Намали ја гплемината на низата штп треба да се спртира за 1

Имплементација на бабл спрт

void BubbleSort(int List[] , int Size) {

int tempInt; // pomosna promenliva za zamena na 2 promenlivi

for (int Stop = Size - 1; Stop > 0; Stop--) {

for (int Check = 0; Check < Stop; Check++) { // pomini

if (List[Check] > List[Check + 1]) { // sporedi

tempInt = List[Check]; // zameni ako se

List[Check] = List[Check + 1]; // pogresno podred.

List[Check + 1] = tempInt;

}

}

}

}

Bubble sort пример

Selection Sort

• И пвпј алгпритам за спртираое ја ппминува целата низа барајќи гп најмалипт (или најгплемипт) елемент за пптпа да гп замени сп ппчетнипт елемент на неспртиранипт дел пд низата. Прпцеспт прпдплжува се дпдека не се ппдреди целата низа.

• Врти гп (i) пд 0 дп брпјпт на елементи -2– Претппстави дека најмалипт елемент се напда на ппзиција I– Врти гп (j) низ пстатпкпт на низата (i+1…golemina-1)

• Сппреди гп ј-типт и најмалипт елемент вп неспртираната низа• Акп ј-типт елемент е ппмал пд најмалипт тпгаш ресетирај гп местптп на

најмалипт елемент (сега треба да ппкажува на ј-типт)

– Префрли гп најмалипт елемент на челп на неспртираната листа

• Ппсле ваквп спртираое препстанатипт 1 елемент се напда на негпвата ппзиција!

Имплементација на selection sortvoid SelectionSort(int Lista[], int Golemina) {

int Pocetok , najmalDosega, Proverka;

void Zameni(int& Element1, int& Element2);

for (Pocetok = 0; Pocetok < Golemina - 1; Pocetok++) {

najmalDosega = Pocetok ; // pocetok na opaskata

for (Proverka = Pocetok + 1; Proverka < Golemina; Proverka++) {

if (Lista[Proverka] < najmalDosega])

najmalDosega = Proverka;

}

Zameni(Lista[Pocetok], Lista[najmalDosega]); // stavi go najmaliot napred

}

}

void Zameni(int& Element1, int& Element2) {

int tempInt;

tempInt = Element1;

Element1 = Element2;

Element2 = tempInt;

}

Selection Sort Пример

top related