Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо,...

169
Ръководството е предназначено за семинарни и лабораторни упражнения по програмиране І част в Шуменския университет “Константин Преславски”, но може успешно да бъде използвано и в други ВУЗ, както и за обучение по програмиране на базата на езика С++ в профилираните паралелки на средните училища. Тъй като е предназначено за упражнения, теоретичните бележки в него са ограничени и сбити. Предполага се, че обучаемите ще разполагат и с учебник, който изчерпателно ще ги разглежда. Помагалото предлага голямо количество решени задачи и задачи за упражнение. В ръководството са публикувани лабораторните практикуми, които се провеждат по дисциплината програмиране І част в Шуменския университет “Константин Преславски” и са изготвени от екипа, ръководещ тази дисциплина: Бисерка Йовчева, Емануил Стоянов и Божидар Стоянов. Лабораторните практикуми са публикувани без допълнителна редакция със съгласието на колегите, за което авторите на помагалото сърдечно благодарят. 1

Transcript of Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо,...

Page 1: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Ръководството е предназначено за семинарни и лабораторни упражнения по програмиране І част в Шуменския университет “Константин Преславски”, но може успешно да бъде използвано и в други ВУЗ, както и за обучение по програмиране на базата на езика С++ в профилираните паралелки на средните училища. Тъй като е предназначено за упражнения, теоретичните бележки в него са ограничени и сбити. Предполага се, че обучаемите ще разполагат и с учебник, който изчерпателно ще ги разглежда. Помагалото предлага голямо количество решени задачи и задачи за упражнение.

В ръководството са публикувани лабораторните практикуми, които се провеждат по дисциплината програмиране І част в Шуменския университет “Константин Преславски” и са изготвени от екипа, ръководещ тази дисциплина: Бисерка Йовчева, Емануил Стоянов и Божидар Стоянов. Лабораторните практикуми са публикувани без допълнителна редакция със съгласието на колегите, за което авторите на помагалото сърдечно благодарят.

1

Page 2: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Съдържание:

1. Алгоритми----------------------------------------------------------------------------------------------- 32. Етапи при решаване на задача за програмиране------------------------------------------------ 103. Програмно осигуряване на съвремените компютри (обобщение)---------------------------- 134. Системи за програмиране----------------------------------------------------------------------------- 155. Системата за програмиране Borland C++---------------------------------------------------------- 176. Елементи на езиците за програмиране------------------------------------------------------------- 217. Структура на програма на С++---------------------------------------------------------------------- 248. Числови типове данни и операции в С++--------------------------------------------------------- 309. Въвеждане и извеждане на данни в С програма------------------------------------------------- 3710. Лабораторен практикум №1. Линейни алгоритми ---------------------------------------------- 4811. Проверка на условие. Логически операции. Условна операция. Условен оператор if.- - 4912. Лабораторен практикум №2. Разклонени алгоритми------------------------------------------- 6013. Оператор за избор на вариант------------------------------------------------------------------------ 6214. Лабораторен практикум №3. Оператор за избор на вариант---------------------------------- 6915. Оператори за цикъл. Оператор за цикъл do-while----------------------------------------------- 7116. Оператор за цикъл while------------------------------------------------------------------------------ 7717. Оператор за цикъл for---------------------------------------------------------------------------------- 8118. Циклични алгоритми---------------------------------------------------------------------------------- 8519. Лабораторен практикум №4. Циклични алгоритми------------------------------------------- 10520. Лабораторен практикум №5. Теория на числата----------------------------------------------- 10721. Функции------------------------------------------------------------------------------------------------- 10822. Лабораторен практикум №6. Функции----------------------------------------------------------- 11523. Масиви-------------------------------------------------------------------------------------------------- 11624. Лабораторен практикум №7. Масиви--------------------------------------------------------------12825. Използвана литература--------------------------------------------------------------------------------129

2

Page 3: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Алгоритми1. Що е алгоритъм?

Всеки знае какво точно трябва да направи, за да си измие зъбите, да си приготви чантата за другия ден, да се обади на някого по телeфона. Но не е толкова лесно да ушиеш панталон, да пресметнеш обема на даден камион или на домашния хладилник. По голямата част от човешките дейности могат да се изпълнят като последователност от отделни по-малки елементарни действия (действие, което не се нуждае от пояснение, за да бъде изпълнено). За някои дейности тази последователност е по-сложна, и запомнянето, и изпълнението й е не винаги лесно.

За да може даден изпълнител да извърши дадена дейност, той трябва да познава точната последователност от елементарни действия, които трябва да изпълни. За целта той трябва да получи точно предписание с инструкции, за това какви действия трябва да извърши и в каква последователност. Такива предписания е прието да се наричат алгоритми.

Понятието алгоритъм произлиза от името на средноазиатския математик Мохамед ибн Муса ал Хорезми (от град Хорезми, днес Хива в Узбекистан), живял в периода между 780 и 850 година. В своите математически съчинения той е описал алгоритмите за четирите основни аритметични операции. Приема се, че това са едни от първите описания на алгоритми.

Да разгледаме няколко примера:Пример 1:

Алгоритъм за намиране периметъра на правоъгълник.

1.Определя се дължината а и ширината b на правоъгълника.2.Пресмята се периметъра Р на правоъгълника по формулата: Р = 2(a+b)3.Съобщава се Р.

Пример 2: Алгоритъм за намиране корена х на уравнение от вида

а.х = b

1.Определят се коефициентите а и b на уравнението; 2.Пресмята се х по формулата: х = а:b 3.Съобщава се x.

Пример 3:Алгоритъм за намиране на най-голямото от три числа

1.Определят се числата a, b и c.2. На m се присвоява а.3.Ако b>m, на m се присвоява стойността на b.4.Ако c>m, на m се присвоява стойността на с.5.Съобщава се m.

В различните учебници могат да се намерят разнообразни определения на понятието алгоритъм. През годините то е претърпяло известно развитие. За него няма формална дефиниция, но на кратко след разгледаните примери можем да се спрем на следното определение:

Последователност от инструкции, след изпълнението на които се достига до решението на всички задачи от даден клас, или до заключението, че няма решение, се нарича алгоритъм.

Могат да се посочат още редица примери за алгоритми и тяхното описание е основна дейност на програмистите, тъй като те, съобразявайки елементарните действия, които може да изпълнява даден компютър, трябва да опишат даден алгоритъм така, че след изпълнението му компютърът да открие верния резултат.

За да може едно предписание от действия да е алгоритъм, то трябва да притежава някои основни характеристики.

3

Page 4: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

2. Основни характеристики на алгоритмите

а) масовост - алгоритъмът трябва да може да решава възможно най-голям клас задачи. Например, ако бяхме написали предписание за пресмятане на периметъра на правоъгълник със страни 5 и 2, то нямаше да е алгоритъм, тъй като решава само една конкретна задача. Веднага можем да забележим, че и трите алгоритъма, които описахме имат тази характеристика.

б) определеност (детерминираност) - алгоритъмът трябва да е описан така, че резултатът от изпълнението му да не зависи от изпълнителя. Тоест при едни и същи входни данни, независимо от изпълнителя се получават едни и същи резултати.

в) резултатност - характеристика, която изисква алгоритъмът да води до получаване на резултат или до съобщение, че няма такъв, при всеки набор от входни данни.

Ясно е, че първият от примерните алгоритми винаги е резултатен, защото входните данни са дробни числа и с тях трябва да се извършват операциите + и -, които са допустими за всички числа и винаги прилагането им води до получаване на резултат. Не е така, обаче с втория пример: Ако се опитаме да намерим х, при а=0 и b=5, изпълнявайки алгоритъма ще се натъкнем на операцията деление на 0, която не е допустима за никои две числа. Все пак добре знаем какво би трябвало стандартно да отговори нашият алгоритъм: в този случай: "няма решение", докато в случая когато а=0 и b=0, резултатът от изпълнението на алгоритъма трябва да бъде съобщението "всяко х е решение". Ето защо се налага да коригираме описанието на този алгоритъм, съобразно с последното изискване.

Алгоритъм за намиране корена х на уравнение от видаа.х = b (втори вариант)

1. Определят се коефициентите а и b на уравнението;2. Проверява се стойността на а;3. Ако a=0, се проверява стойността на b;

3.1. Ако b=0, се съобщава: "всяко х е решение"3.2. Ако b0, се съобщава: "няма решение"

4. Ако а0, се пресмята х по формулата: х = а:b и се съобщава х.

3. Средства за описание на алгоритмите

Описанието на алгаритмите е предназначено за конкретния изпълнител. То трябва да е оформено така, че да бъде разбираемо и ясно за изпълнение. Все пак по един начин бихме описали алгоритъм предназначен за изпълнение от човек и по съвсем друг начин, ако трябва да го изпълнява компютър. Да разгледаме основните средства за описание на алгоритмите.

а) словесно описание – алгоритъмът се описва с думи на един от говоримите езици. Така описахме трите примерни алгоритъма, които разгледахме.

Веднага се забелязват три основни недостатъка на словесното описание: много е обемно и трудоемко; разбираемо е само за хора, знаещи съответния език; в говоримите езици много често се допускат двусмислици, което противоречи на

изискването за детерминираност.Ето защо се налага да се търсят други средства за описание на алгоритмите.

б) чрез блок-схеми – този метод е бил приет като средство за описание на математически алгоритми. Блок-схемата представлява съвкупност от геометрични фигури, наречени блокове, свързани помежду си със стрелки. Всеки от блоковете има различно предназначение и по този начин се описват инструкциите, докато стрелките показват реда, в който се изпълняват инструкциите.

Ето основните блокове, които се използват при описанието на блок-схеми: блок за начало – представлява овал, в който не влиза нито една стрелка, а излиза само една.

Използва се за посочване на началото на алгоритъма (фиг. 1); блок за край - представлява овал, от който не излиза нито една стрелка, а влиза само една.

Използва се за посочване на края на алгоритъма (фиг. 2);

4

Фиг. 2Фиг. 1

Page 5: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

блок за вход – оформя се като трапец, чиято голяма страна е отгоре. В този блок влиза само една стрелка и излиза само една. Означава, че в алгоритъма се въвеждат някакви стойности на величини, посочени в блока (фиг. 3).

блок за изход - оформя се като трапец, чиято голяма страна е отдолу. В този блок влиза само една стрелка и излиза само една. Означава, че от алгоритъма се извеждат някакви стойности на

величини, посочени в блока (фиг. 4). Трябва да се отбележи, че ако алгоритъмът предполага изход от няколко различни позиции, то техните стрелки ще бъдат насочени към единствената стрелка, влизаща в блока за изход.

аритметичен блок – представлява правоъгълник, в който влиза само една стрелка и излиза само една. В блока се записват един или няколко израза, които трябва да се пресметнат и да се присвоят на някаква величина. Наричат се изрази за присвояване (фиг. 5).

условен блок – има форма на ромб и в него е записано някакво условие, което трябва да се провери. В блока влиза само една стрелка, а излизат точно две – едната се означава с “да”, а другата – с

“не”. В блока се проверява условието и ако е истина изпълнението на алгоритъма продължава по посока на стрелката, означена с “да”, в противен случай – по посока на “не” (Фиг. 6).

5

Фиг. 3

Фиг. 4

Фиг. 5

да

не

Фиг. 6

да

не

Page 6: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

блок-подалгоритъм – обединява съвкупност от елементарни действия, оформени като самостоятелен алгоритъм. Блокът е шестоъгълен и има един вход и един изход. В описанието на алгоритъма се приема, че преминавайки през този блок изпълнителят извършва всички елементарни действия, предвидени в подалгоритъма (Фиг. 7).

блок за пренос – използва се когато алгоритъма трябва да се пренесе на друга страница или на друго място на същата страница. Той е кръгъл и в него се записва число. Има два вида блока за пренос – изходен и входен. В първия само влиза стрелка, а във втория само излиза. На всеки един изходен блок

за пренос трябва да съответства входен със същото число записано в него. Това означава, че алгоритъма, след като премине през изходния блок за пренос продължава от там, където сочи входния блок (фиг. 8).

Да разгледаме блок-схемите на трите алгоритъма, които предложихме като примери.

6

Фиг. 7

a, b

P=2*(a+b)

P

Фиг. 9

Пример 1:

Алгоритъм за намиране периметъра на правоъгълник (Фиг. 9).

Фиг. 8

Page 7: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

7

Пример 3:

Алгоритъм за намиране на най-голямото от три числа (фиг. 11)

Пример 2:

Алгоритъм за намиране корена х на уравнение от вида а.х = b (фиг. 10)

a,b

a=0да

не

b=0

да

не

Всяко х е решение

Няма решение

х := b/a

Фиг. 10

x

да

нене

a,b,c

m := a

b>m да

не

c>m да

не

m := b m := c

Фиг. 11

m

Пример 3Алгоритъм за намиране на най-голямото от три числа

Page 8: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

в) чрез езици за програмиране – езиците за програмиране позволяват алгоритмите да бъдат изразени на език, разбираем от компютрите. Тук ще представим описание на трите алгоритъма съответно на езиците Pascal и C++.

8

Пример 1:

Алгоритъм за намиране периметъра на правоъгълник

на езика Pascalprogram per; var a, b, P: real;begin read(a,b); P:=2*(a+b); writeln(P);end.

на езика C++#include<iostream.h>void main() { float a, b, P; cin>>a>>b; P=2*(a+b); cout<<P<<endl; }

Пример 2:

Алгоритъм за намиране на корена на уравнение от вида а.х = b

на езика C++#include<iostream.h>void main() { float a, b, x; cin>>a>>b; if(a==0) { if(b==0)

cout<<”всяко х е решение\n”; else cout<<”няма решение\n”;

} else

{ x=a/b; cout<<”x=”<<x<<endl;}

}

на езика Pascalprogram ecual; var a, b, x: real;begin read(a,b); if a=0 then begin if b=0 then writeln(‘всяко х е решение’) else writeln(‘няма решение’) end

elsebegin x:=a/b; writeln(‘x=’,x);end

end.

на езика Pascalprogram max; var a, b, c, m: real;begin read(a,b,c); m:=a; if b>m then m:= b; if c>m then m:= c; writeln (m);end.

Пример 3:

Алгоритъм за намиране на най-голямото от три числа

на езика C++#include<iostream.h>void main() { float a, b, c, m; cin>>a>>b>>c;

m=a;if (b>m) m=b;if (c>m) m=c;

cout<<m<<endl; }

Page 9: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Етапи при решаване на задача по програмиранеЩе опишем етапите при решаване на задача по програмиране, използвайки като илюстрация

следния пример:Задача: Да се състави програма, която въвежда от клавиатурата три числа, задаващи

дължините на страните на триъгълник и отпечатва дължините на височините му.

1. Създаване на математически модел на задачата

На този етап е необходимо да се уточни математическият модел на дадената задача. Кои ще бъдат похватите и формулите, моделиращи процеса, който ще се програмира в последствие. В конкретния случай, базирайки се на знанията си по математика може да предложим следния математически апарат за решаване на описаната по-горе задача.

Формулата, в която се дава пряка връзка между страна на триъгълник и височината към нея е тази за лице на триъгълник:

Ако успеем да пресметнем лицето на триъгълника, лесно можем да изразим височината по тази формула.

Известно е, че когато са дадени трите страни на триъгълник, лицето му може да бъде изчислено по Хероновата формула:

, където

След като пресметнем лицето, вече можем да изразим височините от описаните по-горе формули:

По този начин уточнихме математическите похвати, използвани при решаване на задачата и построихме нейния математически модел.

2. Създаване на информационен модел на задачата

За да бъде решена една задача по програмиране, трябва да се уточнят още и данните, които ще постъпят на вход в програмата, както и данните, които ще бъдат изведени като резултат от нея. Налага се да се изясни и това дали ще се наложи използване на някакви междинни резултати. Програмистът трябва да е наясно предварително с основните величини, които използва програмата му. Естествено, допустимо е на този етап да не се прецизират някои детайли, но основните величини трябва да бъдат предварително уточнени.

Ето как ще изглежда информационния модел на разглежданата от нас задача:Входни данни:Променливите a, b, c. Те са реални1 променливи. Програмата трябва да получи стойностите им

от потребителя като вход.Изходни данни:Променливите ha, hb, hc. Те също са реални променливи. Тях програмата извежда след

необходимите пресмятания.

1 В компютърната памет реалните числа се представят на ограничено по обем място и затова е невъзможно да бъдат интерпретирани изцяло. Като говорим за реални числа, се има предвид подмножество на реалните числа.

9

Page 10: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Междинни резултати:За да се пресметнат височините, ще се наложи да се получат междинни резултати, като

полупериметъра и лицето на триъгълника. Ето защо ще използваме дробни променливи и за двете величини: S, p.

3. Описание на алгоритъма

Алгоритъма се описва чрез блок-схема или словесно. Ще изберем кратко словесно описание. Въвеждат се дължините на страните на триъгълника a, b, c.Пресмята се полупериметъра на триъгълника

Пресмята се лицето на триъгълника по Хероновата формула.

Пресмятат се височините на триъгълника.

Извеждат се трите височини ha, hb, hc.

4. Кодиране на алгоритъма

Алгоритъмът се описва на избрания език за програмиране. В нашия случай програмата, която решава задачата е написана на езика С++.

#include<iostream.h>#include<math.h>void main() {

float a, b,c,S,p,ha,hb,hc;cin>>a>>b>>c;p=(a+b+c)/2;S=sqrt(p*(p-a)*(p-b)*(p-c));ha=2*S/a;hb=2*S/b;hc=2*S/c;cout<<”ha=”<<ha<<endl;cout<<”hb=”<<hb<<endl;cout<<”hc=”<<hc<<endl;

}

5. Тестване на алгоритъма и отстраняване на синтактичните грешки

С помощта на средата за програмиране алгоритъмът се въвежда в паметта на компютъра и се тества.

6. Тестване на алгоритъма за логически грешки и отстраняването им

За да се тества алгоритъма за логически грешки се избират специфични входни данни, които трябва да определят дали алгоритъмът работи коректно. При така описания по-горе алгоритъм с входни данни 2, 10 и 7, програмата ще изведе съобщение за грешка, тъй като в определен момент ще се наложи да се намира корен квадратен от –1.

10

Page 11: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

7. Създаване на изпълнима програма.

В нашия случай програмата трябва да се коригира така, че веднага след въвеждането на трите числа a,b и c да се проверява дали те могат да бъдат дължини на страни на триъгълник и ако не – да се изведе подходящо съобщение, а ако могат – да се изпълнят описаните в алгоритъма оператори. След корекцията програмата ще изглежда така:

#include<iostream.h>#include<math.h>void main() {

float a, b,c,S,p,ha,hb,hc;cin>>a>>b>>c;if(a+b>c&&a+c>b&&b+c>a&&a>0&&b>0&&c>0){p=(a+b+c)/2;S=sqrt(p*(p-a)*(p-b)*(p-c)); ha=2*S/a;hb=2*S/b;hc=2*S/c;cout<<”ha=”<<ha<<endl;cout<<”hb=”<<hb<<endl;cout<<”hc=”<<hc<<endl;

}else cout<<“Некоректни данни\n”

}

11

Page 12: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Програмно осигуряване на съвремените компютри 1. Програми

Във всеки момент от време компютърът работи по следният начин :Централният процесор се обръща към оперативната памет, прочита от там поредната инструкция

и необходимите за изпълнението й данни и я изпълнява. Както вече знаем, по този начин компютърът изпълнява едно цяло действие, построено на базата на множество инструкции, които ще наречем команди.

Последователност от команди, които компютърът изпълнява в определен ред се нарича програма.

Тъй като компютърът е машина с програмно управление, той не може да работи без програми. Програмите, необходими за работа на един компютър са различни по своето предназначение.

2. Същност на програмното осигуряване

Казваме, че всички програми които работят на даден компютър образуват неговото програмно осигуряване.

За изразяване на съвкупност от програми в много случаи се използва понятието софтуер (software), противоположно на понятието хардуер (hardware), което както знаем означава апаратната част на компютъра.

Понятието софтуер се разглежда от няколко различни гледни точки. Понякога говорим за софтуер за текстообработка, или за софтуер за счетоводство. В този случай става дума за една или няколко програми с точно определено предназначение. В други случаи говорим за софтуер за определен вид компютри, например за РС или Macintosh.Тогава имаме предвид всички програми, които работят на този вид компютри и определено става дума за много повече програми.

3. Структура на програмното осигуряване

Програмите, работещи на даден компютър се разделят на две основни големи групи (фиг. 12) приложни програми и базови програми.

а) Приложни са тези програми, които превръщат компютъра ни в интелигентна пишеща машина, видео или домашна аудио система. Те са тези, които ни позволяват да превърнем старата, изпокъсана снимка в съвършенна фотография, или използвайки Интернет, да разговаряме с наши приятели от другия край на света.

Познатите вече приложни програми можем да разделим на следните основни групи: текстообработващи системи - съвкупност от програми, предназначени за писане,

редактиране, оформяне и отпечатване на текст: Word Pad, Microsoft Word и др. графични редактори – програми, предназначени за създаване, редактиране и отпечатване

на графични обекти - картинки, графики, снимки и др.: Paint, Power Point, Corel Draw, Photo Shop и др. електронни таблици - програми, обработващи наредена по определени правила

информация: Microsoft Excel и др. информационни системи - програми, които съхраняват огромни обеми от информация и

при заявка от наша страна извеждат необходимата справка: системите в пощата, на гарата, в кварталните видеотеки и др.

експертни системи - програми, които освен базата данни разполагат и с база знания и правила, според които могат да правят изводи. Те имитират човешкото мислене и по дадени начални сведения, могат да генерират експертни предположения. Например: ако кажете на една такава експертна система, която е специализирана в областта на медицината, че имате температура, хрема и ви болят главата и гърлото, тя би трябвало да ви отговори, че сте настинали или нещо от този род.

мултимедийни програми - превръщат компютъра във висококачествена аудио- и видео- система, като позволяват да се слуша музика, да се гледа филм, да се правят записи и др. Такива са Winamp, MDVD, Codeck и др.

компютърни игри - отделяме ги специално от мултимедийните програми, защото те са особен вид програми, които служат за забавление на малки и големи и всички добре ги позвават.

12

Page 13: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Има и други видове специализирани програми, но тези които описахме са най-често използваните.

а) Базови се наричат тези програми, които осигуряват работата на компютъра. Те пряко управляват работата на устройствата му. Към този вид се включват програмите на операционните системи и тези в средите за програмиране.

Среда за програмиране е такъв вид система от програми, която позволява да се създават други програми - да се пишат, редактират и изпълняват. Познаването на среда за програмиране е задължително за всеки, които би искал да посвети живота си на тази невероятна магия - програмирането.

13

Програмно осигуряване

Базово програмноосигуряване

Приложно програмноосигуряване

елек

трон

ни

табл

ици

инф

орма

цион

ниси

стем

и

текс

тови

ре

дакт

ори

граф

ични

ре

дакт

ори

мулт

имед

ийни

прог

рами

операционнисистеми

системи запрограмиране

И Г Р И

Фиг. 1

Фиг. 12

сервизни програми

Page 14: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Среди за програмиране1. Що е програмиране?

Програмите, които компютърът изпълнява са кодирани чрез нули и единици, защото това е единственият език, който компютърът разбира. За един човек писането на поредици от нули и единици е трудна и досадна работа. При това много лесно може да се допуснат грешки.

Например много лесно можем да помислим за еднакви следните две редици от нули и единици: 010111111011111 и 0101111111011111Ето защо програмистите пишат своите програми на специални езици, за които има програми -

преводачи. Те могат да преведат програма написана на този език на езика на компютъра. Основно задължение на програмистите е да напишат програмата така, че изпълнявайки я, компютърът да прави точно това, което е било предвидено. След това с помощта на специални програми, наречени среди за програмиране, програмистите въвеждат своите програми чрез клавиатурата в оперативната памет на компютъра и активирайки програмата-преводач създават изпълнима програма, т.е. програма, написана на езика на компютъра.

2. Елементи на средите за програмиране

Всяка среда за програмиране е съставена от множество програми, които съответстват на различните етапи при решаване на една задача по програмиране.

а) текстов редактор - той предоставя възможност за въвеждане от клавиатурата на текста на програмата, с използване на основните операции за работа с текстове и тяхното редактиране (меню EDIT). Осигурява възможности за съхраняване и прередактиране на програмите.

б) транслатор - компютърна програма, предназначена да преобразува (превежда) програми, написани на даден език за програмиране на езика на компютъра. При това преобразуване, транслаторът анализира програмата и за така наречените синтактични грешки, произтичащи от това, че дадена част от описанието алготитъма не отговаря на правилата за писане на програмите на конкретния език за програмиране. Новополучените програми са еквивалентни на първоначалните, т.е. работят по същия начин или с други думи: при едни и същи входни данни дават еднакви резултати.

Можем да си представим ролята на транслатора като тази на преводачите от един говорим език на друг. Известно е, че преводачите работят по различен начин: някои превеждат разговорите между няколко събеседници (симултантен превод). Те изчакват разговарящият да произнесе своята реплика и след това я превеждат веднага. Други преводачи получават написан текст, превеждат го изцяло и го написват отново, но вече на другия език. Докато в първият случай преводачът винаги трабва да е до нас, за да може да превежда всяка реплика, във втория ние можем да ползваме преведения вече текст и без присъствието му.

По подобен признак можем да разделим и видовете транслатори, които са - компилатори и интерпретатори.

Интерпретаторът е транслатор, който приема като вход всяка отделна команда на програмата, проверява я за грешки и я изпълнява, след което преминава към следващата команда и т.н.

Компилаторът е транслатор, който приема като вход цялата програма, проверява я за грешки и

14

Етап 1Транслиране на програмата

Етап 2ИзпълнениеНа програмата

Транслатор за дадения ЕП

Програма за ЕП

Компютър Програма МЕ

Входни данни за програмата

Програма на МЕ Резултат от изпълнението на

програматаКомпютър

Фиг. 13

Page 15: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

я превежда. В резултат се получава изпълнима програма. Тя може да се изпълнява многократно и без наличието на компилатор на дадения компютър (фиг. 13).

За съжаление, както компилаторът, така и интерпретаторът могат да открият само синтактичните грешки в дадена програма. Друг вид грешки, които често се допускат, особено от начинаещите програмисти, са логическите грешки, т.е. програмата не изпълнява това, за което е предназначена. Тези грешки се откриват много трудно и за това е прието програмите да се проверяват, като се използват предварително подготвени входни данни, за които резултатът е известен. Те се наричат тестови примери.

в) дебъгери (Debuger) - програма за търсене на грешки. Тя позволява да следим изпълнението на цялата програма стъпка по стъпка и по този начин да открием логическите грешки. По време на преглеждането дебъгерът може да показва и някои междинни резултати, които позволяват да се определи мястото и вида на логическата грешка.

г) библиотеки приложни програми (функции) В структурата на сложните обекти обикновенно присъстват по-прости. Например: Учебниците се изграждат от няколко раздела. Разделите се състоят от няколко теми.

Всяка тема включва няколко урока. Всеки урок се състои от няколко точки. Мебелите в дома и в офиса се "сглобяват" от отделни секции (според пространството и

вкуса). Влаковата композиция се състои от локомотиви и вагони (променлив брой и различни

видове). Организационната структура в армията е йерархична. Например:

- полкът се състои от батальони- батальонът се състои от роти - ротите от взводовe- взводовете от отделения и т.н.

Във всяка житейска ситуация можем да открием примери в подкрепа на извода, че сложните структури се изграждат от по-простите градивни елементи.

Подчинявайки се на този принцип още от самото начало в системите за програмиране се поставят основите на автоматизацията на програмирането.

Много скоро след създаването на първите компютърни програми, специалистите са осъзнали, че по сложните програми биха могли да се изграждат от предварително написани и проверени програми, наречени стандартни програми (функции).

Този начин на организация на програмирането има редица предимства: ако една програма е вече готова, няма да губим време да я пишем, да търсим грешките и да я компилираме. Тя просто се взема от библиотеката стандартни програми и се включва в нашата програма.

Например в езика С++ всички функции за въвеждане и извеждане са дадени като отделни библиотеки (stdio.h, iostream.h и др.). В друга библиотека са всички математически функции (math.h) и др.

д) свързващ редактор Понякога една програма е твърде голяма, за да се запише като един файл, освен това различните

части може да се пишат от различни програмисти. Понякога части от дадена програма могат да бъдат използвани и в друга, така че отново се налага тези части да бъдат оформени като самостоятелни файлове. За да бъдат изпълнени е необходимо те да бъдат обединени в една цяла програма, което се осъществява от свързващ редактор. Друга роля на свързващия редактор е да добави към програмата библиотека която тя използва.

е) меню за изпълнение на програми (RUN) - чрез него се извършва стартиране на програми или на части от тях. Може да се представи изпълнението на програмата или изпълнението и да се извърши в режим, в които може да бъде наблюдавано.

ж) помощна информация - към системите за програмиране винаги се прилага и програма за помощна информация, описваща както работата на самата система, така и правилата за запис на различните елементи на съответния език за програмиране.

15

Page 16: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Среда за програмиране Borland C++

1. Стартиране

Знаем различни варианти за стартиране на програми, които зависят от допълнителните настройки, които правим в работната среда. Най-сигурният начин, по който можем да стартираме средата Borland C++ е:

C:\BorlandC\Bin\Bc.Exe

2. Работен екран

Работния екран (фиг.2) на средата за програмиране Borland C++ предлага инструменти за редактиране, съхраняване, тестване и изпълнение на програми. Основните му елементи са следните:

ивица с команди; работна област – включва в себе си няколко вида прозорци:

текстов прозорец – такива може да има няколко, в зависимост от това върху колко програми работи програмистът в дадения момент;

прозорец за съобщения – това е прозорец, в който системата извежда информация за своята работа – компилиране, свързване, стартиране и др. Ако по време на компилация бъдат открити грешки, те също се извеждат в този прозорец;

прозорец за проследяване на стойностите на променливи и изрази по време на изпълнението на програмата – визуализира се с помощта на комбинацията от клавиши Ctrl+F7. При това се задава име на променливата или израза, чиято стойност искаме да проследим.

Прозорците могат да се затварят, да се максимизират, да променят размера си. Всеки от тях разполага със скролиращи ленти, които се появяват когато информацията предвидена за изобразяване на екрана е твърде много, за да се изобрази на един екран.

16

фиг. 14

затваряне на прозорец

максимизиране/минимизиране

на прозорец

скролиращи ленти промяна на

размера на прозореца

меню ивица

прозорец за проследяване на стойности

прозорец за съобщения

информационна лента

Page 17: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

3. Текстов редактор:

а) въвеждане и редактиране на текст;

Текстовия редактор предоставя всички стандартни инструменти за текстообработка. Двата режима на работа – вмъкване и заместване, се превключват чрез клавиша Insert. Движението на курсора в текстовото поле се осъществява чрез клавишите – стрелки и чрез клавишите Page Up, Page Down, Home, End, като тяхното значение е същото каквото е в стандартните текстови редактори.

Page Up – придвижва курсора с един екран нагоре на същата позиция в реда;Page Down– придвижва курсора с един екран надолу на същата позиция в реда;Home – придвижва курсора в началото на текущия ред;End – придвижва курсора в края на текущия ред;Ctrl +Page Up – придвижва курсора в началото на текста;Ctrl + Page Down– придвижва курсора в края на текста;Ctrl + Home – придвижва курсора в началото на текущия екран, запазвайки хоризонталната му

позиция;Ctrl + End – придвижва курсора в края на текущия екран, запазвайки хоризонталната му позиция;Другият стандартен начин за придвижване на курсора е чрез щракване на левия бутон на

мишката на желаното място.

б) маркиране

Маркирането на текста се извършва по стандартните начини – чрез мишката или чрез клавиша Shift и клавишите - стрелки;

в) копиране, преместване и изтриване /Edit/

Тези операции са реализирани както в останалите текстови редактори с командите Cut, Copy, Paste и Clear, но клавишните комбинации, съответстващи на тези команди, не съвпадат с тези в редакторите на Microsoft.

Съответствието между командите и клавишните комбинации е следното:

Команда Клавишна камбинацияEdit/Undo Alt+BkSpEdit/Cut Shift +DelEdit/Copy Ctrl + InsertEdit/Paste Shift + InsertEdit/Clear Ctrl + Delизтриване на текущия ред Ctrl+Yизтриване на маркиран текст Ctrl+K,Y

