More On Data Types and Variables
The following topics are covered in this section:
Scope refers to the region where something is valid or the region where something can exist. Variables in C++ have a defined scope, which depends on the way they are declared. There are three places where a variable can be declared: as local variables, formal parameters and global variables.
Remember: In C we can declare variables only in the starting of the function. In C++, we can declare variables anywhere within the program.
Local Variables
Variables declared within a function are called local
variables (sometimes called automatic variables). These variables can be used
only within the block (or function) in which they are declared. A block starts
with an opening curly brace and ends in a closing curly brace. A local variable
is created upon entry into the block and destroyed when the program exits that
block. If you create a variable in the main ( ) function then it can be used
only within the main ( ) function. That variable cannot be accessed by some
other function that you may have created.
For example:
void test ( )
{
// Start of block
int q;
q = 2;
}
// End of block
void test2 ( )
// Start of another block
{
int q;
q = 5;
}
The two q's declared in the two functions (test and test2) have no relationship with each other. Each q is known only within its own block (since it is a local variable). The main advantage is that a local variable cannot be accidentally altered from outside the block.
Try it: Compile the following piece of code in your compiler and check the results
int main( )
{
int outer;
{
int inner;
cout<<"enter the outer variable value : ";
cin>>outer;
}
cout<<"\n Enter inner variable value : ";
cin>>inner;
return 0;
}
What do you think will happen? The above program will lead to a compile-time error. Variables are visible only within the block of code where they are declared (unless they are global variables). The coding enclosed within the two braces is called as a ‘block’ of code. Thus:
{
int inner;
cout<<"enter the outer variable value : ";
cin>>outer;
}
is a block of code within which we have declared an integer variable ‘inner’. This variable ‘inner’ is not visible outside of this block. Thus the statement:
cin>>inner;
will lead to an error because ‘inner’ is only known inside this block and not outside the block.
Note the difference between the two codes given below:
int main( )
{
int i=5;
{
int i;
//This ‘i' is only visible within this block.
i=6;
}
cout<<i;
//Value will be 5 (NOT 6)
return 0;
}
Compare this coding with the one below:
int main( )
{
int i=5;
{
i=6;
}
cout<<i;
//Value of ‘i' is 6 (NOT 5)
return 0;
}
What’s the difference between the two codes? In the first one we have declared a new integer ‘i' within the inner block. Now this inner variable is different from the outer block variable.
In the second case, we are modifying the value of the outer block variable (in this case there is only one variable – the outer block variable).
Remember: An inner block can access the variables that are present in the outer block. But the reverse is not possible.
Formal Parameters
As we have seen, if a function is to use arguments then it must declare variables that will accept the values of the arguments. These variables are called parameters or formal parameters. For example:
int remainder (int a, int b)
// In this function, the parameters are ‘a’ and ‘b’.
{
return a % b;
}
They are actually similar to local variables and the parameters are visible only within the function block.
Global Variables
#include <iostream.h>
int count; // count is a global variable
void increment( )
{
count=count+2;
}
int main ( )
{
count=1;
}
The above program is not complete but you can see that two functions (increment and main) can access the same variable ‘count’.
count=1;
The increment ( ) function increases the same count value by 2. Now count is 3 and finally the main ( ) function increases count by 1. The final count value is 4. This is a case of more than two variables accessing the same global variable.
Remember: Global variables will take up more memory because the compiler has to always keep it in memory. Avoid using too many global variables. Use it only if the variable is going to be used by a number of functions.
What would happen if a program uses an identifier as both local and global variable name? Consider the program below:
#include<iostream.h>
int var=55;
//Global variable
int main( )
{
int var=20;
//Local variable with same name
cout<<"\nGlobal variable value is : "<<::var;
var=var+1;
cout<<"\nLocal variable value is : "<<var;
return 0;
}
The output of the program will be:
Global variable value is : 55
Local variable value is : 21
Within the main ( ) function whenever we refer to ‘var’, it will mean the local variable only. Suppose you want to call the global variable, then you have to make use of the scope resolution operator (::). This operator is explained later but for the time being just remember that ‘::var’ will refer to the global variable.
Beware: It is not good programming practice to use the same variable name for global and local varaibles (it can lead to a lot of confusions and programming errors).
Storage classes are qualifiers that you can use to tell the compiler how you want the variable to be stored in memory and how you want to access it.
The four storage classes are:
These four terms are keywords in C++.
Auto
All local variables are ‘auto’ by default (auto meaning automatic). Whenever you declare a variable in a function, it is already ‘auto’. You needn’t explicitly specify this qualifier. For example:
int var;
will be the same as:
auto int var;
Suppose we have a function named counter ( ) with a local variable ‘count’
void counter ( )
{
int count=0;
cout<<count;
}
Each time this function is called the value of ‘count’ will be initialized to 0.
Static
There may be occasions when you want to retain a particular variable’s value each time the function is called. When you use auto variables, you will lose the value of the variable. If you declare a variable as a static variable then it will retain its value.
int counter( )
{
static int count=0;
count=count+1;
return count;
}
int main( )
{
for (int i=1;i<10;i++)
{
cout<<counter();
}
return 0;
}
The output will be:
123456789
The function counter ( ) is actually being called 9 times by the function main ( ) and each time the ‘count’ value is retained. If the variable ‘count’ were not declared as a static variable, the output would be: 000000000
You might be thinking that the line:
static int count=0;
will initialize the variable ‘count’ each time to zero but this does not happen. It is used to initialize ‘count’ to 0 only once (i.e. at the first call).
Extern variable
Extern or external variable is useful in multiple file C++ programming. So far we have only seen single file programming (i.e. you write the entire program in one *.cpp file, compile and run it). As your program complexity increases you will find it better to divide your program into different files. In such instances, extern variables are useful. This will be dealt with in the topic of "Multiple File programming".
Register variable
When you specify a variable as ‘register’ the compiler might place the variable in one of its hardware registers. The word ‘might’ is very important because you cannot be sure that the compiler has placed the variable in its register.
Remember: In C programming you shouldn’t try to find the address of a register variable.
Why do we need register variables? Placing a variable in the register will help in speeding up the computational processes that involve the register variable. Since the computer processor has only a fixed set of available hardware registers it cannot place all your variables in its registers. Depending on availability the compiler will decide whether to make a variable a register variable or not.
Usually, variables are stored in the computer’s memory (as explained earlier, memory will have addresses for accessing the location and values are stored in these locations). But a register variable is stored in one of the registers of the CPU (the central processing unit). Every microprocessor has a set of internal registers available that it can use for its operations (and accessing these registers is faster than accessing external memory).
The syntax is:
register data-type variable-name;
By the way, it isn’t a rule that only integers can be made register variables. Any data type variable can be made a register variable.
Beware: Don’t expect that specifying all your variables as register type will speed up the program. There is a specific limit and beyond that the compiler will treat your register variables as normal variables. Though you can use it on any variable data type, the register variable might work effectively only in the case of an integer or a character. Use register variables for variables that are accessed frequently in your program.
Copyright © 2004 Sethu Subramanian All rights reserved.