4. Основни управляващи оператори

План:
Оператор if
Оператор if/else
Условна операция
Операции за сравнения
Проверка за валидност на входните данни
Оператор while
Обработка на входна редица
Булев тип данни


** Оператор if (условен оператор)

Операторът if се състои от 2 части - условие и тяло. if е съставен оператор.

Пример:

if (area < 0)
   cout << "Error: Negative area.\n";

[блок-схема]

Когато условието е вярно (текущата стойност на променливата area е отрицателно число), се изпълнява тялото на оператора if, т.е оператора за изходен поток
cout << "Error: Negative area.\n";

Ако условието е нарушено (не е вярно: текущата стойност на променливата area е нeотрицателно число), се изпълнява следващия оператор (след оператора if).
Тялото на if може да бъде друг оператор или блок.
Блок е група от оператори, оградени с къдрави (големи) скоби {}.

Пример:

if (area < 0)
{  cout << "Error: Negative area.\n";
   return 1;
}

Блокът замества (или се разглежда като) един оператор.

// area1.cpp

#include
<iostream>
#include <cmath>

using namespace std;

int main()
{  double area;
   cout << "Please enter the area of a square: ";
   cin >> area;
   if (area < 0)
   { 
cout << "Error: Negative area.\n";
      return 1;
   }
   /* now we know that area is >= 0  */
   double length = sqrt(area);
   cout << "The side length of the square is " << length << "\n";
   return 0;
}

nkirov@CITB107 % c++ -o area area1.cpp
nkirov@CITB107 % ./area
Please enter the area of a square: 25
The side length of the square is 5
nkirov@CITB107 % ./area
Please enter the area of a square: -100
Error: Negative area.

** Оператор if/else (условен оператор)

Операторът if/else се състои от условие и две алтернативи. if/else е съставен оператор.

Пример:

if (area >= 0)
   cout << "The side length is " << sqrt(area) << "\n";
else
   cout << "Error: Negative area.\n";

Всяка алтернатива е оператор или блок.

[блок-схема]

Операторът if/else е по-добър избор в сравнение с два if оператора с допълващи се условия:

if (area >= 0)               /* complementary conditions */
   cout << "The side length is " << sqrt(area) << "\n";
if (area < 0) /* complementary conditions */
   cout << "Error: Negative area.\n";

// area2.cpp

#include
<iostream>
#include <cmath>

using namespace std;

int main()
{  double area;
   cout << "Please enter the area of a square: ";
   cin >> area;

   if (area >= 0)
      cout << "The side length is " << sqrt(area) << "\n";
   else
      cout <<"Error: Negative area.\n";

   return 0;
}
nkirov@CITB107 % c++ area2.cpp
nkirov@CITB107 % ./a.out
Please enter the area of a square: 25
The side length is 5
nkirov@CITB107 % ./a.out
Please enter the area of a square: -1
Error: Negative area.


** Условна операция (операция за избор, selection operator)

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

Пример:

   x >= 0 ? x : -x

Ако условието или първият аргумент, (x >= 0) е вярно,  стойността на операцията е вторият аргумент (x), ако не е вярно - третият аргумент (-x).

Операторът, съставен от операция присвояване и една условна операция:

   y = x >= 0 ? x : -x;

или (приоритет на операциите в C++)
   y = ((x >= 0) ? x : -x);

е еквивалентен на следния if/else оператор:

   if (x >= 0) y = x;
else y = -x;

и присвоява на променливата  y абсолютната стойност на променливата x.

    Израз (expression), операция (operator)
Оператор (statement)
  x >= 0 ? x : -x
if (x >= 0) y = x;
else y = -x;
  y = x
y = x;
  -b + sqrt(d)
-b + sqrt(d);

** Операции за сравнения (relational operators)

C и С++ имат 6 операции за  сравнения, като стойността на операцията е true или false.

C++ 
Описание
Пример
Бележки
>
по-голямо от
a > 5

>=
по-голямо от или
равно на
x >= 5
Внимавайте да не напишете =>
Двата знака са в реда на произнасяне.
<
по-малко от
x < 10

<= 
по-малко от или
равно на
x <= 11
Внимавайте да не напишете =<
Двата знака са в реда на произнасяне.
==
равно на
a == 5
Не бъркайте с = , което е операция присвояване!
!=
неравно на
(различно от)
a != 5
Все едно ! минава през (задрасква) знака за равенство.

Сравняването на числа в С++ е по правилата в математиката.
Аргументна зависимост на операциите за сравнения за числа тип int и тип double.

Сравняването на низове е според лексикографската наредба:

