You are on page 1of 92

Karnataka State Open University

Mukthagangotri, Mysore-570006

MSc Computer science


First Semester

Advanced C Programming

COURSE – MCSDSE-1.6 BLOCK – 1-2


CREDIT PAGE

Programme Name: MSc-Computer Science Year/Semester: I Semester Block No:1-2

Course Name: Advanced C Programming Credit: 2 Unit No: 1-8

Course Design Expert Committee


Dr. Vidyashankar S. Chairman
Vice Chancellor,
Karnataka State Open University,
Mukthagangotri, Mysuru-570006.

Dr. Ashok Kamble Member


Dean (Academic),
Karnataka State Open University,
Mukthagangotri, Mysuru-570 006.

Editorial Committee
Dr. D M Mahesha MCA.,PhD Chairman
BOS Chairman,
Assistant Professor & Programme co-ordinator(PG)
DoS&R in Computer Science,
Karnataka State Open University, Mysuru-570 006.

Smt, Suneetha MSc.,(PhD) Member Convener


Dept Chairperson & Programme co-ordinator (UG)
DoS&R in Computer Science,
Karnataka State Open University, Mysuru-570 006.

Dr Bhavya D.N., MTech., PhD Member


Assistant Professor & Programme co-ordinator(UG)
DoS&R in Computer Science,
Karnataka State Open University, Mysuru-570 006.

Dr. Ashoka S B., MSc.PhD Member


External Subject Expert,
Assistant Professor,
DoS&R in Computer Science,
Maharani’s Cluster University, palace Road Bangalore-01
Name of Course Writer No of No Name of No
Blocks of Course Editor of
Unit Uni
s ts
Dr. Bhavya D.N., BE., M.Tech., Dr.Mahesha D.M.MCA.PhD
Ph.D., Block-1 1-2 Assistant Professor
Assistant Professor 1-2
DoS&R in Computer
DoS&R in Computer Science, Science,
Karnataka State Open Karnataka State Open
University, Mysuru-06 University, Mysuru-06

Sri. Somashekar BM Dr.Basappa B Kodada


BE., MTech., (PhD) Block-1-2 3-8 BE., MTech., PhD 3-8
Assistant Professor, Associate professor
Department of Information Department of Computer
Science MIT Naguvanhalli post, Science,AJ Institute of
SR Patna Taluk571438 Engineering and Technology
Mangalore
Copy Right
Registrar,
Karnataka State Open University,
Mukthagantoghri, Mysore 570 006.

Developed by the Department of Studies and Research in Computer Science, under


the guidance of Dean (Academic), KSOU, Mysuru.
Karnataka State Open University, February-2022.
All rights reserved. No part of this work may be reproduced in any form or any other
means, without permission in writing from the Karnataka State Open University.
Further information on the Karnataka State Open University Programmes may be obtained
from the University’s Office at Mukthagangotri, Mysore – 570 006.

Printed and Published on behalf of Karnataka State Open University, Mysore-570 006 by
the Registrar (Administration)-2022
TABLE OF CONTENTS

BLOCK 1 PAGE NO.

UNIT- 1 1-12
Functions

UNIT-2 Recursion and storage classes 13-22

UNIT-3 Structures and unions 23-38

UNIT-4 Pointer 39-52

BLOCK 1I

UNIT-5 Dynamic memory allocation 53-60


Linked list 61-72
UNIT-6

UNIT-7 Fibonacci heaps: structure – merge able-heap operations- 73-80


Decreasing a key and deleting a node-bounding the maximum 81-88
UNIT-8
degree.

Preface

The programming language is certainly the essential language to this modern world. It is
evolved profoundly over the past few decades. Program developers can often get confused with
a wide variety of programming languages, deciding which one to opt for learning However
some valuable reason to learn programming in C. The C programming language massively
used in the scientific computing society regardless of popularity of high level luggage’s. Aside
from changes in programming language and presentation, additional sections have been
included. Some frequently asked questions and common programming errors are listed at the
end of the chapter. Only a subset of the ANSI C language is tackled here. Specifically, it is
assumed that the student will be working under the Linux environment and programming using
GNU C (which supports ANSI C) or the Borland Turbo C/C++ compiler under the Windows
environment. Coding standards to be followed,

May you learn a lot from the study of this manual, and may the knowledge that you have gained
be used for the common good of all people.

All the Best


UNIT 1: FUNCTIONS
Structure
1.0 Objectives
1.1 Introduction
1.2 Functions
1.3 User defined functions
1.4 Categories of user defined functions
1.4.1 Functions with no arguments and no return values
1.4.2 Functions with no arguments and with return values
1.4.3 Functions with arguments and no return values
1.4.4 Functions with arguments and with return values
1.5 Summary
1.6 Key words
1.7 Questions
1.8 References

1.0 OBJECTIVES

After going through this unit you will be able to


 Explain about function in C.
 Describe user defined functions
 Discuss different categories of function with example

1
1.1 INTRODUCTION
Function in C programming is a reusable block of code that makes a program easier to
understand, test and can be easily modified without changing the calling program. The
Function in C which can divide the code and modularize the program for better and effective
results. In short, the functions are defined as larger program is divided into various
subprograms which are called as functions. The function is divided into two types library
function and user-defined function.

1.2 FUNCTIONS

A function is a block of statements that performs a specific task. Let’s say we are writing a C
program and we want to perform a same task in that program more than once. In such case
we have two options:
a) We can use the same set of statements every time to perform the task
b) We can create a function to perform that task, and just call it every time you need to
perform that task.
Select Option (b) is a good practice and a good programmer always uses functions while
writing code in C.
The below are the following reasons to why functions are used
 Improve the readability of code.
 Improves the reusability of the code, same function can be used in any
program rather than writing the same code from scratch.
 Debugging of the code would be easier if you use functions, as errors are easy
to be traced.
 Reduces the size of the code, duplicate set of statements are replaced by
function calls.

Types of Functions:

1) Predefined standard library functions


The Standard library functions are also called as built-in functions. Functions for
example puts(), gets(), printf(), scanf() etc are standard library functions. These functions are

2
already defined in header files in C library (files with .h extensions are called header files
such as stdio.h), so we just call them whenever there is a need to use them.
For example, printf() function is defined in <stdio.h> header file so in order to use
the printf() function, we need to include the <stdio.h> header file in our program
using #include <stdio.h>.

2) User defined functions


1.3 USER DEFINED FUNCTIONS

The functions which are created by user are known as user defined function. Another way the
user defined function is defined as we create in a program is known as user defined functions

or in other words you can say that a function created.


Syntax of a function:
return_type function_name (argument list)
{
Set of statements (Block of code)
}

return_type: The Return type can be of any data type such as int, float, double, char, void
and short etc.

function_name: It can be anything the user given, however it is advised to have a


meaningful name for the functions so that it would be help us to understand the purpose of
function just by seeing it’s name.
argument list: The Argument list contains variables names along with their data types. These
arguments are kind of inputs for the function. For example – To add two integer variables we
can used add() function having two integer argument.
Block of code: It contains set of C statements, which will be executed whenever a call will be
made to the function.
For example – Suppose you want to create a function to add two integer variables.
Function to add the two numbers so it should have some meaningful name like sum, addition,
etc. For example if we taken the name addition for this function.

3
return_type addition(argument list)

This addition function adds two integer variables, which means we need two integer variable
as input, let’s provide two integer parameters in the function signature. The function
signature would be –
return_type add(int num1, int num2)

The sum of two integers result would be integer only. Hence function should return an
integer value – I got my return type – It would be integer –
int add(int num1, int num2);
So we got your function prototype or signature. Now we can implement the logic in C
program shown below:
The example shows the how to call function in a program
Consider the following C program
Example1: Creating a user defined function addition()

#include<stdio.h>
#include<conio.h>
void main(){
int num1, num2, result ;
int addition(int,int) ; // function declaration
clrscr() ;
printf("Enter two integer numbers : ") ;
scanf("%d%d", &num1, &num2);
result = addition(num1, num2) ; // function call
printf("SUM of two integers= %d", result);
getch() ;
}
int addition(int num1, int num2) // function definition
{
return num1+num2 ;
}

In C user defined function must be declared and implemented. Whenever we make function

4
call the function definition gets executed. For example, consider the following program in
which we create a fucntion called addition with two paramenters and a return value.

The above example program describes, the function declaration statement "int
addition(int,int)" tells the compiler that there is a function with name addition which takes
two integer values as parameters and returns an integer value. The function call statement
takes the execution control to the addition() definition along with values of num1 and num2.
Then function definition executes the code written inside it and comes back to the function
call along with return value.

The below are the few Points to Note regarding functions in C:

1) The main() in C program is also a function.


2) In each C program must have at least one function, which is main() function.
3) There is no limit on number of functions; A C program can have any number of functions.
4) A function can call by itself and it is known as “Recursion

1.4 CATEGORIES OF USER DEFINED FUNCTION

Different types of user-defined functions: 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.
1. Category 1: Functions with no arguments and no return values
 Category 2: Functions with no arguments and with return values
 Category 3: Functions with arguments and no return values
 Category 4: Functions with arguments and with return values
Functions with no arguments and no return value

Functions with no arguments and no return value:The following syntax describes how to
write a function which neither takes any arguments nor returns any value.

Syntax for function definition

5
void functionName() //Return type in the function header should be 'void' and do not give
any arguments within the parenthesis.
{
........
........
return; //Need not return any value
}

Syntax for function call


functionName();

Example: Write a function to increase the value of the given variable by 10


As arguments should not be passed to the function and no value should be returned, the
function body should be written in such a way that it reads the input value, increases its value
by 10 and prints the result within the function itself.

include <stdio.h>
void modify() //function definition
{
int a;
printf("Enter a value:");
scanf("%d",&m);
m=m+10;
printf("The modified value is %d",m);

6
return;
}

int main()
{
modify(); //function call
getch();
return 0;
}

output: if m=1
The modified value is 11.

Functions with no arguments and with return values

Functions with no arguments and with return values:


The below given syntax shows how to write a function which does not take any arguments
but returns some value back to the calling function.

The Syntax for function definition given below:

returnType functionName() //Identify type of value will be returned by the function and
accordingly it specify the return type and empty
{
parenthesis since there is no argument
....
....
return value;
}

Syntax for function call

7
X = functionName //As the function is going to return the modified Value, call the function
like this.

Example: The previous program is modified such that the value of 'a' is read in the user-
defined function and the changed value is returned to the main(), where it gets printed.

include <stdio.h>
void modify()
{
int a;
printf("Enter a value:" )
scanf("%d",&m);
m=m+10;
return m;
}

int main()
{
int a;
a=modify();
printf("The modified value is %d",a);
getch();
return 0;
}