Всяка една от клавишните комбинации може да бъде разгледана в самата среда BorlandC, срещу името на съответната команда в менюто.

г) търсене и заместване

В много случаи може да се наложи претърсване на програмата за някакъв текст и/или заместването му с друг. Това се реализира с помощта на командите от меню Search;

4. Изпълнение на програми

а) меню RUN

Съдържа команди за изпълнение на програми (клавишната комбинация за изпълнение на програма е Ctrl + F9 – тя предизвиква изпълнението на командата Run/Run, която осигурява компилирането и последващото стартиране на програмата;

б) меню Compile

Съдържа команди за компилиране на програми (клавишната комбинация за компилиране на програма е F9 – тя предизвиква изпълнението на командата Compile/Make, която осигурява компилирането на програмата и създаването на изпълним файл);

в) преглеждане на резултати от изпълнението

Резултатите от изпълнението на програмата могат да се разглеждат чрез комбинация Alt + F5.

17

Page 18: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

5. Файлове, създавани от средата за програмиране BorlandC:

файл с разширение СРР – съдържа текста на програмата и се получава след изпълнението на командата File\Save или чрез клавиша F2.

файл с разширение ВАК – архивно копие на програмата. Прави се автоматично от средата, след изпълнение на Save.

файл с разширение ЕХЕ – изпълнима програма, еквивалентна на написаната. Създава се при компилиране на синтактически правилана програма.

6. Проследяване на изпълнението на програмата.

Проследяването на изпълнението на програма е много удобно, както при изучаването на даден алгоритъм, така и при търсене на логически грешки в програмата. Средата BorlandC дава възможност за такова проследяване. При нужда може да се изведе прозорец, съдържащ определени променливи и изрази, чието изменение искаме да проследим.

а) извеждане на проследяващ прозорец

Извеждането на този прозорец става с помоща на клавишната комбинация Ctrl + F7 или чрез командата Debug/Watches/Add Watch. След изпълнението и на екрана се появява прозорец и се очаква въвеждането на израза, който искаме да проследим. Въвеждаме израза и избираме бутона ОК. Веднага след това на екрана се появява прозорец, съдържащ въведения израз и неговата стойност (ако е изчислена до момента). При следващото изпълнение на тази команда новият израз се появява след стария.

Следящия прозорец може да се редактира чрез командата Debug/Watches/Edit Watch или чрез позициониране на курсора на прозореца върху даден израз и натискане на клавиша Enter.

Допуска се и изтриване на изразите, които се проследяват. Това става чрез командата Debug/Watches/Delete Watch или чрез маркиране на съответния израз и натискане на клавиша Delete.

б) Проследяване на изпълнението на програмата

Осъществява се чрез последователно натискане на клавиша F7 или чре командата Run/Trace Into. На всяка стъпка се изпълнява по един ред в програмата и се изчисляват всички изрази, описани в този ред.

Задачи за упражнение:

Зад. 1. Напишете текста на следната програма на С++#include<iostream.h>void main(){

cout<<”Това е първата”; cout<<”програма, която пиша на С++”; cout<<”Успех!Чао\n”;}Зад. 2. Запишете програмата под име Р1 със следната последователност от команди File/Save asЗад. 3. Компилирайте програмата (проверка за грешки и превод без да се стартира - F9).Зад. 4. Ако има грешки, поправете ги и съхранете промените с клавиша F2.Зад. 5. Предизвикайте изпълнението на програмата с Ctrl + F9.Зад. 6. Използвайте Alt + F5 или Windows\User screen, за да видите резултата.Зад. 7. Върнете се към средата с натискане на произволен клавиш.Зад. 8. Отворете нов файл и въведете следната програма на С++

#include<iostream.h>void main(){

cout<<”Аз се казвам ХХХ.\n”;cout<<”Здравей ХХХ”;cout<<”Приятен ден!”;

}Зад. 9. Променете вторият ред cout<<“\n\n Здравей ХХХ!”;

18

Page 19: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

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

Всички ние сме учили в една или друга степен чужди (говорими) езици. Усвояването на един език е свързано с изучаването на неговите елементи – азбука, структура на изреченията, правила за образуване на изреченията, смисъла на различните думи и словосъчетания и др. Езиците за програмиране се различават от говоримите езици, но все пак изучаването им много прилича на изучаването на говорим език. Ето защо, базирайки се на опита, който имаме при усвояване на чужди езици, дори и на езика на математиката, запознаването ни с конкретен език за програмиране трябва да започне с усвояване на елементите на езика – знаците и символите, с които ще си служим. Тук ще изброим елементите на езиците за програмиране, като за илюстрасия ще използваме езика С++.

1. Азбука на езиците за програмиране (С++) -

Наборът от допустими символи – букви, цифри и комбинации от други символи, необходими за изграждане на всички останали елементи на езика, се нарича азбука на езика за програмиране.

а) букви – в основата обикновено е заложена латинската азбука - използват се всички малки и главни латински букви. В езика С++ се прави разлика между малките и главните букви. Символът долно тире “_” също се приема за буква.

б) цифри – всички арабски цифри 0, 1, ..., 9 в) служебни символи на езика- , . : ; ? ! < > ( ) [ ] + - * / \ = & % ~ “ { } # $ ^ >=

<= == || != += *= -= /= и др. г) запазени думи – for, int, void, do, if, while, floid, long, else, struct и др. Използват се за

описание на различни елементи на програмата. Записват се винаги с малки букви. Тяхното значение не може да бъде променено от програмиста в текста на програмата.

д) служебни думи – cin, cout, abs, fabs printf, scanf и др. те имат точно определено предназначение в програмата. За разлика от запазените думи, те могат да се използват за наименования на други елементи на програмата, но тогава те губят стандартното си предназначение. Ето защо, използването на стандартните думи в смисъл, различен от стандартния, не е препоръчително.

е) разделители – интервал, ;, “нов ред” и табулация. Аналогично на практиката с текстови редактори, тези знаци се използват като разделители, а “нов ред” за край на текущият ред.

Задача 1: Открийте отделните елементи от азбуката на езика С++ в следните програми:а)#include<iostream.h>void main(){

int a, b, s; a=5; b=4; s=a*b;}

б)#include<iostream.h>void main(){

cout<<”Това е първата “; cout<<”програма на С”;}

2. Коментари

Много често се налага написана програма да се използва не от автора, а от потребители. Понякога, след известно време и самият автор на програмата забравя какво е имал предвид при писането и. В такива ситуации е добре да има текстове, които поясняват основните етапи в нея и тяхното предназначение. В езиците за програмиране те се наричат коментари.

Коментарите позволяват въвеждане в програмата на произволен текст на естествен език, с цел разясняване на предназначението на даден оператор, променлива, подпрограма и др.. В тях може да се използва кирилица и всички други символи, които могат да се въведат от клавиатурата на компютъра.

19

Page 20: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

В езика С++ има два вида коментари: едноредов (действащ до края на реда) - задава се с // и се използват за обявяване на текста

до края на реда за коментар. многоредов - за начало на коментара се задава последователността /*, а за край */. Този вид

означение обявява за коментар само тази част от текста на програмата, който е заграден от посочените символи.

Реализирането на по-сложни алгоритми изисква задължително използване на коментари. Те могат да се поставят на всяко място в програмата. Могат да бъдат произволно големи. Не влияят върху бързината на изпълнение на програмата.

Задача 2: Вмъкнете коментари в програмите от Задача 1 по известните ви начини.

3. Величини

а) определениеЦелта на запознаването ни с конкретен език за програмиране е да добием представа как се

записват алгоритмите, за да могат да се изпълняват от компютър. Знаем, че алгоритъм е последователност от елементарни действия, чието изпълнение води до решаване на дадена задача. Това означава, че освен с азбуката на езика, ние трябва да се запознаем и с начините, по които ще означаваме елементарните действия в него и величините, за които се отнасят.

Величините се използват, за да се представят данните, които алгоритъмът трябва да обработи. Те могат да се изполват по време на изпълнение на целия алгоритъм или за съхраняване и обработка на междинни резултати.

Величината е характеристика на даден предмет или явление.Величини, например, са следните характеристики: обем, маса, цвят, материал, дължина, ширина

и др.

б) видове величини

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

протичат при дадено явление и въздействията, които те имат върху даден предмет. Пример за такива величини са математическите числа e и π, земното ускорение g, температурата на кипене и замръзване на водата при морска височина и др.

От гледна точка на езиците за програмиране константите са величини, за стойностите, на които се заделя място в оперативната памет на компютъра, те имат собствено име и стойността им не се променя в процеса на изпълнение на програмата..

променливи Голяма част от величините представят дадена характеристика, която може да се промени в

процеса на изпълнение на програмата. Променливите са величини, за стойностите, на които се заделя място в оперативната

памет на компютъра, те имат собствени имена и могат да заемат различни стойности в процеса на изпълнение на програмата.

В израза за пресмятане дължината на окръжност участват няколко величини:С=2* π *r;

Тук C и r са променливи, защото могат да са дължина и радиус на различни окръжности, а π е константа.

литералиЧислото 2 играе важна роля в тази формула, но то не отговаря на нито едно от определенията за

константи и променливи дадени по-горе. По-скоро бихме казали, че то е константа, но забелязваме, че няма собствено име и за него няма да се задели място в оперативната памет на компютъра. Величини от този вид се наричат “литерали”.

Литерали – величини, които нямат собствени имена, а само участват със своята стойност в процеса на изпълнение на програмата.

Зад понятието константа и променлива се крие в действителност клетка от оперативната паметта на компютъра, в която се съхранява текущата стойност на променливата. Всяка клетка от паметта има определен адрес. Използването на името на константата или променливата е аналогично на обръщение към адреса на съответната клетка от паметта и на използване на нейното съдържание, т.е. на стойността на променливата.

20

Page 21: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

4. Идентификатор

Програмите в езика С++ различават променливите, константите и другите обекти в програмите чрез техните имена. Те се задават чрез идентификатори.

Идентификаторът е комбинация от букви и цифри, започваща винаги с буква.При задаване и използване на идентификаторите трябва да се имат предвид следните важни

Забележки В С++ е позволено символът за подчертаване да се използва като буква (например А_B е

идентификатор); не се препоръчва символът _ да е първи, тъй като се използва от много служебни и

системни програми; идентификаторът трябва да е различен от ключовите думи за езика С++. Единствения

случай, когато в качеството на идинтификатор се използва ключова дума е ако в него се използва една или повече главни букви.

Пример 1:forward – е валиден идентификатор независимо, че съдържа for;

FOR – валиден идентификатор;

for – невалиден идентификатор;

Тъй като, както вече казахме, в С++ се прави разлика между малки и големи букви, трябва да се има пред вид, че един идентификатор трябва да се използва навсякъде, написан по един и същи начин;

Пример 2:А а, Name name

Всяка променлива или константа се означава с име, представляващо идентификатор. Обикновено се стремим името да съответства в някаква степен на смисъла на представяната информация.

Задача 3: Посочете в програмите от Задача 1 идентификаторите.

5. Оператори

Последователност от елементи на езика, записани по определени правила, които предизвикват изпълнение на една или повече команди, се нарича оператор.

6. Подпрограма(функция)

В много случаи алгоритмите са твърде сложни и е удачно те да бъдат разделени на по-прости подалгоритми, което би улеснило тяхното описание. Подалгоритмите в езика С++ се описват чрез специални елементи на езика, наречени подпрограми или по-точно – функции.

7. Правила за запис и правила за изпълнение на елементите на езиците за програмиране

Вече стана ясно, че за да се изпълни една програма, написана на език за програмиране, тя трябва да се преведе от компилатора и да се получи изпълнима програма, която изпълнява точно това, което е предвидено в изходната програма. Ето защо е необходимо да познаваме елементите на езика за програмиране, който ползваме, като за тях са важни следните две характеристики:

правила за запис; правила за изпълнение.Да се спрем по-подробно на тях.

а) правила за запис

Всеки език има точно определени правила, по които се построяват неговите конструкции. Например в българския език има точно определени правила, по които се построяват изреченията. Прието е науката за тези правила да се нарича синтаксис. Така ще наричаме и правилата за запис на елементите на езиците за програмиране.

21

Page 22: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

б) правила за изпълнение

Не винаги правилата за запис са достатъчни за да се построи едно правилно изречение.Пример 3:Известно е, че синтактически правилно е едно изречение да бъде съставено от подлог, сказуемо и

допълнение. Като подлог и допълнение могат да се ползват съществителни, а като сказуемо – глаголи. Нека са ни дадени съществителните момиче и ябълка и глаголът яде. Да видим колко синтактически правилни изречения можем да съставим с тях.

Момичето яде ябълка.Ябълката яде момиче.

Второто изречение е правилно синтактически, но в него липсва смисъл. Ето защо за даден език е много важен смисъла на езиковите конструкции. Науката, която се занимава с това, се нарича семантика. Така ще наричаме и правилата за изпълнение на елементите на езиците за програмиране.

Става ясно, че за да познаваме един елемент от езика ние трябва да сме наясно с неговите синтаксис и семантика. Ето защо от сега нататък при изучаване на езика С++ ние ще се спираме подробно и на двете характеристики на всеки негов елемент.

Задачи за упражнение:

Зад. 1. Посочете кои от изброените последователности от знаци могат да бъдат идентификатори и кои не, и защо?

Max1, 1sum, max_1, max, max 1, int2

Зад. 2..Създайте нови идентификатори, като използвате тези от Зад. 1.

22

Page 23: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Структура на програма на С++1. Изпълнение на С++ програма:

а) предпроцесор (предкомпилатор)

Поради особеностите на езика С++, изпълнението на една програма, написана на него преминава през няколко етапа. Преди всичко много често се налага към нашата програма да се добавят написани от преди фрагменти, наречени заглавни файлове, които съдържат библиотеки от различни декларации на величини, подпрограми и др. Пример за това са програмите, които въвеждат данни от клавиатурата и извеждат данни на екрана. Тъй като езиците С и С++ нямат вградени оператори за тази цел, се налага да се използват допълнително библиотеки, съдържащи инструменти за вход-изход.

За да могат тези библиотеки да се включат към текста на нашата програма, се налага този текст да бъде обработен от специална програма, наречена предпроцесор (предкомпилатор). Ролята на предпроцесора е да обработи първоначалния текст на програмата в зависимост от специални команди, написани в началото и. Тези команди се наричат директиви на предпроцесора и се различават от останалия текст на програмата по това, че всяка директива се пише на отделен ред, като реда започва винаги със знака #. Директивите посочват на предпроцесора, че трябва да включи дадена библиотека към текста на нашата програма или, че трябва да замести даден символен низ с друг и т.н.

б) етапи на изпълнение на С++ програма

Програма на ЕП

предпроцесор

прекомпилаторПрограма 2

компилаторИзпълнима програма

изпълнение

При описаното изпълнение могат да бъдат открити грешки при всеки един от етапите. Тогава се

налага те да се поправят и отново да се пристъпи към изпълнение на програмата. Когато програмата е вече готова, с отстранени грешки и уточнен алгоритъм, може да се изпълнява само получената като краен резултат изпълнима програма.

2. Общ вид на С++ програма:

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

а) директиви към предпроцесора

Най-често ще използваме следните две директиви на предпроцесора: директива за включване на заглавен файл:

#include <име на заглавен файл>или

#include “име на заглавен файл”В първият случай предпроцесора търси файла със зададеното име в специалната папка за

заглавни файлове, която всяка система за програмиране използваща езика С++ има. Тази папка се казва include. Създава се по време на инсталацията на системата за програмиране и се намира в папката, в която са папката bin и останалите папки на системата.

В папката include обикновенно се записват тези библиотеки, които стандартно се поддържат от съответната система за програмиране. Ако решим да създаваме собствени библиотеки, не е добре да ги поставяме отново там. Ето защо се предлага втората възможност. Когато името на файла е зададено в кавички, предпроцесора го търси в текущата папка или евентуално на друго място, което е посочено точно в името на файла.

директива за дефиниране на стойност на идентификатор:#define идентификатор стойност

23

фиг. 15

Page 24: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Смисълът на тази директива е следният: предпроцесора обхожда целия текст на програмата и навсякъде където намери описания идентификатор го замества с указаната стойност. Тя се използва с цел да се спести писане или когато това е константа, която може да бъде променяна на различни етапи на разработване на програмата.

б) декларации на глобални обекти

В тази част на програмата се декларират различни величини, типове и други обекти, които трябва да са достъпни от всички участници в програмата, т. е. от всички подалгоритми (функции), които използваме в нея. По-късно ще се спрем по-подробно на глобалните обекти. За сега ще пишем само програми, в които не се налага да се декларират глобални обекти.

в)описание на функции, една от които е главна и винаги се нарича main

В една програма на С++ може да има множество подпрограми (функции), описващи различни алгоритми, но винаги трябва да има точно една главна функция, която се нарича main и от нея започва изпълнението на програмата. Една функция ще бъде изпълнена в нашата програма, само ако е била извикана от функцията main или от друга функция, която вече се изпълнява. Независимо от ролята си в дадена програма всяка функция се описва по определени правила и има следните елементи:

тип_на_функция име_на_функция (параметри_на_функция ){ дефиниция на различни величини и оператори;}Тази част от функцията, която е заградена в {} се нарича тяло на функцията. Да разгледаме една програма, която извършва нещо сравнително лесно – прочита от

клавиатурата две числа и ги отпечатва в нарастващ ред. За да може да направи това програмата сравнява двете числа и ако първото е по-голямо от второто им разменя местата с помощта на специално описана функция. Програмата е написана на езика С++ и повечето елементи в нея са непознати, но по-нататък когато се запознаем по-подробно с езика, ще се върнем отново на тази програма, за да изясним по-подробно нейните елементи.

#include <iostream.h>void swap(int &x, int &y)//функция, която разменя стойностите на две цели числа{ int z=x ;

x=y ;y=z

}void main(){

int a,b;cin>>a>>b; //въвеждат се две цели числа a и b от клавиатуратаif(a>b)swap(a,b); //ако a>b техните стойности се разменятcout<<a<<’ ‘<<b<<endl; //на екрана се извеждат стойностите на а и b, отделени с един интервал

}

3. Правила за подреждане на програми

В практиката често върху една и съща програма работят екип от програмисти. Често се налага те да четат взаимно своите програми. Ето защо е добре те да бъдат написани така, че да могат лесно да се четат и разбират. Това се налага дори и когато човек работи сам и иска да прочете след известно време собствените си програми. За да могат програмите да са достъпни за разбиране, при писането им трябва да се спазват някои определени правила:

Програмите трябва да съдържат коментари, указващи действието, което извършва дадения програмен фрагмент.

Операторите, които се изпълняват един след друг се подреждат точно един под друг на еднакво разтояние от лявта рамка на прозореца, в който пишем програмата.

Когато даден оператор е съставен от няколко елемента (запазени думи или елементи на езика) и се налага пренасянето им на нов ред, те трябва да бъдат написани малко по-надясно от основния оператор.

24

Page 25: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Ако в рамките на даден оператор трябва да се изпълни друг, то вторият оператор се нарича вложен в първия. Такъв вложен оператор отново се записва малко по-надясно от основния оператор

Желатено е скобите { и } да се пишат на самостоятелен ред и една под друга. Например, следният оператор if е съставен от няколко елемента. Ще приведем двата начина за

запис на оператора – Без подреждане:

if(a==0) if(b==0)сout<<”всяко х е решение\n”;else cout<<”няма решение\n”;}else { x=a/b;cout<<”x=”<<x<<endl;}

С подреждане:

if(a==0) {

if(b==0)cout<<”всяко х е решение\n”;

else cout<<”няма решение\n”;

}else{

x=a/b;cout<<”x=”<<x<<endl;

}При втория начин става ясно, че конструкциите

{ if(b==0)

cout<<”всяко х е решение\n”;else cout<<”няма решение\n”;

{x=a/b;cout<<”x=”<<x<<endl;

}са елементи на оператора if(a==0) ... else …. Също така е ясно, че операторът if(b==0)...else... е

вложен в предходния оператор if. При първия запис това не е ясно от пръв поглед. Всеки програмист е в правото си да си състави собствени правила за подреждането на

програмите си. Тук приведохме само някои общи основни правила. Програмите, които ще бъдат представени по-нататък в ръководството са съобразени преди всичко с тях. Предлагаме на читателя да се стреми да се придържа към това подреждане.

4. Задачи за упражнение:

Зад. 1. От колко функции се състои следната програма и какви са техните имена.

#include <iostream.h>int m,n,mn[20][10000];void read(){int i,j;cin>>m;

25

Page 26: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cin>>n;for (i=0;i<m;i++)

for (j=0;j<n;j++)cin>>mn[i][j];

}int i_i_t(int p,int f){

int k=0;for (int i=0;i<p;i++) if (mn[f][p]>mn[f][i]) k++;return k;

}void compare(){

int i,j,br;for (i=0;i<m;i++)

{br=0;br+=mn[i][0]-1;for (j=1;j<n;j++)

if (mn[i][j]!=1) br+=mn[i][j]-(i_i_t(j,i))-1;cout<<br<<endl;

}}

int main(){

read();compare();return 0;

}

26

Page 27: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Числови типове данни и операции в С++I. Теоретични бележки

1. Типове данни

В темата “Алгоритми” споменахме, че освен елементарните действия, от които се състои един алгоритъм голямо значение за неговото правилно съставяне има и изборът на величините, които участват в него. В различните алгоритми величините представят различни характеристики Това определя и стойностите, които те могат да заемат, както и операциите, кито могат да се извършват с тях. В компютърните алгоритми определяме предварително какви стойности може да приема една величина и какви действия са допустими с нея. Това става като зададем нейния тип.

а) що е тип данни?

Конкретните стойности, които заемат величините при изпълнение на програмата, ще наричаме данни.

Типът на данните определя какви могат да бъдат конкретните стойности на величините от съответния тип (например цели числа) и кои са характерните операции, които могат да се извършват с тях (например +, - и др.)

За да бъде определен един тип трябва да са известни няколко важни елемента, които го характеризират.

б)елементи на тип данни:

множество от стойности, които могат да приемат величините от типа; множество от операции, в които могат да участват величините от типа;

2. Деклариране на тип на величина

а) константи

За да декларираме константа ние трябва да укажем нейният тип, име и стойност. За да стане ясно, че декларираме именно константа преди декларацията записваме запазената дума const. Синтаксисът за деклариране на константа е следния:

const тип_на константа име_на_константа = стойност_на_константа;Пример 1: const a=12, b=-1;const float pi=3.14;Забележка 1: Указването на типа на константата е задължително Има само един случай когато

може да не укажем типа на константата – когато тя е целочислена. Забележка 2: Ако искаме да декларираме няколко константи от един и същ тип, можем да

използваме само едно указване на думата const и само едно указване на тип, след което да изредим със запетаи имената на константите и техните стойности, като в следната декларация.

const float pi=3.14, g=9.8, e=2.67;

Какво се случва при декларация на константа? Да разгледаме като пример декларацията на константата pi. Когато програмата срещне тази декларация, се предизвиква следната последователност от действия в компютъра:

заделя се толкова памет, колкото е необходима за обект от указания тип. (В случая – за дробно число);

така заделената памет се свързва с идентификатора, указан като име на константата. От този момент нататък винаги когато в програмата се срещне идентификатора pi, той ще се свързва със същата част от паметта;

в паметта, заделена за константата се записва нейната стойност, така че всеки път когато програмата се обръща към нея да може да получи тази стойност. Както вече отбелязахме, когато говорихме за константи, стойността на константата не може да се променя по време на изпълнение на програмата.

27

Page 28: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

б) променливи

За да декларираме променлива е задължително да укажем нейният тип и име. Синтаксисът за деклариране на променлива е следния:

тип_на_променлива име_на_ променлива;Пример 1:

int a;

float c;

Забележка: Ако искаме да декларираме няколко променливи от един и същ тип, можем да използваме само едно указване на тип, след което да изредим със запетаи имената на променливите, като в следните декларации.

int x,y,z;

float k,l,m ;

в) инициализация на променливи

В много случаи се налага променливите, които декларираме да имат предварително зададена стойност. Езинът С++ позволява това да стане още със самата декларация, по същия начин както това се прави с константите. Тогава казваме, че сме инициализирали променливата. При декларация на няколко последователни променливи не е необходимо да инициализираме всичките. Ето примери за правилни декларации и инициализации на променливи:

int x,y=0,z;

float k=1.002, l=2.4, m ;

Какво се случва при декларация на променлива? Да разгледаме като пример декларацията

int x;

Когато програмата срещне тази декларация, се предизвиква следната последователност от действия в компютъра:

заделя се толкова памет, колкото е необходима за обект от указания тип. (в случая – за цяло число);

така заделената памет се свързва с идентификатора, указан като име на променливата. От този момент нататък винаги когато в програмата се срещне идентификатора х, той ще се свързва със същата част от паметта;

ако променливата е инициализирана, в паметта, заделена за нея се записва нейната стойност, така че всеки път когато програмата се обръща към нея да може да получи тази стойност. Както вече отбелязахме, стойността на променливите може да се променя по време на изпълнение на програмата. Какви са начините за промяна на стойности на променлива ще разгледаме по-нататък.

3. Стандартни типове данни

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

28

Типове величини

Прости Съставни

Чис

лови

фиг. 16

Указ

ател

Текс

тови

Мас

иви

Стр

укту

ри

Фай

лове

Цел

и

реал

ни

Page 29: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

В настоящото ръководство ще се разгледат само част от изброените типове. Останалите са предмет на дисциплината Програмиране 2 и ще бъдат разгледани в друго ръководство.

4. Числови типове.

При изучаването на нов тип данни, трябва да обърнем внимание на следните основни моменти: множество от стойности на типа; множество от операции, в които могат да участват величините от типа; множество от отношения между величините от типа; средства на езика за програмиране за работа с величини от типа.Самото наименование на числовите типове показва, че стойностите, които ще приемат

величините от тези типове, са числа. От опит знаем, че делим числата на две основни групи (множества): цели и реални, които дават имената на двата подтипа числови величини: целочислен тип и реален тип. Оформянето на два отделни подтипа е необходимо, тъй като операциите, допустими за двата типа не съвпадат. Друга не по-маловажна причина е мястото, което се заделя в оперативната памет за величините от двата типа и начина, по който те се представят в нея.

а)целочислени типове

Тип Размер в байтове Числен интервалint 2 [-32768,32767]

unsigned 2 [0,65535]long 4 [-2 147 483 648, 2 147 483 647]

unsigned long 4 [0, 4 294 967 295]фиг. 17

Интервалите, в които могат да се променят стойностите на величините от различните типове на пръв поглед изглеждат странно, но ограниченията съвсем не са случайни. Те зависят от начина, по който числата се представят в компютъра - кодирани чрез 0 и 1, т. е. представени в двоична бройна система .

Ако разгледаме например типа int: за него се заделят точно 2 байта, т. е. 16 бита, като най-левият от тях се отделя за записване на знака на числото. Ако числото е положително, в този бит се записва 0, а иначе 1. Най-голямото число, представено в двоична бройна система, което може да се запише в останалите 15 бита е число, съставено от 15 единици и то е точно 32767. При типа unsigned, както личи от името му, не се отделя място за знак и затова интервалът на стойностите се измества, като те започват от 0 и достигат до 65535 (най-голямото число, което може да се запише в 16 бита). По същия начин е организирано представянето и на другите два целочислени типа.

Интересен е въпросът: Какво би станало ако към променлива със стойност 32767 от тип int прибавим числото 1? Очевидно би трябвало да се получи число извън границите на типа int. В този момент програмата преобразува полученото число в –32768, т. е. “превърта” стойностите на типа и започва отначало. Може би ви се е случвало да “превъртите” някоя игра, т. е. изведнъж тя да започне да ви дава точки отново от 0, независимо от великото ви постижение.

По същият начин реагират и стойностите от останалите целочислени типове. Ето защо винаги трябва да имаме предвид особеностите на компютърната аритметика и да избираме нашите типове в зависимост от очакваните стойности, които дадена величина може да приема.

б) дробни типове данни:

Тип Размер в байтове Числен интервалfloat-реално число със знак 4 bytes от 3.4х10-38 до 3.4х10+38

double-реално число със знак, но много по-голямо

8 bytes от 1.7х10-308 до 1.7х10+308

фиг. 18

Представянето на величините от реален тип в паметта се отличава значително от представянето на целочислените величини. Всяко дробно число се представя с две стойности – първата, наречена мантиса, съдържа числото, съдържащо всички значещи цифри, но представено като число не по-голямо от 10 и не по-малко от 1; втората, наречена порядък, съдържа степента, на която трябва да повдигнем числото10 преди да го умножим с мантисата, така че да се получи нашето число. Това може да стане ясно чак след разглеждане на няколко примера.

Пример 1 :

29

Page 30: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Числото 34567.68 се представя чрез мантиса: 3.456768 и порядък: 4, което означава, че като преместим десетичната точка с 4 знака надясно, се получава точно разглежданото число.

В следващата таблица ще покажем представянията като мантиса и порядък на още няколко числа.

Число Мантиса Порядък3428.453 3.428453 323.0007 2.30007 10.000000078934 7.8934 -126.789 6.789 0

фиг. 19Както вече видяхме в таблицата на дробните типове за типа float се заделят 4 байта, т. е. 32 бита.

Част от тях се заделят за мантиса, а останалите – за порядък. Ето защо този тип може да работи само с числа, чиято абсолютна стойност е не по-голяма от 1037 и не по-малка от 10-37. Подобно на описаният по-горе начин в отделената за порядъка не може да се запише число по-голямо от 37 или по-малко от –37. Въпреки, че числата от тип float могат да са твърде големи (все пак 1037 не е малко число), се оказва, че мястото, заделено за мантиса също е малко за представяне на число с 36 осмици. Видяхме, че в четири байта не могат да се съберат числа с много цифри по простата причина, че трябва да се кодират чрез 0 и 1. Ето защо броят на значещите цифри на едно число от тип float, независимо колко голямо е то, е не повече от 7, т.е. оказва се, че с числата от този тип може да пресмятаме стойности, които са достъпни за най-простите джобни калкулатори. Когато числото надхвърли 7 значещи цифри, програмата автоматично го закръгля, така че да се получи число с по-малък брой цифри. Например числото 99999999 се представя като число с мантиса 1 и порядък 9, т.е. закръгля се към 100000000.

Все пак не можем да допуснем, че в ежедневната практика никага няма да се наложи да използваме числа с повече значещи цифри. Напротив, можем да дадем куп примери за обратното. (Опитайте да преброите цифрите на разстоянието от Земята до Луната или на дължината на екватора.). В такива случаи се използва тип double, който запазва до 15 значещи цифри.

5. Допустими операции за стандартните числови типове:

а) аритметични:

знак операция+ събиране- изваждане* умножение/ деление% остатък при деление

Използват се по познатият математически начин: a+b, c-d, x*y, z/t и т.н. Изброените операции са валидни за всички числови типове. Изключение прави операцията “%”. Тя е дефинирана само за операнди от цял тип. Интересна е интерпретацията на операцията “/” при прилагането и към различните типове данни. Когато се прилага към целочислени величини, резултатът е цялата част от делението на тези величини, докато ако се прилага към реални – резултатът е закръглена десетичната дроб, получена при делението на двете величини.

Пример 2: 5 / 2 2 5.0 / 2=2.55 % 2=1Пример 3: int a, b;

a=5; b=2;

тогава:

a/b=2;

a%b=1;

Пример 4: float a, b;

30

Page 31: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

a=5; b=2;

тогава:

a/b=2.5;

Естествено е да си зададем въпроса: Можем ли да получим резултата от делението на две цели числа като десетична дроб? Ако става дума за конкретни стойности, то чрез записване на точка след стойността на поне едно от целите числа, участващи в операцията, го превръщаме в дробно. Програмата приема тази операция за дробна и я изпълнява като такава, т. е. резултатът от операцията 5. / 2 е 2.5, тъй като числото 5. се приема от програмата за дробно.

Задача:

Нека int a,b,c;

float x,y;

Определете типа на резултата:

Пример Резултат Пример Резултатc=a/bx=a/bc=a/xc=x/a

intintintint

x=a/ya/ba/xx/a

floatint

floatfloat

фиг. 20

б) операции за присвояване

обикновена (стандартна) – позволява присвояване на стойности на променливи. Означава се със символа за равенство “=”.

Ето и нейните синтаксис и семантика:Синстаксис (правило за запис):име_на_променлива=израз;Семантика (правило за изпълнение):- Пресмята се стойността на израза.- Получената стойност се записва на мястото, заделено в паметта на компютъра за съответната

променлива. - Резултатът от операцията за присвояване е присвоеният израз.Пример 5 : a=5;b=a*3+2;С първият оператор за присвояване на мястото в оперативната памет, което е заделено за

променливата с име а, се записва числото 5. При втория оператор за присвояване първо се пресмята стойността на израза вдясно(17) и след това тази стойност се записва на мястото, заделено за променливата b.

Забележка 1:Тъй като операцията за присвояване връща резултат, то е допустимо да се използва следната

операция:a=b=1.В този случай първо ще се пресметне изразът вдясно от първата операцията за присвояване и тъй

като това също е операция за присвояване, първо на променливата b ще се присвои стойност 1, след това операцията b=1 ще върне стойност 1, която от своя страна ще се присвои на променливата а.

Забележка 2:Има разлика между “=” в математиката и “=” – операцията за присвояване. Например, докато в

математиката е напълно безмислен записа х=х+1, то в езика за програмиране С++ това означава, че първо ще се прочете от паметта, заделена за променливата х, нейната стойност, след това към нея ще се прибави числото 1 и получената в резултат на това стойност ще се присвои на променливата х, при което старата стойност на тази променлива ще бъде заместена с новата. Освен това в математиката е разрешено вляво от знака за присвояване да стои израз, докато тук е задължително това да е име на променлива, на която се присвоява изразът отдясно.

31

Page 32: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Забележка 3:В случай на присвояване на стойност, различна по тип от типа на променливата отляво

компилаторът на С++ не извежда съобщение за грешка, а се извърщва автоматично преобразуване на типа на данните така, че да съответства на типа на променливата отляво. В такива ситуации може да се получи загуба на информация! Следният пример ясно я демонстрира.

Пример 6:

Нека int a=4, b=5,C;float x=3.0,Y;

Израз РезултатC=a/bY=a/bC=a/xY=a/x

C=0Y=0C=1

Y=1.333333

фиг. 21

съкратени операции за присвояване:Стремежът за по-кратко записване на алгоритмите и увеличаване на скоростта за тяхното

изпълнение е довело до по-странен начин на записване на операциите за присвояване, характерни за езика С:

a=a+b a + =ba=a-b a - =ba=a*b a * =ba=a/b a / = ba=a%b a % = b

Задача 1: Нека int x=3, y=1,z=5. Запишете в разширен вид операциите за присвояване:x - =100;y * =x;z / =x+y;

Определете стойностите на променливите след изпълнение на операциите при зададените начални стойности.

операции за увеличаване и намаляване с 1:++ -увеличаване с единица-- -намаляване с единицаЗаписваме по следният начин: а=а+1 ++а;

а++;а=а-1 --а;

а--;Както се вижда тези операции са едноместни, т.е. прилагат се само към един операнд.Забележка 1:Има разлика при използването на операциите ++ и --, в зависимост от това дали са записани

преди или след операнда, към който се прилагат. Ако операцията е записана след операнда, то той участва в израза с досегашната си стойност и чак след като се извърши пресмятането, увеличава (намалява) стойността си с 1. Например, ако имаме променливите int x,y, след изпълнение на операциите

x=15;y=5+х++; променливите х и у ще имат стойности, съответно х=16, у=20. Това е така, защото когато се

пресмята изразът, който трябва да се присвои на променливата у, променливата х участва в него със стойността си 15 и чак след изчислението се увеличава с 1.

Ако в същият пример променим мястото на операцията ++р т.е. х=15;у=5+(++х);

то резултатът от изпълнението им ще бъдат стойности за х и у, съответно х=16 и у=21. Сега вече три пресмятането на израза от втората операция, първо се х увеличава с 1 и чак тогава се пресмята стойността на израза.

32

Page 33: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

в) Операция за последователно изпълнение – означава се с “ ,”

Синстаксис (правило за запис):операнд1 , операнд2Семантика (правило за изпълнение): изчислява се операнд1 изчислява се операнд2Резултат от операцията: операнд2.Тип на резултата: типът на операнд2. Пример 7:

Нека int а=5; тогава резултатът от операцията

а+6,а+7

ще бъде 12. При това примера в случая е безмислен, защото пресмятането на първия израз се

забравя.

Съвсем друг смисъл би имала операцията ако в първия израз вместо + се използва операцията +=.

Тогава резултатът от операцията:

а+=6, а+7

ще бъде 18, защото при прилагане на първата операция ще се промени стойността на

променливата а.

г) Операция за размер на обект – означава се със sizeof

Синстаксис (правило за запис):sizeof (операнд)Резултат от операцията:размерите в байтове на отделните типове данниПример 8:

sizeof (int)=2sizeof (float)=4

д) Операция за преобразуване на типове – означава се със ()

Синстаксис (правило за запис):(тип)израз Резултат от операцията:Резултата от израза след операцията се интерпретира от програмата от типа, посочен в

операцията.Използването на тази операция се налага, когато резултатът от дадена операция трябва за

момента да бъде от друг тип. Пример 9:

Нека са дадени променливите int a=5, b=2;Резултатът от операцията a/b ще бъде 2, тъй като с цели числа се извършва само целочислено

деление. Ако искаме да получим реалния резултат като десетична дроб, ще трябва да използваме операцията за преобразуване на типове по следния начин:

(float)a/b, при което типът на израза се преобразува в реален и резултатът ще бъде 2.5.

6. Изрази

а) как се получават изразите?

Всяка правилно структурирана комбинация от символи за операции, операнди (константи, променливи) и кръгли скоби ще наричаме израз.

33

Page 34: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Комбинацията не бива да противоречи на правилата в езика (операции, операнди, синтаксис).Пример 10:(c/a)+(z*t)-(a+c)(x1*10)=(c/10)

б) приоритет на операциите (или ред на изчисляване на изразите) Приоритета на операциите определя реда, в който те ще се изпълняват при пресмятането на изразите. В обикновенните математически изрази, с които сме свикнали да работим всеки ден първо се пресмятат операциите умножение и деление и след това събиране и изваждане. Изключение правят случаите когато използваме скоби. Тук в езика за програмиране С++, правилата са същите, с тази разлика, че използваме само един вид скоби за промяна на приоритета на операциите и това са кръглите скоби ( ). Останалите видове скоби, използвани в математиката [ ] и { } имат друг смисъл в езика С++. Ето разгледаните до тук операции, подредени по техния приоритет:

- ( ) ++ -- * / %+ -= += -= *= /=Трябва да отбележим, че ако имаме две последователни операции с един и същ приоритет,

подобно на общите правила в математиката, те се изпълняват последователно отляво надясно.Поставянето в програмата на интервали, скоби и табулации не причиняват грешки и не забавят

изпълнението и. По-скоро подобряват подредбата и разбираемостта и.

II. Задачи за упражнение

Зад. 1. Кои от константите са от цял и кои от реален тип? 256, .256, -67, 12.0, -127, 5.0, 4.2538, 67.Зад. 2. Кои от изброените операции са допустими за величини от реален тип? +, *, %, /, -Зад. 3. Какъв е резултатът от изпълнение на аритметичните операции:15.0/416%417%3-29%415/4-16+47*435/(-6)Зад. 4. Посочете какъв е резултата от операциите за присвояване b/=a, b-=a b%=a, ako:а) int a=5, b=-7б) float a=5.0; int b=-7;в) int a=5; float b=-7.0;Зад. 5. Какви са окончателните стойности на променливите x и y:a) x=1+2*7; б) x=4+2*6; в) x=6*2;

y=3+x--; y=2*--x ; у=24/х++;Зад. 6. Пресметнете:

а)(int) 17/4;

б)(int) 17/4.0;

в)sizeof (int);

г)x=(y=3, y+2).

34

Page 35: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Въвеждане и извеждане на данни в С++ програмаI. Теоретични бележки

Един алгоритъм може да се изпълни от компютър, ако е записан като програма на даден език за програмиране. За използването и в конкретна ситуация трябва величините в програмата да получат конкретни стойности – т.нар. входни данни.

Данните, които програмата трябва да получи от потребителя по време на своето изпълнение, ще наричаме входни данни.

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

Данните, които програмата извежда в резултат на своята работа, ще наричаме изходни данни.

Нека разгледаме познатият ни алгоритъм за намиране обиколка на правоъгълник:

#include<iostream.h>void main(){

1. Задава се дъжината а и ширината b на правоъгълника. float a,b,P; cin>>a>>b;

2. Пресмята се периметъра P на правоъгълника по форулата P=2*(a+b). P=2*(a+b);3. Съобщава се P. cout<<P<<endl;

}В посочения пример можем да отделим две основни стъпки, които неизменно присъстват във

всеки един алгоритъм: първата, с която определяме първоначалните стойности на величините, т.е. входните

данни; последната, с която извеждаме резултатите от работата (изпълнението) на

програмата, т.е. иходните данни.За реализиране на тези стъпки в програмата използваме оператора cin>>a>>b, които ще наричаме

оператор за вход, и cout<<P<<endl, който наричаме оператор за изход.

1. Библиотеки

Както вече неколкократно стана дума, тъй като в езика С и С++ не са реализирани всички стандартно използвани функции, те се предоставят на програмистите в множество библиотеки. Към тези библиотеки принадлежат и библиотеките, съдържащи различни средства за вход и изход. Библиотеките, които основно осъществяват вход-изхода в езика С са stdio.h и conio.h, в езика С++ към тях се прибавят още iostream.h и fstream.h.

За да използваме функциите от дадена библиотека е необходимо да се обърнем към библиотеката (да напишем името и) в началото на програмата, след което можем да използваме функциите в тялото на програмата:

# include<iostream.h>void main(){float a,b,P;cin>>a>>b;P=2*(a+b);cout<<P<<endl;}

35

Компютърна програма

Входниданни

Изходни даннирезултат

Page 36: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

2. Входно-изходна библиотека iostream.h

а) оператор за вход – cin

Чрез cin въвеждаме в програмата конкретни стойности, наричаме го още оператор за вход.

Синтаксис(правила за запис):cin>> променлива 1>> променлива 2>>...>> променлива n;променлива 1, променлива 2, ..., променлива n - имена на променливи, декларирани някъде в

програмата, преди използването им в оператора. Това са променливи, чиито стойности трябва да бъдат въведени от клавиатурата. В оператора може да бъде зададена и само една променлива.

Семантика(правила за изпълнение):Когато достигне до изпълнение на оператора cin, програмата спира и чака да зададем стойности

на променливите от клавиатурата.Въведените стойности се записват в клетки в оперативната памет, които са отделени за

въвежданите променливи по време на декларацията им.

При работа с cin се съобразяваме със следните правила:- При въвеждане от клавиатурата входните данни се отделят една от друга с интервал или Enter

(т.е. числата, въведени от клавиатурата могат да бъдат разположени на един или няколко реда, но задължително разделени с поне един интервал). След задаване на последната стойност, задължително използваме Enter. Това е знак програмата да продължи по-нататък своето изпълнение.

- Екранът, на който изписваме входните данни и се отпечатват изходните резултати е различен от прозореца, в който се намира текста на програмата.

- С едно използване на cin можем да зададем стойности на една или няколко променливи:cin>>променлива 1>>променлива 2>> ... >>променлива n; cin>>променлива 1;

cin>> променлива 2;…

cin>> променлива n;- Чрез cin въвеждаме стойности на променливите, изброени в оператора(операторите) в реда, в

който са посочени, т.е. първата променлива приема първата въведена стойност, втората –следващата и т.н.

- Ако броя на въведените числа е по-голям от броя на променливите, присъстващи в оператора, излишните се игнорират.

- Ако броя на въведените числа е по-малък от броя на променливите, присъстващи в оператора, cin изисква въвеждането им, и не допуска по-нататъшно изпълнение на програмата

Пример 1:Нека int a,b;

Оператор Екран Състояние на променливата в ОП

cin>>a>>b; 5 7

a b

cin>>a>>b; 5 7 a b

36

5 7

5 7

5 7

5 7

Page 37: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cin>>a;cin>>b; 5 7 a b

cin>>a;cin>>b;

5 7 a b

cin>>a>>b>>c; 12 121 64 80 a b c

cin>>a>>b>>c; 12 121 a b c

б) оператор за изход – cout

Чрез cout извеждаме на стандартно изходно устройство (монитор, принтер) или дисков файл, числа, съобщения, стойности на променливи или изрази.

Синтаксис(правила за запис):cout<< израз 1<< израз 2<< ...<< израз n;където израз 1, израз 2, ..., израз n могат за бъдат числа, имена на променливи(декларирани и

получили стоността си преди използването им в оператора), допустими за езика изрази или съобщения(последователност от знаци).

Семантика(правила за изпълнение):Когато стигне до изпълнение на оператора cout, програмата извежда на стандартното изходно

устройство(в нашият случай – монитора) от някаква текуща позиция (на екрана) числовата стойност, стойността на променливите, на изразите или посоченият текст в оператора.

При работа с cout се съобразяваме със следните правила:- За извеждане на цяло число се отделя поле, което е с ширина, равна на броя на знаците от които

се състои числото.- За извеждане на реално число се отделя поле, което е с ширина, равна на броя на знаците от

които се състои числото, включително една позиция за десетичната точка(запетая).- При използване на допустими за езика изрази в оператор cout, първо се пресмята стойността на

израза, след което полученият резултат се извежда на екрана.- Текст, съобщение или някаква последователност от символи, която искаме да изведем на екрана

задължително заграждаме в кавички.- За по добро оформяне на резултатите от действието на дадена програма използваме \n (в

текстове) или endl – за извеждане на нов ред, които действат по един и същи начин: Преместват курсора на нов ред и следващото отпечатване е там. Ако се налага използване на \n самостоятелно(извън текст), той задължително се загражда в апострофи ‘\n’.

- Оператор cout допуска комбинирано използване на текст, променливи, изрази и числа.

Пример 2:Нека float a=7.2,b=8;

Оператор 1 Оператор 2 Състояние на екрана

cout<<13<<4.57; cout<<13;cout<<4.57;

134.57

cout<<13<<endl<<4.57; cout<<13<<endl;cout<<4.57;

134.57

cout<<13<<endl;cout<<4.57;

cout<<13<< “\n”;cout<<4.57;

134.57

37

12 121 64

125

121 ?

Page 38: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<a<<b; cout<<a;cout<<b;

7.28

cout<<a<<endl<<b; cout<<a<<endl;cout<<b;

7.28

cout<<a+b; 15.2

cout<<”Мая Тодорова Георгиева”; Мая Тодорова Георгиева

cout<<”Мая\n Тодорова\n Георгиева\n” МаяТодороваГеоргиеваcout<<”Мая”<<endl;

cout<<”Тодорова”<<endl;cout<<”Георгиева”<<endl;

3. Използване на cin и cout за “дружелюбно” поведение на програма на С++

Задача: Да се състави програма AVERAGE.CPP, която въвежда от клавиатурата две числа a и b и извежда на екрана тяхното средно аритметично.

Решение:#include<iostream.h>void main(){ float a,b;cout<<”a=”; cin>>a;cout<<”b=”; cin>>b;float c=a+b;cout<<”Ср. аритметично е: “<<c/2<<endl; 

}

Редовете от програмата cout<<”a=”;cin>>a;cout<<”b=”;cin>>b;

наричаме “дружелюбен вход”. Въвеждането на данни, предхождано от подобен род съобщения ни помага да се ориентираме за променливите, на които задаваме стойности.

II. Решени задачи

1. Задачи за изчисление.

Това са стандартни задачи, в които при зададени входни данни трябва да се пресметне дадена стойност с помощта на формула или чрез последователно изчисление на няколко различни израза. Подобни задачи ние вече разглеждахме. Това бяха задачите за намиране на лице и обиколка на правоъгълник, за намиране лице на кръг и др. Понякога решението не е толкова очевидно както при задачите, които току що изброихме и се налага предварително внимателно да се обмисли алгоритъмът, по който те ще се решат.

38

a=7b=8Ср. аритметично е: 7.5

Състояние на екрана

Page 39: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 1. Ограда.

В едно училище направили кръгли градинки, в които красиво посадили цветя. За съжаление все се намирали недобросъвестни ученици, които влизали в градинките и тъпчели цветята. Ето защо, от ръководството на училището решили да оградят градинките с ограда от телена мрежа. Училищният градинар, който точно знаел радиусите на всички градинки, трябвало да изчисли колко дълга мрежа е необходима за ограждането на всяка една от тях. Той не бил добре с математиката, а и трябвало бързо да смята. Помогнете на градинаря, като напишете програма OGRADA.CPP, която въвежда от клавиатурата радиуса на една градинка (реално число) и извежда на екрана дължината на мрежата, която трябва да се закупи, за да се огради градинката.

Примерен вход

1

Примерен изход

6.28

Решение

Тъй като градинката е кръгла, то за да се намери дължината на мрежата, трябва да се намери дължината на окръжността с дадения радиус.

1. Ще определим величините, които участват в програмата: това са две дробни променливи r и c, съответно за радиуса и за дължината на

окръжността. Те се декларират по следния начин:float r,c; необходима е и дробната константа pi, която има за стойност числото и се декларира по

следния начин:const float pi=3.14;

2. След като необходимите величини са декларирани, трябва да се въведе от клавиатурата радиуса на окръжността.

cin>>r;3. Когато вече знаем радиуса, можем да пресметнем дължината на окръжността по

математическата формула c=2r,която на езика С++ се записва чрез следната операция за присвояване:c=2*pi*r;

4. Щом пресметнем дължината на окръжността, можем да я изведем на екрана:cout<<c<<endl;Като използваме описаното решение и правилата за писане на програма на езика С++, можем да

напишем следната програма:

//ograda.cpp#include<iostream.h>void main()

{const float pi=3.14;float r,c;cin>>r;c=2*pi*r;cout<<c<<endl;

}Тази програма вече може да бъде въведена чрез системата за програмиране BorlandC, да бъде

съхранена под име OGRADA.CPP и да бъде изпълнена.

39

Page 40: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 2. Боя.

Налага се да се боядиса провоъгълна стена с дължина l и височина h. Известно е, че с една кутия боя могат да се боядисат m квадратни единици площ от стената. Напишете програма BOJA.CPP, която прочита от клавиатурата дробните числа l, h и m, и отпечатва колко кутии боя са необходими, за да се боядиса стената.

Примерен вход

2 4 5

Примерен изход

2

Решение

1. Необходими величини: за дължината и височината на стената, и количеството боядисана площ от една кутия боя

са необходими три дробни променливи:float l, h, m; за броя кутии, обаче, ще ни трябва цяла променлива, защото брой винаги се задава с цяло

число. При това броя кутии боя никога не може да е отрицателен и затова ще използваме целочислен тип, който няма отрицателни числа.

unsigned b;2. Въвеждат се променливите l, h и m:

cin>>l>>h>>m;За да стане по-ясно на потребителя какво точно трябва да въвежда, може да реализираме

дружелюбен вход по следния начин:cout<<”Дължина: “; cin>>l;cout<<”Височина: “; cin>>h;cout<<”площ в кв. м., която се боядисва с една кутия: “; cin>>m;

3. Пресмята се лицето на стената: Тук става ясно, че е необходима още една дробна променлива, в която ще се запише стойността

на лицето на стената. Да я означим с s. Тя може да се декларира в момента, в който ни потрябва:float s=l*h;

4. Пресмята се броя кутии с боя: Най-лесно е просто да разделим лицето на площта, която се боядисва с една кутия боя, но

резултатът, получен в този случай няма да е винаги точен. Всъщност, той ще е точен само в случаите, когато s се дели на m без остатък, а те явно са много малка част от общия брой случаи. Естествено, ако се получи дробно число като резултат, то задължително трябва да се закръгли към по-голямият брой кутии, защото и за най-малката останала част от стената ще се наложи да се купи още една кутия боя. Закръглянето се извършва със специалната функция ceil, която е описана в специализираната библиотека math.h. Функцията ceil приема като параметър реално число и връща най-малкото цяво число надвишаващо параметъра.

Сега можем да запишем операцията за присвояване, с помощта на която ще присвоим на променливата b броя на кутиите боя, необходими за боядисване на стената.

b=ceil(s/m);5. След като търсеният брой е пресметнат, той трябва да бъде изведен на екрана:

cout<<b<<endl;Окончателно програмата има следния вид:

// boja.cpp#include<iostream.h>#include<math.h>void main()

{float l, h, m;unsigned b;cout<<”Дължина: “; cin>>l;cout<<”Височина: “; cin>>h;cout<<”площ в кв. м., която се боядисва с една кутия: “; cin>>m;

40

Page 41: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

float s=l*h;b=ceil(s/m);cout<<b<<endl;

}

Задача 3. Разстояние от точка до центъра на координатната система

Да се състави програма DIST.CPP, която въвежда от клавиатурата координати на точка в равнината и изчислява разстоянието от точката до центъра на координатната система.

Примерен вход

4 3

Примерен изход

5

Решение

1. Необходими величини: Трябва да декларираме три дробни числа – по едно за координатите на точката и едно за

разстоянието от нея до центъра на координатната система:float x,y,d;

2. Първо трябва да се въведат координатите на точката:cin>>x>>y;

3. След това се изчислява разстоянието от точката до центъра на координатната система:r=sqrt(x*x+y*y);

4. В края на програмата намереното разстояние се извежда на екрана:cout<<r<<endl;Тук трябва да отбележим нещо важно: тъй като използваме функцията sqrt, не трябва да

забравяме да включим към програмата математическата библиотека math.h. Окончателно програмата има следния вид:

// dist.cpp#include<iostream.h>#include<math.h>void main()

{float x,y,d;cin>>x>>y;float r=sqrt(x*x+y*y);cout<<r<<endl;

}

2. Отделяне на цифрите на число

В много случаи се налага, ако имаме дадено число да отделим цифрите му. Например ако искаме да проверим дали дадено число се дели на 3 или на 9, ние намираме сумата от цифрите му. Понякога се налага да ръзменим цифрите на едно число или да го прочетем наобратно. Да си припомним и играта “Бикове и крави”, където също се налага да се отделят цифрите на числото. Има много други примери, при които се налага да се отделят цифрите на едно число.

41

Page 42: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 4. Сума от цифри на число

Дадено е трицифрено число k. Да се състави програма SUMCIF.CPP, която прочита от клавиатурата числото k и отпечатва сумата от цифрите му.

Примерен вход

365

Примерен изход

14

Решение

За да намерим сумата от цифрите на числото, трябва да намерим поотделно всяка една от тях – цифрата на единиците, на десетиците и на стотиците.

1. Необходими величини:Освен цялото число k се налага да заделим по едно цяло число за всяка една от цифрите:

int k,e,d,s; // е – цифрата на единиците, d – на десетиците и s – на стотиците. 2. Първо трябва да се въведе числото к:

cin>>k;3. След това трябва да се изчислят съответните цифри като използваме целочислените

операции за деление по следния начин:e=k%10;d=k/10%10;s=k/100;

4. Накрая, чрез оператора за изход извеждаме сумата на цифрите на числото:cout<<e+d+s<<endl;В този случай програмата е следната://sumcif.cpp#include<iostream.h>void main()

{int k,e,d,s;cin>>k;e=k%10;d=k/10%10;s=k/100%10;cout<<e+d+s<<endl;

}

Допълнителна задача:Коригирайте програмата така, че да работи за четирицифрено число. Проверете и резултата, при

въведено двуцифрено число. Защо програмата връща правилен резултат при двуцифрено число и грешен при петцифрено?

Задача 4. Намиране на обърнато число на дадено

Да се състави програма OBRATNO.CPP която прочита от клавиатурата трицифрено число N и отпечатва обърнатото му.

Примерен вход

365

Примерен изход

563

Решение

За да намерим обратното на числото, трябва да намерим поотделно всяка една от цифрите му – цифрата на единиците, на десетиците и на стотиците.

1. Необходими величини:Освен цялото число N се налага да заделим по едно цяло число за всяка една от цифрите:

42

Page 43: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

int N,e,d,s,oN; // е – цифрата на единиците, d – на десетиците и s – на стотиците, ок- обратното на числото к.

2. Първо трябва да се въведе числото N:cin>>N;

3. След това трябва да се изчислят съответните цифри, като използваме целочислените операции за деление по следния начин:

e=N%10;d=N/10%10;s=N/100;

4. Когато знаем цифрите на числото, можем да намерим обратното му по следната формула:оN=100*e+10*d+s;

5. Накрая извеждаме намереното обратно число.След този анализ напишете програмата самостоятелно.Допълнителна задача:Коригирайте програмата така, че да работи за четирицифрено и петцифрено число. Проверете и

резултата, при въведено двуцифрено число.

3. Преобразуване на мерни единици

Превръщането от грамове в килограми, от километри в метри става с по-малко пресмятания, защото се налага деление на 10, но превръщането от секунди в минути и в часове и обратно изисква по-сериозни пресмятания. Ето няколко задачи, в които се поставят и решават подобни проблеми.

Задача 5. Склад

За нуждите на един склад трябва да се направи програма SKLAD.CPP за пресмятане на складовите наличности. Програмата трябва да прочита от клавиатурата количеството стока в килограми и грамове, както и продаденото количество, измерено по същия начин, и да отпечатва оставащото количество стока. Програмата приема като вход четири числа, първото от които е килограмите на наличното количество, второто е грамовете; третото число е килограмите на продаденото количество, а четвъртото – грамовете на продаденото количество. Програмата отпечатва 2 числа – първото е килограмите на оставащото количество, а второто – грамовете. Складът е толкова голям, че в него не може да се съхранява повече от 10 тона стока.

Примерен вход

1000 200 50 700

Примерен изход

949kg 500g

Решение

Най-лесно можем да решим задачата като в началото преобразуваме всички мерни единици в грамове, извършваме изваждането на продаденото количество от наличното, след което преобразуваме оставащото количество в килограми и грамове. При това ще са необходими поне 6 променливи – по две за всяко количество – налично, продадено, оставащо.

1. Необходими величини:Тук трябва добре да обмислим какъв ще е типът на променливите, с които ще работим. От

условието се вижда, че най-голямото количество стока, която може да се съхрани в склада е 10 тона, което ако се превърне в грамове е 10 000 000 грама. Това число очевидно не може да се събере нито в тип int, нито в unsigned. Все пак е необходимо да ползваме целочислен тип, защото за окончателното преобразуване на грамовете на оставащото количество в килограми ще ни трябва операцията за целочислено деление. Целочислен тип, който може да тозволи използването на толкова големи числа е unsigned long. Ето защо дефинираме следните величини:

unsigned long nk, ng, pk, pg, ok, og;където nk са наличните килограми, ng – наличните грамове, pk – килограмите на продаденото

количество, pg – грамовете на продаденото количество, ok – килограмите на оставащото количество, og - грамовете на оставащото количество.

2. Въвеждаме входните данни:cin>>nk>>ng>>pk>>pg;

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

43

Page 44: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

ng=nk*1000+ng;pg=pk*1000+pg;

4. Пресмятаме оставащото количество в грамове:og=ng-pg;

5. Превръщаме оставащото количество в грамове и килиграми:ok=og/1000;og=og%1000;

6. Извеждаме килограмите и грамовете на оставащото количество.cout<<ok<<” kg “<<og<<”g\n”;Програмата, решаваща тази задача има следния вид:

//sklad.cpp#include<iostream.h>void main(){

unsigned long nk, ng, pk, pg, ok, og;cin>>nk>>ng>>pk>>pg;ng=nk*1000+ng;pg=pk*1000+pg;og=ng-pg;ok=og/1000;og=og%1000;cout<< ok<<” kg “<<og<<”g\n”;

}

Задача 6. Самолет

Известно е, че един самолет излита в h часа и m минути, като полетът му продължава m1 минути. Да се състави програма AIR.CPP, която прочита от клавиатурата данните h, m и m1 за полета и отпечатва в часове и минути точното време на кацането му. Например: самолетът излита в 23 часа и 50 минути, полетът продължава 75 минути, следователно часът на кацане е 1 часа и 5 минути.

Примерен вход

23 50 75

Примерен изход

1h 5m

Решение

Задачата се решава като предходната, като към минутите на излитане се добавят минутите на продължителността на полета. След това получения резултат се преобразува в часове и минути, като часовете се прибавят към часа на излитане. Остава само да съобразим, че има възможност да се премине в следващото денонощие и тогава часа на кацане ще се ролучи като вземем остатъка при деление на получения час на 24.

1. Необходими величини:Можем да решим задачата само с помощта на трите променливи обявени в условието, като ще се

уговорим в променливите, указващи времето на излитане да получим времето на кацане.unsigned h,m,ml;

2. Въвеждаме входните данни:cin>>h>>m>>ml;

3. Прибавяме минутите на продължителността на полета към минутите на излитане:m+=ml;

4. Преобразуваме получените минути в часове и минути, като часовете прибавяме към часа на излитане, а минутите записваме в променливата m:

h+=m/60;m%=60;

5. Пресмятаме часа на кацане, като остатък при деление на 24 за да избегнем грешката при прехвърляне в другото денонощие:

h%=24;6. Отпечатваме часа на кацане:

44

Page 45: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<h<<”h “<<m<<”m\n”;След този анализ напишете програмата самостоятелно.

III. Задачи за упражнение

Зад. 1 Какъв е резултатът от изпълнение на следните оператори:int a=3,b=4;

а) cout<<a<<”+”<<b<<”=”<<a+b; a+b=7cout<<”a+b=”<<a+b; 3+4=7cout<<”a+b=\n”<<a+b; a+b=

7

б) cout<<”1\n1 2\n1 2 3\n”;

Зад. 2 Дадена е програмата: Какво ще се изведе на екрана след изпълнение на програмата? Защо извежда този резултат?

#include<iostream.h>void main(){int b:cout<<b<<endl;

}

Зад. 3 Как ще изглежда екрана на монитора след изпълнение на програмата:#include<iostream.h>void main()

{int a,b;cout<<”a=”;cin>>a;cout<<”b=”;cin>>b;cout<<a<<”+”<<b<<”=”<<a+b<<endl;cout<<a<<”-”<<b<<”=”<<a-b<<’\n’;cout<<”Остатъкът от делението на ”<<a<<”и”<<b<<”е”<<a%b;cout<<’\n’;}

ако сме задали следните входни данни:а) 5 и 3; б) 5.7 и 3; в) 5 и 3.5; г)7.1 и 8.6. Зад. 4 Кои от следните записи са грешни и защо? Поправете грешките, така че да получите

изпълними оператори.а) cin<<a;б) cin>>10>>a+b>>”c”;в) cout>>p;Зад. 5 Какъв ще бъде резултатът от изпълнение на програмния фрагмент: ...cout<<”a=”;cin>>a;cout<<”b=”;cin>>b;cout<<a<<”_”<<b<<endl; ...Ако:а) int a,b; и за входни данни разполагаме с числата 17 и -3;б) float a,b; и за входни данни разполагаме с числата -17 и -3;в) int a,b; и за входни данни разполагаме с числата -17.9 и 3;г) int a; float b; и за входни данни разполагаме с числата 17.1 и 3.7;Зад. 6 Как ще изглежда оператор cout, за да се изведе следната пирамида:

11 _ 2

1 _ 2 _ 3

45

Page 46: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Зад. 7 Да се състави програма PLO4KA.CPP, която прочита от клавиатурата широчината a и дължината b на правоъгълен под и широчината c и дължината d на фаянсова плочка и отпечатва минималния брой плочки, необходими за покриване на пода. Приемаме, че ако някъде трябва да се постави част от плочка, е необходимо да се закупи цяла плочка за това място и че плочките могат да се разполагат винаги по един и същи начин – или всички се поставят вертикално, или всички се поставят хоризантално.

Примерен вход:110 140 20 30 Примерен изход:30Зад. 8. В една библиотека имало три вида печатни издания – книги, вестници и списания.

Служителите добре знаят, че книгите са а броя, вестниците – b, а списанията – c. За да се подредят на лавиците, обаче, те трябва да се разделят на групи по 15. Да се състави програма BIBLIO.CPP, която прочита от клавиатурата a,b и c и отпечатва броя на купчините книги, вестници и списания.

Примерен вход:45 25 48

46

Page 47: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №1Линейни алгоритми

зад. 1 Въведете текста на следната програма:#include <iostream.h>void main() { int a,b; cin>>a>>b; int c=a+b; cout<<c<<endl;

}Изпълнете следните задачи:

Съхранете програмата под име SUMA.CPP. Стартирайте програмата със следните входни данни:

a=5, b=6;a=20, b=30а=34523, b=1235и запишете получените резултати.

Какво се получава в резултат на изпълнение на програмата? Какво е характерно за последния резултат? Коригирайте програмата(ако е необходимо) така, че винаги да се получава верен резултат.

Коригирайте програмата така, че да осъществява приятелска връзка с потребителя, т.е. да извежда съобщения за това какво очаква да бъде въведено, както и да обяснява какво извежда. Напишете текста на новата програма.

зад. 2 Да се състави програма, която въвежда от клавиатурата координатите на точка в равнината и изчислява разстоянието от точката до центъра на координатната система.

Съхранете програмата под име DIST.CPP Стартирайте програмата със следните входни данни:

Абциса: 34,6Ордината: 53,7

Абциса: 4Ордината: 3

Абциса: 34456,678Ордината: 53678,78и запишете получените резултати.

Коригирайте програмата, така че да осъществява приятелска връзка с потребителя, т.е. да извежда съобщения за това какво очаква да бъде въведено, както и да обяснява какво извежда. Напишете текста на новата програма.Съхранете я под същото име.

зад. 3 Да се състави програма, която въвежда от клавиатурата цяло четирицифрено число и отпечатва сумата от цифрите му.

Съхранете програмата под име SUMCIF.CPP Стартирайте програмата. Коригирайте програмата, така че да работи и с 5-цифрени числа.

зад. 4 Напишете програма за обработка на складова наличност, която въвежда от клавиатурата наличността на дадена стока (в килограми и грамове), продаденото количество стока (отново в килограми и грамове) и отпечатва останалата наличност (в кг и г).

Пример: наличността е била 56 кг и 250 г, продадени са 5 кг и 700 г.; при което програмата трябва да изведе 50 кг и 550 г.

Съхранете програмата под име SKLAD.CPP Въведете програмата и я тествайте със следните входни данни:Наличност: 138 кг и 456 гПродажба: 26 кг и 850 гНаличност: 23456 кг и 345 гПродажба: 26789 кг и 850 гНаличност: 45678 кг и 5689 гПродажба: 345 кг и 450 г

47

Page 48: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Проверка на условие. Логически операции. Условна операция. Условен оператор if.

I. Теоретични бележки

1. Логически операции

а) аритметични сравнения

В качеството на аритметични сравнения се използват:> - по-голямо< - по-малко>= - по-голямо или равно<= - по-малко или равно== - равно!= - различно

Всички аритметични сравнения са двуместни операции, като в качеството на операнди могат да се използват произволни аритметични изрази. Резултатът от дадено отношение е цяло число 1 или 0, като 1 се приема за истина, а 0 – за лъжа. Съответно ако отношението е вярно резултатът е 1, а в противен случай е 0.

б) логически операции

Много често се налага да се комбинират няколко аритметични сравнения едновременно. Например ако искаме да кажем, че едно число трябва да е в интервала от 0 до 5 включително, то трябва да е едновременно по-голямо или равно на 0 и по-малко или равно на 5. В друг случай числото трябва да е извън този интервал: тогава то е по-малко от 0 или по-голямо от 5. Доста често се налага да разглеждаме противното на дадено твърдение. В тези случаи на помощ ни идват логическите операции.

Ще разгледаме основните логически операции. Техните стойности са също цели числа, но също като аритметичните отношения, имат смисъл на истина, ако стойността им е 1 и лъжа – ако стойността им е 0.

Чрез аритметичните отношения и логическите операции се получават тъй наречените логически изрази. Тъй като в езика С++ стойностите на логическите изрази се интерпретират като цели числа, то с логическите операции могат да се свързват и числови изрази. Тази възможност на езика го прави много гъвкав в някои ситуации, което дава възможност за създаване на оригинални и ефективни алгоритми в определени случаи.

В езика С++ са дефинирани следните логически операции: Конюнкция – логическо умножение: означаваме с && и четем “и”.

Тази операция е двуместна, като нейни операнди са логически изрази. Както вече отбелязахме, в качеството на логически израз може да се използва и произволен целочислен израз. В този случай за истина се приема всяка стойност различна от 0, докато нулевата стойност се приема за лъжа. Резултатът от операцията конюнкция е истина само в случаите, когато и двата операнда имат стойност истина. Ако поне един от тях е лъжа – резултатът от операцията е лъжа. В следната таблица е показан резултатът от прилагане на операцията && за всички възможни комбинации от стойности на двата операнда.

x y x&&y0

(лъжа)0

(лъжа)0

(лъжа)0

(лъжа)0

(истина)0

(лъжа)0

(истина)0

(лъжа)0

(лъжа)0

(истина)0

(истина)0

(истина)

Дизюнкция – логическо събиране: означаваме с || и четем “или”.

48

Page 49: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Тази операция отново е двуместна, и резултатът от нея е лъжа само в случаите, когато и двата операнда са лъжа. Ето и таблицата за стойностите на операцията || за всички възможни комбинации от стойности на двата операнда.

x y x||y0

(лъжа)0

(лъжа)0

(лъжа)0

(лъжа)0

(истина)0

(истина)0

(истина)0

(лъжа)0

(истина)0

(истина)0

(истина)0

(истина)

Отрицание – означаваме с ! и четем ”не”.Операцията е едноместна и в случай, че операндът е лъжа, резултатът от нея е истина и обратно –

в случай, че операндът е истина, резултатът от нея е лъжа. Ето и таблицата представяща операцията:x !x0

(лъжа)0

(истина)0

(истина)0

(лъжа)

2. Условна операция (операция за условен избор)

Позволява да се пресметне дадена стойност в зависимост от това дали е изпълнено дадено условие или не. Тя е триместна операция и операндите в нея се отделят със знаците ? и :. Ето синтаксиса и семантиката на тази операция:

а) Синстаксис (правила за запис):операнд1 ? операнд2 : операнд3б) Семантика (правила за изпълнение)- изчислява се операнд1;- ако стойността на операнд1 е различна от нула (т.е. истина) се изчислява операнд2 и неговата

стойност се приема като резултат от операцията;- ако стойността на операнд1 е 0 (т.е. лъжа) се изчислява операнд3 и неговата стойност се приема

за резултат от операцията;Пример 1:1)x>y ? 10:100 или (x>y) ? 10 :100

2)z=(x>y) ? 10 :100

Задача: Да се състави програма MINNUM.CPP , която прочита от клавиатурата три цели числа а,b и c и отпечатва на екрана най-малкото от тези числа.

Решение:Този алгоритъм беше разгледан вече в темата “Алгоритми” и затова направо ще направим анализ

на реализацията му.1. Необходими величини:

Освен трите променливи, чрез които ще бъдат въведени входните данни, ще използваме още една целочислена променлива, в която в края на програмата ще бъде записано минималното от трите числа.

int a,b,c,m;2. Като начало, трябва да се въведат трите числа:

cin>>a>>b>>c;3. Търсенето на минималното число започва, като се приеме, че това е числото а и се

присвоява на променливата m, в която в крайна сметка ще бъде записано минималното от трите числа.m=a;

4. На следващата стъпка се сравнява числото b с m и с помощта на условната операция на m се присвоява по-малкото от числата b и m.

m=b<m?b:m;

49

Page 50: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

5. На следващата стъпка се сравнява числото c с m и с помощта на условната операция на m се присвоява по-малкото от числата c и m.

m=c<m?c:m;6. Накрая на екрана трябва да бъде изведено числото m.

cout<<m<<endl;Окончателно програмата има следния вид:

//minnum.cpp#include<iostream.h>void main(){int a, b, c, m;cin>>a>>b>>c;m=a;m=m<b?b:m;m=m<c?c:m;cout<<m<<endl;

}

3. Условен оператор

Чрез условната операция може да се изчисли една или друга стойност на даден израз в зависимост от това, дали е изпълнено или не даденото условие. Понякога от условие зависи дали да се изпълни или не даден оператор. В този случай условната операция не може да бъде използвана и затова в езика С++, както и във всички останали езици за програмиране, се използва т.нар. условен оператор. Условните оператори реализират разклоняващи се изчислителни процеси (разклонени алгоритми).

а) Пълен условен оператор

Синтаксис(правила за запис):if (израз) оператор1;

else оператор2;израз – нарича се условие за преход. Може да бъде допустим за езика израз.оператор1 и оператор2 – произволни, допустими за езика оператори;Семантика (правила за изпълнение):- изчислява се стойността на израза;- ако стойността на израза е различна от нула (т. е. истина), се изпълнява оператор1;- ако стойността на израза е равна на нула (т.е. лъжа), се изпълнява оператор2;- след изпълнението на оператор1 или оператор2 се пристъпва към изпълнението на следващият

оператор в програмата, който е записан непосредствено след конструкцията if-else.

Пример 2: Какъв ще бъде резултата от изпълнението на условният оператор

if (x) cout<<”да”<<endl; else cout<<”не”<<endl;

за x=3, x=-2, x=0, x=0.12Отговор: за x=3 резултата е “да”

за x=-2 резултата е “да”за x=0 резултата е “не”за x=0.12 резултата е “да”

При работа с if се съобразяваме със следните правила:- С оператор if-else се избира и изпълнява една от двете взаимноизключващи се възможности.

Един от операторите – оператор1 или оператор2, винаги остава неизпълнен.- Преди else задължително се поставя “;” с изключение на случаите когато преди else е записана

затваряща скоба “}”.- Изразът (условието за преход) задължително се загражда в скоби;

50

Page 51: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

- Условието за преход допуска използването и изчисляването на по-сложни изрази, които могат да включват в себе си операциите за отношение и логическите операции.

- Условният оператор може да се използва многократно в рамките на една програма.

б) Кратък условен оператор

Синтаксис(правила за запис):if (израз) оператор;

израз – нарича се условие за преход. Може да бъде всеки допустим за езика израз; оператор – произволен, допустим за езика оператор.Семантика (правила за изпълнение):- изчислява се стойността на израза;- ако стойността на израза е различна от нула (т.е. истина), се изпълнява операторът, след което

програмата продължава с изпълнението на следващият оператор в програмата след if;- ако стойността на израза е нула, програмата продължава с изпълнението на следващият

оператор в програмата след if;

в) Съставен оператор

В някои случаи синтаксиса на езика изисква използване само на един оператор, а алгоритъма предвижда изпълнение на няколко действия. В такива случаи се налага няколко последователни оператора да се обединят в един. Това става с тъй наречения съставен оператор.

Синтаксис(правила за запис): {оператор 1;оператор 2; …оператор n;}където оператор 1, оператор 2, ..., оператор n са допустими за езика оператори.Семантика(правила за изпълнение):Съставният оператор се изпълнява, като се изпълняват писледователно операторите, които го

съставят.

4. Вложени условни оператори

В случаите, когато на мястото на оператор1 и(или) оператор2 в конструкцията if-else се налага използване на друг условен оператор, говорим за вложени условни оператори.

При използване на вложени условни оператори спазваме следните правила:- Всяко else се съчетава с най-близкият до него неизползван if.- Текста на програмата се преглежда отляво надясно.- За по-голяма прегледност в текста на програмата подреждаме всеки else под if-а за който се

отнася.- За да избегнем неправилното съчетаване на else с if е добре да ограждаме вложения условен

оператор с {}.

51

Page 52: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

II. Решени задачи

Задача 1. Уравнение.

Да се състави програма KOREN.СРР, която намира корена на уравнението ax=b, където а и b са числа, въведени от клавиатурата.

Примерен вход

2 8

Примерен изход

4

Примерен вход

0 5

Примерен изход

Няма решение

Примерен вход

0 0

Примерен изход

Всяко х е решение

Решение

1. Необходими величини:За решението на задачата са необходими трите дробни променливи a,b и x:float a, b, x;

2. В началото коефициентите на уравнението трябва да се въведат от клавиатурата:cin>>a>>b;

3. Както вече беше обсъдено в темата “Алгоритми”, решението на уравнението зависи от това дали а е 0 или е различно от 0. Така, че на следващата стъпка се налага да се провери дали а=0:

а/ Ако а=0, се проверява дали b=0:3.1.1. Ako b=0, на екрана се отпечатва, че всяко х е решение на уравнението.3.1.2. Ако b0, на екрана се отпечатва, че уравнението няма решение.

б/ Ако а0, се пресмята x=b/a, след което на екрана се отпечатва неговата стойност.Това на езика С++ се записва чрез следните оператори:if(a==0)

if(b==0)cout<<”всяко х е решение\n”;

else cout<<”няма решение\n”;

else{x=b/a;cout<<x<<endl;

}Тук, веднага след условието на първия оператор if, е вложен още един условен оператор. След

клаузата му else е използван съставен оператор, тъй като алгоритъмът, описан по-горе предвижда две действия – пресмятане на х и отпечатването му на екрана.

Окончателния вид на програмата е следния:

//koren.cpp#include<iostream.h>void main() { float a, b, x;

52

Page 53: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cin>>a>>b; if(a==0) { if(b==0)

cout<<”Всяко х е решение”<<endl;else cout<<”Няма решение”<<endl;}else{ x=b/a; cout<<”x=”<<x<<endl;}

}

Задача 2. Квадранти.

Да се състави програма KVAD.CPP, която въвежда от клавиатурата координатите x и y на точка в равнината и отпечатва номера на квадранта, на който тя принадлежи. Ако точката принадлежи на някоя от осите на координатната система, да се изведе ОХ за абсцисната ос и ОУ – за ординатната.

Примерен вход

2 8

Примерен изход

І

Примерен вход

-1 5

Примерен изход

ІІ

Решение:

За да определим в кой квадрант се намира точката, трябва да проверим знаците на координатите и.

1. Необходими величини:Необходими са ни единствено двете дробни координати на точката:float x,y;

2. Въвеждаме координатите на точката:cin>>x>>y;

3. Проверките за това на кой квадрант принадлежи точката ще извършим чрез няколко последователни оператора if, всеки от които проверява дали точката принадлежи на даден квадрант:

if(x>0&&y>0)cout<<”I\n”;if(x<0&&y>0)cout<<”II\n”;if(x<0&&y<0)cout<<”III\n”;if(x>0&&y<0)cout<<”IV\n”;

4. Накрая е добре да отбележим, че ако оставим програмата така, в случай че се въведе точка, принадлежаща на координатните оси, на екрана нищо няма да се изведе. Вече отбелязахме, че добрия алгоритъм винаги трябва да извежда решение или съобщение, че няма такова. Ето защо ще добавим още два условни оператора, с които ще си осигурим “реакция” на програмата при въвеждане на точка от координатните оси.

if(x==0)cout<<”OY\n”;if(y==0)cout<<”OX\n”;Ето и окончателния вид на програмата:

//kvad.cpp#include<iostream.h>void main()

53

Page 54: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

{float x,y; cin>>x>>y;if(x>0&&y>0)cout<<”I\n”;if(x<0&&y>0)cout<<”II\n”;if(x<0&&y<0)cout<<”III\n”;if(x>0&&y<0)cout<<”IV\n”;if(x==0)cout<<”OY\n”;if(y==0)cout<<”OX\n”;

}

Задача 3. Ограда.

Да се състави програма DOMAIN.CPP, която въвежда от клавиатурата координати на точка в равнината и отпечатва “YES”, ако тя принадлежи на защрихованата област и “NO”в противен случай.

Примерен вход

0.5 0.5

Примерен изход

NO

Примерен вход

1 1

Примерен изход

YES

Решение:

За да определим дали точката се намира в защрихованата област е необходимо да проверим дали тя е извън кръга с радиус 1 и вътре в правоъгълник със страна 2, като и двете фигури имат за център, центъра на координатната система.

1. Необходими величини:Двете координати на точката x и y.float x,y;

2. Първо въвеждаме от клавиатурата координатите на точката:cin>>x>>y;

3. Проверката за принадлежност на областта ще осъществим чрез конюнкция на следните две условия:

(x*x+y*y)>=1 –точката не принадлежи на кръга; (fabs(x)<=1)&&(fabs(y)<=1) – точката принадлежи на квадрата.

Проверката ще извършим с оператор if:if((x*x+y*y)>=1&&(fabs(x)<=1)&&(fabs(y)<=1)) cout<<”YES\n”; else cout<<”NO\n”;Окончателно програмата има следния вид:

//domain.cpp#include<iostream.h>#include<math.h>void main(){float x,y;cin>>x>>y;if((x*x+y*y)>=1&&(fabs(x)<=1)&&(fabs(y)<=1)) cout<<”YES\n”;

else cout<<”NO\n”}

54

1

-1 -r 1

-1

Page 55: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

III. Задачи за упражнение

Зад. 1. Пресметнете:а)5+6<0?4:2;б)(4<6)&&(5>7)?5:6;в)15>3+6?1:0.

Зад. 2. Какъв е резултата от операциите, ако a=3, b=2, c=4:а) b+3>=a*c-7; г) 7>=16 && 4==4;б) a==(b=12); д) 7>=16 || 4==4;в) !(4!=5); е) 15+c !=a*b-c.

Зад. 3. Запишете като изрази условията:а) x [0,1];б) x [0,1];в) x [2,5] или x [-1,1].

Зад. 4. Какво трябва да променим в записа на условният оператор,if (a>b ) cout<<”max”<<a<<endl; else cout<<”max”<<a<<endl;

така че вместо по-голямото, програмата да извежда на екрана по-малкото от две реални числа a и b.

Зад. 5. В записите на кои от условните оператори е допусната грешка. Поправете я:а) if (y) x=y

else x=2*y ; б) if x x=3*x ;

else cout<<x;в) if (a%b=0) cout<<a;

else cout<<b;г) if (x>y) x=y;

y=y-x;x=x-y ;

else cout<<y ;Зад. 6. Кой от посочените варианти описва функцията:

а) if(x>2)y=x;else if(x<=3)y=2;else y=x-1;б) if(x<2)y=x;else if(x>=3)y=2;else y=x-1;в) if(x<=2)y=x;else if(x<=3)y=2;else y=x-1. Запишете вярното решение по подходящ начин, като всяко else подредете под if-а, към който се

отнася.

Зад. 7. На входа на една дискотека трябвало да се изгради пропусквателна система с компютър, която да определя дали клиентът може да бъде допуснат в заведението. Съставете програма VHOD.EXE, която по въведено четирицифрено число n, годината на раждане на клиента, от клавиатурата извежда съобщение “Yes”, “No” или “Yes, s pridrugitel!”, като знаете, че след 22 часа в дискотеките не се допускат деца под 16 години, а от 16 до 18 годишна възраст - само с придружител.

Зад. 8. Да се състави програма VAL.CPP, която въвежда числата A и B и извежда стойността на C, ако:

Зад. 9. В едно училище започнали да облагородяват двора и решили да поставят беседка, но се оказало, че тя може да бъде или с формата на квадрат със страна а, или кръг с радиус r. Да помогнем на

55

Page 56: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

ръководството на училището като съставим програма BESEDKA.CPP, която по въведени дробни положителни числа a и r, определя по-голямата по площ беседка.

Зад. 10. Да се състави програма YEAR.CPP, която след въведена година от клавиатурата, извежда съобщение дали е високосна.

Зад. 11. Да се състави програма ODD.CPP, която за две числа x и y извежда тяхното произведение, ако x е четно и тяхната разлика, ако x е нечетно.

Зад. 12. Да се състави програма TRI.CPP, която извежда на екрана “YES”, ако три реални числа въведени от клавиатурата, могат да бъдат страни на триъгълник и “NO”, в противен случай.

Зад. 13. Една година е щастлива, ако има поне две еднакви цифри в записа си. Да се състави програма HAPPYYEAR.CPP, която прочита от клавиатурата дадена година (цяло четирицифрено число) и отпечатва “YES”, ако тя е щастлива и “NO”, в противен случай.

Зад. 14. Да се състави програма COMPET.CPP, която прочита от клавиатурата целочислените резултати на трима състезатели, участвали в едно лекоатлетическо състезание и отпечатва най-високия резултат.

Зад. 15. Хвърляме зарче и ако ни кажат, че числото, което се е паднало е голямо, дели се на 2, а също и на 3, веднага ще отгатнем, че това е числото 6. Ако направим уговорката, да считаме числата 1, 2 и 3 за малки, а числата 4, 5 и 6 – за големи, всеки без затруднение би могъл да отгатне едно зарче, достатъчно е само да знае за него отговорите на следните три въпроса: “Числото голямо ли е?”, “Числото дели ли се на 2?”, “Числото дели ли се на 3?”. Разбира се, трябва да внимаваме да не би да си имаме работа с някой шегобиец, който би отговорил, че числото е голямо и се дели на 3, но не се дели на 2.

Да се напише отгатваща програма ZAR4E.CPP, която по зададени от нея въпроси и получени от страна на потребителя отговори извежда на екрана намисленото число.

Зад. 16. В една компютърна игра, наречена SeaWar, в даден момент трябва да се реши следния проблем: Зададени са два плавателни съда A(XA,YA) и B(XB,YB). Предполага се, че играчът се намира в центъра на координатната система, но бойната мощ на оръжията му е гарантирана до точно определено разстояние от целта. Налага се да се изведат на екрана координатите на този плавателен съд, който се намира в обхвата на оръжията на играча.

Съставете програма SEAWAR.CPP, която въвежда координатите на плавателните съдове и максималното разстояние, при което оръжията на играча гарантират успех, и извежда на екрана координатите на този от корабите, който може да бъде поразен от тази позиция. Ако някой от корабите не може да бъде поразен, да се отпечата разстоянието, което не достига за това.

Забележка: Могат да бъдат поразени и двата кораба или нито един от тях.Зад. 17. Даден е квадрат със страна 2, чийто център съвпада с центъра на координатната система.

Да се състави програма SQUARE.CPP, която въвежда от клавиатурата координатите х и у на точка в равнината и отпечатва “YES”, ако точката принадлежи на квадрата и “NO” – в противен случай.

Примерен вход:0 0Примерен изход:YESПримерен вход:2 1Примерен изход:NO

56

О(0,0)

фиг. 21.

1

1-1

-1

Page 57: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Зад. 18. Даден е квадрат със страна 2, чийто център съвпада с центъра на координатната система и квадрат със страна 4, чийто център също съвпада с центъра на координатната система. Страните на двата квадрата са успоредни на координатните оси както е показано на фиг. 22. Да се състави програма

SQUARE2.CPP, която въвежда от клавиатурата координатите х и у на точка в равнината и отпечатва “YES”, ако точката принадлежи на защрихованата област и “NO” – в противен случай.

Примерен вход:0 0Примерен изход:NOПримерен вход:2 1Примерен изход:YESЗад. 19. Дадена е квадратна мишена, чийто център съвпада с центъра на координатната система.

Да се състави програма TARGET.CPP, която въвежда от клавиатурата координатите на изстрел х и у и отпечатва колко точки получава изстрела, като е известно, че изстрел, попаднал в първия квадрат получава 10 точки, във втория – 5 точки, а в третия – 2 точки. Ако изстрелът е извън мишената, получава 0 точки.

Примерен вход:0 0Примерен изход:10Примерен вход:2 1Примерен изход:5Примерен вход:2 3Примерен изход:2Примерен вход:4 4Примерен изход:0

57

О(0,0)

фиг. 22.

1

1

-1

-1

2

2

-2

-2

Page 58: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

0

Зад. 20. Дадени са два правоъгълника, долния ляв ъгъл, на които съвпада с началото на координатната система и техните страни a1, b1, a2 и b2. Да се състави програма IMPL.CPP, която прочита от клавиатурата последователно координатите x,y на точка в равнината и дължините на страните на двата правоъгълника a1, b1, a2 и b2 и отпечатва 0, ако точката принадлежи едновременно на двата правоъгълника, 1 – ако принадлежи само на един от тях и –1- ако не принадлежи на нито един от тях.

Примерен вход:2 4 5 2 1 1 Примерен изход:0Примерен вход:7 8 10 10 8 8Примерен изход:1Примерен вход:1 1 1 1 5 5Примерен изход:-1Зад. 21. Дадени са два правоъгълника, така както са показани на фиг. 7. Да се състави програма

RECTS.CPP, която въвежда координатите на посочените върхове на двата правоъгълника, съответно (x1,y1) и (x2,y2) за единия и (a1,b1) и (a2,b2) за другия и отпечатва лицето на сечението на двата

правоъгълника.Примерен вход:1 1 5 3 3 2 7 8Примерен изход:2

58

О(0,0)

фиг. 24

1

1

-1

-1

2

2

-2

-2

5

3

-5

-3

О(0,0)a1

a2

b1 b2

фиг. 25

О(0,0)

фиг. 26

(x1,y1)

(x2,y2)

(a1,b1)

(a2,b2)

Page 59: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №2Разклонени алгоритми

зад. 1 Въведете текста на следната програма:#include <iostream.h>void main(){int x,y;cout<<” x=”; cin>>x ;cout<<” y=”;cin>>y;if(x==5) if(y==7) cout<<“sl. 1\n”; else cout<<“sl. 2\n”;if(x==5) { if(y==7) cout<<“sl. 1\n”;} else cout<<“sl. 3\n”;if(x==5) if(y==7) cout<<“sl. 1\n”; else cout<<“sl. 2\n”;else if (y==5) cout<<“sl. 4\n”; else cout<<“sl. 5\n”;}

Изпълнете следните задачи: Стартирайте програмата със следните входни данни:

x=5, y=7;x=5, y=30x=34, y=1235x=8, y=7;x=8, y=8;

и запишете получените резултати. С помощта на прозореца за проследяване на програми проследете как се променят

стойностите на величините в програмата в зависимост от изпълняваните оператори.

зад. 2 Да се състави програма, която въвежда от клавиатурата координати на точка в равнината и отпечатва в кой квадрант се намира тя.

Стартирайте програмата със следните входни данни:Абциса: 34,6Ордината: 53,7

Абциса: 4Ордината: 3

Абциса: 34456,678Ордината: 53678,78и запишете получените резултати.

С помощта на прозореца за проследяване на програми проследете как се променят стойностите на величините в програмата в зависимост от изпълняваните оператори.

зад. 3 Да се състави програма, която въвежда от клавиатурата координати на точка в равнината и отпечатва дали тя принадлежи на защрихованата област.

Стартирайте програмата със следните входни данни:Абциса: 1Ордината: 2,7

Абциса: 5Ордината: 0

Абциса: 1

59

Page 60: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

О(0,0)

фиг. 27.

1

1

-1

-1

2

2

-2

-2

5

3

-5

-3

Ордината: 0.5и запишете получените резултати.

Коригирайте програмата така, че да прави аналогични проверки и за другите области.

Стартирайте новите варианти на програмата за същите входни данни и запишете резултатите.

зад. 4 В една компютърна игра, наречена SeaWar, в даден момент трябва да се реши следния проблем: Зададени са два плавателни съда A(XA,YA) и B(XB,YB). Предполага се, че играчът се намира в центъра на координатната система, но бойната мощ r на оръжията му е гарантирана до точно определено разстояние от целта. Налага се да се отпечатат координатите на този плавателен съд, който се намира в обхвата на оръжията на играча.

Съставете програма SEAWAR.CPP, която въвежда координатите на плавателните съдове и максималното разстояние, при което оръжията на играча гарантират успех, и отпечатва координотите на този от корабите, който може да бъде поразен от тази позиция. Ако някой от корабите не може да бъде поразен, да се отпечата разстоянието, което не достига за това.

Стартирайте програмата със следните входни данни:XA=2 YA=4XB=2 YB=2r=4

XA=2 YA=4XB=2 YB=2r=14

XA=2 YA=4XB=2 YB=2r=2.5

XA=2 YA=4XB=2 YB=2r=1

С помощта на прозореца за проследяване на програми проследете как се променят стойностите на величините в програмата в зависимост от изпълняваните оператори.

зад. 5 Дадена е квадратна мишена, чийто център също съвпада с центъра на координатната система. Да се състави програма TARGET.CPP, която въвежда от клавиатурата координатите на изстрел х и у и отпечатва колко точки получава изстрела, като е известно, че изстрел, попаднал в първия кръг получава 10 точки, във втория – 5 точки, а в третия – 2 точки. Ако изстрелът е извън мишената, получава 0 точки.

Стартирайте програмата със следните входни данни:

0 02 12 34 4

60

Page 61: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Оператор за избор на вариантI. Теоретични бележки

1. Пример

Ще разгледаме следната задача:Задача: Да се състави програма DAY.CPP, която въвежда от клавиатурата цяло число от 1 до

7 и отпечатва съответния ден от седмицата, като на 1 съпоставя понеделник, на 2 – вторник и т.н. В случай, че е въведено число различно от описаните, на екрана се извежда “Еrror!”.

Решение:

Единствената величина, която ще използваме при решението на тази задача е целочислената променлива съдържаща номера на деня от седмицата.

int day;След въвеждане на числото day от клавиатурата, с помощта на няколко последователни условни

оператора проверяваме какво число е въведено и извеждаме съответното съобщение:cin>>day;if(day==1) cout<<”понеделник\n”;

elseif(day==2) cout<<”вторник\n”;elseif(day==3) cout<<”сряда\n”; elseif(day==4) cout<<”четвъртък\n”; elseif(day==5) cout<<”петък\n”;elseif(day==6) cout<<”събота\n”;elseif(day==7) cout<<”неделя\n”;else cout<<”Error!!!\n”;

От тук вече е много лесно да се реализира окончателния вид на програмата.Прави впечатление, че многократно се повтарят еднотипни езикови конструкции, които

проверяват еднотипни условия. В този случай се налага разклоняване на програмата не само в две, а в много посоки. Описаната задача е често явление в програмирането. По една или друга причина често се налага програмата да се разклонява в няколко посоки. Операторите, с които реализирахме решението на задачата могат да се заменят с единствен оператор, наречен оператор за избор на вариант. Повечето езици за програмиране включват такъв оператор. В езика С++ това е оператор switch. Да разгледаме особеностите при използването на оператора.

2. Синтаксис и семантика на оператор switch

а) Синтаксис на оператора за избор на вариант (правила за запис):

switch (израз) { case израз1 : оператор; оператор;… оператор; break; case израз2 : оператор; оператор;… оператор; break; ... case израз n : оператор; оператор;… оператор; break; [default : оператор; оператор;… оператор; break; }

където:оператор – произволен оператор, допустим за езикаизраз – допустим за езика израз, резултата от който задължително не е от реален тип. Нарича се

още дискриминанта.

61

switch (израз) {case израз1 : оператор; оператор;… оператор; break; case израз2 : оператор; оператор;… оператор; break;

... case израз n : оператор; оператор;… оператор; break;

[default : оператор; оператор;… оператор; break; }

Page 62: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

израз1, израз2 ,..., израз n – константни изрази, задължително с различни стойности. Наричаме ги етикети. Тяхната стойност не зависи от входните данни

Забележка: Операторът break, описан в синтаксиса не е задължителен за използване. Неговото пропускане води до промяна на смисъла на програмата. Ще разгледаме това в следващите примери.

б) Семантика на оператор switch (правила за изпълнение):

- изчислява се стойността на израза(както споменахме по-горе, резултата е константа);- получената константа се сравнява последователно със стойностите на етикетите(израз1,

израз2 ,..., израз n);- при съвпадение на стойността с някой от етикетите се изпълняват оперторите, записани след

клаузата case на съответния вариант, до срещане на оператор break;- при несъвпадение на стойността с някой от етикетите се изпълняват оперторите, съответстващи

на варианта default, до достигане на оператор break. При липса на вариант default не следват никакви действия от оператор switch.

в) Забележки (Правила на използване)

При използването на оператор switch трябва да спазваме няколко основни правила: дискриминантата задължително се загражда в скоби; етикетите задължително са константи; стойностите на етикетите не зависят от входните данни; редицата от оператори, съответстващ на даден етикет може да е празна; варианта default не е задължителен, но добрият стил за програмиране го изисква; обикновенно последният оператор за изпълнение от всеки вариант е оператор break. Той

предизвиква прекъсване на изпълнението на оператор switch и предава управлението на първия оператор след него;

3. Оператор break

Синтаксис(правило за запис):break;Семантика(правило за изпълнение): Прекратява изпълнението на най-вътрешния, съдържащ го оператор switch или оператор за

цикъл. Изпълнението на програмата продължава от оператора, следващ прекъснатия.

Имайки предвид казаното можем да решим задачата, като използваме оператор за избор на вариант:

//day.cpp#include<iostream.h>void main(){int day;cin>>day; switch (day) { case 1 : cout<<”Понеделник\n”; break;case 2 : cout<<”Вторник\n”; break;case 3 : cout<<”Сряда\n”; break;case 4 : cout<<”Четвъртък\n”; break;case 5 : cout<<”Петък\n”; break;case 6 : cout<<”Събота\n”; break;case 7 : cout<<”Неделя\n”; break;default : cout<<”Error!!!\n”; break;

}}

62

Page 63: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

II. Решени задачи

Задача 1. Месеци.

Да се състави програма MONTH.CPP, която прочита от клавиатурата цяло число от 1 до 12 и отпечатва броя на дните в съответния месец.

Примерен вход

1

Примерен изход

31

Примерен вход

2

Примерен изход

28 или 29

Решение:

1. Необходими величини:За решение на задачата е необходима единствено променливата, в която се записва номера на

месеца:int m;

2. Първо се въвежда от клавиатурата цялото число m:cin>>m;

3. Знаем, че има три възможности за брой на дни в месеца: 31, 30 и броя на дните през февруари. Използването на оператор switch във вида от предната задача не е разумно, защото това предполага да напишем многократно един и същ оператор за отпечатване на 30 или 31. Ето защо ще използваме тази особеност на семантиката на оператора, която изисква програмата да изпълнява всички оператори, записани след съответния case до първото срещане на break. Ще опишем клаузи case за всички месеци с по 30 дни, като ще опишем само един оператор cout<<”30\n” срещу последния case и няма да използваме break преди него. Същото ще направим и с месеците от 31 дни. Ето как ще изглежда оператор switch в този случай:

switch(m){

case 1: case 3: case 5: case 7: case 8: case 10: case 12: cout<<”31\n”; break;

case 4: case 6: case 9: case 11: cout<<”30\n”; break;case 2: cout<<”28 или 29\n”; break;default: cout<<”Error!!!\n”; break;

}Окончателния текст на програмата е следния:

//month.cpp#include<iostream.h>void main(){ int m;cin>>m; switch(m){case 1: case 3: case 5: case 7: case 8: case 10: case 12:

cout<<”31\n”; break;case 4: case 6: case 9: case 11: cout<<”30\n”; break;case 2: cout<<”28 или 29\n”; break;default: cout<<”Error!!!\n”; break;

}}

63

Page 64: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Допълнителна задача: Да се състави програма MONTH2.CPP, която прочита от клавиатурата цяло число m от 1 до 12 и цяло четирицифрено число g – задаващо съответната година, и извежда на екрана броя на дните в съответния месец.

Задача 2. Лица.

Да се състави програма AREA.CPP, която въвежда от клавиатурата дробно число а и цяло число х, и извежда периметъра на равностранен триъгълник със страна а - ако х=1, лицето на квадрат със страна а - ако х=2 и лицето на кръг с радиус а - ако х=3.

Примерен вход

3 1

Примерен изход

9

Примерен вход

5.2 2

Примерен изход

27.04

Решение:

1. Необходими величини:int x; float a;

2. Първо се въвеждат двете числа а и х.cin>>a>>x;

3. Проверката за това коя от трите възможности е избрана, ще реализираме с оператор switch по следния начин:

switch(x){case 1: cout<<3*a<<endl; break;case 2: cout<<a*a<<endl; break;case 3: cout<<3.14*a*a<<endl; break;default: cout<<”Error!!!\n”; break;

}Окончателния текст на програмата е следния:

//area.cpp#include<iostream.h>void main(){float a; int x; cin>>a>>x;switch(x){case 1: cout<<3*a<<endl; break;case 2: cout<<a*a<<endl; break;case 3: cout<<3.14*a*a<<endl; break;default: cout<<”Error!!!\n”; break;

}}

64

Page 65: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 3. С думи.

Да се състави програма INWORDS.CPP, която въвежда от клавиатурата цяло число n от 0 до 19 и го извежда на екрана с думи.

Примерен вход

1

Примерен изход

едно

Примерен вход

15

Примерен изход

петнадесет

Решение:

Известна е зависимостта, по която се образуват имената на целите числа от 13 до 19 – първо се отпечтва думата, съответстваща на цифрата на единиците и след това се отпечатва надставката “надесет”. За разлика от тях числата единадесет и дванадесет се образуват малко по-различно. (вместо еднонадесет – единадесет и вместо двенадесет – дванадесет), което означава, че тези две числа ще се обработват отделно от останалите. Ако числото е едноцифрено, то се отпечатва със съответната дума без надставка. Изключение прави и числото 10, защото неговото наименование е специфично. От казаното до тук става ясно, че ще се наложи да се отделят двете цифри на числото и отпечатването ще се контролира от тяхната стойност.

1. Необходими величини:За решението на задачата освен цялото число, което трябва да се отпечата с думи, са необходими

и две целочислени променливи - за двете му цифри (ако числото е едноцифрено, цифрата на десетиците е 0).

int x,e,d;2. Въвежда се числото от клавиатурата:

cin>>n;3. Пресмятат се цифрите на единиците и десетиците на числото:

e=x%10; //цифра на единицитеd=x/10; //цифра на десетиците

4. Чрез следните проверки се определя какво ще се отпечата на екрана:if(e==0)

if(d) cout<<”десет\n”;else cout<<”нула\n”;

else{switch(e){case 1: if(d)cout<<”еди”; else cout<<”едно”; break;case 2: if(d)cout<<”два”; else cout<<”две”; break;case 3: cout<<”три”; break;case 4: cout<<”четири”; break;case 5: cout<<”пет”; break;case 6: cout<<”шест”; break;case 7: cout<<”седем”; break;case 8: cout<<”осем”; break;case 9: cout<<”девет”; break;

}if(d)cout<<”надесет\n”; else cout<<”\n”;

}Окончателния вид на програмата е следния:

//inwords.cpp

65

Page 66: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

#include<iostream.h> void main(){

int x,e,d;cin>>n;e=x%10; d=x/10; if(e==0)if(d) cout<<”десет\n”;

else cout<<”нула\n”;else{switch(e){case 1: if(d)cout<<”еди”; else cout<<”едно”; break;case 2: if(d)cout<<”два”; else cout<<”две”; break;case 3: cout<<”три”; break;case 4: cout<<”четири”; break;case 5: cout<<”пет”; break;case 6: cout<<”шест”; break;case 7: cout<<”седем”; break;case 8: cout<<”осем”; break;case 9: cout<<”девет”; break;

}if(d)cout<<”надесет\n”; else cout<<”\n”;

}}

66

Page 67: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 4. Детайли.

В едно предприятие се произвеждат три изделия (I1, I2, I3), като за тях са необходими детайлите D1, D2 в количествата, зададени от таблицата:

D1 D2I1 2 0I2 4 2I3 5 4

Да се състави програма DETAILS.CPP, която по дадено изделие и налични количества от детайлите определя колко броя от това изделие могат да се произвеждат.

Примерен вход

3 18 30

Примерен изход

3

Примерен вход

1 12 14

Примерен изход

6

Решение:

За да може да се произведе дадено изделие, за него трябва да има достатъчно количество и от двата детайла. За всеки от двата детайла ще изчислим b1 и b2, съответно броя на изделията, които могат да се произведат с първия и втория детайл. Броя на произведените изделия се определя от по-малкото от двете числа b1 и b2. В зависимост от това кое изделие е избрано, програмата се разклонява в три посоки. Ето защо е удачно да използваме оператор switch.

1. Необходими величини:За решението на задачата е необходима една целочислена променлива, която ще заема стойности

от 1 до 3 и ще определя номера на изделието, което ще се изработва. Освен това са необходими и целочислените величини d1 и d2, които съдържат съответно наличното количество детайли от първия и втория вид. Накрая да отбележим, че са ни необходими и двете променливи b1 и b2, които определят от кой детайл колко изделия могат да се произведат.

int i,d1,d2,b1,b2;2. Първо трябва да се въведат предвидените от условието данни:

cin>>i>>d1>>d2;3. След това в зависимост от избраното изделие, трябва да се изчислят b1 и b2.

switch(i){case 1: b1=d1/2;b2=d1; break;case 2: b1= d1/4;b2=d2/2; break;case 3: b1= d1/5;b2=d2/4; break;

}4. Накрая ще се изведе по-малкото от числата b1 и b2.

cout<<(b1<b2)?b1:b2<<endl;Ето пълния текст на програмата, решаваща задачата:

//details.cpp#include<iostream.h> void main(){int i,d1,d2,b1,b2;cin>>i>>d1>>d2;switch(i){

67

Page 68: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

case 1: b1=d1/2;b2=d1; break;case 2: b1= d1/4;b2=d2/2; break;case 3: b1= d1/5;b2=d2/4; break;

}cout<<(b1<b2)?b1:b2<<endl;

}

III. Задачи за упражнение

Зад. 1. Да се състави програма INWORDS2.CPP, която въвежда от клавиатурата цяло число от 1 до 99 и го отпечатва словом

Примерен вход:56 Примерен изход:петдесет и шестЗад. 2. Да се състави програма MINMAX.CPP, която прочита от клавиатурата целочислените

променливи a,b и с и разменя местата на най-голямата и най-малката измежду трите стойности. Примерен вход:1 8 3 Примерен изход:8 1 3

68

Page 69: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №3Оператор за избор на вариант

зад. 1. Въведете следната програма:#include <iostream.h>void main(){ int d; cout<<“vavedi den ot sedmicata: “; cin>>d; switch (d) {

case 1: cout<<“ponedelnik\n”; break;case 2: cout<<“vtornik\n”;case 3: cout<<“srqda\n”; break;case 4: cout<<“4etvyrtyk\n”;case 5: cout<<“petyk\n”;case 6: cout<<“sybota\n”; break;case 7: cout<<“nedelq\n”;break;default: cout<<“ERROR\n”;

}}

Тествайте програмата със следните входни данни:d=3;d=5;d=1;d=7;d=-15

Защо при някои от тестовете се извежда повече от един отговор? Коригирайте програмата така, че да работи коректно. Опишете какви са корекциите.

зад. 2. В едно предприятие се произвеждат три изделия (I1, I2, I3), като за тях са необходими детайлите D1, D2 в количествата, зададени от таблицата:

D1 D2I1 2 0I2 4 2I3 5 4

Да се състави програма, която по дадено изделие и налични количества от детайлите определя колко броя от това изделие могат да се произвеждат.

Тествайте програмата при следните входни данни:D1=5349D2=3815I=3

D1=4896D2=123I=3

зад. 3. Да се състави програма, която въвежда от клавиатурата цяло число а и по избор извежда периметъра на равностранен триъгълник със страна а, лицето на квадрат със страна а или лицето на кръг с радиус а.

Тествайте я със следните данни:a=35897;i=1;

a=16;i=1;

a=8971;

69

Page 70: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

i=2;

зад. 4. Да се състави програма, която въвежда от клавиатурата цяло число от 1 до 20 и го извежда на екрана с думи.

Коригирайте програмата така, че да работи и с числа от 0 до 99. Напишете новата програма.

зад. 5. Дадени са целочислените променливи a,b и c. Да се състави програма, която разменя местата на най-голямата и най-малката измежду трите стойности.

Тествайте програмата.

70

Page 71: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Оператори за цикълОператор за цикъл do-while

I. Теоретични бележки

1. Пример

Задача: Да се състави програма SUM3.CPP , която въвежда от клавиатурата три цели числа и отпечатва сумата им.

До момента ни е известно едно решение на тази задача – декларираме три променливи, въвеждаме трите числа, събираме ги и отпечатваме резултата. Тъй като в програмирането целта е не просто да напишем програмата, а да намерим оптималния от всички възможни варианти, продължаваме да търсим нови решения.

При създаване на програми се налага използване на страндартни способи, които са се утвърдили с времето и са особено подходящи в определена ситуация.

Когато се търси сума на повече от две числа е добре да се подходи по следният начин:- Декларираме една допълнителна променлива, в която да запишем сумата на трите числа и

приемаме, че първоначално тази променлива има стойност 0.- Последователно въвеждаме всяко едно от трите числа и го добавяме към сумата веднага след

въвеждането му.- Отпечатваме получената сума.Така описаната програма изглежда по следния начин:

#include<iostream.h>void main(){ int a, b, c, s=0;cin>>a; s+=a;cin>>b;s+=b;cin>>c; s+=c;cout<<s<<endl;

}Решението е интересно с това, че числата се въвеждат последователно и на всяка стъпка

успяваме да определим сумата на въведените до момента числа.Така оформена програмата си има и недостатък - с въвеждане на нова променлива заемаме по-

голяма част от оперативната памет, необходима за програмата. Ето защо е добре да помислим за нейното доусъвършенстване.

Лесно можем да забележим, че всяка една от променливите се използва само в два последователни оператора – при прочитането и при добавянето и към сумата. В останалата част от програмата тези променливи не се използват. В този случай можем да се откажем от променливите b и c и вместо тях отново да използваме а.

#include<iostream.h>void main(){ int a, b, c, s=0;cin>>a; s+=a;cin>>а;s+=а;cin>>а; s+=а;cout<<s<<endl;

}

71

Page 72: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Трасирайте програмата с използване на клавиш F7 и проследете как се изпълнява програмата. Как се променят стойностите на променливите a и s?

Какво трябва да променим в програмата, ако търсим сумата на 4 числа, 5 числа ... 100 числа?Колкото и трудоемко да е реализирането на програмата за по-голям брой числа, създаването и е

възможно. Повече би ни затруднила задачата, ако предварително не ни е известен броя на числата.Ако погледнем последната програма ще видим, че има два оператора, които се повтарят при

всяко въвеждане на нова стойност на променливата:cin>>а;s+=а;Ако имаме възможност да напишем програмата, така че да укажем на компютъра да повтаря тези

два оператора определен брой пъти (примерно докато въведем числото 0), това би улеснило работата ни многократно. Повторението на едни и същи действия в една програма, се нарича цикъл. Едно от най-полезните възможности на компютрите е способността им многократно да изпълняват едни и същи действия, с едни и същи или различни стойности на изразите, които участват в тях. Всеки език за програмиране разполага със средства за задаване на такива повторения, които е прието да се наричат “оператори за цикъл”.

За да можем да организираме един цикъл трябва да можем да си отговорим на два основни въпроса:

- Какво се повтаря? - Това трябва да бъде едно или няколко действия, описани чрез допустими за езика за програмиране оператори. Всяко изпълнение на тези действията е прието да се нарича итерация.

- До кога се повтаря? - Това повтаряне на едни и същи действия не може да се извършва безкрайно, т.е. трябва ни условие (израз), което да може да прекъсне цикъла.

2. Синтаксис и семантика на оператор do-while

Задача: Да се състави програма, която въвежда от клавиатурата числа до въвеждане на 0, и отпечатва сумата им.

Решение:Очевидно, тук ще се наложи многократно повторение на описаните в решението на предишната

задача оператори:cin>>а;s+=а;Освен това в условието на задачата е казано ясно до кога трябва да се извършат тези повторения:

докато се въведе числото 0.Като имаме предвид, че използваните променливи остават същите – програмата, която решава

тази задача има следния вид.

//sum.cpp#include <iostream.h>void main(){int a,s=0;do{cin>>а;s+=а;

}while(a);cout<<s<<endl;

} Тук операторът do-while осигурява цикличното повторение на двата оператора cin>>а;s+=а;докато променливата а е различна от 0.Както и за всеки друг оператор и в този случай, ще опишем синтаксиса и семантиката му.а) Синтаксис (правила за запис):do оператор while (израз);оператор – произволен оператор, който е прието да се нарича тяло на цикъла;

72

Page 73: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

израз – условие, което определя до кога се повтаря тялото на цикъла. Тук могат да участват както аритметични, така и логически операции и логически отношения, описани по правилата за логически и аритметични изрази.

Забележка: Тялото на цикъла описва действието, което трябва да се повтаря. Ако се налага да се повтаря повече от едно действие, т. е. се използва повече от един оператор, повтарящите се оператори се обединяват в съставен оператор чрез заграждането им в {}.

б) Семантика (правила за изпълнение):

Операторът do P while (B);, където Р е оператор, а В е израз, се изпълнява по следния начин:- изпълнява се Р;- изчислява се стойността на израза В;- ако стойността на В е различна от нула, т. е. истина, се преминава към изпълнение на P;- ако стойността на В е нула, се изпълнява следващия оператор в програмата.Като използваме този оператор за цикъл, да решим следната задача:Задача. Да се състави програма, която въвежда числа от клавиатурата до въвеждане на нула

и отпечатва броя на числата:Решение:Както вече беше казано, за да успеем да решим задачата, трябва да изясним двата основни

момента:Какво се повтаря? – по аналогия с предишната задача лесно се съобразява, че ще се повтарят

две действия: въвеждането на число а и преброяването му. Самото преброяване ще се осъществи, като при прочитане на всяко число увеличаваме с 1 стойността на една цяла променлива br (много важно е да съобразим, че в началото на програмата на тази променлива трябва да се присвои стойност 0). След този анализ става ясно, че тялото на оператора за цикъл се състои от следните два оператора:

cin>>a;br++;До кога се повтаря? – тук израза, определящ до кога ще се изпълнява програмата, е зададен явно

в условието на задачата, т. е. тялото на цикъла ще се повтаря докато въвежданото число е различно от 0. По-точно казано, в качеството на израз можем да използваме самата променлива а, чрез която се въвеждат числа от клавиатурата. Ако тя е ненулева, тялото на цикъла ще продължи да се изпълнява. В момента, в който се въведе 0, програмата ще продължи със следващия оператор, а следвайки условието, той трябва да извежда броя на въведените числа - br.

След тези уточнения, получаваме като решение на задачата следната програма:

//count.cpp#include<iostream.h>void main(){int a, br=0;do{cin>>a;br++;

}while (a);cout<<”br=”<<br<<endl;

}

При тестване на програмата се оказва, че броят на числата е с 1 по-голям от действителния, т.е. програмата е преброила и числото 0. Ако решим, че числото 0 не трябва да бъде преброявано, трябва да помислим за промяна в решението, която ще го избегне.

//count1.cpp#include<iostream.h>void main(){int a, br=0;do{cin>>a;

73

Page 74: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

br++;}

while (a);cout<<”br=”<<br-1<<endl;

}

в) Забележки (Правила на използване)

При използването на оператора за цикъл do-while трябва да спазваме следните основни правила:- израза задължително се загражда в скоби;- когато в тялото на цикъла трябва да са включени няколко оператора, те се заграждат с { }, т.е.

използваме съставен оператор;- управляващото условие трябва да се променя в тялото на цикъла;- при създаването на програмите трябва да имаме предвид, че тялото на цикъла се изпълнява

задължително поне веднъж.

II. Решени задачи

Задача 2. Да се състави програма MULT.CPP, която чете от клавиатурата цели числа, до въвеждане на числото 1, и отпечатва произведението им.

Примерен вход

3

-1

9

126

1

Примерен изход

-3402

Примерен вход

-13

2

0

1

Примерен изход

0

Решение:От условието на задачата е видно, че при решението ще трябва да реализараме повторение така,

че както и до сега трябва да си отговорим на следните въпроси:- Какви величини са необходими за работата на програмата?int a; //тази целочислена променлива ще използваме за последователното въвеждане на всяко едно от числатаlong Р=1; //в тази променлива ще натрупваме произведението на числата. Присвояваме и първоначална стойност 1, за да можем да умножаваме досегашната стойност на Р

с поредното въведено число. Променливата е от тип long, защото произведението винаги е много по-голямо от числата, които умножаваме и може бързо да излезе извън границите на тип int.

- Какво се повтаря? – по аналогия с предишната задача, лесно се съобразява, че ще се повтарят две действия: въвеждането на число а и умножението на Р с това число, т.е. тялото на оператора за цикъл се състои от следните два оператора:

cin>>a;Р*=а;- До кога се повтаря? – тук израза, определящ до кога ще се изпълнява програмата, е зададен

явно в условието на задачата, т. е. тялото на цикъла ще се повтаря, докато въвежданото число е различно от 1. В момента, в който се въведе 1, програмата ще продължи със следващия оператор, а следвайки

74

Page 75: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

условието, той трябва да извежда произведението на въведените числа Р. Условието за край на цикъла ще изглежда така:

(а!=1)След тези уточнения можем да напишем решението на задачата (кода на програмата).

//mult.cpp#include<iostream.h>void main(){int a;long P=1;do{cin>>a;P*=a;

}while(a!=1);cout<<P<<endl;

}

Задача 2. Да се състави програма NEGATIV.CPP, която чете от клавиатурата цели числа до въвеждане на отрицателно число и отпечатва броя на въведените четни числа

Примерен вход

3

13

24

55

0

46

-8

Примерен изход

2

Упътване:- Какви величини са необходими за работата на програмата?int a; // за последователното въвеждане на всяко едно от числатаint br=0; //за броя на четните числа- Какво се повтаря? cin>>a; //въвежда се поредното числоif(a%2==0)br++; //ако въведеното число се дели на 2 без остатък , се увелечава броя на четните числа.- До кога се повтаря? Докато (а>=0).

III. Задачи за упражнение

Зад. 1. Посочете колко пъти ще се изпълни тялото на цикъла и кое ще бъде последното отпечатано число:

a) I=0; N=11do{I=I+1;cout<<I;

}

75

Page 76: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

while (I<=N);

б) N=11; I=-5;do{I=I+1;cout<<I;

}while (I<=N);

в) I=1;doI=I+2;

while (I!=18);

г) N=11; I=-5;do{I=I-1;cout<<I;

}while (I<=N);

Зад. 2. Какъв е резултатът от изпълнението на следния програмен фрагмент? do

cin>>a>>b>>c;while (a+b>c && a+c>b && b+c>a);

76

Page 77: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Оператор за цикъл whileIV. Теоретични бележки

1. Пример

Нека отново разгледаме една традиционна и вече позната задача.Задача: Да се състави програма MAX3.CPP, която въвежда от клавиатурата три цели числа и

отпечатва най-голямото от тях.Вече намерихме начин на решение на тази задача и той е следния:- Декларираме една допълнителна променлива m, в която да запишем максималното от трите

числа.- Въвеждаме първото число и приемаме, че то e максимално, с други думи го присвояваме на

променливата m.- Последователно въвеждаме всяко едно от останалите две числа и го сравняваме с m. Ако се

окаже, че числото е по-голямо от m, то става максимално, т. е. променяме стойността на m, като и присвояваме стойността на новото число.

- Отпечатваме полученото максимално число.

#include<iostream.h>void main(){ int a, b, c, m;cin>>a; m=a;cin>>b;if(b>m)m=b;cin>>c; if(c>m)m=c;cout<<m<<endl;

}

Лесно може да се забележи, че променливите b и c не са задължителни за правилната работа на програмата и могат да се заменят с променливата a, при което програмата ще добие следният вид:

//max3.cpp#include<iostream.h>void main(){ int a, m;cin>>a; m=a;cin>>a;if(a>m)m=b;cin>>a; if(a>m)m=a;cout<<m<<endl;

}

Също като при задачата за сумата забелязваме, че ако започнем да увеличаваме броя на числата, това просто ще доведе до увеличаване броя на повтарящите се оператори за въвеждане и проверка. Това означава, че можем да решим задачата по същия начин, стига да уточним двата основни въпроса:

- Какво се повтаря? Отговорът в случая е - двата оператора:

cin>>a;if(a>m)m=b;

- До кога се повтаря?

77

Page 78: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Това зависи от условието на задачата. Да решим следната задача:Задача: Да се състави програма MAX.CPP, която въвежда от клавиатурата числа до

въвеждане на 0 и отпечатва най-голямото от тях.Така формулираното условие ни дава възможност да определим до кога ще се повтарят

посочените по-горе оператори, а именно докато въвежданото число а е различно от 0.Сега вече, използвайки знанията си за оператора за цикъл do-while, можем да решим задачата.

Получаваме следната програма:#include <iostream.h>void main ( ){ int a, m;cin>>a;m=a; do{cin>>a;if (m<a) m=a;

}while (a);cout<<”max=”<<m;

}

Вече знаем, че макар и да изглеждат перфектни на пръв поглед, програмите не винаги се държат коректно. Това особено важи когато става дума за някои по-специални случаи.

От решените преди това задачи с цикли, знаем, че при подобна формулировка на повторението, след въвеждане на 0, повторенията спират. Да тестваме и новата програма, като първо въведем числото 0. Ако програмата работи коректно, тя би трябвало да спре в този момент и да отпечата като най-голямо число 0. За съжаление забелязваме, че след въвеждане на 0, програмата продължава да изчаква въвеждането на второ число. След като още веднъж въведем 0, програмата вече наистина спира.

Подобен пропуск е непростим в програмирането и затова сега ще трябва да го отстраним. За целта трябва да открием на какво се дължи. След трасиране на програмата с помощта на клавиша F7, забелязваме, че първото число 0 се въвежда с оператора cin>>a;, който се намира извън тялото на цикъла. След присвояването m=a;, започва изпълнението на тялото на оператора за цикъл, което както вече споменахме винаги се изпълнява поне веднъж. Именно тогава се изисква второто въвеждане на 0, което се оказва излишно.

Ето защо, за да решим проблема, се налага да изключим възможността при първо число 0 цикъла да се изпълнява. Лесно се вижда, че ако поставим преди запазената дума do оператор за проверка, дали стойността на а е различна от 0, програмата вече ще работи коректно, т. е. цикълът ще започне да се изпълнява само ако първото въведено число не е 0.

Получава се следната (вече коректна) програма:#include <iostream.h>void main ( ){ int a, m;cin>>a;m=a; if(a)do{cin>>a;if (m<a) m=a;

}while (a);cout<<”max=”<<m;

}

Тук прави впечатление, че проверката за това, дали a е различно от 0, се прави веднъж от оператора if преди изпълнението на оператора за цикъл и след това отново при условието за край на

78

Page 79: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

цикъла. Това изглежда доста тромаво и неестествено. За щастие, в езика за програмиране С++ е предвиден специален оператор, при който тялото на цикъла може да не се изпълни нито веднъж.

Това е така наречения оператор за цикъл с предусловие while.Операторът while позволява да се организира цикъл, т.е. многократно изпълнение на един или

група последователни оператори. Наборът от последователни оператори записани след while образува тялото на цикъла. Продължителността на цикъла се управлява от условие за край на цикъла, включено в заглавието на оператора while.

За да можем правилно да използваме и този оператор, трябва да се запознаем с правилата за неговото записване (синтаксис) и с правилата за неговото изпълнение (семантика).

2. Синтаксис и семантика на оператор while

а) Синтаксис на оператора за цикъл с предусловие while (правила за запис):

while (израз) оператор;оператор – произволен оператор, който е прието да се нарича тяло на цикъла;израз – условие, което определя до кога се повтаря тялото на цикъла. Тук могат да участват както

аритметични, така и логически операции и логически отношения, описани по правилата за логически и аритметични изрази.

Забележка: Тялото на цикъла описва действието, което трябва да се повтаря. Ако се налага да се повтаря повече от едно действие, т. е. се използва повече от един оператор, повтарящите се оператори се обединяват в съставен оператор чрез заграждането им в {}.

б) Семантика оператора while (правила за изпълнение):

Операторът while (B) P; където Р е оператор, а В е израз, се изпълнява по следния начин:- изчислява се стойността на израза В;- ако стойността на В е различна от нула, т. е. истина, се преминава към изпълнение на P;- ако стойността на В е нула, се изпълнява следващия оператор в програмата.

в) Забележки (Правила на използване)

Както при използването на оператора за цикъл do-while и тук трябва да спазваме няколко основни правила:

- изразът задължително се загражда в скоби;- когато в тялото на цикъла трябва да са включени няколко оператора, те се заграждат с { };- управляващото условие трябва да се променя в тялото на цикъла;- задължителна инициализация (даване на начални стойности) на условието на цикъла;Освен това при създаването на програмите трябва да имаме предвид, че тялото на цикъла може

да не се изпълни нито веднъж.С помощта на оператора за цикъл while, решението на разгледаната по горе задача изглежда така://max.cpp#include <iostream.h>void main ( ){int a, m;cin>>a;m=a; while (a){cin>>a;if (m<a) m=a;

}cout<<”max=”<<m;

}

г) Прилики и разлики в операторите while и do-while

прилики:- и двата оператора имат тяло, което показва какво ще се повтаря;

79

Page 80: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

- и двата оператора имат израз, който определя до кога ще се извършват повторенията. разлики:

- тялото на оператора while може да не се изпълни нито веднъж, докато тялото на do-while се изпълнява задължително поне веднъж;

- в do-while, след скобите на израза поставяме “;”, тъй като с това приключва оператора, докато при while след израза започва тялото на оператора.

Кой от двата оператора ще използваме в дадена ситуация зависи от условието на задачата, която решаваме в момента.

V. Задачи за упражнение:

Зад. 1. Посочете колко пъти ще се изпълни тялото на цикъла и кое ще бъде последното отпечатано число:

а) const N=11;int I=0;while (I<N)

{ I=I+1;cout<<”I=”<<I;

}

б) const N=11;int I=-5;while (I<=N)

{ I++; cout<<I; }

в) I=7;while (I<4)

I+=4;cout<<I;

г) I=3;while (I<4)

I--;cout<<I;

д) const N=11;int I=27;while (I<N)

{ I-=1; cout<<I; }

Зад. 2. Да се състави програма, която чете от клавиатурата числа до въвеждане на 0 и извежда на екрана най-малкото въведено число.

80

Page 81: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Оператор за цикъл forI. Теоретични бележки

1. Пример

Задача: Да се състави програма, която прочита от клавиатурата целите числа M и N и извежда на екрана всички цели числа в интервала [M,N], които се делят на 3.

Решение:Най-лесно тази задача можем да решим като обходим всички цели числа в интервала [M,N] и за

всяко едно от тях проверим дали се дели на 3. Ако това е така, ще го отпечатаме. Това, естествено налага повторение, т. е. организиране на оператор за цикъл. За тази организация е необходимо да отговорим на двата въпроса:

Какво се повтаря?- проверка, дали пореднота число i се дели на 3 и отпечатването му, ако се дели;- преминаване към следващото число.Това на езика С++ изглежда по следния начин:

if (i%3==0) cout<<i<<endl;i++;

До кога се повтаря?- повторението се извършва докато числото i е в интервала [M,N], т. е. докато i<=N.След като уточним, че за инициализация на цикъла е необходимо да дадем начална стойност на

i=M, решението на задачата е следната програма:

#include <iostream.h>void main(){int i, M, N;cin>>M>>N;i=M;while(i<=N);{if (i%3==0) cout<<i<<endl;i++;

}}

В организацията на цикъла while в тази програма има три основни елемента:- инициализацията на цикъла:

i=M- преминаване към следващото число:

i++;- условието за край:

i<=N.Тези три елемента са типични за подобен вид задачи. Винаги когато се налага обхождане на

предварително зададен интервал, ще се налага тяхното използване. В програмирането се срещат много задачи от този тип. За по-лесното им решаване в езика С++ се използва специален оператор за цикъл for. Синтаксисът му е по-сложен от другите два оператора за цикъл, но организиран чрез него, цикълът е по-компактен и заема най-малко място в текста на програмата.

В него трите основни елемента на цикъла са изнесени извън тялото му и се открояват по-лесно. Ето как изглежда горната програма с използване на цикъл for.

#include <iostream.h>void main(){int i, M, N;cin>>M>>N;for(i=M;i<=N;i++)

81

Page 82: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

if (i%3==0) cout<<i<<endl;}

Компактността на програмата е очевидна, така че да се заемем с разглеждането на синтаксиса и семантиката на оператора за цикъл for.

2. Синтаксис и семантика на оператора за цикъл for

а) Синтаксис на оператора за цикъл for (правила за запис):

for (израз1; израз2; израз3) оператор;Където израз1, израз2 и израз 3 са произволни изрази, допустими за езика;Оператор – произволен прост или съставен оператор;израз1 - инициализация на цикъла. С него се присвояват началните стойности на параметрите на

цикъла;израз2 - условие за край, управляващо продължителността на цикъла;израз3 - израз за изменение на текущите стойности на параметрите на цикъла;оператор – тяло на цикъла;Досещаме се, че за да бъде безпроблемно изпълнението на цикъла е необходимо израз1, израз2 и

израз3 да бъдат свързани помежду си логически: с израз1 се установяват началните стойности на променливите, които участват в условието за проверка, а с израз3 се определят правилата, по които променливите се изменят на всяка итерация на цикъла. Израз1 и израз3 най-често са изрази за присвояване, а израз2 е израз за сравнение. И все пак трябва да отбележим, че според синтаксисът на езика нито един от трите израза не е задължителен, т. е. допустимо е използването и на следния оператор:

for(;;)оператор;Тъй като в него не е посочено условие за край, той ще се изпълнява безкрайно и тогава в

използването му не се вижда особен смисъл.

б) Семантика на оператор for (правила за изпълнение):

При изпълнение на оператор for се поражда следната последователност от действия:- изчислява се стойността на израз1, която се използва като начална стойност на управляващата

променлива на цикъла;- изчислява се стойността на израз2, която зависи от управляващата променлива;- ако стойността на израз2 е различна от нула, се изпълнява операторът в тялото на цикъла. След

това се изчислява стойността на израз3 и се присвояава нова стойност на управляващата променлива, като управлението се връща в стъпка 2(т.е. изчислява се стойността на израз2), за да се осъществи следващото завъртане на цикъла;

- ако стойността на израз2 е равна на нула, се изпълнява операторът, записан непосредствено след тялото на цикъла.

Условието за проверка – израз2 определя дали операторите в тялото на цикъла ще бъдат изпълнени поне веднъж или ще бъдат прескочени. От механизма на действие на оператор for следва, че израз1 се изпълнява само веднъж. Ако стойността на израз2 е нула още на първото завъртане на цикъла, израз3 изобщо не се изпълнява.

Променливите, които се използват в израз1, израз2 и израз3 трябва предварително да се дефинират според изискването за дефиниране на нови идентификатори, т.е. преди тяхната упореба. Операторът for в С++ позволява деклариране на управляващите структури в самият цикъл.

Сравнявайки двете решения на разглежданата задача можем да формулираме правило, чрез което да замениме оператор while с for и обратно.

II.

Задачи за упражнение:

Зад. 1. Посочете колко пъти ще се изпълни тялото на цикъла и какъв ще е резулатата от това, ако:

82

for(израз1;израз2;израз3) оператор;израз1; while(израз2)

{оператор;израз3;

}

Page 83: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

а) int n=10;for(int i=1;i<=n;i=i+2) cout<<i<<endl;

б) int n=5,i;for(i=1;i<=n;i--) cout<<i<<endl;

в) int n=-1,i;for(i=1;i<=n;i--) cout<<i<<endl;

г) int n=1;for(int i=1;i<=n;i++) cout<<i<<endl;if (i%3==0) cout<<i<<endl;

Зад. 2. ДСПК отпечатва на отделни редове n пъти:а) поздрава ‘Hello’;б) числата от 1 до n.

Зад. 3. Колко пъти ще се изпълни тялото на цикъла и какъв е резултата от изпълнението на програмния фрагмент?

а) s=0;for(i=1;i<=3;i++) s+=i;cout<<”S=”<<s;

б) s=0;for(i=1;i>=5;i++) s+=i;cout<<”S=”<<s;

в) p=1;for(i=1;i>=0;i+2) p*=i;cout<<”P=”<<p;

г) for(i=1,s=0;I<=N;i++, s+=i);

Зад. 4. Запишете следния цикъл for като цикъл while:int i,s=0;for(i=1;i<=10;i++) s+=i;

Зад. 5. Да се състави програма, която въвежда цяло положително число n, а след това въвежда още n на брой цели числа и пресмята:

а) сумата им;б) произведението им.Зад. 6. ЛИНИЙКИДадени са две еднакви непрозрачни измервателни линийки с разграфени милиметри. По

дължината на всяка линийка са пробити по няколко малки дупки, като дупките са на еднакво разстояние от ръба на линийката. Дупките започват от нулевото деление и след това са разположени равномерно с разстояние между всеки две съседни дупки, равно на М милиметра за едната линийка и на N милиметра за другата. Считаме, че дупки са пробити и на самите крайни деления на линииките, ако там се пада да се пробие дупка, съгласно казаното по-горе. Дължината на всяка от линийките е L милиметра.

Напишете програма LIN.EXE, която въвежда от клавиатурата стойностите на M, N и L, и извежда на екрана броя на дупките, които се виждат след като двете линиики се поставят точно една над друга. Стойностите, които ще се въвеждат са цели положителни числа, като стойностите на M и N са по-малки от 50, а стойността на L може да има най-голяма стойност, равна на 5000.

Пример Въвеждаме: 12 4Програмата трябва да изведе:3

83

Page 84: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Контрол на входните данниПрограмите, които програмистите създават, са предназначени за потребители-неспециалисти по

програмиране. Може да се очаква, че в много случаи те биха допускали грешки при въвеждането на необходимите за работата на програмите входни данни. Това може да се случи и не само поради незнание на материята, но и в резултат на най-обикновенна човешка грешка. Ето защо е изключително важна всяка една потребителска програма да бъде написана така, че да може да предвижда всички варианти на грешно въвеждане и да може да дава подходящи съобщения. Това е сложно за програмиране и ще бъде обект на изучаване на други дисциплини на по-късен етап на обучението по програмиране.

Тук ще се опитаме да дадем идея за това как се контролират входните данни при работа с дадена програма. За целта да разгледаме задачата, която използвахме в предходната тема за илюстрация на цикъл for.

Задача: Да се състави програма, която прочита от клавиатурата целите числа M и N и извежда на екрана всички цели числа в интервала [M,N], които се делят на 3.

Решение:Решението беше описано по горе и окончателния вид на програмата е следния:

#include <iostream.h>void main(){int i, M, N;cin>>M>>N;for(i=M;i<=N;i++)

if (i%3==0) cout<<i<<endl;}

В тази програма входните данни са стойностите на двете цели променливи M и N, които определят границите на интервала [M, N]. При въвеждането им от потребителя може да се допусне грешката числото M да е по-голямо N, при което интервал практически не съществува. Тогава програмата няма да изведе нищо и потребителят може да остане с впечатление, че тя не работи. Добре е веднага след въвеждането на двете числа, да се направи проверка дали входа е коректен. Това може да стане с оператор if за проверка дали M да е по-малко N по следния начин:

#include <iostream.h>void main(){int i, M, N;cin>>M>>N;if(M<N)

for(i=M;i<=N;i++)if (i%3==0) cout<<i<<endl;

elsecout<<”въведени са некоректни данни\n”;

}В този вариант при въвеждане на некоректни входни данни програмата ще спре и няма да

продължи своете изпълнение, при това ще изведе съобщение за причината за това свое действие.Прекратяването на работата на програмата също не е най-добрия вариант за контролиране на

действията на потребителя, защото предвижда повторното и стартиране, за да може да бъде изпълнена с коректен вход.

Ще предложим още един вариант за контролиране на входните данни, при който при въвеждане на некоректен вход, потребителят се задължава отново да направи опит за въвеждане и така докато въведе коректни входни данни според изискванията на програмата. Това изисква организация на оператор за цикъл.

Ще изберем оператор за цикъл while, който се организира непосредствено след въвеждане на променливите M и N. Тялото на оператора се изпълнява докато потребителят въвежда некоректни данни, т. е. докато M >= N. При това на всяка изпълнение се извежда съобщение за причината за повторение на въвеждането. Ако още на първото въвеждане данните са коректни, тялото на цикъла не се изпълнява нито веднъж.

cin>>M>>N;while(M>=N){

84

Page 85: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<”въведени са некоректни данни\nвъведете отново M и N\n”;cin>>M>>N;

}Подобни проблеми стоят пред програмистите при решаване на всяка една от задачите.

Препоръчваме на читателя да допълва описаните по-нататък програми с проверка за коректен вход. Все пак, както вече споменахме, потребителския интерфейс е обект на изучаване на друга дисциплина, затова с цел да избегнем натоварването на алгоритмите, които ще разглеждаме по-нататък, ние ще се абстрахираме от тези проверки.

85

Page 86: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Циклични алгоритмиКакто вече споменахме една от най-мощните възможности на компютъра е бързото многократно

повторение на едно и също действие или изчисление. Ето защо, след като се запознахме и с операторите за цикъл, можем да решаваме много сериозни задачи, които ще разделим на няколко основни групи.

Последователно въвеждане на числа и обработката им

Това са стандартни задачи, при които се осъществява четене на последователност от по едно или няколко числа, като едновременно се обработват за намиране на някакъв резултат.

Задача 1. Отрицателни.

Да се състави програма NEGATIVES.CPP, която въвежда от клавиатурата цели числа до въвеждане на 0 и отпечатва броя на въведените отрицателни числа.

Примерен вход

1

-3

7

-2

-6

0

Примерен изход

3

Решение

1. Ще определим величините, които участват в програмата:Необходими са ни две целочислени променливи – едната – int a, за да записваме в нея текущо

въведеното число и друга – за броя на отрицателните числа. Ще отбележим, че променливата, съдържаща броя на нечетните числа трябва предварително да се нулира: int br=0;

2. Последователното въвеждане на числа е свързано с повторение на определени действия и затова да уточним двете характеристики на повторението:

- Какво се повтаря? Повтарят се две действия: въвеждане на поредното число и проверка, дали то е отрицателно. В

случай, че числото е отрицателно, брояча се увеличава с 1. Тези действия се записват на С++ по следния начин:

cin>>a;if(a<0)br++;- До кога се повтаря? В условието на задачата точно е указан признака за повторение: описаните действия се повтарят,

докато въведеното число а е различно от 0.3. Остава да уточним какъв цикъл ще използваме за реализация на повторенията. Тъй като в

условието за край на повторенията участва стойността на променливата а, то е добре тя да получи стойност преди проверката на това условие. От друга страна условието на задачата предполага, че ще трябва да се въведе поне едно число. Ето защо е правилно в случая да използваме операторът do-while.

4. Накрая програмата трябва да изведе броя на отрицателните числа.Сега можем да напишем текста на програмата:

//negative.cpp#include <iostream.h>void main(){int a,br=0;do{

86

Page 87: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cin>>а;if(a<0)br++;

}while(a);cout<<br<<endl;

}

Тази програма вече може да бъде въведена чрез системата за програмиране BorlandС, да бъде съхранена под име NEGATIVES.CPP и да бъде изпълнена.

Допълнителни задачи:Променете програмата така, че тя да отпечатва броя на числата, кратни на 7.Какво ще се промени в програмата, ако в условието се изисква да се намери не броя, а сумата на

числата, кратни на 7?

Задача 2. Сума К.

Да се състави програма SUMK.CPP, която прочита от клавиатурата цяло число К и след него последователност от числа, докато сумата им стане по-голяма или равна на К, и отпечатва броя на въведените числа.

Примерен вход

10245

Примерен изход

3

Решение

1. Необходими величини:int K; - за първото въведено числоint a; - за текущото число от последователносттаint br=0; - за броя на въведените числа. Като всеки брояч, и този трябва да се нулира.int S=0; - за сумата на числата.

2. Въвежда се променливата K:cin>>К;

3. Организира се цикъл, в който се повтаря:cin>>a; //прочита се текущото числоbr++; //увеличава се броя на въведените числа,S+=a; //добавя се прочетеното число към сумата,докато получената сума не е станала по-голяма или равна на К, т.е. докото S<K.

4. Извежда се броя на въведените числа.cout<<br<<endl;

5. Както и преди, ще използваме цикъл do-while.Окончателно програмата има следния вид:

//sumk.cpp#include<iostream.h>void main()

{int a,br=0,K,S=0;cin>>K;

do {

cin>>а;br++;S+=a;

}while(S<K);

87

Page 88: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<br<<endl;}

Допълнителни задачи:Променете програмата така, че да намира и отпечатва средното аритметично на въведените

числа.

Задача 3. Викторина

За училищна викторина трябвало да се съставят отбори от по трима души, но участниците в тях трябвало да се сработват добре, за да има успех всеки отбор. За да се подберат правилно отборите всички участници били анкетирани, като резултатите от анкетата били записани с цели числа [0, 255]. Въпросите от анкетата били зададени така, че от резултата се разбира лесно дали един отбор е добре подбран. А това е така ако сумата от резултатите на тримата участници в отбора е кратна на 3. Да се състави програма ANKETA.CPP, която чете от клавиатурата последователности от три числа (резултатите на тримата участници в отбора) до въвеждане на три нули и отпечатва след всяка от тях – OK, ако отбора е добре сформиран и Error, ако това не е така. За нулевата тройка не се отпечатва нищо

Примерен вход

6 7 8 8 9 35 4 121 3 510 11 40 0 0

Примерен изход

OKERROROKOKERROR

Решение

За да определим дали даден отбор е добре сформиран, е необходимо да намерим сумата от точките на трите участника и да проверим дали се дели на три.

1. Необходими величини:Тъй като е необходимо на всяка стъпка да обработваме резултатите и на тримата състезатели, ще

са ни необходими три целочислени променливи a, b и c за всеки един от състезателите, както и променливата S за сумата от точките на тримата.

int a,b,c, S=0;2. Още веднага се организира цикъл do-while, в който на всяка стъпка се въвеждат трите

числа a,b и c, пресмята се сумата им S и се проверява дали е кратна на 3. Условието за край може да бъде проверено най-лесно, като се вземе под внимание, че сумата на три цели положителни числа (каквито са нашите) е 0 тогава и само тогава, когато и трите са 0.

do{cin>>а>>b>>c;S=a+b+c;if(s&&s%3) cout<<”ERROR\n”;//проверката за s се налага от условието, че за последната тройка програмата не отпечатва нищоelse cout<<”NO\n”;

}while (S);Тези две стъпки всъщност решават задачата.В този случай общия вид на програмата е следния:

//anketa.cpp#include<iostream.h>void main()

{int a,b,c,S=0;

88

Page 89: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

do{

cin>>а>>b>>c;S=a+b+c;if(S&&S%3) cout<<”ERROR\n”;

else cout<<”OK\n”;}while (S);

}

Намиране на оптимален елемент от въвеждана последователностВ темата за оператор за цикъл while решихме задача, в която се въвежда редица от числа и се

отпечатва максималното от тях. Този вид задачи са едни от най-популярните в програмирането. Непрекъснато се налага да се намери победител в състезание, да се определи най-висока цена и т.н.

Задача 4. Максимално отрицателно число

Напишете програма MAXNEG.CPP, която въвежда от клавиатурата цели числа, до срещане на числото 0(нула), и извежда на екрана максималното отрицателно число. Ако в последователността не е въведен нито един отрицателен елемент се извежда 0.

Примерен вход

1-37-2-60

Примерен изход

-2

Решение

Когато се определя оптимален елемент, първата стъпка е да приемем, че един от всички елементи, който отговаря на останалите условия, е евентуален кандидат за оптимален. След това го сравняваме с всички останали и ако намерим такъв, който го превъзхожда – го заместваме. Ще определим величините, които участват в програмата:

1. Необходими са ни две целочислени променливи – едната: int a;, за да записваме в нея текущо въведеното число и друга int mn; – за максималното отрицателно число.

2. Както вече споменахме, първо трябва да открием първото отрицателно число от поредицата и да го обявим за максимално. Да обърнем внимание и на това, че във въвежданата последователност може и да няма отрицателни елементи. Ето защо, трябва да предвидим и варианта да се въведе 0, без да е въведен нито един отрицателен елемент и тогава трябва да отпечатаме 0. Намирането на първия отрицателен елемент ще се реализира с цикъл, в който числата ще се четат от клавиатурата докато бъде въведено отрицателно число или 0.

do cin>>a while(a>0);3. След като цикълът завърши, се налага да проверим причината за спирането му. Това

може да бъде въвеждане на 0, което означава извеждане на 0 и край на програмата. В случай, че е въведено отрицателно число означава, че то трябва да бъде обявено за максимално и въвеждането да продължи до въвеждане на 0, като при това всяко число се проверява дали е отрицателно и дали е по-голямо от определения вече максимален елемент. Ако се открие такова число, то се обявява за максимален елемент. Това се реализира по следния начин:

if(!a) cout<<0<<endl;else{

mn=a;while(a)

{cin>>a;if(a<0&&a>mn)mn=a;

89

Page 90: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

}cout<<mn<<endl;

}Последният оператор извежда на екрана максималното отрицателно число.Сега можем да напишем текста на програмата:

//maxneg.cpp#include <iostream.h>void main(){ int a,mn;do cin>>а; while(a>0);if(!a) cout<<0<<endl; else{

mn=a;while(a)

{cin>>a;if(a<0&&a>mn)mn=a;

}cout<<mn<<endl;

}

} Допълнителни задачи:Променете програмата така, че тя да отпечатва минималното въведено положително число.Какво ще се промени в програмата, ако в условието се изисква да се намери минималното четно

число?

Задача 5. Състезание

В състезание по вдигане на тежести при равни резултати на по-предно място се класира по-лекия състезател. Да се състави програма COMP.CPP, която прочита от клавиатурата цяло число n<=50, резултатите и теглата (които могат да бъдат и дробни числа) на n състезатели и отпечатва номера на златния медалист.

Примерен вход

5

150 70

130 65

150 69

120 80

145 100

Примерен изход

3

В тази задача ще трябва да определим оптимален елемент по два признака, като първият е водещ, но при равенство – оптималността се решава в полза на този, с по-добър втори признак (в случая – с по-малко тегло). Ето защо за златния медалист трябва да съхраним не само номера, но и резултата и теглото му.

1. Необходими са ни две целочислени променливи – едната – int n, за броя на състезателите и друга – за номера на златния медалист –int mn. Ще са необходими и по две променливи за постижението и теглото на състезателя, чиито данни въвеждаме в момента – float p,t; както и за постижението и теглото на златния медалист – float mp,mt;

2. Тук за определяне на първоначалната стойност на оптималния елемент, ще използваме факта, че в най-лошия случай резултата на един състезател е 0 и ще приемем този резултат за

90

Page 91: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

максимален. Естествено е да очакваме, че при въвеждане на данните за всички състезатели, ще се въведе поне едно постижение, различно от 0 и то ще замести приетото за оптимално нулево постижение. Преди да продължим с въвеждане на данните за броя и постиженията на състезателите, ще направим следната инициализация на променливите, характеризиращи златния медалист:

mp=mt=mn=0;3. Въвеждаме броя на състезателите:

cin>>n;4. Сега трябва да въведем последователно постиженията и теглата на всичките n

състезатели, като сравним постижението на всеки от тях с най-доброто до момента: Ако е по-добро, да запомним в променливите mn, mt и mp параметрите на този състезател; ако постижението е равно на най-доброто, ще се наложи да сравним теглата на най-добрия и текущия състезател и ако текущия е по-лек, той ще стане най-добър. Във всички останали случаи промени не са необходими. За n-кратното повторение на тези действия ще използваме цикъл for, управляващата променлива, на който ще съдържа във всеки момент номера на текущия състезател.

for(int i=1;i<=n;i++){cin>>p>>t;if((p>mp)||(p==mp&&t<mt)){mp=p; mt=t;mn=I;

}}

5. Накрая извеждаме номера на златния медалист.cout<<mn<<endl;Ето окончателния вид на програмата:

//comp.cpp#include <iostream.h>void main(){

int n, mn; float p,t,mp,mt ;mp=mt=mn=0;cin>>n;for(int i=1;i<=n;i++){cin>>p>>t;if((p>mp)||(p==mp&&t<mt)){mp=p; mt=t;mn=i;

}}

cout<<mn<<endl;}

91

Page 92: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Отделяне на цифрите на числоЗадача 6. Цифри

Напишете програма DIGITS.CPP, която въвежда от клавиатурата цяло, положително число n и извежда на екрана неговите цифри отдясно наляво, като всяка от тях се отпечатва на отделен ред.

Примерен вход

234

Примерен изход

432

Решение

Лесно можем да определим коя е последната цифра на числото n. За целта е достатъчно да намерим остатъка при деление на n на 10, т.е. n%10. Лесно можем да получим и число, същото като n, но без последната му цифра. Това ще стане като разделим n на 10, т.е n/10. По този начин можем да кажем, че сме задраскали последната цифра на числото.

1. За решението на проблема ще е достатъчна само една целочислена променлива int n; в която ще записваме текущата стойност на числото n.

2. Като начало програмата трябва да въведе числото n от клавиатурата.cin>>n;

3. След въвеждането ще отпечатваме последователно поредната цифра на числото и ще я “задраскваме” от записа му докато свършат всички цифри, т.е. докато числото стане 0. Това може да се реализира с оператор do-while по следния начин:

do{cout<<n%10<<endl;n/=10;

}while(n);

Текстът на тази програма изглежда така:

//digits.cpp#include <iostream.h>void main(){int n;cin>>n;do {cout<<n%10<<endl;n/=10;

}while(n);

} Допълнителни задачи:Променете програмата така, че тя да отпечатва сумата от цифрите на числото.Какво ще се промени в програмата, ако в условието се изисква да се намери броя на цифрите на

числото?

92

Page 93: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 7. Обратно число

Да се състави програма REVERT.CPP, която прочита от клавиатурата цяло число n и го отпечатва, като подрежда цифрите му в обратен ред.

Примерен вход

1234

Примерен изход

4321

Решение

Нека да разгледаме числото от конкретния пример. То може да се представи по следния начин:1234=1*103+2*102+3*10+4=((10*1+2)*10+3)*10+4По същия начин може да се представи и обратното на това число4321=((10*4+3)*10+2)*10+1Лесно се вижда как от първото число може да се получи второто – като се отделят цифрите една

по една и се добавят към натрупаното до момента число, умножено по 10. В началото обърнатото число ще има стойност 0 и постепенно цифрите от едното число “ще се прехвърлят” на другото.

1. Необходими са ни две целочислени променливи: едната – int n; за числото и другата int on; - за обърнатото.

2. Като начало да въведем числото n: cin>>n;

3. След това, докато има цифри в числото n ги прехвърляме в on по следния начин:on=on*10+n%10;n/=10;За да прехвърлим всички цифри е необходимо да организираме цикъл, чието тяло ще съдържа

горните два оператора и ще завършва когато свършат цифрите на n, т. е. докато n е различно от 0.Цикълът ще изглежда по следния начин:do{on=on*10+n%10;n/=10;

}while(n);

4. Накрая извеждаме обърнатото число:cout<<on<<endl;Ето окончателния вид на програмата:

// revert.cpp#include <iostream.h>void main(){

int n, on=0;cin>>n;do

{on=on*10+n%10;n/=10;

}while(n);cout<<on<<endl;

}

Допълнителни задачи:Eдно число се нарича палиндром ако отляво надясно и отдясно наляво се чете по един и същи

начин. Променете програмата така, че да отпечатва “YES”, ако числото е палиндром и ”NO” – в противен случай.

93

Page 94: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Делимост. Делители. Прости числа.В много случаи дадена задача се свежда до намиране на делителите на дадено число, проверка

дали то е просто или разлагането му на прости делители. Да разгледаме някои типични алгоритми, които решават посочените задачи и да опишем тяхната реализация.

Задача 8. Сума от делителите

Да се състави програма DIV.CPP, която прочита от клавиатурата цяло число n и и отпечатва сумата от тези негови делители, които са различни от 1 и n.

Примерен вход

18

Примерен изход

20

Решение

Числата, които могат да бъдат делители на n са тези, които принадлежат на интервала [2, n/2]. Това е очевидно, защото ако допуснем, че 2 е най-малкият възможен делител, то най-големият се получава като разделим числото на него.

1. Необходими са ни две целочислени променливи: едната – int n; за числото и другата long S=0; - за сумата от делителите му. Числото S е от тип long, за да може в него да се запише сумата от делителите на кое да е число от тип int.

2. Като начало да въведем числото n: cin>>n;

3. Обхождат се всички евентуални делители и за всеки от тях се проверява дали наистина дели n. Ако това е така, той се добавя към сумата S:

for(int d=2;d<=n/2;d++) if(n%d==0)S+=d;

4. Накрая се извежда S:cout<<S<<endl;Ето окончателния вид на програмата:

// div.cpp#include <iostream.h>void main(){int n, long S=0;cin>>n;for(int d=2;d<=n/2;d++)

if(n%d==0)S+=d;cout<<S<<endl;

}

94

Page 95: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 9. Просто число

Да се състави програма PRIME.CPP, която прочита от клавиатурата цяло число n и отпечатва “PRIME”, ако числото е просто и “NOPRIME” в противен случай..

Примерен вход

7

Примерен изход

PRIME

Примерен вход

14

Примерен изход

NOPRIME

Решение

Решението на тази задача може лесно да се изведе от предходната, тъй като е очевидно, че едно число е просто, ако сумата от делителите му е 0. Тогава единственото, което трябва да се промени в предходната задача е операторът за отпечатване и така решението ще изглежда по следния начин:

#include <iostream.h>void main(){

int n, S=0;cin>>n;for(int d=2;d<=n/2;d++)

if(n%d==0)S+=d;if(S) cout<<”NOPRIME\n”;

else cout<<”PRIME\n”}

Ако разгледаме внимателно изпълнението на тази програма, ще установим, че цикълът for се изпълнява за всички стойности на d в интервала [2, n/2], независимо от това, че е ако то не е просто, това няма смисъл. Това е крайно нерационално и навежда на мисълта изпълнението на цикъла да се прекратява веднага след срещането на първия делител на числото n. Това може да се постигне, като се добави оператор break, след проверката за делимост. Тогава окончателният вид на програмата е следния:

// prime.cpp#include <iostream.h>void main(){int n, S=0;cin>>n;for(int d=2;d<=n/2;d++)

if(n%d==0){S+=d;break;}if(S) cout<<”NOPRIME\n”;

else cout<<”PRIME\n”;}

95

Page 96: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 10. Най-голям общ делител

Да се състави програма NOD.CPP, която прочита от клавиатурата две цели числа M и N и отпечатва техният най-голям общ делител. Ако двете числа са взаимно прости отпечатва 1.

Примерен вход

18 42

Примерен изход

6

Решение

За да решим тази задача ще използваме известния в математиката Алгоритъм на Евклид за намиране на най-голям общ делител на две числа:

1. Ако М=N, техният общ делител е едно от двете числа.2. Докато двете числа са различни се изпълнява следното:Ако M<N, от М се изважда N, в противен случай от N се изважда М.3. Когато двете числа се изравнят – резултатът е техния НОД.

Тук можем веднага да напишем пълния текст на прогрмата:

//nod.cpp#include <iostream.h>void main(){

int M,N;cin>>M>>N;while(M !=N)

if(M<N)N-=M;else M-=N;

cout<<M<<endl;}

Задача 11. Прости делители

Да се състави програма DIVPR.CPP, която прочита от клавиатурата цяло число n и отпечатва всички негови прости делители, взети с тяхната кратност.

Примерен вход

24

Примерен изход

2 – 3

3 – 1

Решение

Прости делители на n могат да бъдат числа, които принадлежат на интервала [2, n/2]. Ако всеки път, когато намерим делител на n, извършваме делението толкова пъти, колкото е възможно и чак тогава преминаваме към следващото число, можем да гарантираме, че винаги ще попадаме на прости делители. Като добавим и брояч, който всеки път отчита колко пъти сме разделили оставащото число на делителя, ще можем да отпечатаме и неговата кратност. Този алгоритъм се реализира по следния начин:

1. Необходими са целочислени променливи за числото n, за текущия възможен делител d, както и за неговата кратност к.

int n,d,k=0;2. Първо се прочита числото:cin>>n;3. Обхождат се последователно всички възможни делители, като за всяко d се проверява

дали n се дели на него. Ако се дели, се извършва делението и се увеличава с 1 кратността на текущия делител. Ако числото d не дели n и отчетената до момента кратност е различна от 0, на екрана се извежда d и тази кратност, след което кратността се нулира. Щом d не дели n, във всички случаи се преминава към следващото число.

96

Page 97: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

for(d=2;d<=n/2;)if(n%d==0){k++;n/=d;}

else {if(k){ cout<<d<<’-‘<<k<<endl; k=0;}d++;

}Окончателно програмата има следния вид:

//divpr.cpp#include <iostream.h>void main(){int n,d,k=0;cin>>n;for(d=2;d<=n/2;)if(n%d==0){k++;n/=d;}

else {if(k){ cout<<d<<'-'<<k<<endl; k=0;}d++;

}cout<<d<<'-'<<k<<endl;}

Вложени циклиВече стана въпрос, че в тялото на който и да е от операторите за цикъл може да участват

произволни оператори. В това число и оператори за цикъл. Тогава, подобно на оператора if, ще казваме, че имаме вложени оператори за цикъл. Когато се влагат два оператора за цикъл, при изпълнението им трябва да се има предвид, че на всяка итерация на външния цикъл съответства пълно завъртане на вътрешния. Да разгледаме една примерна задача, която изисква влагане на цикли:

Задача 12. Монети

В една държава разполагат с монети от 2 и 5 пари. Да се състави програма MONETI.CPP, която по въведена сума S отпечатва всички възможни комбинации от монети, с които тя може да се представи. Ако тя не може да се представи с тези монети, отпечатва “NO”.

Примерен вход

17

Примерен изход

1.2+3.56.2+1.5

Примерен вход

3

Примерен изход

NO

Решение

За решаването на задачата ще разгледаме всички възможни комбинации от монети от по 2 и 5 пари и ако сумата от тези монети е S, ще ги отпечатваме. Това ще реализираме с два цикъла for, единият от които обхождa всички възможности за монети от по 2 пари, а втория за всяка такава възможност обхожда всички възможности от по 5 пари..

1. Ще са ни необходими 3 целочислени променливи: едната за сумата – int S;, а другите две съответно за отчитане броя на монетите от 2 и 5 пари – int i2, i5;.

2. Като начало програмата трябва да въведе сумата S от клавиатурата:cin>>S;

97

Page 98: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

3. Ето как ще организираме двата цикъла, за които стана дума: първият цикъл ще се отнася за броя монети от по 2 пари, с които би могла да бъде

образувана сумата. Те могат да бъдат най-малко 0 и най-много S/2. Ето защо, управляващата променлива на първия цикъл for ще се мени от 0 до S/2, обхождайки всички числа:

for(i2=0;i2<=S/2;i2++) в тялото на първия цикъл ще вложим втория, чиято цел ще бъде да обходи всички

възможни броеве монети от по 5 пари и подобно на първия, тези броеве ще са в интервала от 0 до S/5. for(i5=0;i5<=S/5;i5++)На всяка стъпка на вторият цикъл трябва да проверяваме дали сумата от стойностите на

текущите за момента броеве монети е равна на s и ако е така – да ги отпечатамеif(i2*2+i5*5==S) cout<<i2<<”.2+”<<i5<<”.5\n”;4. Накрая трябва да предвидим и възможността сумата S да не може да се получи от наличните

монети, тогава нашата програма трябва да отпечата “NO”. За да успеем да проверим тази ситуация, ще използваме допълнителна променлива int b; която ще има стойност 0, ако с нито една комбинация от брой монети не се получава сумата S и различна от 0, ако поне една комбинация от брой монети е удовлетворила сумата. Ето защо при всеки печеливш случай ще увеличаваме b с 1. В края на програмата трябва да проверим стойността на b и ако все още е 0, да изведем “NO”

Текстът на тази програма изглежда така:

//moneti.cpp#include <iostream.h>void main(){

int i2,i5,s,b=0;cin>>s;for(i2=0;i2<=s/2;i2++)for(i5=0;i5<=s/5;i5++){if(i2*2+i5*5) cout<<i2<<”.2+”<<i5<<”.5\n”;b++;

}if(!b)cout<<”NO\n”;}

Допълнителни задачи:С помощта на прозореца за проследяване на програми проследете как се променят стойностите

на величините в програмата в зависимост от изпълняваните оператори.Изпълнете файла MONETI.ЕХЕ с посоченият пример и проверете дали програмата ви връща

правилен отговор. Проверете я и с още тестови примери.Променете програмата така, че да отпечатва това представяне на сумата, което има най-малко

монети. Какво ще се промени, ако условието изисква сумата да бъде представена с възможно най-голям брой монети?

98

Page 99: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 13. Представяне на число

Да се състави програма SUM2.CPP, която прочита от клавиатурата цяло число n и отпечатва всички негови представяния като сума от три различни числа.

Примерен вход

10

Примерен изход

1+2+7

1+3+6

1+4+5

2+3+5

Решение

За да решим задачата е необходимо да разгледаме всички възможни стойности за всяко едно от трите числа и да отпечатаме само тези тройки, чиято сума е n.

1. Необходими са ни следните променливи – int n; - за числото, което ще въведем от клавиатурата и ще представим като сума от три числа; три целочислени променливи int a,b,c;, образуващи сумата от трите числа.

2. Като начало да въведем числото n: cin>>n;

3. Числото a може да бъде измежду числата от 1 до n/3, защото ако , то и и

