Home arrow C++ arrow Page 12 - More on Handling Basic Data Types
C++

More on Handling Basic Data Types


Have you ever wanted to learn how basic types of C++ variables interact in complex situations? Ivor Horton explains this, and also describes some interesting features of C++. This article is from chapter 3 of Ivor Horton's Beginning ANSC C++ The Complete Language (Apress, 2004; ISBN 1590592271).

Author Info:
By: Apress Publishing
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
March 02, 2005
TABLE OF CONTENTS:
  1. · More on Handling Basic Data Types
  2. · Try It Out: Explicit Casting
  3. · Finding Out About Types
  4. · Try It Out: Finding the Sizes of Data Types
  5. · Using the Bitwise AND
  6. · Using the Bitwise Exclusive OR
  7. · Try It Out: Using the Bitwise Operators
  8. · More on Output Manipulators
  9. · Enumerated Data Types
  10. · Try It Out: Enumerated Data Types
  11. · The Lifetime of a Variable
  12. · Try It Out: The Scope Resolution Operator
  13. · Declaring External Variables

print this article
SEARCH DEVARTICLES

More on Handling Basic Data Types - Try It Out: The Scope Resolution Operator
(Page 12 of 13 )

As youíve seen, a global variable can be hidden by a local variable with the same name. However, itís still possible to ďget atĒ the global variable by using the scope resolution operator (::), which you saw in Chapter 1 when you learned about namespaces. Hereís a demonstration of how this works with a revised version of the last example:

 // Program 3.7 Using the scope resolution operator
 #include <iostream>
 using std::cout;
 using std::endl;
 int count1 = 100;    // Global version of count1
  int main() {           // Function scope starts here
  int count1 = 10;
  int count3 = 50;
 
cout << endl << "Value of outer count1 = " << count1;
 
cout << endl << "Value of global 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;
  
cout << endl << "Value of global 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

If you compile and run this example, youíll get the following output:

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

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

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

HOW IT WORKS

The lines in bold indicate the changes made to the previous example, and theyíre the only ones whose effects I need to discuss. The declaration of count1 prior to the definition of the function main() is global, so in principle itís available anywhere through the function main(). This global variable is initialized with the value of 100 in its declaration:

int count1 = 100;         // Global version of count1

However, you have two other variables called count1 that are defined within main(), so the global count1 is hidden by the local count1 variables throughout the program. In fact, in the inner block it is hidden behind two variables called count1: the inner count1 and the outer count1.

The first new output statement is as follows:

 int count1 = 10;
 int count3 = 50;
 cout << endl << "Value of outer count1 = " << count1;
 
cout << endl << "Value of global count1 = " << ::count1;

This uses the scope resolution operator, ::, to indicate to the compiler that you want to reference the global count1, not the local one. You can see that this works by the value displayed in the output. The global scope resolution operator also does its stuff within the inner block, as you can see from the output generated by this statement:

  int count1 = 20;          // This hides the outer count1
  int count2 = 30;
  cout << endl << "Value of inner count1 = " << count1;
  cout << endl << "Value of global count1 = " << ::count1;

This outputs the value 100, as beforeóthe long arm of the scope resolution operator used in this fashion always reaches a global variable.

Youíll see a lot more of this operator when I cover object-oriented programming, where itís used extensively. Iíll also talk further about namespaces, including how to create your own, in Chapter 10.


Static Variables

Itís conceivable that you might want to have a variable thatís defined and accessible locally within a block, but that also continues to exist after exiting the block in which it is declared. In other words, you need to declare a variable within a block scope, but give it static storage duration. The static keyword provides you with the means of doing just this, and the need for it will become more apparent when you begin to deal with functions in Chapter 8.

A variable that you declare as static will continue to exist for the life of a program, even though itís declared within a block and is only available from within that block (or its sub-blocks). It still has block scope, but it has static storage duration. To declare a static variable called count, you would write

 static int count;

Variables with static storage duration are always initialized for you if you donít provide an initial value yourself. The variable count declared here will be initialized with 0. If you donít specify an initial value when you declare a static variable, it will always be initialized with 0 and converted to the type applicable to the variable. Remember that this is not the case with automatic variables. If you donít initialize your automatic variables, theyíll contain junk values left over from the program that last used the memory they occupy.

The register Storage Class Specifier

The register specifier is used to indicate that a variable is critical to the speed of execution and should therefore be placed in a machine register. (A register is a special, high-speed storage facility located separately from main memory, usually on the processor chip.) Hereís an example of how you use this modifier:

 register int index = 0;

Here, youíre requesting that the variable index use a register. The compiler is under no obligation to accede to this request, and in many compilers it wonít result in a register being allocated for this purpose.

In general, you shouldnít use register unless youíre absolutely sure of what youíre doing. Most compilers will do a better job of deciding how registers should be used without any prompting.

The volatile Type Modifier

The volatile modifier is used to indicate that the value of a variable can be modified asynchronously by an external process, such as an interrupt routine:

volatile long data = 0L;  // Value may be changed by
     another process

The effect of using the volatile modifier is to inhibit the optimization that the compiler might otherwise carry out. For example, when a program references a non-volatile variable, the compiler might be able to reuse an existing value for that variable that was previously loaded into a register, to avoid the overhead of retrieving the same value from memory. If the variable was declared as volatile, its value will be retrieved every time itís used.

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.


blog comments powered by Disqus
C++ ARTICLES

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials