Програмен език C++
(съдържание)

Част 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