Assume m=1. When `m=m+10' is executed m=11. Here the modified value (11) is returned to
the place where the function was called. 11 is returned as a=11. If x is printed, 11 will be the
output.

8
Functions with arguments and no return values

Functions with arguments and no return values: Function with arguments can perform
much better than function with no argument function type. This type of function will be
accept data from calling function. In other words, we send data to the called function from
calling function but we cannot send result data back to the calling function. Rather, it displays
the result on the terminal. But we can control the output of function by providing various
values as arguments.

The Syntax for function definition given below:

void functionName(typel argl, type2 arg2,...... typeN argN)


{
....
....
return;
}

Syntax for function call


functionName(argl, arg2, , argN);

Example: In the program, read the value of 'm' in main(), pass it to modify() and print the
changed value of 'm' in modify() function itself.

include <stdio.h>
void modify(int x) // function takes the argument x and since it does not return
anything, specify 'void'

9
{
a = a + 10;
printf(" Modified value is %d", a);
return;
}

int main()
{
int m;
printf("Enter the value:");
scanf("%d",&m);
modify(m); // pass the argument 'a' to the function
getch();
return 0;
}

m's value is read in the main function and that value is passed to the modify() function. m's
value is assigned to the formal argument 'a'. Then 'a' value is changed and printed in the
modify() function itself.

Functions with arguments and with return values:

Functions with arguments and with return values:


This function type will send arguments (data) from the calling function to the called function
and wait for the result to be returned back from the called function back to the calling
function. And this function type is mostly used in programming world because it will do two
way communications; it can accept data as arguments as well as can send back data as return
value. The data returned by the function can be used later in our program for further
calculations
Syntax for function definition

returnType functionName(typel argi, type2 arg2,.........typeN argN)


{
....

10
....
return value;
}

Syntax for function call


X = functionName(argl, arg2,... , argN);

Example: In the above program, read the value of 'a' in main(), pass it to modify() and return
the changed value of 'a' to main() and print the changed value in main().

include <stdio.h>
void modify(int x) // function takes the argument x and since it does not return anything,
specify 'void'
{
m = m + 10;
return m;
}

int main()
{
int a;
printf("Enter the value:");
scanf("%d",&a);
printf(" Modified value is %d", modify(a)); // pass the argument 'a' to the function
getch();
return 0;

11
}

Points to be Remembered
 The parameters specified in calling function are said to be Actual Parameters.
 The parameters declared in called function are said to be Formal Parameters.
 The value of actual parameters is always copied into formal parameters.

1.5 SUMMARY

At the end of this unit you have learnt about functions, how to define and declare functions,
what are the functions different data types. In this unit we have also discussed about the
library functions and user defined functions. Finally you learnt different types of functions.
1.6 KEYWORDS
Function call, prototype, library function, used defined function.
1.7 QUESTIONS
1. Discuss function in c.
2. Describe user-defined function.
3. Briefly explain different types of functions.
4. Explain how to access and declare pointer in c.
1.8 REFERENCES

 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.


Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden
 5. http://www.cprogrammingexpert.com/C/Tutorial
 Simplifying C (First Edition 2010) Publication: Dreamtech by Harshal Arolkar and
Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

12
UNIT 2: RECURSION AND STORAGE CLASSES

Structure
2.0 Objectives
2.1 Introduction
2.2 Recursion
2.3 Storage classes
2.4 Nesting of function
2.5 Summary
2.6 Key words
2.7 Questions
2.8 References

2.0 OBJECTIVES

After going through this unit you will be able to


 Discuss about recursion
 With example explain storage classes-auto, register, static and extern
 Describe nesting of function.

13
2.1 INTRODUCTION

Recursion is the process of repeating items in a self-similar way. In programming languages,


if a program allows we to call a function inside the same function, then it is called a
recursive call of the function.

A storage class defines the scope (visibility) and life-time of variables and/or functions
within a C Program. They precede the type that they modify. We have four different storage
classes in a C program –auto, register, static and extern.

2.2 RECURSION

Recursive Functions in C
In C programming language, always function calls can be made from the main() function,
other functions or from the same function itself. The recursive function is defined by: The
function call by itself is called recursion function

While using the recursive functions we should be used very carefully because, when a
function called by itself it enters into the infinite loop. If the function enters into the infinite
loop, the function execution never gets completed. We always should define the condition to
exit from the function call so that the recursive function gets terminated.
Whenever a function is called by itself, the first call should remains under execution till the
last call gets invoked. Every time when a function call is invoked, the function returns the
execution control to the previous function call.

Example Program
#include<stdio.h>
#include<conio.h>

int factorial( int ) ;


int main()
{
int fact, x ;
printf("Enter the number: ") ;

14
scanf("%d", &x) ;
fact = factorial( x ) ;
printf("\nFactorial of %d is %d\n", x, fact) ;
return 0;
}
int factorial( int x )
{
int temp ;
if( x == 0)
return 1 ;
else
temp = x * factorial( x-1 ) ; // recursive function call
return temp ;
}
Output:
In the above given example, the factorial() function call is initiated from main() function
with the value 3. The function calls factorial(2), factorial(1) and factorial(0) are called
recursively inside the factorial() function. In this program execution process, till the
execution of function calls factorial(2), factorial(1) and factorial(0) gets completed the
function call factorial(3) remains under execution. Similarly till the execution of function
calls factorial(1) and factorial(0) gets completed the function call factorial(2) remains under
execution. In the same way till the execution of function call factorial(0) gets completed the
function call factorial(1) remains under execution. The complete execution process of the
above program is shown in the following figure...

15
16
2.3 STORAGE CLASSES

In C language, storage classes are described by the features of variables and functions like
visibility and scope of q variable or function.
The storage classes in C language classified into four types namely
 Automatic variables
 External variables
 Static variables
 Register variables

Automatic variable(auto)

Auto storage class will be the default storage class for all the local variables. variables are
created when function is called. When the execution of function is completed, variables are
automatically destroyed. They are also called as local variables because they are local to a
function. By default, they are assigned the garbage value by the compiler.

Scope − auto variables are local variables to the function block.


Default value − default initialized value is the garbage value.
Lifetime − Lifetime of auto variable is bound by the block in which it is defined.

Here is an example of auto variable in C language,


#include <stdio.h>
int main()
{
auto int x = 30;
int y = 10;
printf("The value of auto variable : %d\n", x);
printf("The sum of auto variable & integer variable : %d", (x+y));
return 0;
}
The value of auto variable : 30
The sum of auto variable & integer variable : 40

17
External variables (extern)
External variables are also called as global variables. These variables are defined outside the
function. These variables are available globally throughout the function execution. The value
of global variables can also be modified by the functions.

Scope − They are not bound by any function. They are everywhere in the program i.e. global.
Default value − Default initialized value of global variables are Zero.
Lifetime − Till the end of the execution of the program.
Here is an example of extern variable in C language,
Example
#include <stdio.h>
extern int x = 32;
int b = 8;
int main() {
auto int a = 28;
extern int b;
printf("The value of auto variable is: %d\n", a);
printf("The value of extern variables x and b is: %d,%d\n",x,b);
x = 15;
printf("The value of modified extern variable x is : %d\n",x);
return 0;
} The value of auto variable is : 28
The value of extern variables x and b is: 32,8
The value of modified extern variable x is: 15

Static variables (static)


Static variables are initialized only once. Compiler persist the variable till the end of the
program. Static variable can be defined inside or outside the function.
Scope − They are local to the block.
Default value − Zero is the default initialized value .
Lifetime − Till the end of the execution of the program.
Here is an example of static variable in C language,
Example

18
#include <stdio.h>
int main()
{
auto int x = -28;
static int y = 8;
printf("The value of auto variable : %d\n", x);
printf("The value of static variable b : %d\n",y);
if(x!=0)
printf("The sum of static variable and auto variable : %d\n",(y+x));
return 0;
}
The value of auto variable : -28
The value of static variable b : 8
The sum of static variable and auto variable : -20

Register variables (register)


Register variables inform the compiler to store the variable in CPU register instead of
memory. Frequently used variables are kept in registers and they have faster accessibility. We
can never get the addresses of these variables.
Scope − They are local to the function.
Default value − Garbage value is the default initialized value .
Lifetime − Until the end of the execution of the block in which it is defined.
Here is an example of register variable in C language,
Example
#include <stdio.h>
int main() {
register char x = 'S';
register int a = 10;
auto int b = 8;
printf("The value of register variable b : %c\n",x);
printf("The sum of auto and register variable : %d",(a+b));
return 0;
}
The value of register variable b : S

19
The sum of auto and register variable : 18

2.4 NESTING OF FUNCTIONS

In some applications, we have seen that some functions are declared inside another function.
This is sometimes called as nested function, but actually this is not the nested function. This
is called as the lexical scoping. Lexical scoping is not valid in C because the compiler will be
unable to reach correct memory location of inner function.

Nested function definitions can access only global variables. They cannot access local
variables of surrounding blocks. In C there are two nested scopes the global and the local. So
nested function has some limited use. If we need to create nested function like below, it will
generate error.

Example

#include <stdio.h>

main(void) {

printf("Welcome");

int my_fun() {

printf("my world");

// defining another function inside the first function.

int my_fun2() {

printf("Hello");

my_fun2();

Output

Get output: text.c:(.text+0x1a): undefined reference to `my_fun2'

20
But an extension of GNU C compiler allows declaration of the nested function. For this we
have to put auto keyword before the declaration of nested function.

Example

#include <stdio.h>

main(void) {

auto int my_fun();

my_fun();

printf("Welcome\n");

int my_fun() {

printf("My world\n");

printf("hello");

Output

My world

Welcome

hello

2.5 SUMMARY
In this unit we have discussed in detail about the recursion. This unit also covered in detail about
variables and storage classes such as automatic, external (global), register and static variable
and storage class with an example. At the end of this unit discussed about nesting of
functions.
2.6 KEYWORDS
Auto, extern, register, static, recursion
2.7 QUESTIONS
1. Explain with an example about storage classes in C.
2. With an example show how efficiently you can utilize available storage class in C?

21
3. Describe the recursion in detail.
4. Discuss nesting of functions.
2.8 REFERENCE
 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden
 5. http://www.cprogrammingexpert.com/C/Tutorial
 Simplifying C (First Edition 2010) Publication: Dreamtech by Harshal Arolkar and
Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

22
UNIT 3 – STRUCTURES AND UNIONS

Structure
3.0 Objectives
3.1 Introduction
3.2 Structure
3.3 Arrays v/s structures
3.4 Accessing structure members
3.5 Nested structures
3.6 Unions
3.7 Summary
3.8 Key words
3.9 Questions
3.10 References

3.0 OBJECTIVES

After going through this unit you will be able to


 Describe the structure.
 Discuss arrays v/s structures
 Elucidate accessing structure members
 Explain about nested structures
 Describe unions

3.1 INTRODUCTION

The C programming language has many built-in data types. It allows users to create their own
custom data types. Both the structure and union are user-defined data types in C
programming that can hold any data type. Structure and union seem to perform most similar
functions, there are few differences between them. Structures allocate enough space to store
all their members, but unions can only hold one member value at a time.

3.2 STRUCTURE

23
Basic of Structures
Structures are defined as constructed data type supported by C, a mechanism for packing data
of different types. A structure is a very good tool for handling a group of logically related
data items. For example, it can be used to represent a set of attributes, such as stud_name,
roll_num and marks. The structure concept is analogous to that of a ‘record’ in many other
languages.

More examples of such structures are:


Date : day, month, year Time : seconds, minutes, hours
City : name, country, population Book : author, title, price, year

Structures are more helpful to organize complex data in a more meaningful way. It is a more
powerful concept that we may often need to use in our program design.

Defining a Structure
Let us use an example to illustrate the process of structure definition and the creation of
structure variables. Consider an employee database consisting of employee name, id, and
salary. We can define a structure to hold this information as follows:
struct employee
{
char name[30]; varchar Id[25]; int salary;
};
The keyword struct declares a structure to hold the details of three data fields, employee
name, id, and salary. The fields in struct employee are called structure elements or members.
Each member will be belong to a different type of data. employee is the name of the structure
and is called the structure tag. The tag name should be used subsequently to declare variables
that have the tag’s structure.

The general syntax of a structure definition is as follows:


struct tag_name
{
data_type member 1; data_type member 2;
…. ……. ……data_type member n;

24
};

In defining a structure we may have some following rules:


1. The template will be terminated with a semicolon.
2. The entire definition is considered as a statement, each member in structure is
declared independently for its name and type in a separate statement inside the
template.
3. The tag name such as employee can be used to declare structure variables of its type,
later in the program.
#include <stdio.h>
/* Created a structure here. The name of the structure is
* EmployeeData.
*/
struct EmployeeData{
char *emp_name;
int emp_id;
int salary;
};
int main()
{
/* student is the variable of structure StudentData*/
struct EmployeeData student;

/*Assigning the values of each struct member here*/


employee.emp_name = "surabhi";
employee.emp _id = 1234;
employee.emp _salary = 300000;

/* Displaying the values of struct members */


printf("employee Name is: %s", employee.emp_name);
printf("\nemployee Id is: %d", employee.emp _id);
printf("\employee salary is: %d", employee.emp _salary);
return 0;
}

25
Output:

employee Name is: Surabhi


employee Id is: 1234
employee salary is: 300000

3.3 ARRAY V/S STRUCTURES


1. An array has the collection of related data elements of same type. Structure can have
elements of different data types.
2. An array has derived data type but the structure is a programmer-defined one.
3. Any array behaves like a built-in data type.
In case of array we have to declare an array variable and use it. But in the case of a structure,
first we should design and declare a data structure before the variables of that type are
declared and used.
Declaring Structure Variables
After defining a structure format we can declare variables of that type. A structure variable
declaration is same as the declaration of variables of any other data types. It includes the
following elements.
1. Keyword struct
2. Structure tag name
3. List of variables names separated by commas
4. A terminating semicolon
For example, the statement
struct company_employee, employee1 , employee 2, employee 3;
declares employee 1, employee 2 and employee 3 as variables of type struct
company_employee.
Each one of these variables has three members as specified by the template. The complete
declaration might look like this:

struct company_employee {
char *emp_name;
int emp_id;

26
int salary;
};
struct company_employee, employee1 , employee 2, employee 3;

3.4 ACCESSING STRUCTURE MEMBERS

In structure we can access and assign values to the members in a number of ways. The
members of structure should be linked to the structure variables in order to make them
meaningful members. For example, the word only ‘title’ has no meaning whereas the phrase
‘title of book3’ has a meaning. The link between a member and a variable is accomplished
using the member operator ‘.’ Which is also known as ‘dot operator’ or ‘period operator’?
For example,
book1.price is the variable representing the price of book1 and can be treated like any other
ordinary variable? Here is how we would assign values to the members of book1:
strcpy(book1.title,”C Programming”);
strcpy(book1.author, “Balaguruswamy”);
book1.pages = 350;
book1.price = 400;
We can also use scanf to give the values through the keyboard.
scanf(“%s\n”,book1.title);
scanf(“%d\n”,&book1.pages);
are valid input statements.
Structure Initialization
Like any other data type, a structure variable can be initialized at compile time.
struct st_record
{
int weight; float height;
} student1 = {6-,180.75};

void main()
{
struct st_record student2 = {53, 170.60};
}

27
The C language does not permit the initialization of individual structure members within the
template. The initialization would be done only in the declaration of the actual variable.

Note that the compile-time initialization of a structure variable must have the following
elements:
1. Keyword struct
2. Structure tag name
3. Name of the variable to be declared
4. Assignment operator =
5. A set of values for the members of the structure variable, separated by commas and
enclosed in braces
6. Terminating semicolon

Rules for initializing structures


There are a few rules to keep in mind while initializing structure variables at compile- time.
1. We cannot initialize individual members inside the structure template.
2. The order of values enclosed in braces should match the order of members in the
structure definition
3. It is permitted to have a partial initialization. We will be initializing only the first few
members and leave the remaining blank. The uninitialized members must be only at
the end of the list.
4. The uninitialized members can assigned default values as follows:
a. Zero for integer and floating point numbers
b. ‘\0’ for character and strings

Arrays of Structures
We use structures to be describing the format of a number of related variables. For example,
in analyzing the marks obtained by a class of students, we will use a template to describe
student name and marks obtained in various subjects and then declare all the students as
structure variables. In such cases, we may declare an array of structures, each element of the
array representing a structure variable. for example,

struct class student[100];

28
It defines an array called student, that consists of 100 elements. Each element is defined to
be of the type struct class. Consider the following declaration:
struct marks
{
int sub1; int sub2; int sub3;
};
void main()
{
struct marks student[3]={{45,66,81},{75,53,72},{80,36,71}};

This declares the student as an array of three elements student[0], student[1] and student[2]
and initializes their members as follows:

student[0].sub1=45; student[0].sub2=66;
………..
………..
student[2].sub3=72;

Note that the array is declared just as it should have been with any other array. The student is
an array, we use the usual array-accessing methods to access individual elements and then the
member operator to access members. The each element of student array is a structure variable
with three members.
Any array of structures is stored inside the memory in the same way as a multi- dimensional
array. The array student actually looks as show in below figure.
Arrays within Structures
C permits the use of arrays as structure members. We have already used arrays of characters
inside a structure. Similarly, we can use single-or multi-dimensional arrays of type int or
float. For example, the following structure declaration is valid:
struct marks
{
int number; float sub[3];
} student[2];

29
Here, the member subject contains three elements, sub[0], sub[1] and sub[2]. These elements
can be accessed using appropriate subscripts. For example, the name
student[1].subj[2];

would refer to the marks obtained in the third subject by the second student.

3.5 STRUCTURES WITHIN STRUCTURES (NESTED STRUCTURES)


Structure within structure means nesting of structure. We can define the new structure inside
one structure or we can declare the variable of one structure inside another structure. For
example in following example we have defined two structures for Address and Student.

struct address
{
char society[100]; char area[100]; char city[50];
int pincode;
};
struct student
{
int rollno;
char name[50];
struct address add; // Structure inside structure
};

In above example we have defined one structure having member variable society, area, city,
and pincode number. Then we have defined another structure having member variable roll
number, name, and structure variable of structure address.

We can also define above structure by following way. Any method is valid for C program.

struct student
{
int rollno;
char name[50];

30
// Structure address defined inside the structure struct address
{
char society[100]; char area[100]; char city[50];
int pincode;
} add;
};

We can access the members of nested structure in program as under:

void main( )
{
struct student s;
printf(“Enter student detail\n”); scanf(“%d”, &s.rollno); gets(s.name);

// Accessing the member of nested structure gets(s.add.society);


gets(s.add.area); gets(s.add.city);
scanf(“%d”,&s.add.pincode);
}
3.6 STRUCTURES AND FUNCTIONS
In many ways we can pass the structure to the user defined function. The one method
involves passing of a copy of the entire structure to the called function. Since the function is
working on a copy of the structure, any changes to structure members within the function are
not reflected in the original structure. It is, therefore, necessary for the function to return the
entire structure back to the calling function.
PASSING STRCUTRE VARIABLE INSIDE FUNCTION
As like as simple variable and array variable we can also pass the structure variable inside the
function. Following example demonstrate passing structure variable inside the function.
struct student
{
int rollno;
char name[100];
};

31
// Function declaration void print(struct student); void main( )
{
struct student s;
printf(“Enter Roll Num. and Student name : “); scanf(“%d”,&s.rollno);
gets(s.name);
// Call a function
print(s);
}
// Function definition
void print(struct student s) { print(“Roll No. = %d\n”,s.rollno); printf(“Name =
%s\n”,s.name);
}

In above example we have defined one structure template for the student, which contain roll
number and name as structure member. We have used one function print() to print the
member of structure and we have passed that variable as argument inside function.
RETURNING STRUCTURE VARIABLE FROM FUNCTION
As like passing the structure variable inside structure we can return structure variable from
function. But it is supported only when our compiler supports the assignment operation over
structure.
struct student
{
int rollno;
char name[100];
};

// Function declaration
struct student read( );

void main( )
{
struct student s;
// Call function
s = read( );

32
}

// Function definition
struct student read( )
{
struct student t;
printf(“Enter Roll No. and Name of student\n”); scanf(“%d”,&t.rollno);
gets(t.name);
return( t ); // Returning structure variable
}

In above example we have defined one structure template for the student, which contain roll
number and name as structure member. We have used one function read() to read the data of
structure. This function return the value of type struct student and then it is assigned to
variable used inside main( ) function.

Important Points
1. The called function should be declared for its type, appropriate to the data type it is
expected to return. For example, if it is returning a copy of the entire structure, then it
should be declared as struct with an appropriate tag name.
2. The structure variable used as the actual argument and the corresponding formal
argument in the called function should be of the same struct type.
3. The return statement is necessary only when if the function is returning some data
back to the calling function. The expression may be any simple variable or structure
variable to an expression using simple variable.
4. When a function returns a structure, it should be assigned to a structure of identical
type in the calling function.
5. The called functions should be declared in the calling function appropriately.
3.7 UNIONS

Union is a user defined datatype in C programming language. Union is defined as collection


of variables of different datatypes in the same memory location. We can define a union with
many union members, but at a given point of time only one union member can contain a

33
value. Unions can be very handy when we need to talk to peripherals through some memory
mapped registers.

Need for Union in C programming


C unions are very useful to save memory. To better understand a union, think of it as a chunk
of memory that is used to store variables of different types. When we would like to assign a
new value to a field, then the existing data is replaced with new data.

C unions allow us to data members which are mutually exclusive to share the same memory.
This is very important when memory is valuable, such as in embedded systems. Unions are
used in embedded programming where direct access to the memory is needed.

Difference between structure and union


The main difference between structure and a union given below

Structure allocate enough space to store all of the fields in the struct. The first field is stored
at the beginning of the struct, the second is stored after that, and so on.
Unions only allocate enough space to store the largest field which is listed in the union, and
all fields are stored at the same space.
The basic syntax of the Union in C Programming is as shown below
union UName
{
Data_Type Variable_Name; //Member
Data_Type Variable_Name; //Member
………….
};
Union is the system reserved keyword used to create and accessing its members. The UName
is the name given by user for this.
For example, employees, persons, students.
Data_Type means data type of the variable that we want to declare in the program. For
example, int, float, char, etc. And the Variable_Name is the name of the variable. For
example, id, age, name, salary. For Example

Union Student //Name = Employee

34
{
//Members
int Roll_No; //Data Type = int; Variable Name = Roll_No
char name[50]; //Data Type = char Array; Variable Name = name
char address[100]; //Data Type = Char Array; Variable Name = address
};

Declaration of Union
In declaration of Union before accessing the members inside it, we have to create the
variables. We can able to declare the variables in multiple ways. The First Approach is
declaring the union first, and then create the variable in the main function.

union employee

{
int age;
char name[50];
float salary;
};

//Creating the Structure variable in union

Union employee emp1, emp2;

emp1 = {45, "surabhi", 25000}


emp1 and emp2 are the variables.
In the second Approach is to create the variables at the time of the C union declaration
union Employee

int age;
char name[40];
float salary;

35
} emp1, emp2;

Accessing Members of Union


We would be access the C union members using the dot operator (.) or members operator. For
example, let us take the above example.
//Assigning the values
emp1.age = 45;
strcopy (emp1.name, "ruchi");
emp1.salary = 55000.50;

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

union Employee
{
int age;
char Name[40];
char Department[30];
float Salary;
};

int main()
{
union Employee emp1;
union Employee emp2;

emp1.age = 37;
strcpy(emp1.Name, "vijay");
strcpy(emp1.Department, "Science");
emp1.Salary = 85000.70;

printf("\nDetails of the First Employee \n");


printf(" Employee Age = %d \n", emp1.age);
printf(" Employee Name = %s \n", emp1.Name);

36
printf(" Employee Department = %s \n", emp1.Department);
printf(" Employee Salary = %.2f \n\n", emp1.Salary);
printf("Details of the Second Employee \n" );
emp2.age = 30;
printf(" Employee Age = %d \n", emp2.age );
strcpy(emp2.Name, "chiru");
printf(" Employee Name = %s \n", emp2.Name );
strcpy(emp2.Department, "Computer science" );
printf(" Employee Department = %s \n ", emp2.Department );
emp2.Salary = 88000.20;
printf(" Employee Salary = %.2f \n ", emp2.Salary );
return 0;
}

3.8 SUMMARY

In this unit we have learnt some advance concepts on structure and unions such as passing to
function, pointers to structure and we also discussed about union in detail.
3.9 KEYWORDS

Structure, unions, pointer to structure, structure as function argument


3.10 QUESTIONS

1. Explain the concept of structure as function arguments and pointer to structure with
suitable program.
2. Explain unions with example.
3. Define structure in C.
3.11 REFERENCES

 C Programming: A Modern Approach by K.N. King


 C Programming in 12 Easy Lessons by Greg Perry
 C for Dummies Vol. II by Dan Gookin
 5. http://www.cprogrammingexpert.com/C/Tutorial
 Simplifying C (First Edition 2010) Publication: Dreamtech by Harshal Arolkar and
Sonal Jain

37
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

38
UNIT 4: POINTER

Structure
4.0 objectives
4.1 Introduction
4.2 Introduction to pointer
4.3 pointer arithmetic
4.4 pointers and arrays
4.5 pointers and structures
4.6 pointers and functions
4.7 Summary
4.8 Keywords
4.9 Questions
4.10 References

4.0 OBJECTIVES

After going through this unit you will be able to


 Elucidate introduction to pointer
 Discuss pointer arithmetic
 Describe pointers and arrays
 Explain about pointers and structures
 Discuss pointers and functions

39
4.1 INTRODUCTION
Pointer in C language is a variable which holds the address of another variable of same data
type. Pointers are used to access memory and manipulate the address. Pointers are one of the
most distinct and exciting features of C language.

4.2 INTRODUCTION TO POINTER


Derived data type in C is a pointer. It has built from one of the fundamental data types
available in C. Pointers should contain memory addresses as their values. So these memory
addresses are the locations in the computer memory where program data and instructions are
stored, To access and manipulate data stored in the memory we can use pointers.
Pointers are used frequently in C, there are number of benefits to the programmers to use
pointers. They include below:
1. In handling arrays and data tables pointers are more efficient .
2. To return multiple values from a function via function arguments pointers can be
used.
3. Pointers permit references to functions and thereby facilitating passing of functions as
arguments to other functions.
4. The benefit of pointer arrays to character strings results in saving of data storage
space in memory.
5. Pointers allow C to support the dynamic memory management.
6. Pointers provide an efficient tool for manipulating dynamic data structures such as
linked lists, structures, , queues, stacks and trees.
7. Pointers would be reduce length and complexity of programs.
8. Pointers increase the execution speed and thus reduce the program execution time.

Addressing the address of a variable


The actual location of a variable in the memory is system dependent and therefore, the
address of a variable is not known to us immediately. The address can be determine with the
help of the operator & available in C. The & operator immediately preceding a variable
returns the address of the variable associated with it. For example, the statement below shows
P = &a;

40
Would assign the address 62264 (i.e. the location of a) to the variable p. The & operator will
be remembered as ‘address of’. The & operator can be used only with a simple variable or an
array.

Declaring Pointer Variables


The declaration of a pointer variable takes the following form: data_type *pt_name;
data_type *pt_name tells the compiler three things about the variable pt_name.
1. The asterisk (*) tells that the variable pt_name is a pointer variable.
2. Pt_name needs a memory location.
3. Pt_name points to a variable of the data_type.

Example,
int *p;
It declares the variable p as a pointer variable that points to an integer data type. Remember
that the type interferes to the data type of the variable being pointed to by p and not the type
of the value of the pointer. Similarly, the statement
float *x;
Declares x as a pointer to a floating-point variable.

Initialization of pointer variable


“The process of assigning the address of a variable to a pointer variable is called as
initialization”. All uninitialized pointers will have some unknown values that will have some
unknown values that will be interrupted as memory address. They must not be valid
addresses or they can point to some values that are wrong. Since the compilers do not detect
these errors, the programs with uninitialized pointers will produce erroneous result. It is
therefore important to initialize pointer variable carefully before we are used in the program.
Once a pointer variable has been declared we can use the assignment operator to initialize the
variable is allowed. The only requirement here is that the variable quantity must be declared
before the initialization take place. Remember, this is as initialization of pand not *p.

Example
int quantity;
int*p; /* declaration of pointer */

41
p = &quantity; /* initialization */ We can also combine the initialization with the declaration.
That is,
int *p = &quantity;

They must ensure that the pointer variables always point to the corresponding type of data.
For example,
float a,b; int x, *p; p= &a;
b = *p;

We declare a pointer to be of int type, the system assumes that any address that the pointer
can hold will point to an integer variable. Since the compiler cannot detect such errors, care
should be taken to avoid wrong pointer assignments.

It is also possible to combine the declaration of data variable, since the declaration of pointer
variable and the initialization of the pointer variable in one step. For example,

int x, *p = &x; /* three in one*/

Is perfectly valid. It declares x as an integer variable and pas a pointer variable and then
initializes pto the address of x. and also remember that the target variable x is declared first.
The statement int *p = &x, x; is not valid.

We could also define a pointer variable with an initial value of NULL or zero. That is, the
following statements are valid
int *p =null;
int *p = 0;

With the exception of null and zero, no other constant value can be assigned to a pointer
variable. For example, the following is wrong:
int *p = 5360; /*absolute addresses */

Accessing a variable through its pointer

42
When a pointer has been assigned the address of a variable, the question arise is to how to
access the value of the variable using the pointer. Accessing of value of variable by using
another unary operator * (asterisk), usually known as the indirection operator. Another name
for the indirection operator is called as dereferencing operator. Consider the following
statements:
int quantity, *p, n; quantity = 179; p=&quantity; n=*p;
The first line declares quantity and n as integer variables and p as a pointer variable pointing
to an integer. The second line assigns the value 179 to quantity and the third line assigns the
address of quantity to the pointer variable p. The fourth line consists of indirection operator *.
When the operator * is always placed before a pointer variable in an expression, the pointer
returns the value of the variable of which the pointer value is the address. In this case, *p
returns the value of the variable quantity, because the p is the address of quantity. The * will
be remembered as ‘value at address’. Thus the value of n would 179. The two statements
p=&quantity; n=*p;
are equivalent to
n=*&quantity;which in turn is equivalent
n=quantity;

Example:

#include <stdio.h>
void ()
{
int var = 25;
int *pt;
pt = &var;
printf("Address is: %p \n",pt);
printf("Value is: %d \n", *pt);
}
int main()
{
TechVidvan();
}
Output:

43
Address is: 0x7ffc9e1fb704
Value is: 25

4.3 POINTER ARITHMETIC

Like other variables in C. Pointer variables can be used in expressions. For example given
below, if p1 and p2 are properly declared and initialized pointers, then the following
statements are valid.

Y = *p1 * *p2 same as (*p1) * (*p2) sum = sum + *p1;


Z = 5* - *p2/*p1; same as (5 *(-(*p2))) / (*p1)
*p2 = *p2 + 10;

Note that there is a blank space between / and * in the item 3 above. The following is wrong.

Z = 5* - *p2/ *p1;

C allows us to add integers to or subtract from pointers, as well as to subtract one pointer
from another. P1+4,P2-2 and p1-p2 are all allowed. If p1 and p2 are both pointers to the same
array, then p2-p1 gives the number of element between p1 and p2.

We can also use short –hand operators with the pointers.


P1++;
-p2;
Sum + = *p2;
In addition to arithmetic operations discussed above, pointers can also be compared using the
relational operators. The expression such as p1>p2, p1==p2 and p1!=p2are allowed.
However, any comparison of pointers that refer to separate and unrelated variables makes no
sense. Comparison can be used meaningfully in handling arrays and strings. We may not use
pointers in division or multiplication. For example, expression such as
p1/p2or p1 * p2 or p1/3 are not allowed. Similarly, two pointers cannot be added. That is,
p1+p2 is illegal.

44
Pointer increments and scale factor
We have seen that the pointer can be incremented like
p1 = p2 + 2; p1 = p1 + 1;
And so on. Remember, however an expression likep1++;
Will cause the pointer p1 to point to the nest value of its type. For example, if p1 is an integer
pointer with an initial value, say 2800, then after the operation p1 = p1+1, the value of p1 will
be 2802, and not 2801. That is, when we increment a pointer, its value is increased by the
‘length’ of the data type that it points to. This length called the scale factor.

Rules for Pointer Operations


1. A pointer variable will be assigned the address of another variable.
2. A pointer variable will be assigned the value of another pointer variable.
3. A pointer variable will be initialized with NULL or zero value.
4. A pointer variable will be pre-fixed or post-fixed with increment or decrement
operators.
5. An integer value can be added or subscribed from a pointer variable.
6. When two pointers point to the same array, one pointer variable can be subtracted
from another.
7. When two pointers point to the objects of the same data types, we can be compared
using relational operators.
8. A pointer variable cannot be multiplied by a constant.
9. The Two pointer variables cannot be added.
10. A value cannot be assigned to an arbitrary address (i.e&x=10; is illegal).

4.4 POINTERS AND ARRAYS

If an array is declared, the compiler allocates a base address and sufficient amount of storage
to contain all the elements of the array in contiguous memory locations. The base address is
the location of the first element (index 0) of the array.
The compiler also defines the array name as a constant pointer to the first element. Suppose
we declare an array x as follows:
int x[5] = {1,2,3,4,5};

45
suppose the base address of x is 1000 and assuming that each integer requires two bytes, the
five elements will stored as follows:
Element Value Address
X[0] 1 1000
X[1] 2 1002
X[2] 3 1004
X[3] 4 1006
X[4] 5 1008

The name x is defined as a constant pointer pointing to the first element, x[0] and therefore
the value of x is 1000, the location where x[0] is stored. That is

X =&x[0] = 1000
If we declare p as an integer pointer, then we can make the pointer p to point to the array x by
the following assignment:
p = x;
This is equivalent to
p =&x[0];
Now, we will access every value of x using p++ to move from one element to another. The
relationship between p and x is shown as below:
p= &x[0] (=1000) p+1 =&x[1] (=1002)
p+2 =&x[2] (=1004)
p+3 =&x[3] (=1006)
p+4 =&x[4] (=1008)
We may notice that the address of an element is calculated using its index and the scale factor
of the data type.

#include <stdio.h>
int main () {
int value_array[] = {55, 366, 855, 112};
int a, *point[4];
printf("the array of pointer\n\n");
for (a = 0; a < 4; a++) {
point[a] = &value_array[a]; // assigning address!

46
}
for (a= 0; a < 4; a++) {
printf("Value => var[%d]: %d\n", a, *point[a] );
}

return 0;
}
output:
array of pointers!

Value => var[0]: 55


Value => var[1]: 366
Value => var[2]: 855
Value => var[3]: 112ple:

4.5 POINTERS AND STRUCTURES


If we know that the name of an array stands for the address of its zeroth element. The same
thing is true for the names of arrays of structure variables. Suppose product represents the
address of its zeroth element. Consider the following declaration given:
struct inventory
{
char name[30]; int number; float price;
} product[2], *ptr;

The above statement declares product as an array of two elements, each of the type struct
inventory and ptr as a pointer to data objects of the type inventory. The assignment given in
below statement
ptr = product;
We would assign the address of the zeroth element of product to ptr. That is, the pointer ptr
will now point to product[0]. Its members will be accessed using the following notation.
ptr ->name ptr -> number ptr -> price

47
The symbol -> is called the arrow operator is made up of a sign and a greater than sign. Note
that ptr is simply another way of writing product[0]. When the pointer ptr is incremented
by one, it is made to point to the next record. i.e. product[1].
The following for statement will print the values of members of all the elements of product
array.

for(ptr=product; ptr<product+2;ptr++)
{
printf(“%s %d %f\n”,ptr->name,ptr->number,ptr->rate);
}
#include<stdio.h>
struct point
{
int a;
float b;
};
int main()
{
struct point p1={4,8.3};
struct point *p2=&p1;
printf("pointers to structures!\n\n");
printf(" The first value is: %d\n",p2->a);
printf("The second value is: %0.1f",p2->b);
return 0;
}
output:
pointer to structures!

The first value is: 4


The second value is: 8.3

4.6 POINTERS AND FUNCTIONS

48
If an array is passed to a function as an argument, only the address of the first element of the
array is passed, but not the actual values of the array elements. If x is an array, if we call any
function by passing x as an argument like sort(x), the address of x[0] is passed to the function
sort. The function uses this address for manipulating the array elements. Similarly, we will
pass the address of a variable as an argument to a function in the normal way.
If we pass addresses to a function, the parameters receiving the addresses should be pointers.
The process of calling a function using pointers to pass the addresses of variables is called as
‘call by reference’, where the process of passing the actual value of variable is called as ‘call
by value’. The function which is called by ‘reference’ can change the value of the variable
used in the call.
Consider the following code:
void main()
{
int x; x = 20;
change(&x); /* call by reference or address */
printf(“%d\n”,x);
}
change(int *p)
{
*p=*p+10;
}

If the function change() is called, the address of the variable, not its value, is passed into the
function change(). Inside change(), the variable p is declared as a pointer and therefore p is
the address of the variable x. The statement,
*p = *p + 10;

means‘add 10 to the value stored at the address p’. since p represents the address of x, the
value of x is changed from 20 to 30. Therefore the output of the program will be 30, not 20.
This mechanism is known as “call by address” or “pass by pointers”. Rules for pass by
Pointers given below:
1. The types of the actual argument and formal arguments should be same.

49
2. The actual arguments (in the function call) should be the address of variables that are
local to the calling function.
3. The formal arguments in the function header should be prefixed by the indirection
operator *.
4. If the prototype, the arguments must be prefixed by the symbol *.
5. To access the value of an actual argument in the called function, we should use the
corresponding formal argument prefixed with the indirection operator *.
Returning multiple values through pointer
In functions, we can seen that it return just one value using a return statement. That is
because; a return statement can return only value. Suppose, however that we need to get more
information from a function. We will achieve this using the arguments not only to receive
information but also to send back information to the calling function. The arguments that are
used to “send out” information are called output parameters.
The mechanism of sending back information through arguments is achieved using what are
known as the address operator (&) and indirection operator (*). Following is the example:
void main()
{
int x=20,y=10,s,d;
void mathoperation(int x, int y, int *s, int *d); clrscr();
mathoperation(x,y,&s,&d); printf(“\n s=%d \n d=%d”,s,d); getch();
}
void mathoperation(int x, int y, int *s, int *d)
{
*s=x+y;
*d=x-y;
}
#include <stdio.h>
void display(int *val);
int main () {
int a;
display(&a);
printf("TechVidvan Tutorial: Passing pointers to function!\n\n");
printf("Value is: %d\n",a);
return 0;

50
}
void display(int *val) {
*val = 1002;
return;
}
output:
TechVidvan Tutorial: Passing pointers to function!

Value is: 1002

4.7 SUMMARY

At the end of this unit we have learnt pointer concept in depth, we dealt with advance concept
on pointers such as passing pointer to function and returning pointer from function. In the
later stage we focused pointer arithmetic. In the last section of this unit we have discussed
pointers and arrays, pointers and structures and also pointer and functions..
4.8 KEYWORDS

Pointer, pointers and arrays, & operator, * operator


4.9 QUESTIONS

1. How can pointers be used as arguments for function? Demonstrate the stages with
suitable code as an example?
2. Discuss pointers and functions.
3. With example explain pointer and arrays.
4. Describe declaration of pointer in C.
5. Explain pointers and functions.
4.10 REFERENCE

 "Common Pointer Pitfalls" by Dave Marshall


 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden
 Simplifying C (First Edition 2010) Publication: Dreamtech by Harshal Arolkar and
Sonal Jain

51
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

UNIT 5: DYNAMIC MEMORY ALLOCATION

52
Structure
5.0 objectives
5.1 Introduction
5.2 Dynamic memory allocation
5.3 Malloc() function
5.4 Calloc() function
5.5 Realloc() function
5.6 Free() function
5.7 Summary
5.8 Keywords
5.9 Questions
5.10 References

5.0 OBJECTIVES

After going through this unit you will be able to


 Elucidate dynamic memory allocation
 Discuss Malloc() function
 Describe Calloc() function
 Explain Realloc() function
 Discuss Free() function

5.1 INTRODUCTION

53
The dynamic memory allocation in c language concept enables the C programmer to
allocate memory at runtime. Dynamic memory allocation in c language is having the 4
functions of stdlib.h header file.

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

5.2 DYNAMIC MEMORY ALLOCATION


In programming where we may have to deal with data we may come across some situations,
which is dynamic in nature. During the executions of a program the number of data items
may change. The number of customers in a queue will be increase or decrease during the
process at any time. If the list grows we need to allocate more memory space to
accommodate additional data items. Such situations can be handled by using dynamic
techniques very easily. Dynamic data items executes at run time, thus optimizing file usage of
storage space.
The process of allocating memory at run time is called as dynamic memory allocation.
Although c does not inherently have this facility there are four library routines which allow
this function.
The many languages permit a programmer to specify an array size at run time. Such
languages would have the ability to calculate and assign during executions, the memory space
required by the variables in the program. But C programming inherently does not have this
facility but supports with memory management functions, which can be used to allocate and
free memory during the program execution. The following functions are used in c for purpose
of memory management.

Function Task
malloc This function allocates memory requests size of bytes and returns a pointer to the 1 st
byte of allocated space.
calloc This function allocates space for an array of elements initializes them to zero and
returns a pointer to the memory.
Free This function frees previously allocated space

54
realloc This function modifies the size of previously allocated space.

Memory Allocation Process:


According to the conceptual view of the program instructions, global and static variable in a
permanent storage area and local area variables are stored in stacks. The memory space that is
located between these two regions is available for dynamic allocation during the execution of
the program. The free memory region is called the heap in dynamic memory allocation. The
size of heap keeps on changing when program is executed due to creation and death of
variables that are local for functions and blocks. Therefore it is possible to encounter memory
overflow during dynamic allocation process. In such situations, the memory allocation
functions mentioned above will return a null pointer.

5.3 MALLOC()
Malloc: Allocating a block of memory
A block mf memory can be allocated using the function malloc. The malloc function reserves
a block of memory of specified size and returns a pointer of type void. This means that we
will assign it to any type of pointer. It takes the following form:
ptr=(cast-type*)malloc(byte-size);

ptr is a pointer of type cast-type the malloc returns a pointer (of cast type) to an area of
memory with size byte-size.

Example:
x=(int*)malloc(1000*sizeof(int));

On successful execution of this statement a memory equivalent to 1000 times the area of int
bytes is reserved and the address of the first byte of memory allocated is assigned to the
pointer x of type int. The malloc allocates a block of contiguous bytes. The allocation will fail
if the space in the heap is not sufficient to satisfy the request. If it fails, it returns a NULL.

C program to find sum of n elements entered by user. To perform this program,


allocate memory dynamically using malloc() function.
#include <stdio.h>

55
#include <stdlib.h>
int main(){
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int)); //memory allocated using malloc
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
return 0;
}

5.4 CALLOC()

Calloc means Allocating multiple blocks of memory. Calloc is another memory allocation
function that is normally used for requesting memory space at runtime for storing derived
data types such as structures and arrays. The malloc allocates a single block of storage space
but the calloc allocates multiple blocks of storage, each of the same size and then sets all
bytes to zero. The general format of calloc is:
ptr=(cast-type*) calloc(n,element-size);

56
The above statement can allocates contiguous space for n blocks each size of elements size
bytes. Here all bytes are initialized to zero and a pointer to the first byte of the allocated
region is returned. If there is not enough space a null pointer is returned.

The following segment of a program allocates space for a structure variable:


…..
structstudent
{
char name[25]; float age; longintid_num;
};
typedefstruct student record; record *st-ptr;
int class_size = 45;

st_ptr=(record *)calloc(class_size, sizeof(record));


…..
record is of type struct student having three members: name, age and id_num. the calloc
allocates memory to hold data for 45 such records.
Example for calloc() function
write a c program to find sum of n elements entered by user. to perform this program, allocate
memory dynamically using calloc() function.
#include <stdio.h>
#include <stdlib.h>
int main(){
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)calloc(n,sizeof(int));
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)

57
{
scanf("%d",ptr+i);
sum+=*(ptr+i);
}
printf("Sum=%d",sum);
free(ptr);
return 0;
}

5.5 REALLOC()
Realloc is used to altering the size of a block: If the previously allocated memory is not
sufficient and then we need additional space for more elements. It is also possible that the
memory allocated is much larger than necessary and we need to reduce it. In mentioned
above cases, we can change the size of memory already allocated with the help of the
function realloc. This process is known as the reallocation of memory. For example, if the
original allocation is done by the statement
ptr = malloc(size);
then reallocation of space may be done by the statement
ptr = realloc(ptr, newsize);
this function allocates a new memory space of size newsize to the pointer variable ptr and
returns a pointer to the first byte of the new memory block. The newsize may be larger or
smaller than the size.

Example for realloc() function:

Here, ptr is reallocated with size of newsize.


#include <stdio.h>
#include <stdlib.h>
int main(){
int *ptr,i,n1,n2;
printf("Enter size of array: ");
scanf("%d",&n1);
ptr=(int*)malloc(n1*sizeof(int));

58
printf("Address of previously allocated memory: ");
for(i=0;i<n1;++i)
printf("%u\t",ptr+i);
printf("\nEnter new size of array: ");
scanf("%d",&n2);
ptr=realloc(ptr,n2);
for(i=0;i<n2;++i)
printf("%u\t",ptr+i);
return 0;
}
5.6 FREE()
Free: Releasing the used space.The Compile time storage of a variable has allocated and
released by the system in according to the storage class. In the dynamic runtime allocation, it
is our responsibility to release the space when it is not required. When the storage is limited
then the release of storage space becomes more important. When we no longer want the data
we stored in a block of memory and we do not intend to use that block for storing any other
information, we may release that block of memory for future use, using the free function.
free(ptr);
ptr means the pointer that has been created by using malloc or calloc.

5.7 SUMMARY

At the end of this unit we have covered dynamic memory allocation. In dynamic memory
allocation we have discussed about different memory management functions such as
malloc(), calloc(), free() and realloc() with some programming examples.
5.8 KEYWORDS

dynamic allocation, Malloc(), Calloc(), Free() and Realloc().


5.9 QUESTIONS
1. Describe dynamic memory allocation.
2. Write a short note on malloc() and Calloc().
3. Explain realloc with example.
4. Differentiate different memory allocation.
5.10 REFERENCE

59
 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden Simplifying C
(First Edition 2010) Publication: Dreamtech by Harshal Arolkar and Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

60
UNIT 6: LINKED LIST

Structure
6.0 objectives
6.1 Introduction
6.2 Linked list
6.3 Types of linked list
6.4 Singly linked list
6.5 Applications of linked list
6.6 Summary
6.7 Keywords
6.8 Questions
6.9 References

6.0 OBJECTIVES

After going through this unit you will be able to


 Elucidate linked list
 Discuss types of linked list
 Describe singly linked list
 Discuss applications of linked list

61
6.1 INTRODUCTION

A linked list consists of various nodes, and each node contains two things: One is the data,
and the other is the pointer, which will point to the next node. A linked list basically can
have n nodes, and each node is connected to its next node with the help of a pointer.
6.2 LINKED LIST

A linked list is a data structure. A data structure is nothing but how we organize and store the
data in memory. A linked list consists of various nodes, and each node contains two things:
One is the data, and the other is the pointer, which will point to the next node. A linked list
basically can have n nodes, and each node is connected to its next node with the help of a
pointer. There are two types of linked lists: singly linked lists (SLL) and doubly linked lists
(DLL).

In a SLL, we have a single pointer that’ll point to the next node and, therefore, it is called a
singly linked list. In a DLL, we have two pointers: One pointer will point to the next node, and
another will point to the previous node. That’s why we call it a doubly linked list.

In C programming, we use structures to create a linked list. The structure is a data type inside
which we can define variables with different data types (e.g., int, char, pointer, etc.).

For creating a linked list, we’ll define the structure of our linked list (using the struct data
type), which will represent what a single node in a linked list will look like. And then we’ll
actually create a linked list by assigning memory to use using the malloc() function.

Structure of a linked list:


The above code represents the structure for our linked list which contains two things. First is a
variable, data, which will hold the integer value inside it. And the second is struct node *p,
which is a pointer that’ll point to the next node in a linked list. Here, struct represents the
structure data type, and node is the name of that structure. You can give whatever name you
want to the structure.

62
Advantages of linked lists:

Linked lists have many advantages. Some of the very important advantages are:

1. Linked lists are dynamic data structures. i.e., they can grow or shrink during
the execution of a program.
2. Linked lists have efficient memory utilization. Here, memory is not pre-
allocated. Memory is allocated whenever it is required and it is de-allocated
(removed) when it is no longer needed.
3. Insertion and Deletions are easier and efficient. Linked lists provide flexibility
in inserting a data item at a specified position and deletion of the data item
from the given position.
4. Many complex applications can be easily carried out with linked lists.

Disadvantages of linked lists:

1. It consumes more space because every node requires a additional pointer to


store address of the next node.
2. Searching a particular element in list is difficult and also time consuming.

6.3 TYPES OF LINKED LISTS

Basically we can put linked lists into the following four items:

1. Single Linked List.


2. Double Linked List.
3. Circular Linked List.
4. Circular Double Linked List.

A single linked list is one in which all nodes are linked together in some sequential
manner. Hence, it is also called as linear linked list.

A double linked list is one in which all nodes are linked together by multiple links which

63
helps in accessing both the successor node (next node) and predecessor node (previous
node) from any arbitrary node within the list. Therefore each node in a double linked list
has two link fields (pointers) to point to the left node (previous) and the right node (next).
This helps to traverse in forward direction and backward direction.

A circular linked list is one, which has no beginning and no end. A single linked list can be
made a circular linked list by simply storing address of the very first node in the link field
of the last node.

A circular double linked list is one, which has both the successor pointer and predecessor
pointer in the circular manner.

ARRAY LINKED LIST

Size of an array is fixed Size of a list is not fixed

Memory is allocated from stack Memory is allocated from heap

It is necessary to specify the number of It is not necessary to specify the


elements during declaration (i.e., during number of elements during declaration
compile time). (i.e., memory is allocated during run
time).
It occupies less memory than a linked It occupies more memory.
list for the same number of elements.
Inserting new elements at the front is Inserting a new element at any position
potentially expensive because existing can be carried out easily.
elements need to be shifted over to make
room.
Deleting an element from an array is Deleting an element is possible.
not possible.

64
6.4 SINGLY LINKED LIST
Operations Performed on an SLL
1. Insert an element in the linked list
 Before inserting a node (element) into a linked list, you first have to create a node by
using malloc.
 Also, before inserting a node (element), you first have to check whether the head is
pointing to the NULL or not — otherwise, it will give a segmentation fault.

if (head == NULL) {
return;
}

 Now, there are three ways in which we can insert this node in the above linked list
Insert node at the beginning

For inserting a node that we’ve created that’s being pointed by a pointer called new
at the beginning of the linked list, we have to write the following code.
new ->link = head;
head = new;

65
What this will do is: It’ll first store the starting address of the node that’s being
pointed by the pointer head into the node that’s being pointed by pointer new. And
then it’ll assign the address of the new pointer to the head pointer.

If you directly assign the address of new pointer to the head pointer to insert the
node at the beginning before storing the address of the head pointer to the new
pointer, then the entire linked list will be lost because, in this case, there’s no pointer
that’ll be pointing to that memory location where the starting node of our linked list
is present.
This might be somewhat confusing at first to understand, so I suggest you read it a
number of times and try to understand it visually.
b. Insert node in the middle
Now to insert the node in the middle, we first have to think about where we’ll be
inserting the new node.
Let say we want to insert the newly created node after the second node in the above
linked list. For that, we have to reach the second node and then store whatever the
second node is pointing too into the new->link. And then, we’ll insert the node at
the location.

66
Insert node in the middle

c. Insert node at the end


For inserting a node at the end, we first have to find the end of the linked list. The
ending node or the last node in a linked list will always have a NULL (also
represented as \0) in this next part. From the above linked list, we can say the node
that has a value of 5 is the last node because its next is NULL.
To reach the end, we first have to check whether t->next is null of not. If null, then
we can insert the node at the position. Otherwise, keep moving forward until we
reach t-> next is null.

Insert node at the end


2. Traversing a linked list
Traversing means visiting every node in a linked list.
For traversing, instead of using the actual pointer, which is currently pointing to the
linked list, we have to create another pointer (say, t). By using that, we can traverse
the list. Because if we move the current pointer, then there’s a chance we may lose
some of the nodes in a linked list.
Let’s understand this with an example. Say we have a linked list, as shown below.

67
So let’s traverse it.
Example of a linked list
Code for traversing the above linked list:

Output:
Here, first, we have a template for our node which defines what we have in our
linked list. Secondly, we have the main function inside, for which we’ve created a
new pointer t of type struct node (a pointer that we’ll use to traverse the list) and a
while loop which will print the data inside the list and then increment the pointer.
In this, we are now touching the head pointer. If we do this, then we may lose some
of the nodes inside our linked list as we have no pointer at the starting position of
the list.
After creating another pointer — say, t — you have a choice. You can either move t
or head. it doesn’t matter which because now you have two pointers at the starting
position of the linked list.
3. Delete an element from the linked list
Before deleting a node (element), you first have to check whether the head is
pointing to the NULL or not. Otherwise, it’ll give a segmentation fault.
Whenever you’re deleting an element from the linked list that you’ve created using
the malloc() function, you also have to free it up by using a free() function. It’s not
compulsory to free the space after deleting an element, but it’s a good practice to do
so.
Also, create a temporary pointer — say, t — to hold the node that you want to
delete, and then do the other operations. Otherwise, the node that you want to delete
will get lost.
Conditions to check:
There are three ways to delete a node in the same way as insertion.
a. Delete the node at the beginning
To delete the node at the beginning, create a new pointer t, and make it point to the
head. Now, we have to move the position of the head pointer one step ahead using
head = head->next. Then free up the t to delete the first element in a linked list.

Delete the node at the beginning


b. Delete the node in the middle

68
Here, we have to identify which node we want to delete. After that, create a new
pointer, and make it point to the position where the head pointer is pointing.
Let say we want to delete a node whose data part has the value 3. Then, check if t-
>next->data is 3 or not. If the data part, has a value of 3, then create another pointer
— say, p — to hold the next part of the node whose value is 3. After that, free the
location that’s currently pointed by the t pointer, and then assign the address of
pointer p to t->next.

Delete the node in the middle


c. Delete the node at the end
When we’re deleting a node at the end, then we have to stand two steps back and
check whether the second element is null or not.

The figure below explains the above code:

Delete node at the end


Searching for an element in a linked list takes a longer time O(n) because in the
worst case, we have to traverse n elements. And in the best case, we can find the
element in the first attempt, so time complexity will be O(1).
When searching for an element in an array, it takes O(1) times (considering the array
is sorted); otherwise, it’ll take O(n) times only.

The function delete_at_mid(), is used for deleting the intermediate node in the list.

void delete_at_mid()
{
int ctr = 1, pos, nodectr; node *temp, *prev; if(start == NULL)
{

}
else
{

69
printf("\n Empty List.."); return ;
printf("\n Enter position of node to delete: "); scanf("%d", &pos);
nodectr = countnode(start); if(pos > nodectr)
{

printf("\nThis node doesnot exist");


}

if(pos > 1 && pos < nodectr)


{
temp = prev = start; while(ctr < pos)
{
prev = temp;
temp = temp -> next; ctr ++;
}
}
else
{

}
}

prev -> next = temp -> next; free(temp);


printf("\n Node deleted..");

printf("\n Invalid position.."); getch();

}
}

70
Traversal and displaying a list (Left to Right):
To display the information, you have to traverse (move) a linked list, node by node from
the first node, until the end of the list is reached. Traversing a list involves the following
steps:

Assign the address of start pointer to a temp pointer. Display the


information from the data field of each node.

