5. Условни оператори  I

 
"Човечето от нищо искало да опита, потърсило стена, за да си
блъсне главата, но стената била от нищо и тъй като се било
засилило - паднало от другата страна."
Джани Родари, Човечето от нищо
 
Условният оператор if.
** Програма за  намиране на корените на квадратното уравнение ax2+ bx + c = 0.
// sqe1.cpp
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
 double a;
 double b;
 double c;
 cout << "Enter the coeficients a, b and c: ";
 cin >> a >> b >> c;
 double diskr = b*b - 4*a*c;
 if (diskr >= 0)
 {
  double x1 = (-b+sqrt(diskr))/(2*a);
  double x2 = (-b-sqrt(diskr))/(2*a);
  cout << "The roots are: " << x1 << " and " << x2;
 }
 return 0;
}

Enter the coeficients a, b and c: 1 -3 2
The roots are: 2 and 1
    В този вариант на програмата трябва да се задават "разумни" стойности - например при въвеждане на 0 за стойност на променливата a изпълнението на програмата ще се прекрати поради грешка "деление на 0".
** Синтаксис:
if (<условие>)  <оператор>;

    Когато условието е вярно, се изпълнява оператора. Ако условието е нарушено (не е вярно), се изпълнява следващия оператор (след оператора if).
    Блок се нарича група оператори, заградени с фигурни скоби {}.Блокът се разглежда като един оператор.



Операции за сравнение на числа и низове.
 
 >  по-голямо
 >=  по-голямо или равно
 <  по-малко
 <=  по-малко или равно
 ==  равно
 !=  различно (неравно)
* Сравняване на числа - по правилата в математиката.
* Сравняване на низове - лексикографска наредба. Когато два низа се сравняват, се започва със сравняване на първите им символи - ако те са еднакви, се преминава към вторите и т.н. Процесът спира или когато се стигне до края на единия низ, или когато се стигне до първата разлика. В първия случай по-късият низ е по-напред (по-малък) в лексикографската наредба. Във втория случай се гледа кой от двата символа е по-напред в  ASCII таблицата.
"car" < "truck", "car" < "cat", "car" < "cargo"

* ASCII таблица
  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.



Сравняване на числа с плаваща точка.
* Числата с плаваща точка имат ограничена точност и пресмятанията с тях са източник на грешки от закръгляне. Например
// round1.cpp
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
 double r = sqrt(2);
 if (r*r == 2) cout << r*r << " OK\n";
 else cout << r*r << " BAD\n";
 return 0;
}

2 BAD
    Вътрешното представяне на r*r е всъщност 2.00000000004 (броят на нулите няма значение).
Затова числа с плаваща точка никога не се сравняват за равенство.
*  За избягване на подобни ефекти числата трябва да се сравняват за абсолютна или относителна близост.
- Aбсолютна близост на числата x и y:
  if (fabs(x-y) < eps) cout << "Числата за абсолютно близки";
- Относителна близост на числата x и y:
  double dmax = fabs(x);
  if (fabs(y) > dmax) dmax = fabs(y);
  if (fabs(x-y) < dmax*eps) << "Числата за относително близки";


Проверка за валидност на входните данни.
* Проверка дали въведеното число е положително.
// 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: area cannot be negative\n";
      return 1;
   }
/* знаем, че area >= 0  */
   cout << "The side length of the square is "
        << sqrt(area) << "\n";
   return 0;
}

Please enter the area of a square: 64
The side length of the square is 8
Please enter the area of a square: -25
Error: area cannot be negative

* Проверка на състоянието на входния поток.
// area2.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())
   {  cout << "Error: bad input\n";
      return 1;
   }
/* знаем, че променливата area има стойност */
   if (area < 0)
   {  cout << "Error: area cannot be negative\n";
      return 1;
   }
/* знаем, че area >= 0 */
   cout << "The side length of the square is "
        << sqrt(area) << "\n";
   return 0;
}

Please enter the area of a square: two
Error: bad input

Двойката оператори if/else.
** Подобрение на програмата за  намиране на корените на квадратно уравнение.
// sqe2.cpp
#include <iostream>
#include <cmath>
using namespace std;

int main()
{
 double a, b, c;
 cout << "Enter the coeficients a, b and c:";
 cin >> a >> b >> c;
 double diskr = b*b - 4*a*c;
 if (fabs(a) < 1e-10)
 {
  cout << "The equation is not quadratic!";
  return 0;
 }
 if (diskr >= 0)
 {
  double x1 = (-b+sqrt(diskr))/(2*a);
  double x2 = (-b-sqrt(diskr))/(2*a);
  cout << "The roots are: " << x1 << " and " << x2;
 }
 else cout << "The equation has no real roots.";
 return 0;
}
 

Enter the coeficients a, b and c: 1 2 1
The equation has no real roots.

** Синтаксис:

if (<условие>)  <оператор1> else   <оператор2>;

Условна операция (операция за избор)
** Операторът
     y = x>0 ? x : -x;
присвоява на y абсолютната стойност на x.
** Синтаксис:

(условие) ?  израз1 : израз2
    Ако условието е изпълнено, се пресмята израз1, в противен случай - израз2. Получената стойност на израза е и стойност и на операцията.


Програмиране на алтернативи (избор на един от няколко варианта).
    Да се намери стойността (в долари) на купчина американски монети (1 penny = 1 цент, 1 nickel = 5 цента, 1 me = 10 цента, 1 quarter = 25 цента). Купчината съдържа еднакви монети.
// coins6.cpp
#include <iostream>
#include <string>
using namespace std;

int main()
{  int n;
   string name;
   cout << "Enter the number and the coins name: ";
   cin >> n >> name;
   name = name.substr(0, 4);

   double value = 0;
        if (name == "penn") value = n * 0.01;
   else if (name == "nick") value = n * 0.05;
   else if (name == "dime") value = n * 0.10;
   else if (name == "quar") value = n * 0.25;
   else cout << name << " is not a valid coin name\n";
   cout << "Value = " << value << "\n";
   return 0;
}

Enter the number and the coins name: 25 dimes
Value = 2.5
 А без операторите else?
 if (name == "penn") value = n * 0.01;
 if (name == "nick") value = n * 0.05;
 if (name == "dime") value = n * 0.10;
 if (name == "quar") value = n * 0.25;
В този случай ще бъдат проверени всички условия на операторите if.