void raise_salary(Employee& e, double
            by) 
      /* ЦЕЛ:  увеличава заплатата на даден
            служител 
         RECEIVES: e - служител,
            получаващ увеличение 
                  
            by - процент на увеличението 
      */ 
      {  double new_salary =
            e.get_salary() * (1 + by / 100); 
        
            e.set_salary(new_salary); 
      } 
      int main() 
      {  Employee harry("Hacker,
            Harry", 45000.00); 
         raise_salary(harry, 5); 
         cout << "New
            salary: " << harry.get_salary() << "\n"; 
         return 0; 
      }
| New salary: 47250 | 
--
      Формалният параметър Employee&
            e на
        функцията raise_salary е параметър-псевдоним
      на променливата harry от главната функция main.
      -- Промяната на стойността на параметъра-псевдоним e във функцията raise_salary води до промяна и на
      стойността на фактическия параметър (променливата) harry от функция main. 
      * Затова параметрите-псевдоними се наричат входно-изходни
      параметри - те "пренасят" данни от извикващата функция (main)
      към извиканата функция (raise_salary) и обратно.
*
      Използват се за да се избегне копирането - особено нежелателно,
      ако параметърът е обект, съдържащ много данни. 
      * Тъй като стойността на константния псевдоним не може да се
      променя, той не "пренася" данни от извиканата функция (print_employee)
      в извикващата функция (main). 
Пример: Функция ца
        отпечатване на данните на обект от тип Employee
       void print_employee(const
            Employee & e) 
      { 
       cout <<
            "Name:   " << e.get_name() 
           
            << "Salary: " << e.get_salary(); 
      } 
            int main()
            {  
                 Employee harry("Hacker, Harry", 45000.00); 
                 print_employee(harry);
                 return 0;
            }
       
| Параметри-променливи | Параметри-псевдоними | Константни псевдоними | 
| Входни параметри за функцията | Входно-изходни параметри за функцията | - | 
| Предаване на параметри чрез копиране | Предаване на параметри по адрес (не се копира) | 
          Предаване на параметри по адрес (не се копира) | 
        
| Стойността на параметъра може да се променя (фактическия
            параметър не се променя) | 
          Стойността на параметъра може да се променя (фактическия
            параметър се променя) | 
          Стойността на параметъра не може да се променя | 
| Фактически параметър може да бъде константа, променлива
            или израз (rvalue) | 
          Фактически параметър може да бъде само променлива (lvalue) | 
          Фактически параметър може да бъде константа, променлива
            или израз (rvalue) | 
        
** Област на действие на
        променливите (scope), глобални променливи
          
         * Ако едно и също име на променлива се използва в
      две функции,  то не съществува  връзка между двете
      променливи. 
      * Областта на действие на променлива, която е дефинирана в блока
        на функция, се простира единствено в рамките на тази
      функция.  
        
          Пример: Сложна лихва - променливи с едно и също име в две
        функциии.
    
// futval1.cpp 
      #include <iostream> 
      #include <cmath> 
      using namespace std;
double
            f_val(double i_bal, double p, int ny) /*дефиниции на параметрите-променливи i_bal,
            p и ny*/ 
      { 
        double r; /*дефиниция на променливата r в блока на
            функцията future_value*/ 
        r = i_bal*pow(1 + p/(12*100),
            12*ny); 
        return r; 
      } /*край
            на областта на действие на променливите i_bal, p, ny и r*/ 
      int main() 
      { 
       cout << "Interest rate in
            percent: "; 
       double r; /*дефиниция на променливата r в блока на
            функцията main*/ 
       cin >> r; 
       double bal = f_val(1000, r,
            10); /*дефиниция на
            променливата bal*/ 
       cout << "After 10 years,
            the balance is " << bal << "\n"; 
       return 0; 
      } /* край на областта на действие на
            променливите r и bal*/
В примера няма връзка между двете
      променливи с име r в
        двете функции future_value и main. 
      
      * Променлива, дефинирана в блок на функция, се нарича локална променлива.
      
      * Областта на действие на локална променлива е от мястото на
      дефинирането до края на блока, в който е дефинирана
      променливата (block scope). 
      * В тази област променливата е видима, т.е. може да бъде
      използвана. 
* Променлива, дефинирана извън
        блок на функция, се нарича глобална
        променлива. 
      * Областта на действие на глобална променлива е от мястото на
      дефинирането до края на файла, в който е дефинирана
      променливата (file scope). 
      * Досега са използвани глобалните променливи (обекти) cin и cout, които са дефинирани в
      заглавния файл iostream.h. 
Пример: Увеличаване на заплата с глобална променлина.
 // global.cpp 
      #include <iostream> 
      using namespace std; 
        
       #include "ccc_empl.cpp"
double annual_raise; /* дефиниране на глобална променлива */
 void
            raise_salary(Employee& e) 
      { double new_salary = e.get_salary()
                        
            *(1 + annual_raise/100);  /* използване на глобалната променлива */
        e.set_salary(new_salary);  
      } 
 int
            main() 
      {  Employee boss("Reindeer,
            Rudolf", 48000.00); 
         Employee harry("Hacker,
            Harry", 35000.00); 
         annual_raise = 5; /* използване на глобалната променлива */ 
         raise_salary(boss); 
         raise_salary(harry); 
         cout <<
            boss.get_name() << " " << boss.get_salary()
            << "\n"; 
         cout <<
            harry.get_name()<< " " <<
            harry.get_salary()<< "\n"; 
         return 0; 
      }
| Reindeer, Rudolf 50400  Hacker, Harry 36750  | 
        
string
            digit_name(int n) 
      /* ЦЕЛ:  превръща цифра в
            английското й име 
         ПОЛУЧАВА: n - цяло число
            между 1 и 9 
         ВРЪЩА:  името на n
            ("one" . . . "nine") 
      */ 
      {  if (n == 1) return "one"; 
         else if (n == 2) return
            "two"; 
         else if (n == 3) return
            "three"; 
         else if (n == 4) return
            "four"; 
         else if (n == 5) return
            "five"; 
         else if (n == 6) return
            "six"; 
         else if (n == 7) return
            "seven"; 
         else if (n == 8) return
            "eight"; 
         else if (n == 9) return
            "nine"; 
         return ""; 
      } 
      string teen_name(int n) 
      /* ЦЕЛ:  превръща цяло число
            между 10 и 19 в английското му име 
         ПОЛУЧАВА: n - цяло число
            между 10 и 19 
         ВРЪЩА:  името на n
            ("ten" . . . "nineteen") 
      */ 
      {  if (n == 10) return "ten"; 
         else if (n == 11) return
            "eleven"; 
         else if (n == 12) return
            "twelve"; 
         else if (n == 13) return
            "thirteen"; 
         else if (n == 14) return
            "fourteen"; 
         else if (n == 15) return
            "fifteen"; 
         else if (n == 16) return
            "sixteen"; 
         else if (n == 17) return
            "seventeen"; 
         else if (n == 18) return
            "eighteen"; 
         else if (n == 19) return
            "nineteen"; 
         return ""; 
      } 
      string tens_name(int n) 
      /* ЦЕЛ:  дава английското име на
            десетиците между 20 и 90 
         ПОЛУЧАВА: n - цяло число
            между 2 и 9 
         ВРЪЩА:  името на
            10*n ("twenty" . . . "ninety") 
      */ 
      {  if (n == 2) return "twenty"; 
         else if (n == 3) return
            "thirty"; 
         else if (n == 4) return
            "forty"; 
         else if (n == 5) return
            "fifty"; 
         else if (n == 6) return
            "sixty"; 
         else if (n == 7) return
            "seventy"; 
         else if (n == 8) return
            "eighty"; 
         else if (n == 9) return
            "ninety"; 
         return ""; 
      } 
      string int_name(int n) 
      /* ЦЕЛ:  превръща цяло число в
            английското му име 
         ПОЛУЧАВА: n - цяло
            положително число < 1000000 
         ВРЪЩА:  името на n
            (т.е. "two hundred seventy four") 
      */ 
      {  int c = n; /* оставащата за превръщане част */ 
         string r;  /* стойността на функцията */ 
         if (c >= 1000) 
         {  r = int_name(c /
            1000) + " thousand"; 
            c = c
            % 1000; 
         } 
         if (c >= 100) 
         {  r = r + " " +
            digit_name(c / 100) + " hundred"; 
            c = c
            % 100; 
         } 
         if (c >= 20) 
         {  r = r + " " +
            tens_name(c / 10); 
            c = c
            % 10; 
         } 
         else if (c >= 10) 
         {  r = r + " " +
            teen_name(c); 
            c = 0; 
         } 
         if (c > 0) 
            r = r
            + " " + digit_name(c); 
         return r; 
      } 
      int main() 
      {  int n; 
         cout << "Please
            enter a positive integer: "; 
         cin >> n; 
         cout <<
            int_name(n); 
         return 0; 
      }
| Please enter a positive integer: 20119  twenty thousand one hundred nineteen  | 
        
** Предусловия и
        макрос assert. 
          
         * Какво трябва да направи една функция, ако е
      извикана с неподходящ вход? 
    
 * Има два варианта - да завърши
      нормално или да прекъсне работата на програмата. 
      -- Първият вариант е подходящ, когато функцията може да върне нещо
      разумно на извикващата функция - напр. digit_name от
      предишния пример връща празен низ. 
      -- Стандартните аритметични функции прекъсват работата на
      програмата със съобщение за грешка. 
        
       * Едно решение на проблема е да се използва макрос assert,
      който прекъсва работата на програмата при грешка. 
      - Когато се тества програмата, той дава мястото на "грешката"
      (некоректни входни данни на функция) в текста на програмата. 
      - Когато програмата е готова, може да се изключи проверката
      на  assert с директива на
      препроцесора. 
      
Пример: Сложна лихва - макрос assert.
  // futval0.cpp 
      #include <iostream> 
      #include <cmath> 
      #include <cassert> 
      using namespace std;
| nkirov@cpp % c++ futval0.cpp nkirov@cpp % ./a.out Please enter the interest rate in percent: 10 After 10 years, the balance is 2593.74 nkirov@cpp % ./a.out Please enter the interest rate in percent: -10 Assertion failed: (p > 0), function future_value, file futval0.cpp, line 9. zsh: abort ./a.out  | 
        
Ако
        условието в assert е изпълнено, нищо не се случва. Ако обаче
        изразът има стойност false,
        програмата прекратява работата си със съобщение от макрос assert.