Wednesday, September 23, 2015

STATIC OBJECTS IN FUNCTIONS


#include "stdafx.h"
#include "iostream"
#include "cstdlib"
#include "ctime"
using namespace std;
void LovesMeNot() {
       static bool LovesMe = false;
       LovesMe = !LovesMe;
       if (LovesMe){
             cout << "Loves Me!" << endl;
       }
       else{
             cout << "Loves Me Not!" << endl;
       }
}
int _tmain(int argc, _TCHAR* argv[])
{
       srand(time(0));
       int i = rand() % 10 + 1;
       while (i--)
             LovesMeNot();
       system("pause");
       return 0;
}


If we remove static from the declaration of variable LovesMe then the variable LovesMe would be on each entry in the function initialized to the same value (false) and every function call made to print the same message:
#include "stdafx.h"
#include "iostream"
#include "cstdlib"
#include "ctime"
using namespace std;

void LovesMeNot() {
       bool LovesMe = false;
       LovesMe = !LovesMe;
       if (LovesMe){
             cout << "Loves Me!" << endl;
       }
       else{
             cout << "Loves Me Not!" << endl;
       }
}

int _tmain(int argc, _TCHAR* argv[])
{
       srand(time(0));
       int i = rand() % 10 + 1;
       while (i--)
             LovesMeNot();
       system("pause");
       return 0;
}

Static object exists in the function during whole time of program execution, but they are available only inside the function in which they are declared. We can imagine these static objects that they are declared outside the function using special class static and can be only accessed only using function in which they are declared. That's why we use the same keyword static: the placement of this objects and global static objects is carried out in the same way so static objects will have the same initial value 0 if they are not initialized otherwise.


GLOBAL OBJECTS

Sometimes it's not good that change in variables have an effect outside of the function body. So let's assume that in some program we have three integer variables called day, month and year which contain data on current date. Function newmonth is responsible for changing the variable month but also for changing the variable year at the end of calendar year. So let's take a closer look at the following example:
#include "stdafx.h"
#include "iostream"
using namespace std;

int newmonth(int month, int year){
       if (++month > 12){
             month = 1;
             year++; //without effect
       }
}

int _tmain(int argc, _TCHAR* argv[])
{
       int day = 20;
       int month = 2;
       int year = 2015;
       month = newmonth(month, year);
       return 1;
}

It's obvious that the change in month, over the return value, will affect in program code. However the change in the year will not affect the function.
Some of you will try to solve this problem using pass by pointer or reference instead of pass by value. The function will then work with intermediaries so the returning value of function newmonth is not necessary. This type of solution only removes the problem partially. Let's illustrate this with following situation: let's say that function newmonth isn't called directly from the function main but instead over the function newday which change the day in the current date. It's obvious to conclude that the function newday will sometimes call the function newmonth.
int newmonth(int *month, int *year);
int newday(int *day, int *month, int *year);
In declaration of a function we will have additional arguments that are not necessary to the function and this procedure will make code more bulky and unreadable. Let's imagine how it would all look like for multiple level function calls. The unnecessary arguments will piled up and after couple of levels some functions would have dozen arguments.
The simple solution of this problem is that the objects which have to be used by a number of different function are declared as global variables. In order that some variable becomes global we need to declare this variable outside of the function body. It's possible that some variables are needed to other functions so we will define it before function main():
#include "stdafx.h"
#include "iostream"
using namespace std;
int newmonth(); //global variables
int day, month, year;
int newmonth(){
       if (++month > 12){
             month = 1;
             year++; //without effect
       }
       return month;
}
int _tmain(int argc, _TCHAR* argv[])
{
       int day = 24;
       int month = 2;
       int year = 2025;
       month = newmonth();
       cout << "The result:" << month << endl;
       system("pause");
       return 0;
}

Variables day, month and year are declared as global variables and now they are visible to the functions main() and newmonth() following the declaration of objects so we don't they don't have to separately carry as arguments in function call. Moreover in previous example there is no need that value of the month is returned as result.
Objects that are declared outside the function are visible in all of the functions whose definition follows in the file source code.
If we defined the global variables after the function main the compiler would give us an error saying that the variables are not declared in the function main(). The global declaration is also a definition. In fact all of the global objects are inserted in program code. They exist from start of the execution of the program until the end of the program.
If they are not explicitly initialized the global objects are initialized on value 0 while local objects which are not explicitly initialized they will take some accident value.
#include "stdafx.h"
#include "iostream"
using namespace std;
int global;

int _tmain(int argc, _TCHAR* argv[])
{
       int local;
       cout << global << endl;
       cout << local << endl;
       system("pause");
       return 0;
}

The program will not start because the error C4700: uninitialized local variable 'local' used. So if we remove cout << local << endl; the program code will be successfully built and the result would be 0.
It's obvious to conclude that using global variables we make easy access to them but that also means that they are in danger from uncontrolled changes inside different functions.
IMPORTANT: Global variables have to be used as less as possible.
The data which have to be available to every function but they must not be changed (universal mathematical of physical constants) are declared as global constants by adding modification const before the type declaration.
Global objects can have two located class and these classes are:
-          External and
-          Static
If program code extends over several modules, global objects that are declared on previously described way will be visible to every module. More modules can use the same object provided that this object can be defined exclusively in one module. In other modules object needs to be only declared not defined. The declaration shall be carried out so that in the front of the name of the object we put the key word extern:
extern int variable_in_second_module;
Objects that are declared with extern have external linkage which means that they are available to other modules during linkage. If nothing is specified by default is that this is external declaration and definition.
Some of the objects can be useful only inside one module. That objects can be static which opens the possibility that the other modules declare the objects with same name. This objects are local for module and have internal linkage. Object can be static if we put before the declaration of the variable word static:

static int m = 9;