The scope of a variable is the portion of the program where the variable is valid or "known".
Local Variables
- ★ A local variable is defined inside a function or a block statement and is not accessible outside the function or block.
- ★ This means that these variables are visible and can only be used by the function in which the variable is defined!
- ★ Local variable lifetime: A function's local variables exists only while the function is executing.
- ★ When the function begins, its local variables and its parameter variables are created in memory, and when the function ends, the local variables and parameter variables are destroyed.
What is the output of the following code fragment? void ThisFunc[int]; int main[] { int m1, m2; m1 = 1; m2 = 21; ThisFunc[m2]; cout 40 ] { char x[ 'A' ]; // Very local, value = 65 printf[ "Third x = %c\n", x ]; // Prints very local, 'A' func[ x ]; // Passes the very local char, converted to an int. } printf[ "Fifth x = %d\n", x ]; // Ordinary local 42 again return 0; } void func[ int x ] { // local parameter printf[ "Fourth x = %d\n", x ]; // Local parameter, 65 return; }
Program Output: First x = 0.0 |
Storage Class
- Variables can be in one of four storage classes, depending on where in computer memory they are stored.
Automatic Variables
- Automatic variables, [ a.k.a. auto variables ] are stored on a data structure known as "the stack".
- The stack grows and shrinks as a program executes.
- In particular, when a new function is entered, space is allocated on the stack to store all of the local variables for that function. [ Actually space is allocated for each variable at the time when it first goes into scope, i.e. when it is declared. ]
- More importantly, when the function exits, the stack space allocated to that function is freed up, and becomes available for other uses. [ The stack shrinks. ]
- Local variables, function parameters, and very local variables are ordinarily auto variables stored on the stack.
- Any data stored in auto variables is lost when the variables go out of scope, i.e. when a function exits. The next time the variable comes back into scope [ i.e. when the function gets called again ], the variable is allocated new space, and re-initialized if an initialization is given.
Static Variables
- Static variables are stored in a separate storage area known as "the heap".
- Space for static variables is allocated one time only, before main[ ] begins, and never expires.
- Global variables are normally static. Other variables may be declared static.
- In particular, if function variables are declared as "static", then they are only initialized once, and retain their values between function calls. [ The variables can still go out of scope, but when they come back into scope they will still retain their previous values. ]
- Example: The following code will generate the output shown below the code:
- Static variables can be used to count how many times a function is called, or to perform some special behavior the first time a function is called. [ Declare a static variable "firstTime" initialized to true. If firstTime is true, do the special code and then set firstTime to false. ]
- Variation: The static keyword applied to a global variable makes it global to this file only, and not visible from other files, [ in a multi-file development project. ]
void staticExampleFunction[ void ]; int main[ void ] { for[ int i = 0; i < 5; i++ ] staticExampleFunction[ ]; return 0; } // main void staticExampleFunction[ void ] { int normalInt = 0; static int staticInt = 0; printf[ "The normal int = %d. The static int = %d.\n", ++normalInt, ++staticInt ]; return; }Output:
The normal int = 1. The static int = 1. The normal int = 1. The static int = 2. The normal int = 1. The static int = 3. The normal int = 1. The static int = 4. The normal int = 1. The static int = 5.
Extern Variables
- The "extern" keyword applied to a variable indicates that it is declared and allocated space in some other file.
- A declaration with the word "extern" is like a function prototype - It tells the compiler of the existence of the variable, without actually creating it or allocating any space for it.
- All such variables must be declared exactly once, [ i.e. in one file only of a multi-file development project ] without the "extern", so that space can be allocated for it.
- Exterm variables are global in the file in which they are declared without "extern", but may be either local or global in other files.
- Extern will be covered more fully under the topic of multi-file development.
Register Variables
- The keyword "register" suggests to the compiler that the given variable be stored in one of the CPU registers, [ for faster access ], instead of in regular memory.
- Register variables act as auto variables, except they do not have an "address", and so cannot be referred to by pointer variables or by the address operator, &.
- Loop counters are the most common and obvious use of register variables.
- Modern optimizing compilers have elminated most need for the keyword register.
Summary of Variable and Parameter Declaration Qualifiers
The following example shows all possible qualifiers for variables and function parameters, and how those qualifiers affect the variables in three key areas:
- Storage duration, indicating whether the item continues to exist when it goes out of scope [ static storage ], or whether it is re-created and re-initialized every time that it goes into scope [ auto storage. ]
- Scope, indicating whether the item is available to the remainder of the file [ file scope ], or only through the remainder of the block in which it is defined [ block scope. ]
- Linkage, indicating whether the item is also accessible from other files [ external linkage ] or whether it is private to multiple functions only within this file [ internal linkage ], or whether it is accessible only within a block [ no linkage, i.e. none. ]
int a; extern int b; static int c; void f[ int d, register int e ] { auto int g; int h; static int i; extern int j; register int k; }
NameStorage DurationScopeLinkage a
static
file
external
b
static
file
??? - see below
c
static
file
internal
d
auto
block
none
e
auto
block
none
f
auto
block
none
g
auto
block
none
h
auto
block
none
i
static
block
none
j
static
block
??? - see below
k
auto
block
none
??? - The linkage for b and j depends on their original declaration, but are normally external
Inline Functions [ C99 only ]
There is also one additional qualifier that can be applied to functions only: inline
The ordinary function call-and-return mechanism involves a certain amount of overhead, to save the state of the original function on the stack, create stack space for a return address and the local [ auto ] variables needed for the new function and its parameters, transfer control to the new function, do the work, store the return value back on the stack, clean up the stack, and then transfer control back to the original calling function.
For certain small fast functions, this overhead can add significantly to the processing time of the function, often greatly surpassing the effort needed to perform the work of the function.
Therefore the inline qualifier applied to a function suggests to the compiler to simply copy the instructions for the function into this location in the calling function's code, instead of invoking all of the overhead of the call and return process.
An alternative to inlined functions is parameterized macros, implemented with #define, which are covered elsewhere.
Related Topics
The following topics are not covered here, but may be found in many books on C Programming
- Functions with variable argument lists [. . . ]