Програмен език C++

Част 11

Функции с аргументи

(съдържание)

В част пета се спряхме на функциите на класа, но разгледаните досега функции извършваха строго предопределени операции, т.е. операции, които не могат да се повлияят от потребителя. Това бе така, защото функциите бяха дефинирани без списък от аргументи. В общия случай програмистът се нуждае да изпрати допълнителна информация на функцията при нейното извикване. Това се извършва с така наречените аргументи.

1. Събиране на две комплексни числа. Нека продължим с примера от предишния материал и да създадем функция на класа complex_number, която към дадено комплексно число да събира друго. Първото число (което се променя) е самият представител на класа, т.е. конкретният обект, а второто число ще е аргумент на функцията на класа. Следният код решава този проблем:

// complex2.cpp
// a class that models a complex number data type

#include <iostream.h>
#include <conio.h>               //for getche()

class complex_number
{
  private:
    float real;          // real part
    float imaginary;     // imaginery part
  public:
    void set()
    {
      char dummy;        // for comma

      cout << "Enter number (format Re, Im): ";
      cin >> real >> dummy >> imaginary;
    }

    void display()
    {
      cout << '('
           << real       // real part
           << ','
           << imaginary  // imaginary part
           << ')';
    }

    void add(complex_number compl_num)
    {
      real += compl_num.real;
      imaginary += compl_num.imaginary;
    }

};  // class complex_number

void main()
{
  complex_number c1, c2; // create two complex_number variables

  // enter c1
  cout << "For c1, ";
  c1.set();       // set c1

  // enter c2
  cout << "For c2, ";
  c2.set();       // set c2

  // add c2 to c1 and save the result into c1
  c1.add(c2);

  // show the addition result
  cout << "\nc1 + c2 = ";
  c1.display();   // display c2

  // stop the flow on the monitor
  getch();

}  //end main

Функцията add има следната декларация void add(complex_number compl_num). Единственият аргумент на функцията е compl_num, и той е от тип complex_number. В тялото на функцията се извършват две присвоявания:

  real += compl_num.real;
  imaginary += compl_num.imaginary;

Не сте забравили, че операторът += означава, че към операнда в лявата му част (в случая real) се прибавя операнда от дясната му страна (в случая compl_num.real) и получената стойност се присвоява на операнда в лявата част (в случая real).

Фактически се променят двете променливи на обекта (real  и imaginary), чиято функция се извиква. Самото извикване на функцията за даден обект се извършва с оператора, наречен class member access operator (вижте част пета), който се изписва с една точка:

c1.add(c2);

Това означава, че променливите (real  и imaginary) на обекта c1 (комплексно число c1) ще бъдат увеличени с променливите (real  и imaginary) на  обекта c2 (комплексно число c2). Обаче, променливите на обекта c2 няма да се променят.

По същия начин може да се декларира и дефинира функция за изваждане на едно комплексно число от друго.

  void subtract(complex_number compl_num)
  {
    real -= compl_num.real;
    imaginary -= compl_num.imaginary;
  }

Няма никаква принципна трудност да напишем и функции за умножаване и делене на дадено комплексно число с друго - припомнете си формулите от предишния материал. Ето функцията за умножение:

  void mult(complex_number compl_num)
  {
    complex_number cn;

    cn.real = real;
    cn.imaginary = imaginary;

    real = cn.real*compl_num.real - compl_num.imaginary*cn.imaginary;
    imaginary = cn.real*compl_num.imaginary + compl_num.real*cn.imaginary;
  }

Например (1,2)x(3,5) дава (-7,11). В тялото на функцията бяхме принудени да създадем временна променлива cn, в която първо да съхраним обекта, чийто функция се извиква. Това бе необходимо защото в първия ред на присвояванията (real = ...), реалната част на обекта (real) се променя, а пък тази част ни трябва в следващото присвояване (imaginary = ...). Написването на функция за делене на дадено комплексно число с друго остава за домашна работа.

Да обобщим наученото дотук за функциите на класа с аргументи:

1. Аргументът на функцията на класа се дефинира както се дефинира променлива от даден тип, но това става в кръгли скоби след името на функцията.

void add(complex_number compl_num)  // ако следва тялото на функцията няма точка и запетая

2. В тялото на функцията всяко едно боравене с имена на променливи на класа означава, че боравим с променливите на обекта, с помощта на който сме извикали функцията на класа. В горните три функции (add, subtract и mult) това бяха real и imaginary на обекта c1, ако извикваме функцията с c1.add(c2);.

3. Това извикване става с точковия оператор от вида обект.функция(аргумент); В горния код това е

c1.add(c2);

4. Аргументът не се променя при така използваната схема за деклариране и дефиниция на функцията на класа. Променя се обектът, чиято функция се извиква. Т.е. в резултат на горния код ще се промени c1, но не и c2.

2. Отново за главната функция main като функция с аргументи. Всяка програма на C++ (както и тези на C) трябва да има главна функция, която се изписва в програмата така: main(). Изпълнението на програмата започва от първия ред в тялото на тази функция. В една програмата главната функция може да се дефинира да не връща никаква стойност - void main(). Но тази дефиниция може да се направи и така - int main(), което означава, че след изпълнение на програмата тя (програмата или по-точно нейната главна функция) връща числена стойност. Обикновено тази числена стойност показва дали програмата е работила без грешка или някаква грешка е прекъснала нейното изпълнение. Това е така, защото в зората на операционните системи (от DOS 3.00 до DOS 6.22) програмите можеха да се стартират в т.н. сериен режим, който се описваше в серийни файлове (batch files) с разширение .BAT, и тогава тази върната от main() стойност може да се обработва от серийния файл.

Ако искате да използвате вашата програма в серийни файлове или да я стартирате с набор от параметри след нея, то може да дефинирате главната функция по следния начин:

int main(int argc, char * argv[])

където argc е целочислено число, показващо броя на параметрите (command-line arguments) след името на програмата, argv  е масив от показатели към стрингове (array of pointers to strings, char *[]). Първият елемент на този масив, argv[0], е пълното име на директорията, от която програмата се стартира (full path name of the program being run), argv[1] е първият стринг подаден към програмат, argv[2] - вторият и т.н. argv[argc - 1] е последният, а argv[argc] съдържа NULL.

В част 5 е показан един по-конкретен пример за използване на тази функция.

(съдържание)

Литература

[1] Robert Lafore; C++ Interactive Course. Waite Group Press, Macmillan Computer Publishing, 1996.

Автор: Проф. Процесор Аритметиков

.
[ това е материал от брой 17 от март 2008 г. на списание "Коснос" www.kosnos.com ]

Keywords: С++,  OOP programming , C++ , Classes , Inheritance , Reusability , Creating New Data Types , Polymorphism and Overloading
Ключови думи: клас , обект, обектно ориентирано програмиране , полиморфизъм switch if else ?