Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Unit 2 Notes

Download as pdf or txt
Download as pdf or txt
You are on page 1of 73

Contents

UNIT 2- Part 1: C Functions ........................................................................................................... 4


Introduction ................................................................................................................................. 4
Definition .................................................................................................................................... 4
Advantages of using function ...................................................................................................... 5
Types of function ........................................................................................................................ 6
1. Standard functions: .............................................................................................................. 6
2. User defined functions: ........................................................................................................ 6
User defined functions ................................................................................................................ 6
Elements of user defined functions ......................................................................................... 6
1. Function definition .......................................................................................................... 8
1.1 Function header ............................................................................................................. 9
a. Function name and type .......................................................................................... 9
b. Formal parameter list .............................................................................................. 9
1.2 Function body ....................................................................................................... 11
Function calls ......................................................................................................................... 13
Function declaration/ Function prototype.............................................................................. 13
Advantages of prototype ................................................................................................... 14
Positioning function declaration ....................................................................................... 14
Case 1: Function definition written before main .......................................................... 14
Case 2: Function definition written after main ............................................................. 14
Global v/s local prototype...................................................................................................... 15
Complete Example on function prototype, function definition and function call : ............... 16
Category of functions or types of function invoking ............................................................. 16
Category 1: function with no arguments & with no return value ..................................... 17
Category 2: function with no arguments & with return value .......................................... 18
Category 3: function with arguments & with no return value .......................................... 19
Category 4: function with arguments & with return value ............................................... 20
Scope rule of functions .......................................................................................................... 21
Advanced features of functions ............................................................................................. 22
1. Calling function by value or by reference................................................................. 22
1. Call by value [photocopy method] ........................................................................ 22
2. Call by Reference/Pointer/Address: ...................................................................... 24
Pointer ....................................................................................................................... 25
C Pointer to Pointer............................................................................................... 30
Pointer Arithmetic in C ......................................................................................... 53
Incrementing Pointer in C ................................................................................. 53
Decrementing Pointer in C................................................................................ 54
C Pointer Addition ............................................................................................ 55
C Pointer Subtraction ........................................................................................ 55
Summary of Call by Value and Call by Reference: ...................................................... 33
2. Advanced feature – RECURSION............................................................................ 33
Recursion v/s Iteration ........................................................................................................... 35
UNIT 2- Part 2: Storage classes................................................................................................ 37
Four storage classes in C: .......................................................................................................... 38
a. Automatic storage class: ............................................................................................... 38
Example ............................................................................................................................ 38
b. Register storage class: ................................................................................................... 39
Example ............................................................................................................................ 39
c. Static storage class: ....................................................................................................... 39
Example 1 ......................................................................................................................... 39
Example 2 ......................................................................................................................... 41
d. External storage class:................................................................................................... 41
Example ............................................................................................................................ 41
Summary................................................................................................................................ 43
The C Preprocessor..................................................................................................................... 44
UNIT 2 PART 3: ARRAYS: ........................................................................................................ 47
Arrays ........................................................................................................................................ 47
Characteristics of array .......................................................................................................... 47
Array Application .................................................................................................................. 47
Limitations of Array .............................................................................................................. 48
Single Dimensional Array : ................................................................................................... 49
Characteristics ................................................................................................................... 49
Syntax : ............................................................................................................................. 49
Example of Single Dimensional Array : ........................................................................... 50
Accessing Array Elements ........................................................................................................ 51
Relationship between pointer and arrays ...................................Error! Bookmark not defined.
Pointer to Array................................................................................................................. 56
Array of Pointers ............................................................................................................... 58
Memory allocation .................................................................................................................... 59
Dynamic memory allocation functions in C: ......................................................................... 61
1. malloc() function in C: .................................................................................................. 61
Example program for malloc() function in C: .............................................................. 61
Output: .......................................................................................................................... 62
2. calloc() function in C: ................................................................................................... 62
Example program for calloc() function in C: ................................................................ 62
Output: .......................................................................................................................... 62
3. realloc() function in C: .................................................................................................. 62
4. free() function in C: ...................................................................................................... 63
Example program for realloc() and free() functions in C: ............................................ 63
Output: .......................................................................................................................... 63
Difference between static memory allocation and dynamic memory allocation in C: ..... 63
Difference between malloc() and calloc() functions in C: ................................................ 64
UNIT 2 PART 4: Preprocessor Directives.................................................................................... 65
Most common preprocessor directives ...................................................................................... 65
#define ................................................................................................................................... 65
#include ................................................................................................................................. 65
Stringize (#) ........................................................................................................................... 67
Token Pasting (##)................................................................................................................. 68
Conditional Compilation ........................................................................................................... 69
The #if Directive .................................................................................................................... 69
#if example........................................................................................................................ 70
The #ifdef Directive............................................................................................................... 70
#ifdef example .................................................................................................................. 70
The #ifndef Directive............................................................................................................. 71
#ifndef example ................................................................................................................ 71
The #else Directive ................................................................................................................ 72
The #elif Directive ................................................................................................................. 72
The #endif Directive .............................................................................................................. 72
The defined Operator ............................................................................................................. 73

Figure 1 elements of function ......................................................................................................... 7


Figure 2 function example .............................................................................................................. 8
Figure 3 syntax for function definition ........................................................................................... 9

UNIT 2- Part 1: C Functions

Functions: declaration, definition & scope, recursion, call by value, call by reference.

Introduction

A function in C is a small “sub-program” that performs a particular task, and supports the
concept of modular programming design techniques. In modular programming the various
tasks that your overall program must accomplish are assigned to individual functions and the
main program basically calls these functions in a certain order.

Definition
A function is a self contained block of executable code that can be called from any other
function.

Arrow Means
→ Calling function with data (argument) if any
← Return to the next statement or execution with data if any

 A function in C is an independent module that will be called to o a designated task.


 A called function receives control from a calling function.
 When the called function completes its task, it returns control to the calling function.

Advantages of using function

1. Don’t have to repeat the same block of code many times in your code. Make that
code block a function and call it when needed.

2. Easy to debug. Get one function working well then move on to the others.

3. Easy to modify and expand. Just add more functions to extend program capability.

4. For a large programming project, you will code only a small fraction of the
program.

5. Make program self-documenting and readable.


Types of function

There are two types of Functions in C

1. Standard Functions (Pre-defined Functions/ Built-in functions)


2. User-defined Functions

1. Standard functions:

All standard functions, such as sqrt() , pow() , log() , sin() etc. are porvided in the library of the
functions. The standard functions are also called library functions or built in functions.
Predefined Functions are already created. Eg: printf() , scanf() , getch() , clrscr() etc.

2. User defined functions:

User defined Functions which are created by the User according to his need.

User defined functions

In order to use functions, the programmer must do three things

– Define the function


– Declare the function
– Use the function in the main code.

Elements of user defined functions


In order to make use of user defined functions, we need to establish 3 elements that are related to
functions.
elements of a function

fun. definition fun. declaration


fun. call

fun. type
function fun.
header body
fun. name
fun type local
declaration
parameter
fun. name list
fun. stms.

formal terminatin
parameters returm stmt. g
semicolon

Figure 1 elements of function

Important definitions:

1. Function definition:
a. Is also called as function implementation
b. Is an independent program module that is specifically written to implement the
requirements of the function.
2. Function call:
a. In order to use a function, we need to invoke it at a regular place in the program.
This is known as function call.
3. Calling function:
a. the program that calls the function is referred to as the calling function.
4. Function declaration/ prototype:
a. The calling program should declare any function that is to be used later in the
program. This is known as function declaration or function prototype.

Figure 2 function example

1. Function definition

• function name
function • function return type
header • list of parameters

• local variable declaration


function • function statements
body • return statements
Function header
Returntype functionName (formal argument list)

Function Body
{
// Local declarations

// statements

…// return value „


}

Figure 3 syntax for function definition

1.1 Function header


It consists of

a. Function name and type

The function type specifies the type of value (like float or double) that the function is expected to
return to the program calling the function.

If the return type is not explicitly specified, C will assume that it is an integer type.

If the function is not returning anything, then we need to specify the return type as void.

The function name is any valid C identifier and therefore must follow the same rules of
formation as the other variable names in C.

b. Formal parameter list

The parameter list declares the variables that will receive the data sent by the calling program.

They serve as an input data to the function to carry out the specified task.
Since, they represent actual input values; they are often referred to as formal parameters.

[Parameters written at the time of function definition are known as formal parameters.]

For example

float quadratic (int a, int b, int c)


{ Formal parameters

… Return type function name

Difference between parameters and arguments

parameters arguments
1. The names given in the function 1. The values supplied in the function call are
definition are called Parameters called Arguments.

2. An object declared in a function definition 2.An expression in the comma separated list in a
or declaration. function call.

3. Also know as formal parameters 3. Also known as actual parameters.

For example

#include <stdio.h>

int add(int a, int b); //function prototype(declaration)…a & b are parameters

void main(){

int num1,num2,sum;

printf("Enters two number to add\n");

scanf("%d %d",&num1,&num2);

sum=add(num1,num2); //function call ………num1 & num2 are arguments

printf("sum=%d",sum);
getch();

int add(int a,int b) //function definition…………a & b are parameters

/* Start of function definition. */

int add;

add=a+b;

return (add); //return statement of function

/* End of function definition. */

1.2 Function body

The function body contains the declaration and statements necessary for performing the required
task.

The body enclosed in braces, contains 3 parts

a. Local declarations that specify the variables needed by the function.


b. Function statements that perform the task of the function.
c. A return statement that returns the value evaluated by the function.

If a function does not return any value, we can omit the return statement. In this case, return type
should be specified as void.

For example

1. Float mul( float x, float y)


{
Float result; //local variables
Result= x * y; //computes the product
Return(result); //returns the result
}
2. Void display(void)
{
Printf (“no type, no parameter”);
}
Return value and their types
A function may or may not send back any value to the calling function. If it does, it is
done through the return statement.

Syntax :

1. Return;

It does not return any value.


When such a return is encountered, the control is immediately passed back to the calling
function .

For example if(error)


Return;

2. Return(expression )

Returns the value of the expression.

For example

Int mul(int x, int y)

Int p;

P=x*y;

Return(p); //

}
Function calls
A function can be called by simply using the name followed by a list of actual parameters, if any,
enclosed in parentheses.

Function declaration/ Function prototype


A function prototype is a function declaration that specifies the data types of its arguments in the
parameter list.

It consists of 4 parts

1. Function type
2. Function name
3. Parameter list
4. Terminating semicolon [ only difference between declaration and definition syntax]
Syntax:

Functiontype FunctionName (parameter list);

 Prototype can be written either before main or inside main()

Advantages of prototype
1. It tells about the return type
2. It tells how many parameters there are, and what their types are.
3. If this prototype is provided, the compiler will catch the error in main (). If it is
omitted, then the error may go unnoticed.

Note:

1. Parameter names need not to be same in function declaration or function definition.


2. Types must match the types of parameters in function definition, in number and order.
3. Function declaration requires that every function which is to be accessed should be
declared in the calling function.

Positioning function declaration

1. If function definition is written after main then and then only we write prototype
declaration in global declaration section
2. If function definition is written above the main function then ,no need to write prototype
declaration

Case 1: Function definition written before main


NO NEED OF PROTOTYPE

#include<stdio.h>

void displayMessage() {
printf("www.c4learn.com");
}

void main() {
displayMessage();
}

Case 2: Function definition written after main


NEED OF PROTOTYPE
#include<stdio.h>

//Prototype Declaration
void displayMessage();

void main() {
displayMessage();
}

void displayMessage() {
printf("www.c4learn.com");
}

Global v/s local prototype


A prototype declaration may be placed in 2 places in a program:

1. Above all the functions(including main)


2. Inside the main function

When we place the declaration above all the functions, the prototype is referred to as global
prototype.

When we place the declaration inside the main functions, the prototype is referred to as local
prototype.

For example

#include <stdio.h>

Void main()

Int n, sq;

Int square(int); //function prototype

Printf (“enter a number”);

Scanf (“%d”,&n);

Sq=square(n); // function call with parameter passing

Printf (“Square is %d”,sq);

}
Int square(int no) // passing of argument

Int result; // local variable to function square

Result= no * no;

Return (result); // returns an integer value

Complete Example on function prototype, function definition and function call :


Write a C program to add two integers. Make a function add to add integers and display sum in
main() function.

/*Program to demonstrate the working of user defined function*/

#include <stdio.h>
int add(int a, int b); //function prototype(declaration)
int main(){
int num1,num2,sum;
printf("Enters two number to add\n");
scanf("%d %d",&num1,&num2);
sum=add(num1,num2); //function call
printf("sum=%d",sum);
return 0;
}
int add(int a,int b) //function declarator
{
/* Start of function definition. */
int add;
add=a+b;
return add; //return statement of function
/* End of function definition. */
}

Category of functions or types of function invoking


A function depending on whether arguments are present or not and whether a value is returned or
not, may belong to one of the following categories:

Category 1: function with no arguments & with no return value

Category 2: function with no arguments & with return value


Category 3: function with arguments & with no return value

Category 4: function with arguments & with return value

e
lu
e

va
lu
va

rn
rn

tu
tu
re

re
o

No
N
1 2

No arguments 3 4

Arguments

Category 1: function with no arguments & with no return value

The called Function does not receive any data from the calling Function and it does not return
any data back to the calling Function. Hence, there is no data transfer between the calling
Function and called Function.
Category 2: function with no arguments & with return value

The called Function does not receive any data from the calling Function but does send some
value to the calling function, then that the function falls in this category.

#include<stdio.h>
#include<conio.h>
void main()
{
float sum;
float total();
clrscr();
sum = total();
printf(" Sum = %f\n" , sum);
}
float total()
{
float a, b;
a = 5.0 ;
b = 15.0 ;
return(a+b);
}

Output:
Sum = 20.000000

Category 3: function with arguments & with no return value

Here the called Function receives the data from the calling function but the called function does
not return any value back to the calling function.

Types of arguments

1. Actual arguments – the arguments of calling function are actual arguments.


2. Formal arguments – the arguments of called function are formal arguments.

For example

main()

abc(x,y,z); // function call with actual arguments

abc (j,k,l) //function definition with formal arguments

return() //return value

For example

#include<stdio,h>

Main()
{

Int dat(int,int,int);

Int d,m,y;

Printf (“enter date in dd/mm/yy format”);

Scanf (%d%d%d”,&d,&m,&y);

Dat(d,m,y);

Return 0;

Dat (int x, intr y , int z)

Printf(“date = %d / %d / %d”,x,y,z);

Category 4: function with arguments & with return value

In this category, two way communications takes place between the calling and called function i.e
a function returns a value and also arguments are passed to it.

For example

#include<stdio.h>
float calculate_area(int);
int main()
{
int radius;
float area;
printf("\nEnter the radius of the circle : ");
scanf("%d",&radius);
area = calculate_area(radius);
printf("\nArea of Circle : %f ",area);
return(0);
}
float calculate_area(int radius)
{
float areaOfCircle;
areaOfCircle = 3.14 * radius * radius;
return(areaOfCircle);
}

Output:

Enter the radius of the circle: 2


Area of Circle: 12.56

Scope rule of functions


The place of declaration of a function defines a region in which the function may be used by
other functions. This region is known as the scope of the functions.

Scope of a variable is local to the function in which it is defined.

For example

#include <stdio.h>

Void display(int);

Void main()

Int i=20;
display(i) //20
}

display(i)

Void display(int j) //20

int k =35;
Printf (“\n %d”,j); //20
Printf (“\n %d”,k); //35
}
Output: j=20 k=35

In the above program, it is necessary to pass the value of the variable “i” to the display(), because
by default, the scope of a variable is local to the function in which it is defined.

Similarly , the variable k is local to the display() and hence it is not available to main().

Advanced features of functions


1. Calling function by value or by reference
2. Recursion

1. Calling function by value or by reference

1. Call by value [photocopy method]


In this type, value of actual arguments is passed to the formal arguments and the operation is
done on formal arguments. Any change in the formal arguments does not affect the actual
arguments because formal arguments are photocopy of actual arguments.

Hence, when function is called by value method, it does not affect the actual arguments.

Changes made in the formal arguments are local to the block of the called function. Once control
returns back to the calling function, the changes made vanish.

Example 1

#include<stdio.h>

#include<conio.h>

Void display(int);

Void main()

Int i=7;

Clrscr();

I=i+3;

Printf (\n value of i in main() before calling display=%d”.i);

Display(i);
Printf (\n value of i in main() after calling display=%d”.i);

Getch();

Void display(int k)

Int k;

K=k+3;

Printf (“\n value of I in display()= %d”.k);

Example 2

#include<stdio.h>

void interchange(int number1,int number2)


{
int temp;
temp = number1;
number1 = number2;
number2 = temp;
}

int main() {

int num1=50,num2=70;
interchange(num1,num2);

printf("\nNumber 1 : %d",num1);
printf("\nNumber 2 : %d",num2);

return(0);
}
Output :
Number 1 : 50
Number 2 : 70

Explanation: Call by Value


1. While Passing Parameters using call by value , xerox copy of original parameter is
created and passed to the called function.
2. Any update made inside method will not affect the original value of variable in calling
function.
3. In the above example num1 and num2 are the original values and xerox copy of these
values is passed to the function and these values are copied into number1,number2
variable of sum function respectively.
4. As their scope is limited to only function so they cannot alter the values inside main
function.

2. Call by Reference/Pointer/Address:
#include<stdio.h>

void interchange(int *num1,int *num2)


{
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}

int main() {

int num1=50,num2=70;
interchange(&num1,&num2);

printf("\nNumber 1 : %d",num1);
printf("\nNumber 2 : %d",num2);

return(0);
}

Output :
Number 1 : 70
Number 2 : 50

Explanation: Call by Address

1. While passing parameter using call by address scheme, we are passing the actual
address of the variable to the called function.
2. Any updates made inside the called function will modify the original copy since we are
directly modifying the content of the exact memory location.

Pointer
Define pointers

A pointer is a special variable in C language meant just to store address of any other variable or
function. Pointer variables unlike ordinary variables cannot be operated with all the arithmetic
operations such as '*','%' operators.
It follows a special arithmetic called as pointer arithmetic.

A pointer is declared as:

Syntax: datatype *ptr;

int *ap;

int a = 5;

In the above two statements an integer a was declared and initialized to 5. A pointer to an integer
with name ap was declared.

Next before ap is used

ap=&a;

This operation would initialize the declared pointer to int. The pointer ap is now said to point to
a.

Similarly

double *dp; /* pointer to a double */


float *fp; /* pointer to a float */
char *ch /* pointer to a character */

Operations on a pointer:
· Dereferencing operator ' * ': This operator gives the value at the address pointed by the
pointer . For example after the above C statements if we give

printf("%d",*ap);

Actual value of a i.e 5 would be printed. That is because ap points to a.

Advantages of using pointers

1. The length and complexity of a program is reduced.


2. Pointers allow us to pass values to functions using call by reference.
3. Dynamic allocation of memory is possible with the help of pointers.
4. Pointers point to physical memory and allow quicker access to data.

Disadvantages of pointers:

1. If sufficient memory is not available during runtime for the storage of pointers, the
program may crash.

Normal variable v/s pointer variable


 Normal variable provides direct access to their own values.
 Pointer variable provides indirect access to the variable whose address it stores

Print the address of any variable / use of & operator

#include <stdio.h>

void main ()
{
int var1;
char var2[10];

printf("Address of var1 variable: %u\n", &var1 );


printf("Address of var2 variable: %u\n", &var2 );

getch();
}

When the above code is compiled and executed, it produces result something as follows:

Address of var1 variable: 4066

Address of var2 variable: 4068


Assignments x = 1 and y = 2 obviously load these values into the variables.

ip is declared to be a pointer to an integer and is assigned to the address of x (&x). So ip gets


loaded with the value 100.

Next y gets assigned to the contents of ip. In this example ip currently points to memory location
100 -- the location of x. So y gets assigned to the values of x -- which is 1.

We have already seen that C is not too fussy about assigning values of different type. Thus it is
perfectly legal (although not all that common) to assign the current value of ip to x. The value of
ip at this instant is 100.

Finally we can assign a value to the contents of a pointer (*ip).

Void main( )
{
int i = 3 ;
int *j ;
j = &i ;
printf ( "\nAddress of i = %u", &i ) ;
printf ( "\nAddress of i = %u", j ) ;
printf ( "\nAddress of j = %u", &j ) ;
printf ( "\nValue of j = %u", j ) ;
printf ( "\nValue of i = %d", i ) ;
printf ( "\nValue of i = %d", *( &i ) ) ;
printf ( "\nValue of i = %d", *j ) ;
getch();
}

Address of i = 65524
Address of i = 65524
Address of j = 65522
Value of j = 65524
Value of i = 3
Value of i = 3
Value of i = 3

Void main( )
{
int i = 3, *j, **k ;
j = &i ;
k = &j ;
printf ( "\nAddress of i = %u", &i ) ;
printf ( "\nAddress of i = %u", j ) ;
printf ( "\nAddress of i = %u", *k ) ;
printf ( "\nAddress of j = %u", &j ) ;
printf ( "\nAddress of j = %u", k ) ;
printf ( "\nAddress of k = %u", &k ) ;
printf ( "\nValue of j = %u", j ) ;
printf ( "\nValue of k = %u", k ) ;
printf ( "\nValue of i = %d", i ) ;
printf ( "\nValue of i = %d", * ( &i ) ) ;
printf ( "\nValue of i = %d", *j ) ;
printf ( "\nValue of i = %d", **k ) ;
}
The output of the above program would be:

Address of i = 65524
Address of i = 65524
Address of i = 65524
Address of j = 65522
Address of j = 65522
Address of k = 65520
Value of j = 65524
Value of k = 65522

Value of i = 3
Value of i = 3
Value of i = 3
Value of i = 3
C Pointer to Pointer

In C pointer to pointer concept, a pointer refers to the address of another pointer.

In c language, a pointer can point to the address of another pointer which points to the address of
a value. Let's understand it by the diagram given below:

Let's see the syntax of pointer to pointer.

int **p2;

C pointer to pointer

Example 1

Let‟s suppose we have a pointer „p1′ that points to yet another pointer „p2′ that points to a
character „c‟. In memory, the three variables can be visualized as :
So we can see that in memory, pointer p1 holds the address of pointer p2. Pointer p2 holds the
address of character „c‟.

So „p2′ is pointer to character „c‟, while „p1′ is pointer to „p2′ or we can also say that „p2′ is a
pointer to pointer to character „c‟.

Now, in code „p2′ can be declared as :

char *p2 = &c;

But „p1′ is declared as :

char **p1 = &p2;

So we see that „p1′ is a double pointer (ie pointer to a pointer to a character) and hence the two
*s in declaration.

Now,

 „p1′ is the address of „p2′ ie 5000


 „*p1′ is the value held by „p2′ ie 8000
 „**p1′ is the value at 8000 ie „c‟

I think that should pretty much clear the concept, lets take a small example :

#include<stdio.h>

int main(void)
{
char **ptr = NULL;

char *p = NULL;

char c = 'd';

p = &c;
ptr = &p;

printf("\n c = [%c]\n",c);
printf("\n *p = [%c]\n",*p);
printf("\n **ptr = [%c]\n",**ptr);

return 0;
}

Here is the output :

$ ./doubleptr

c = [d]
*p = [d]

**ptr = [d]

Example 2

Let's see an example where one pointer points to the address of another pointer.

As you can see in the above figure, p2 contains the address of p (fff2) and p contains the address
of number variable (fff4).

#include <stdio.h>
#include <conio.h>
void main(){
int number=50;
int *p;//pointer to int
int **p2;//pointer to pointer
clrscr();
p=&number;//stores the address of number variable
p2=&p;

printf("Address of number variable is %x \n",&number);


printf("Address of p variable is %x \n",p);
printf("Value of *p variable is %d \n",*p);
printf("Address of p2 variable is %x \n",p2);
printf("Value of **p2 variable is %d \n",**p);

getch();
}

Output
Address of number variable is fff4
Address of p variable is fff4
Value of *p variable is 50
Address of p2 variable is fff2
Value of **p variable is 50

Summary of Call by Value and Call by Reference:


Point Call by Value Call by Reference

Duplicate Copy of Original Parameter Actual Copy of Original Parameter is


Copy
is Passed Passed

The values of actual arguments are The addresses of actual arguments are
Substitution substituted in formal arguments which substituted in formal arguments which are
are ordinary variables. pointer variable.

No effect on Original Parameter after Original Parameter gets affected if value


Modification
modifying parameter in function of parameter changed inside function

Example Swapping example Swapping example

2. Advanced feature – RECURSION

1. Recursion is basic concept in Programming.


2. When Function is defined in terms of itself then it is called as “Recursion Function“.
3. Recursive function is a function which contains a call to itself.

Recursive function must have at least one terminating condition that can
be satisfied.

Example 1

Factorial
#include<stdio.h>

long factorial(int);

void main()
{
int n;
long f;
printf("Enter an integer to find factorial\n");
scanf("%d", &n);

if (n < 0)
printf("Negative integers are not allowed.\n");
else
{
f = factorial(n);
printf("%d! = %ld\n", n, f);
}

Getch();
}

long factorial(int n)
{
if (n == 0)
return 1;
else
return(n * factorial(n-1));
}

Practice question on recursion


1. WAP to find sum of first n natural numbers using recursion.

Recursion v/s Iteration

Parameter Recursion Iteration


Control structure Uses a selection structure Uses a repetition structure
Repetition Achieves repetition through repeated function Explicitly uses a repetition
calls. structure.

Termination test Terminates when a base case is recognized Terminates when the loop
continuation condition fails.

Condition for Infinite recursion occurs if the recursion step does Infinite loop occurs with iteration
infinite execution not reduce the problem in a manner that if the loop continuation test never
converges on the base case. becomes false.
Efficiency Recursive solutions are often less efficient in More efficient.
terms of both time and space.
UNIT 2- Part 2: Storage classes

The scope of a variable determines the region of the program in which it is known. An
identifier's "visibility" determines the portions of the program in which it can be
referenced—its "scope." An identifier is visible only in portions of a program
encompassed by its "scope," which may be limited to the file, function or block in which
it appears.

File scope: The variables and functions with file scope appear outside any block or list
of parameters and is accessible from any place in the translation unit after its
declaration.
Identifier names with file scope are often called "global" or "external." The scope of a
global identifier begins at the point of its definition or declaration and terminates at the
end of the translation unit. A function has file scope.

Function scope: A label is the only kind of identifier that has function scope. A label is
declared implicitly by its use in a statement. Label names must be unique within a
function however a label having the same name in two different functions is allowed.

Block scope: The variables with block scope appear inside a block or within the list of
formal parameter declarations in a function definition. It is visible only from the point of
its declaration or definition to the end of the block containing its declaration or definition.
Its scope is limited to that block and to any blocks nested in that block and ends at the
curly brace that closes the associated block. Such identifiers are sometimes called
"local variables."

A variable’s storage class tells us:

 Memory location i.e. where variable would be stored.


 Initial value or default value of variable
 What is scope of the variable
 What is life of the variable

Scope of variable:

Scope of variable i.e. in which function the value of the variable would be available.

Life of the variable:

The life of the variable i.e. how long would the variable exists.
Four storage classes in C:

a. Automatic storage class:


The features of variables are as follows

-Storage: Memory
-Default initial value: Garbage value
-Scope: Local to the block in which defined
-Life: till the control remains within the block in which defined.

Example

1 #include<stdio.h>
2 void increment(void);
3
4 int main()
5 {
6 increment();
7 increment();
8 increment();
9 increment();
10 }
11
12 void increment(void)
13 {
14 auto int i = 0 ;
15 printf ( "%d \n", i ) ;
16 i++;
17 }

Output:
0
0
0
0
b. Register storage class:
The features of variables are as follows

-Storage: CPU registers


-Default initial value: Garbage value
-Scope: Local to the block in which defined
-Life: till the control remains within the block in which defined

Example

All looping program where a variable are frequently used, declare variable as register.

/*shows uses of register storage class*/


#include<stdio.h>
int main()
{
register int i;
for(i=10; i>=0; i=i-2)
printf("%d ",i);
return 0;
}

OUTPUT:-

10 8 6 4 2 0

c. Static storage class:


The features of variables are as follows

-Storage: Memory
-Default initial value: Zero
-Scope: Local to the block in which defined
-Life: value of variable persists between different function calls.

Example 1
main()
{

add();

add();

add()

static int i=10;

printf(“\n%d”,i);

i=i+1;

Output:

10

11
Example 2
1 //C static example
2 #include<stdio.h>
3 void increment(void);
4
5 int main()
6 {
7 increment();
8 increment();
9 increment();
10 increment();
11 }
12
13 void increment(void)
14 {
15 static int i = 0 ;
16 printf ( "%d \n", i ) ;
17 i++;
18 }

Output:
0
1
2
3

d. External storage class:

The features of variables are as follows

-Storage: Memory
-Default initial value: Zero
-Scope: global
-Life: As long as program execution does not come to an end.

Example
1 #include<stdio.h>
2 int x = 10 ;
3 int main( )
4 {
5 extern int y ;
6 printf ( "The value of x is %d \n", x ) ;
7 printf ( "The value of y is %d",y ) ;
8 }
9 int y = 50 ;

Output:
The value of x is 10
The value of y is 50
Summary
The C Preprocessor
Preprocessor directives are actually the instructions to the compiler itself. They are not
translated but are operated directly by the compiler. Note that preprocessor statements begin with
a #symbol, and are NOT terminated by a semicolon. Traditionally, preprocessor statements are
listed at the beginning of the source file. They are also termed as macros.

The C preprocessor is a macro processor that is used automatically by the C compiler to


transform our program before actual compilation. It is called a macro processor because it allows
us to define macros, which are brief abbreviations for longer constructs.

In simplistic terms, a C Preprocessor is just a text substitution tool and they instruct compiler to
do required pre-processing before actual compilation.

The C preprocessor provides four separate facilities that we can use:

1. Inclusion of header files. These are files of declarations that can be substituted into your
program.

2. Macro expansion. We can define macros, which are abbreviations for arbitrary
fragments of C code, and then the C preprocessor will replace the macros with their
definitions throughout the program.

3. Conditional compilation. Using special preprocessing directives, we can include or


exclude parts of the program according to various conditions.

4. Line control. If we use a program to combine or rearrange source files into an


intermediate file which is then compiled, we can use line control to inform the compiler
of where each source line originally came from.

Advantages of preprocessor:

1. Programs easier to develop,


2. Easier to read,
3. Easier to modify
4. C code more transportable between different machine architectures.
Macro expansion

Example:

Before preprocessing After preprocessing

#include<stdio.h> #include<stdio.h>
#define TEN 10 void main()
void main() {
{ int a = 10;
int a = 10; if (a == 10)
if (a == TEN) {
{ printf("The value of a is 10");
printf("The value of a is 10"); }
} }
}

If we run the above example, in both cases we will get the output as "The value of a is 10".

The above explained macro is called as „Simple macro‟. There is another form of macro called
„Macros with Arguments‟.

„Macros with Arguments’

Example:
Before preprocessing After preprocessing

#include<stdio.h> #include<stdio.h>
#define AREA (3.14 * a * a) void main()
void main() {
{ int ar = 3.14 * 10 * 10;
int ar = AREA(10); printf("Area = %f", ar);
printf("Area = %f", ar); }
}

If we run the above example, we will get the output as “AREA = 314.000000”.
In the above example, we have used macros with arguments. As we learnt, before compilation
process the Source code goes through preprocessing process. During preprocessing, the program
is scanned from top to bottom. Every occurrence of AREA(10) in the source code is replaced by
(3.14 * 10 * 10).
Predefined Macros
ANSI C defines a number of macros. Although each one is available for use in programming, the
predefined macros should not be directly modified.

Macro Description

__DATE__ The current date as a character literal in


"MMM DD YYYY" format

__TIME__ The current time as a character literal in


"HH:MM:SS" format

__FILE__ This contains the current filename as a string


literal.

__LINE__ This contains the current line number as a


decimal constant.

__STDC__ Defined as 1 when the compiler complies with


the ANSI standard.

Example:

#include <stdio.h>

main()
{
printf("File :%s\n", __FILE__ );
printf("Date :%s\n", __DATE__ );
printf("Time :%s\n", __TIME__ );
printf("Line :%d\n", __LINE__ );
}

When the above code in a file test.c is compiled and executed, it produces the following result:

File :test.c
Date :Jun 2 2012
Time :03:36:24
Line :8

Explanation:

The above program uses 5 macros in printf() statement.the program displays program file name,
system date, time, total lines of the program.
UNIT 2 PART 3: ARRAYS:

Arrays, pointers, array & pointer relationship, pointer arithmetic, dynamic memory allocation,
pointer to arrays, array of pointers, pointers to functions, array of pointers to functions

Arrays

An array is a container object that holds a fixed number of values of a single type. The length of
an array is established when the array is created. After creation, its length is fixed.

An array is a sequence of data item of homogeneous value (same type). We cannot have an array
of 10 indices storing 5 int and 5 float values.

Array of characters is known as string.

Array of integer/float values is known simply as array.

Characteristics of array
1. An array is a collection of similar elements.
2. The first index of an array is zero, so the last element is 1 less than the size of array.
3. An array is also known as subscripted variable.
4. Before using an array, its type & dimension must be declared.
5. All the elements of an array share the same name; and they are distinguished from one
another with the help of an element number.
6. However big an array, its elements are always stored in contiguous memory locations.

Array Application

1. Stores Elements of Same Data Type


2. Array Used for maintaining multiple variable names using single name
3. Array Can be Used for Sorting Elements
4. Array Can Perform Matrix Operation
5. Array can be used in CPU Scheduling: CPU Scheduling is generally managed by Queue.
Queue can be managed and implemented using the array.

Arrays are of two types:

1.

Limitations of Array

1. Static Data

1. Array is Static data Structure


2. Memory Allocated during Compile time.
3. Once Memory is allocated at Compile Time it Cannot be Changed during Run-time
2. Can hold data belonging to same Data types
3. Inserting data in Array is Difficult

1. Inserting element is very difficult because before inserting element in an array


we have to create empty space by shifting other elements one position ahead.
2. This operation is faster if the array size is smaller, but same operation will be
more and more time consuming and non-efficient in case of array with large size.

4. Deletion Operation is difficult

1. Deletion is not easy because the elements are stored in contiguous memory
location.
2. Like insertion operation, we have to delete element from the array and after
deletion empty space will be created and thus we need to fill the space by moving
elements up in the array.

5. Bound Checking

1. If we specify the size of array as „N‟ then we can access elements upto „N-1′ but
in C if we try to access elements after „N-1′ i.e Nth element or N+1th element
then we does not get any error message.
2. Process of Checking the extreme limit of array is called Bound Checking and C
does not perform Bound Checking.
3. If the array range exceeds then we will get garbage value as result.

6. Shortage of Memory

1. Array is Static data structure. Memory can be allocated at compile time only Thus
if after executing program we need more space for storing additional information
then we cannot allocate additional space at run time.
2. Shortage of Memory , if we don‟t know the size of memory in advance

7. Wastage of Memory , if array of large size is defined

Single Dimensional Array :

Characteristics
1. Single or One Dimensional array is used to represent and store data in a linear form.

2. Array having only one subscript variable is called One-Dimensional array

3. It is also called as Single Dimensional Array or Linear Array

Syntax :
<data-type> <array_name> [size];
Example of Single Dimensional Array :

 int num[5] = {2, 8,7,6,0};

 char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};


or
char greeting[] = "Hello";

 float x[8] = {16.0, 12.0, 6.0, 8.0, 2.5, 12.0, 14.0, -54.5}
Accessing Array Elements
An element is accessed by indexing the array name.

Arrayname[index]

For example:

printf ( "%d" , age[0]); /* statement to print first element of an array. */

double salary = balance[9];

The above statement will take 10th element from the array balance and assign the value to salary
variable.

#include <stdio.h>

void main ()
{
int count[ 10 ]; /* n is an array of 10 integers */
int i ,j, k=0;

/* initialize elements of array n to 0 */


for ( i = 0; i < 10; i++ )
{
count[ i ] = k;
k=k+1;
}

/* output each array element's value */


for (j = 0; j < 10; j++ )
{
printf("Element[%d] = %d\n", j, count[j] );
}

getch();
}
When the above code is compiled and executed, it produces the following result:

Element[0] = 0
Element[1] = 1
Element[2] = 2
Element[3] = 3
Element[4] = 4
Element[5] = 5
Element[6] = 6
Element[7] = 7
Element[8] = 8
Element[9] = 9

Arrays and pointer relationship

When an array is declared, compiler allocates sufficient amount of memory to contain all the
elements of the array. Base address which gives location of the first element is also allocated by
the compiler.

Suppose we declare an array arr,

int arr[5]={ 1, 2, 3, 4, 5 };

Assuming that the base address of arr is 1000 and each integer requires two byte, the five
elements will be stored as follows

Here variable arr will give the base address, which is a constant pointer pointing to the element,
arr[0]. Therefore arr is containing the address of arr[0] i.e 1000.

arr is equal to &arr[0] // by default

We can declare a pointer of type int to point to the array arr.

int *p;
p = arr;
or
p = &arr[0]; //both the statements are equivalent.

Now we can access every element of array arr using p++ to move from one element to another.

NOTE : You cannot decrement a pointer once incremented. p-- won't work.

Pointer Arithmetic in C

In C pointer holds address of a value, so there can be arithmetic operations on the pointer
variable. Following arithmetic operations are possible on pointer in C language:

 Increment
 Decrement
 Addition
 Subtraction
 Comparison

Incrementing Pointer in C

Incrementing a pointer is used in array because it is contiguous memory location. Moreover, we


know the value of next location.

Increment operation depends on the data type of the pointer variable. The formula of
incrementing pointer is given below:

1. new_address= current_address + i * size_of(data type)

32 bit

For 32 bit int variable, it will increment to 2 byte.

64 bit

For 64 bit int variable, it will increment to 4 byte.

Let's see the example of incrementing pointer variable on 64 bit OS.

1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6.
7. printf("Address of p variable is %u \n",p);
8. p=p+1;
9. printf("After increment: Address of p variable is %u \n",p);
10. }

