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.
Затова параметрите-псевдоними се наричат още входно-изходни
параметри - те "пренасят" информация от извикващата функция към
извиканата функция и обратно.
Използват
се за да се избегне копирането - особено нежелателно, ако
параметърът е обект, съдържащ много данни.
Тъй като стойността на константния псевдоним не може да се
променя, той не "пренася" информация от извиканата функция в
извикващата функция.
void print_employee(Employee const
& e)
{
cout <<
"Name: " << e.get_name()
<< "Salary: " << e.get_salary();
}
параметри-променливи | параметри-псевдоними | константни псевдоними |
входни параметри за функцията | входно-изходни параметри за функцията | - |
предаване на параметри чрез копиране | предаване на параметри по адрес | предаване на параметри по адрес |
стойността на параметъра може да се променя | стойността на параметъра може да се променя | стойността на параметъра не може да се променя |
фактически параметър може да бъде константа, променлива или израз | фактически параметър може да бъде само променлива | фактически параметър може да бъде константа, променлива или израз |
** Област на действие на
променливите, глобални променливи.
Ако едно и също име на променлива се използва в две функции,
то не съществува връзка между двете променливи.
Областта на действие на променлива, която е дефинирана в блока на
функция, се простира единствено в рамките на тази функция.
// 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.
Променлива, дефинирана в блок на функция, се нарича локална променлива.
Областта на действие на локална променлива е от мястото на
дефинирането до края на блока, в който е дефинирана променливата.
В тази област променливата е видима, т.е. може да бъде използвана.
Променлива, дефинирана извън блок
на функция, се нарича глобална
променлива.
Областта на действие на глобална променлива е от мястото на
дефинирането до края на файла, в който е дефинирана променливата.
Досега са използвани глобалните променливи (обекти) 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 с директива на
препроцесора.
// futval0.cpp
#include <iostream>
#include <cmath>
#include <assert.h>
using namespace std;
double
future_value(double initial_balance, double p, int nyear)
{ assert(nyear>=0 &&
p>=0);
return initial_balance*pow(1 +
p/(12*100), 12*nyear);
}
int main()
{ cout <<
future_value(1000,6,-5);
return 0;
}
fincalc.cpp:8: failed
assertion `nyear>=0 && p>=0' abnormal program termination |
Ако
условието в assert е изпълнено, нищо не се случва. Ако обаче
изразът има стойност false,
програмата прекратява работата си със съобщение от макрос assert.