9. Цикли
** Синтаксис:
|
** Удвояване на влог (задачата от лекция 1. Увод).
Внасяме 10000 лв. в банкова сметка с 6% год. лихва
при месечно олихвяване. След колко години сумата в сметката ще се удвои?
// doublinv.cpp
#include <iostream>
using namespace std;
int main()
{ double rate = 6;
double balance = 10000;
int month = 0;
while (balance < 20000)
{ month++;
balance
= balance * (1 + rate/12/100);
}
cout << "The investment
doubled after "
<< month / 12.0 << " years.\n";
return 0;
}
The investment doubled after 11.5833 years. |
** Факториел.
Да се пресметне стойността на функцията факториел
без рекурсия.
// whilefac.cpp
#include <iostream>
using namespace std;
long factorial(int n)
{ int factor = 1;
long product = 1;
while (factor <= n)
{ product = product
* factor;
factor++;
}
return product;
}
int main()
{ cout << "Please enter a
number: ";
int n;
cin >> n;
cout << n <<
"! = " << factorial(n) << "\n";
return 0;
}
** Максимална стойност.
Програмата чете редица от стойности (числа) и извежда
най-голямата стойност.
// maxtemp.cpp
#include <iostream>
using namespace std;
int main()
{
/* съхранява
текущото число */
double next;
/*
съхранява
най-голямото въведено число до момента */
double highest;
cout << "Please enter
the temperature values:\n";
if (cin >> next)
/* инициализира
highest с първото въведено число */
highest
= next;
else
{ cout << "No
data!\n";
return
1;
}
while (cin >> next)
if (next
> highest) highest = next;
cout << "The highest
temperature is " << highest << "\n";
return 0;
}
Please enter the temperature values:
12 22 -3 a The highest temperature is 22 |
Цикъл for.
** Синтаксис:
|
Редът на изпълнение на четирите части на оператора е:
<инициализация>
<условие> - ако
не е изпълнено, край на цикъла
<оператор>
<корекция>
<условие> - ако
не е изпълнено, край на цикъла
<оператор>
<корекция> и т.н.
** Най-често срещаната форма за използване на оператора for
е:
for
(i=начало; i<=край;
i++)
{
тяло
на цикъла
}
** Пресмятане стойността на функцията факториел - вместо цикъл while
се използва цикъл for.
// forfac.cpp
#include <iostream>
using namespace std;
long factorial(int n)
{ long product = 1;
int factor;
for (factor = 1; factor <=
n; factor++)
product
= product * factor;
return product;
}
int main()
{ cout << "Please enter a
number: ";
int n;
cin >> n;
cout << n <<
"! = " << factorial(n) << "\n";
return 0;
}
** Синтаксис:
|
** Алгоритъм на Херон за намиране на квадратен корен.
Търси се квадратен корен от положителното число
a.
Строи се редицата:
x0 = a, xn+1
= (xn + a/xn)/2
която е сходяща с граница точно търсеното число. Организира се цикъл
за пресмятане членовете на редицата и когато разликата между два
съседни члена на редицата стане достатъчно близо до 0, т.е. |xn+1-xn|
< eps, пресмятанията се прекратяват.
// sqroot.cpp
#include <iostream>
#include <cmath>
using namespace std;
bool not_equal(double x, double y)
/* ЦЕЛ:
сравнява две числа с плаваща точка
ПОЛУЧАВА: x,y - числа
ВРЪЩА:
true ако x не е достатъчно близо до y
*/
{ const double EPSILON = 1E-14;
double dmax = fabs(x);
if (fabs(y) > dmax) dmax
= fabs(y);
return fabs(x - y) > dmax*EPSILON;
}
double squareroot(double a)
/* ЦЕЛ:
пресмята квадратен корен по формулата на Херон
ПОЛУЧАВА: a - положително
число
ВРЪЩА:
квадратен корен от a
*/
{ if (a == 0) return 0;
double xnew = a;
double xold;
do
{ xold = xnew;
xnew =
(xold + a/xold)/2;
}
while (not_equal(xnew, xold));
return xnew;
}
int main()
{ cout << "Please enter a
number: ";
double x;
cin >> x;
cout << "The square
root is " << squareroot(x) << "\n";
return 0;
}
Please enter a number: 2
The square root is 1.41421 |
Безкрайни цикли
Примери:
for (i=1; i>0; i++)
cout << i;
while (true) cout <<
"no end";
Смислено използване на безкраен цикъл: в тялото
на цикъла се намира изхода от цикъла, най-често оператор return,
който прекратява изпълнението на функцията.
double squareroot(double
a)
{
if (a == 0) return
0;
double xnew =
a;
while (true)
{
double
xold = xnew;
xnew =
(xold + a/xold)/2;
if (equal(xnew,
xold)) return xnew;
}
}
int main()
/* Програмата
намира броя на думите от входния поток */
{ int count = 0;
string word;
while (cin >> word)
count++;
cout << count <<
" words.\n";
return 0;
}
Here are 4 words
^Z 4 words. |
** Пренасочване на входния и изходния потоци.
C:\my\>myprog <
a_cin.txt
Вместо от клавиатурата, операционната система пренасочва
входа от текстов файл, в случая това е файла a_cin.txt.По
този начин програмата за намиране на броя на думите може намери броя на
думите в текстов файл (едно по-смислено приложение на тази програма).
C:\my\>myprog > a_cout.txt
Вместо на екрана, операционната система пренасочва
изхода на текстов файл, в случая това е файла a_cout.txt.
** Извеждане на таблици.
Да се отпечати таблица, която показва съдържанието
на банкова сметка с първоначален влог 10000 в края на десетата година.
Лихвата варира от 5% до 10% и се изменя със стъпка 0.5%.
// baltable.cpp
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double future_value(double initial_balance,
double p, int nyear)
/*
ЦЕЛ:
пресмята стойността на влог със сложна лихва
ПОЛУЧАВА: initial_balance - начална
стойност на влога
p - годишен лихвен процент
nyear - броя на годините
ЗАБЕЛЕЖКИ: лихвата се начислява всеки
месец
*/
{ double b = initial_balance*pow(1
+ p/12/100, 12*nyear);
return b;
}
int main()
{ cout << "
Rate Balance\n";
double rate;
double initial_amount = 10000;
int nyear = 10;
cout << fixed << setprecision(2);
for (rate = 5; rate <= 10; rate
= rate + 0.5)
{ double balance = future_value(initial_amount,
rate, nyear);
cout << setw(10)
<< rate << setw(10) << balance << "\n";
}
return 0;
}
Rate Balance
5.00 16470.09 5.50 17310.76 6.00 18193.97 6.50 19121.84 7.00 20096.61 7.50 21120.65 8.00 22196.40 8.50 23326.47 9.00 24513.57 9.50 25760.55 10.00 27070.41 |
Същата информация може да се изобразим графично,
като се начертае редица от точки - по една точка за всяка стойност.
// balgraph.cpp
#include "ccc_win.cpp"
double future_value(double initial_balance,
double p, int nyear)
{ double b = initial_balance * pow(1
+ p/12/100, 12*nyear);
return b;
}
int main()
{ double rate;
double initial_amount = 10000;
int nyear = 10;
cwin.coord(5, 3*initial_amount,
10, 0);
for (rate = 5; rate <=
10; rate = rate + 0.5)
{ double balance = future_value(initial_amount,
rate, nyear);
cwin <<
Point(rate, balance);
}
return 0;
}
int main()
{ double a = cwin.get_double("Please
enter a number");
if (a == 0) return 0;
double xnew = a;
double xold;
int iteration = 0;
const int MAX_ITERATIONS
= 20;
cwin.coord(0, a, MAX_ITERATIONS,
-a);
do
{ xold = xnew;
xnew =
(xold + a / xold) / 2;
cwin <<
Point(iteration, xnew);
iteration++;
} while (iteration < MAX_ITERATIONS);
return 0;
}
void rand_seed()
/* ЦЕЛ: Инициализира генератора за случайни
числа
*/
{ int seed = static_cast<int>(time(0));
srand(seed);
}
double rand_double(double a, double b)
/* ЦЕЛ: намира случайно число в
интервала [a, b]
ПОЛУЧАВА: границите на интервала
ВРЪЩА: случайно число x,
a <= x и x <= b
*/
{ return a + (b - a)*rand()*(1.0/RAND_MAX);
}
double deg2rad(double alpha)
/* ЦЕЛ: превръща градуси в радиани
ПОЛУЧАВА: alpha - големина
на ъгъл в градуси
ВРЪЩА: големината на
ъгъла в радиани
*/
{ const double PI = 3.141592653589793;
return alpha * PI / 180;
}
int main()
{ int NTRIES = 10000;
int i;
int hits = 0;
rand_seed();
for (i = 1; i <= NTRIES;
i++)
{ double ylow = rand_double(0,
2);
double
angle = rand_double(0, 180);
double
yhigh = ylow + sin(deg2rad(angle));
if (yhigh
>= 2) hits++;
}
cout << "Tries / Hits
= " << NTRIES*(1.0/hits) << "\n";
return 0;
}
Tries / Hits = 3.18471 |
Вложени цикли.
Да се отпечати таблица, която показва
натрупаната сума по влог от 10000 лв. за 5, 10, 15, и 20 години при годишна
лихва от 5 до 10% (през 0.5%).
// table.cpp
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double future_value(double init_balance,
double p, int n)
{ return init_balance*pow(1 + p/12/100,
12*n);
}
int main()
{
const double RATE_MIN = 5;
const double RATE_MAX = 10;
const double RATE_INCR = 0.5;
const int YEAR_MIN = 5;
const int YEAR_MAX = 20;
const int YEAR_INCR = 5;
/* отпечатва
заглавната част на таблицата */
cout << " Rate ";
int year;
for (year=YEAR_MIN; year<=YEAR_MAX;
year=year+YEAR_INCR)
cout <<
setw(2) << year << " years ";
cout << "\n";
cout << fixed << setprecision(2);
double rate;
double init_bal = 10000;
for (rate=RATE_MIN; rate<=RATE_MAX;
rate=rate+RATE_INCR)
/* отпечатва
ред от таблицата */
{ int year;
cout << setw(5) <<
rate;
for (year=YEAR_MIN; year<=YEAR_MAX;
year=year+YEAR_INCR)
{ double balance = future_value(init_bal,
rate, year);
cout <<
setw(10) << balance;
}
cout << "\n";
}
return 0;
}
Rate 5 years 10
years 15 years 20 years
5.0 12833.59 16470.09 21137.04 27126.40 5.5 13157.04 17310.76 22775.84 29966.26 6.0 13488.50 18193.97 24540.94 33102.04 6.5 13828.17 19121.84 26442.01 36564.47 7.0 14176.25 20096.61 28489.47 40387.39 7.5 14532.94 21120.65 30694.52 44608.17 8.0 14898.46 22196.40 33069.21 49268.03 8.5 15273.01 23326.47 35626.53 54412.43 9.0 15656.81 24513.57 38380.43 60091.52 9.5 16050.09 25760.55 41345.93 66360.61 10.0 16453.09 27070.41 44539.20 73280.74 |
Област на действие
на променлива.
Всяка променлива се разпознава само вътре
в блока, в който е дефинирана. Променливата, дефинирана в оператор for
се разпознава до края на блока на оператора for. В следващия
пример са използвани съкращенията НОДП - начало на
областта на действие на променливата и КОДП - край на областта на действие
на променливата.
int main()
{
cout << "Minimal interest
rate in percent: ";
double rmin;
/* НОДП rmin */
cin >> rmin;
double init = 10000;
/* НОДП init */
for (int r=rmin; r<=rmin+5; r++)
/* НОДП r */
{ cout << setw(5) <<
r;
for (int year=2; year<=10;
year+=2) /* НОДП year */
{ double bal = future_value(init,r,year);/*
НОДП bal */
cout <<
setw(10) << bal;
}
/* КОДП year и bal */
cout << "\n";
}
/* КОДП r */
return 0;
}
/* КОДП rmin и init */