0% found this document useful (0 votes)
4 views

C NOTES

The document provides an overview of advanced C programming concepts, focusing on preprocessor directives, storage classes, and their types. It explains macro expansion, file inclusion, conditional compilation, and various storage classes such as automatic, register, static, and external, detailing their characteristics and usage. Additionally, it highlights the differences between macros and functions, as well as the scope, visibility, and lifetime of variables.

Uploaded by

ravalkaran187
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

C NOTES

The document provides an overview of advanced C programming concepts, focusing on preprocessor directives, storage classes, and their types. It explains macro expansion, file inclusion, conditional compilation, and various storage classes such as automatic, register, static, and external, detailing their characteristics and usage. Additionally, it highlights the differences between macros and functions, as well as the scope, visibility, and lifetime of variables.

Uploaded by

ravalkaran187
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

ADVANCED C PROGRAMMING

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( )

{ {

int i ; float r = 6.25 ;

for ( i = 1 ; i <= UPPER ; i++ ) float area ;

printf ( "\n%d", i ) ; area = PI * r * r ;

} printf ( "\nArea of circle = %f", area ) ;

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’.

A #define directive is A #define directive could A #define directive could be


many a times used to be used even to replace a used to replace even an entire C
define operators as condition, as shown statement. This is shown below.
shown below. below.

[Example of NESTED
MACRO]

#define AND && #define AND && #define LINE printf (


"==================="
#define OR || #define ARANGE ( a > 25
);
AND a < 50 )
main( )
main( )
main( )
{
{
{
int f = 1, x = 4, y = 90
LINE;
; int a = 30 ;
Printf(“\n 1.ADDITION”);
if ( ( f < 5 ) AND ( x if ( ARANGE )
<= 20 OR y <= 45 ) ) Printf(“\n2.SUBTRACTION”);
printf ( "within range" ) ;
printf ( "\nYour PC will LINE;
else
work fine..." ) ;
}
printf ( "out of range" ) ;
else
}
printf ( "\nIn Need
maintenance" ) ;

Macro with arguments


Macros can also be used with argument so that we can obtain different replacement
text for different values of arguments. E.g.
#define AREA(x) (3 * x * x)
#include<stdio.h>
void main ( )
{
int r1 =6, r2=2,a;
a=AREA(r1);

Page 2
ADVANCED C PROGRAMMING

printf("\n Area of circle = %d",a);


a = AREA(r2);
printf("\n Area of circle = %d",a);
}

Points to remember while writing macros with arguments:


1. Be careful not to leave a blank between the macro template and its argument
while defining the macro. For example, there should be no blank between AREA
and (x) in the definition, #define AREA(x) ( 3.14 * x * x )
If we were to write AREA (x) instead of AREA(x), the (x) would become a part
of macro expansion, which we certainly don‟t want.
2. The entire macro expansion should be enclosed within parentheses. Here is an
example of what would happen if we fail to enclose the macro expansion within
parentheses.
#define SQUARE(n) n * n
void main( )
{
int j ;
j = 64 / SQUARE ( 4 ) ;
printf ( "j = %d", j ) ;
}
The output of the above program would be: j = 64
Whereas, what we expected was j = 4.
What went wrong? The macro was expanded into
j = 64 / 4 * 4 ;
This result 64.
3. Macros can be split into multiple lines, with a „\‟ (back slash) present at the end of
each line. Following program shows how we can define and use multiple line
macros.
#define ABC for ( i = 0 ; i < 50 ; i++ ) \
printf ( "=" ) ;
3] Nested Macro –
We can also use one macro in the definition of another macro. That is macro
definition may be nested. Example –
#define M 3
#define N M+4
void main()
{
printf(“\n\tM=%d\t\tN=%d”,M,N);
}

Other example of simple macros can be


#define directive is used to replace a „C‟ statement.
#defines FOREVER for (: :)
#define FOUND printf (“hello world”)

Page 3
ADVANCED C PROGRAMMING

#define is used to replace a operator and a condition


#define AND &&
#define ARRANGE (a>25 AND a<50)
The macro expansion can also contain a macro template
File inclusion
We have used #include directive in programs written so far
#include filename
The contents of the file given by filename are replaced at the point where the
directive is written.
The file inclusion statement can be written in two ways
1. #include “file-name”
If we use the first way, „C‟ would search for the file; filename in the current
working directory as well as in the specified list of directories.
2. #include <file-name>
If we use the second way, the file; filename will be searched only in the specified
list of directories

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.

A more sophisticated use of #ifdef has to do with making the programs


portable, i.e. to make them work on two totally different computers. Suppose an
organization has two different types of computers and you are expected to write a
program that works on both the machines. You can do so by isolating the lines of
code that must be different for each machine by marking them off with #ifdef.
For example:
void main( )
{
Page 4
ADVANCED C PROGRAMMING

#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

On some occasions it may be desirable to cause a defined name to become


„undefined‟. This can be accomplished by means of the #undef directive. In
order to undefine a macro that has been earlier #defined, the directive,
#undef macro template
can be used. Thus the statement,
#undef PI

 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

If we go through the program we can notice three problems immediately


1) f1() doesn‟t return a value.
2) The parameter x that is passed to f2() is not being used anywhere in f2()
3) Control can never reach x++ in f3().
If we compile the program we should expect warning indicating the above
problems. However , this does not happen since we have given the warnings
using the #pragma directives.
If we replace „-„ sign with „+‟ then these warning would be flashed on
compilation.
Macro verses Function –

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