Output
Address of p variable is 3214864300
After increment: Address of p variable is 3214864304

Decrementing Pointer in C

Like increment, we can decrement a pointer variable. The formula of decrementing pointer is
given below:

1. new_address= current_address - i * size_of(data type)

32 bit

For 32 bit int variable, it will decrement to 2 byte.

64 bit

For 64 bit int variable, it will decrement to 4 byte.

Let's see the example of decrementing pointer variable on 64 bit OS.

1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6.
7. printf("Address of p variable is %u \n",p);
8. p=p-1;
9. printf("After decrement: Address of p variable is %u \n",p);
10. }

Output
Address of p variable is 3214864300
After decrement: Address of p variable is 3214864296
C Pointer Addition

We can add a value to the pointer variable. The formula of adding value to pointer is given
below:

1. new_address= current_address + (number * size_of(data type))

32 bit

For 32 bit int variable, it will add 2 * number.

64 bit

For 64 bit int variable, it will add 4 * number.

Let's see the example of adding value to pointer variable on 64 bit OS.

1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6.
7. printf("Address of p variable is %u \n",p);
8. p=p+3; //adding 3 to pointer variable
9. printf("After adding 3: Address of p variable is %u \n",p);
10. }

Output
Address of p variable is 3214864300
After adding 3: Address of p variable is 3214864312

As you can see, address of p is 3214864300. But after adding 3 with p variable, it is 3214864312
i.e. 4*3=12 increment. Since we are using 64 bit OS, it increments 12. But if we were using 32
bit OS, it were incrementing to 6 only i.e. 2*3=6. As integer value occupies 2 byte memory in 32
bit OS.

C Pointer Subtraction

Like pointer addition, we can subtract a value from the pointer variable. The formula of
subtracting value from pointer variable is given below:

1. new_address= current_address - (number * size_of(data type))


32 bit

For 32 bit int variable, it will subtract 2 * number.

64 bit

For 64 bit int variable, it will subtract 4 * number.

Let's see the example of subtracting value from pointer variable on 64 bit OS.

1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6.
7. printf("Address of p variable is %u \n",p);
8. p=p-3; //subtracting 3 from pointer variable
9. printf("After subtracting 3: Address of p variable is %u \n",p);
10. }

Output
Address of p variable is 3214864300
After subtracting 3: Address of p variable is 3214864288

You can see after subtracting 3 from pointer variable, it is 12 (4*3) less than the previous address
value.

Pointer to Array

As studied above, we can use a pointer to point to an Array, and then we can use that pointer to
access the array. Lets have an example,

int i;
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // same as int*p = &a[0]
for (i=0; i<5; i++)
{
printf("%d", *p);
p++;
}
In the above program, the pointer *p will print all the values stored in the array one by one. We
can also use the Base address (a in above case) to act as pointer and print all the values.

