C Session11
C Session11
l Storage Classes
l Macros
l The #include Directory
l Type Casting
Storage Class and C Processor
Comp-U-Learn
C Trim
redundant. Variables that are declared within functions are assumed to be auto variables.
When the block containing the automatic variable declaration is entered, Memory is allocated .
If the variable is not initialized, then it is not given a particular initial value.
It is visible through out the block in which it is declared but not outside it. Once the control is
outside the block, the variable and its value are removed, and memory de-allocated .
In this program, a variable lastNum is declared as an auto type in the function random and then
is given a particular value.
#include <stdio.h>
int random (int N)
{
auto int lastNum = 1;
lastNum = (lastNum*234721 + 17223) % N;
return(lastNum);
}
main ()
{
auto int i;
for (i=1; i <= 10; i++)
printf(“%d\n”, random(1000));
}
The output
Comp-U-Learn
Storage Class and C Processor
This program prints the same random number in a row. Because the last number is an automatic
variable, it is initialized to one, every time the function random is called. Here the last return
value cannot be saved.
This storage type is used to minimize access time. It tells the compiler that a variable used commonly
in a block of code should be allocated a register. It is very similar to auto, though it places the
object in a machine register, which enables faster access. Because the compiler generates many of
the commonly used variables, register variables do not get priority for placement in machine
registers. The limited size and number of registers available on most systems, enable only few
variables to be actually put in registers.
If the compiler does not allocate a machine register for a register object, the object is treated as
having the storage class specifier auto. They do make Object files smaller and faster to run. However
the register storage class specifier can not be used in file scope data declarations.
The keyword register is used to define data and a parameter declaration describes an object that
possesses a register storage class. An object having the register storage class specifier must be
defined within a block or declared as a parameter to a function.
The following lines of code define automatic storage duration objects using the register storage
class specifier:
While a register object can be initialized, its parameters can not. When you do not initialize a
variable then its value is not specific. When a value is specified, it should be a C expression.
The initial value assigned to structure and union member has to be a valid constant expression.
Each time the program block is initialized, that objects value is reset to what it set.
The duration of the Objects that are with the register storage class specifier is set automatically.
The storage for register objects that are defined in it is made available when the control shifts to
Comp-U-Learn
C Trim
that block. The objects are no longer in use when the block is exited. If a register object is defined
within a function that is recursively invoked, the memory is allocated for the variable at each
invocation of the block.
A variable that belongs to a static storage class will have storage in the memory and a default value
of Zero. It is local to the block of code in which it is defined and the value of this variable will be the
same even when called several times.
Memory is allocated at the beginning of the program once and for all.
If the variable is initialized while declaration, then it is initialized when the variable is allocated
at the beginning of the program execution. If it is not initialized during declaration then it is
initialized to Zero. A static variable is visible all through the function but not outside it.
It is visible throughout the function, but not outside. The bottom line is that the values of static
variables survive across multiple function calls unlike auto variables. If the control comes back to
the same function then the value remains the same as when it left that particular function.
# include <stdio>
int random(intN);
{
static int lastnum =1;
lastnum =(lastnum*234721+17223)%N;
return(lastnum);
}
main()
{
int I;
for(I=1;I<=0;I++)
printf(“%d\n”, random(1000));
}
This program is very similar to the previous program. The only difference being that a static
variable is declared . The output will be the number 944.
Comp-U-Learn
Storage Class and C Processor
A variable whose storage class is Memory, default initial value is Zero, whose scope is Global and
whose life span is equal to the time taken for the programs execution to complete is an External
variable.
Global Variable
#include <stdio.h>
int lastNumber = 1;
int random (int N)
{
lastNumber = (lastNumber*234721 + 17223) % N;
return(lastNumber);
}
main ()
{
int i, seed;
printf(“Please enter a seed for the random number generator: “);
scanf(“%d”, &seed);
lastNumber = seed;
for (i=1; i <= 10; i++)
printf(“%d\n”, random(1000));
}
The Output
When the number 6 is entered, the random numbers that are available are displayed.
Comp-U-Learn
C Trim
For every global variable, there must be one real declaration, but there can be any number of
``extern declarations.
When we declare a variable as an external one, the C compiler understands that a certain variable
with the same name is present in a different file. So understandably the compiler does not allocate
memory to that variable. It refers to a variable that is declared elsewhere.
This code should explain how external storage variables are declared:
int sum;
void addup3(int,int,int);
main()
{
int n[]={1,2,3};
addup3(n[0],n[1],n[2]);
printf(“Sum = %d\n”,sum);
}
void addup3(int a,int b,int c)
{
sum = a+b+c;
}
In the above program, the variables are declared externally in a function called Void addup3(int,
int, int). Then the variables are used in the main() by calling this function and passing the values
as arguments.
MACROS
A macro is an abbreviation, which is defined only once but put to use several times. They are
associated with the preprocessor.
The different types of macros are Simple Macros, Macros with arguments,
Simple Macro
A name which stands for a mere fragment of code is a Simple Macro. It is sometimes referred to as
a manifest constant. A Macro must be defined explicitly before it is used. This is done by using #
define, which is followed by the name of the macro and then the code it is abbreviating.
Comp-U-Learn
Storage Class and C Processor
It is common convention to use the upper case alphabets for Macro names. This makes it easier to
identify a Macro in the maze of a code.
Though a Macro definition consists of a single line, the use of a new line is permitted here. This is
limited to the scope of a string or character constant. A macro should not contain an unbalanced
quote character. Surprisingly the Parentheses need not be balanced.
To make Macros more flexible, the acceptance of arguments was enabled. A macro that can
accept arguments is written in a manner in which # define is followed by the macro name and
then the list of arguments in parentheses. The arguments may be any valid C identifiers, which are
separated by either white spaces or commas. The open parenthesis must follow the macro name
immediately without a whitespace. While using Macros with arguments, one must remember
that the number of arguments given must match the number of arguments expected by the
macro.
When a Macro name is followed by something other than an open parenthesis then it is not
considered to be a call to the macro and the preprocessor does not make the necessary changes.
If the name of a Macro and a variable or function match, then the preprocessor has to be told
which one it is expected to refer to. This type of naming should be avoided if macros with arguments
are to be used effectively.
Predefined Macros
There are several predefined Simple macros in C language. They are classified into Standard
Predefined Macros and Non Standard Predefined Macros.
All the standard predefined macros start and end with underscores.
_FILE_ : Expands to the name of the current file in the form of a decimal integer constant.
_LINE_ : Expands to the current input line number in the form of a decimal integer constant.
Comp-U-Learn
C Trim
_DATE_: Expands to a string constant that describes the date on which the preprocessor is being
run. It is limited to eight characters.
_TIME_: Describe the time at which the preprocessor is run. It is limited to eight characters.
_GNUC_: This macro is defined only if the entire GNU C compiler is in use. If the preprocessor is
invoked directly, then it is left undefined.
_BASE_FILE_: Expands to the name of the main input file, in the form of a string constant.
_VERSION_: This expands to a string, which specifies the version number of the GNU C.
_OPTIMIZE_: This is defined in optimizing compilations. It enables a few of the GNU header
files, to define the alternative macro definitions for the systems library functions.
_CHAR_UNSIGNED_: This is defined, depending on the status of the data type char, whether it
is unsigned on the target machine or not.
The C processor has several predefined macros that vary between machines.
EXAMPLE
EXAMPLE
Comp-U-Learn
Storage Class and C Processor
Preprocessing takes place in several logically successive phases that are condensed. A Preprocessor
makes three transformations on all the input received. The first and foremost transformation is
done on the comments. They are replaced by white spaces. All the backslash and newline sequences
are deleted. The predefined macros are replaced by their expansions.
A C preprocessor feature is inactive till it receives specific commands that enable their use. There
are stringent set of command names that are fixed and can not at any time be changed. However
some of these names require arguments that are fulfilling but separated by white spaces. A
preprocessor command consists of a single line, which may have a backlash or a whitespace or
even a comment. New lines only occur in comments.
The # and the command name cannot come from a macro expansion. For example, if hello is
defined as a macro expanding to define, that does not make #hello a valid preprocessor command.
To put it in simple terms the Preprocessor includes, substitutes and selects text to form finished
source code prior to actual compile
Comp-U-Learn
C Trim
Header Files
A Header file is one in which the declarations and definition of macros are stated. It is shared
between a large number of files. System header files are those which declare the interfaces to parts
of the Operating System. When they are included in a program, they supply the definitions and
declarations that invoke system calls and libraries.
User defined header files contain declarations and interfaces between the source files of the program.
Including a header file is equivalent to copying the entire header file into the source code. While
copying the file involves copying the whole code, the included file does not involve copying the
whole file, it serves the same purpose, without increasing the size of the code.
#include
This directive enables a file to be included into another. When the control comes in contact with
this directive, the content of that file is included at that point. Writing long code can get very
tiresome,To make life easier for the programmers, C allows the program to be broken up and used
by another program.
Sometimes it so occurs that a certain function is required in a number of programs. Here the
function can be written in a separate class from where it can be accessed by different classes.
Files that are to be included should have a .h extension. This symbolizes that the file is a header
file. The compiler searches for the included file when it encounters brackets or quotes. If the
filename is in quotes, then the compiler looks for it in the same source code. If it is in brackets, it
searches according to an implementation-defined rule.
Both user and system header files are included using the preprocessor command #include. It has
three variants:
#include <file>
Here a file named File is searched for in the list of directories specified or in system directories.
This variant is used for system header files. It searches for a file named file in a list of directories
specified by you, then in a standard list of system directories.
Comp-U-Learn
Storage Class and C Processor
The directories in which header files are to be searched for are scanned for files that have the
command option -I. Where-nostdinc is specified, the standard system directories are searched.
The argument file may not contain a > character. It may, however, contain a < character.
#include “file”
Here the file named file is first searched for in the current directory and then in the same directories
used for system header files. This order of search is followed because, the current directory is more
likely to be actually referred to.
The file that poses as an argument does not contain any special character and when a backslash is
encountered, it is considered to be a text character.
This is computed #include. If an argument does not resemble the above-mentioned two, then it
comes under this category. If any macro calls are encountered, they are expanded. The result has to
then match the above two types. The expanded text must be encompassed in quotes or angle
braces.
This allows for a file to be used at any point in the program. A site-configuration file can be used to
specify the names of the system include files. It makes the header file portable enough to be used
by various Operating Systems wherever the header files are necessary.
int x;
#include “header.h”
main ()
{
printf (test ());
}
char *test ();
Sometimes by mistake, it so occurs that a header file may be included more than once. This may
lead to various errors. To prevent this, a programmer can enclose the entire real contents of the file
in a conditional, like this:
Comp-U-Learn
C Trim
#ifndef __FILE_Filename_SEEN__
#define __FILE_Filename_SEEN__
#import
This is a variant of #include. This includes a file but is limited to doing so only once.
If this is used then the conditionals inside the header file that prevent multiple execution of the
contents, are not needed.
#if is always followed by an integer constant. If the expression is not zero, then the statement that
follows the #if is compiled. If it is otherwise, then it ignores it. The statement in which #if is used
should always be bonded by #endif or #else or even #elif. If any macros are encountered, then the
undefined ones are replaced by zero before the actual evaluation.
When #if is used, some relational or integer operators may also be used.
The comment following the #endif is not required, but it helps to match the #endif with its
corresponding #if. However anything that is put after #endif is ignored by the GNU C preprocessor.
The comments are acceptable in ANSI Standard C.
The expression is a C expression of Integer type. It may include Integer constants, long or unsigned.
It may also include character constants, interpreted according to the character set and conventions
of the machines Operating system. Arithmetic operators, identifiers other than macros and macro
calls.
#elif
#elif is used in a case where there are more than two alternatives that might be possible. #elif
stands for else if. This goes in between the #if and #endif statements. #elif is followed by a
conditional statement. The condition thus set by #elif is tested only if the #if statement fails. More
Comp-U-Learn
Storage Class and C Processor
than one #elif can be used in a block of code. If the #if and the first #elif fail, then the next #elif is
tested. This goes on till the #endif is encountered. It is to be noted that #elif does not follow the
#else statement.
#if x = =1
1 Statement;
#else /*x is not equal to 1*/
#if x = =2
2 Statement;
#else /* x is not equal to 2*/
# endif /* x is not equal to 2*/
#endif /* x is not equal to 1*/
Now let us see how the use of #elif abbreviates this code.
#if x = = 1
1 Statement;
#elif x = =2
2 Statement;
#else /* x us not equal to 2 and x is not equal to 1*/
#Statement;
#endif /* x is not equal to 2 and x is not equal to1*/.
Now let us take a look at the #else statement.
#else
#else is used to provide alternative text, if and when a condition proves to be
false.
This can be understood on observing the following:
# if condition
1 Statement if true
#else
2 Statement if false
#endif */ Statement if false.
If the #if statement is true then the #else statement is ignored. If the #if state-
ment is false, then the #else statement is included.
Comp-U-Learn
C Trim
#define
The interesting part here is that when the program is to be compiled, the preprocessor examines
the whole code. When it comes across the #define, it combs the whole code and replaces all the
macro templates with the respective macro expansion.
Here the preprocessor replaces the instances of the identifier with the token sequence. There can
be only one #define for an identifier. If there are two then they should be identical.
#undef and #pragma are very uncommon directives, that are not used in conventional
programming.
To change the status of a defined variable to an undefined variable, #undef is used. As discussed
earlier, to define a directive #define is used.
When the #undef command is used for a macro, its definition gets cancelled. Like a definition, an
undefinition also occurs at a specific point in the source file. From that point, the name loses its
status as a Macro and is treated by the preprocessor in a sort of impartial manner.
The following code shows how a #define variable is undefined using #undef:
x = abc; /* Here the value of x is assigned the value of abc, which is equal to
123*/
#undef abc
#undef cancels definitions with or without arguments. #undef will not work on a
name that is currently defined as a macro.
Comp-U-Learn
Storage Class and C Processor
Redefining Macros
Redefining a macro involves defining a name that has already been defined. Sometimes it may so
happen that a name might be redefined with an identical definition. Though this might sound
trivial, it may be because a header file is included twice. When a nontrivial definition is encountered,
then the preprocessor may send out a warning error message.
For a redefinition to be trivial, the new definition must exactly match the one already in effect,
with two possible exceptions:
#pragma
Its main function is to turn on or off certain program features. #pragma varies from one compiler
to another. The #pragma command is specified by the ANSI Standard, to possess an arbitrary
implementation definition effect. The GNU C preprocessor uses the #pragma command only in
the case of the #pragma once case.
T he #pragma once command tells the preprocessor that a file need not
be included more than once.
These commands are left in the preprocessor output and are available for the compilation pass.
Certain Pragmas are available with the Microsoft C compiler, which deal with formatting the
source listing and placing comments in the object file that is generated by the compiler.
The Turbo C compiler, which we are now well versed with, has a pragma that enables assembly
language to be incorporated in the C programs.
Comp-U-Learn
C Trim
TYPECASTING
Typecasting is done mainly while using pointers. It occurs during assignment operation for certain
types. Though it may sound complex, Typecasting is as simple as writing a sentence. This is done by
placing the type name in the parentheses and then putting it in front of the value that is intended
to be changed.
Main()
{
float fl;
int a =6;
int b = 4;
fl=a/b;
printf(“Value of fl = %f”,fl);
}
The value of a would be displayed as 1.000000.
Since 6 and 4 are both integers, 6/4 yields an integer. When it is stored in fl, it
becomes 1.0. Hence a and b have to be declared as a float.
The program can be written as follows:
float fl;
int a =6;
int b = 4;
fl =(float) a/b;
printf(“Value of fl = %f”,fl);
}
So when the value of fl is typecast to a float, after a/b then the result will be a float. It should be
noted that the value thus changed is not permanent.
Extended Reference
http://www.lysator.liu.se/c/rat/title.html
Comp-U-Learn
Storage Class and C Processor
T HE Z ERO H OUR
Q: What is the keyword used to declare a variable in an automatic storage class?
Ans: auto.
Storage
Default
Scope
Life
Ans: No.
Q: What is a macro?
Comp-U-Learn
C Trim
T HE S ESSION G UIDE
The Session Guide helps you time your session with the help of the slides provided. Beneath each
image of the slides is the time given to be spent on each slide while it is being displayed. The slide
will thus, guide you through the contents of the session with ease.
Programming Using C
Slide 1
Comp-U-Learn
Display Time
This slide discusses storage classes and C preprocessor. You should spend 5 minutes on it.
Road Map
Display Time
You discuss the various points to be discussed in this session and you need to spend at least 10
minutes on this slide.
Comp-U-Learn
Storage Class and C Processor
Storage classes
Automatic Storage class Register Storage class Extern al Storage class Static Storage class
Slide 3
Comp-U-Learn
Display Time
In this slide you will deal about the storage classes and its properties. Spend 14 minutes on this
slide.
ies
ro pert
T he P
Slide 4
Comp-U-Learn
Display Time
Comp-U-Learn
C Trim
⇒Default: Garbage.
Slide 5
Comp-U-Learn
Display Time
When you display this slide, you discuss the automatic storage class and its properties. Keep this
slide for 6 minutes.
⇒Keyword: Static.
Slide 6
Comp-U-Learn
Display Time
When you display this slide, you discuss the static storage class and its properties. Keep this slide
for 6 minutes.
Comp-U-Learn
Storage Class and C Processor
⇒Keyword: Extern.
Slide 7 Comp-U-Learn
Display Time
When you display this slide, you discuss the external storage class and its properties. Keep this
slide for 6 minutes.
⇒Keyword: Register.
Slide 8
Comp-U-Learn
Display Time
You will discuss about the register storage class and you can spend upto 6 minutes on this slide.
Comp-U-Learn
C Trim
Macros
Definition:
Single identifiers equivalent to expressions or statements.
General format:
#define identifier string.
Example:
#define AND &&
Note:
Macro definition is never terminated using a semicolon.
Slide 9
Comp-U-Learn
Display Time
Define a macro and discuss about it when this slide is displayed. Spend 6 minutes on this slide.
General format
#define identifer(func1,func2,….funcn),string
Example
#define PROB (a) (3.14*a*a)
main()
{
float x1=3.45, x2=5.67, i;
i=PROB(xi);
printf(“Area of first circle=%f ”, i );
i=PROB(x2);
Slide 10 nd
printf(“Area of 2 circle =%f ”, i );
} Comp-U-Learn
Display Time
This slide discusses the macros with arguments. You can display this slide for 10 minutes.
Comp-U-Learn
Storage Class and C Processor
#include Directive
Comp-U-Learn
Slide 11
Display Time
Discuss about the #include directive when you display this slide. Spend nearly 8 minutes on this
slide.
Example
main()
{
#if POST<=10
s t a t e m e nt 1 ;
s t a te m e nt 2 ;
st a t e m e nt 3 ;
#else
st a t e m e n t 4 ;
statement 5;
Slide 12
statement 6;
#e n d i f Comp-U-Learn
}
Display Time
Spend about 10 minutes on this slide as you will discuss the #if and #else directives with an
example.
Comp-U-Learn
C Trim
Example
main()
{
#if DE G RE E == B C O M
s t at e me n t 1
s t at e me n t 2
# e l if DE G RE E == B A
s t at e me n t 1
s t at e me n t 2
# e l if DE G RE E == B S C
s t at e me n t 1
s t at e me n t 2
# e l se
d e fa u lt st a te m en t
# e n di f
Slide 13 }
Comp-U-Learn
Display Time
Spend about 8 minutes on this slide as you will discuss the #if and #elif directives with an example.
#undef
Used for removal from the macro system.
General format:
undef macro_template
#Pragma
⇒ Used to turn on/off features.
Slide 14 Comp-U-Learn
Display Time
Spend about 7 minutes on this slide as you will discuss the #undef and #pragma directives.
Comp-U-Learn
Storage Class and C Processor
Typecasting
Example:
float X;
int a,b;
X= float (a/b);
Display Time
Discuss about the typecasting when you display this slide. Spend 8 minutes on this slide.
Display Time
This slide shows the going over it again Session. You summarize all the points that are covered in
this session and spend 10 minutes on this slide.
Comp-U-Learn