Потпрограми / Функции

Прашања:

1. Што се потпрограми,која е нивната задача?
2. Која  е разликата помеѓу функции и процедури? Кога се користи функција, а кога процедура.
3. Какви можат да бидат функциите
4. Напиши 3 програми со користење на математички функции
5. Која е разликата помеѓу прототип и дефиниција на функција? Од што се состои прототипот
6. Што се пишува во header на функцијата?
7. Од што е составено телото на функцијата?
8. Дали имињата на параметрите мораат да бидат исти во прототипот, дефиницијата и повикот на функцијата ?
9. Ако функцијата не враќа никаква вредност, како ја декларираме?
10.Ако не декларираме повратен тип на функцијата, тогаш се подразбита дека е од тип ? 
11.Објасни за формални и вистински параметри ( пример)
12.Објасни ги повикувањето на функцијата по вредност и повикувањето на функцијата по референца! 
13.Во кој случај се користи повикување на функцијата по референца?

Во секоја сложена програма може да се издвојат низа наредби кои чинат логичка целина и извршуваат одредена работа. Таквите издоени самостојни целини се  нарекуваат потпрограми Задачата на потрограмите е да се подобри структурата на програмата .

При структурното програмирање се користат две техники на програмирање:

  • ·       прoграмирање одгоре надолу (анг. top-down programming) и
  • ·       мoдуларно  прoграмирање (анг. modular programming).

Користејќи ги овие техники задачата се дели (расчленува) на помали и поедноставни задачи, кои лесно се програмираат. Секоја подзадача може да се разгледува како посебна целина, односно за секоја подзадача може да се напише посебна програма која се нарекува потпрограма (sub- program).

Со првата техника се врши разделување (расчленување) на задачата (проблемот) на поедноставни задачи-подзадачи, а со втората на модулите. Притоа, секој модул има точно одреден почеток и крај, како и ограничена должина. Секој модул реализира посебна функција. Модулите можат да се менуваат и да се тестираат независно еден од друг, а во програмата се 
повикуваат според зададен редослед.

Потпрограмите што најчесто се користат при програмирањето, наречени стандардни потпрограми, се зачувани во посебни програмски модули кои се составен дел на соодветниот програмски јазик. Кога е потребно, овие потпрограми може да се повикаат и да се извршат во главната програма. Притоа доволно е да се знае што работи потпрограмата, не е многу важно како тоа го работи.

Подалгоритам
Секој модул може да се разгледува како посебна целина, независна од другите, и за секој од нив може да се напише алгоритам − подалгоритам.

Суштината на подалгоритмите е во тоа што тие можат да се користат во различни алгоритми, а и на повеќе места во ист алгоритам. Тоа е овозможено со примена на т.н. формални (подалгоритам) и вистински аргументи (алгоритам).
Формалните (вистинските) аргументи можат да бидат влезни и излезни. Тие се ставаат во зграда по името на подалгоритмот – листа на формални (вистински) аргументи.

Општ запис на еден подалгоритам:


ИмеНаПодалгоритмот (листа на формални аргументи);
Според бројот на излезни формални аргуменит постојат два вида подалгоритми

  • функциски
  • процедурални

1. Функциски подалгоритми
Функциските подалгоритми, наречени функции (анг. function), имаат само еден излезен формален аргумент, а можат да имат еден или повеќе влезни аргументи.

Излезниот параметар се нарекува излезен формален параметар, додека влезните параметри, кои можат да бидат и повеќе, се нарекуваат влезни формални параметри .
Влезните формални параметри се ставаат во заграда по името. За да одлучиме дали за една подзадача може да се напише функциски подалгоритам, потребно е да се одговори на следното прашање:

0      Дали подалгоритмот за подзадачата има една излезна вредност?

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

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

    1.  Од кои аргументи директно зависи резултатот на подзадачата?

    2. Од кој тип е излезниот резултат на подзадачата?

Одговорот на првото прашање ќе ни укаже на тоа: кои, колку и каков тип влезни формални аргументи ќе има во листата на формални аргументи.

Одговорот на второто прашање ќе го одреди типот на излезниот резултат од функцискиот подалгоритам.

Пример на задача каде решението не може да се добие со функциски подалгоритам: Да се подредат три броја по големина. Одговорот на основното прашање (ред. бр. 0) е НЕ, затоа што во задачата се бара влезните податоци (трите броја) да бидат и излезни резултати, пак три броја, само подредени по големина. Затоа решението не можеме да го добиеме со функциски подалгоритам.