There are 4 methods for referring to array elements:

1. array subscripting
2. pointer offset with the array name as a pointer
3. pointer subscripting
4. pointer / offset with a pointer

for example int b[]={10,20,30,40};

int *bptr=&b

Method Notation Value


Array subscript notation B[i]
B[0] 10
B[1] 20
And so on….. And so on…
Pointer offset with the array *(b+offset)
name as a pointer *(b+0) 10
*(b+1) 20
And so on…. And so on….
Pointer subscripting Bptr [i]
Bptr[0] 10
Bptr[1] 20
And so on…. And so on….
Pointer/offset with a pointer *(bptr +offset)
*(bpte + 0) 10
*(bptr +1) 20
And so on…. And so on….

Array of Pointers

Just like array of integers or characters, there can be array of pointers too.

An array of pointers can be declared as :

<type> *<name>[<number-of-elements];

For example :

char *ptr[3];

The above line declares an array of three character pointers.

Lets take a working example :

#include<stdio.h>

int main(void)
{
char *p1 = "Himanshu";
char *p2 = "Arora";
char *p3 = "India";

char *arr[3];

arr[0] = p1;
arr[1] = p2;
arr[2] = p3;

printf("\n p1 = [%s] \n",p1);


printf("\n p2 = [%s] \n",p2);
printf("\n p3 = [%s] \n",p3);

printf("\n arr[0] = [%s] \n",arr[0]);


printf("\n arr[1] = [%s] \n",arr[1]);
printf("\n arr[2] = [%s] \n",arr[2]);
return 0;
}

In the above code, we took three pointers pointing to three strings. Then we declared an array
that can contain three pointers. We assigned the pointers „p1′, „p2′ and „p3′ to the 0,1 and 2 index
of array. Let‟s see the output :
$ ./arrayofptr

p1 = [Himanshu]

p2 = [Arora]

p3 = [India]

arr[0] = [Himanshu]

arr[1] = [Arora]

arr[2] = [India]

So we see that array now holds the address of strings.

Pointers to functions
Every function defined in C language has a base address attached to it. This base address acts as
an entering point into that function. This address can be stored in a pointer known as a function
pointer.

A function pointer can be declared as :

<return type of function> (*<name of pointer>) (type of function arguments)

For example :

void (*fptr)(int, int)

The above line declares a function pointer „fptr‟ that can point to a function whose return type is
„void‟ and takes two integers as arguments.

Lets take a working example :

#include<stdio.h>

void func (int a, int b)


{
printf("\n a = %d\n",a);
printf("\n b = %d\n",b);
}

void (*fptr)(int,int); // Function pointer


void main()
{
clrscr();
fptr = func; // Assign address to function pointer

func(2,3);
fptr(12,13);

getch();
}

In the above example, we defined a function „func‟ that takes two integers as inputs and returns
an integer. In the main() function, we declare a function pointer „fptr‟ and then assign value to it.
Note that, name of the function can be treated as starting address of the function so we can assign
the address of function to function pointer using function‟s name. Lets see the output :

$ ./fptr

a = 2

b = 3

a = 2

b = 3

So from the output we see that calling the function through function pointer produces the same
output as calling the function from its name.

Array of pointers to functions

Memory allocation

The process of allocating memory during program execution is called dynamic memory
allocation.
Dynamic memory allocation functions in C:

C language offers 4 dynamic memory allocation functions. They are,

1. malloc()
2. calloc()
3. realloc()
4. free()

S.no Function Syntax

1 malloc () malloc (number *sizeof(int));

2 calloc () calloc (number, sizeof(int));

3 realloc () realloc (pointer_name, number * sizeof(int));

4 free () free (pointer_name);

1. malloc() function in C:

 malloc () function is used to allocate space in memory during the execution of the
program.
 malloc () does not initialize the memory allocated during execution. It carries garbage
value.
 malloc () function returns null pointer if it couldn‟t able to allocate requested amount of
memory.

Example program for malloc() function in C:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *mem_allocation;
/* memory is allocated dynamically */
mem_allocation = malloc( 20 * sizeof(char) );
if( mem_allocation== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( mem_allocation,"fresh2refresh.com");
}
printf("Dynamically allocated memory content : " \
"%s\n", mem_allocation );
free(mem_allocation);
}

Output:
Dynamically allocated memory content : fresh2refresh.com

2. calloc() function in C:

 calloc () function is also like malloc () function. But calloc () initializes the allocated
memory to zero. But, malloc() doesn‟t.

Example program for calloc() function in C:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *mem_allocation;
/* memory is allocated dynamically */
mem_allocation = calloc( 20, sizeof(char) );
if( mem_allocation== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( mem_allocation,"fresh2refresh.com");
}
printf("Dynamically allocated memory content : " \
"%s\n", mem_allocation );
free(mem_allocation);
}

Output:
Dynamically allocated memory content : fresh2refresh.com

3. realloc() function in C:

 realloc () function modifies the allocated memory size by malloc () and calloc ()
functions to new size.
 If enough space doesn‟t exist in memory of current block to extend, new block is
allocated for the full size of reallocation, then copies the existing data to new block and
then frees the old block.
4. free() function in C:

 free () function frees the allocated memory by malloc (), calloc (), realloc () functions and
returns the memory to the system.

Example program for realloc() and free() functions in C:


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *mem_allocation;
/* memory is allocated dynamically */
mem_allocation = malloc( 20 * sizeof(char) );
if( mem_allocation == NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( mem_allocation,"fresh2refresh.com");
}
printf("Dynamically allocated memory content : " \
"%s\n", mem_allocation );
mem_allocation=realloc(mem_allocation,100*sizeof(char));
if( mem_allocation == NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( mem_allocation,"space is extended upto " \
"100 characters");
}
printf("Resized memory : %s\n", mem_allocation );
free(mem_allocation);
}

Output:
Dynamically allocated memory content : fresh2refresh.com
Resized memory : space is extended upto 100 characters

Difference between static memory allocation and dynamic memory allocation in C:


S.no Static memory allocation Dynamic memory allocation

In static memory allocation, memory is allocated


1 In dynamic memory allocation,
while writing the C program. Actually, user
memory is allocated while executing
requested memory will be allocated at compile
time. the program. That means at run time.

Memory size can be modified while


Memory size can‟t be modified while execution.
2 execution.
Example: array
Example: Linked list

Difference between malloc() and calloc() functions in C:


S.no malloc() calloc()

It allocates only single block of requested It allocates multiple blocks of requested


1
memory memory

int *ptr;Ptr = calloc( 20, 20 * sizeof(int)


int *ptr;ptr = malloc( 20 * sizeof(int) );For the
);For the above, 20 blocks of memory will
above, 20*4 bytes of memory only allocated in
2 be created and each contains 20*4 bytes of
one block.
memory.
Total = 80 bytes
Total = 1600 bytes

malloc () doesn‟t initializes the allocated calloc () initializes the allocated memory to
3
memory. It contains garbage values zero

type cast must be done since this function


Same as malloc () function int *ptr;ptr =
4 returns void pointer int *ptr;ptr =
(int*)calloc( 20, 20 * sizeof(int) );
(int*)malloc(sizeof(int)*20 );
UNIT 2 PART 4: Preprocessor Directives
The preprocessing step happens to the C source before it is fed to the compiler. The two
Most common preprocessor directives are #define and #include...

