Част 8. Операторите за управление (Simple Decisions)
В тази и следващата лекции ще разгледаме логическите оператори ако (if), ако-иначе(if-else),ключ (switch) и условния оператор " ?: , ", както и една специфична конструкция на if-else оператора.
1. Оператор if . Той има вида if ( <condition> ) <statement>;, където <statement> се изпълнява, ако условието <condition> е истина. В противен случай управлението на програмата преминава на реда следващ <statement>;. Например, следният израз проверява дали числото num е четно.
if
(num % 2 == 0)
cout << "The number " << num << " is even." <<
endl;
Обърнете внимание, че логическото условие е заградено с малки скоби, (num % 2 = 0), и след тях няма точка и запетая! Една от най-неприятните и труднооткриваеми грешки е да сложите точка и запетая след условието, както е направено в кода по-долу. Обърнете внимание, че този код е безсмислен и зебележете, колко трудно се забелязва символа ; след if (num % 2 == 0).
int
num = 3; // !!! ERROR HERE
!!!
if
(num % 2 == 0);
cout << "The number " << num << " is even." <<
endl;
В резултат на тази грешка изходът на екрана е неправилен и е следният:
The number 3 is even.
На следващия ред в правилния пример най-горе се изпълнява само едно твърдение, затова то завършва с точка и запетая. Ако искаме да изпълним няколко твърдения, то ги заграждаме с големи скоби, както това е направено в този пример:
if
(choice == 'l')
{
cout << "The plane is landing. ";
plane1.land;
}
След голямата скоба накрая на този код няма няма точка и запетая! Причината за това е, че самата скоба служи като разделител.
Операторът if много прилича на оператора while, но за разлика от него тялото му се изпълнява само веднъж, докато при вторият това изпълнение се повтаря, докато условието стане неистина.
2. Оператор if-else . Той има вида if ( <condition> ) <statement 1>; else <statement 2>;. Ако условието <condition> е истина се изпълнява <statement 1>, иначе - се изпълнява <statement 2>. Обърнете внимание, че отново условието е заградено в малки скоби и след тях, както и след else няма точка и запетая. Например, следната конструкция проверява дали числото num е четно или нечетно:
if
(num % 2 == 0)
cout << "The number " << num << " is even.";
// числото е четно
else
cout << "The number " << num << " is odd.";
// числото е нечетно
В този пример и двете твърдения не бяха заградени с големи скоби, защото са по едно след съответните ключови думиif и else, но в общия случай е необходимо използването на големи скоби, след които не се поставя точка и запетая. Например следните редове коригират датата, в зависимост от месеца и година:
// if it's Feb 28 and it's a leap year
if(
day == 28 &&
month == 2 &&
year%4 == 0 &&
year % 100 != 0)
{
day = 29;
// then the next day is the 29th
}
else
// otherwise,
{
day = 1;
// next day is March 1st
month = 3;
}
Не е необходимо твърдението day = 29; да бъде заградено с големи скоби, но лично аз винаги ги слагам, защото с тях кодът е по-прегледен.
Обърнете внимание, че условието след if бе съставено от няколко оператора за сравняване, свързани с логическия оператор и, &&. В това условие може да се сложи какъвто и да е логически израз, съставен от произволно число оператори за сравняване и логически оператори.
3. Включени един в друг оператори if-else (Nested if-else Statements) . Често е необходимо да се вземе поредица от решения, които се записват с поредица от if-else оператори. Най-общият вид на тази конструкция е
if
( <condition 1> )
<statement1>;
else
if ( <condition 2> )
<statement 2>;
else
<statement 3>;
Ако първото условие е вярно, то ще се изпълни първото твърдение, иначе програмата ще стигне до проверка на второто условие. Ако то е вярно, ще се изпълни второто твърдение, иначе програмата ще изпълни третото твърдение. Логиката на тези включени един в друг if-else оператори е, че else "принадлежи" към последния if, ако няма големи скоби, които да променят логиката на изпълнение на решенията. Обикновено и отмесването (indentation) на втория (после на третия и т.н.) if-else оператор показва логиката на управлението в програмата, което улеснява разчитането и. Но програмистът не бива да се подвежда по това отмесване, което няма никаква връзка с управлението на програмата, а е направено субективно от друг програмист. Ето един много конфузен пример:
if
(age > 2)
// if greater than 2
if (age < 18)
// and less than 18
cout << "\nChild"; // it's a
child
else
cout << "\nInfant";
// ERROR: inappropriate response
По отмесването на else оператора, човек може да се обърка, че ако възрастта не е по-голяма от две, програмата ще отпечата на екрана Infant, но истината е че при (age <= 2) нищо няма да се отпечата на екрана и програмата ще премине на реда след последния ред от този код. Защото else операторът "принадлежи" към последния if оператор. Докато при (age >= 18) програма ще изпише на екрана Infant. Правилно е следното отмесване при записа на тези програмни редове, които са и променени леко - cout << "\nAdult"; вместо cout << "\nInfant"; :
if
(age > 2)
// if greater than 2
if (age < 18)
// and less than 18
cout << "\nChild"; // it's a
child
else
cout << "\nAdult"; // it's
an adult
Обърнете внимание на промяната на "\nInfant" в "\nAdult", която отразява факта, че ако възрастта е по-голяма от 2 се проверява дали тя е по-малка от 18, и ако не е по-малка от 18 се изписва "възрастен" на екрана.
Както споменахме, скобите могат да променят логиката на взимането на решения. Ето как горния конфузен пример може да се коригира:
if
(age > 2)
// if greater than 2
{
// а brace is added
if (age < 18)
// and less than 18
cout << "\nChild"; // it's a
child
}
// а brace is added
else
cout << "\nInfant";
// it is OK now!
3. Един пример с оператори за управление. В част 4 на тази поредица бе дадена една елементарна програма с обекти, което управлява продажбата на хот-доци, взаимствана от курса по C++ на Лафоор [1]. Ето едно нейно подобрение, което се постига с използване на гореспоменатите оператори.
//
hotdog2.cpp
//
hot dog stand inventory database
//
uses while loop and if statement
#include
<iostream.h>
// for cout, cin, etc.
#include
<conio.h>
//for getche()
class
HotDogStand
// class specification
{
private:
int HotDogsOnHand;
// hot dogs on hand
int BunsOnHand;
// buns on hand
public:
void displayData()
// display hot dogs and buns
{
cout << "\n Hot dogs = " << HotDogsOnHand;
cout << "\n Buns = " << BunsOnHand;
}
void SoldOneDog()
// record sale of one dog
{
--HotDogsOnHand;
--BunsOnHand;
}
void initData()
// set initial quantities
{
cout << "\n Enter hot dogs on hand: ";
cin >> HotDogsOnHand;
cout << " Enter buns on hand: ";
cin >> BunsOnHand;
}
};
// end of HotDogStand class
/////////////////////////////////////////////////////////////
void
main()
{
char choice = 'x';
// user's letter choice
HotDogStand stand1;
// create hot dog stand object
// set initial data
cout << "\nInitialize data";
stand1.initData();
while(choice != 'q') //
loop until 'q' typed
{
cout << "\nEnter s to record sale, q to quit: ";
cin >> choice;
if(choice == 's') // if
user entered 's'
{
// then sell a dog
cout << "Selling a dog";
stand1.SoldOneDog();
}
} // end while
// display current data
cout << "\nSupplies on hand";
stand1.displayData();
// stop the flow on the monitor
getch();
} //end main
Ако сравните предишната версия с тази новата, ще забележите че спецификацията на класа HotDogStand е същата, а само е променена главната функция на програмата. Това е една от характеристиките на обектно-ориентираното програмиране -- написаните спецификации на класовете могат да се използват отново в други програми, които са подобрени версии на предишни. Тази ценна възможност на английски се нарича reusability - повторна използваемост.
Литература
[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
Ключови думи: клас
, обект, обектно ориентирано програмиране , полиморфизъм if else