C NOTES
C NOTES
Preprocessor Directives
A preprocessor is a program that processes our program before it is passed to
the compiler for compilation. The commands of a preprocessor are called
preprocessor directives. Each preprocessor directive begins with a # symbol.
Preprocessor directives can be placed anywhere in the „C‟ program. But are
generally placed at the beginning of the program before main(). They can be
recognized as „C‟ program statements starting with „#‟. Preprocessor directives are
not terminated with a semicolon.
Types of Preprocessor Directives –
Preprocessor directives can be categorized into four types
Macro expansion
File inclusion
Conditional compilation
Miscellaneous directives
Macro expansion
Simple macros.
Macro with arguments.
Simple macro -
The definition has the following form
#define name replacement_text
name is called the macro template &
replacement_text is called the macro expansion.
The rules for giving a macro name are same as for variable name.
Generally macro name is written with capital letters. E.g.
#define UPPER 25 #define PI 3.1415
main( ) main( )
{ {
Page 1
ADVANCED C PROGRAMMING
UPPER and PI in the above programs are often called ‘macro templates’,
whereas, 25 and 3.1415 are called their corresponding ‘macro expansions’.
[Example of NESTED
MACRO]
Page 2
ADVANCED C PROGRAMMING
Page 3
ADVANCED C PROGRAMMING
Conditional compilation
A number of the directives control conditional compilation, which allows certain
portions of a program to be selectively compiled or ignored depending upon specified
conditions. The directives concerned are: #if, #ifdef, #ifndef together with the
preprocessor unary operator defined.
General form of conditional compilation is as follows-
#ifdef macroname
Statement 1;
Statement 2;
Statement 3;
#endif
If macroname has been #defined, the block of code will be processed as usual;
otherwise not.
#ifdef INTEL
code suitable for a Intel PC
#else
code suitable for a Motorola PC
#endif
code common to both the computers
}
When you compile this program it would compile only the code suitable for a
Intel PC and the common code. This is because the macro INTEL has not been
defined. Note that the working of #ifdef - #else - #endif is similar to the
ordinary if - else control instruction of C.
#if and #elif Directives
The #if directive can be used to test whether an expression evaluates to a nonzero
value or not. If the result of the expression is nonzero, then subsequent lines upto a
#else, #elif or #endif are compiled, otherwise they are skipped.
Miscellaneous directives
Undef
pragma
Some of the pragmas such as #pragma startup and #pragma exit
These directives allow us to specify functions that are called upon pragma
startup(before main()) or program exit(just before the program terminates)
Example
#pragma startup function1
#pragma exit function2
void main()
{
printf(“\n Inside main”);
}
void function1()
{
printf(“\n Inside Function1”);
}
Page 5
ADVANCED C PROGRAMMING
void function2()
{
printf(“\n Inside FUNCTION2”);
}
Output -
Inside Function1
Inside main
Inside Function2
1) #pragma warn-
This directive tells the compiler whether or not we want to suppress a specific
warning.
#pragma warn –rvl //return value
#pragma warn –par //parameter not used
#pragma warn –rch //unreachable code
int f1()
{
int a=5;
}
void f2(int x)
{
printf(“\n Inside f2”);
}
int f3()
{
int x=6;
return x;
x++;
}
void main()
{
f1();
f2(7);
f3();
Page 6
ADVANCED C PROGRAMMING
1. Usually macros make the program run faster but increase the program size,
whereas functions make the program smaller and compact.
2. In a macro call the preprocessor replaces the macro template with its macro
expansion, in a stupid, unthinking, literal way. As against this, in a function call
the control is passed to a function along with certain arguments, some
calculations are performed in the function and a useful value is returned back
from the function.
3. If we use a macro hundred times in a program, the macro expansion goes into
our source code at hundred different places, thus increasing the program size.
On the other hand, if a function is used, then even if it is called from hundred
different places in the program, it would take the same amount of space in the
program. But passing arguments to a function and getting back the returned
value does take time and would therefore slow down the program. This gets
avoided with macros since they have already been expanded and placed in the
source code before compilation
4. Macro is simple and sweet; it makes nice shorthand and avoids the overheads
associated with function calls.
Page 7
ADVANCED C PROGRAMMING
The scope of a variable is the range of program statements that can access that
variable. The lifetime of a variable is the interval of time in which storage is bound to
the variable. A variable is visible within its scope and invisible or hidden outside it.
'Storage' refers to the scope of a variable and memory allocated by compiler to store
that variable. Scope of a variable is the boundary within which a variable can be used.
Storage class defines the scope and lifetime of a variable.
From the point view of C compiler, a variable name identifies physical location from a
computer where variable is stored. There are two memory locations in a computer
system where variables are stored as : Memory and CPU Registers.
Functions of storage class :
To determine the location of a variable where it is stored ?
Set initial value of a variable or if not specified then setting it to default value.
Defining scope of a variable.
To determine the life of a variable.
Types of Storage Classes:
Storage classes are categorized in 4 (four) types as,
Automatic Storage Class
Register Storage Class
Static Storage Class
External Storage Class
Automatic Storage Class :
Keyword : auto
Storage Location : Main memory
Initial Value : Garbage Value
Life: Control remains in a block where it is defined.
Scope: Local to the block in which variable is declared.
Syntax : auto [data_type] [variable_name];
Example : auto int a;
Page 8
ADVANCED C PROGRAMMING
20 printf(“%d”,i);
10
}
printf(“%d”,i);
Output :3 2 1
Page 9
ADVANCED C PROGRAMMING
When the calculations are done in CPU, then the values of variables are transferred
from main memory to CPU. Calculations are done and the final result is sent back to
main memory. This leads to slowing down of processes.
Register variables occur in CPU and value of that register variable is stored in a
register within that CPU. Thus, it increases the resultant speed of operations. There is
no waste of time, getting variables from memory and sending it to back again.
It is not applicable for arrays, structures or pointers. It cannot not used with static or
external storage class.
Program :
/* Program to demonstrate register storage class.*/
#include <stdio.h>
#include <conio.h>
void main()
{
register int i=10;
clrscr();
{
register int i=20;
printf("\n\t %d",i);
}
printf("\n\n\t %d",i);
getch();
}
Output :
20
10
Static Storage Class :
Keyword : static
Storage Location : Main memory
Initial Value: Zero and can be initialize once only.
Life : depends on function calls and the whole application or program.
Scope : Local to the block.
Syntax : static [data_type] [variable_name];
Example : static int a;
Page 10
ADVANCED C PROGRAMMING
Page 11
ADVANCED C PROGRAMMING
Page 12
ADVANCED C PROGRAMMING
Page 13