a+b+c>n. Ето защо, ще се наложи да обходим всички възможни стойности за a, което е най-удачно да стане с цикъл for:

for(a=1;a<=n/3;a++)4. За всяка стойност на а е необходимо да обходим оставащите възможни стойности на b.

Числата a и b трябва да са различни, а и се налага да избегнем повторното отпечатване на дадена сума. (например ако вече сме отпечатали 2+4+5, не трябва да отпечатваме 4+2+5, защото това е същата сума). Затова ще започваме обхождането на евентуалните стойности за b от a+1. Променливата b може да заема стойности не по големи от n-a+1. Ето защо цикълът, който ще обхожда евентуалните стойности на b ще има следния вид:

for(b=a+1;b<n-a;b++)На всяка стъпка в този цикъл ще трябва да изчисляваме стойността на третата променлива с по

следния начин:c=n-a-b;

5. Получената тройка числа ще отпечатаме само в случай, че c>a и c>b, за да избегнем повторението на някои представяния.

Двата вложени цикъла ще изглеждат по следния начин:for(a=1;a<=n-3;a++)for(b=a+1;b<n-a;b++){

c=n-a-b;if(c>a&&c>b) cout<<a<<”+”<<b<<”+”<<c<<endl;

}Ето окончателния вид на програмата:

// sum3.cpp#include <iostream.h>void main(){int n,a,b,c;cin>>n;for(a=1;a<=n-3;a++)for(b=a+1;b<(n-a)/2;b++)

{c=n-a-b;

99

Page 100: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

if(c>a&&c>b) cout<<a<<”+”<<b<<”+”<<c<<endl;}

}

Допълнителни задачи:С помощта на прозореца за проследяване на програми проследете как се променят стойностите

на величините в програмата, в зависимост от изпълняваните оператори.Изпълнете файла SUM3.ЕХЕ с посоченият пример и проверете дали програмата ви връща

правилен отговор. Проверете я с още тестови примери.

Задачи за упражнение:

Зад. 1 Да се състави програма SUMMULT.CPP, която чете от клавиатурата последователност от цели числа, до въвеждане на 0 и отпечатва сумата на четните и произведението на нечетните от въведените числа.

Примерен вход:1234560 Примерен изход:12 15

Зад. 2. Да се състави програма SUMK.CPP, която прочита от клавиатурата цяло число К и след него последователност от числа, докато броят им стане равен на К, и отпечатва броя на въведените числа, кратни на 5.

Примерен вход42451Примерен изход1Зад. 3. Да се състави програма TWONEG.CPP, която чете от клавиатурата последователност от

числа докато не се въведат две отрицателни и отпечатва броя на всички числа, с последна цифра 5.Примерен вход10-245151-3Примерен изход2

Зад. 4. Щастливи дати Една рожденна дата е щастлива когато сумата от цифрите на деня, месеца и годината на раждане

е число, което при четене от дясно наляво и от лява надясно е едно и също. Да се състави програма DATE.CPP, която чете от клавиатурата тройки числа d,m и g, съдържащи съответно деня, месеца и годината на раждане. Въвеждането спира когато се въведе дата 00.00.0000. В края програмата отпечатва броя на щастливите рожденни дати.

Примерен вход:26 12 195917 07 178423 02 2000

100

Page 101: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

10 01 198215 03 199523 01 198011 01 142100 00 0000Примерен изход4Зад. 5. Да се състави програма THREE.CPP, която чете от клавиатурата последователност от

тройки реални числа до въвеждане на такава тройка, елементите на която не могат да бъдат страни на триъгълник, и отпечатва броя на тези тройки, чиито елементи са страни на равностранен, равнобедрен и разностранен триъгълник.

Примерен вход10 4 72 3 440 45 385 5 57 7 78 8 99 8 91 9 2Примерен изход2 2 3

Зад. 6. Да се състави програма SEC7.CPP, която чете от клавиатурата редици от по пет числа, до въвеждане на строго растяща редица, и отпечатва на екрана сумата от елементите на последната редица.

Примерен вход10 4 7 3 62 3 4 58 640 45 38 335 5 5 2 370 70 70 70 701 2 3 4 5Примерен изход15Зад. 7. Да се състави програма TWONEG1.CPP, която чете от клавиатурата последователност

от числа докато не се въведат две отрицателни и отпечатва минималното от всички въведени числа, с последна цифра 5.

Примерен вход10-245151-3Примерен изход15

Зад. 8. Да се състави програма SUMK1.CPP, която прочита от клавиатурата цяло число K и след него последователност от числа докато броят им стане равен на K и отпечатва най-голямото от въведените числа, кратни на 5.

Примерен вход1024571535

101

Page 102: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

18201Примерен изход20Зад. 9. Да се състави програма PTREE.CPP, която чете от клавиатурата последователност от

тройки реални числа до въвеждане на такава тройка, елементите на която не могат да бъдат страни на триъгълник и отпечатва номера на триъгълника с най-голям периметър.

Примерен вход10 4 72 3 440 45 385 5 57 7 78 8 99 8 91 9 2Примерен изход3

Зад. 10. Да се състави програма SEC.CPP, която чете от клавиатурата редици от числа от по пет елемента, до въвеждане на строго растяща редица, и отпечатва на екрана най-голямата сума от елементи на редица.

Примерен вход10 4 7 3 6 2 3 4 58 6 40 45 38 335 5 5 2 3 70 70 70 70 703 4 5 6 7Примерен изход350Зад. 11. Да номерираме позициите на цифрите на числото отдясно наляво, започвайки от 1.

Тогава първата цифра на числото 234 е 4, втората - 3, а третата - 2. Да се състави програма EVENDIG.CPP, която прочита от клавиатурата цяло число n и отпечатва сумата на тези от цифрите му, които са на четни позиции.

Примерен вход1234Примерен изход4

Зад. 12. При условията на предната задача, да се състави програма ODDDIG.CPP, която прочита от клавиатурата цяло число n и отпечатва произведението на тези от цифрите му, които са на нечетни позиции.

Примерен вход3456Примерен изход24Зад. 13. Да се състави програма DIGIT1.CPP, която чете от клавиатурата цяло число n и

отпечатва “YES”, ако като се задраска първата му цифра от ляво надясно се получава число, кратно на 3 и ”NO” в противен случай.

Примерен вход12346Примерен изходYESПримерен вход12345Примерен изходNO

102

Page 103: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Зад. 14. Да се състави програма DIGIT2.CPP, която прочита от клавиатурата цяло число n и цяло число k (1<к<5) и отпечатва числото, получено като премахнем k-тата цифра на n от лявo надясно.

Примерен вход4567 2 Примерен изход467Зад. 15. Да се състави програма DIGIT3.CPP, която прочита от клавиатурата цяло число n и цяло

число k (1<k<5) и отпечатва квадрата на числото, получено като задраскаме k-тата цифра на n от дясно наляво.Примерен вход

456 2Примерен изход2116Упътване: Забележете, че квадрата на числото е твърде голям и не винаги се събира в типа int.

Зад. 16. СЕЙФ. Програмистът Гошо Тарикатски съхранява сорсовете на своите програми в специален сейф. За да го обезопаси срещу крадци решил да създаде сложна система за отключване. Тя се задействала от два различни пулта, от които се въвеждали две цели числа, броя на цифрите, на които не бил предварително фиксиран, но е известно, че са не повече от девет, и двете числа винаги имат равен брой цифри. След като се въведат числата, се стартира програма, която генерира кода за сейфа, като първо получава едно цяло число по следния начин:

Събира първата цифра на първото число с последната цифра на второто число. Ако резултатът е двуцифрено число, цифрите му се събират. Получената цифра се записва като най-лява за числото.

Втората цифра се получава като по същият начин се обработят втората цифра на първото число и предпоследната цифра на второто число и т. н.

След сумирането на последната цифра на първото число и първата цифра на второто по посочената схема, се получава последната цифра на новото число.

За да се постигне пълна секретност така генерираното число се сумира с обратното си и получената сума е кода за сейфа. (Под обратното на дадено число разбираме, числото, прочетено в обратен ред. Например: обратното на 345 е 543).

Гошо е много добър програмист, но е затрупан от поръчки, затова възлага на вас написването на програмата за получаване на кода.

Програмата се нарича KASA.EXE и получава от клавиатурата две цели числа с равен брой цифри, след което извежда на екрана получения по горната схема код.

Примерен вход492971 851673Примерен изход1710016

Зад. 17. Дадено еестествено число N. Да се състави програма RAVENSTVO.CPP, която установява, дали съществуват тройки естествени числа x, y, z, така че да е в сила равенството x2+y2+z2=N и отпечатва тези тройки на екрана. Ако няма такава тройка, програмата отпечатва “NO”.

Примерен вход14Примерен изход1 2 3Примерен вход15Примерен изходNO

Зад. 18. За всеки правоъгълен триъгълник е в сила равенството a2+b2= c2 / Теорема на Питагор/, където a и b са катетите, а c е хипотенузата на триъгълника. Да се състави програма PITAGOR.CPP, която за дадено естествено число N намира и отпечатва всички тройки естествени числа a, b и c, не по-големи от N, които могат да бъдат страни на правоъгълен триъгълник.

Примерен вход11Примерен изход3 4 5

103

Page 104: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

6 8 10Зад. 19. Да се състави програма THREE.CPP, която за дадено естествено число N намира и

извежда на екрана всички възможни тройки естествени числа a,b и c( по малки от N), които могат да бъдат страни на триъгълник.

Упътване: a,b и c са страни на триъгълник, ако са в сила неравенствата a+b>c, a+c>b, b+c>a.Примерен вход5Примерен изход2 3 42 4 53 4 5Зад. 20. Разполагаме с В1 банкноти по 1лв., В2 – по 2лв. и В5 – по 5лв. Да се състави програма

MONEY.CPP, която въвежда от клавиатурата последователно броя на копюрите от всеки вид – B1, B2, B5 и сума Р, и извежда на екрана всички възможни начини, по които може да се представи сумата Р лева с възможните банкноти.

Примерен вход3 5 2 18Примерен изход0 4 22 3 2 3 5 1

Зад. 21. Да се състави програма DIG3.CPP, която въвежда от клавиатурата цяло число N<=27 извежда на екрана броя на трицифрените естествени числа, сумата от цифрите на които е равна на N.

Примерен вход3Примерен изход6

Зад. 22. Да се състави програма DIGDIF.CPP, която въвежда от клавиатурата цяло число N и намира броя на всички трицифрени числа по-малки от N, които не съдържат еднакви цифри.

Примерен вход120Примерен изход9Примерен вход12Примерен изход0

Зад. 23. Група от N деца отива на почивка. В почивната станция разполагат със стаи с по 3 и 4 легла. Да се състави програма CHILDREN.CPP, която въвежда от клавиатурата броя на децата N и отпечатва броя на различните разпределения на децата по стаите. Ако такова разпределение е невъзможно, на екрана се извежда “NO”.

Примерен вход30Примерен изход3

104

Page 105: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задачи от състезания:

Зад. 24 АВТОПАРК. Група разузнавачи трябвало да проучат състоянието на автопарка на противника. За целта те проникнали в базата и установили, че противниците притежават леки автомобили (с по 4 колела), товарни автомобили (с по 6 колела) и мотори с кош (с по 3 колела). Те внимателно преброили превозните средства и установили, че общият брой колела е N, след което ги описали. За съжаление при изтеглянето, разузнавачите попаднали на засада и се наложило да прекосят река, при което част от документацията се намокрила и се загубила важна информация. Когато прегледали останалата информация, установили, че се чете ясно само броят на колелата. За да възстановят информацията се наложило да се напише програма, която намира всички различни комбинации на трите вида превозни средства за определения брой колела. Тъй като програмистът на групата бил много болен (много силно настинал при преминаването на реката) се налага вие да им помогнете като напишете програма CARS.EXE, която прочита от клавиатурата цялото число N (3 < N < 50) и отпечатва на отделни редове на екрана различните комбинации на превозните средства, като ги подрежда на първо място броя на леките автомобили, на второ – броя на товарните автомобили и на трето – броя на моторите с кош.

Примери:

Вход Вход10 16

Изход Изход

1 0 2 1 0 4

1 1 0 1 2 0

1 1 2

4 0 0

Решение:

Задачата е подобна на задачата с монетите, решена по-горе. За нейното решение е необходимо да се организират три вложени оператора for, които ще обхождат съответните възможности за брой коли, брой товарни автомобили и брой мотори с кош, като на всяка стъпка на най-вътрешния цикъл проверяваме дали текущата комбинация е възможна и ако е, я отпечатваме. Програмата има следния вид:

//cars.cpp#include <iostream.h>void main(){int i,j,k,N;cin>>N;for(i=0;i<=N/4;i++) //този цикъл обхожда възможния брой леки автомобилиfor(j=0;j<=N/6;j++) //този цикъл обхожда възможния брой товарни автомобилиfor(k=0;k<=N/3;k++) //този цикъл обхожда възможния брой мотоциклети с кошif(i*4+j*6+k*3==N)

cout<<i<<’ ‘<<j<<’ ‘<<k <<endl; //отпечатва откритата комбинация}

105

Page 106: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №4Циклични алгоритми

Зад. 1. Въведете следната програма:#include <iostream.h>void main(){ int a; int S=0; do { cout<<”vyvedi 4islo:”; cin>>a;

S+=a;}

while(a!=0); cout<<“sumata ot vyvedenite 4isla e:”<<S<<endl;}

Тествайте програмата със следните входни данни:2, 8, 6, 8, 22, 67, 234, 345, 5, 6, 02345, 12345, 3456, 3456, 4567, 5678, 890, 567, 01, 2, 3, 4, 5, 6, 7, -7, -6, -5, -4, -3, -2, -1, 0

Има ли тестове, които връщат некоректен отговор? Коригирайте програмата така, че да работи коректно. Опишете какви са корекциите.

Зад. 2. Да се състави програма, която чете от клавиатурата цели числа до въвеждане на 0 и отпечатва броя на четните и броя на нечетните числа.

Тествайте програмата при следните входни данни:2, 8, 6, 8, 22, 67, 234, 345, 5, 6, 2, 8, 6, 8, 22, 67, 234, 345, 5, 6, 2, 8, 6, 8, 22, 67, 234, 345, 5, 6, 2, 8, 6,

8, 22, 67, 234, 345, 5, 6,02345, 12345, 3456, 3456, 4567, 5678, 890, 567, 01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0

Променете програмата така, че да може да преброява и числата, кратни на 3 и да отпечатва този брой.

Напишете текста на новата програма.Зад. 3. Да се състави програма, каято въвежда от клавиатурата цели числа до въвеждане на 0

и отпечатва най-малкото от тях.Тествайте програмата при следните входни данни:2, 8, 6, 8, 22, 67, -234, -345, 5, -6, -2, -8, 6, 8, -22, 7, -234, -45, -6, - 8, 22, 67, 234, 345, 5, 6, 2, 8, 6, 8,

22, 67, 234, 345, 5, 6,02345, 12345, 3456, 3456, 4567, 5678, 890, 567, 01, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0Какво трябва да се промени в програмата, че да може да отпечатва максималното положително

число?Напишете текста на новата програма.Зад. 4. Да се състави програма, която въвежда от клавиатурата последователност от точки в

равнината, зададени със своите координати и отпечатва координатите на тази от тях, която е най-близо до центъра на координатната система.

Тествайте програмата при следните входни данни:2 33 45.6 7.84.6 3.54.7 5.84.8 6.90 0Коригирайте програмата така, че да отпечатва и броя на точките от І, ІІ, ІІІ и ІV квадрант.

Напишете текста на новата програма.

106

Page 107: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Зад. 5. Да се състави програма, която чете от клавиатурата две цели числа m и n и отпечатва броя на числата в интервала [m,n], които са кратни на 7.

Тествайте програмата при следните входни данни:1 1511 135123 3456124 5678

107

Page 108: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №5Теория на числата

Зад.1. Въведете текста на следната програма:#include<iostream.h>long int n,k,Sum=0;void main(){ cout<<"Въведете числото n= "; cin>>n; Sum+=n%10; k=n/10; do { Sum+=k%10; k=k/10; } while(k!=0); cout<<"Сумата от цифрите на ”<<n<<” е "<<Sum<<endl;}

a) Тествайте програмата за следните входни данни:1234; 4321; 343; 132112; 5113; 2147483647;

и запишете получените резултати.б) Коригирайте програмата така, че вместо с do-while да работи само с while -цикъл.в) Допълнете програмата така, че да отпечатва само онези въведени числа, на които

сумата от цифрите съвпада с произведението им. Напишете текста на новата програма.

Зад.2. Да се състави програма, която въвежда положително цяло число и намира, и отпечатва неговото огледално (обърнато).

а) Тествайте програмата за следните входни данни:123; 4321; 12345; 1234567891; 1234567893;

и запишете получените резултати. Ако се налага коментирайте някои от резултатите.б) Променете програмата така, че при въведено число да създава ново,съдържащо двойно

повече цифри, и което се получава като към старото се залепи неговото обърнато. Напишете текста на новата програма и я тествайте със същите числа.

Зад.3. Да се състави програма, която въвежда две цели числа и отпечатва техният най-голям общ делител.

а) Тествайте програмата за следните двойки входни данни:(45,137); (45,566); (128,-4192)

и запишете получените резултати.

Зад.4. Да се състави програма, която въвежда цяло положително число и определя дали е просто.а) Проверете и запишете, кои от следните няколко числа са прости:

137; 537; 1129; 3715; 4293; 4297; 3421б) Допълнете програмата така, че за останалите числа (които не са прости) да

отпечатва първият открит делител. Напишете текста на новата програма.

108

Page 109: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

ФункцииI. Теоретични бележки

1. Пример

Задача: Да се състави програма COUNTEVEN.CPP, която въвежда от клавиатурата числа до въвеждане на 0 и отпечатва броя на въведените четни числа.

Решение:Такава задача вече сме решавали и тук можем да разгледаме направо програмата, която я

реализира:

//counteven.cpp#include <iostream.h>void main(){int a,b=0;do{cin>>а;if(a&&a%2==0)b++;

}while(a);cout<<b<<endl;

}

Тук е добре да обърнем внимание на проверката за това дали дадено число е четно. Тази проверка се извършва сравнително лесно в термините на езика С++, но понякога има условия, проверката на които не е толкова тривиална. Дори има случаи, при които кодът, който трябва да се напише за да се извърши дадена проверка е по-голям и по-сложен от останалата част от програмата. В момента целта не е да разглеждаме толкова сериозни примери и затова ще се спрем на една сравнително по-лека задача:

Задача: Да се състави програма COUNTPRIME.CPP, която въвежда от клавиатурата естествени числа до въвеждане на 0 и отпечатва броя на въведените прости числа.

Решение:Тук е ясно, че единственото, което различава тази задача от предходната е проверката за това

дали числото е просто, докато в предишната се проверява дали то е четно. За да се ориентираме как ще изглежда главната функция, на мястото на проверката ще напишем текст на български:

//countprime.cpp#include <iostream.h>void main(){int a,b=0;do{cin>>а;if(а е просто число)b++;

}while(a);cout<<b<<endl;

} Вече разглеждахме задачата за определяне на това дали дадено число е просто и знаем, че за

решението и е необходимо да организираме цикъл, който обхожда всички възможни делители на числото и ако намери негов делител, установява, че числото не е просто, а в противен случай – е просто. Това би усложнило написаната по-горе програма. Ясно е, че ако можем да изнесем проверката извън нея, задачата ще се улесни значително. Ето защо ще използваме предоставения от езика С++ механизъм за дефиниране на потребителски функции и ще опишем функция, която ще получава като параметър цяло

109

Page 110: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

число х и ще връща стойност 1, ако числото е просто и стойност 0, ако не е. Функцията ще изглежда по следния начин:

int prime(int x){if(x==0||x==1) return 0; //нулата не е просто числоfor(int d=2; d<=sqrt(x);d++)if(x%d==0)return 0;

return 1;}

След като сме написали тази функция, можем да я използваме в нашата програма, като я извикаме на мястото, където на български сме написали “а е просто число”. Тогава функцията main вече ще има следния вид:

void main(){int a,b=0;do{cin>>а;if(prime(a))b++;

}while(a);cout<<b<<endl;

} Накрая ще отбележим, че за да се изпълни коректно програмата, е необходимо да включим

библиотеката math.h, заради функцията sqrt. Използването на функциите в програмите на С++ е толкова често явление, че реално една

програма представлява списък от използваните в нея функции. Да разгледаме основните синтактични изисквания при описание и обръщение към функция.

2. Описание и използване на функции

а) Синтаксис на описание на функция

тип име_на_функцията(списък_от_формални_параметри){тяло_на_функцията }тип – задава се типа на резултата, който функцията връща. Ако не се налага функцията да връща

резултат, като тип се задава void. име_на_функция – произволен идентификаторсписък_от_формални_параметри – задават се параметрите, използвани за описание на

функцията, като за всеки параметър се посочва неговия тип и различните параметри се отделят един от друг със запетая.

Списъкът от формални параметри има следния синтаксис:списък_от_формални_параметри::=тип идентификатор, тип идентификатор ...тяло_на_функцията – тук се описват всички локални за функцията обекти и операторите, които

трябва да се изпълнят в нея. Реда на описание на обектите и операторите няма значение, но не се допуска използването на даден обект, преди той да е дефиниран. Ако е посочена стойност, която функцията трябва да върне, в тялото и задължително трябва да фигурира поне един оператор return.

Забележка: Една функция може да няма параметри, но скобите, които ги заграждат, са задължителни.

б) Семантика на описание на функция:

Както вече споменахме по-горе, функцията е основната структурна единица на С++ програмата. Описанието на всяка от функциите се приема от компилатора информативно. Самото изпълнение на функцията се реализира след обръщение към нея в някоя от другите функции или дори в собственото и тяло.

в) Обръщение към функция:

Синтаксис(правила за запис):

110

Page 111: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

име_на_функция(списък_от_фактически_параметри)Семантика(правила за изпълнение):В момента на обръщение към функцията за всеки параметър се заделя памет и в нея се копира

стойността на фактическите параметри, с които е извикана функцията. Започва реалното изпълнение на функцията с копираната вече стойност. Когато това изпълнение приключи, паметта заемана от нейния параметър се освобождава, а самата функция връща на мястото, от което е извикана, получената стойност.

Пример 1:Нека да разгледаме функцията prime, описана по-горе. При описанието и е използван

целочисления формален параметър х. Този параметър се използва за описанието на тялото на функцията. Самото описание предвижда обработка на параметъра х. При обръщението към функцията обаче, е използван фактическият параметър а, т. е. променливата от функцията main, за която трябва да бъде проверено дали е просто число или не.

Забележка: Обръщението към функцията може да се използва като оператор, или ако функцията връща резултат от някакъв тип – навсякъде, където се допуска използването на величина от този тип. Фактическите параметри са реалните стойности, с които се изпълнява функцията.

г) Формални и фактически параметри:

формални параметри: използват се само при описанието на функция, като при това се указва точно техният тип. При описанието на функцията формалните параметри се отделят един от друг със запетая.

фактически парамерти: използват се при обръщението към функцията. В качеството на фактически параметри могат да се използват произволни изрази. Фактическите параметри съответстват по брой и по тип на формалните, така че при извикване техните стойности да бъдат точно копирани на заделените места в оперативната памет на компютъра.

д) Оператор return:

Синтаксис(правила за запис):return израз;израз – това е произволен израз, който трябва да съответства по тип на типа, който връща

функцията по дефиниция.Семантика(правила за изпълнение):Когато при изпълнението на функцията се достигне до изпълнение на оператора return, първо се

изчислява изразът, записан след думата return, след което изпълнението на функцията се прекратява. Цялата заемана от нея памет се освобождава и изчислената вече стойност се връща на мястото, от което е била извикана функцията.

е) място на функцията в програмата:

Както вече отбелязахме в темата “Структура на програма на С++”, функцията е основната структурна единица в програмата. В една програма винаги трябва да има главна функция. Реда на описание на функциите няма значение, но единственото изискване е да няма обръщение към функция, която не е била дефинирана до този момент. Понякога това изискване създава проблеми при подреждането на функциите. Ето защо в езика С++ е предвидена възможност да се декларират всички функции в програмата посредством прототипи. Те позволяват обръщение към дадената функция навсякъде, независимо от мястото където е описана. Обикновенно прототипите се описват в началото на програмата. Те имат следния синтаксис

Прототиптип_на_функция име_на_функция (параметри_на_функция );След всичко, казано за функции ще представим общият вид на разглежданата програма.

//countprime.cpp#include <iostream.h>int prime(int x){if(x==0||x==1) return 0; //нулата не е просто числоfor(int d=2; d<=sqrt(x);d++)if(x%d==0)return 0;

111

Page 112: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

return 1;}

void main(){int a,b=0;do{cin>>а;if(prime(a))b++;

}while(a);cout<<b<<endl;

} При този запис на програмата функцията prime трябва задължително да е дефинирана преди

main, която се обръща към нея. Ако не искаме да се съобразяваме с това, е достатъчно да опишем нейния прототип в началото на програмата. Ето как би изглеждала тя в този случай:

//countprime.cpp#include <iostream.h>int prime(int x);void main(){int a,b=0;do{cin>>а;if(prime(a))b++;

}while(a);cout<<b<<endl;

} int prime(int x){if(x==0||x==1) return 0; //нулата не е просто числоfor(int d=2; d<=sqrt(x);d++)if(x%d==0)return 0;

return 1;}

112

Page 113: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

II. Решени задачи

Задача 1. Палиндроми.

Да се състави програма PALINDROM.EXE, която въвежда от клавиатурата две числа m и n и извежда всички палиндроми в интервала [m, n]

Примерен вход

110 150

Примерен изход

111

121

131

141

Решение

Вече сме разглеждали задачата за проверка на хипотезата дали едно число е палиндром. Използвахме следния подход: намираме обратното на числото и го сравняваме с него. Ако двете числа са равни, това означава, че нашето число е палиндром, в противен случай – не е. След като идеята е ясна, лесно можем да напишем функция, която приема като параметър цяло число х, и връща като резултат 1, ако числото е палиндром и 0 – ако не е. Това предполага, че типа на връщания от функцията резултат е int. Ето как ще изглежда описанието на функцията palindrom:

int palindrom(int x){

int ox=0, a=x ;while(x)

{ox=10*ox+x%10 ;x/=10 ;

}return (a==ox) ;

}Като използваме описаната функция можем да открием палиндромите в зададения интервал като

с помощта на цикъл for обходим всяко цяло число в този интервал и чрез обръщение към функцията проверяваме дали числото е палиндром. Ако функцията върне стойност 1 за някое число, то трябва да се отпечата. По този начин главната функция има следния вид:

void main(){

int m,n;cin>>m>>n ;for( int i=m;i<=n; i++)

if(palindrom(i))cout<<i<<endl;}За да получим цялата програма е достатъчно да включим входно изходната библиотека iostream.h

в началото, преди описанието на функцията palindrom.Ето окончателния вид на програмата:

//palindrom.cpp#include <iostream.h>int palindrom(int x){

int ox=0, a=x ;while(x)

{ox=10*ox+x%10 ;x/=10 ;

113

Page 114: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

}return (a==ox) ;

}void main(){

int m,n;cin>>m>>n ;for( int i=m;i<=n; i++)

if(palindrom(i))cout<<i<<endl;}

Задача 2. Най-голям общ делител.

Да се състави програма NOD.EXE, която въвежда от клавиатурата три цели числа m, n и к и извежда всички двойки числа в интервала [m, n], които имат най-голям общ делител по-голям или равен на к.

Примерен вход

11 27 8

Примерен изход

11 22

12 24

13 26

16 24

18 27

Решение

За решението на задачата ще използваме алгоритъма на Евклид за намиране на най-голям делител на две числа a и b. Алгоритъмът на Евклид е следния:

1. Докато числата не са равни повтаряме следното: ако a>b намаляваме b с a; в противен случай намаляваме a с b;

2. Когато двете числа се изравнят, е намерен най-големият им общ делител и той е равен на получената една и съща стойност за двете числа.

На базата на така описания алгоритъм можем да съставим функция, която да приема като параметри числата, чийто НОД търсим и връща като резултат намерения НОД. Както параметрите, така и типа на функцията са цели числа. Ето вида на функцията, която пресмята НОД на числата a и b.

int NOD(int a,int b){while(a!=b)if(a<b)b-=a;else a-=b;

return a;}

За да намерим всички двойки числа в интервала [m, n], които имат най-голям общ делител по-голям или равен на к, е необходимо да разгледаме всички възможни двойки числа в този интервал и за всяка да проверим дали отговаря на условието и ако е така – да я изведем на екрана . Обхождането на всички двойки ще реализираме чрез два вложени цикъла for, в единия от които управляващата променлива i приема последователно като стойности всички числа в интервала, а другия обхожда всички числа от i+1 до края на интервала n. За всяка получена двойка се проверява дали резултатът от функцията NOD е по-голям от к. Ако е така, съответната двойка се извежда на екрана. Функцията main има следния вид:

void main(){int m,n,k;

114

Page 115: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cin>>m>>n>>k;for(int i=m;i<=n;i++)for(int j=i+1;j<=n;j++)if(NOD(i,j)>=k) cout<<i<<' '<<j<<endl;

}

Задача 3. Сума от цифри

Да се състави програма SUMDIGIT.CPP, която въвежда от клавиатурата две цели числа L и K и извежда всички числа в интервала [L, K], които имат сума от цифрите, кратна на 11 .

Примерен вход

545 597

Примерен изход

551

560

589

Решение

За решението на задачата ще използваме допълнителна функция, която по дадено цяло число пресмята сумата от цифрите му. Вече сме решавали задачата за пресмятане на сумата от цифрите на едно число. Това което трябва да съобразим в момента е как да оформим решението като функция, да опишем нейните параметри и стойността, която връща. Функцията ще има следния вид:

int Suma(int a){int Sum=0;while(a)

{ Sum+=a%10; a/=10; } return Sum;}В главната функция, ще прочитаме двете числа L и K, определящи краищата на интервала, след

което ще организираме цикъл for, който обхожда всички цели числа в интервала [L, K] и за всяко от тях проверява дали е кратно на 11. Ако това е така, отпечатва съответното число.

Ето вида на главната функция:void main(){int K,L,n;cin>>K>>L;

for(n=K;n<=L;n++) if (!(Suma(n)%11)) cout<<n<<endl;}

115

Page 116: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Задача 4. Дружествени числа

Да се състави програма FRIENDS.CPP, която по зададен интервал [K,L] (K и L цели положителни) извежда на екрана двете най-големи приятелски числа в този интервал. K и L се въвеждат от клавиатурата. Две числа са приятелски ако са прости и разликата им по модул е равна на 2.

Примерен вход

10 50

Примерен изход

43 41

Решение

Тук очевидно ще ни трябва разгледаната вече от нас функция simple, използвана в първата програма на този раздел. Трябва да съобразим, че най-бързия начин да намерим най-голямата двойка приятелски числа в интервала [K,L] е да започнем обхождането на интервала отзад напред, като на всяка стъпка проверяваме дали числото, което е с 2 по-малко от текущото и текущото са прости. Ако това е така, означава, че сме намерили двойка приятелски числа и тя е най-голямата, което означава, че трябва да преустановим търсенето. Това ще се осъществи с оператор break.

Ето текста на цялата програма:

//friends.cpp#include<iostream.h>#include<math.h>int simple(int x){ for(int d=2;d<=sqrt(x);d++)

if(x%d==0)return 0; return 1;}

void main(){int m,n;cin>>m>>n;for(int i=n;i>=m;i--){int j=i-2;if(simple(i)&&simple(j)){cout<<i<<','<<j<<endl; break;

}}

}

III. Задачи за упражнение

Зад. 1. Две числа са дружествени, ако сумата от делителите на едното е равна на другото и обратно - сумата от делителите на второто число е равна на първото. Нека да номерираме, двойките дружествени числа в даден интервал с числата 1, 2, 3.., започвайки от първата намерена двойка в интервала. Тогава на всяка двойка ще съответства едно цяло число, което ще наречем пореден номер. Да се състави програма FREND.CPP, която по зададен интервал [K,L] (K и L цели положителни) отпечатва онази двойка дружествени числа, която има пореден номер половината от общият им брой в интервала. K и L се въвеждат от клавиатурата. Примерен вход

1 1500Примерен изход

48 75

116

Page 117: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Зад. 2. Да се състави програма EQDIGIT.CPP, която по зададен интервал [K,L] (K и L цели положителни) отпечатва всички числа в интервала [K,L], които имат две съседни еднакви цифри в записа си.Примерен вход

10 50Примерен изход

11 22 33 44

Зад. 3. Да се състави програма AVERDIG.CPP, която въвежда от клавиатурата три цели числа m, n и к и извежда всички числа в интервала [m, n], за които средното аритметично от цифрите е равно (или по-голямо) на k.Примерен вход

10 50 6Примерен изход

39 48 49

Зад. 4. Да се състави функция, която по дадено цяло число и цифра k определя колко пъти в записа на числото n се среща цифрата k. Като се използва тази функция да се състави програма DIFDIG.CPP, която чете от клавиатурата цифра k и последователност от цели числа до въвеждане на отрицателно число или 0 и отпечатва броя на тези от въведените числа, които имат цифрата k в записа си поне два пъти.

117

Page 118: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №6Функции

Зад.1. Въведете текста на следната програма:#include<iostream.h>int Suma(int a)

{int Sum=0;while(a)

{Sum+=a%10;a/=10;

}return Sum;

}

void main(){

int K,L,n;cin>>K>>L;for(n=K;n<=L;n++)

if (!(Suma(n)%11)) cout<<n<<endl;}

a) обяснете какво прави програмата.б) тествайте програмата за интервала [1,150] и запишете получените резултати:в) коригирайте програмата така, че да намира най-малкото число в интервала [K,L], сумата

от цифрите на което е равно на 21.Напишете текста на новата функция.

Зад.2. Въведете програмата, която решава следната задача: Да се състави програма, която въвежда положителни цели числа(до въвеждане на 0) и отпечатва само онези, които са палиндроми.

Тествайте програмата със следните входни данни:12, 123, 32123, 135631, 3513153, 1111111111, 11112111, 0

и запишете получените резултати.

Зад.3. Въведете програмата, която решава следната задача: Да се състави програма, която по зададен интервал [K,L] (K и L цели положителни) отпечатва най-голямата двойка дружествени числа. K и L се въвеждат от клавиатурата.

Напишете текста на програмата и я тествайте със следните входни данни:K=1, L=1500

и запишете получените резултати.

Зад.4. Въведете програмата, която решава следната задача: Да се състави програма, която по зададен интервал [K,L] (K и L цели положителни) отпечатва онази двойка приятелски числа, която има пореден номер половината от общият им брой в интервала.K и L се въвеждат от клавиатурата. Поредния номер и тук има същия смисъл като в Зад. 1 на стр. 114.

Напишете текста на новата програма.

118

Page 119: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

МасивиI. Теоретични бележки

1. Пример

Задача: Да се състави програма TEMP.CPP, която за месец, състоящ се от 30 календарни дни, въвежда данните за средните дневни температури за всеки ден и извежда на екрана:

а) средната температура за месеца;б) средната температура за второто десетдневие;в) минималната температура за първото десетдневие;г) датите, на които температурите са били под средната. При анализ на задачата виждаме, че за да напишем програма имаме две възможности – да

използваме тридесет напълно еднотипни променливи, на които да присвоим дневните температури. В случай като този, когато се налага работа с голямо количество еднородни обекти се използва структура от данни, наречена масив.

2. Масив

а) Определение

Множество от краен брой, последователно разположени в паметта еднотипни променливи, които притежават общо име и се различават помежду си по своя индекс.

Всяка променлива от масива се нарича елемент на масива. В С++ масивът се дефинира като една променлива, заделя се памет за всички негови елементи и се запомня указателят към първият му елемент. Елементите на масива се разполагат един до друг в паметта и се различават помежду си по своя индекс (номер). В С++ номера на първия елемент е 0.

0 1 2 3 4 5 6 7 8 9 ..........

б) Дефиниране(деклариране) на масив:

При деклариране на масива се посочва: - типа на неговите елементи;- име, което е общо за всички елементи от масива;- броя на елементите, от които той се състои.тип име[израз];тип – може да бъде произволен тип, позволен за използване в езика С++.име – валиден идентификатор;израз – определя броя на елементите в масива, този брой се нарича граница на масива;

зададеният израз трябва да е константен (обикновено цяло десетично число).Пример 1: int A[100] - масив А с 100 елемента от тип intfloat D[30] – масив D с 30 елементи от тип float

Тъй като всеки елемент от масива е променлива, тя може да бъде разглеждана и използвана като такава.

в) Обръщение към елементите на масив.

Eлементите в масива имат общо име и се различават само по мястото, което заемат в масива. Тази позиция се нарича индекс и при обръщение към съответния елемент на масива, се записва до името му, заградена в средни скоби. Индексът на елемента на масива трябва да е цяла константа, променлива от тип int или израз с целочислена стойност.

Пример 2: А[0], A[55]. Индексът определя позицията на съответния елемент спрямо началото на масива. Споменахме, че

в С++ първият елемент на масива има индекс 0 ( т.е. А[0]), така че елементаА[1] реално е втория елемент на масива.

119

Page 120: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Пример 3:Ако имаме дефиницията int I, j, A[100]; можем да използваме следните обръщения към елементи

на масива А: A[3], А[I+5], А[I*j] и т.н.

г) Използване на елементи на масив

Предвид това, че елементите на масив са стандартни променливи и можем да се обръщаме към всяка от тях, следва че можем да ги използваме като операнди в изрази:

Пример 4: (A[2]+A[4])/2, където А е масивът от горния пример.

3. Операции с масиви

При разглеждане на най-често използваните действия с масиви ще направим уговорката, че ще работим с един масив и всяка една от операциите с него ще реализираме с отделна функция. В началото ще приемем, че сме декларирали масива извън всички функции в програмата, така че всяка една от тях, включително и главната да има достъп до него. За илюстрация на различните операции с масиви ще използваме целочислен масив с не повече от 100 елемента. Освен това ще приемем, че при всяко стартиране на програмата ще работим с различен брой елементи на масива, който ще се въвежда от клавиатурата. За целта ще декларираме още една глабална целочислена променлива n, в която ще прочитаме броя на елементите на масива. Ето необходимите декларации на глобални променливи, които ще използваме в следващите функции.

int a[100], n;Тъй като повечето операции са свързани преди всичко с действия с масиви, те не връщат някаква

конкретна стойност и затова ще използваме функции от тип void.

а) Въвеждане на масив

Въвеждане на масива означава запълване със стойности от клавиатурата на всички елементи на масива. Преди всичко, обаче, трябва да въведем цялото число n, което както вече се уговорихме съдържа броя на елементите в масива:

cin>>n;Последователното въвеждане на всичките n елемента на масива ще реализираме с цикъл for, тъй

като се налага да ги обходим един по един, започвайки от нулевия и да ги въвеждаме от клавиатурата.for( int i=0; i<n;i++) cin>>a[i];Като цяло функцията за въвеждане на масива а, който декларирахме по-горе, ще изглежда така:void read_a(){cin>>n;for( int i=0; i<n;i++) cin>>a[i];

}Тук бихме могли да променим малко описания код, така че функцията да осъществява

приятелски интерфейс с потребителя като извежда подходящи съобщения. Ето как би могло да стане това:

void read_a(){

cout<<”въведи брой елементи на масива: “;cin>>n;for( int i=0; i<n;i++) {cout<<”a[“<<i<<”]=”;cin>>a[i];

}}

б) Извеждане на масив

Под извеждане на масив ще разбираме последователното извеждане на всеки един елемент на масива на екрана. Според условието на задачата елементите на масива могат да се извеждат по един на ред или по няколко на ред и т.н.

120

Page 121: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

При тази илюстрация ще приемем, че елементите се извеждат по един на ред. Както и при въвеждането ще опишем функция, която реализира това извеждане. Обхождането на елементите на масива отново ще извършим с цикъл for:

void write_a(){for( int i=0; i<n;i++) cout<<a[i]<<endl;

}

в) Намиране на оптимален елемент на масив

За определеност ще приемем, че ще търсим минималния елемент на масива. Ще реализираме тази операция с функция, която ще връща като резултат намерения минимален елемент. Търсенето на минималния елемен ще осъществим по познатия алгоритъм за намиране на оптимален елемент:

определяме за минимален нулевия елемент на масива:int m=a[0]; обхождаме всички останали елементи на масива и ги сравняваме с минималния. Ако

намерим елемент по-малък от минималния, присвояваме стойността му на минималния.for(int i=1;i<n;i++)

if(a[i]<m) m=a[i];Окончателния вид на функцията за намиране на минимален елемент на масив е следния:int min(){int m=a[0];for(int i=1;i<n;i++)if(a[i]<m) m=a[i];

return m;}Задачата за намиране на оптимален елемент може да е формулирана така, че да се налага

търсенето не на самия оптимален елемент, а на неговия индекс. Тогава горната функция ще претърпи известни корекции, като в променливата m ще запомняме не стойността, а индекса на елемента. Преобразуваната функция ще бъде следната:

int minindex(){int m=0;for(int i=1;i<n;i++)if(a[i]<a[m]) m=i;

return m;}

г) Търсене на елемент в масива

Стандартната формулировка на задачата за търсене на елемент на масива е следната: “Даден е израз х, който е от типа на елементите от масива. Да се състави функция, която намира индекса на елемент, равен на х в масива. Ако в масива няма елемент, равен на х, функцията връща стойност –1”.

За решаване на тази задача ще изпозваме функция, която приема като параметър цялото число х и в тялото си обхожда всички елементи на масива с помощта на цикъл for, като на всяка стъпка проверява дали поредния елемент на масива е равен на х. Ако открие такъв елемент функцията веднага връща като резултат индекса му. Ако цикълът завърши без да е намерен елемента х, функцията връща резултат -1. Ето как ще изглежда и конкретната реализация:

int search(int x){for(int i=0;i<n;i++)if(a[i]==x)return i;

return -1;}

121

Page 122: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

II. Решени задачи

Задача 1. Масив

Да се състави програма MASIV.CPP, която обработва целочислен масив с n (n100) елемента и изпълнява последователно следните операции:

- прочита от клавиатурата цялото число n и елементите на масива;- извежда на екрана минималния елемент на масива;- прочита от клавиатурата цяло число k и извежда на екрана номера на първия елемент, равен на

k;- извежда на екрана всички елементи на масива, като всеки елемент се извежда на отделен ред.

Решение

1. Необходими величини:Според уговорката, която направихме по-горе, е необходимо да декларираме една променлива от

тип масив от цели числа и променлива n, съдържаща броя на елементите на масива. И двете променливи трябва да бъдат глобални, за да са достъпни от всички функции, които ще използваме за реализацията на програмата. В този случай ще декларираме:

int a[100], n;непосредствено след описанието на директивите към предпроцесора.

2. Във функцията main ще декларираме променливата k, описана в третото условие на задачата. По-горе описахме по една функция за всяка една от дейностите, зададени в условието:

Въвеждането на масива се изпълнява от функцията void read_a(); Намирането на минималния елемент – от функцията int min(); Намирането на първия елемент, равен на k – от функцията int search(int x); Отпечатването на елементите на масива на екрана – от функцията void write_a().

3. Като използваме тези функции, ще реализираме следната главна функция.void main(){int k;read_a();cout<<”min = “<<min()<<endl;cout<<”k= “ ; cin>>k ;int l=search(k);if(l==-1) cout<<”няма такъв елемент в масива\n “;else cout<<l<<endl;

write_a() ;}Ето целия текст на програмата, решаваща задачата:

//masiv.cpp#include <iostream.h>int a[100], n;void read_a(){

cin>>n;for( int i=0; i<n;i++) cin>>a[i];

}void write_a(){for( int i=0; i<n;i++)

cout<<a[i]<<endl;}int min(){int m=a[0];for(int i=1;i<n;i++)if(a[i]<m) m=a[i];

return m;

122

Page 123: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

} int search(int x){for(int i=0;i<n;i++)if(a[i]==x)return i;

return -1;}void main(){int k;read_a();cout<<”min = “<<min()<<endl;cout<<”k= “ ; cin>>k ;if(search(k)==-1) cout<<”няма такъв елемент в масива\n “;

else cout<<search(k)<<endl;write_a() ;

}

Задача 2. Редица

Да се състави програма REDICA.CPP, която въвежда от клавиатурата цяло число n (n<100) и рeдица от n цели числа и отпечатва броя на отрицателните елементи от редицата.

а) добавете нова функция, която намира индекса на първото просто число в редицата и добавете в главната функция отпечатването на това число;

б) добавете нова функция, която отпечатва всички нечетни елементи на редицата само, ако броя на отрицателните съвпада с индекса на първото просто число в редицата.

Решение

1. Необходими величини:За представянето на редицата ще използваме масив от цели числа, който ще бъде глобален за

цялата програма. Като глобална ще обявим и променливата n, съдържаща броя на елементите на редицата.

int a[100],n;2. За въвеждане на масива ще използваме описаната вече в предишната задача функция

read_a().3. Да напишем функцията, която връща броя на отрицателните числа:

Тази функция ще пресмята брой и следователно ще връща резултат от тип int. В тялото на функцията ще ни е необходима една променлива, в която ще отчитаме броя на

отрицателните числа:int b=0; Търсеният брой ще намерим като прегледаме всички елементи на масива и за всеки

проверяваме дали е отрицателно число, при което ако елемента е отрицателен, ще увеличаваме брояча с 1. Това се реализира с цикъл for.

Накрая функцията трябва да върне като резултат стойността на b. return b;Ето общия вид на функцията:int count_negative(){int b=0;for (int i=0;i<n;i++)

if(a[i]<0)b++;return b;

}4. Главната функция ще включва обръщение към функцията за четене и отпечатване на

резултата от функцията count_negative.void main(){read_a();

123

Page 124: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<count_negative()<<endl;}

5. За решението на подточка а) ще използваме известната вече функция prime, която определя дали дадено цяло число е просто. Решението ще реализираме отново с функция, която връща като резултат индекса на първото просто число. За тази реализация ще използваме следния алгоритъм:

Обхождаме масива а (преглеждаме неговите елементи), започвайки от нулевия му елемент и на всяка стъпка проверяваме дали поредния елемент на масива е просто число.

Щом намери такъв елемент функцията ще прекратява своята работа и ще връща индекса, до който е стигнала. Ако такъв елемент не бъде намерен, функцията ще върне –1.

int first_prime(){for(int i=0;i<=n;i++)if(prime(a[i])) return i;

return –1;} Остава да добавим в главната функция отпечатването на намереното първо просто число.

Това ще се реализира със следните редове:int k=first_prime();if(k==-1)cout<<”няма прости числа\n”;else cout<<a[k]<<endl;

6. Решението на подточка б) ще оставим на читателя като ще отбележим само, че преди да отпечатаме всички нечетни числа трябва да проверим условието: first_prime()==count_negative() и да предприемем отпечатването само ако то е истина.

Задача 3. Положителни елементи

Да се състави програма POSITIVE.CPP, която въвежда от клавиатурата цяло число n (n<100) и рeдица от n цели числа и отпечатва средното аритметично от положителните и елементи.

Решение:

1. Необходими величини:По аналогия с предната задача отново ще използваме глобалния масив а[100] и променливата n,

съдържаща броя на елементите в масива. 2. За улеснение ще копираме и функцията за четене на елементите на масива.3. Функцията, която намира средното аритметично на елементите от масива, ще бъде от тип

float и ще има следния вид:float ave_pos(){float S=0;int br=0;for (int i=0;i<n;i++)

if(a[i]>0) {S+= a[i]; br++}return S/br;

}4. Главната функция, която решава тази задача е следната:

void main(){read_a();cout<<ave_pos()<<endl;

}

Задача 4. Обръщане

Да се състави програма REV_MAS.CPP, която въвежда от клавиатурата цяло число n (n<100) и масив от n дробни числа и го обръща обратно (т.е. първият елемент става последен, а последният първи; вторият предпоследен, а предпоследният втори и т.н.).

Решение:

1. Необходими величини:

124

Page 125: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

По аналогия с предната задача отново ще използваме глобалния масив а и променливата n, съдържаща броя на елементите в масива, както и функцията за въвеждане на глобалния масив а read_a().

2. Преобразуването на масива ще стане в отделна функция, която ще бъде от тип void, тъй като няма да връща конкретна стойност.

В нея ще трябва да преценим зависимостта между индексите на елементите, които трябва да разменим:

Според условието елемента а[0] ще разменим с елемента а[n-1];Eлемента а[1] – с a[n-2];Eлемента а[2] – с a[n-3];… Eлемента а[i] – с a[n-(i+1)];… Eлемента а[n/2-1] – с a[n/2]; Това означава, че трябва да обходим само половината от елементите на масива и всеки от тях да

разменим със съответният му. Описаната функция изглежда по следния начин:void revert(){

for(int i=0;i<n/2;i++){int z=a[i];a[i]=a[n-(i+1)];a[n-(i+1)]=z;

}}Същата фукция може да се реализира и по следни начин:void revert(){

int i=0, j=n-1;while(i<j){ int z=a[i];

a[i]=a[j];a[j]=z;i++;j--;

}}

3. За отпечатване на новополучения масив ще използваме отново описаната вече функция за отпечатване на глобален масив write_a().

Задача 5. Температури

Да се състави програма TEMP.CPP, която за месец, състоящ се от n календарни дни, въвежда данните за средните дневни температури за всеки ден и отпечатва:

а) средната температура за месеца;б) средната температура за второто десетдневие;в) минималната температура за първото десетдневие;г) датите, на които температурите са били под средната;д) най-дългия период на застудявяне – последователност от дни с температура под средната.

Решение

1. Необходими величини. Както и в предишната задача ще използваме глобален масив за средните дневни температури,

който е с цели числа и съдържа n елемента. Тъй като в част от условията се иска отпечатване на дати, няма да използваме нулевия елемент от масива, за да може индекса на масива да съответства на датата. Така, че декларираме:

double a[31]; int n;2. Като начало да опишем функция, която въвежда средните дневни температури по дати от

клавиатурата. Тя е аналогична на функцията read_a(), която използвахме в предишната задача, но ще добавим подходящо съобщение, за това кой елемент въвеждаме:

void read_a(){

125

Page 126: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

cout<<”Въведете броя на дните в месеца: “cin>>n;for( int i=1; i<=n;i++) {cout<<”Въведете средната температура на “<<i<<”-и: “;cin>>a[i];

}}Другата разлика между тази функция и горната е, че въвеждането на елементите започва от

първия, поради уговорката, че няма да използваме нулевия елемент.3. Сега можем да пристъпим към последователното реализиране на всяка една от

функциите: Намирането на средната месечна температура ще реализираме, като с помощта на цикъл

for ще сумираме всички елементи на масива и получената сума разделим на n.int average(){int S=0;for(int i=1;i<=n;i++) S+=a[i];return S/n;

} Средната температура за второто десетдневие ще намерим по същия начин, но ще

сумираме само елементите, с индекси от 11 до 20 и ще разделим сумата на 10. int average10(){int S=0;for(int i=11;i<=20;i++) S+=a[i];return S/10;

} Минималната температура за първото десетдневие ще намерим подобно на намирането

на минимален елемент на масив от предходната задача, но ще обходим само първите 10 елемента на масива:

int minfirst10(){int m=a[1];for(int i=2;i<=10;i++)if(a[i]<m) m=a[i];

return m;} За да намерим датите, на които температурите са били под средната трябва първо да

намерим средната месечна температура и да я присвоим на една променлива, като след това ще обходим всички дати от месеца и ако температурата е по-малка от средната, ще извеждаме съответната дата:

void minaver(){

int av=average();for ( int i=1;i<=30;i++)

if(a[i]<av)cout<<i<<endl;} Остава да опишем функцията, която намира най-дългия период на застудяване. В случая

става дума за стандартен алгоритъм за намиране на най-дълга последователност от елементи на масив, притежаващи едни и същи свойства. За реализацията на този алгоритъм са необходими две променливи, едната от които съдържа индекса на първия елемент на най-дългата последователност, а втората – дължината на тази последователност. Необходими са и две променливи със същото предназначение за текущата последователност.

В началото ще инициализираме всички тези променливи с 0, с изключение на началото на текущата последователност, което ще има стойност 1:

int m1=0, md=0, t1=1, td=0 ;След това ще обходим елементите на масива един по един и за всеки ще проверяваме дали е под

средната температура за месеца. Ако е така, това означава, че трябва да добавим още един елемент към текущата последователност, т. е. td++. В противен случай означава, че сме намерили елемент с по-висока

126

Page 127: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

температура, т. е. края на текущата последователност – в този момент е необходимо да сравним намерената дължина на текущата последователност с тази на максималната и ако е по-голяма да я присвоим на променливата, в която се пази минималната температура. Едновременно с това не трябва да забравяме да присвоим и на началото на най-дългата последователност началото на текущата, като при това присвоим на променливата td (дължината на текущата последователност) стойност 0, а на променливата t1 (началото на текущата последователност) индекса на следващия елемент на масива. Когато обхождането завърши е необходимо още веднъж да сравним дължината на текущата последователност с най-дългата, за да не пропуснем случая, когато най-дългата последователност е в края на масива. Ето как изглежда функцията, решаваща тази част от задачата:

void longseq(){int av=average();int m1=0, md=0, t1=1, td=0 ;for(int i=1;i<=30;i++)if(a[i]<av)td++;else {if(td>md){md=td; m1=t1;}td=0;t1=i+1;

}if(td>md){md=td; m1=t1;}cout<<”най-дългият период на затопляне е от “<<m1<<” до “<<m1+md-

1<<endl;}В главната програма последователно ще извикаме всички функции, които написахме.

Предоставяме на читателя тази вече сравнително тривиална задача.

III. Задачи за упражнение:

Зад. 1. Определете броя на елементите в масива A, B, C като знете, че последните елементи в съответните масиви са:

а) A[5];б) B[(i+j)*3], ако i=3, j=5;в) C[i/3+j%3], ако i=7, j=5;Зад. 2. Даден е масив от 6 елемента int A[5], като

А[0] A[1] A[2] A[3] A[4] A[5]3 -2 8 7 5 -3

Какви стойности имат елементите на масива след изпълнението на следните операции за присвояване:

а) A[5]=5;б) A[5]=A[0];в) A[3]=(A[2]+A[4])/2;г) X =A[3]; A[3]=A[4]; A[4]=X;

Зад. 3. Да се състави програма за работа с масив от цели числа, която да въвежда от клавиатурата броя на числата и самите числа и:

а) сгъстява масива, като премахва нулевите му елементи;б) отпечатва броя на платформите в масива. (платформа е последователност от равни елементи –

в условието на задачата платформата може да бъде зададена като последователност от елементи, които изпълняват определено свойство);

в) отпечатва началния и крайния индекс на най-дългата платформа в масива;г) разменя местата на първия елемент, равен на минималния и последния елемент, равен на

максималния.Зад. 4.РедициИмате редица от цели числа с дължина N (3<N<100).Необходимо е да се проверят качествата на

дадената редица относно следните свойства, като след всяко свойство е отбелязана буквата с която ще се демонстрира наличието на свойството в проверяваната редица:

127

Page 128: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

а) растяща редица - всеки пореден член е не по-малък от предишния член (A).б) строго растяща редица - всеки пореден член е по-голям от предишния член (B).в) намаляваща редица - всеки пореден член е не по-голям от предишния член (C).г) строго намаляваща редица - всеки пореден член е по-малък от предишния член (D).д) осцилираща редица - ако предищния член е бил по-малък от сегашния, то следващия е по-

малък или равен на сегашния и обратно - ако предишния член е бил по-голям от сегашния то следващия трябва да е по-голям или равен на сегашния (E).

е) строго осцилираща - същото като осцилираща, само че не може да има два последователни еднакви елемента (F).

ж) аритметична прогресия - всеки член се получава от предишния с прибавяне на число, което е константа за цялата редица и може да е положително, отрицателно или нула (G).

з) геометрична прогресия - всеки член се получава от предишния с умножение на число, което е константа за цялата редица и може да е положително или отрицателно (H).

Примерен вход5 1 2 3 4 54 1 –1 1 –15 1 2 3 3 88 1000 900 800 700 –1 –2 –3 –46 -1 7 7 –8000 –90 –100Примерен изходABGEFHACDE

Зад. 5. Великата СтенаВеликата Стена разделяла Острова на Програмистите на две части - едната била на

програмистите пишещи на Паскал, другата - на пишещите на С. Това било направено с цел срещите им да се сведат до нула понеже иначе се стигало до спорове завършващи в Пирогов. Стената била тухлена,като тухлите били наредени в колони,плътно залепени една до друга и с еднаква височина. Но една нощ вандали (програмисти на ассемблер) разместили тухлите като вземали от една колона и ги слагали върху някоя друга. Така стената станала неравна и можело да се мине през нея. Това било недопустимо, затова бил извикан известния майстор - QuickBasic, който трябвало да възстанови стената. Но QuickBasic имал странен нрав-искал преди да започне работа всичко да е предефинирано и известно, затова сега му е необходимо да научи с колко премествания на тухли може да се свърши работата и ако може с по-малко защото и не е много паметлив. На Вас се пада задачата да откриете (независимо от коя страна на стената сте) какъв е минималния брои тухли, които трябва да се преместят за да се изравни стената. Под едно преместване се разбира: вземаме една тухла от някоя колона с поне една тухла (броя на тухлите в тази колона намалява с една) и я слагаме върху някоя друга (броя на тухлите във втората се увеличава с една).

От клавиатурата се въвеждат следните данни: На първия ред се намира цялото число N (1<= N<=3000) показващо броя на колоните в стената.На следващите N реда е самата стена,като на всеки ред се намира цяло число Xi (0<=Xi<=60000)

показващо броя на тухлите в i-тата колона.Общия брой на тухлите в стената не надвишава 60000.Програмата отпечатва намереното число (минималния брой премествания) на екрана.

Примерен вход44 9 8 7Примерен изход3

Зад. 5 DATEЩастлива година е тази, която има в записа си две равни цифри. Да се състави програма

DATE.EXE, която чете от клавиатурата цяло число n и след него n години, и извежда на екрана броя на тези от тях, които имат по две еднакви цифри.

Примерен вход

128

Page 129: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

41234198712712001Примерен изход2 Зад. 6 Дадени са резултатите от N(N<=100) поредни хвърляния на зарче. Да се състави програма

ZAR4E.CPP, която прочита от клавиатурата броя N на хвърлянията и падналите се числа и отпечатва:числото, което се е падало най-често;началния и крайния номер на най-дългата последователност от еднакви попадения.

Примерен вход101244233344Примерен изход:46 8

Зад. 7. Да се състави програма BANK.CPP за работа с банкови сметки. Програмата съхранява сумите на не повече от 100 банкови сметки, като извършва следните дейности по избор от меню:

а) въвежда сумите за N сметки (0<N<100);б) добавя нова банкова сметка;в) отпечатва номера на банковата сметка с най-голяма сума;г) олихвява всички банкови сметки с въведен процент и отпечатва получените след олихвяването

суми;д) внася или изтегля суми по даден номер на банкова сметка; е) по даден номер на банкова сметка отпечатва сумата.Зад. 8. а)Да се състави функция, която по дадено цяло число връща броя на различните му цифри

(числото 3321 има три различни цифри). б)Като използвате подпрограмата от точка а) да се състави програма DIF.CPP, която

запълва от клавиатурата едномерен целочислен масив с n елемента (1n100) и отпечатва тези от тях, които имат три различни цифри.

Зад. 9. Да се състави програма MASIV1.CPP, която чете от клавиатурата цяло число n<=1000 и n реални числа и:

а) Определя колко от тях са равни на минималното от всички числа.б) Замества всички числа, равни на максималното със средното аритметично на всички числа;в) Определя минималното отрицателно число от дадените. Ако няма такова отпечатва 0.г) Извежда числата по 15 в ред.Зад. 10. Да се състави програма COMP.CPP, която въвежда и обработва резултатите на n

състезатели, (n<=25). Всеки резултат представлява неотрицателно число, не по голямо от 999, всяка една от цифрите, на което представя резултата от пореден кръг в състезанието. ( Например, числото 1 означава, че състезателят е имал 0 точки на първите два кръга и 1 на третия, числото 165 – на първи кръг има 1 точка, на втория – 6, на третия – 5.)

а) да се отпечатат номерата на състезателите с равни резултати от всеки кръг; (Например, 555, или 0, или 111 и т.н.);

б) да се преобразуват резултатите на всички състезатели, като всеки един се замести въведения резултат със сумата от точките на трите кръга.

в) да се отпечата номера на състезателя с най-висок резултат.Зад. 11. Всяко число N (1N3000000000) може да има или да няма повтарящи се цифри. В

някои от числата дадени цифри се повтарят повече от други. Съставете програма REPEAT.EXE, която прочита от клавиатурата дадено цяло число N и отпечатва на първия ред на екрана колко пъти се повтаря

129

Page 130: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

най-често срещаната цифра, а на втория ред - коя е тя. Ако с такъв брой повторения са няколко цифри, програмата отпечатва всичките на един ред, отделени с интервали в нарастващ ред.

Примерен вход34456784Примерен изход:34Примерен вход2223555725Примерен изход:42 5Примерен вход101010Примерен изход:30 1

130

Page 131: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Лабораторен практикум №7Масиви

Зад.1. Въведете текста на следната програма:#include<iostream.h>int a[10],n;

void Vhod(){

cout<<”n=”; cin>>n; for(int i=0; i<n; i++) {

cout<<”a[“<<i<<”]=”; cin>>a[i];

}}

void Print(){

for(int i=0;i<n;i++) cout<<a[i]<<’ ‘;cout<<endl;

}void main()

{ Vhod(); Print();

}

а) тествайте програмата и обяснете как работи.б) добавете нова функция, която отпечатва симетричните спрямо центъра двойки елементи,

които са приятелски числа. Тествайте програмата за следните редици:18 3 15 29 59 61 31 71 5 20149 33 21 17 17 19 37 23 31 151

Напишете текста на новата функция и резултатите от тестовете.Зад. 2. Да се състави програма, която въвежда рeдица от цели числа и отпечатва броя на

отрицателните елементи.а) добавете нова функция, която намира индекса на първото просто число в редицата и добавете в

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

на отрицателните съвпада с индекса на първото просто число в редицата.Напишете текста на новата програма и резултатите от следните тестове:

-12 9 21 151 -87 23 89 -3 -15 7545 2 -27 9 71 -2 -18 63 -35 101

Зад. 3. Да се състави програма, която въвежда рeдица от цели числа и отпечатва наи-малкото от тях и средното аритметично от положителните елементи.

Зад. 4. Да се състави програма, която въвежда масив от цели числа и го обръща обратно (т.е. първият елемент става последен а последният първи; вторият предпоследен а предпоследният втори и т.н.).

Зад. 5. Всяко число N (1N3000000000) може да има или да няма повтарящи се цифри. В някои от числата дадени цифри се повтарят повече от други. Съставете програма REPEAT.EXE, която прочита от клавиатурата дадено цяло число N и отпечатва на първия ред на екрана колко пъти се повтаря най-често срещаната цифра, а на втория ред - коя е тя. Ако с такъв брой повторения са няколко цифри, програмата отпечатва всичките на един ред, отделени с интервали в нарастващ ред.

Примерен вход101010Примерен изход:30 1

131

Page 132: Алгоритми - Школа А&Бab-bg.com/students/uchebnik.doc · Web viewЕто защо, базирайки се на опита, който имаме при усвояване

Използвана литература:

1. Красимир Манев, Нели Манева, “Информатика за 9 клас на СОУ – профилирано обучение”, Издателство “Анубис”, София 2003 г.

2. Красимир Манев, Нели Манева, “Информатика за 9 клас на СОУ”(учебно помагало), Издателство “Анубис”, София 2000 г.

3. Димитър Богданов, И. Мустакеров, “Език за програмиране С”, Издателство “Техника”, София 2001 г.

4. Магдалина Тодорова, “Програмиране на С++ - част първа”, Издателство “Сиела”, София 2002 г.

5. Емил Келеведжиев, Зорница Дженкова, “Алгоритми, Програми и Задачи”, Издателство “Регалия”, 2004 г.

6. Петър Бърнев, Георги Тотков, Росица Донева, Владимир Шкуртов, Коста Гъров, “Информатика за 9 клас на СОУ”, Издателство “Летера”, Пловдив 2001 г.

7. Павел Азълов, Фани Златарова “Информатика с Паскал в примери, тестове и задачи”, Издателство “Аsio”, София 1995 г.

8. http://www.infoman.musala.com

132