C++
  Home arrow C++ arrow Page 11 - More on Handling Basic Data Types
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C++

More on Handling Basic Data Types
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 5
    2005-03-02

    Table of Contents:
  • More on Handling Basic Data Types
  • Try It Out: Explicit Casting
  • Finding Out About Types
  • Try It Out: Finding the Sizes of Data Types
  • Using the Bitwise AND
  • Using the Bitwise Exclusive OR
  • Try It Out: Using the Bitwise Operators
  • More on Output Manipulators
  • Enumerated Data Types
  • Try It Out: Enumerated Data Types
  • The Lifetime of a Variable
  • Try It Out: The Scope Resolution Operator
  • Declaring External Variables

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    More on Handling Basic Data Types - The Lifetime of a Variable


    (Page 11 of 13 )

    All variables have a finite lifetime when your program executes. They come into existence from the point at which you declare them and then, at some point, they disappear—at the latest, when your program terminates. How long a particular variable lasts is determined by a property called its storage duration. A variable can have three different kinds of storage duration:

    • Automatic storage duration

    • Static storage duration

    • Dynamic storage duration

    The storage duration that a variable has depends on how you create the variable. I defer discussion of variables with dynamic storage duration until Chapter 7, but you’ll look into the characteristics of the other two kinds of storage duration in this chapter.

    Another property that variables have is scope. The scope of a variable is simply that part of your program in which the variable name is valid. Within a variable’s scope, you can legally refer to it, set its value, or use it in an expression. Outside of the scope of a variable, you can’t refer to its name—any attempt to do so will cause a compiler error. Note that a variable may still exist outside of its scope, even though you can’t refer to it by name. You’ll see examples of this situation a little later in this discussion.

    All the variables that you’ve declared up to now have had automatic storage duration, and are therefore called automatic variables. Let’s take a closer look at these first.

    Automatic Variables

    The variables that you’ve declared so far have been declared within a block—that is, between a pair of curly braces. These are called automatic variables and are said to have local scope or block scope. An automatic variable is “in scope” from the point at which it is declared until the end of the block containing its declaration.

    An automatic variable is “born” when it’s declared and automatically ceases to exist at the end of the block containing the declaration. This will be at the closing brace matching the first opening brace that precedes the declaration of the variable. Every time the block of statements containing a declaration for an automatic variable is executed, the variable is created anew, and if you specified an initial value for the automatic variable, it will be reinitialized each time it’s created.

    You can use the auto keyword to specify explicitly that a variable is automatic, but this keyword is rarely used because it’s implied by default. Let’s put together an example of what you’ve learned so far.


    Try It Out: Automatic Variables

    You can demonstrate the lifetime of automatic variables with the following example:

      // Program 3.6 Demonstrating variable scope
      #include <lostream>
      using std::cout;
      using std::endl;
      int main() {               // Function scope starts here
      int count1 = 10;
      int count3 = 50;
      cout << endl << "Value of outer count1 = " << count1;
      {                // New block scope starts here...
      int count1 = 20; // This hides the outer count1
      int count2 = 30;
      cout << endl << "Value of inner count1 = " << count1;
      count1 += 3;     // This changes the inner count1
      count3 += count2;
     }                // ...and ends here.
      cout << endl
           << "Value of outer count1 = " << count1
           << endl
           << "Value of outer count3 = " << count3;
      // cout << endl << count2; // Uncomment to get an error
      cout << endl;
      return 0;
    }                              // Function scope ends here

    The output from this example is as follows:

    ===========================================

    Value of outer count1 = 10
    Value of inner count1 = 20
    Value of outer count1 = 10
    Value of outer count3 = 80

    ===========================================

    HOW IT WORKS

    The first two statements declare and define two integer variables, count1 and count3, with initial values of 10 and 50, respectively:

     int count1 = 10;
     int count3 = 50;

    Both of these variables exist from this point in the code to the closing brace at the end of the program. The scope of these variables also extends to the closing brace at the end of main().


    NOTE Remember that the lifetime and scope of a variable are two different things. Lifetime is the period of execution time over which a variable survives. Scope is the region of program code over which the variable name can be used. It’s important not to get these two ideas confused.

    Following the variable definitions, the value of count1 is presented in the first line of output by this statement:

     cout << endl << "Value of outer count1 = " << count1;

    There’s then a second opening brace that starts a new block. Two variables, count1 and count2, are defined within this block, with the values 20 and 30, respectively. The count1 variable declared here is different from the first count1. Although the first count1 still exists, its name is masked by the second count1. Any use of the name count1 following the declaration within the inner block refers to the count1 declared within that block.

    I’ve duplicated names in this way only to illustrate what happens—it’s not a good approach to programming in general. Doing this kind of thing in a real program would be confusing and unnecessary, and produce code that was extremely prone to error.

    The output statement shows by the value in the second line that you’re using the count1 in the inner scope—that is, inside the innermost braces:

    {                       // New block scope starts here...
     int count1 = 20;       // This hides the outer count1
     int count2 = 30;
     
    cout << endl << "Value of inner count1 = " << count1;

    Had you still been using the outer count1, this statement would have output the value 10. The variable count1 is then incremented by this statement:

      count1 += 3;          // This changes the inner count1

    The increment applies to the variable in the inner scope, because the outer one is still hidden. However, count3, which was defined in the outer scope, is incremented without any problem by the next statement:

      count3 += count2;

    This shows that the variables that were defined at the beginning of the outer scope are still accessible in the inner scope. They could have been defined after the second of the inner pair of braces and still be within the outer scope, but in that case they wouldn’t exist at the point that you’re using them.

    After the brace ending the inner scope, count2 and the inner count1 cease to exist. Their lifetime has come to an end. The variables count1 and count3 are still there in the outer scope, and their values are displayed by this statement, demonstrating that count3 was indeed incremented in the inner scope:

     cout << endl
          << "Value of outer count1 = " << count1
          << endl
          << "Value of outer count3 = " << count3;

    If you uncomment the next line

    // cout << endl << count2;   // uncomment to get an error

    the program will no longer compile correctly, because it attempts to output a nonexistent variable.


    Positioning Variable Declarations

    You have great flexibility in where you place the declarations for your variables. The most important issue to consider is what scope the variables need to have. Beyond that, you should generally place a declaration close to where the variable is first to be used in a program. You should always write your programs with a view to making them as easy as possible for another programmer to understand, and declaring a variable close to its first point of use can be helpful in achieving that.

    It’s possible to place variable declarations outside all of the functions that make up a program. Let’s look what effect that has on the variables concerned.

    Global Variables

    Variables declared outside of all blocks and classes are called globals and have global scope (which is also called global namespace scope). This means that they’re accessible in all the functions in the source file, following the point at which they’re declared. If you declare them at the very top, they’ll be accessible from anywhere in the file.

    Globals also have static storage duration by default. Global variables with static storage duration will exist from the start of execution of the program until execution of the program ends. If you don’t specify an initial value for a global variable, it will be initialized with 0 by default. Initialization of global variables takes place before the execution of main() begins, so they’re always ready to be used within any code that’s within the variable’s scope.

    Figure 3-4 shows the contents of a source file, Example.cpp, and the arrows indicate the scope of each of the variables.


    Figure 3-4.  Variable scope

    Figure 3-4 illustrates the extent of the scope of each variable in a file. The variable value1 that appears at the beginning of the file is declared at global scope, as is value4, which appears after the function main(). The global variables have a scope that extends from the point at which they’re declared to the end of the file. Even though value4 exists when execution starts, it can’t be referred to in main() because main() isn’t within the variable’s scope. For main() to use value4, you would need to move its declaration to the beginning of the file. Both value1 and value4 will be initialized with 0 by default, which isn’t the case for the automatic variables. Remember that the local variable called value1 in function() will hide the global variable of the same name.

    Because global variables continue to exist for as long as the program is running, this might raise the following question in your mind: “Why not make all variables global and avoid this messing about with local variables that disappear?” This sounds very attractive at first, but there are serious disadvantages that completely outweigh any advantages that you might gain.

    Real programs are generally composed of a large number of statements, a significant number of functions, and a great many variables. Declaring all at the global scope greatly magnifies the possibility of accidental, erroneous modification of a variable, and it makes the job of naming them sensibly quite intractable. They’ll also occupy memory for the duration of program execution. By keeping variables local to a function or a block, you can be sure they have almost complete protection from external effects. They’ll only exist and occupy memory from the point at which they’re defined to the end of the enclosing block, and the whole development process becomes much easier to manage.


    This article is excerpted from Beginning ANSI C++ The Complete Language by Ivor Horton (Apress, 2004; ISBN  1590592271). Check it out at your favorite bookstore today. Buy this book now.

    More C++ Articles
    More By Apress Publishing


     

    C++ ARTICLES

    - Paths and Files
    - Directories in C++
    - Focusing on C++ Files
    - Const Correctness in C++
    - Manipulating Streams and Files with C++
    - Streams and Files
    - Multiplying Large Numbers with Karatsuba`s A...
    - Large Numbers
    - Dijkstra`s Shunting Algorithm with STL and C...
    - Brief Introduction to the STL Containers
    - The Standard Template Library
    - Templates in C++
    - C++ Programmer Alerts
    - C++ Programming Tips
    - First Steps in (C) Programming, conclusion






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway
    Stay green...Green IT