Scope, Lifetime, and
More on Functions
Identifiers can be declared either inside a block (local variables) or outside a block (function names).
C++ has rules governing how a function may access parameters declared outside its own block.
A value-returning function returns a single result to the expression from which it was called.
We’ll look at writing user-defined value-returning functions.

Scope of Identifiers
Listing all of the places from which an identifier can be accessed legally is describing that identifier’s scope.
C++ defines several categories of scope for any identifier
Class scope. Postpone this until chapter 11.
Local scope. The scope of an identifier declared inside a block extends from the point of declaration to the end of that block.
Global scope. The scope of an identifier declared outside all functions and classes extends from the point of declaration to the end of the entire file containing the program code.

Global Variable Example
int gamma; // Global variable
int main()
{
    gamma = 3;
      .
      .
      .
}
void SomeFunc()
{
    gamma = 5;
     .
     .
     .
}

Local Definitions Take
Precedence Over Global Ones
void SomeFunc(float);
const int a = 17;      // A global constant
int b, c;      // Two global variables
int main()
{
    b = 4;      // Assignment to global b
    c = 6;               // Assignment to global c
    SomeFunc(42.8);
   return 0;
}

Local Definitions Take
Precedence Over Global Ones
void SomeFunc(float c)   // Prevents access to global c
{
    float b;           // Prevents access to global b
    b = 2.3;             // Assignment to local b
    cout << “a = “ << a;  // Output global a(17)
    cout << “b = “ << b;  // Output local b(2.3)
    cout << “c = “ << c;  // Output local c(42.8)
}

Scope Rules Explored
void Block1(int, char&);
void Block2();
int a1;               // One global variable
char a2;              // Another global variable
int main()
{
   .
   .
   .
}
void Block1(int a1,   // Prevents access to global a1
            char& b2) // Has same scope as c1 and d2
{
   int c1;          // A variable local to Block1
   int d2;          // Another variable local to Block1
     .
     .
     .
}

Scope Rules Explored (continued)
void Block2()
{
   int a1;            // Prevents access to global a1
   int b2;            // Local to Block2; no conflict
                      // with b2 in Block1
   while (…)
   {                 // Block3
      int c1;        // Local to Block3; no conflict
                      // with c1 in Block1
      int b2;         // Prevents nonlocal access to b2
                      // in Block2; no conflict with
                      // b2 in Block1
        .
        .
        .
   }
}

Accessing Identifiers From
Other Program Files
Individually
extern int someInt;
Collectively, from a namespace
std::abs(beta);   (qualified name)
using std::abs;  (using declaration)
using namespace std; (using directive)

Lifetime of A Variable
Lifetime is the period of time during program execution when an identifier actually has memory allocated to it.
Two types of variables
Static variables – storage remains allocated for the duration of the entire program
Automatic variables – storage is allocated at block entry and deallocated at block exit
By default, variables declared within a block are automatics, this can be changed using the reserved word static.

Side Effects Illustrated
void CountChars();
int count = 0;    // Supposed to count input lines
char ch;          // Hold one input character
int main()
{
   cin.get(ch);
   while(cin)
   {
      count++;
      CountChars();
      cin.get(ch);
   }
   cout << count << “ lines of input processed.” << endl;
   return 0;
}

Side Effects Illustrated (continued)
void CountChars()
// Counts the number of characters on one input line
// and prints the count Note: main() has already
// read the first character on a line
{
   count = 0;
   while (ch != ‘\n’)
   {
      count++;
      cin.get(ch);
   }
   cout << count << “characters on this line.” << endl;
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0;
   one( );
   cout << " a = " << a << endl;
}
int main () a = 20
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0;
   one( );
   cout << " a = " << a << endl;
}
int main () a = 20
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0; a = 0
   one( );
   cout << " a = " << a << endl;
}
int main ()
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0;
   one( ); a = 0
   cout << " a = " << a << endl;
}
int main ()
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10; a = 10
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0;
   one( );
   cout << " a = " << a << endl;
}
int main ()
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl; a = 10
}
void two ()
{
   int a = 0;
   one( );
   cout << " a = " << a << endl;
}
int main ()
{
   int a = 20;
   two( );
}

Another Scope Example
void one()
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two ()
{
   int a = 0;
   one( );
   cout << " a = " << a << endl; a = 0
}
int main ()
{
   int a = 20;
   two( );
}

Another Scope Example
void one(void)
{
   int a = 10;
   cout << " a = " << a << endl;
}
void two (void)
{
   int a = 0;
   one( );
   cout << " a = " << a << endl;
}
int main (void) a = 20
{
   int a = 20;
   two( );
}