Define the term Scope, Visibility And Lifetime of a variable.

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.

What is a Storage class?

'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

#include <stdio.h> #include <stdio.h>

#include <conio.h> #include <conio.h>

void main() void main()


{ {
auto int i=10; auto int i=1;
clrscr();
{
{
auto int i=20; auto int i =2;
printf("\n\t %d",i);
{
}
printf("\n\n\t %d",i); auto int i =3
getch();
printf(“%d”,i);
}
Output : }

20 printf(“%d”,i);
10
}

printf(“%d”,i);

Output :3 2 1

Register storage class -


 Keyword : register
 Storage Location : CPU Register
 Initial Value : Garbage
 Life : Local to the block in which variable is declared.
 Scope : Local to the block.
Syntax : register [data_type] [variable_name];
Example : register int a;

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

There are two types of static variables as :


a) Local Static Variable b) Global Static Variable
Static storage class can be used only if we want the value of a variable to
persist between different function calls.
/* Program to demonstrate static storage class.*/
#include <stdio.h>
#include <conio.h>
void increment();
void main()
{
increment();
increment();
increment();
}
void increment()
{
static int a=1;
printf("\t %d",a);
a++;
}
Output :
1 2 3

External Storage Class :


 Keyword : extern
 Storage Location : Main memory
 Initial Value : Zero
 Life : Until the program ends.
 Scope : Global to the program.
Syntax : extern [data_type] [variable_name];
Example : extern int a;
The variable access time is very fast as compared to other storage classes. But few
registers are available for user programs.
The variables of this class can be referred to as 'global or external variables.' They are
declared outside the functions and can be invoked at anywhere in a program.

Page 11
ADVANCED C PROGRAMMING

/* Program to demonstrate external storage class.*/


#include <stdio.h>
#include <conio.h>
extern int i=10;
void main()
{
int i=20;
void show(void);
clrscr();
printf("\n\t %d",i);
show();
getch();
}
void show(void)
{
printf("\n\n\t %d",i);
}
Output :
20
10
Array :
Array is a collection of homogenous data stored under unique name. The values in an
array is called as 'elements of an array.' These elements are accessed by numbers
called as 'subscripts or index numbers.' Arrays may be of any variable type.
Array is also called as 'subscripted variable.'
Types of an Array :
 One / Single Dimensional Array
 Two Dimensional Array
Single / One Dimensional Array :
The array which is used to represent and store data in a linear form is called as 'single
or one dimensional array.'
Syntax: <data-type> <array_name> [size];
Features :
 Array size should be positive number only.
 String array always terminates with null character ('\0').

Page 12
ADVANCED C PROGRAMMING

 Array elements are countered from 0 to n-1.


 Useful for multiple reading of elements (numbers).
Disadvantages :
 There is no easy method to initialize large number of array elements.
 It is difficult to initialize selected elements.
Two Dimensional Array/Multidimensional Array:
The array which is used to represent and store data in a tabular form is called as 'two
dimensional array.' Such type of array specially used to represent data in a matrix
form.
The following syntax is used to represent two dimensional array.
Syntax: <data-type> <array_nm> [row_subscript][column-subscript];
Example: int a[3][3];
* MEMORY ALLOCATION :

Memory allocation for two dimensional array


Limitations of two dimensional array :
 We cannot delete any element from an array.

 If we don‟t know that how many elements have to be stored in a memory in


advance, then there will be memory wastage if large array size is specified.

Page 13

You might also like