Општа синтакса на еден функциски подалгоритам:


Тип ИмеНаПодалгоритмот(влезни аргументи);


Повикување на подалгоритам :
променлива = ИмеНаПодалгоритмот(листа на вистински аргументи); или 
ИмеНаПодалгоритмот(листа на вистински аргументи)

Листата на вистински аргументи, во однос на листата формални аргументи, мора да биде со:
• ист број на аргументи
• ист редoслед на аргументи
• ист тип на аргументи.

Предности при користење на функции
  • пократок запис на програмата
  • поедноставно одржување на програмата
  • можност за користење претходно развиени функции
  • се користат постоечки функции како градбени блокови за новите програми
  • се одбегнува повторување на еден ист код на различни места на програмата
  • заштеда на мемориски простор
Подалгоритмите кои имаат повеќе излезни аргументи се нарекуваат процедурални подалгоритми или процедури . 

Функции во C++

Кај сите програми кои ги разгледавме досега, наредбите ги пишувавме во една функција - main(). Тоа е основниот дел кој го содржат сите програми - main() e првата функција која се повикува при стартот на програма напишана во  C++. Затоа функцијата mаin се нарекува и влезна точка. Ако нема функција main, преведувачот јавува грешка.

За разлика од некои програмски јазици (на пр. Pascal) кои разликуваат процедури и функции, во C++ се користат само функции. Функциите претставуваат множества наредби кои се извршуваат при секој нивен повик.

Повик на одредена функција претставува наредба до процесорот за запирање на тековното извршување на наредби, запишување на моментната локација во програмата и повикување на соодветната функција. По завршување на повиканата функција, програмата продолжува со извршување од местото од каде е функцијата повикана.

 Можно е:

- User-defined Function: Created by users да се напишат сопствени функции па тие да се користат во програма (кориснички функции) или
- Standard Library Functions: Predefined in C++ да се користат веќе постоечки функции кои се подготвени за користење и зачувани во библиотеки ( библиотечни вградени функции

Голем број на математички операции и трансформации се веќе имплементирани во програмскиот јазик C++ - во вид на функции кои  може да се повикуваат

За да може да ги користиме овие функции, потребно е вклучување на соодветната датотека од библиотеката на C++ која ги содржи нивните дефиниции 

 ( користење на директивата    #include <cmath> )

Основни математички функции – библиотека cmath


#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double x = 3.0, y = 2.7;
cout << pow(2.0, 3.0) << endl; //pechati '8'
cout << sqrt(4) << endl; //pechati '2'
cout << fabs(-7.123) << endl; //pechati '7.123'
cout << log(x) << endl; //pechati '1.09861'
cout << log10(x) << endl; //pechati '0.477121'
cout << floor(y) << endl; //pechati '2'
cout << ceil(y) << endl; //pechati '3'
return 0;
}

 Задача: Да се пресмета y= x3,зa  x=2, x=3

 





      Exercise:

Use the correct function to print the highest value of x and y.

int x = 5;
int y = 10;
cout << (x, y);

Start the Exercise

Функциите се создаваат надвор од главната ( main ) функција. Во  main функцијата се повикуваат. Може да се сместат пред или после main функцијата.

Ако функцијата се дефинира пред главната ( main) функција тогаш таа е подготвена за користење. Доколку функцијата ја дефинираме после  main функцијата тогаш истата мора да се декларира - мора да се користи прототип на функцијата (тоа е првиот ред од функцијата/header  кој содржи:  тип на податок кој ја враќа функцијата, име на функцијата и листа на параметри).

Кога компалјерот  во програмскиот код наиде на име на функција која е дефинирана после main, тој знае согласно прототипот дека функцијата постои, ја бара и извршува.  

Видови на функции

Во С++ постојат 2 вида на функции:

  • Функции кои враќаат вредност
  • Функции кои не враќаат вредност (void)
Секоја функција има свое име и тело претставено во загради { }. Функциите кои не враќаат вредост мора да започнат со клучниот збор void, додека функциите кои враќаат некоја вредност мора да имаат return statement која враќа вредност при повикување на функцијата. Секоја функција може да прима еден или повеќе аргументи или да не прима ниеден.

Function Declaration and Definition

A C++ function consist of two parts:

  • Declaration: the function's name, return type, and parameters (if any)
  • Definition: the body of the function (code to be executed)



Декларирање на функција

 Како и варијаблите и функцијата треба да се декларира, т.е да се најави .  Општ облик на декларирање на функција

tip    ime_na_funkcijata ( lista na parametri);      // прототип завршува со  ; )                                                                         

·       tip – каква вредност враќа функцијата како резултат (int, float,  char, bool)  (типот на податокот што функцијата го враќа (повратна вредност) го определува типот на функцијата.)

·       ime – име на функцијата (го бира корисникот и треба да  асоцира на тоа за што е наменета функцијата)

·       tip_parametri – (int, float …)

Прототипот на функцијата ја декларира истата пред нејзината дефиниција . Врз оснoва на прототипот компајлерот знае кој е повратниот тип на функцијата, колку аргументи има и кој тип се .


Единствена функција која не бара прототип е функцијата main (), истата е вградена во јазикот

Пример :

float  volumen_na_kvadrat  (float a, float b, float c ); 

Кога се декларира некоја функција, треба да се одговори на следниве прашања:

  • ·       колку параметри (влезни податоци) има функцијата,
  • ·       од кој тип се тие податоци и
  • ·       каков тип ќе има резултатот (повратната вредност).
Three ways exist to declare a function: 
• Write your prototype into a file, and then use the #include directive to include it in your program.
• Write the prototype into the file in which your function is used. 
• Define the function before it is called by any other function. When you do this, the definition acts as its own prototype.

Пример:

float koren(float x) ; − реална функција со реален аргумент
int pomal(int, int) ; − целобројна функција без имиња на аргументити
int g() ; − целобројна функција без аргументи
int f(int a, b); − неправилно , треба int f(int a, int b)
long plostina (long a, long b); − тип на резултатот long
void pecati(int broj) ; − тип на резултатот void

 Дефинирање на функцијата

Секоја функција се состои од  низа наредби кои одредуваат што и како функцијата работи. Оваа низа се нарекува тело на функцијата. Телото започнува со { , a завршува со }. Секоја наредба завршува со ;  Во еден ред можат да се запишат и повеќе наредби раздвоени со знакот ;

Функцијата завршува со return по што се запишува податокот кој функцијата го враќа како резултат од работата.

Пример:

Funkcija volumen_na_kvadrat


float volumen_na_kvadrat (float a, float b, float c )
{
     float v;
     v=a*b*c;
     return v;
}

- дефиницијата на функцијата мора да е во соглаcност со нејзиниот прототип
- ако функцијата има параметри тие мора да имаат тип , име
- параметрите се одвојуваат со запирка
- ако функцијата враќа вредност се користи клучниот збор return
- ако функцијата не враќа вредност таа се декларира како void

Повикување на функцијата

Функцијата се извршува така што се повикува во главната програма . Се наведува нејзиното име и аргументите запишани по истиот редослед како при декларирањето.

Ime _na_funkcija (листа на аргументи )

 Пример:

Повикување на функцијата volumen_na_kvadrat

vol = volumen_na_kvadrat (x,y,z) 

Пример :

#include <iostream>
using namespace std;
int max(int a, int b); //prototip (so iminja na parametri)
int min(int , int); //prototip (bez iminja na parametri)
int main()
{
cout << max(3, 4) << endl; //pechati '4'
cout << min(2, 1) << endl; //pechati '1'
return 0;
}
//definicija na max(int a, int b)
int max(int a, int b)
{
if (a > b)
return a;
return b;
}
//definicija na min(int a, int b)
int min(int a, int b)
{
if (a < b)
return a;
return b;
}

Вежба:

Креирај функција со име  myFunction и повикај ја во главната ф-ја main().

void () {
  cout << "I just got executed!";
}

int main() {  
  ;
  return 0;
}

Start the Exercise

Example

int main() {
  myFunction();
  return 0;
}
void myFunction() {
  cout << "I just got executed!";
}
// Error
Try it Yourself »

Предавање на вредностите во функцијата. Аргументи и параметри

Функциите се повикуваат со наведување на нивните аргументи – вредности кои им се потребни за да ја извршат својата задача.

Аргумент на функција претставува вредност (константа, променлива или израз) со која се повикува одредена функција. Функцијата може, но не мора да има аргументи

Параметар претставува променлива наведена во декларацијата и во заглавјето на истата таа функција која ја прифаќа вредноста на аргументот.

Значи вредностите на аргументите во функцијата се предаваат преку нејзините параметри.





Пример:  Собирање на два броја
 Пример за void функција
Објасни !  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;
int f1(int a, int b, int c)
{
a = a+1;
b = b-1;
c = c + (a*b);
return c;
}
int main()
{
int a=3, b=2, c=5;
cout << f1(1, 1, 1) << endl; //pechati '1'
cout << f1(a, 2, 0) << endl; //pechati '4'
cout << f1(a, b, c) << endl; //pechati '9'
//vrednostite na a, b i c se nepromeneti
cout << a << " " << b << " " << c << endl; //pechati '3 2 5'
return 0;
}

#include <iostream>
using namespace std;
int soberi(int a, int b)
{
cout << "2 ";
int r = (a+b);
return r;
}
//(x+x)*(y+y)
int mnozenje(int x, int y)
{
cout << "4 ";
int p = soberi(x, x);
int v = soberi(y, y);
return (p*v);
}
void ispechatiKraj()
{
cout << "Kraj na programata." << endl;
}
int main()
{
int a=4, b=4;
cout << "1 ";
int rezultat1 = soberi(3, 5);
cout << "3 ";
//presmetaj (a+a)*(b+b) + 1
int rezultat2 = mnozenje(a, b) + 1;
cout << "5 " << endl;
//dosega, izlezot od programata e '1 2 3 4 2 2 5'
cout << rezultat1 << endl; //pechati '8'
cout << rezultat2 << endl; //pechati '65'
cout << soberi(3, soberi(1, 2) + 1) << endl; //pechati '2 2 7'
//ispechati 'Kraj na programata.'
ispechatiKraj();
return 0;
}

Напишете програма која ќе го пресметува збирот на два дадени броја. Ако двете вредности се исти, тогаш вратете го нивниот троен збир.
Примерок за внесување
1, 2
3, 2
2, 2
Излезен примерок:
3
5
12 исти
Решение:  
#include <iostream>
using namespace std;
int test(int x, int y)
{ int a,b;
if (x == y)
return ((x + y)*3) ;
else
return (x + y);
}
int main()
{
cout << test(1, 2) << endl;
cout << test(3, 2) << endl;
cout << test(2, 2) << endl;
return 0;
}



Предавање аргументи по вредност и по референца

Предавање аргументи по вредност

При повикување функција, аргументите во функцијата стандардно се предаваат по вредност – ваков начин на повикување се нарекува повикување по вредност

Бидејќи параметрите на функцијата претставуваат локални променливи (се креираат со повикување на функцијата и ги снемува кога ќе се изврши наредбата return), промените кои се прават врз параметрите не влијаат на промена на аргументите

Ова значи дека не постои начин на кој функцијата може да ги промени вредностите на аргументите. 

Така, на пр. не е можно да се направи функција за замена на два броја со повикување по вредност. Променливите ќе се заменат во функцијата, а во главната програма ќе останат исти. 


void swap(int x, int y)
{
   int temp;
   temp = x; /* save the value of x */
   x = y;       /* put y into x */
   y = temp; /* put x into y */
}

Предавање аргументи по референца

Во ваквите случаи се користи повикување по референца – во функцијата се пренесува адресата на променливата, а не нејзината вредност. На тој начин, со промена на вредноста на параметрите, директно се менуваат и вредностите на аргументите. 

Кога е потребно аргументите да се предадат по референца, во заглавјето на функцијата, пред имињата на параметрите се става знакот & (ampersand). 

Пример :    int   &a       или   int&  a 

Разлика

1. пренос по вредност: (pass-by-value)

·       вредноста на аргументот се копира во параметарот на функцијата /  локалните параметри на функцијата се копии на оригиналните (вистинските ) параметри кои се пренесуваат /

·       измените на параметрите немаат никаков ефект на аргументите кои се користат за повикување на функцијата  / локалните променливи не ги менуваат вистинските параметри /

·       повикување по вредност е default  начин на пренос на параметри

 2. пренос по референца  ( pass-by-reference)

во параметарот се копира адресата, а не вредноста на аргументот / локалните параметри на функцијата се референци (покажуваат) на мемориската локација на оригиналните (вистинските ) параметри кои се пренесуваат /  

параметрите претставуваат референци до аргументите, а не нивни копии

·       промените на параметарот , го менуваат и аргументот  / измените на овие променливи во функцијата влијаат, ги менуваат вистинските параметри

·       не се прави копија на променливите, но памети каде и кога е складиран податокот така што се заштедува на време и простор.


#include <iostream>
using namespace std;
void reshi(int x, int y, int &sob, int &odz, int &mnoz)
{
sob = x+y;
odz = x-y;
mnoz = x*y;
}
int main()
{
int a = 30, b = 4;
int s, o, m;
reshi(a, b, s, o, m);
cout << s << " " << o << " " << m << endl; //pechati '34 26 120'
return 0;
}

 ППример: Функција за замена на вредностите на две променливи

# include < iostream>

using namespace std;

 // prototip na Функција за замена на вредностите на две променливи

void zameni(int &x, int&y);

 int main()

{ int a,b;

cout<<"vnesi dva broja"<< endl;
cin>>a>>b;

zameni(a, b);

cout<<"novite vredvosti se "<<a<<" "<< b;
return 0; }

void zameni(int& x, int& y) // x i y se parametri
 { int t;
   t=x; // vrednosta na x se stava vo privremena promenliva t
   x=y; // vrednosta na y se stava vo promenlivata x
  y=t; // vrednosta na t se stava vo promenlivata y
}

#include <iostream>
using namespace std;
int f1(int &t, int u, int v)
{
t = t+1;
u = u-1;
v = v + (t*u);
return v;
}
int main()
{
int a=3, b=2, c=5;
cout << f1(a, b, c) << endl; //pechati '9'
//vrednosta na a e promeneta
//vrednostite na b i c ostanaa nepromeneti
cout << a << " " << b << " " << c << endl; //pechati '4 2 5'
return 0;
}

Доколку сакаме на функцијата да и предадеме голема структура на податоци, но не сакаме функцијата да може да ги промени вредностите кои се чуваат во структурата, во тој случај, најдобро решение е аргументите да ги предадеме по т.н. константна референца (референца која не дозволува промена на вредноста на аргументот). Во C++, тоа се прави така што, во декларацијата на функцијата, се додава клучниот збор const - пред името или типот на параметарот. Нормално, бидејќи се работи за референци, задолжително е наведување и на знакот '&'.


#include <iostream>
using namespace std;
int f1(int const &x, int const &y)
{
x = x+1; //greshka, nedozvoleno
y = y*3; //greshka, nedozvoleno
return x+y;
}
int f2(const int &x, const int &y)
{
x = x+1; //greshka, nedozvoleno
y = y*3; //greshka, nedozvoleno
return x*y;
}
int main()
{
int a = 30, b = 4;
cout << f1(a, b) << endl;
cout << f2(a, b) << endl;
return 0;

}


SCOPE  -  правила на делокруг / подрачје на важење

Правилата на делокруг (scope) на променливи се однесуваат на видливоста и животниот век на објектот.

Глобални и локални променливи

C++ овозможува декларирање на променливи на два начини:

  • -          глобално (надвор од која било функција или блок )
  • -          локално (во одредена функција или блок).

Променливите кои се декларираат надвор од било кој блок се нарекуваат глобални променливи, а променливите кои се декларираат во потпрограмите се нарекуваат локални променливи. Самото нивно име ни зборува и за областа во која со нив може да се оперира, т.е. кога тие се достапни (видливи).

Променливите кои се декларирани глобално може да се користат на која било локација во програмата (во која било функција или блок). Од друга страна, променливите кои се декларирани локално може да се користат само во функцијата/блокот во кој се декларирани (и тоа, откако ќе бидат декларирани).

Глобалните променливи се статички и тие живеат цело време додека се извршува програмата. 

И локалните променливи можат да се декларираат со зборот static. 

На пример: static int broj=n; 

                      static double iznos; 

Глобалните променливи живеат од моментот на нивното декларирање, до завршување на извршувањето на програмата. Иницијализација: само еднаш. (ако не се иницијализирани автоматски се иницијализираат на 0 - сите битови 0). Локалните статички променливи живеат од едно до друго повикување на функцијата. При новото повикување на функцијата тие ја имаат состојбата (вредноста) добиена во претходното повикување.

Локалните променливи живеат од моментот на извршување на дефиницијата, до крајот на извршување на блокот (функцијата) во која се дефинирани. Тие се автоматски by default. Автоматските променливи се декларираат со зборот auto.  

Пример :      auto int a=0 ; // isto so int a=0;             во програмскиот јазик C

vo   C++   не може да се користи горната декларацијa

    ( two or more data types in declaration of ‘a’) 

                      auto a=0.5 ;  // isto so float a=0.5        во програмскиот јазик C ++ 

automatic variable is a local variable which is allocated and deallocated automatically when program flow enters and leaves the variable's scope.

There are two separate concepts here 

  • scope, which determines where a name can be accessed - global and local
  • storage duration, which determines when a variable is created and destroyed - static and auto


Програма со која се демонстрира примена на статички и нестатички променливи 

#include <iostream>
using namespace std;
int a=0;              //Globalna promenliva
void increase()        // Se zgolemuva globalnata promenliva 
{  
   a++;
   cout<<"a= "<<a<<endl; 
}  
/*Se namaluva vrednosta na lokalnata promenliva  a.
Globalnata promenliva ja zadrzava svojata vrednost*/
void decrease()
{
   //Ova e nezavisna promenliva vo odnos na globalnata a.
   int a=0;
   a--; 
   cout<< "a= "<<a<<endl; 
}
void nestaticna()
{  //Nestaticnite promenlivi ne ja zadrzuvaat vrednosta pri povik na funkcijata
   int s=0;
   s++;
   cout<< "s= "<<s<<endl; 
}
void staticna()
{  /* Statickite promenlive ja zadrzuvat vrednosta pri povik na funkcijata
      Inicijalizacija e samo pri povik */
   static int s=0;
   s++;
   cout<<"s= "<< s<<endl;
}
int main()
{  //Lokalni promenlivi za funkcijata  main
   int i, x=3; 
   cout<< "x= "<<x<<endl;
   for(i=0; i<3; i++)
    {
   /*Promenlivata vo ovoj blok e nezavisna od nadvoresnata promenlive.
    Ovde se koristi promenliva x, lokalna za ovoj blok so vrednsot 5,
    dodeka orginalno x i ponataka ima vrednost  3*/
     int x=5;
     cout<<"x= "<<x<<endl;
    }
   // Vo ovoj prostor x ima vrednost 3
      cout<< "x= "<<x<<endl;
   increase();
   decrease();
   cout<< "a= "<<a<<endl;  //Globalna promenliva a
   // Demonstracija  na nestaticki promenlivi
   for(i=0; i<3; i++)
   nestaticna();
   // Demonstracija na staticki promenlivi
   for(i=0; i<3; i++)
   staticna();
   return 0; 
}
Излез 
x= 3
x= 5
x= 5
x= 5
x= 3
a= 1
a= -1
a= 1
s= 1
s= 1
s= 1
s= 1
s= 2
s= 3

Променливите кои се декларирани во внатрешноста на одреден блок или функција може да имаат исто име со друга променлива (која е дефинирана глобално или во блок). Во тој случај, променливата која е декларирана во внатрешноста (најлокалната променлива) ги крие останатите променливи со исто име. Доколку една локална променлива (promenliva) крие глобална променлива со исто име (promenliva), можеме да го искористиме операторот :: за да пристапиме до содржината на глобалната променлива (::promenliva). Иако C++ ги нуди овие можности, обидувајте се да избегнувате креирање на повеќе променливи со исто име (со тоа програмата станува посложена за разбирање).



#include <iostream>
using namespace std;
int promenliva; //globalna promenliva
int main()
{
int a = 10, b = 20, c = 30; //lokalni promenlivi
if (b > a)
{
int d; //lokalna promenliva
d = a+b; //vidliva samo vo ovoj blok
cout << d << endl; //pechati '30'
}
//promenlivata 'd' ne e vidliva tuka
int promenliva;
promenliva = 10; //lokalna promenliva
::promenliva = 100; //globalna promenliva
cout << promenliva << endl; //pechati '10'
cout << ::promenliva << endl; //pechati '100'
return 0;
}

Локални променливи

  • -          Променлви кои се декларирани во функцијата
  • -          Се користат само за наредби кои се во функцијата
  • -          Се креираат кога се влезе во нивниот простор (scope), a се уништуваат кога се излезе од него
  • -          Меморискиот простор е алоциран (одвоен) во текот на извршување на програмата

Глобални променливи

  • -          Променливи декларирани надвор од сите блокови
  • -          Видливи се на сите програмски нивоа
  • -          Се дефинираат само еднаш
  • -          Доколку не е доделена вредност се иницијализирани на почетна вредност 0
  • -          Пристапни се секаде во програмата

-          Меморискиот простор е резервиран пред извршување на програмата


 Бидејќи локалниот scope го поништува глобалниот, променлива со исто име како и глобална  променлива оневозможува пристап на глобалната променлива во локалниот простор



Пример за локални и глобални варијабли 





Грешка !!! 

#include <iostream>
using namespace std;
void Potprogram()
    int i=5;
   }     

