Част 9. Операторите за управление II част (Advanced Decisions)
В тази предната лекция разгледахме логическите оператори ако (if) и ако-иначе (if-else). В тази ще разгледаме ключ (switch) и условния оператор " ?: , ", както и една специфична конструкция на if-else оператора.
1. Конструкцията else-if . Нека разгледаме примера от предната лекция, който определя възрастовите категории.
if
(age < 2)
cout << "\nInfant";
// it's an infant
else
if (age < 18)
cout << "\nChild";
// it's a child
else
if (age < 70)
cout << "\nAdult"; // it's an
adult
else
cout << "\nElderly"; // it's an elderly
Самата конструкция по-горе е доста объркваща, въпреки отместването на редовете. Сравнете горните редове с редовете по-долу, които са същият код, но написан без отместванията и с двата оператора else и if на един ред.
if
(age < 2)
cout << "\nInfant";
// it's an infant
else
if (age < 18)
cout << "\nChild";
// it's a child
else
if (age < 70)
cout << "\nAdult";
// it's an adult
else
cout << "\nElderly"; //
it's an elderly
Както споменахме в предната лекция операторът else "принадлежи" на последния if оператор. Ето защо кодът по-горе може да се тълкува като "стълбица", в която, ако условието е вярно, ще се изпълни редът след условието или, ако не е вярно - по-следващия ред, който е проверка на следващото условие.
Обърнете внимание, че конструкцията else-if не е част от синтактиса на C++, а просто е начин на подредба на двата оператора -- реално погледнато, както показва най-горният код, конструкцията е if-else.
2. Оператор "прекъсване" (The break Statement) . Операторът break препраща изпълнението на програмата на следващия ред след най-вътрешния цикъл, в който той е употребен. Този оператор прекъсва изпълнението на конструкцията switch и циклите for, while, и do-while.
Примерът по-долу проверява дали цялото число n е просто. За целта то се дели на всички числа, започвайки от 2 и стигайки до половината му. Ако се осъществи целочислено делене с j, т.е. ако (n%j == 0) е истина, то числото не е просто (има множител, равен на j) и по-нататъшна проверка за други множители е излишна, т.е. трябва да спрем изпълнението на цикъла. Това се постига с оператора break.
int
isPrime = 1;
// assume n is prime
for(int
j = 2; j < n/2; j++) // divide by all integers from 2 to
n/2
{
if (n%j == 0)
// if evenly divisible,
{
isPrime = 0;
// n is not a prime
break;
// no point in looping again
}
}
Ако условието след if оператора е вярно, то променливата isPrime става неистина и програмата достига до оператора break. Неговото действие е програмата да излезе от най-вътрешния цикъл, който съдържа този оператор. В случая това е цъкълът for(int j = 2; j < n/2; j++). Аналогично, с break се излиза и от на другите два цикъла while и do, както и от конструкцията switch, стига те да са най-вътрешни цикли или, съответно, конструкции.
Искаме да обърнем внимание върху израза "излиза от най-вътрешния цикъл" -- операторът break не повлиява по-външните цикли, както показва следващата кратка програма за намиране на всички прости числа сред нечетните числа между 3 и 1001 (2 е също просто число, въпреки че е четно).
//
test_prime.cpp
//
finds all prime numbers between 3 and 1001
#include
<iostream.h>
// for cout and endl
#include
<conio.h>
// for getch()
#include
<iomanip.h>
// for setw()
void
main(int argc, char* argv[] )
{
int n, isPrime;
int prNumCoun = 0;
// counter of prime numbers
for(n = 3; n <= 1001; n = n + 2) // all numbers between 3 and 1001
{
isPrime = 1;
// assume n is prime
for(int j = 2; j < n/2; j++) // divide by all integers from
2 to n/2
{
if(n%j == 0)
// if evenly divisible,
{
isPrime = 0;
// n is not a prime
break;
// no point in looping again
}
}
// } of for(int j = 2; j < n/2; j++)
if (isPrime)
// if n is a prime number ...
{
prNumCoun++;
// another prime number
cout << setw(3)
<< n << ", ";
// ... print it
if (prNumCoun%10 == 0) // print exactly
10 prime numbers a line
cout << endl;
}
}
// } of for(n = 3; n <= 1001; n = n + 2)
cout << "\nEnd of the program!";
getch();
}
// main()
Най-външния цикъл, for(n = 3; n <= 1001; n = n + 2), пробягва всички нечетни числа, и както се вижда от резултата по-долу, той не се повлиява от изпълнението на break. Резултатът от изпълнение на горния код е:
3, 5, 7, 11, 13, 17, 19,
23, 29, 31,
37,
41, 43, 47, 53, 59, 61, 67, 71,
73,
79,
83, 89, 97, 101, 103, 107, 109, 113, 127,
131,
137, 139, 149, 151, 157, 163, 167, 173, 179,
181,
191, 193, 197, 199, 211, 223, 227, 229, 233,
239,
241, 251, 257, 263, 269, 271, 277, 281, 283,
293,
307, 311, 313, 317, 331, 337, 347, 349, 353,
359,
367, 373, 379, 383, 389, 397, 401, 409, 419,
421,
431, 433, 439, 443, 449, 457, 461, 463, 467,
479,
487, 491, 499, 503, 509, 521, 523, 541, 547,
557,
563, 569, 571, 577, 587, 593, 599, 601, 607,
613,
617, 619, 631, 641, 643, 647, 653, 659, 661,
673,
677, 683, 691, 701, 709, 719, 727, 733, 739,
743,
751, 757, 761, 769, 773, 787, 797, 809, 811,
821,
823, 827, 829, 839, 853, 857, 859, 863, 877,
881,
883, 887, 907, 911, 919, 929, 937, 941, 947,
953,
967, 971, 977, 983, 991, 997,
End
of the program!
3. Оператор "продължавам" (The continue Statement) . Този оператор е подобен на break, но за разлика от него управлението на програмата се предава на първия ред на цикъла, а не на първия ред след цикъла, както прави break. Ето един пример, който илюстрира употребата на continue.
float
dividend, divisor;
char
ch;
do
{
cout << "Enter dividend: ";
cin >> dividend;
cout << "Enter divisor: ";
cin >> divisor;
if (divisor == 0)
// if user error,
{
cout << "Divisor can't be zero\n";
continue;
// go back to top of loop
}
cout << "Quotient is " << dividend / divisor;
cout << "\nDo another (y/n)? ";
cin >> ch;
} while(ch != 'n');
При делител (divisor), равен на нула, не е възможно делене, затова на екрана се изписва предупредителен надпис "Divisor can't be zero" и програмата преминава в началото на цикъла, без да извърши деленето.
Често се появява необходимост от използването на continue и break в програмите и употребата им прави кода по-прегледен -- напълно е възможно с операторите if-else или други оператори да се постигне същия резултат както с break или continue, но разбираемостта на кода намалява драстично: сравнете тези два примера с примерите в настоящия текст.
4. Оператор ключ (The switch Statement). Това е конструкция за взимане на решения, които се основават на стойността на една променлива. Структурата на switch ключа е следната:
switch
( <switch variable> )
{
case <constant expression 1> : <statement 1>; [break;]
case <constant expression 2> : <statement 2>; [break;]
case <constant expression 3> : <statement 3>; [break;]
...
case <constant expression K> : <statement K>; [break;]
default : <statement>;
}
Ако стойността на променливата <switch variable> е равна на стойността на някой от изразите <constant expression k> то се изпълнява съответният оператор <statement k>: това е вярно при наличие на операторите break;, иначе се изпълняват всички редове след оператора, избран по условието <constant expression K>. Ако стойността на променливата <switch variable> не отговаря на нито една от стойностите в изразите <constant expression k>, то се изпълняват операторите в твърдението <statement>;, намиращи се след default клаузата. Последната клауза не е задължителна, и ако я няма и стойността на променливата <switch variable> не отговаря на нито една от стойностите в изразите <constant expression k>, то програмата продължава изпълнението си след последната голяма скоба на конструкцията switch.
Ето един пример от втората лекция от програмата за управление на полетите
switch (type)
{
case AIRLINER : ceiling = 35000; break;
case COMMUTER : ceiling = 20000; break;
case PRIVATE : ceiling = 8000;
}
Ако променливата type има стойност AIRLINER, то се изпълнява присвояването ceiling = 35000; и операторът break;. Ако променливата type има стойност COMMUTER, то се изпълнява присвояването ceiling = 20000; и операторът break; и т.н. Обърнете внимание, че при последния случай (case) няма нужда от оператора break.
! Изпускането на break води до много неприятна логическа грешка. Това е много често срещана грешка при хората, които са програмирали преди това на Pascal, където при съответната конструкция case няма нужда от break.
5. Условният оператор "? : , " (The Conditional Operator). Това е оператор който замества цяла if-else конструкция както показва следният пример за определяне на по-малкото от две числа.
if
(x < y)
min = x;
else
min = y;
Тази конструкция може да се замести само с един ред, а именно
min = (x < y) ? x : y;
В скоби е дадено условието, което се проверява, а след питанката стоят двете стойности (променливи, изрази), които трябва да приеме променливата min. Ако е вярно условието преди питанката min приема стойността след питанката (в примера - стойността на x), а ако не е вярно - стойността след двоеточието (в примера - стойността на y).
Интересно е, че в програмата Excel на Microsoft има същата функция по подобие на условният оператор "? : , ". Но нейното име е IF и е със следния синтаксис: IF(logical_test, value_if_true, value_if_false).
Литература
[1] Robert Lafore; C++ Interactive Course. Waite Group Press, Macmillan Computer Publishing, 1996.
Автор: Проф. Процесор Аритметиков
[ това е материал от брой 15 от януари 2008 г. на списание "Коснос" www.kosnos.com ]
Keywords: С++,
OOP programming , C++ , Classes , Inheritance , Reusability , Creating
New Data Types , Polymorphism and Overloading
Ключови думи: клас
, обект, обектно ориентирано програмиране , полиморфизъм switch if else
?