#define

The #define directive can be used to set up symbolic replacements in the source. As with all
preprocessor operations, #define is extremely unintelligent -- it just does textual replacement
without understanding. #define statements are used as a crude way of establishing symbolic
constants.

Example:

#define MAX 100

#define SEVEN_WORDS that_symbol_expands_to_all_these_words

Later code can use the symbols MAX or SEVEN_WORDS which will be replaced by the text to
the right of each symbol in its #define.

SUMMARY OF #define

 allow the use of symbolic constants in programs


 in general, symbols are written in uppercase
 are not terminated with a semi-colon
 generally occur at the beginning of the file
 each occurrence of the symbol is replaced by its value
 makes programs readable and easy to maintain

#include [“ “—will search in current as well as standard library]


[ < >-- will search in standard library only]

The "#include" directive brings in text from different files during compilation. #include is a very
unintelligent and unstructured -- it just pastes in the text from the given file and continues
compiling. The #include directive is used in the .h/.c file convention below which is used to
satisfy the various constraints necessary to get prototypes correct.
#include "c.h" // refers to a "user" c.h file in the originating directory
for the compile

#include <c.h> // refers to a "system" c.h file in the compiler's directory


somewhere
#include example

Create a file with name bca.c

Int display();

display();

{
Preprocessor Operators
Printf(“\n Coming from bca.c”);

Create another file with name call.c

#include<stdio.h>

#include<conio.h>

Void main()

clrscr();

display();

getch();

Output: coming from bca.c


The C preprocessor offers following operators to help us in creating macros:

Stringize (#)
The stringize or number-sign operator ('#'), when used within a macro definition, converts a
macro parameter into a string constant. This operator may be used only in a macro that has a
specified argument or parameter list.

For example:

#include <stdio.h>

#define say(m) printf(#m)

void main()
{
clrscr();
say(HELLO);
getch();
}

When the above code is compiled and executed, it produces the following result:

Explanation

In the above program, after conversion the statement say (HELLO) is treated as
printf (“HELLO”). It is not essential to enclose the text in quotation marks in the stringizing
operator.
Token Pasting (##)
The token-pasting operator (##) within a macro definition combines two arguments. It permits
two separate tokens in the macro definition to be joined into a single token.

For example:

#include <stdio.h>
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
void main()
{
int token34 = 40;
tokenpaster(34);
getch();
}

When the above code is compiled and executed, it produces the following result:

How it happened, because this example results in the following actual output from the
preprocessor:

printf ("token34 = %d", token34);

This example shows the concatenation of token##n into token34 and here we have used both
stringizing and token-pasting.
Conditional Compilation

 Six directives are available to control conditional compilation.


 They delimit blocks of program text that are compiled only if a specified condition is
true.
 These directives can be nested.
 The program text within the blocks is arbitrary and may consist of preprocessor
directives, C statements, and so on.
 The beginning of the block of program text is marked by one of three directives:

Some of the directives are:

1. #if
2. #ifdef
3. #ifndef

Optionally, an alternative block of text can be set aside with one of two directives:

1. #else
2. #elif

The end of the block or alternative block is marked by the #endif directive.

If the condition checked by #if , #ifdef , or #ifndef is true (nonzero), then all lines between
the matching #else (or #elif ) and an #endif directive, if present, are ignored.

If the condition is false (0), then the lines between the #if , #ifdef , or #ifndef and an #else ,
#elif , or #endif directive are ignored.

The #if Directive

The #if directive has the following syntax:

#if constant-expression newline

This directive checks whether the constant-expression is true (nonzero). The operand must be a
constant integer expression that does not contain any increment (++), decrement (- -), sizeof ,
pointer (*), address (&), and cast operators.

The constant expression in an #if directive is subject to text replacement and can contain
references to identifiers defined in previous #define directives. The replacement occurs before
the expression is evaluated. Each preprocessing token that remains after all macro replacements
have occurred is in the lexical form of a token.

If an identifier used in the expression is not currently defined, the compiler treats the identifier as
though it were the constant zero.
#if example
#include <stdio.h>

#define SWITCH 0

#if (SWITCH==1)

#define TEXT “EXAMPLE TO #IF”

#else

#define TEXT “example to else”

#endif

void main()

Printf(TEXT)

getch();

The #ifdef Directive

The #ifdef directive has the following syntax:

#ifdef identifier newline

This directive checks whether the identifier is currently defined. Identifiers can be defined by a
#define directive or on the command line. If such identifiers have not been subsequently
undefined, they are considered currently defined.

#ifdef example
#include <stdio.h>

#define LINE 1

Void main()

Clrscr();
#ifdef LINE

Printf(“this is defined);

#else

Printf(“this is not defined”);

#endif

Getch();

Output : this is defined

The #ifndef Directive

The #ifndef directive has the following syntax:

#ifndef identifier newline

This directive checks to see if the identifier is not currently defined.

#ifndef example
#include <stdio.h>

#define LINE 8

Void main()

Clrscr();

#ifndef LINE

Printf(“this is not defined);

#else

Printf(“this is defined”);

#endif

Getch();
}

Output: this is defined

The #else Directive

The #else directive has the following syntax:

#else newline

This directive delimits alternative source text to be compiled if the condition tested for in the
corresponding #if , #ifdef , or #ifndef directive is false. An #else directive is optional.

The #elif Directive

The #elif directive has the following syntax:

#elif constant-expression newline

The #elif directive performs a task similar to the combined use of the else-if statements in C.
This directive delimits alternative source lines to be compiled if the constant expression in the
corresponding #if , #ifdef , #ifndef , or another #elif directive is false and if the additional
constant expression presented in the #elif line is true. An #elif directive is optional.

The #endif Directive

The #endif directive has the following syntax:

#endif newline

This directive ends the scope of the #if , #ifdef , #ifndef , #else , or #elif directive.

The number of necessary #endif directives changes according to whether the elif or #else
directive is used. Consider the following equivalent examples:

#if true #if true


. .
. .
. .
#elif true .
. #else
. #if false
. .
#endif .
.
#endif
#endif
The defined Operator

Another way to verify that a macro is defined is to use the defined unary operator. The defined
operator has one of the following forms:

defined name
defined (name)

An expression of this form evaluates to 1 if name is defined and to 0 if it is not.

The defined operator is especially useful for checking many macros with just a single use of the
#if directive. In this way, you can check for macro definitions in one concise line without
having to use many #ifdef or #ifndef directives.

For example, consider the following macro checks:

#ifdef macro1
printf (“Hello!\n" );
#endif

#ifndef macro2
printf (“Hello!\n" );
#endif

#ifdef macro3
printf( "Hello!\n" );
#endif

Another use of the defined operator is in a single #if directive to perform similar macro
checks:

#if defined (macro1) ||! defined (macro2) || defined (macro3)


printf ( "Hello!\n" );
#endif
Note that defined operators can be combined in any logical expression using the C logical
operators. However, defined can only be used in the evaluated expression of an #if or #elif
preprocessor directive.

You might also like