PART 5
PART 5
To fully define a variable one needs to mention not only its type but also its storage class. There are two
types of locations where variables can be stored there are memory and CPU registers.
Automatic variable:
These are declared within which they are used. They are also referred as internal (or) local variables.
These variables are created when a function is called, and destroyed automatically when a function is
excited.
Automatic variables are given only temporary memory space.
Local variables are given the storage class auto by default. The keyword auto is used to declare
automatic variables.
The Automatic variables have two distinct advantages.
Advantages:
The memory space is used economically since it is used only as long as it is needed.
There local scope prevent from affecting other functions due to inadvertent changes.
Register variable:
These variables are stored in CPU registers and gets default initial as “garbage value”. Any variable
which is stored in the CPU registers can be accessed faster than the one which is stored in memory.
If a variable is used at many places it is better to declare its storage class as register.
A good example for frequently used variables in looping counter.
main ( )
{
register int I;
for (i=1; i<=10; i++)
printf(“%d”,i);
}
Here, even though we have declared the storage class of ‘i’ as register, we are not sure that the value of
‘i’ would be stored in a CPU register. Because the number of CPU registers is limited {14 for micro
computer} and these are busy in doing some other task. In those situations it treats them as auto.
There are some restrictions on register variables. We can’t use register storage class for all types of
variables. Since, CPU registers are 16 bit registers. They can’t hold float (or) double values which
require 4 & 8 bytes respectively. Even though we use register for float and double we don’t get any
error because they treat as auto.
Static variable:
As the name suggest that the value of the static variable persists until at the end of the program i.e., the
contents of the variable will be retained.
A variable can be declared as static by using the keyword “static”.
A static variable may be either an internal type (or) an external type depending upon the place of
declaration.
The scope of internal static variable extends up to the end of the function in which they are defined.
The internal static variables are similar to automatic variables. The difference between them is the static
variables do not disappear when the function is no longer active. Their values are persisting.
If the control comeback to the same function again the static variables have the same value. They had
last time announced.
Internal static variables can be used to retain values between function call.
A static variable is initialized only once and it takes default initial value as zero.
When the program is compiled it will never initialized again.
Ex:- main ( )
{
dec ();
dec ();
dec ();
}
void dec ()
{
static int i=5;
printf(“%d”,--i);
return ();
}
External variable:
Here the variable is both alive and active throughout the entire program. They are also known as “Global
variables”.
Unlike local variables, global variables can be accessed by any function in the program.
These variables are defined by using the keyword “extern”.
Eg: main ()
{
extern int i=5;
printf(“%d”,i);
}
We can also define these variables without using keyword. At that time we declare variables outside the
function.
int x=20;
main()
{
int y;
printf(“%d”,x);
}
The default initial value of external variable is a “garbage” value.
The C Pre-processor:
A pre-processor is a program that modifies the source program according to the directives supplied in
the program.
The pre-processor commands are often referred as compiler directives.
The original source program is usually stored in a file. The pre-processor doesn’t modify this file but
creates a new file that contains the processed version of the program. This new file is then submitted to
the compiler.
The pre-processor makes the program easy to understand.
The pre-processor provides several tools that are not available in any other languages.
The program can use these tools to make the program easy to read and modify.
Rules:
The general rules of defining a pre-processor are
All pre-processor directives begin with sharp sign.
These should not be any space between the sharp sign and the directive name.
The pre-processor directive is not terminated by the semi-colon.
Only one pre-processor directive can occur in a line.
Compiler directives:
The following are the some of the compiler directives
Directive name Function
#include Specify the file to be included.
#define defines a macro substitution
#undef undefines a macro
#ifdef Test for a macro definition
#endef Specifies end of # if
#ifndef Test whether a macro is not define
#if Test a compile time condition.
#else Specify the alternative when #if test fails.
These directives can be divided in to four categories.
Macro substitution directive
File inclusion directives
Compiler control directives
Miscellaneous directives
The following are the different steps involved when we enter through the program until the stage of
executing the program to produce the results.
Hand-written program
[Enter in to the computer]
Source code
[Pre-processor]
Expanded source code
[Compiler]
Object code
[Linker]
Executable code.
Macro substitution Directive:
The macro substitution is a process where an identifier in a program is replaced by a pre-defined string
composed of one (or) more characters.
The general format of macro substitution is as follows.
#define identifier string
If this statement is included in the program, the pre-processor replaces every occurrence of the identifier
in the source code by a string.
There are different forms of Macro substitution
o Simple Macro substitution
o Argument Macro substitution
o Nested Macro substitution
Simple Macro substitution:
These are the macros where a simple string replacement is commonly used to define constants. The
advantage of these macros is if the constant value is modified at the macro definition. Automatically, in
all the statements wherever this variable is used the new value is accepted. In addition to this, it
increases the readability of the program.
#define PI 3.14
#define false 0
#define or ||
#define name “MAHESH”.
Argument Macro substitution:
The pre-processor permits us to define more complex and useful forms of replacement. Here, we can
specify the list of input variables s arguments in order to calculate various values. The following in the
general format.
#define variable (v1, v2, ……………….. vn) string
Here, there is no space between the variable which is a macro name and the left parenthesis.
Ex: #define square (x) (x*x)
In the program we get the statement as value =square (side), then statement will be expanded as value
= (side*side)
If we have a statement like value = square (x+y), then this sentence will be expanded as
= (x+y *x+y)
Thus, we get incorrect result with this expansion. This can be corrected by defining the macro as
following.
#define square(x) ((x)*(x))
the following is some of the examples.
#define cube(x) ((x)*(x)*(x))
#define cube(x) (sqr(x) * (x))
Nesting of Macros:
The term nesting of macros refers to using definition of one macro within the definition of another
macro i.e., using already defined macro in order to define a new macro.
#define max (x, y) ((x) > (y))? (x) :( y))
This macro is defined to find the largest of given two numbers.
Using this macro we can’t find largest of three numbers but by using nesting of macros we can find the
largest of three numbers.
max (x, max(y, z)).
This statement causes the entire contents of the given file to be inserted into source code at that point in
the program. We will use these directives mainly for two reasons:
If we have a large program, the code is divided in two different files each containing a set of
related functions.
At many times we need some functions (or) some macro definitions to be used in almost all
programs. In such cases we will store all these definitions in a file and we will include that file.
A file names used in the #include directive should have an extension of .h
We can use # include directive in two forms, they are
# include “file name.h”
# include <file name.h>
In the first form, the given file name is searched in the current directory as well as in the specified list of
directories that are mentioned in include searched part.
In the second form, the given file name will be searched only in the list of directories specified in the
include search part.