The function traverse() is used for traversing and displaying the information stored in the
list from left to right.
void traverse()
{
node *temp; temp = start;
printf("\n The contents of List (Left to Right):
\n"); if(start == NULL )
printf("\n Empty List");
else
{
while (temp != NULL)
{
printf("%d ->", temp -> data);temp = temp -> next;
}
}
printf("X");
}

6.5 APPLICATIONS OF LINKED LIST:

 Linked lists are used to represent and manipulate polynomial. Polynomials are
expression containing terms with non zero coefficient and exponents. For example:
o P(x) = a0 Xn + a1 Xn-1 n-1 X + an
 Represent very large numbers and operations of the large number such as addition,
multiplication and division.

71
 Linked lists are to implement stack, queue, trees and graphs.
 Implement the symbol table in compiler construction

7.7 SUMMARY

At the end of this unit we have covered linked list. Also discussed about types of liked list.
We have also discussed singly linked list. At the end of this unit also covered applications of
linked list.
7.8 KEYWORDS

Insert, delete, array and list


7.9 QUESTIONS
1. Describe linked list.
2. Discuss types of linked list.
3. Explain singly linked list.
4. Write applications of linked list.
7.10 REFERENCE
 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden Simplifying C
(First Edition 2010) Publication: Dreamtech by Harshal Arolkar and Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

72
UNIT 7: FILE HANDLING IN C

Structure
7.0 Objectives
7.1 Introduction
7.2 Basics of File handling in C
7.3 Defining and opening a file
7.4 Closing file
7.5 Input and output operations on file
7.6 Error Handling during I/O Operations
7.7 Summary
7.8 Keywords
7.9 Questions
7.10 References

7.0 OBJECTIVES

After going through this unit you will be able to


 Explain basics of File handling in C
 Defining and opening a file
 Briefly explain Closing file
 Discuss Input and output operations on file
 Elucidate Error Handling during I/O Operations

7.1 INTRODUCTION
A File is a collection of data stored in the secondary memory. So far data was entered into the
programs through the keyboard. So Files are used for storing information that can be
processed by the programs. Files are not only used for storing the data, programs are also
stored in files. In order to use files, we have to learn file input and output operations. That is,
how data is read and how to write into a file.

7.2 BASICS OF FILE HANDLING IN C

73
In programming, we may require some specific input data to be generated several numbers of
times. commonly, it is not enough to only display the data on the console. The data to be
displayed only a limited amount of data or may be very large can be displayed on the console,
and since the memory is volatile, it is impossible to recover the programmatically generated
data again and again. However, if we want to do so, we have to store it onto the local file
system which is volatile and will be accessed every time. Here, comes the need of file
handling in C.

File handling in C allows us to create, update, read, and delete the files stored on the local file
system through our C program. The below following operations can be performed on a file.

o Creating of the new file


o Opening of an existing file
o Reading from the file
o Writing to the file
o Deleting the file

There are two well defined ways to perform the file operation in c. the first one is known as
the low level I/O and uses UNIX system calls. The second method is referred to as the high-
level I/O operation and uses function in C’s standard I/O library. There are listed in table.

Function Name Operation


fopen() This function creates a new file for use.
Opens an existing file for use.
fclose() This function closes a file which has been
opened for use.
getc() This function reads a character from a file.
putc() This function writes a character to a file.
fprintf() This function writes a set of data values to a
file.
fscanf() This function reads a set of data values from
a file.

74
getw() This function reads an integer from a file.
putw() This function writes an integer from a file.

There are many other functions. Not all of them are supported by all compilers.

7.3 DEFINING AND OPENING A FILE


If we want to store data in a file in the secondary memory, we must specify some things
about the file to the operating system. They include:
 File Name
 Data Structure
 Purpose
Filename is a string of characters that make up a valid filename for the operating system. It
may contain two parts, a primary name and an optional period with the extension.
Examples:
Input.data, Prog.c, Student.c and Text.out
Data structure of a file is defined as FILE in the library of standard I/O function definitions.
Therefore, all files would be declared as type FILE before they are used. The FILE is a
defined data type. When we open a file, we must specify what we need to do with the file.
For Example, we may read or write data to the file or the already existing data.
The following is the general format for declaring and opening a file in C:
FILE *fp;
fp = fopen(“filename”, “mode”);
The first statement declared the variable fp as a “pointer to the data type FILE” is a defined
data type. File is structured that is defined in I/O library. The second statement opens the file
which one is given in format and assigns an identifier to the FILE type pointer fp. This
pointer which contains all the information absolute the file is subsequently used as a
communication link between the system and the program.
The second statement also tells the purpose of opening this file. The mode does this job.
Mode can be one of the following.

Mode Description
r Open the file for reading only.
w Open the file for writing only.

75
A Open the file for appending (or editing) data to it.

Both the filename and mode are specified as strings. They would be enclosed in double
quotation marks. When trying to open a file, one of the following things may happen:
 If the mode is ’writing’, a file with the specified name is created. if the file does not
exist. The content is detected, if the file already exists.
 If the mode is ‘appending’, the file is opened with the current contents safe. A file
with the specified name is created if the file does not exist.
 If the mode is ‘reading’, and if it exists, then the file is opened with the current
contents safe otherwise an error occurs.

Consider the following statements:

FILE *p1, *p2;


p1 = fopen(“data”, “r”);
p2 = fopen(“results”, “w”);

The file data is opened for reading and results is opened for writing. In case, the result file
already exists, its content is detected and the file is opened as anew file. If data file does not
exist, an error will occur.

Many recent compilers include additional modes of operation. They include:


r+ the existing a file is opened to the beginning for reading and writing.
w+ same as w except both for reading and writing.
a+ same as a except both for reading and writing.

7.4 CLOSING A FILE


A file should be closed as soon as all operations on it have been completed. This ensures that
all outstanding information associated with the file has flushed out from the buffers and all
links to the file are broken. It also prevents any accidental misuse of the file. In case, there is
a limit to the number of files that would be kept open simultaneously, closing of unwanted
files might help open the required files. Another instance where we should to close a file is

76
when we need to reopen the same file in a different mode. The I/O library supports a function
to do this for us. It takes the following form:

fclose (file_pointer);

This should close the file associated with the FILE pointer file_pointer. The following
segment of a program is given below.
-----
FILE *p1, *p2;
p1 = fopen (“INPUT”, “w”);
p2 = fopen (“OUTPUT”, “r”);
-----
fclose (p1); fclose (p2);

This program opens two files and closes them after all operation on them are completed.
After the file is closed, its file pointer can be reused for another file. Whenever a program
terminates automatically all files are closed.

7.5 INPUT/OUTPUT OPERATIONS ON FILES


Once a file is opened, reading out of writing to it is accomplished using the statement I/O
routines.

getc and putc functions


In C programming we have simplest file I/O functions getc and putc. These are similar to
getchar and putchar functions and handle one character at a time. Assume that a file is opened
with mode w and file pointer fp1. Then, the statement writes the character combined in the
character variable c to the file associated with FILE pointer fp1. Similarly, getc function is
used to read a character from a file that has been opened in read mode.

putc(c, fp1);

For example, the statement should read a character from the file whose file pointer is fp2.
c = getc(fp2);

77
The file pointer moves by one character position for every operation of getc and putc. The
getc will return an end-of-file maker EOF, when end of the file has been reached. Therefore,
the reading would be terminated when EOF is encountered.

getw and putw functions


The functions getw and putw are integer-oriented functions. They are analogous to the getc
and putc functions and are used to read and write integer values. These functions should be
useful when we deal with only integer data. The general format of getw and putw are:

putw(integer,fp); getw(fp);

fprintf and fscanf functions

The most compilers support two other functions, namely fprintf and fscanf, that can handle a
group of mixed data simultaneously.

The functions fprintf and fscanf perform I/O operations that are identical to the familiar printf
and scanf functions, expect of course that they work on files. The first argument of these
functions is a file pointer which state the file to be used. The general form of fprintf is

fprintf(fp,”control string”,list);

Where fp is a file pointer which is associated with a file that has been opened for writing. The
control string contains output specifications for the items in the list. The list may include
variables, constants and string.

Example:
fprintf(f1,”%s %d %f”,name,age,7.5);
Here, name is an array variable of type char and age is an int variable.
The general format of fscanf is
fscanf(fp, ”control string”, list);

78
This statement would state the reading of the items in the list from the file specified by fp,
according to the specifications contained in the control string.
Example:
fscanf(f2,”%s %d”, item, &quantity);

Similar to scanf, fscanf also returns the number of items that are successfully read. When the
end of file is reached, it returns the value EOF.

7.6 ERROR HANDLING DURING I/O OPERATIONS


During the file operations, it is possible that an error may occur. This error may occur due to
following reasons given below:
• Reading beyond the end of file mark.
• Performing operations on the file that has not still been opened.
• Writing to a file that is opened in the read mode.
• Opening a file with invalid filename.
• Device overflows.

Thus, to check the status of the pointer in the file and to detect the error is the file. C provides
two status-enquiry library functions

feof() - The feof() function can be used to test for an end of file condition

Syntax

Example

feof(FILE *file_pointer);

if(feof(fp))
printf(“End of file”);

79
ferror() - The ferror() function reports on the error state of the stream and returns true if an
error has occurred.

Syntax
ferror(FILE *file_pointer);

Example
if(ferror(fp)!=0)
printf(“An error has occurred”);

7.7 SUMMARY

At the end of this unit we have covered basics of file handling in C. Also discussed defining
and opening a file and then closing file. We have also discussed input and output operations
on file. At the end of this unit also covered error handling during I/O operations.
7.8 KEYWORDS

Fopen(), fclose(), getc(), putc(),fprint(), fscanf() and putw()


7.10 QUESTIONS
5. Describe file handling in C.
6. Write a short note on fprint() and fscanf().
7. Explain error handling in C.
8. Differentiate different Input/output operations.
7.10 REFERENCE
 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden Simplifying C
(First Edition 2010) Publication: Dreamtech by Harshal Arolkar and Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

80
UNIT 8: PREPROCESSORS

Structure
8.0 objectives
8.1 Introduction
8.2 Preprocessors
8.3 Types of preprocessor
8.4 Macro substitution directive
8.5 File inclusion directive
8.6 Compiler control directive
8.7 Summary
8.8 Keywords
8.9 Questions
8.10 References

8.0 OBJECTIVES

After going through this unit you will be able to


 Explain about Preprocessors in C.
 Describe types of preprocessors
 Elucidate macro substitution directive
 Discuss file inclusion directive
 Briefly explain compiler control directive

8.1 INTRODUCTION

The C preprocessor is a macro preprocessor (allows you to define macros) that transforms
your program before it is compiled. These transformations can be the inclusion of header file,
macro expansions etc. All preprocessing directives begin with a # symbol. For example,
#define PI 3.14

8.2 PREPROCESSORS
Most often it is made as a misconception that Preprocessors or macros are part of the
compilation of the program, but it is totally wrong. Preprocessor directives are the type of

81
macros and a phase before compilation takes place. It can be said that these are some set of
instructions given to compiler to perform actual compilation. They are also known as longer
construct abbreviations for macros which means the value in macros gets replaced with the
segment of codes. Macro is defined by a special symbol and has a symbol starting with “#”
Therefore these # define is a kind of special preprocessor followed by the actual compiler. In
this topic, we are going to learn about Preprocessor Directives in C.
The preprocessor has a special type of representation for its identification like any
preprocessor directive initiates itself by a special symbol of “#” followed by an identifier and
then the directive name. Whitespace is also allowed before and after the #. For example, #
include.

There are certain fits or facilities which a C Preprocessor can provide:

 Header files: Inclusion of header files are a way in which declarations can get
substituted by program syntax and program body.
 Expanding Macro: Defining macros are like abbreviating a piece of code which a C
preprocessor replaces the macros with their respective definition throughout.
 Compilation by Conditions: According to various scenarios or various conditions
inclusion of certain parts of the program is possible by conditional compilation.
 Line Control: If you use a program to combine or rearrange someone or more source
files into an intermediate file for compilation, you can use line control to inform the
compiler of where each source line originated from.

8.3 TYPES OF PREPROCESSOR DIRECTIVES

All types of Preprocessor Directives are as follows:

Directive Description

82
#define Substitutes a preprocessor macro

#include Inserts a particular header from another file


#undef Undefines a preprocessor macro
#ifdef Returns true if this macro is defined
#ifndef Returns true if this macro is not
defined#if Tests if a compile time condition is true
#else The alternative for #if

#elif #else an #if in one statement

#endif Ends preprocessor conditional

#error Prints error message on stderr

#pragma Issues special commands to the compiler, using a standardized method

Preprocessors Examples

Analyze the following examples to understand various directives.

#define MAX_ARRAY_LENGTH 20

This directive tells the CPP to replace instances of MAX_ARRAY_LENGTH with 20. Use
#define forconstants to increase readability.

#include <stdio.h> #include


"myheader.h"

These directives tell the CPP to get stdio.h from System Libraries and add the text to the current
source file. The next line tells CPP to get myheader.h from the local directory and add the conten
to the current source file.

#undef FILE_SIZE
#define FILE_SIZE 42

83
This tells the CPP to undefine existing FILE_SIZE and define it as 42.

#ifndef MESSAGE
#define MESSAGE "You wish!"
#endif

This tells the CPP to define MESSAGE only if MESSAGE isn't already defined.

#ifdef DEBUG
/* Your debugging statements here */

#endif

8.4 FILE INCLUSION IN C PROGRAMMING.


#include causes the contents of another file to be compiled as if they actually appeared in
place of the #include directive. The way this substitution is performed is simple, the
Preprocessor removes the directive and substitutes the contents of the named file. Compiler
allows two different types of #include’s, first is standard library header include, syntax of
which is as follows,
#include <filename.h>
Here, filename.h in angle brackets causes the compiler to search for the file in a series of
standard locations specific to implementation. For example, gcc compiler on Linux, searches
for standard library files in a directory called /usr/include.
Other type of #include compiler supports is called local include, whose syntax is as follows,
#include "filename.h"
filename in double quotes “” causes compiler to search for the file first in the current
directory and if it’s not there it’s searched in the standard locations as usual. Nevertheless, we
can write all our #include in double quotes but this would waste compiler’s some time while
trying to locate a standard library include file. Though, this doesn’t affect runtime efficiency
of program, however, it slows down compilation process. For ex.,
#include "stdio.h"
Notice here that stdio.h is a standard library file which compiler, first, should required to
search in the current directory before locating it in standard location. A better reason why

84
library header files should be used with angle brackets is the information that it gives the
reader. The angle brackets make it obvious that
#include <string.h>
references a library file. With the alternate form
#include "string.h"
it’s not clear if string.h is a library header or local file with same name is being used.
Remember that header files are suffixed with .h extension by convention. We can write our
own header files and include them in programs. For ex.,
/* sll.h */

#include <stdio.h>
#include <stdlib.h>#define T 1
#define I 2
#define S 3
#define D 4
#define Q 5
#define TRAVERSE "enter 1 to TRAVERSE the list..."
#define INSERT "enter 2 to INSERT new value in the list..."
#define SEARCH "enter 3 to SEARCH a value in the list..."
#define DELETE "enter 4 to DELETE a value from the list..."
#define QUIT "enter 5 to QUIT the program..."

typedef struct NODE {


struct NODE *link;
int value;
} Node;

/* function declarations */
int traverse(Node **);
void insert(Node **, const int);
int search(Node **, const int);
int delete(Node **, const int);
Notice here that header file named sll.h contained declarations to be used in a particular
program. The fact that everything in the header file is compiled each time it’s #include’d

85
suggests that each header file should only contain declarations for one set of functions or
data. It’s better to contain several header files, each containing the declarations appropriate
for a particular function or module than put up all declarations for the entire program in one
giant header file.

8.5 MACRO SUBSTITUTION DIRECTIVES

Macro substitution is a process where an identifier in a program is replaced by a predefined


string composed of one or more tokens. The preprocessor accomplishes this task under the
direction of #define statement. This statement, usually known as a macro definition takes the
following form:
#define identifier string
If this statement is included in the program at the beginning, then the preprocessor replaces
every occurrence of the identifier in the source code by the string.

Note: Care should be taken that there is no space between the # and the word define. Also
there should be atleast a single space between #define and the identifier and between
the identifier and the string. Also, there will be no semi-colon at the end of the statement.

There are different forms of macro substitution. The most common are:
1. Simple macro substitution
2. Argumented macro substitution
3. Nested macro substitution
Simple Macro Substitution

The simple macro substitutions are generally used for declaring constants in a C program.
Some

valid examples for simple macro substitution are:

86
8.6 COMPILER CONTROL DIRECTIVES

These compiler control directives are used in different situations. They are:

Situation 1

You have included a file containing some macro definitions. It is not known whether a certain
macro has been defined in that header file. However, you want to be certain that the macro is
defined.

This situation refers to the conditional definition of a macro. We want to ensure that the
macro TEST is always defined, irrespective of whether it has been defined in the header file
or not. This can be achieved as follows:

87
1 #include”DEFINE.H”
2 #ifndef TEST
3 #define TEST 1
4 #endif

DEFINE.H is the header that is supposed to contain the definition of TEST macro. The
directive #ifndef TEST searches the definition of TEST in the header file and if it is not
defined, then all the lines between the #ifndef and the corresponding #endif directive are
executed in the program.
8.7 SUMMARY

At the end of this unit we have discussed the preprocessors. Also covered types of
preprocessors. We have also dealt with macro substitution directive. At the end of this unit
also covered file inclusion directive and compiler code directive.
8.8 KEYWORDS

#include, #define, Macro and #ifdef


8.9 QUESTIONS
1. Describe preprocessorg in C.
2. Write a short note on types of preprocessors.
3. Discuss file inclusion directive.
4. Elucidate compiler code directive.
8.10 REFERENCE
 The C Programming Language (Ansi C Version) by Brian W. Kernighan, Dennis M.
Ritchie
 Expert C Programming: Deep C Secrets by Peter Van, Der Linden Simplifying C
(First Edition 2010) Publication: Dreamtech by Harshal Arolkar and Sonal Jain
 Programming in ANSI C (Fifth Edition 2011) Publication: Mc Graw Hill by
Balagurusamy
 Programming in C (First Edition 2011) Publication: Oxford Higher Education by
Reema Thareja

88

You might also like