- Започва със сравняване на първите им символи.
c a r
t r
u c k

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

Процесът спира:
- или когато се стигне до края на единия низ,
c a r
c a r g o

- или когато се стигне до първата разлика.
c a r g o
c a t h o d e

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

Примери:

"car" < "truck", "car" < "cargo""cargo" <= "cathode" са изрази със стойност true.
"car" == "truck"
, "car" > "cargo""cargo" >= "cathode"
са изрази със стойност false.

ASCII Table

(American Standard Code for Information Interchange)

0-31 are control codes, for example "/n" (newline) has ASCII code 10.

  32:   33:!  34:"  35:#  36:$  37:%  38:&  39:'  40:(  41:)
  42:*  43:+  44:,  45:-  46:.  47:/  48:0  49:1  50:2  51:3
  52:4  53:5  54:6  55:7  56:8  57:9  58::  59:;  60:<  61:=
  62:>  63:?  64:@  65:A  66:B  67:C  68:D  69:E  70:F  71:G
  72:H  73:I  74:J  75:K  76:L  77:M  78:N  79:O  80:P  81:Q
  82:R  83:S  84:T  85:U  86:V  87:W  88:X  89:Y  90:Z  91:[
  92:\  93:]  94:^  95:_  96:`  97:a  98:b  99:c 100:d 101:e
 102:f 103:g 104:h 105:i 106:j 107:k 108:l 109:m 110:n 111:o
 112:p 113:q 114:r 115:s 116:t 117:u 118:v 119:w 120:x 121:y
 122:z 123:{ 124:| 125:} 126:~ 127:  128:Ђ 129:Ѓ 130:‚ 131:ѓ
 132:„ 133:… 134:† 135:‡ 136:€ 137:‰ 138:Љ 139:‹ 140:Њ 141:Ќ
 142:Ћ 143:Џ 144:ђ 145:‘ 146:’ 147:“ 148:” 149:• 150:– 151:—
 152:� 153:™ 154:љ 155:› 156:њ 157:ќ 158:ћ 159:џ 160:  161:Ў
 162:ў 163:Ј 164:¤ 165:Ґ 166:¦ 167:§ 168:Ё 169:© 170:Є 171:«
 172:¬ 173:­  174:® 175:Ї 176:° 177:± 178:І 179:і 180:ґ 181:µ
 182:¶ 183:· 184:ё 185:№ 186:є 187:» 188:ј 189:Ѕ 190:ѕ 191:ї
 192:А 193:Б 194:В 195:Г 196:Д 197:Е 198:Ж 199:З 200:И 201:Й
 202:К 203:Л 204:М 205:Н 206:О 207:П 208:Р 209:С 210:Т 211:У
 212:Ф 213:Х 214:Ц 215:Ч 216:Ш 217:Щ 218:Ъ 219:Ы 220:Ь 221:Э
 222:Ю 223:Я 224:а 225:б 226:в 227:г 228:д 229:е 230:ж 231:з
 232:и 233:й 234:к 235:л 236:м 237:н 238:о 239:п 240:р 241:с
 242:т 243:у 244:ф 245:х 246:ц 247:ч 248:ш 249:щ 250:ъ 251:ы

 252:ь 253:э 254:ю 255:

Първите 32 символа (от 0 до 31) са управляващи символи и нямат стандартен графичен образ.
Символите от 127 до 255 са различни в различните езици.

Мястото на българската азбука е различно в зависимост от типа на кодирането - в таблицата е даден стандарта Windows-1251.


** Проверка за валидност на входните данни

Проверка на входа е приложение на оператора if, което проверява дали потребителят е дал разумен вход.

Пример: Оператор за прочитане на число, което става стойност на променлива.

double area;
cin >> area;

Ако потребителят напише "five" и натисне <return>, то обектът cin ще премине в състояние грешка (fail) и променливата area ще остане с непроменена (вероятно неопределена) стойност.

Пример:

// area3.cpp

#include
<iostream>
#include <cmath>

using namespace std;
 
int main()
{  double area;
   cout << "Please enter the area of a square: ";
   cin >> area;
   if (cin.fail()) // проверка на състоянието на cin
   { 
cout << "Error: Bad input\n";
      return 1;
   }
   if (area < 0)
   { 
cout << "Error: Negative area.\n";
      return 1;
   }
   cout << "The side length is " << sqrt(area) << "\n";

   return 0;
}
nkirov@CITB107 % c++ area3.cpp
nkirov@CITB107 % ./a.out
Please enter the area of a square: four
Error: Bad input
nkirov@CITB107 % ./a.out
Please enter the area of a square: -25
Error: Negative area.
nkirov@CITB107 % ./a.out
Please enter the area of a square: 25
The side length is 5

Други стратегии за проверка на състоянието на cin.

Пример:

if (cin)
   /* the stream did not fail */
else
   /* the stream failed */

Операцията входен поток  (с първи аргумент cincin >> x има стойност cin. Това позволява да се комбинират няколко операции >> в един израз (верижка).

Пример:

cin >> x >> y    /* което означава (cin >> x) >> y */
подобно на
a + b + c       /* което означава (a + b) + c */
или
a = b = c      /* което пък означава a = (b = c) */
(приоритет на операциите в C++)

Изразът cin >> x може да се използва като условие в оператора if, като състояние "нормално" е true, а състояние "грешка" е false.

Пример:

if (cin >> x) cout << x;

** Оператор while (оператор за цикъл)

Пример:
Внасяме 10000 лв. в банкова сметка с 6% год. лихва при месечно олихвяване. След колко години сумата в сметката ще се удвои?

Месец Сума  Пресмятане
0 10000.00  
1 10050.00 =10000.00*1.005
2 10100.25 =10050.00*1.005
3 10150.75 =10100.25*1.005
4 10201.51 =10150.75*1.005
.. ... ...

1. Започваме с таблицата:
(int month = 0; double balance = 10000;)

Месец Сума
0 10000

2. Повтаряме стъпки 2а-2в докато съдържанието на сметката е под 20000 лева.
(цикъл, докато balance < 20000)
2а. Добавяме нов ред към таблицата.
2б. В първата колона на този ред поставяме число, с 1 по-голямо от това на горния ред.
(month++;)
2в. Във втората колона на същия ред поставяме числото от горния ред (същата колона), умножено с 1.005.
(balance = balance*1.005;)

3. Разделяме последното число от първата колона на 12.
(year = month/12;)

while (balance < 2 * initial_balance)
{  balance = balance * ( 1 + rate / 100);
   month++;
}

[блок-схема]

// doublinv.cpp

#include
<iostream>
using namespace std;

int main()
{
double
rate = 5;
double
initial_balance = 10000;
double balance = initial_balance;
int
month = 0;

while (balance < 2
* initial_balance)
  {

balance = balance * (1 + rate /
100 / 12);
month
++;
 }
int years = month/12;
cout << "The investment doubled after "
<<
years << " years.\n";

return 0;
}
nkirov@CITB107 % c++ doublinv.cpp
nkirov@CITB107 % ./a.out
The investment doubled after 15 years.
nkirov@CITB107 %


** Обработка на входна редица - сентинел (sentinel, страж)
// sentinel.cpp

#include
<iostream>
using namespace std;
 
int main()
{  double sum = 0;
   int count = 0;
   double salary = 0;
   while (salary != -1)
   { 
      cout << "Enter a salary, -1 to finish: ";
      cin >> salary;
      if (salary != -1) 
      { 
         sum = sum + salary;
         count++;
      }
   }
   if (count > 0)
      cout << "Average salary: " << sum / count << "\n";

   return 0;
}
nkirov@CITB107 % c++ sentinel.cpp
nkirov@CITB107 % ./a.out
Enter a salary, -1 to finish: 1200
Enter a salary, -1 to finish: 3450
Enter a salary, -1 to finish: 2900
Enter a salary, -1 to finish: 3400
Enter a salary, -1 to finish: -1
Average salary: 2737.5
nkirov@CITB107 %


// maxtemp.cpp

#include
<iostream>
using namespace std;
 
int main()
{  double next;
   double highest;
 
   cout << "Please enter the temperature values:\n";
   if (cin >> next) 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;
}
nkirov@CITB107 % c++ maxtemp.cpp
nkirov@CITB107 % ./a.out
Please enter the temperature values:
23
-2
9
0
The highest temperature is 23

** Булев тип данни

Тип данни bool - булев или логически тип, съдържа две константи - true и false.
Стойност на булева променлива е едната от тези две стойности.

Пример:

bool more = true;
while (more)
{  cin >> next;
   if (cin.fail()) more = false;
   else
   {      
// process next
   }
}

Стойността на всяка операция за сравнение е от булев тип (и е true или false).
Условията в операторите if и while са изрази със стойност true или false.

Пример:

int k = 5;
bool
positive = (k > 0); //
променливата има стойност true
positive = (k == 0);
// променливата има стойност false

Не пишете (лош стил на програмиране):

while(more == false) /* don't */
while(more != true) /* don't */
еквивалентно (добър стил на програмиране):
while(!more) /* OK */
while(more)  /* OK */