int main()
{   Potprogram();
    cout <<i;
    return 0;
}


Што ќе се прикаже 

 b=4 a=1 b=2 c=3 

             11113311                      
 177117


#include <iostream>

float average( int num1, int num2 ); /* declaring function named average */

int main(){
	using namespace std;
	int num1, num2;
  	float c;
  	cout << "Enter first number" << endl;
  	cin >> num1;
  	cout << "Enter second number" << endl;
  	cin >> num2;
  	c = average( num1, num2 ); /* calling the function average and storing its value in c*/
  	cout << "Average is " << c << endl;
	return 0;
}

float average( int num1, int num2 ) /* function */
{
    	float avg; /* declaring local variable */
    	avg = ( num1 + num2 )/2.0;
   	return avg; /* returning the average value */
}


  • Функции кои не враќаат вредност (void)
    • без параметри 
    • # include <iostream>

      using namespace std;
      void prime();
      int main()

      { // No argument is passed to prime()
      prime();
      return 0;
      }
      // Return type of function is void because value is not returned.
      void prime()
      {
        int num, i, flag = 0;
        cout << "Enter a positive integer enter to check: ";
        cin >> num;
        for(i = 2; i <= num/2; ++i)
        {
           if(num % i == 0)
             {
                flag = 1;
                 break;
             }
         }
        if (flag == 1)
            cout << num << " is not a prime number.";
             else
             cout << num << " is a prime number.";
      }
    • со параметри 

    • #include <iostream>
      using namespace std;
      void prime(int n);
      int main()
      {
       int num;
       cout << "Enter a positive integer to check: ";
       cin >> num;
      // Argument num is passed to the function prime()
       prime(num);
       return 0;
       }
      // There is no return value to calling function. 
      void prime(int n)
      {
      int i, flag = 0;
      for (i = 2; i <= n/2; ++i)
      {
         if (n%i == 0)
        {
           flag = 1;
            break;
          }
      }
      if (flag == 1)
         cout << n << " is not a prime number.";
          else
          cout << n << " is a prime number.";
      }



  • Функции кои враќаат вредност
    • без параметри 

    • #include <iostream>
      using namespace std;
      int prime();
      int main()
      {
      int num, i, flag = 0;
      // No argument is passed to prime()
      num = prime();
      for (i = 2; i <= num/2; ++i)
       {
           if (num%i == 0)
         {
            flag = 1;
            break;
         }
      }
      if (flag == 1)
        cout<<num<<" is not a prime number.";
          else
         cout<<num<<" is a prime number.";
      return 0;
      }
      // Return type of function is int
      int prime()
      {
      int n;
      cout<<"Enter a positive integer to check: ";
      cin >> n;
      return n;
      }
    • со параметри 

    • #include <iostream>
      using namespace std;
      int prime(int n);
      int main()
      {
      int num, flag = 0;
      cout << "Enter positive integer to check: ";
      cin >> num;
      // Argument num is passed to check() function
      flag = prime(num);
      if(flag == 1)
      cout << num << " is not a prime number.";
      else
      cout<< num << " is a prime number.";
      return 0;
      }
      /* This function returns integer value. */
      int prime(int n)
      int i;
      for(i = 2; i <= n/2; ++i)
        {
         if(n % i == 0)
         return 1;
        }
      return 0;
      }
    The call by value method of passing arguments to a function copies the actual value of an argument into the formal parameter of the function. In this case, changes made to the parameter inside the function have no effect on the argument.

    By default, C++ uses call by value to pass arguments. In general, this means that code within a function cannot alter the arguments used to call the function. Consider the function swap() definition as follows.

    // function definition to swap the values.
    void swap(int x, int y)
    {
    int temp;
    temp = x; /* save the value of x */
    x = y; /* put y into x */
    y = temp; /* put x into y */
    return;
    }

    Now, let us call the function swap() by passing actual values as in the following example:

    #include <iostream>
    using namespace std;
    // function declaration
    void swap(int x, int y);
    int main ()
    {
    // local variable declaration:
    int a = 100;
    int b = 200;
    cout << "Before swap, value of a :" << a << endl;
    cout << "Before swap, value of b :" << b << endl;
    // calling a function to swap the values.
    swap(a, b);
    cout << "After swap, value of a :" << a << endl;
    cout << "After swap, value of b :" << b << endl;
    return 0;
    }

    When the above code is put together in a file, compiled and executed, it produces the following result:

    Before swap, value of a :100
    Before swap, value of b :200
    After swap, value of a :100
    After swap, value of b :200


    Which shows that there is no change in the values though they had been changed inside the function.

    The call by reference method of passing arguments to a function copies the reference of an argument into the formal parameter. Inside the function, the reference is used to access the actual argument used in the call. This means that changes made to the parameter affect the passed argument.

    To pass the value by reference, argument reference is passed to the functions just like any other value. So accordingly you need to declare the function parameters as reference types as in the following function swap(), which exchanges the values of the two integer variables pointed to by its arguments.

    // function definition to swap the values.
    void swap(int &x, int &y)
    {
    int temp;
    temp = x; /* save the value at address x */
    x = y; /* put y into x */
    y = temp; /* put x into y */
    return;
    }

    For now, let us call the function swap() by passing values by reference as in the following example:

    #include <iostream>
    using namespace std;
    // function declaration
    void swap(int &x, int &y);
    int main ()
    {
    // local variable declaration:
    int a = 100;
    int b = 200;
    cout << "Before swap, value of a :" << a << endl;
    cout << "Before swap, value of b :" << b << endl;
    /* calling a function to swap the values using variable reference.*/
    swap(a, b);
    cout << "After swap, value of a :" << a << endl;
    cout << "After swap, value of b :" << b << endl;
    return 0;
    }

    When the above code is put together in a file, compiled and executed, it produces the following result:

    Before swap, value of a :100
    Before swap, value of b :200
    After swap, value of a :200
    After swap, value of b :100

    The call by pointer method of passing arguments to a function copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. This means that changes made to the parameter affect the passed argument.

    To pass the value by pointer, argument pointers are passed to the functions just like any other value. So accordingly you need to declare the function parameters as pointer types as in the following function swap(), which exchanges the values of the two integer variables pointed to by its arguments.

    // function definition to swap the values.

    void swap(int *x, int *y)

    {

       int temp;

       temp = *x; /* save the value at address x */

       *x = *y; /* put y into x */

       *y = temp; /* put x into y */

         return;

    }

    To check the more detail about C++ pointers, kindly check C++ Pointers chapter.

    For now, let us call the function swap() by passing values by pointer as in the following example:

    #include <iostream>

    using namespace std;

    // function declaration

    void swap(int *x, int *y);

    int main ()

    {

       // local variable declaration:

       int a = 100;

       int b = 200;

        cout << "Before swap, value of a :" << a << endl;

       cout << "Before swap, value of b :" << b << endl;

     

       /* calling a function to swap the values.

        * &a indicates pointer to a ie. address of variable a and

        * &b indicates pointer to b ie. address of variable b.

        */

       swap(&a, &b);

       cout << "After swap, value of a :" << a << endl;

       cout << "After swap, value of b :" << b << endl;

       return 0;

    }

    When the above code is put together in a file, compiled and executed, it produces the following result:

    Before swap, value of a :100

    Before swap, value of b :200

    After swap, value of a :200

    After swap, value of b :100

Calling a function inside another


#include <iostream>

using namespace std;

int div_2(int a){
  if(a%2==0){
  	return 1;
  }
  else{
    return 0;
  }
}

void div_6(int b){
  if( div_2(b)==1 && b%3 == 0 ){
    cout << "Yes, the number is divisible by 6." << endl;
  }
  else{
    cout << "No, the number is not divisible by 6." << endl;
  }
}

int main(){
  div_6(12);
  div_6(25);
  return 0;
}

No comments: