You are on page 1of 180

Introduction to Borland C

Control Structure
Functions
Arrays
Pointers
Structures and Unions
File Handling

MSc. In Software

1
Introduction To
Borland C
Main points covered

!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!

Introduction
Displaying Different Types of Data with printf( )
The new line tag \n
puts()
putc()
Formatted output
Controlling the cursor position
Variables
sizeof()
Values in variables
Users input, scanf()
buffer
fflush()
User's input, getchar()

User's input, gets()


Summary

MSc. In Software

Introduction

rian Kernighan and Dennis Ritchie, two computer programmers, developed a


brilliant program called Operating System (OS). Unfortunately, this program
could be run only on one machine. They tried different methods but were not
successful. Since they could not find a solution, they created one - They wrote a
programming language, which enabled the OS to run on different machines (Mac,
PCs.) Thus "C" was born.
C - language possesses the powerful low-level features of second-generation
languages, like pointers, memory allocation, bit-manipulation etc. It also
supports conditional constructs, loop constructs, a rich list of operators and a
variety of data structures as in the third-generation languages.
The combined features of second and third generation languages make C language a
very powerful and flexible one. These features make it possible to use the language
for systems programming, like development of compilers, interpreters, operating
systems, graphics and general utilities and also for a host of applications in the
commercial environment.
You will understand the beauty of C as we go deep into it.

Displaying Different Type of Data with printf()


Program 1.1
#include<stdio.h>
main ()
{
printf(Hello Students.);
}

/*
/*
/*
/*
/*

Including standard input output header file.


Creating main function .
Starting of main function.
Standard printf statement for output.
End of main function.

*/
*/
*/
*/
*/

This is the smallest useful program in C language. In this program we particularly


have two uncommon words, main() and printf(). These are functions. You will
learn more about functions in the third chapter. For the time being, main() is the
first function to be called by the C compiler . Even if main() is not at the first line of
the program, the control goes there first and executes the program from that point.
There will be no C program without this main().
printf() is a less important function; meaning by C programs can exist without this
printf(). We put this printf() in our very first program, only because we want a
useful program. When you run this program you will get an output saying Hello
Students. This is the work of printf(). When you write anything in in printf(),
it will be displayed on the screen when you run (execute) the program.
Another difference between main() and printf() is that, when you say main(), you
create a function and when you say printf(), you call a function. You can also

MSc. In Software

observe that the word main () has no semicolon (;) following it. However, printf ()
has a semicolon at the end.
We will learn a lot more of printf () statement in the following pages.
A typical syntax of it (in comparison to our knowledge) is,
printf(what ever you want to display);
Run the program to get the output. Now to run the program you need to follow some
steps. Open Borland C++ and MS Dos on your computer. In Borland C++, click on
File on the menu bar and then click on new-> Text Edit. You will get an editing
space, write your full program here. Save this program in your working directory as a
file having .c extension. Now click on the compile button. If your program is right,
you will get a success status. Click on ok. Now click on the run button from your
menu bar. If you get a black screen, which will disappear immediately you are in the
right track. Now open your MS Dos screen and run the program in your working
directory by writing the primary name of your file. You will definitely get your
desired output.
You follow the same procedure for all the rest of the program.
If your program is not correct, you will get clues to correct your program from Borland
C++. We will discuss more about error messages in our practice session on the net.
Output of program 1.1
Hello Students.
By this time you must be wondering about the meaning of the first line. Here is the
explanation.
#include
C provides certain language facilities by means of a preprocessor, which is
conceptually a separate first step in compilation. The two most frequently used
features are:
#include - to include the contents of a file during compilation, and
#define - to replace a token by an arbitrary sequence of characters.
a) #include : File inclusion makes it easy to handle collections of declarations. Any
source line of the form,
or

#include filename
#include <filename>

MSc. In Software

is replaced by the contents of the file filename. If the filename is quoted, searching
for the file typically begins where the source program was found. If it is not found
there, or if the name is enclosed in < and >, searching follows an implementation
defined rule to find the file. An include file may itself contain #include files.
#include is the preferred way to tie the declarations together for a large program. It
guarantees that all the source files will be supplied with the same definition and
variable declaration, and thus eliminate a particularly nasty bug. Naturally, when an
included file has changed, all files that depend on it must be recompiled.
b) #define : Study the following program: If we remove the 2nd line, we will get an
error. This is because myname is not defined in the program. But if we keep the 2nd
line, 420 will replace all the myname in the program. This is the main feature of
#define. Sometimes, a few formulae which are often used in the program are
#defined, so that you do not need to write the whole thing again.
#include<stdio.h>
/* Including standard input output header file
#define myname 420
/* The usage of #define
main ()
/* Creating main function
{
/* Starting point of main function
printf(My name is %d, myname);
/* Standard printf statement
}
/* End of main function

*/
*/
*/
*/
*/
*/

This program appears very mysterious now. Do not panic, we will solve these
mysteries and learn everything before we finish this module.
Run the program to get the output.
Output My name is 420
Now, the second part of the line i.e.,
<stdio.h>
stdio.h is called a header file. It is basically a standard input output header file. All
the standard C-functions are written in this file. If you do not include this file in your
program, during compilation you will get a message saying, call to a function
printf with no prototype. Therefore, this line has to be included in all C
programs.
One more new word is prototype. Prototype means full description of a function, i.e.
the function name,
the type of parameters passed to it and
the type of return value of the function.
Before C calls any function, the details of the function should be available to C. The
header file stdio.h provides this prototype to the C program.

MSc. In Software

A typical syntax of function prototype is given below.


Return-type function-name (parameter1, parameter2)
This is not the right time to explain each part of this syntax. However, make a note of
this and we will explain the syntax while discussing functions.
Program 1.2
#include<stdio.h>
main ()
{
printf (Hello Students.);
printf(Good bye);
printf(Have a nice trouble);
}

/*
/*
/*
/*
/*
/*
/*

Standard input output header file.


Creating main function.
Starting of main function.
Standard printf statement for output.
Standard printf statement for output.
Standard printf statement for output.
End of main function.

*/
*/
*/
*/
*/
*/
*/

This is a bigger program. In the above example, we have used the same printf()
statement 3 times. So, you can expect 3 lines in the output. The problem is that, C
remembers where it printed last (how it remembers is not important at this stage).
Thus it will continue printing at the place it last printed and will give you a badly
shaped output.
Run the program to get the output.
Output of program 1.2
Hello studentGood byeHave a nice trouble

The new line tag \n


In order to get a clear display of the lines, we need to put a \n at the end of the 1st
and 2nd line. Whenever C sees a \n it jumps to the beginning of the next line. Thus
you will get the desired output.
Program 1.3
#include<stdio.h>
main()
{
printf(Hello students .\n);
printf(Good bye .\n);
printf(How do you find it ? );
}

/* Including standard input output header file.


*/
/* Creating main function
*/
/* Starting point of main function
*/
/*Standard printf statement with new line tag.
*/
/* Standard printf statement with new line tag
*/
/* Standard printf statement.
*/
/* End of main function.
*/

MSc. In Software

Notice that we have not put a \n at the end of the 3rd line. This is because our
program is getting over at the end of the 3rd line. Therefore, do we need to take care
of the cursor position?
Run the program to get the output.
Output of program 1.3
Hello students .
Good bye .
How do you find it ?
Whatever is put within and in printf (), is treated as a string of characters.
Now, lets see if we can display integer and float type data through the printf().
(More about data types while dealing with variables.)
Program 1.4
#include<stdio.h>
main()
{
printf(50\n);
printf(100.40);
}

/*
/*
/*
/*
/*
/*

Including standard input output header file.


*/
Creating main function
*/
Starting point of main function.
*/
Standard printf statement to display integer type data.*/
Standard printf statement to display float type data. */
End of the main function.
*/

Run the program to get the output.


Output of program 1.4
50
100.40
Though we claim to display the integer and the float type data, from printfs point
of view, it is not really doing anything extra.
The next program is just a variation of the above program. This program shows that
you can just put anything within " and " of a printf statement. We have just one
printf statement in this program. We still add a \n though it doesnt make any
sense. We have used it deliberately to make you understand how unimportant it is.
Program 1.5
#include<stdio.h>
main()
{
printf(Hello 50 \n);

/*
/*
/*
/*

Including standard input output header file.


Creating main function
Starting point of main function.
Standard printf statement.

*/
*/
*/
*/

MSc. In Software
}

/* End of the main function.

7
*/

The discussion about printf() function is not complete as yet. printf() is actually
used to display formatted data. We will revert to this function while dealing with
formatted data.
Run the program to get the output.
Output of program 1.5
Hello 50

puts()
There are other functions available to display string type and character type of
data. puts() is used to display string type data. puts() deals only with string type
data. Whatever we have learnt so far with printf statements is fully applicable for
puts() also. puts() cannot be used to display formatted output.
A typical syntax for this case is,
puts(what ever you want to put);
Program 1.6
#include<stdio.h>
/* Including standard input output header file.
main()
/* Creating main function
{
/* Starting of main function.
puts(You can display your name in this way also.);
/* The usages of puts ()
}
/* End of main function.

*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 1.6
You can display your name in this way also.

putchar()
Single characters can be displayed using the C library function putchar(). The
character being passed is normally represented as a character type variable. The
character must be enclosed in the parentheses, following the word putchar.
A typical syntax,

MSc. In Software

putchar( character to be displayed)


Program 1.7
#include<stdio.h>
main()
{
putchar(A);
}

/*
/*
/*
/*
/*

Including standard input output header file.


Creating main function
Starting of main function.
Usages of putchar function.
End of main function.

*/
*/
*/
*/
*/

Output of program 1.7


A

putc()
This is another function of C library. The functionality of this function is similar to the
putchar (), the only difference is that in this case, user needs to provide a pointer
(We will discuss pointer in detail in the pointer section), indicating where this function
should put the character that is passed to it.
A typical syntax for this,
putc(character to be displayed, a pointer indicating where to put the
character);
Program 1.8
#include<stdio.h>
main()
{
putc(A,stdout);
}

/*
/*
/*
/*
/*

Including standard input output header file.


Creating main function
Starting of main function.
Usages of putc function.
End of main function.

*/
*/
*/
*/
*/

In this case, it writes the character A to the standard output i.e. the monitor of the
computer. In C language putc is considered as a macro rather than a function.
Output of program 1.8
A
Again, there is a new word called macro. So, let us discuss,

Macros Versus Functions

MSc. In Software

To understand the functionality of macros, let us first study the following program.
#include<stdio.h>
#define UPPER 25
main()
{
printf(%d\n,UPPER);
}

/*
/*
/*
/*
/*
/*

Including standard input output header file


Upper is called macro which contains value 25
Creating main function
Starting point of main function
Standard printf statement
End of main function

*/
*/
*/
*/
*/
*/

In this program we will get output as 25. We are writing it in the form of UPPER,
which has already been defined before main() through the statement,
#define UPPER 25
This statement is called macro definition or more commonly, just a macro. What
purpose does it serve? During preprocessing, the preprocessor replaces every
occurrence of UPPER in the program with 25.
In C program it is customary to use capital letters for macros. This makes it easy for
programmers to pick up all the macros when reading through the program.
Note that macro definition is never to be terminated by a semicolon.
Though macro calls are like function calls, they are not really the same thing. Then
what is the difference between the two?
Read this program,
#include<stdio.h>
#define SQUARE(n)n*n
main()
{
int j;
j = 64/SQUARE(4);
printf(j = %d,j);
}

/*Including standard input output header file */


/* Another macro definition with variable
*/
/* Creating main function
*/
/* Starting point of main function
*/
/* Declaring a variable called j
*/
/* Usages of macro
*/
/* Displays the value of j.
*/
/* End of main function
*/

The output of the above program would be:


j = 64
Whereas what we expected was j = 4.
What went wrong? The macro was expanded into
j = 64/4*4;

MSc. In Software

10

64 first gets divided by 4, and the result is 16. Then 16 gets multiplied by 4, giving
you back 64.
In a macro call the preprocessor replaces the macro template with its macro
expansion, in a stupid, unthinking, literal way. Whereas in a function call the
control is passed to a function along with certain arguments, some calculations are
performed in the function and a useful value is returned from the function.
This brings us to a question: when is it best to use macros with arguments and when
is it better to use a function? Usually macros make the program run faster but
increase the program size, whereas functions make the program smaller and compact.
If we use a macro hundred times in a program, the macro expansion goes into our
source code at hundred different places, thus increasing the program size. On the
other hand, if a function is used then even if it is called from hundred different places
in the program, it would take the same amount of space in the program.
But passing arguments to a function and getting back the returned value does take
time and would therefore slow down the program. This gets avoided with macros
since they have already been expanded and placed in the source code before
compilation.
Moral of the story is: if the macro is simple like in our example, it makes nice
shorthand and avoids the overheads associated with function calls. On the other hand,
if we have a fairly large macros and it is used fairly often, perhaps we ought to
replace it with a function.

Formatted output
In all these programs, you will not have any control over the position of the string on
the screen. Format specification strings of C language are used to control the
position of an output on the screen. (We have said screen here, because right now we
are dealing only with the outputs that will appear on the screen.)
If you want more power in displaying your material at the desired position, you need
to satisfy C with something that might not make any sense to you. Something like
this:
printf (control string, arg1, arg2, arg3argn);
This is a typical syntax for printf (). Here, control string determines how the
arguments passed to the printf () will get displayed. Here, agr1, arg2 are different
arguments. They can be of different data types. Control string knows how to handle
different types of data.
Read the following example to get a clear idea of control string.
As long as data types are concerned, it will be cleared while dealing with variables.

MSc. In Software

11

#include<stdio.h>
/* Standard input output header file.
main()
/* Creating main function.
{
/* Starting point of main function.
printf(%c \t %d \t %f \n %s\n,a,50,20.5,I am learning C.);
/* Standard printf function.
}
/* End of main function.

*/
*/
*/

Program 1.9

*/
*/

Let us discuss each part of the printf statement.


%c means part of control string, used for character type data get displayed.
%d means part of control string, used for integer type data get displayed.
%f means part of control string, used for float type data get displayed.
%s means part of control string, used for string type data get displayed.
\t means part of control string, used to position cursor(one tab forward).
\n means part of control string, used to position cursor(new line).
This is a typical of printf statement. In this printf statement we have 4 arguments.
They are of different data types.
The first argument, a will take the position of %c,
the second argument, 50 will take the position of %d,
the third argument, 20.5 will take the position of %f and
the last argument, I am learning C will take the position of %s.
We have already come across the new line tag \n. In this program we have a new
tag \t. Whenever C sees a \t, the cursor moves one tab position in the forward
direction. So, ultimately we have achieved to place the second argument and the third
as well, to our desired position.
Notice that we have a \n after %f (the position of third argument). So, we can
expect our fourth argument to start from the beginning of the next line.
Run the program to get the output.
Output of program 1.9
a
50
20.5
I am learning C.

Controlling the cursor position


There are many control string elements used for different purposes. A list of that is
given below.

MSc. In Software

\a
\b
\f
\n
\r
\t
\v
\\
\?
\
\
\<enter>
\nnn
\oxnn
\007

12

Audible alert
Back space
Form feed
New line
Carriage return
Horizontal tab
Vertical tab
Back slash
Question mark
Double quote
Single quote
Line continuation
nnn
=
octal
character value
Hexadecimal value
Beep

These are called format specification string.


You can also mention the space in the format specification string.
Like this,
Format specification Data
string
%2d
9

Output

-%2d
%03d
%10s
-%10s
-%10.2s
%0.2s
%f
%4.1f

|9_|
|009|
|----Output|
|Output----|
|Ou--------|
|Ou|
|87.670000|
|87.7|

9
9
Output
Output
Output
Output
87.67
87.67

|_9|

%2d, if you put a 2 in %d it means you allocate 2 spaces for a numerical data to
get displayed. Data get displayed in the right aligned manner by default.
-%2d, if you put a - before a format specification string, data get displayed in left
aligned way.
%03d, this is interesting. 3 spaces will be reserve for data display. Display will be
right aligned. Blank spaces will be filled up by 0s.

MSc. In Software

13

%10s, this will display a string type of data. Space reserved for display is 10.
Display will be right aligned.
-%10s, this will display a string type of data. Space reserved for display is 10.
Display will be left aligned.
-%10.2s, this will display a string type of data. Space reserved for display is 10.
Display will be left aligned. However, only 2 characters will appear.
%0. 2s, this will display a string type of data. Space reserved for display is 2.
Display will be right aligned. Only 2 characters will appear.
%f , This will display a float type data. 6 spaces will be reserved for the decimal
part by default.
%4.1f, this will display a float type of data. Only one space will be reserved for the
decimal part.
It is evident that format specification strings are used for three main purposes:
First,
Second,
Third,

it determines the data type.


it defines the space on which the data is to be displayed
it decides the alignment of data.

For other data types there are some more format specification strings.

%n

%i
reads a decimal integer
%e
reads a floating point number
%g
also reads a floating point number
%o
reads an octal number
%x
reads a hexadecimal number
%p
reads a pointer
%u
reads an unsigned integer
%[]
scans for a set of character
receives an integer value equal to the number of characters read so far.

Program 1.10
#include<stdio.h>
main()
{
printf(a = %c, a = %d\n,a,a);
}
Run the program to get the output.
Output of program 1.10

/*
/*
/*
/*
/*

Standard input output header file.


Creating main function.
Starting point of main function.
Standard printf function.
End of main function.

*/
*/
*/
*/
*/

MSc. In Software

14

a = a, a = 97
Computers do not recognize a,b,c,d or 1,2,3,4 as it is. Everything is stored in
the form of 1s and 0s. The different combinations of 1s and 0s make a letter or a
digit. In the above program %c is replaced by a whereas %d denotes the ascii
value of a. Ascii value denotes a number by which a is known to the computer.

Variables
Variable literally means a storing space for data. There are four fundamental data
types:
i) char,
ii) short,
iii) int
and
iv) long type.
These data types have nothing to do with alphabet types of data or numerical types of
data. When a variable is created, C will inquire about the memory that the variable
would require. Instead of answering in a cryptic fashion you declare the variable as
either a char, short, int or long.
When you define a as char type of data, it means a occupies one memory
space. If you define a as short type of data, it means a occupies two memory
spaces. Similarly, if you define a as int type of data, it means a occupies four
memory spaces. In Borland C, long type variable also occupies 4 memory spaces.
(For window system these values are different. But that should not bother you right
now.)

sizeof()
sizeof is a function that tells us the size of a variable meaning by how many bytes
get reserved by a particular type of data. We have already told you that different
variables occupy different amount of memories. The following program is a proof of
that.
Program 1.11
#include<stdio.h>
main()
{
short i;
int j;
char k;
long l;
float f;
double d;

/*
/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function.
Starting point of main function
Declaration of short type data.
Declaration of integer type data.
Declaration of character type data.
Declaration of long type data.
Declaration of float type data
Declaration of double type data.

*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

15

printf(short = %d .. int = %d .. char = %d long = %d float = %d double =


%d\n , sizeof(i), sizeof(j),sizeof(k),sizeof(l),sizeof(f), sizeof(d));
/* This printf displays the size of different types of data. */
}
/* End of the program
*/
In this program i, j, k, l, f, d are the six variables. They have their respective data
types. The printf() function of this program will show the amount of memory space
occupied by these variables.
Run the program to get the output.
Output of program 1.11
Short = 2 ..int = 4.. char = 1 ..long = 4 float = 4 double = 8
float type is used to handle data with a decimal point. double type behaves just
as int type, with a difference that its size is double the size of an int type variable.

Values in Variables
Variables should have values. You are aware that variables mean storage spaces.
What you store in that place is called value of the variable. The following program will
elaborate it for you.
Program 1.12
#include<stdio.h>
main()
{
int i;
i = 10;
printf(The value of the variable
}

/* Standard input output header file


*/
/* Creating main function
*/
/* Starting point of main function.
*/
/* Declaration of an int type variable.
*/
/* Assigning a value to the variable.
*/
i is %d , i);
/* Apart from the prompt, it shows the input.*/
/* End of main function
*/

Run the program to get the output.


In this program we have declared a variable, i of int type. That means, somewhere
in the memory we have reserved four memory spaces and that is referred as i. In
that memory location we put a value 10. In technical language it is called assigning a
value to a variable. You know the meaning of the next sentence. %d will be replaced
by the value of i i.e. 10.
By all means, it is a programmers program. The user can only see the output of this
program. He/she cannot change the value of the variable.

MSc. In Software

16

Output of program 1.12


The value of the variable is 10
In the following pages, we will learn how the user can enter his/her desired value to a
variable.

User's input, scanf ()


scanf() of C language is responsible for user input. In other words scanf () receives
whatever the user enters through the keyboard. A typical syntax of scanf () is given
below,
scanf (control string, arg1,arg2,.argn);
The syntax for scanf() and printf() are identical. But in the case of non-string type
data an & (ampersand) is required in front of the variable.
Program 1.13
#include<stdio.h>
/* Standard input output header file */
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
int i;
/* Declaration of variable.
*/
printf("Enter the value of i:"); /* This is a prompt for you to enter some value. */
scanf("%d", &i);
/* This function is responsible to get the value you have entered.
*/
printf("The value of i that you have entered is %d",i);
/* Standard printf statement.
*/
}
/* End of main function
*/
Now, the user is free to enter any value for 'i. The value you have entered will get
displayed at %d of printf(). If you have entered 101 at the prompt, the next line will
display the message: The value of i that you have entered is 101.
Output of program 1.13
Enter the value of i: 101
The value of i that you have entered is 101
As far as string type data is concerned, the syntax of this function is the same as
printf(). For integer or character type of data an &(ampersand) is necessary
before the data. For example,
Program 1.14

MSc. In Software

17

#include<stdio.h>
/* standard input output header file
main()
/* Creating main function
{
/* Starting point of main function
int num;
/* Declaring an integer type variable
char sex;
/* Declaring a char type variable
char name[20];
/* Declaring a string type variable
printf("Enter the Roll no. ");
/* Standard printf statement for prompt
scanf("%d", &num);
/* Usage of scanf() for integer type of data
fflush(stdin);
/* Clearing buffer
printf("Enter Sex :");
/* Standard printf statement for prompt
scanf("%c", &sex);
/* Usage of scanf() for char type of data
fflush(stdin);
/* Clearing buffer
printf("Enter the Name of the student :"); /* Another prompt
scanf("%20s", name);
/* Usage of scanf() for string type of data
printf("Roll no. - %d Sex - %c Name - %20s \n", num,sex,name);
/* Displaying roll no., sex and name
}
/* End of main function

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

In the above example sex is a character type of data, num is a numeric type of
data and name is a string type of data. Notice that the data names are listed as
&sex and &num when the data type is character or number type.
Run the program to get the output.
Output of program 1.14
Roll no. - 99

Sex - F

Name - XYZ

In this program, after you enter the roll no., the cursor jumps to the next line and
waits there for the second input. When you enter the data for sex, which is a
character type, the cursor jumps again to the next line for the third input. In the
format specification part of scanf() you can even mention the size of the data.
Another point to be noticed is that, for more than one data input through scanf(),
you need to clear the input buffer through fflush().

What is this buffer?


We did not say anything about the buffer before since it is invisible to the
programmer when using high-level disk I/O functions. However, buffer is necessary
even if it is invisible.
Consider, for example, how inefficient it would be to actually access the disk every
time we want to write a character to it. Every time we write something to a disk, it
takes sometime for the disk drive to position the read/write head correctly. On a
floppy disk system, the drive motor has to actually start rotating the disk from a
standstill every time the disk has accessed. If this is to be done for every character

MSc. In Software

18

we write to the disk, it would take a long time to perform disk I/O. This is where the
buffer comes in.
When you send a character by using scanf (), the character is actually stored in a
buffer, an area in memory, rather than being immediately written to the disk. When
the buffer is full, its contents are written to the disk at once. Or if the program knows
that the last character to be written to the disk has been received in the buffer, but it
is still not full, it forces the buffer to be written to the disk.
In most of the cases, these activities take place automatically; the programmer
doesnt need to worry about them.

Now, something about fflush()


fflush() is a new word for you. If you use scanf(), you have to use fflush(). The
reason is to get rid of a peculiarity of scanf(). After supplying the data for roll no.,
we would hit the enter key. What scanf() does is it assigns roll no. to appropriate
variable and keeps the enter key unread in the key board buffer. So, when we enter
the value for next item, the program reads the enter key from the buffer thinking
that user has entered the enter key. To avoid this problem we use the function
fflush(). It is designed to remove or flush out any data remaining in the buffer.
The argument to fflush() must be the buffer that we want to flush out. Here, we use
stdin, which means buffer related with standard input device the keyboard.
We know how to enter data and how to get a desired output.
User's input, getchar()
Previously, we used scanf() for formatted input. As discussed before, formatted
means the space and alignment of data. C-language provides two more functions:
gets() and getchar() for unformatted data input. The next program will explain this.
Program 1.15
#include<stdio.h>
main()
{
char initial;

/* Standard input output header file


*/
/* Creating main function
*/
/*Starting point of main function
*/
/*Name of the variable is initial. It is a
character type.
*/
puts("Enter Initial of your name at the prompt :");
/* Displaying this message on the screen
*/
initial = getchar();
/* Usages of getchar().
*/
printf("Initial of your name is :%c", initial);
/* Apart from displaying the message, this
line will also show your input.
*/
}
/* End of main function
*/
Run the program to get the output.

MSc. In Software

19

Output of program 1.15


Enter Initial of your name at the prompt: A
Initial of your name is A
In this program, initial is the name of the variable of char type. When you run this
program the cursor will wait after : for an input from the user. You can enter
a,b,c, or your name as you like. This program will show the first character that
you have entered.

User's input, gets()


Suppose you want to enter your name i.e., in computer terminology, a string. Here
we like to mention that for strings scanf() is not a better option. This is because, if
the string contains a blank (for example, a blank between first and second name),
scanf() assumed that the name being entered has ended. The result is that there is
no way (at least not without a lot of trouble on the programmers part) to enter a
multi word string to a single variable. The solution to this problem is to use gets().
Program 1.16
#include<stdio.h>
main()
{
char name[20];
puts("Enter your name(not more than

/* Standard input output header file


/* Creating main function
/* Starting point of main function
/* Declaring a string of length 20
20 character) :");
/* standard prompt
gets(name);
/* Usages of gets()
printf("The name you have entered is : %-20s",name);
/* Standard printf statement with left alignment specification
}
/* End of main function

*/
*/
*/
*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 1.16
Enter your name (not more than 20 character) : Abcd
The name you have entered is : Abcd
This program will expect a string of 19 characters. The cursor will wait after the : for
your input. If you enter less than 19 characters, there will be no problem. If you enter
more than 19 characters, you are writing in spaces that are not reserved by your
variable.
In your practice paper run the same program without the - sign before %. If your
input is less than 20 letters, in your practice session you will get a bad looking output.

MSc. In Software

20

This is because in normal cases, all the alignments are right setting. Unless you make
your alignments left setting, for a shorter name, you will get a gap between is and
the name, you have entered. Therefore, the output of the above program will be like
this,
The name that you have entered is ---------------Abcd.
Your input will be displayed in these 20 blank spaces. Now if you put - sign before
% sign the name will start from the left position. Otherwise, it will end at the right
most position.

Summary
In this chapter we have covered the following topics.
# Introduction
This is actually not a topic but a brief introduction of the birth of C. Why C is an
important language. It is a combination of second and third generation languages.
It has got many important features like bit manipulation, pointers etc. It is the C
language that is used to develop compiler, interpreter even the operating system.
Since this language can interact directly to the memory, speed becomes another
important feature of this language.

# Displaying Different Types of Data with printf()


This function is the second most important function of C language. This is the main
function, which helps you to get something on the monitor when you run the
program. There are of course other functions available to do the similar kind of job.
But as you go ahead, you will understand the importance of this function.
# The new line tag \n
This is the most commonly used tag in C language. When C program sees this tag,
it understands that the next print should start from the beginning of the next line. If
you do not use this, your C program will put all your sentences in a single line.
# puts()
This function is used to display strings on the monitor.
# putc()
This function is used to display a single character on the monitor.
# Formatted output

MSc. In Software

21

The subject under this heading deals with how to display different types of data on
the monitor in a desired way. This type of formatted output is only possible with
printf(). puts() and putc() cannot be used in this case.
# Controlling the cursor position
Here we have discussed different parameters of control string. In the table, we have
given a lot of control string elements. You can use all of them the way we have used it
for \t or for \n. The meaning of all the tags are given there.
# Variables
The function of the variable is to reserve some memory spaces for use. This reserved
memory should be known by some name. These names are called variables. As you
know already, there are different types of variables. Different variables reserve
different amount of memory. For instance short type of variable reserve two memory
locations. In the main lesson we have discussed the details of this memory allocation.
# sizeof()
This is also a function of C language. This function takes the type of variable as the
parameter of the function. This function returns the amount of memory reserved by
that particular variable type.
# Values in variables
This is understood that we reserve some memory spaces to keep something there.
This something is called the value of the variable.
# Users input, scanf()
This is also a function of C language. Through this function the user can put some
value into variables while the program is running.
# Buffer
This is some sort of memory. Data input output becomes very easy from this part of
the memory. For details of buffer, see references.
# fflush()
This function is used to flush out or remove any remaining data left in the buffer.
fflush() is always used after scanf().
# User's input, getchar()

MSc. In Software

22

This function is also useful for users input. But this function does not support any
formatting string. This function is generally used for single character input.
# User's input, gets()
scanf() is not suitable for the input of strings. gets() is the best function while users
input is of string type.

Zee Interactive Learning System

MSc. In Software

2
Control Structures
Main Topics Covered

!
!
!
!
!
!
!
!
!
!
!
!
!
!

Introduction
conditions(if ..else.)
conditions(switchcase)
Nested condition
looping(for,while,do..while)
Conditions in loops
Unary Operator
Binary Operator
Ternary Operator
Comma operator
Compound assignment
Increment / Decrement Operator
Casting of Variables
Summary

MSc. In Software

Introduction

n the previous chapter we had written a program to enter a name (be it your own or
your friends'). However, after running the program you could enter only one name. For
the second name, you had to run the program again. You might find this procedure
very boring. C-language offers you facilities whereby you can enter any number of names
with the desired length.
Moreover, you might have a lot of names, but would want only a few of them to appear on
the screen. In which case, your program should follow some conditions. We will discuss
these procedures in this chapter.

Condition (if..else)
In the following program we will discuss a decision making tool called if. if takes a
condition as a parameter. If the condition is TRUE, the following statements get executed.
If the condition is not TRUE, the following statements simply get ignored. if has got its
counterpart as else. When the if part is not TRUE, the else part must be TRUE. And
vice-versa. But it is not necessary that every if part should be followed by an else part.
A typical syntax for ifelse statement is as follows.
if(condition)
{
statement1;
statement2;
.
.
.
}
else
{
statement1;
statement2;
.
.
.
}
Nested if..else is also allowed. We will discuss them with proper programs.
Program 2.1
#include<stdio.h>
main()
{

/* Including standard input output header file.


/* Creating main function
/* Starting point of main function

*/
*/
*/

MSc. In Software
if(0)
printf(hi \n);
printf(bye);
}

/*
/*
/*
/*

This is if condition.
Standard printf statement
Standard printf statement
End of main function

3
*/
*/
*/
*/

We repeat that 'if is a word, understood by C, as a decision making tool. We need to give
a condition with if. If the condition happens to be TRUE, the block of statements (within
{ and } ) following the if condition get executed. On the other hand, if the condition is
FALSE, the statements within the if block are ignored. In case of a single statement after
if condition, we generally do not put { and }. In such cases the ; after the statement
indicates the end of the if block.
All these statements will be explained clearly with examples.
Here we have said:
if(0)
When the compiler sees a zero, it interprets the statement as FALSE. Hence this statement
instructs the C compiler to ignore the next statement.
As discussed earlier, the second printf statement is not within the if condition. Therefore,
you will get an output as Bye.
Run the program to see the output.
Output of program 2.1
Bye

Program 2.2
#include<stdio.h>
main()
{
if(0)
{
printf(hi \n);
printf(bye);
}
}
Run it to see the output.

/*Including standard input output header file


/* Creating main function
/* Starting point of main function
/* This is the syntax of if condition.
/* Starting point of if statement.
/* Standard printf statement already familiar
/* Standard printf statement
/* End of if statement.
/* End of main function

*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

Output of program 2.2


(blank screen)
If you get a blank screen, it means that the program is working fine. Notice that you have
enclosed both the printfs within the if statement. This causes both the statements to be
ignored. Hence the blank screen.
Program 2.3
#include<stdio.h>
main()
{
if(8)
printf(Hi \n);
printf(Bye);
}

/*
/*
/*
/*
/*
/*
/*

Including standard input output header file


Creating main function
Starting point of main function
This is the syntax of if condition.
Standard printf statement
Standard printf statement
End of main function

*/
*/
*/
*/
*/
*/
*/

Whenever we have any number other than zero in the if condition, the compiler
understands it as TRUE and does not ignore the following statements. Here, the if
condition evaluates a TRUE as the parameter passed is 8 (anything other than zero).
So, as per definition you should be able to execute the first printf statement. At this point
the role of the if condition is also over. But you cannot stop the second printf from being
executed. Therefore, you will get two lines as output.
Run the program
Output of program 2.3
Hi
Bye
Let us now discuss some variables in the if condition.
Program 2.4
#include<stdio.h>
main()
{
int i;
i = 0;
if(i)
printf(Hi \n);
i = 6;
printf(Bye);
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file


Creating main function
Starting point of main function
Declaration of variable.
Initialisation of the variable.
This is if condition with variable.
Standard printf statement
Reinitialisation of variable.
Standard printf statement
End of the main function

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

We will now discuss the variables in the if condition. A single variable can have different
values in this condition. With different values we assume that the condition is sometimes
TRUE and sometimes FALSE. To remind you, any value other than zero is TRUE and zero is
FALSE.
In this program, the value of i is zero initially. So, it ignored the printf statement
following if(i). Later, we will assign a non-zero value (6) to the variable. However, at this
stage, the if condition is TRUE and you will get an output as Bye.
Run the program and see the output.
Output of program 2.4
Bye

Nested Condition
It is important to state that if can be used in a nested pattern i.e., within one if
statement, you can place more if clauses.
Program 2.5
#include<stdio.h>
main()
{
int i=0,j=7;
if(i)
printf(Value of i
else
{
if(j)
printf(Value of
else
printf(Value of
printf(Value of i
/*
}
}

/* Including standard input output header file*/


/* Creating main function
*/
/* Starting point of main function
*/
/* Declaration and initialization of variables */
/* if condition with variable
*/
is not zero\n);/* Standard printf statement
*/
/* else part of the if stated above
*/
/* Starting point of else block
*/
/* Nested if
*/
j is not zero\n);
/* Standard printf statement
*/
/* Nested else
*/
j is zero\n);
/* printf statement within nested else */
is zero\n);
printf statement outside nested else but within outer else */
/* End of outer else block
*/
/* End of main function
*/

Study the program carefully. i has been assigned a value of 0. However, the first if
statement in the 5th line is FALSE. So, the control heads for the else part of the
statement. Within else we have an if..else block. This if evaluates the statement as
TRUE because the value of j is 7, i.e. non-zero. Therefore, in your output you can expect
the line Value of j is not zero as given by the next printf statement.

MSc. In Software

Since in this case if is TRUE, the else part has to be FALSE. However, the boundary of
the else part gets over after the first printf statement following it. Therefore, you cannot
stop the second printf statement from being executed.
Can you guess the output now? Read the above example again to understand the function
of { and }.
Output of program 2.5
Value of j is not zero
Value of i is zero

Condition (switchcase)
A switch statement evaluates an expression and attempts to match the value of the
expression with the case label. If a match is found, the program executes the associated
statement and if the match is not found, it executes the default. The default is optional. If
the default is absent and the switch is not found, the program continues execution at the
end following the switch. An example of a switch statement is as follows:
switch(expression)
{
case label:
statement;
break;
case label:
statement;
break;
...
default : statement;
}
For a better understanding, read the following program.
Program 2.6
#include<stdio.h>
/* Including standard input output header file*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
char x ;
/* Declaration of variable
*/
printf(Enter any character in lower case \n);
/* Standard printf statement or prompt
*/
scanf(%c,&x);
/* Standard scanf() statement.
*/
switch(x)
/*This is switch condition statement. x is the name of the variable. */
{
/* Beginning of switch function
*/
case a :
printf(Input is a \n);
/* Syntax of switch function.
*/
break;
/* Required in switch function */
case b :
printf(Input is b \n);
/* Syntax of switch function.
*/

MSc. In Software
break;
case c
break;
default
}
}

:
:

/* Required in switch function


printf(Input is c \n);
/* Syntax of switch function
/* Required in switch function
printf(It is a default case);/*Syntax of switch function
/*End of switch function
/* End of main function

7
*/
*/
*/
*/
*/
*/

Run the program to see the output.


Output of program 2.6
Enter any character in lower case
a
Input is a
This switch () function takes the variable name when you have to compare its value with
the specified cases. The variable may be an integer expression or a character constant.
They also specify the corresponding action that you might have to take if the value
matches with the value of the switch () variable. After the action for a particular case
value is specified, you can use the break statement to bring the control out of the
switch() block of statements.
If you fail to specify the break statements in the above function and the switch() variable,
x, contains b, the display will be,
Input is b
Input is c
It is the default case.
This is because when one of the case statements is evaluated as TRUE, the action
statements are executed until a break statement sends the control out of the switch()
block of statements or the switch() block comes to an end.

for looping
The most commonly used loop is, for loop. A 'for loop repeats until a specified condition
evaluates to FALSE. Following is an example of a 'for' statement:
for([initialExpression]; [condition]; [incrementExpression])
{
statements
}
All three expressions in for loop are optional.

MSc. In Software

The initializing expression:


The initial-expression, if any, is executed first. This expression usually initializes one or
more variables, but the syntax allows an expression of any degree of complexity.
The condition expression:
Then condition expression checked and if condition returns TRUE, the loop statements
executed else the loop terminates.
The increment/decrement expression:
Then after executing all the statements inside loop increment/decrement expression
updates the initialized variables, and again condition is checked. This process is repeated
until the condition is FALSE. Alternately we can exit the loop by break statement.
Study the following program:
Program 2.7
#include<stdio.h>
main()
{
for(i= 1; i<= 10; i++)
printf(%d\n,i);
}

/*
/*
/*
/*
/*
/*

Including standard input output header file


Creating main function
Starting point of main function
This is for loop, a feature of C-language
Standard printf function, giving the value of i
End of the program.

*/
*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 2.7
1
2
3
4
5
6
7
8
9
10
Here we have shown you the 'for loop'. The 'for loop' takes 3 items called parameters,
each separated by semicolons. Hence we have three parameters and two semicolons. The
first parameter establishes the initial value of i (in our case 1). The second parameter is
the condition testing parameter. The third parameter is the action to be taken till the
limiting condition is reached. The 'for loop' works in the following way:

MSc. In Software

Here, initially i = 1. C checks if it is <= 10 i.e. if i<=10. Yes it is! It goes to


printf(%d\n,i);
and prints 1.
Hence the output is 1. i is now incremented by the i++ part of the for loop.
i++ means i = i+1 i.e. increment the current value of i by 1 and store the new value of
i in i.
Again C checks is i<=10 i.e. 2<=10? Yes it is!! It then proceeds to:
printf(%d\n,i);
and prints 2.
This continues till the condition i<10 is met.
When i becomes 10, it is incremented once more. i now becomes 11. Now the condition
i<=10 no longer holds TRUE and we exit out of the 'for loop'.
Make a small change in the code.
Program 2.8
#include<stdio.h>
main()
{
int i;
for(i = 1; i<=10;i++)
printf(%d\n,i);
printf(%d\n,i);
}

/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable of int type
*/
Standard for syntax, already discussed */
printf statement within for loop
*/
printf statement outside for loop
*/
End of the program.
*/

Here the effect of the 'for loop' is limited only to the first printf statement (Since the
semicolon (;) at the end of the first printf marks the end of the 'for loop') When we exit
from the 'for loop' the value of i is 11 which will be printed by the second printf
statement.
Run the program and check it.
Output of program 2.8
1
2
3
4

MSc. In Software

10

5
6
7
8
9
10
11
Introduce another small modification in the above program:
Program 2.9
#include<stdio.h>
main()
{
int i;
for(i = 1; i<=10;i++)
{
printf(%d\n,i);
printf(%d\n,i);
}
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file


Creating main function
Starting point of main function
Declaring a variable of type int
Standard for loop syntax
Starting point of for loop
Displaying the value of i
Second time displaying the value of i
End of for loop
End of main function

Run the program to get the output.


Output of program 2.9
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

11

This time both the printfs are within the 'for loop' (This is because { and }).

While looping
A 'while loop' executes its statements as long as a specified condition evaluates to TRUE.
An example of the syntax of a 'while statement' is as follows:
while(condition)
{
statements
}
Before executing the loop the condition is checked. If the condition is TRUE the statements
in the loop are executed. If it is FALSE, the control bypasses to the statement following the
loop.
Program 2.10
#include<stdio.h>
main()
{
int i;
i = 1;
while(i <= 10)
{
printf(%d\n,i);
i++;
}
}

/* Including standard input output header file */


/* Creating main function
*/
/* Starting point of main function */
/* Declaring a variable
*/
/* Initialisation of the variable.
*/
/* while loop, another looping feature of C language.*/
/* Beginning of while loop.
*/
/* Standard printf statement.
*/
/* Incrementing i.
*/
/* End of while loop.
*/
/* End of main function.
*/

while takes just one parameter and that is the condition testing parameter.
Run this program to get the output.
Output of program 2.10
1
2
3
4
5
6
7
8
9
10

MSc. In Software

12

The output of this program and the output obtained from program 2.6 will be identical.
We will now explain the loop in detail. Notice that in the condition part of the 'while loop',
we have only one parameter. Initialisation of the variable is done outside the loop. This
loop will continue till the condition (i<=10) is TRUE. Notice that we have not put any
semicolon (;) after this line, because it is not the end of the statement. When the condition
is TRUE the action to be taken is written within the loop body.
Within the loop, the first line will faithfully print 1. %d will be replaced by the current
value of i i.e.,1. In the previous chapter we have discussed this in detail.
} is the sign of the end of the while loop. It means that the control will go back to line
no 4 after meeting this line. This will be repeated until i becomes 11.
Is it clear to you that after each cycle the value of i will be incremented by 1?
When i becomes 11 and control exits from the loop, it is the end of the program.
Now look at this code and guess the outcome:
Program 2.11
#include<stdio.h>
main()
{
int i;
i = 1;
while(i<= 10)
{
printf(%d\n,i);
}
}

Run this program to get the output.


Output of program 2.11
1
1
1
1
1
.
.
.

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
Initialising the variable
*/
while loop with condition
*/
Starting point of while loop
*/
Printing the value of i
*/
End of while loop
*/
End of the program
*/

MSc. In Software

13

Here we have not included i++ in the loop. This means that the value of i will never be
incremented. i will always remain at its initial value (which is 1).
The condition i<=10 (i.e. 1<=10) will always be TRUE and hence we will now have an
infinite loop. Therefore, it will continue printing 1 1 1 1
In this case you have to stop the program with <Ctrl> <Alt> and <Del>.
Now you understand that the philosophy of a 'while loop is no way better or worse than
that of a 'for loop. It is merely a matter of choice.

Do..while looping
The do...while statement repeats until a specified condition evaluates to FALSE. An
example of a do...while statement is as follows:
do{
statement
} while (condition)
Here the statement is executed once and then the condition is checked. If the condition
returns TRUE, the statement is executed again. At the end of every execution, the
condition is checked. When the condition returns FALSE, execution terminates and control
passes to the statement following do...while.
Program 2.12
#include<stdio.h>
main()
{
int i;
i = 1;
do
{
printf(%d\n,i);
i++;
}while(i<=10);
}
Run the program to get the output.
Output of program 2.12
1
2
3
4
5

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
Initialising the variable
*/
do of dowhile loop
*/
Starting point of the loop
*/
Displaying the value of i
*/
Incrementing the value of i by 1
*/
Syntax of dowhile loop and the end of it*/
End of main function.
*/

MSc. In Software

14

6
7
8
9
10
The output of this program is identical to the output of program 2.9. Let us discuss the
main differences between these two loops:
In the first case, the control checks the condition for looping and if it is TRUE, it enters
the loop.
In the second case, the control goes straight into the loop, follows instructions and then
checks the condition. If the condition is TRUE, it repeats the whole part of the loop. If the
condition is FALSE, it exits from the loop.
Observe that if the condition is FALSE at the very beginning, the 'while loop does not
perform at all, but the 'dowhile loop will function at least once.
Program 2.13
#include<stdio.h>
main()
{
int i = 1;
while(i>= 10)
{
printf(%d\n,i);
}
}

/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring and initializing the variable
*/
Syntax of while loop
*/
Starting point of while loop
*/
Displaying the value of i
*/
End of while loop
*/
End of the program
*/

Run the program to get the output.


Output of program 2.13
(Blank screen)
In the third line of this program we have declared and initialized i in the same line.
This is permissible. However, in this program, i will never become equal to or greater
than 10. Therefore, the program will terminate without giving any output.
Program 2.14
#include<stdio.h>
main()
{
int i = 1;
do
{

/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring and initializing the variable
*/
do of dowhile loop
*/
Starting point of dowhile loop
*/

MSc. In Software
printf(%d\n,i);
}while(i>=10);
}

15

/* Displaying the value of i


*/
/* End point of the loop with the while part */
/* End of the program
*/

This is a similar program with the dowhile loop. Though the condition for the loop is
always FALSE, you will get one value of i i.e., 1 (initial value) in your output.
Output of program 2.14
1

Conditions in loops
Let us now club together condition making and looping. We have already discussed the
'if' and 'switch' conditions.
Program 2.15
#include<stdio.h>
main()
{
int i;
for (i = 1; i<= 10; i++)
{
if(i>= 3)
printf(%d\n,i);
}
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
for loop, already discussed
*/
Starting point of for loop
*/
Incorporating if condition within the loop */
Displaying the value of i
*/
End of for loop
*/
End of the program
*/

Run the program to get the output.


Output of program 2.15
3
4
5
6
7
8
9
10
Here i starts with the initial value of 1. Then, the if condition (Is i >= 3) is tested.
The value of i will be printed only when this condition is satisfied.
In many instances we would prefer to make the if statement more restrictive.

MSc. In Software

16

Program 2.16
#include<stdio.h>
main()
{
int i;
for (i = 1; i<= 10; i++)
{
if(i>= 3 && i <= 7)
printf(%d\n,i);
}
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
Standard for loop statement
*/
Starting point of for loop
*/
if condition with logical operator
*/
Displaying the value of i
*/
End of for loop
*/
End of the program
*/

&& should be read as AND. This is called logical operator. This 'if' statement in English
means: print the value of i only if both conditions are TRUE. That again means that
between 1 and 10 only 3,4,5,6 and 7 will get printed as output.
Run the program to see the output.
Output of program 2.16
3
4
5
6
7
Program 2.17
#include<stdio.h>
main()
{
int i;
for (i = 1; i<= 10; i++)
{
if(i>= 4)
printf(%d\n,i);
else
printf(%d..\n,i);
}
}
Run the program to get the output.

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
A standard for loop
*/
Starting point of for loop
*/
if condition with a compound condition
*/
A standard printf statement
*/
else part of if
*/
A standard printf statement
*/
End of for loop
*/
End of main function
*/

MSc. In Software

17

Output of program 2.17


1..
2..
3..
4
5
6
7
8
9
10
Here we have an ifelse construct. Whenever you see an ifelse, remind yourself that
either one of them (if or else) will have to be executed.
Whenever the if condition is FALSE, the else part will have to be TRUE and vice-versa.
In the above program, we will start with the initial value of 1. The if condition is:
if(i >= 4)
Till i = 3 this condition will not be TRUE and hence the else part will automatically
become TRUE.
Run the program to see the output.
The important thing here is that the first three numbers in the output are printed by the
printf statement of the else part and the rest of the numbers are printed by the printf
statement in the if part of the program.
Program 2.18
#include<stdio.h>
main()
{
int i;
i = 4;
printf(%d\n, i = 6);
printf(%d\n,i);
i = 8;
printf(%d\n,i==7);
printf(%d\n,i);
}
Run the program to get the output.
Output of program 2.18

/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file


*/
Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
Initialising the variable
*/
Initialising the variable within printf statement */
A very standard printf statement
*/
Reinitialising the variable
*/
printf statement with a question, discussed later
*/
/* A standard printf statement
*/

MSc. In Software

18

6
6
0
8
Initially i had a value of 4. Now in the first printf the value of i is changed to 6. Hence
the output of the first printf will be 6. You can write assignment statements (like i = 6)
anywhere in the code. The second printf will also print 6. Now, we will set the value of i
as 8. The third printf statement is interesting. Whenever C sees a double equal sign (==),
it asks a question. The question is whether i (which is now 8) is equal to 7. The answer is
No or FALSE which is represented by 0. Hence it will print 0. Since there is no change
in the value of i, the last printf will print 8.
Program 2.19
#include<stdio.h>
main()
{
int i;
for(i=0;i<=10;i++)
{
if(i = 4)
}
}

printf(%d\n,i);

/*
/*
/*
/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
Standard for loop
*/
Starting point of for loop
*/
Within the if condition, the variable
being initialized
*/
/* Standard printf statement
*/
/* End of for loop
*/
/* End of the program
*/

Run the program to get the output.


Output of program 2.19
4
4
4
4
4
.
.
.
Here again, remember that the assignment statement can be put anywhere in the code.
Here i has the initial value of 0. When it comes to the if statement, the value of i first
becomes 4. Since if(4) is always TRUE, it prints 4. However, because of the 'for loop i
gets incremented by1 but as soon as it meets the if statement i becomes 4 again. So, 4
will continue printing unless we break the loop with (Ctrl-Break).

MSc. In Software

19

In the following example, observe that a very small modification to the above program will
give you a very different output.
Program 2.20
#include<stdio.h>
main()
{
int i;
for(i=0;i<=10;i++)
{
if(i == 4)
printf(%d\n,i);
}
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Including standard input output header file */


Creating main function
*/
Starting point of main function
*/
Declaring a variable
*/
A standard for loop
*/
Starting point of for loop
*/
if condition with a question
*/
A standard printf statement
*/
End of for loop
*/
End of the program
*/

Run the program to get the output..


Output of program 2.20
4
In this program of the if statement C inquires if i is equal to 4. This condition is satisfied
only once as the value of i goes from 0 to 10 and hence the output will be 4.

Operator
Logical Operator
You are already familiar with the logical AND (&&) operator.
C allows usage of three logical operators:
(a)
(b)
(c)

&&
||
!

(read as AND)
(read as OR)
(read as NOT)

There are several things to note about these logical operators. Most obviously, two of them
are composed of double symbols: || and &&. Dont use the single symbol | and &.
These single symbols also have a meaning. They are bitwise operators, which we will
examine separately.
The first two operator, && and ||, allow two or more conditions to be combined in an
if statement. Let us see how they are used in a program. Consider the following problem.

MSc. In Software

20

Program 2.21
#include<stdio.h>
/* including standard input output header file */
main()
/* Creating main function
*/
{
/* Starting point of the main function
*/
char x;
/* Declaring a variable
*/
x = getchar();
/* Usages of getchar()
*/
if(x == a || x == e || x == i || x == o || x == u)
/* if condition
*/
printf(This is a vowel\n);
/* Standard printf statement
*/
}
/* End of the function
*/
This is a very simple program to illustrate the meaning of ||. In this program the user is
supposed to enter a letter. If the letter by any chance happens to be a vowel, you will get
a message from the program, confirming that you have entered a vowel.
Moral of the story is that we have joined five conditions through ||. If any one or more of
the five conditions is/are TRUE, the result will become TRUE.
Output of program 2.21
a
This is a vowel.
So far we have used only the logical operators && and ||. The third logical operator is
the NOT operator, written as !. This operator reverses the value of the expression it
operates on; it makes a TRUE expression FALSE and a FALSE expression TRUE. Here is
an example of the NOT operator applied to a relational expression.
!(x < 10)
This means not x less than 10. In other words, x is greater than 10.
The NOT operator is often used to reverse the logical value of a single variable, as in the
expression
if (!flag)
this is another way of saying
if (flag = 0)
Does the NOT operator sound confusing? Avoid it if you find it confusing, since the same
thing can be always said without using the NOT operator.

MSc. In Software

21

Unary Operator
The unary operator (so called because it operates on a single operand) prefixed to an
integer constant (or variable) tells the compiler to reverse the sign by subtracting the
value (or variable) from zero. The effect it has is similar to using the sign to indicate a
number less than zero e.g. 12.

Binary Operators
Binary operators of C are similar to other programming languages. These are
+
*
/
%

(add),
(subtract),
(multiply),
(divide)
(modulo).

and

The parentheses () are used to clarify complex operations.


Apart from the module operator (%), you will be familiar with the other operators. The
module operator gives the remainder of the division between two integer values (constants
or variables). For instance:
Program 2.22
#include<stdio.h>
/*
main()
/*
{
/*
int x,y,z;
/*
x= 27;
/*
y= x % 5;
/*
z= x/5;
/*
printf(The value of y is %d\n,y);
printf(The value of z is %d,z);
}

Including the standard input output header file*/


Creating the main function
*/
Starting point of main function
*/
Declaring 3 int type variables
*/
Initialising the variable x
*/
Storing the remainder of the division
*/
Storing the dividend of the division
*/
/* Printing the value of y
*/
/* Printing the value of z
*/
/* End of the program
*/

Output of program 2.22


The value of y is 2
The value of z is 5
Here, y will be set to 2 (remainder of division of 27 by 5). Also note that z will take on
the value of 5 (integer division of 27 by 5).
An unusual aspect of programming in C is the arithmetic that can be done with characters.
Consider the following:

MSc. In Software
char ch1,ch2;
ch1 = 'a';
ch2 = ch1 + 1;

22

/* declaring two variables ch1 and ch2 */


/* set ch1 to 'a' i.e.
initialization */
/* sets ch2 to 'b'
*/

The second assignment increases the bit value in ch1 by 1(so that the new bit value
corresponds to 'b') and sets the result to ch2. Thus, ch2 now contains 'b'
A similar logic can be used for converting the case of a letter. Observe the following:
char ch;
ch = 'A';
ch = ch + 32;
ch = ch - 32;

/*
/*
/*
/*

declaring the variable


ch set to 'A'
ch now equal to a
ch back to 'A'

*/
*/
*/
*/

The values 32 in the above assignments correspond to the difference in ASCII value
between upper-case and lower-case letters.

Ternary Operators
A typical if..else statement is given below.
if (x>y)
{
z = x;
}
else
{
z = y;
}
In plain English the meaning of the above statements is as follows.
If x is greater than y, then assign z with the value of x, otherwise, assign z with the
value of y.
The same thing can be written in one line using ternary operator.
The same example is shown below:
z= (x > y) ? x : y;
Notice that the above statement works in a straightforward manner. The expression within
the ( ) is tested. If x is greater than y, z will be assigned the value x. Otherwise, it
will take on the value y.
This shorthand can reduce code in many situations.
The general form of an expression that uses the ternary operator (right-hand side of the
above statement) is:

MSc. In Software

23

(test-expression)? T-expression : F-expression;


The expression contains 3 parts and thus the term ternary.

Comma Operator
The comma operator is used to string together several expressions. The expression on
the right becomes the value of the total comma-separated expression. Read the following
example.
a = (b = 5, b + 2)
The above example first assigns b the value of 5 and then assigns a the value of 7
(5+2). The parentheses are necessary because the comma operator has a lower
precedence than the assigning operator.
The comma causes a sequence of operations. When used on the right side of an
assignment statement, the value assigned to the variable on the left side is the value of
the last expression of the comma-separated list.

Compound Assignment Operator


Apart from the standard assignment operator (=), C offers compound assignment
operators which simplify the following statements,
For example:
total = total + some_value;

/* Increase total by some_value*/

can be written as:


total += some_value;

/* Increase total by some_value*/

Another example is:


total-=some_other_value;

/* decrease total by some_other_value*/

The general form of this compound assignment is:


left-value op= right-expression;
Where, op can be either + (add), - (subtract), *(multiply),/ (divide) and %
(modulo). Other values op can take will be described later.
The above general form translates to:
left-value = left-value op right-expression;

MSc. In Software

24

The command assignment is useful, especially when long variable names are used, as in:
a_very_long_identifier = a_very_long_identifier + 2;
which can be written as:
a_very_long_identifier +=2;
The notation saves much typing effort without obscuring the meaning.

Increment/ Decrement Operators


Incrementing (and decrementing) by 1 is such a common computation that C offers
several shorthand versions of the above type of assignment. For instance:
and

total = sum++;

/*statement A*/

total = ++sum;

/* statement B*/

The first statement is equivalent to:


total = sum;
sum = sum + 1;
while the second is the same as:
sum = sum + 1;
total = sum;
Obviously, the above statements A and B do not have the same effect. The ++ in
sum++ is called the postincrement operator while it is called the preincrement
operator in ++sum.
In the following for construct:
for(ctr =0; ctr < 10; ctr++)
the value of ctr is compared to 10 and then incremented, after which the loop is entered.
On the other hand, if the construct is modified to:
for (ctr = 0; ctr < 10; ++ctr)
the value of ctr is first incremented, then compared to 10, and finally the loop is entered.
Thus in the first case, the body of the loop will be executed 10 times whereas in the latter
case, it will be executed only 9 times.

MSc. In Software

25

The above holds TRUE for the decrement operator, - -, as well.


If you just want to increment (or decrement) a variable without any assignment, the
postincrement and preincrement operators are effectively equivalent. So, the following
statements have the same result:
sum++;
++sum;

/* just increases sum by 1 */


/* also increases sum by 1*/

However, ++ (or - -) cannot be used on the left side of an assignment. For instance:
sum ++= total;
is not valid.

Casting of Variables
The arithmetic with characters leads one to suspect that C might be doing similar jugglery
with other data types. What will happen if an expression consists of different data types as
below?
int
i1;
float f1;
double d1;
d1 = f1 + i1;

/*
/*
/*
/*

Declaring an int type data


Declaring a float type data
Declaring a double type data
Arithmetic with different types of data

*/
*/
*/
*/

There is a set of rules, which, if followed, would prevent unexpected results.


The rules are:
a)
Any operand of type char is converted to an int.
b)
All floats are converted doubles.
c)
If either operand is double, the other is converted to a double, giving a double
result.
Thus in the assignment:
d1 = f1 + i1;
the following steps take place:
float f1 is converted to a double (rule b)
Since one operand is a double, the other, i1, is converted to a double (rule c)
The result, a double, is assigned to d1, which is a double.
Hence, no data is lost.

MSc. In Software

26

However, in the case of the assignment:


f1 = d1;
the following steps take place,
a)
b)
c)

Float f1 is converted to a double.


Double d1 is assigned to a double (corresponding to f1).
f1 is converted back to float.

You might lose some data during this conversion because a double value of 32 bytes is
being converted to a float value of 16 bytes.
Keep the above set of rules in mind and avoid assignments like the one above. Note that
though the rules appear confusing, they can be simulated with a paper and pencil and,
more often than not, the data type of the final result can be anticipated.
C also provides a facility to convert variables to a specific type before being evaluated in
an expression, through the casting facility. This has been used in the following code:
int i, j;
double d;
d = i / j;
double assigned the result of the division of two integers .
The problem with the above assignment is that the fractional portion of the above division
is lost and d is effectively assigned the quotient of the division of the two integers.
To resolve this, the variable i can be type cast into a double as follows:
d = (double) i / j;

/* i type cast into double */

In the above, the int i is converted to a double. The int j is also converted to a double
(remember the rules discussed earlier) and the result is a double. The result is assigned
to a double with no side effects.
Note that the type casting can be done only on the right-hand-side of an assignment.

Summary
# conditions(if ..else, switchcase)
This chapter shows how to put condition in your program. In plain English it means if
something is TRUE, do something and if something is not TRUE do not do something. We
have already told you the meaning of TRUE.

MSc. In Software

27

In C two ways are available for this condition checking. First one is ifelse case. We
already know about it, just to recap we can say that either if part or else part has to be
TRUE. It is not necessary to have an else part always. You can have multiple if blocks
one after another with different conditions. Like this,
if(condition 1)
{
statements
}
if(condition 2)
{
statements
}

.
.
.
if( condition n)
{
statements
}
One of these if blocks can contain the condition of else. Though we are saying, the
condition of else, else part really does not carry any condition. It is automatically the
reverse of the condition that if carries. Without any if there is no existence of else
part. Every if block can have its corresponding else part. Like this,
if(condition 1)
{
statements
}
else
{
statements
}
if(condition 2)
{
statements
}
else
{
statements
}

.
.
.
if( condition n)
{

MSc. In Software

28

statements
}
else
{
statements
}
Apart from this there are switchcase way of expressing conditions. This is some sort
of multiple ifs. If one condition is TRUE do something, other go for the next one. In
this case we do not have anything like else part, but we have default case. If no given
conditions are TRUE, it goes for default case.

# Nested condition
We have already discussed in detail the conditions. A typical syntax for this will be,
if (condition1)
{
statements
if (condition2)
{
statements
if (condition3)
{
statements
}
else
{
statements
}
}
else
{
statements
}
}
else
{
statements
}
This is not difficult to follow. Within one if we have more ifs. This is called nested
condition.

# looping(for, while, do..while)

MSc. In Software

29

In this summary section, we will not discuss loops again. Only thing we like to mention
again that all the loops are practically same. Only the dowhile loop is little different.
One more thing we like to mention here and that is the nested looping. Read this,
for( initializing ; checking ; incrementing)
{
for( initializing ; checking ; incrementing)
{
for( initializing ; checking ; incrementing)
{
statements
}
}
}
Only 3 nested loops we have considered here. You can put any number of loops as the
problem demands.
In a very similar way, you can have nested while and dowhile loops. Like this,
While(condition)
{
while(condition)
{
statements
}
}
Similarly, you think about dowhile loop.

# Conditions in loops
You can always put conditions within loop. When you deal with big projects, you have to do
a lot of conditions in loops. So, think about it and wait for the project to come.

# Operator
In the operator part we have discussed unary, binary, ternary and comma operator.
We can call these operators to some extent the mathematical operator. Enough on these
operators have been already discussed. More applications are available on the WEB SITE
zeelearn.com

# Compound assignment

MSc. In Software

30

One most important operator in C is the assignment operator. The sign for this operator is
=. This operator is used to assign any value to a variable. But compound assignment is
something different. It compresses the binary operator. Definition in detail is already
given. For more application login to our WEB SITE zeelearn.com

# Increment / Decrement Operator


This operation is only possible with addition and subtraction operator. In C we often use
incrementing or decrementing a variable by 1. So, the fathers of C made operators for
these operations. For more practical problems login to WEB SITE zeelearn.com

# Casting of Variables
Casting is required, when we force one type of variable to behave as some other type.
There are some rules to be followed for this. We have already discussed it. But for more
detail come to WEB SITE zeelearn.com
Zee Interactive Learning System

MSc. In Software

3
Functions
Main Topics Covered

!
!

!
!

!
!
!
!
!

Introduction
Storage Classes
automatic
global
external
static
register
Functions
Stacks
Passing of Parameters between functions
Passing char type variable and calling with short type
variable.
Passing short type variable and calling with char type
variable.
Restoring of Stack pointer
Variables are known by their memory locations and
not by their name
Calling functions by name and references
Recursion
Parameters of main()
Displaying - Command Line Arguments
Summary

MSc. In Software

Introduction

language is full of functions. If you remember, we dealt with functions in


chapter 1. Our first step was to create a function called main(). Within main(),
we had used printf(). All the functions that we have seen so far are part of the
C language. In this lesson, we will learn how to create our own function, called userdefined function.
The concept of function has made program writing easier. In this concept a big
program is divided into several functions. Thus, debugging, i.e. the correction of
program becomes very simple. But there must be some connections between these
functions. Generally, arguments or parameters are passed between these functions to
maintain these connections. To understand these connections, we will briefly discuss
stack.
Program 3.1
#include<stdio.h>
confused();
main()
{
confused();
}
confused()
{
printf(Confused);
}

/*Including standard input output header file */


/* User defined function
*/
/* Creating main function
*/
/* Starting point of main function
*/
/* Calling the user defined function
*/
/* End of main function
*/
/* Creating the user defined function
*/
/* Starting point of the user defined function */
/* Standard printf statement
*/
/* End of the user defined function
*/

The output of this program reflects the state of your mind.


Run it. But do not waste your valuable time with this useless program. Later on, we
will explain the analytical part of it. Meanwhile, continue reading.
Before we go deep into function, we should understand the meaning of the storage
class of a variable.

Storage Classes
Every C variable has a characteristic called a storage class. The storage class defines
two characteristics of the variable: its lifetime and its visibility (or scope). The
lifetime of a variable is the length of time it retains a particular value. The visibility of a
variable refers to the part of the program where the variable will be recognized.
A variable may be visible in a block, in a function, in a file, or in an entire
program.
There are basically five storage classes in C. These are,

MSc. In Software

automatic
global
external
static
register
Here, we will discuss automatic, global and extern type of variables. At the end of
this chapter we will also explain static and register type of variable.

auto
Keywords in bold indicate their usage as a storage specifier. The storage specifier
precedes the rest of the variable declaration. For example,
auto int i;
Automatic variables are also called local variables. These variables can be referred only
by statements that are inside the code block, which declares it. To be precise, a local
or auto variable is created upon entry into its block and destroyed upon exit. All the
variables you have encountered so far are local variables. They can be declared by
using the specifier auto, though the declaration is not necessary.
Program 3.2
#include<stdio.h>
/* Including standard input output header file
main()
/* Creating main function
{
/* Starting point of main function
int i;
/* Declaring a local variable
i = 10;
/* Initialising the same
printf( value of i is %d.\n,i);/* Standard printf statement
}
/* End of the program

*/
*/
*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 3.2
Value of i is 10.
Here i is declared as an automatic local variable. Its value will be lost when the
program is over. To be more specific, the existence of i will not be recognized outside
the program.

MSc. In Software

Global
If you declare a variable just outside your main program, it is called a global variable.
A global variable is accessible from any part of your program. The important point is
that the global variables are automatically initialized to zero.
Program 3.3
#include<stdio.h>
/* Including standard input output header file
int i;
/* Declared a variable globally.
main( )
/* Creating main function
{
/* Starting point of the function.
printf(i = %d\n,i);/* This line will show the value of global variable.
}
/* End of the program

*/
*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 3.3
i=0

Extern
In C, a large program is split into smaller modules, which are compiled separately and
then linked together. This speeds up compilation and helps manage large projects.
When you link the modules, you have to inform all the files of the global variables
required by the program. A global variable is declared only once. If you declare two
global variables with the same name inside the same file, you will receive an error
message like 'duplicate variable name'. Or, the C compiler will simply choose one
variable. The same problem occurs if all global variables required by the program are
included in every file. Although the compiler does not issue any error message during
the compile time, the fact remains that two or more copies of the same variable are
being made. When you link the files, the linker displays an error message such as
duplicate label because it does not know which variable to use.
extern is used when you declare all global variables in one file and use the same
variables as extern in all other files.
Program 3.3a
#include<stdio.h>
int i;
main()
{
i = 10;
}
Program 3.3b

/*
/*
/*
/*
/*
/*

Including standard input output header file


Declaring a global variable
Creating the main function
Starting point of the main function
Initialising the global variable
End of the program

*/
*/
*/
*/
*/
*/

MSc. In Software

#include<stdio.h>
extern i;
main()
{
i = i +1;
printf(i = %d\n,i);
}

/*
/*
/*
/*
/*
/*
/*

Including standard input output header file


Declaring an extern type variable
Creating the main function
Starting point of the main function
Incrementing the extern variable
Displaying the extern variable
End of the program

*/
*/
*/
*/
*/
*/
*/

Run the program to get the output.


Output of program 3.3
i = 11
Program 3.3b has the same global variable as program 3.3a, except for the fact that
this variable has the extern specifier added to its declaration. You can observe that
when the linker links the two modules, all references to the external variable are
solved.
There are two more storage classes, static and register. To understand these two
storage classes you need to know function thoroughly. So, we will discuss this later at
the end of this chapter.

Functions
You are already familiar with some of the standard C functions like printf(), scanf()
etc. In this chapter, our discussion will focus on user defined functions, i.e. a function
written by a user.
Program 3.4
#include<stdio.h>
/* Including standard input output header file
abc();
/* User defined function
main()
/* Creating main function
{
/* Starting point of main function
abc();
/* Calling the user defined function
}
/* End of main function
abc()
/* Creating the user defined function
{
/* Starting point of the user defined function
printf(In function abc()\n); /* Standard printf statement
}
/* End of the user defined function

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

This program is the same as program 3.1 as long as explanations are concerned. Here,
abc() is your user defined function. This program is not a part of the C language but is
a function that you have created. This program starts with main(). While going
through main function, when it meets the abc(), the program jumps to it (where it

MSc. In Software

has got created), executes it and then returns to the ; of the user defined function (in
the main block).
Before we examine functions in detail, we will briefly deal with the concept of stacks.
This will help you to understand the calling of functions better.
Output of program 3.4
In function abc()

Stacks
In this section, we will introduce a five-letter word that will soon become a part of your
life. Is it a word or is it a concept? It's both! Its the stack. So what's so special about
the stack and what is it made of? Stack has two components:
i)
ii)

the stack
the stack pointer.

Stack is an area of memory which everybody knows about and can use. The stack
pointer tells us the position of the stack. There is a list of things that the stack does.
For now, we will look at only one aspect of the stack and that is,
Passing of Parameters between functions
The stack acts as a facilitator in the exchange of parameters between functions. When
one function calls another function, parameters have to be passed between the two.
Shack is not a complex concept. In fact, you will be amazed by its sheer simplicity!
Program 3.5
#include<stdio.h>
/* Including standard input output header file
abc(short,short) ;
/* Prototype of an user defined function
main()
/* Creating main function
{
/* Starting point of main function
short i,j;
/* Declaring two local variable
i=300;
/* Initialisation of first variable
j=515;
/* Initialisation of second variable
abc(i,j);
/* Calling function abc with two parameters.
}
/* End of main function
abc (short x,short y) /* Creating the user defined function
{
/* Starting point of the user defined function
printf("%d..%d\n", x,y);
/* Standard printf statement showing the values
of x and y.
}
/* End of the user defined function

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

Understand this program carefully. This forms the basis of our chapter.
Let us try to understand the program from the 5th line.
short i,j;
Somewhere in the memory, we reserve 2 memory locations for i and 2 memory
locations for j. Let us assume that i is allocated 2 memory locations starting from
900 and j is allocated 2 memory locations starting from 950 ( As in Fig 3.1).

Now, we have
i = 300;
j = 515;
These statements are assignment statements where i and j are assigned values. C
divides 300 by 256, puts the remainder (44) in 900 and the quotient (1) in 901.
Similarly, 515 is divided by 256, the remainder (3) is put in location 950 and the
quotient is put into location 951 (As shown in Fig 3.2).

abc ( i,j );
This is a call to function abc(). We know this because of the semicolon (;) at the end
of the line. This function is called with 2 parameters i and j. However, C does not
accept variables and hence replaces the variables i and j with their respective
values. To find the value of i, C detects its location in the memory. It finds the value
to be 900. C runs to location 900 and picks the value of i. Similarly, it picks up the
value of j from 950.

MSc. In Software

In calling functions, parameters have to be placed on the stack. We will assume that
the stack points to location 104.(Refer Fig 3.3). When variables are pushed on the
stack, the stack pointer moves backwards. Thus, main() places j on the stack first.
What locations will j occupy on the stack? Since j is a short, it has size 2 and is
therefore put into locations 103 and 102(Fig 3.4).

Now the stack pointer points to 102. Then i is pushed on the stack by main() at
locations 101 and 100. The end result is that the stack pointer points to location
100(Fig 3.5).

MSc. In Software

Now, main() beats a graceful retreat and abc() enters the screen. abc() does not
know what has been happening in the program. Thus, the first question abc() asks is
the position of the stack pointer. 100 is the answer. Now, abc() knows that within its
( and ) there are parameters x and y of type short. For x, it gets its value from
location 100 and 101 and is satisfied by its two bytes (size of short is 2). It is now
time to assign a value to y. y is also of type short. Thus y gets its value from
location 102 and 103 (As in Fig 3.6).

Note that the stack pointer still points to 100. That has not changed.
Now, that abc() has done its job, main() returns. When the '}' of main() is
encountered main() knows that it is time to restore the stack pointer to its original
place. Thus the stack pointer moves up by 4 and points to location 104. (4 locations
since we pushed 2 variables i, j of type short, in main() ). This explains that if we
create 3 variables in main() we will move up by 6 at the '}' of main() .
Run the program.

MSc. In Software

10

Output of program 3.5


300.. 515

Passing char type variables and calling by short type variable


Program 3.6
#include<stdio.h>
/* Including standard input output header file
*/
abc(short,short);
/* Prototype of the user defined function
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
char i,j;
/* Declaring character type variable
*/
i=1;
/* Assigning value to variable i.
*/
j=2;
/* Assigning value to variable j
*/
abc (i,j);
/* Calling user defined function abc, with two parameters*/
}
/* End of main function.
*/
abc(short x,short y)
/* Creating user defined function abc with two passing parameters.
*/
{
/* Starting point of function abc
*/
printf ("%d.. %d", x, y);/* Printing the values of two passing parameters*/
}
/* End of abc function
*/
This is very similar to the above program except for the statements,
char i, j;
i=1;
j=2;
When we described the size of a char as 1 byte, we meant 4 bit operating systems. In
16 bit operating systems (like Borland C), the minimum that a stack pointer can move
is 2 bytes (16 bits). Thus, the size of a char becomes 2 bytes (16 bits). But only 1
byte (8 bits) is used.
abc() is called with the two parameters i and j. Assuming that the stack pointer is
at 104, the variable i and j (which are stored in some memory locations) are put on
the stack, in reverse order, j first and then i. Since the stack pointer can move
only by 2, j (which is a char) is put into locations 103, 102 and i (which is also a
char) is put into locations 101, 100. Thus in Fig 3.7,

MSc. In Software

11

When abc() enters, it has no idea of what is going on. So, it asks for the stack
pointer. It receives a response as 100. Now, abc() has 2 parameters x and y of
type short. x gets the value that is stored in locations 100 and 101, y gets the
value stored in locations 102, 103. Note again, that the stack pointer hasn't moved.
It is still at 100. We should also understand that when the '}' of abc() is encountered
the stack pointer is unmoved. It is only when the semicolon (;) in the statement:
abc (i,j);
is encountered, main() restores the stack pointer from where we started i.e. 104.
Run this program.
Output of program 3.6
1..2

Passing short type variable and calling char type variable


Program 3.7
#include<stdio.h>
abc( char,char);
main()
{
short i,j;
i=300;
j=515;
abc(i,j);
}
abc(char x, char y)
{
printf("%d., %d", x,

/* Including standard input output header file


*/
/* Function prototype of a user defined function.
*/
/* Creating main function
*/
/* Starting point of main function
*/
/* Declaring two variables
*/
/* Assigning value to the variable i.
*/
/* Assigning value to the variable j
*/
/*Calling the abc() with two parameters
*/
/* End of main function
*/
/*Creating user defined function abc with two parameters*/
/* Starting point of abc function
*/
y);

MSc. In Software

12

/* Standard printf statement to display the values of passing parameters. */


/* End of user defined function
*/

This program is similar to the above program except for this statement:
short i,j;
In abc() When abc(i,j) is called the stack looks like this(Fig 3.8):

Now, within abc() there are 2 parameters x and y of type char. Now, we face a
dilemma. We have told you that the minimum a stack can move in a 16 OS is 2 bytes
(16 bits). But we also know that a char uses only 1 byte (8 bit). Therefore, when
abc() enters and looks at the stack, it finds numbers in locations 100, 101, 102,
103. But, the x, which is char understands that it can accommodate only 1 byte.
Hence, it will look only at the first byte, i.e. looks at memory location 100. The next
byte (location 101) is ignored by x. Now, it is the turn of y to be assigned a value.
y, which is also a char, gets the value present in location 102, and ignores the next
memory location.

MSc. In Software

13

Run this program. Refer Fig 3.9.


Output of program 3.7
44..3
Here, you must understand a very important point that you can get values from stack
even if the type of parameters in calling function and those in called functions are not
the same. But if there is a mismatch in the number of parameters, you will get
errors.

Restoring of Stack pointer


Program 3.8
#include<stdio.h>
/* Including standard input output header file*/
abc();
/* User defined function prototype
*/
pqr();
/* User defined function prototype
*/
xyz();
/* User defined function prototype
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
abc();
/* Calling user defined function abc
*/
pqr();
/* Calling user defined function pqr
*/
xyz();
/* Calling user defined function xyz
*/
abc();
/* Calling user defined function abc
*/
}
/* End of main function.
*/
abc()
/* Creating user defined function abc.
*/
{
/* Starting point of abc function
*/
int i,j;
/* Declaring two local variables
*/
printf ("%p..%p\n",&i,&j); /* Displaying the addresses of these local variables*/
}
/* End of abc function
*/
pqr()
/* Creating user defined function pqr
*/
{
/* Starting point of pqr function
*/
int p,q;
/* Declaring two local variables
*/
printf("%p..%p\n",&p,&q);/* Displaying the addresses of these local variables*/
}
/* End of pqr function
*/
xyz()
/* Creating user defined function xyz
*/
{
/* Starting point of xyz function
*/
int i,j;
/* Declaring two local variables
*/
printf("%p..%p\n",&i,&j); /* Displaying the addresses of these local variables*/
}
/* End of xyz function
*/
In this program, we concentrate on one aspect of stack operations: the way the stack
pointer is restored at the end of a function call. Here main() first calls function abc()
with no parameters. We assume that the stack pointer points to location 100. To
assign values to variable within functions, the stack looks forward. Thus, i is
assigned the value present in location 100, 101 (since i is of type short). Since j is

MSc. In Software

14

also a short, it is assigned values present in locations 102, 103. Does the stack
pointer move? No! It is still at 100.
Now, abc() exits and main() returns to the picture. The next call is to function pqr().
Within pqr() we have 2 variables. pqr() inquires about the position of the stack
pointer. It discovers the value as 100 and as before, assigns values present at
locations 100, 101 to p and values present at 102, 103 to q. The stack pointer
remains at 100.
Next, xyz() enters, finds the stack pointer at 100, picks values stored at 100, 101,
assigns it to i, picks values at 102, 103 and assigns it to j. The stack pointer
remains at 100.
Thus, the important thing here is that all functions find the stack pointer at the same
address. Hence, all parameters are stored at the same location on the stack. The
previous values are overwritten by recent values.
Thus, all the 3 printf's produce the same address.
Run the program.
Output of program 3.8
0063FDF8
0063FDF8
0063FDF8
0063FDF8

..0063FDF4
..0063FDF4
..0063FDF4
..0063FDF4

In your case, you will get different memory locations.

Variables are known by their memory locations and not by their name
Program 3.9
#include<stdio.h>
/* Including standard input output header file*/
abc();
/* Function prototype
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
int i;
/* Declaring an integer type of variable
*/
printf("%p\n",&i);
/* This statement will display the memory location where variable i locates. */
abc() ;
/* Calling the use defined function abc
*/
}
/* End of main function
*/
abc()
/* Creating user defined function abc
*/
{
/* Starting point of abc function
*/
int i;
/* Declaring a local variable called i.
*/
printf("%p\n",&i);
/* This statement will display the memory location where local variable i locates.*/

MSc. In Software
}

/* End of abc function

15
*/

In main() we have a variable i which is of type int. Thus, somewhere in the


memory, we have 4 memory locations that are named i. Let us assume it to be at
location 200,201,202 and 203. In the next statement which is a printf, we display
this location of i. Within abc() we have created a variable i of type int. Assuming
the stack pointer to be at 104, i reserves 4 memory locations on the stack at
locations 105,106,107 and 108. In the next print, we will display this address of i.
If, you see the output of this program, you will find that the address of the variable i
is different. Therefore, we can conclude that variables are not known by their names,
but by their memory locations. Thus, even though we have given the same name to
the variable (i), they are regarded as different variables by C because their memory
locations differ.
Run this program.
Typical output of program 3.9
0063FE00
0063FDF4
In your case the output will be different, because i will be stored in different
locations.

Calling functions by name and by references


In C programs, functions that have parameters are invoked in one of the following
ways:
1. Call by value
2. Call by reference.
Consider the following program.
Call by Value
Program 3.10
#include<stdio.h>
/* Standard input output header file
abc(int);
/* Prototype of user defined function
main()
/* Creating main function
{
/* Starting point of user defined function
int num ;
/* Declaring a local variable called num
printf("Enter a value for num:"); /* Standard printf statement
scanf("%d",&num);
/* User input for variable num
printf(Value of num :%d\n,num);/* Printing the value of num
abc(num);
/* Calling user defined function abc
}
/* End of main function

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

16

abc(val)
/* Creating abc function
*/
{
/* Starting point of abc function
*/
printf("Value of val :%d\n",val);/* Printing the value of passing parameter*/
}
/* End of the function
*/

Run this program.


Output of program 3.10
Enter a value for num : 100
Value of num : 100
Value of val : 100
In this program, value entered for the variable num in the main() is passed to the
function abc().This value gets copied into the memory location of the parameter val
when it is invoked. Thus, the variable in the caller function (main()) is distinct from
the variable in called function(abc()).
If we change the value of val in abc(), that will not get reflected in main().
Why do we not verify the above statement?
Program 3.11
#include<stdio.h>
/* Standard input output header file */
abc(int);
/* Function prototype
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
int num ;
/* Declaration of a local variable
*/
printf("Enter a value for num:"); /* Standard printf statement
*/
scanf("%d",&num);
/* User input for variable num */
printf(Value of num before function call : %d\n,num);
/* Standard printf statement showing the value of num. */
abc(num);
/* Calling the user defined function abc.*/
printf(Value of num (in main()) after function call:%d\n);
/* This statement prints the value of num after
control comes back from abc function*/
}
/* End of main function
*/
abc(val)
/* Creating user defined function abc */
{
/* Starting point of abc function
*/
printf("Value of num :%d\n",val);
/*This prints the value of passing parameter. */
val++;
/*Incrementing the value of passing parameter
*/
printf(Value of val: %d\n,val);
/* Printing the value of passing parameter after incrementing its value*/

MSc. In Software
}

/* End of this function

17
*/

Output of program 3.11


Enter a value for num: 100
Value of num before function call : 100
Value of num : 100
Value of val: 101
Value of num (in main()) after function call: 100
This program is almost similar to the above program. The only difference is that we
have incremented the value of passing parameter by 1 in abc function. So, at the line
Value of val: __, you will get a value one more than what you have entered through
scanf(). After this line, the control goes back to the main function. At this point the
control meets another printf statement. This time it prints the value of num, which is
the original value entered by you.
The moral of the story is that, the value of val is not reflected to num. We can do that
also. For that, continue reading.

Call by reference
Call by reference means that the called function should be able to refer to the variable
of the caller function directly, and not create its own copy of the values in different
variables. This would be possible only if the address of the variables is passed as
parameters to the function.
Program 3.12
#include<stdio.h>
/* Standard input output header file
*/
abc(int*);
/* Prototype of an user defined function */
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
int num ;
/* Declaration of local auto variable
*/
printf("Enter a value for num:"); /* standard printf statement
*/
scanf("%d", &num);
/* Standard input function
*/
abc(&num);
/* Calling of user defined function
*/
printf("Value of num: in main %d \n",num);/* Standard printf statement*/
}
/* End of main function
*/
abc(int *val)
/* Creating the user defined function
*/
{
/* Starting of user defined function
*/
printf("Value of num : in abc %d\n",*val);
/* Printing a pointer type variable, more about pointers in the next chapter
*/
val= val+1;
/* Pointer arithmetic. This means *val = *val +1
*/
printf("Value of val: %d\n",*val);/* Printing a pointer type variable
*/
}
/* End of user defined function
*/

MSc. In Software

18

The addition here is a *, in front of a variable. This type of declaration is called


pointer declaration. You will learn the details of pointer declaration and pointer
arithmetic in the chapter on pointers. Here we have used the same increment
operator. Notice that if we change the value of the variable in the called function, the
change gets reflected in the caller function.
Here in abc() we have changed the value of the passing parameter. After completion
of abc(), when the control returns to main(), i.e. at ; of abc(&num), it will carry
the new value of val. In the next printf statement that new value will get printed as
num.
Run this program.
Output of program 3.12
Enter a value for num : 44
Value of num : in abc 44
Value of val : 45
Value of num in main 45

Recursion
In C, it is possible for the functions to call themselves. A function is called recursive
if a statement within the body of a function calls the same function. Sometime called
circular definition, recursion is thus the process of defining something in terms of
itself.
This is an example of recursion. Try to understand it on your own. Let us repeat that C
functions may be used recursively; that is, a function may call itself either directly or
indirectly.
Program 3.13
#include<stdio.h>
/* Standard input output header file
print(int);
/* Prototype of an user defined function
main()
/* First function of C program
{
/* Starting of main function
int a = 321 ;
/* Initialisation and declaration of a variable
print(a);
/* Calling the user defined function
}
/* End of main
print(int a)
/* Creating user defined function
{
/* Starting of user defined function
if(a /10)
/* A condition
{
/* Starting of conditional block
putchar(a % 10 +'0');
/* Since we are putting an int value in putchar(), a null termination is required.
print(a / 10);/* Calling the same function(recursion) with another parameter.
}
/* End of if block

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software
else
putchar(a +'0');
}

19

/* else part of if

*/

/* Since we are putting an int value in putchar


function, a null termination is required.
/* End of user defined function

*/
*/

Run this program.


Output of program 3.13
123
Consider the above example. For any number, this program will print the number in
the reverse order. When this user defined function calls itself recursively, each
invocation gets a fresh set of the automatic variables, independent of the previous set.
Thus in print (a) where a = 321, the first print receives the number 321, it prints 1 and
passes 32 to a second print(), which in turn prints 2 and passes 3 to the third function.
At last 3 gets printed by the else part of the program. Thus we get the full number
printed backwards.

Parameters of main ()
All sane people of the world are unanimous in deploring arguments. But the computer
begs to differ. The computer looks at arguments as a necessary tool of interaction with
the program. A program without arguments is unacceptable. If you wonder what these
arguments are all about, read on
Program 3.14
#include<stdio.h>
main( argc)
int argc;
{
printf (%d\n,argc);
}

/* Including standard input output header file


/* Creating main function with one parameter
/* Defining that parameter
/* Starting point of main function
/* Printing the value of an int type variable
/* End of the program

*/
*/
*/
*/
*/
*/

Output of program 3.14


1
Now, we dare you to look at the next program and answer a question,
Program 3.15
#include<stdio.h>
main(z)

/* Including standard input output header file */


/* Creating main function with one parameter */

MSc. In Software
int z;
{
printf(%d\n,z);
}

/*
/*
/*
/*

Defining that parameter


Starting point of main function
Printing the value of an int type variable
End of the program

20
*/
*/
*/
*/

Are program 3.14 and program 3.15 identical? Or, to be more specific do the two
programs produce the same output?
This is how you should think. If we can establish that argc and z are identical, then
we can confidently say that the programs are identical. We can observe that int is
situated before argc as well as z. Therefore, aren't they variables of type int??
Yes!! As simple as that!!
Thus, both programs give us the same output. Then why do we use a cryptic variable
like argc? Why not use a simple x or y?
We claim no responsibility for this. All textbooks of the world use this variable name
and we are not the ones to rebel against the system. Remember, variables can be
called by any name.
Output of program 3.15
1
Now, consider that you want to pass two or more variables in main (). Take a short
break. We will come to this point later.
Read this program.
Program 3.16
#include<stdio.h>
main( argc,argv[])
int argc;
char *argv[];
{
printf( %s\n,argv[0]);
printf( %s\n,argv[1]);
}

/* Including standard input output header file */


/* Creating main function with two parameters*/
/* Defining one of those parameters
*/
/* Defining one of those parameters
*/
/* Starting point of main function
*/
/* Standard printf statement
*/
/* Standard printf statement
*/
/* End of the program
*/

Read this new program carefully.


Save this program as aaa.c
And run it as aaa ab pqr xyz
And press enter.
Now your OS (operating system) knows that you have typed 4 words.

MSc. In Software

21

The first thing that OS does is that it recognizes the words as strings. What does that
mean?
It just means that OS allocates memory locations for each of the words. Thus, this is a
probable snapshot of memory.

Thus, aaa is stored at location 200, and abc at location 210. Address of pqr is
220, and that of xyz is 230. These locations are randomly chosen. Since OS regards
them as strings, it puts a 0 to indicate the end of the string.
The next crucial question is: How are we supposed to read these memory locations?
OS takes a giant step forward by storing all the memory locations (200, 210, 220,
230) at memory location 300 (refer Fig 3.11). Observe the move made by OS. Do
you feel that in doing so OS has created an array of pointers to chars? (At this stage
you do not know arrays or pointers. So, just keep on reading. In the next chapter we
will discuss that in detail). After all, the 4 words are strings that will be read one
character at a time. Is array the right word to use? Yes, because an array is a
collection of similar multiple entities and in this case, all these multiple memory
locations have the same data type (char). In fact, 300 can also be regarded as a
pointer since it tells us the location in memory where the array begins.

MSc. In Software

22

Right now, OS knows two things.


One, is that, there were 4 words typed at the command prompt and
Two, it knows that the address of this array is in memory (300). OS now stores this
information on the stack. Assuming the stack is at 106, OS first puts 300 (address of
the array) on the stack and then 4 (the number of words) at the command prompt.
Thus in Fig 3.12,

We have 4 locations for the address of the array, since it is a pointer. The stack
pointer is now at 102. With this groundwork, we can try the next program.
Program 3.17
#include<stdio.h>
main( argc,argv)
int argc;
char *argv[];
{
printf( %s\n,argv[0]);
printf( %s\n,argv[1]);
}

/* Standard input output header file


/* Creating main function with parameters
/* Type of the first argument
/* Type of the second argument
/* Starting point of main function
/* Printing the first argument
/* Printing the second argument
/* End of the program

*/
*/
*/
*/
*/
*/
*/
*/

main (argc,argv) is a function. When main() enters, it will inquire about the location
of the stack pointer. It is at 102. C has to be told about the data type of the
parameters in the main(). The next two statements say,
int argc;
char *argv[];
main allocates locations 100 and 101 to argc and 102,103,104,105 to argv. Thus
argc represents 4 and argv represents 300. Thus in Fig 3.13 we have,

MSc. In Software

23

Let us look at the evolution of this interesting statement


char * argv[];
We will now deal with this statement in detail.
argv, contains 300, which is the starting address of an array in the memory. Thus we
have the [ ] in the above statement. (This [ & ] represents array. More about array
in the next chapter.)
Next, who created this array? None of us. OS did the creation. Therefore we put
nothing in the [ ].() Generally the size of the array comes into these braces).
Lastly, what does the array contain? Pointers to chars. Hence the char *.
(We will request you to read this part of the chapter after doing arrays and pointers. It
will be absolutely easy at that time)
When you call an array a with 4 parameters, a[0], a[1], a[2], a[3] are the
members. We have now called the array argv, starting at 300. Thus, we would be
doing no wrong, if

MSc. In Software

24

What is argv[0]? It is the physical value 200. So, when we say,


printf( %s\n,argv[0]);
wont we see the name of the program i.e. aaa? Refer Fig 3.14.
Similarly,
printf( %s\n,argv[1]);
gives ab.
Now, try to assign some meaning to argc and argv. We can state that argc is for
argument count i.e. the number of command-line arguments and the second, the
argument vector is a pointer to an array of character strings that contain the
arguments.
Output of program 3.17
aaa
ab

Displaying - Command Line Arguments


Study this program, to learn how command line arguments are displayed
Program 3.18
#include<stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
int i;

/* Standard input output header file


/* Creating main function with parameters
/* Type of the first parameter
/* Type of the second parameter
/* Starting point of main function
/* Declaring a variable

*/
*/
*/
*/
*/
*/

MSc. In Software
for(i =1; i<argc;i++)
}

printf(%s\n,argv[i]);

25

/* for loop to display all the command line


parameter
*/
/* Standard printf statement
*/
/* End of the program
*/

The thing of interest here is the 'for loop' which says,


for(i =1; i<argc;i++)
printf(%s\n,argv[i]);
In our example, argc is 4. Thus, the 'for loop' functions 4 times and each of the
command line arguments is printed out. This program can thus be used to print all the
command line arguments irrespective of how many they are.
You remember, long back we had promised you that we would discuss static and
register storage classes at the end of the chapter. Time has come for that.

Static
Static variables are permanent variables within their own functions or file. Unlike
global variables, they are not known outside their function or file. However, they
maintain their values between calls. Therefore, if you terminate a function and then reenter it, the static variables defined within that function will retain their former values.
You can observe that the variable declaration begins with the static storage class
designation.
You can define static variables that have the same name as leading external variables.
The local variables (static as well as auto) take precedence over the external
variables and the values of the external variables remain unaffected by any
manipulation of the local variables. You cannot access external variables of the same
name as local variables directly in a function.
You can assign initial values to variables within static variable declarations but these
values must be expressed as constants and not as expressions.
Like global variables, the compiler automatically assigns the default value of zero
to any static variable that is not initialized. The values of static variables are not reinitialized when a function is re-entered. The variables retain their previous values.
Initialization takes place only at the beginning of the program.
Consider the following programs. The difference between auto and static local
variables will be quite apparent.
Program 3.19
#include <stdio.h>
void incre();
main()

/* Standard input output header file


/* Prototype of the function
/* main function

*/
*/
*/

MSc. In Software
{
/* Starting point of main function
*/
incre();
/* Calling function incre()
*/
incre();
/* Calling function incre()
*/
incre();
/* Calling function incre()
*/
}
/* End of the main function
*/
void incre()
/* Creating the function
*/
{
/* Beginning of the function
*/
char var = 65 ;/* Declaration and initialization of a local character type variable.*/
printf("\nThe character stored in var is %c", var) ;
/* The value of variable var will get displayed
*/
var++;
/* Incrementing the value of variable by 1
*/
}
/* This indicates the end of the function
*/
Run the program to get the output.
Output of program 3.19
The character stored in var is A
The character stored in var is A
The character stored in var is A
Now, if we declare the local variable var as static, see what happens.
Program 3.20
#include <stdio.h>
/* Including standard input output header file*/
void incre();
/* Prototype of the function
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
incre() ;
/* Calling function incre()
*/
incre();
/* Calling function incre()
*/
incre();
/* Calling function incre()
*/
}
/* End of main function
*/
void incre()
/* Creating the function
*/
{
/* Beginning of the function
*/
static char var = 65 ;
/* var is an automatic static variable
*/
printf(\nThe character stored in var is %c, var ) ;
/*The value of variable var will get displayed */
var++;
/* Incrementing the value of variable by 1
*/
}
/*This indicates the end of the function
*/
Output of program 3.20
The character stored in var is A
The character stored in var is B
The character stored in var is C
Each program calls the function incre() thrice.

26

MSc. In Software

27

In the first program, each time you call incre() the variable var will have a storage
class auto (default storage class) re-installed to 65 (which is ASCII character A).
Thus, when you terminate the function, the new value of var (66) is lost (ASCII
character B).
In the second program, var is of static storage class. Here, var is initialized to 65
only once when the program is compiled. At the end of the first function call, var has
a value of 66 (ASCII B) and similarly in the next function call, var has a value of 67
(ASCII C).
At the end of the last function call, var is incremented after the printf() action. This
value of var is lost when the program terminates.

Register
Computers have internal registers in their memory that are used to temporarily store
data that has to be accessed repeatedly. Registers enable you to store the
intermediate results of calculations. You can perform operations more quickly on the
data stored in registers than on the data stored in the memory. In assembly
language, a programmer has access to these registers and can transfer frequently
used data into them. This increases the speed of the program.
A high level programmer usually does not have access to the computers registers. In
C, the option of choosing a storage location for a value has been left to the
programmer. If you need to use a particular value often, (for example, the value
that controls a loop), you can name its storage class register. Then if the compiler
finds a free register, and if the machines registers are big enough to hold the variable,
it (the variable) is placed in the register. Otherwise, the compiler treats register
variables as any other automatic variable, i.e., it stores them in the memory. Use the
keyword register to define the register variables.
The scope and initialization of the register variables is the same for the automatic
variables, except for the location of storage. Register variables are local to a function
and are also dynamic. That is, they come into existence when the function is invoked
and they lose the value once the function is exited from. Hence, initialization of these
variables is the responsibility of the programmer. The system does not initialize
these variables.
While using these registers, you have to remember that the number of register
variables is limited. A programmer has to identify the variables that are used more
often in the program and then declare them as register variables.
The effectiveness of a register variable varies from one machine to another and from
one C compiler to another. Sometimes, a register is not supported at all. Though the
keyword register is accepted, it is treated just like keyword auto. In other cases
where the register is supported and where the programmer uses it with care, a
program can be made to run twice as fast.

MSc. In Software

28

The register declaration looks like


register int x ;
register char c ;
and so on: the int part may be omitted.
Program 3.21
#include <stdio.h>
main()
{
register int i ;

/*
/*
/*
/*

Including standard input output header file*/


Creating main function
*/
Starting point of main function
*/
Declaring an int type variable in register
storage class*/
int no , digit , sum ;
/* Declaring three integer type variables
*/
printf(\nThe numbers between 1 & 100 which are divisible by 23);
/* Standard printf statement.
*/
for( i = 1 ; i <= 100 ; i++ ) /* Standard for loop
*/
{
/* Beginning of for loop
*/
if ( i % 23 == 0)
/* if condition with modulo operator
*/
printf(\t%d\n , i ) ;
/* printf statement giving the value of i.
*/
}
/* End of for loop
*/
}
/* End of main function
*/

In this program, all the numbers between 1 and 100 that are divisible by 23 will be
displayed.
Run the program to get the output.
Output of program 3.21
23
46
69
92
Since i is used to control the looping, (the most essential part of the program), it is
declared as part of the storage class register. With this declaration you can increase
the efficiency of the program.

Summary
# Storage Classes
In this topic we have discussed different scope of variables. They are of five types i.e.
automatic

MSc. In Software

29

global
external
static
register
You are already familiar with all these terms. Just for a recap, the variables we
generally use in a program are automatic variables. In case of an automatic variable,
you do not need to say that this is of automatic type.
If we declare a variable outside a program, it is called global variable. Global variables
are always initialized to zero. From any part of your program, these global variables
are access sable.
You wont be able to understand the external variable, unless you do project. So, do
the project.
static variable, as the name suggests are very static in nature. Like global variables
they are automatically initialized to zero. Like automatic variables they are declared
within the program or within a block of a program. But they do not loose their values
after coming out of the program or out of the block of program.
registers are different types of memory location. Access to this type of memory is very
fast.
# Functions
By functions we meant user defined functions. A huge C program can be a collection of
a lot of functions and nothing else. It is something like, dividing a full program into
small parts and calling them functions. Proper information transfer in modes of
parameters passing is necessary for the functions work properly.
# Stacks
Stacks play a big role in passing of parameters between functions. Stack mainly
consists of a memory location and a stack pointer. We have already told you that stack
pointer moves downwards. Just remember this at this stage. When you will study
windows programming, it will be absolutely clear to you.
# Passing of Parameters between functions
In this topic and its subtopics we have discussed how does a caller function place
variables or parameters (it is the same thing, you know by this time) in stacks? It is
also important to know how a called function gets back these variables. With different
types of variables, we have discussed a lot of programs. Remember one important
point that if there is a mismatch in number between the passing of parameters and
calling of parameters, Borland C will give you an error. But if you work on UNIX or on
some other platform, you will only receive some junk characters, no errors.

MSc. In Software

30

# Restoring of Stack pointer


This is a big topic. Whose duty it is to restore the stack pointer. At this stage, if you do
not bother, nothing will happen. While dealing with window programs, you will
understand the meaning of it.
# Variables are known by their memory locations and not by their name
Though in a program, you cannot declare int i,i, in two different functions of the
same program, you can declare the variables of same name. If you are adamant
enough to declare two variables of same type and of same name in a program, no
double, these two variables will fit themselves in two different memory locations. But
later on it will be difficult for the program to understand which variable you are
referring to.
# Calling functions by name and references
You can access a variable by its name or by its memory location. So, when the
question of passing variables between the functions comes, it can also be done in two
ways. That is it. There is certainly some advantages and disadvantages associated with
these two ways. For details refer the example stated above.
# Recursion
This is a great feature of C. When a function calls itself within itself it is called
recursion. A very common recursive program is to calculate factorial of a number. A
part of the syntax is given below.
recur(n)
{
facto = 1;
if(n >= 1)
facto = facto * n;
recur(n 1);
}
This is a part of a program. Suppose the value of n is 10. So, after passing through if
condition, the control comes to the product and facto becomes 1*10 i.e. 10. Then the
function recur gets called again with the parameter 9. After the same thing facto will
become 10*9 i.e. 90. Next time it will become 90 * 8 and so on until n becomes 1. So
ultimately you are getting 10*9*8*7*6*5*4*3*2*1. This is essentially called factorial
of 10.
By using recursion we can compress our code. Using any loop with proper condition
could solve the same problem.
# Parameters of main ()

MSc. In Software

31

Since we are discussing so much about parameter passing between the functions, we
feel it is the best time to discuss the parameters of main function also.
Suppose you want to copy a.doc file to b.doc file. In a DOS prompt you generally
type, copy a.doc b.doc. Right? Try to understand what actually happens within the
computer. A program runs. We can assume without much difficulty that this very
program has got a main function. Imagine, copy as the name of the program, a.doc
as the 1st argument of main function and b.doc as the 2nd argument of the main
function. Yes!! Thats it. That is the meaning of arguments of main function. Now, read
again the programs associated with this as discussed above.
Zee Interactive Learning System

MSc. In Software

4
Arrays
Main Points Covered

Introduction
! Character type array
! String terminator
! Other types of array
! Index
! One Dimensional Array
! Array Initialisation
! Two Dimensional Integer Array
! Two Dimensional Character Array
! Arrays are not really useful
! malloc()
! Some useful string-handling functions
strcpy()
strcat()
strlen()
strcmp()
atoi()
atof()
! Function for formatting data in the memory
! sprintf()
! sscanf()
Summary
!

MSc. In Software

Introduction

ou are already masters of variables. Just for a recap we are saying again that a variable
stores a particular type of data in a memory place. But if you want more than one (of a
particular type) data to be stored in a contiguous area, array comes to serve the
purpose.
An array is a collection of data elements of the same type that are referenced by a common
name. Each element is stored in successive locations of the main store. These elements are
known as members of the array.

Character Type Array


A typical array declaration is like this.
Program 4.1
#include<stdio.h>
main()
{
char array1[11];
}

/*
/*
/*
/*
/*

Standard input output header file


main function of the program
Starting of main function
Declaration of a character type array
End of main function

*/
*/
*/
*/
*/

In the above program the name of the array is array1. It is of char type and it stores 11
elements. In more clear language array1 is a name of a variable, which stores 11 character
type elements.

String terminator
Caution The above statement is a wrong statement. One point you have to remember
always is that in case of a character type of array the last element is always reserved for a
string terminator character.
In our above case array1 will store 10 valid characters and they will be represented as
array1[0], array1[1], array1[2].array1[9]. array[10] will be used for storing string
terminator character,\0(NULL).
In case of a string input by using any of the string-based functions, namely scanf() and
gets(), the NULL (\0) character is automatically appended to the string in the memory as
the string terminator.
Run the above program.
You will not get any output, because in this program we have only declared an array and
nothing else.

MSc. In Software

Other types of array


In a similar fashion we can declare arrays of other data types.
Program 4.2
#include<stdio.h>
main()
{
int array2[11];
}

/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaration of an integer type array
End of main function

*/
*/
*/
*/
*/

Here the name of the array is array2. It holds 11 integer type data. The data will be denoted
as array2[0],array2[1]array2[10]. In this case there is no concept of null terminator. If you
want to store float type or long type data in a similar way, you need to declare a float type or
long type array.

Index
The non-zero, non-negative integer which we are enclosing in [] is known as index. It is
placed immediately after the array name, without being separated by a space. The value of
index represents the total number of elements in the array. Index always holds integer value
starting at zero.

One Dimensional Array


All the above examples are of one dimensional arrays. By definition, the dimension of an
array is determined by the number of indices needed to uniquely identify each element. It
will be clearer when we will deal with multidimensional arrays.

Array Initialisation
It is already very clear that arrays are for storing more than one data. So it is not possible to
initialize an array the way we initialize variables. All the data members of the array should be
individually initialized. Generally, for loop is used to initialize data members of an array.
Program 4.3
#include<stdio.h>
main()
{
int i;
int array3[4];
for(i = 0; i <= 3 ; i++)
{

/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
incrementing variable
Name of the array is array3
Loop for initialization of array members
Starting point of for loop

*/
*/
*/
*/
*/
*/
*/

MSc. In Software
array3[i] = 0;
}
}

/* ith element of the array is initialized to zero*/


/* End of for loop
*/
/* End of the main function
*/

As a footnote, we would like to remind you that any loop (while, dowhile) could do the
same thing.
Run the program.
Here you will not get any output, since we are not asking for any output. For output, wait till
you reach the next program.
Try to understand the program line by line.
In this program we have declared an integer type of array called array3[4]. This array will
contain 4 integer type of elements. Study the for loop. You already know how a for loop
works. First the value of i is 0. So the first element of the array i.e. array3[0] is initialized
to 0. Then the value of i gets incremented to 1 and the second member of the array i.e.
array3[1] has initialized to 0. In the same fashion the loop will get executed for two more
times and thus initializing the last two data members of the array to 0.
Make the above lines absolutely clear, in the near future we will be dealing with a lot of array
initialization.
Program 4.4
#include<stdio.h>
/* Standard input output header file
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
int i;
/* incrementing variable
*/
int array3[4];
/* Name of the array is array3
*/
for(i = 0; i <= 3 ; i++)
/*Loop for initialization of array members
*/
{
/* Starting of for loop
*/
array3[i] = 0;
/* Initialisation statement for array members */
}
/* End of for loop
*/
for(i = 0; i<= 3; i++)
/* Loop for displaying array members
*/
{
/* Starting of for loop
*/
printf(Array member, %d initialized to : %d\n, i, array3[i]);
/* Printf statement to show the initialization of array members */
}
/* End of for loop
*/
}
/* End of main function
*/
One more for loop in the same program! Not fair.
No, it is fair. At least at this stage you will get a chance to believe us. This for loop does not
need any explanation. Just run the program and enjoy the output.
Output of program 4.4

MSc. In Software

Array
Array
Array
Array

member,1
member,2
member,3
member,4

initialized
initialized
initialized
initialized

to
to
to
to

:
:
:
:

0
0
0
0

Two Dimensional Array


At this stage, you will be familiar with the concept and usages of one-dimensional arrays.
One-dimensional arrays have a single index. By a similar logic, two-dimensional arrays
have two indices.
Program 4.5
#include<stdio.h>
main()
{
int i, j ;
int array1[4][3];
for(i = 0; i <= 3 ; i++)
{
for(j = 0; j <= 2; j++)
{
array1[i][j] = 0;
}
}
}

/* Standard input output header file


/* Creating main function
/* Starting point of main function
/* incrementing variables
/* Name of the array is array1
/*Loop for initialization of array members
/* Starting point of outer for loop
/* Inner for loop
/* Starting point of inner for loop
/* Initialising the members of 2-D array
/* End of the inner for loop
/* End of the outer for loop
/* End of the program

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

Run this program. But you will not get any output since we are not asking for any output. This
program shows how to initialize a two-dimensional array.
The name of the array is array1. It is an integer type of array. It is a two dimensional
array. If you want to visualize it in tabular form, you can think of it as having 4 rows and 3
columns.

0,0
1,0
2,0
3,0

0,1
1,1
2,1
3,1

0,2
1,2
2,2
3,2

Array1[4][3]

For each value of i, the j value will keep on increasing. More precisely, for i=0, the inner
loop will continue 3 times, one with j=0, second with j=1 and third with j=2. This is called
nesting for loop. Try to understand the flow of control. When the inner for loop is over,
control again comes to outer for loop. Now for i=1, again the inner loop will continue for 3

MSc. In Software

times. One with j = 0, second with j = 1 and third with j = 2. Thus giving us the second row
of the array. The full process will continue for two more times, i.e. for i=2 and i=3. So, all the
array members are now initialized to 0.
array1[0][0] = 0
arrsy1[0][1] = 0
array1[0][2] = 0
when j becomes 2, the control will come out of this loop and again the outer for loop will
come into action. i will now become 1. For this particular i value the inner for loop will
again continue for 3 times. So, ultimately we will get,
array1[1][0] = 0
arrsy1[1][1] = 0
array1[1][2] = 0
With the similar explanation for i = 2 and i = 3 we will have,
array1[2][0] = 0
arrsy1[2][1] = 0
array1[2][2] = 0
array1[3][0] = 0
arrsy1[3][1] = 0
array1[3][2] = 0
It is now our responsibility to give you some output of the above program.
Program 4.6
#include<stdio.h>
/* Standard input output header file
main()
/* Creating main function
{
/* Starting point of main function
int i, j ;
/* incrementing variables
int array1[4][3];
/* Name of the array is array1
for(i = 0; i <= 3 ; i++)
/*Loop for initialization of array members
{
/* Starting point of outer for loop for initialization
for(j = 0; j <= 2; j++)
/* Inner for loop for initialization
{
/* Starting point of inner for loop for initialization
array1[i][j] = 0;
/* Initialisation statement
}
/* End of inner for loop for initialization
}
/* End of outer for loop for initialization
for(i = 0; i <= 3 ; i++)
/*outer for Loop for printing the array members
{
/* Starting point of outer for loop for output
for(j = 0; j <= 2; j++)
/* Inner for loop statement used to get output
{
/* Starting point of inner for loop for output
printf("array1[%d][%d] = %d \n",i,j,array1[i][j]) ;
/* printf statement to give you the output

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software
}
}
}

/* End of inner for loop for output


/* End of outer for loop for output
/* End of main function

*/
*/
*/

In this program we have put one more set of for loops to print all the data members.
In a tabular form a two dimensional array looks like,
array1[0][0]
array1[1][0]
array1[2][0]
array1[3][0]

=
=
=
=

0
0
0
0

array1[0][1]
array1[1][1]
array1[2][1]
array1[3][1]

=
=
=
=

0
0
0
0

array1[0][2]
array1[1][2]
array1[2][2]
array1[3][2]

=
=
=
=

0
0
0
0

All of the data members are initialized to 0.


Output of program 4.6
array1[0][0]
array1[0][1]
array1[0][2]
array1[1][0]
array1[1][1]
array1[1][2]
array1[2][0]
array1[2][1]
array1[2][2]
array1[3][0]
array1[3][1]
array1[3][2]

=
=
=
=
=
=
=
=
=
=
=
=

0
0
0
0
0
0
0
0
0
0
0
0

Two Dimensional Character Array


Till now, you have learnt about two-dimensional integer arrays. Extending the same logic,
its a simple matter to have two-dimensional character arrays.
For example, an array to store names of 10 persons could be declared as
Program 4.7
#include<stdio.h>
main()
{
char name[10][40];
}

/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a two-dimensional array
End of the program

*/
*/
*/
*/
*/

MSc. In Software

Here, name[0][40] to name[9][40] would store strings of 39 characters each. The first
index 10, represents the number of names and 40 represents the maximum size of the names
including null terminator.

Arrays are not really useful


Now let us have a question time Are arrays a boon or a curse? You might not want to use
extreme words but arrays are certainly a problem.
Program 4.8
#include<stdio.h>
main()
{
int i = 5;
char array[i];
}

/* Standard input output header file


/* Creating main function
/* Starting point of main function
/*Declaration and initialization is valid
/* Not a valid statement
/* End of the program

The statement int i = 5 is valid. However the statement char arrq


allowed.

az`1ay[i]

*/
*/
*/
*/
*/
*/
is

not

Why? Because arrays have to be fixed in size.


Another reason why arrays are a problem,
When we say,
Problem 4.9
#include<stdio.h>
main()
{
char array1[5];
}

/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Array declaration
End of the program

*/
*/
*/
*/
*/

Here array1 is a number that tells us where the array1 starts in the memory. We cannot
say: array1++.
Not allowed. You cannot take a name of an array and add ++ in front of it, because the name
of an array1 is what is called as a constant. Its value cannot be changed. These are rules
that are built into an array1 by the compiler.

malloc()
Another problem with array is that arrays are not dynamic. This is a problem because we have
to anticipate the amount of memory required and hence fix the size of the array. When we
begin writing code, it is difficult to predict how much memory will be required.

MSc. In Software

For a solution study the following problem.


Problem 4.10
#include<stdio.h>
#include<malloc.h>/*
main()
{
char *p;
p = malloc(100);
printf(%p\n,p);
p=malloc(10);
printf(%p\n,p);
}

/* Standard input output header file


*/
This is another header file. This contains the definition of malloc()*/
/* Creating main function
*/
/* Starting point of main function
*/
/* A pointer declaration, more about it in the next chapter
*/
/* Usages of malloc function to reserve 100 memory locations */
/* Memory address, where malloc function has reserved memory*/
/* Reserving a new set of memory location
*/
/* Memory address, where malloc function has reserved memory*/
/* End of the program
*/

malloc() is a function. You can give it a number or a variable. Depending on the value passed
to malloc() it reserves those many memory locations. Thus when we say,
p = malloc(100);
malloc() will allocate 100 memory locations and will return the address of the start of those
100 locations. p will display for us, where these locations start in the memory.
Now, when we say,
p= malloc(10);
like before, malloc() allocates 10 fresh memory locations. When we say fresh, we mean that
the memory locations allocated by the past malloc() are not used. Thus, the value returned
by malloc() will be different each time.
So, now do you realize the convenience of malloc()? malloc() is a function, it takes
parameters. These parameters can be variables. So, now we are in a position to decide how
much memory to ask for when the program is running. Hence, ultimately we got dynamism in
array.
Typical output of program 4.10
006522A4
0065230C
In your case memory addresses will be different.
Study the following program carefully.
Problem 4.11

MSc. In Software
#include<stdio.h>
main()
{
char a[1000];
gets(a);
printf(%s\n,a);
}

/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a string
User input function for string
Printing the string, the user has typed
End of the program

10
*/
*/
*/
*/
*/
*/
*/

When you run this program gets() asks for an address of a memory location. a in gets(a)
provides that. Now, gets() waits for you to write something. Until you press enter, you remain
at gets. When you press enter, the memory location (in our case a) will contain whatever
you have typed, which is displayed in the next statement. What if you type more than the
array can hold? Oh! You are then writing into no-mans-memory. What will happen is
unknown.
Output of program 4.11
We are now in fourth chapter
We are now in fourth chapter

Some useful string-handling functions


strcpy()
In English, we call this function as string copy function. This function copies a full string into
another string. Study the following example.
Problem 4.12
#include<stdio.h>
main()
{
char a[10];
printf(%s\n,a);
strcpy(a,ABC);
printf(%s\n,a);
}

/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a char type string
Printing an uninitialised string
Usages of string copy function
Printing the initialized string
End of the program

*/
*/
*/
*/
*/
*/
*/
*/

a is the string address of an array. Like a black hole, what the first printf displays, is a
mystery, because we have not initialized the array yet.
Then we have,
strcpy(a,ABC);
Here, the full string ABC is get copied into the memory location named by a. Thus,
the last printf will display ABC.

MSc. In Software

11

Output of Problem 4.12


[Some junc value]
ABC

strcat()
This is another function provided by C. strcat() appends the second string at the end of the
first string passed to it.
Problem 4.13
#include<stdio.h>
main()
{
char a[10];
printf(%s\n,a);
strcpy(a,ABC);
printf(%s\n,a);
strcat(a,DEF);
printf(%s\n,a);
}

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a string type variable
Printing the content of that variable
Copying a constant into that variable
Printing the content of that variable
Adding something new into the existing string
Printing the content of that variable
End of the program

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

In this program, we have added two more lines. From the above program we know that the
second printf will display ABC. After that we have used strcat(). As per definition the last
printf should display for us ABCDEF.
Run the program to check the output.
Output of Problem 4.13
[ some junc value ]
ABC
ABCDEF

strlen()
This function returns the number of characters in the string passed to it. The length does not
include the NULL character. For example,
Problem 4.14
#include<stdio.h>
main()
{
char a[10];
int b;

/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a string type variable
Declaring an int type variable

*/
*/
*/
*/
*/

MSc. In Software
printf(%s\n,a);
strcpy(a,ABC);
strcpy(a,ABC);
printf(%s\n,a);
strcat(a,DEF);
printf(%s\n,a);
b=strlen(a);
printf(%d\n,b);
}

/*
/*
/*
/*
/*
/*
/*
/*
/*

Printing the content of that variable


Copying a constant into that variable
Copying a constant into that variable
Printing the content of that variable
Adding something new into the existing string
Printing the full content of that variable
b contents the length of the string
Printing the length of the string
End of the program

12
*/
*/
*/
*/
*/
*/
*/
*/
*/

Again, we have added two more lines in the previous program. But, apart from that we have
also declared an int type variable called b.
This b will hold the total number of characters in string b. So, the last printf should print for
us 6, the total number of characters in a.
Run the program to check the output.
Output of Problem 4.14
[ some junc value]
ABC
ABCDEF
6

strcmp()
strcmp() compares two strings character by character (ASCII comparison) and returns any of
the value shown in the figure below.
Return Value
Less than 0

Meaning
If the ASCII value of the character of the
first string is less than that of the
corresponding character of the second
string.
The strings are identical.

Example
x=strcmp(ABC,abc);
Will
return
32(ASCII
difference between A and
a)
0
x= strcmp(ABC,ABC);
Will return 0.
Greater than If the ASCII value of the character of the x=strcmp(abc,ABC);
0
first string is greater than that of the Will
return
32(ASCII
corresponding character of the second difference between a and
string.
A)
To verify the above statements run this program.
Problem 4.15
#include<stdio.h>

/* Standard input output header file

*/

MSc. In Software
main()
{
int x;
x = strcmp(abc,ABC);
printf(%d\n,x);
}

/*
/*
/*
/*
/*
/*

Creating main function


Starting point of main function
Declaring an int type variable
Comparing two strings through strcmp()
Printing the result of the comparison
End of the program

13
*/
*/
*/
*/
*/
*/

Similarly you can check for the other two conditions.


Output of program 4.15
32

atoi()
This function returns the int type value of a string passed to it. The value becomes zero
if the string does not begin with a digit.
For example, if the array str1 contains the string 1234, then the following statement,
y= atoi(str1);
will cause y to have value 1234.
However, if the array str1 contains the string ABC, then the following statement,
y=atoi(str1);
will cause y to have value 0.
Program 4.16
#include<stdio.h>
main()
{
int y=0;
char str1[12];
strcpy(str1,1234);
y = atoi(str1);
printf(%d\n,y);
}
Run this program to verify atoi().
Output of Program 4.16
1234

/* Standard input output header file


/* Creating main function
/* Starting point of main function
/* Declaring and initializing an int type variable
/* Declaring a string type variable
/* Usage of string copy function
/* y being assigned with the int value of str1
/* printf statement to print the integer value
/* End of the program

*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

14

atof()
This function returns the float type value of a string passed to it and the value 0 in case the
string does not begin with a digit or a decimal point.
For example, if the array str1 contains the string 1234, then the following statement,
y = atof(str1);
will cause y to have the value 1234.000000.
To verify the functionality of this function, try this program.
Program 4.17
#include<stdio.h>
main()
{
float y=0;
int str1[12];
strcpy(str1,1234);
y = atof(str1);
printf(%f\n,y);
}

/*
/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring and initializing a float type variable
Declaring a string type variable
Usage of string copy function
y being assigned with the float value of str1
printf statement to print the float value
End of the program

*/
*/
*/
*/
*/
*/
*/
*/
*/

Output of program 4.17


1234.0000000

Function for Formatting Data in Memory


sprintf()
This function, like printf() writes variables to a destination. The difference is that while
printf() writes to the screen, sprintf() writes to a variable in the memory. The syntax of
the function sprintf() is,
sprintf(string, format-specification, data, );
where,
string

: is a pointer to the destination string in the memory which


will contain the formatted data as per the format specification.

format-specification

: is the specification of how data is to be formatted.

MSc. In Software
data

15

: is the list of data to be formatted.

Try this program.


Program 4.18
#include<stdio.h>
/* Standard input output header file
*/
main()
/* Creating main function
*/
{
/* Starting point of main function
*/
char str[12];
/* Declaring a string type variable
*/
sprintf(str,%02d-%02d-%02d,28,5,68); /* Usages of sprintf function
*/
printf(%s\n,str);
/* Standard printf statement to display str */
}
/* End of the program
*/
Run this program.
Output of Program 4.18
28-05-68
So, the function sprintf() is useful for formatting data and controlling the width of the
destination string.

sscanf()
While scanf() reads from keyboard into variables, sscanf() reads from a variable in the
memory and stores the data in different variables specified. This function is used for
transferring data between variables in a specific format.
The syntax of the function sscanf() is,
sscanf(string,format-specification,variable,);
where,
string

is a pointer to the source string in memory, which contains the data to be


assigned to the given list of variables according to the format specification.

formatspecification

is the specification of how data is to be formatted.

variable,

is the list of variables to which data should be assigned after formatting.

Try this program.


Program 4.19

MSc. In Software
#include<stdio.h>
/* Standard input output header file
#include<string.h>
/* Standard string header file, this contains all the useful string functions
main()
/* Creating main function
{
/* Starting point of main function
char str1[15],str2[15];
/* Declaring two char type arrays
strcpy(str1,"sscanf_function"); /* Copying of a string with strcpy function
sscanf(str1,"%s",str2);
/* Usages of sscanf function
printf("%12s\n",str2);
/* Printing the contents of str2
}
/* End of the program

16
*/
*/
*/
*/
*/
*/
*/
*/
*/

Output of program 4.19


sscanf_function
Run the program to see the output.
As explained earlier, str2 is getting the contents of str1 in the sscanf function. So,
ultimately when we are printing str2, we are getting whatever we have copied into str1.

Summary
$ Arrays
We hope that after reading the full lesson the meaning of array is absolutely clear to you. If
the elements of the array are of type character, it is called character type array. The only pain
with a character type array is the string terminator. You have to always consider that while
defining the size of the array.
In case of other types of arrays, this null terminator is not there.

$ Index
The only variable associated with an array is index. It is the number of indexes that makes the
dimension of an array. A particular number of this variable represents a particular member of
an array.

$ One Dimensional Array


An array in its simplest form is in one dimensional form. It has got only one index. A typical
syntax just for a recap is
Data_type array_name[index];

$ Array Initialisation

MSc. In Software

17

Arrays cannot be initialized the way we initialize different variables. A loop is required to
initialize each member of the array.

$ Two Dimensional Array


When an array gets two indices it is called two dimensional array. Following the same logic, we
can declare a multi dimensional array. In case of multi dimensional array multiple loops are
required to initialize that array. A typical syntax,
Data_type array_name[index_1][index_2][index_n];

$ malloc()
malloc function helps to reserve some memory through a program. This function takes one
parameter as number stating how many bytes of memory to be reserved.

$ Strcpy()
In this case a string gets copied on a variable. We generally use this function to initialize an
array with a string.

$ strcat()
This function adds a second string to the end of the first string. Both the strings are passed as
parameters.

$ strlen ()
This function returns the length of a string passed as a parameter to this function.

$ strcmp ()
This function compares the ASCII value of two passing strings as parameters. This gives values
as less than zero equal to zero or less than zero according to the strings passing to it. More
problems on this function are available on the WEB.

$ atoi ()
This function takes one parameter as a string and returns the integer equivalent of the passing
string. If the passing string does not contain a digit, it returns zero.

$ atof ()

MSc. In Software
This function also takes one parameter as a string and returns the float equivalent of the
passing string.
Zee Interactive Learning System

18

MSc. In Software

5
Pointers
Main Points Covered
!

Introduction

Address Variable Ampersand

Different type of pointer

Manipulating a short value with a char type of pointer

Manipulating a short value with a short type of pointer

Manipulating a long value with different type of pointers

Summary

MSc. In Software

Introduction

ointers are perhaps the most powerful and widely used feature of C, and
consequently the most dangerous. After all, power and danger go hand in
hand. We suggest that you go through the pointer part of the notes very
carefully and meticulously. If you haven't understood a line, don't go ahead.

Take a deep breath and try this program:

Address variable Ampersand


Program 5.1
#include<stdio.h>
main ()
{
short i;
printf ("%p\n",&i);
}

/* Including the standard input output header file */


/* Creating main function
*/
/* Starting point of main function
*/
/* Declaring a short type variable
*/
/*Printing the address of memory location where is stored*/
/* End of the program
*/

Let us examine one statement at a time.


short i;
This statement creates a memory variable named i of type short. Here we reserve
two memory locations and call this group of memory location i. This location is
reserved somewhere in memory which you and me dont know. But being curious
creatures we wish to know the location. C grants you this wish when it sees the next
statement:
printf (%p\n,&i);
This printf() is different from any of the printf()s we have seen so far in two
respects.
One:
second:

we have a new format specifier %p and


is the & before variable i.

The %p is to tell the C compiler that the value that will be displayed by this printf()
is a computer memory location. & (ampersand) can be put only in front of a
variable. When C sees the & followed by the variable name, it faithfully displays the
memory location of that variable.
Hey, but short occupies 2 memory locations. So what will be displayed, the first
memory location or the second? Good question!! Answer: the first memory location
will be displayed. Thus, if we assume that i is stored at memory location 5150,5151

MSc. In Software

the above printf() will display 5150. Let me repeat, we are assuming i to be stored
at location 5150, it could be anything.
Sometimes, we just wonder, how is that the smallest of programs need the lengthiest
explanations? Its just uncanny.
In short : A pointer is a variable that contains the address of another variable.
Run the program.
Typical Output of program 5.1
0063FE02

Different type of pointer


Program 5.2
#include<stdio.h>
/* standard input output header file
main ()
/* Creating main function
{
/* Starting point of main function
char i;
/* Declaring a char type pointer
short *j;
/* Declaring a short type pointer
long *h;
/* Declaring a long type pointer
i = 0; j = 0; h = 0;
/* Initialising pointer variables
printf(%p..%p..%p\n,i,j,h);
/* Displaying memory locations of pointer variables
i++; j++; h++; /* Incrementing pointer variables
printf(%p..%p..%p\n,i,j,h);
/* Displaying new memory locations of pointer variables
i++; j++; h++; /* Incrementing pointer variables again
printf(%p..%p..%p\n,i,j,h);
/* Displaying new memory locations of pointer variables again
i++; j++, h++; /* Incrementing pointer variables again
printf(%p..%p..%p\n,i,j,h);
/* Displaying new memory locations of pointer variables again
}
/* End of main function
Output of program 5.2
00000000..00000000..00000000
00000001..00000002..00000004
00000002..00000004..00000008
00000003..00000006..0000000C

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

Here we have 3 pointers i,j,h of data type char, short, long respectively. We are
initializing the values of these 3 variables to 0. Just to check this scenario, we have
the first printf, which tells us:
0000:0000..0000:0000..0000:0000
Then we go on to increment the value of each variable. Now, let us give you some
food for thought: Pointers are of size 4. So, when we increment the values of these
variables will they increase by 4? The answer is No!! Why? All the 3 variables are
pointers of different data type. Thus the next printf will prove to you that i, which is
of type char is incremented by 1, j which is of type short is incremented by 2 and
h, which is of type long, is incremented by 4. (Remember: char, short, long type
data takes only 1 byte, 2 bytes, 4 bytes of memory respectively to store values).
Thus the output of the second printf is:
0000:0001..0000:0002..0000:0004
Think we are kidding you? Increment the variables once again and check their values
with the third printf. The output is:
0000:0002..0000:0004..0000:0008
Thus, the combined output looks like this:
0000:0000..0000:0000..0000:0000
0000:0001..0000:0002..0000:0004
0000:0002..0000:0004..0000:0008

Manipulating a short value with a char type of pointer


Program 5.3
#include<stdio.h>
/* Standard input output header file */
main()
/* main function
*/
{
/* Starting point of main function
*/
short i;
/* Declaring a short type variable
*/
char p;
/* Declaring a char type pointer
*/
printf(Memory location of i= %p\n, &i);
/* Displaying the memory location of short type variable i
*/
i= 300;
/* Initialising i, i.e. storing value 300 in the position of i
*/
printf(Value of i= %d\n,i);
/* Displaying the value of i, i.e. 300
*/
printf(Memory location of i= %p\n, &p);
/* The location, where i is stored in the memory
*/
p=&i;
/* Initialising p with the memory location of i
*/
printf(Value of p= %p\n,p);
/* Displaying value of p which is again the address of i
*/
p=10;
/* This means the pointer type variable p, stores 10 in the memory location of i */

MSc. In Software
printf(Value
p++;
printf(Value
*p=10;
printf(Value
p++;
printf(Value
*p= 100;
printf(Value
}

of i= %d\n,i);
/* Displaying the new value of i
*/
/* Incrementing the value of pointer variable by 1
*/
of p= %p\n,p);/* This displays the value of the pointer variable */
/* Putting value 10 in the memory location pointed by p */
of i= %d\n,i);
/* The changed value of i
*/
/* Incrementing the value of p once again
*/
of p= %p\n,p);
/* The changed value of i
*/
/* Again, putting value 100 in the memory location pointed by p */
of i= %d\n,i);
/* Displaying the value of i
*/
/*End of the main function
*/

It is imperative that you follow this program, because the next two programs are
similar. To help you understand the program really well, we have exploded the
program into lines, explaining one line at a time.
Now if you are ready, well start with,
short i;
We are reserving 2 locations in memory and calling them i. Two locations, since size
of a short is 2. For the sake of understanding, we assume that the memory locations
reserved are locations 100 and 101. (in Fig 5.1)

char *p;
Now, p is a pointer. What does that mean? It means it represents 4 memory
locations. Here we assume p occupies locations starting from 200(Fig 5.2). What
does it also mean? It further means, that the value of p is treated as a computer
memory location. Also, p is a pointer of data type char. The significance of this will
be clear shortly.

MSc. In Software

printf(%p\n,&i);
Tell yourself: & means address of memory location of variable i. %p means that
the output will be a computer memory location. This statement will display the actual
address of memory location that is named i. But we have two memory locations
under i. So what does this printf display? The first memory location: 100.
Then,
i=300;
When C sees a value assigned to a variable, it first finds out the location of that
variable in memory. In this case, when C sees 300, it looks for the locations of i. It
finds it to be 100. It then divides 300 by 256. (Why 256? Because in a single
memory location we can only store values 0 to 255). The quotient is 1, the remainder
is 44. Thus it puts 300 in the memory locations 100 and 101 as follows (Fig 5.3):

We are just making the value of i , 300.


Now,

MSc. In Software

printf(%d\n,i);
A simple printf statement. We do not trust our computer to be responsible enough so
we check to see if i is actually stored as 300. This statement will make you trust the
computer more. The value displayed is indeed 300.
After that,
print(%p\n,&p);
Aha! Inquisitive, arent we? We now want to know the address of p in memory. Your
trusted companion (the computer) will faithfully tell you the where in memory p gets
stored. Anything else worth noting?? Yes!! Dont you see a %p, indicating that the
output is a computer memory location! People who are paying real attention to what
we are saying would ask: "p is a pointer, hence it occupies 4 memory locations,
but the size of char is 1, so isnt this a contradiction? Good question! Great
Question!! Answer? Read on.
p=&i;
&i is a computer memory location! Right or wrong? Right! We also know (from Line
4) that p is a pointer, which means the value stored in it is understood as a
computer memory location. So what? So, in this line we are simply putting the
address of i into p(Fig 5.4).

Again,
printf(%p\n,p);
Checking never hurt anyone. So why not be sure of what is happening! This printf will
tell you exactly what the value of p is. Satisfied that it is 100,we take one more step.
*p=10;

MSc. In Software

Wake up! Wake up!! Understand this right now or it will give you sleepless nights for a
long time to come. This small statement packs quite a punch. Time to ask ourselves
questions! What is p?? A variable which occupies 4 memory locations and whose
value does C as a computer memory location understand. What is the current value of
p?? From line 11 we know it is 100. So when we type this line what happens? The
compiler runs to p (memory location 200) finds out its value (100), goes to memory
location 100 and puts the value 10 in memory location 100. So what is effectively
happening is (Fig 5.5):
*100=10;
We suggest you read the previous statements again and again .. until it is absolutely
clear.

.
Checking time again,
printf(%d\n,i);
We ascertain if the value of, i has really changed. This printf tells you it has become
266.
p++;
You see the ++ sign after a variable and you say: I know this one. You are
incrementing the value of the variable. But dont stop at that. Ask: By how much is
the value being incremented?. Stop and ponder. Are you in a position to answer this
question. Yes you are! How?? Flee back to line 5. Remember, we defined p as a
pointer of data type char. You know that size of char is one. So, the value of p
now becomes 101( Fig 5.6).

MSc. In Software

Now,
printf(%p\n,p);
You know our habit. We make a change and check, if all is fine. This printf tells you
that all is indeed fine, and that the value of p is indeed 101.
Then
*p=10;
Now this should not be too difficult. Go to p (memory location 200). See what it
contains (101). Go to that memory location and put the value 10. Effectively it means
(Fig 5.7) :
*101=10;

MSc. In Software

10

Then we have,
p++;
The value of p now becomes 102 (as shown in Fig 5.8).

printf(% p\n,p);
Checking to see the value of p. It is 102.
*p=100;
Similarly, we now have (Fig 5.9):
*102=100

If you notice, we have been taking great pains in the diagrams to show you the
position of i. Now, the time has come for you to know the significance of our labour.

MSc. In Software

11

When we put 100 into memory location 102, do you think that i changes? One look
at the diagram will tell you, No! i represents the memory locations 100 ,101. What
we do to other memory locations does not have any effect on i. So, the value of i is
still 2570.
At last,
printf(%d\n,i);
Just confirming the value of i. Guess what! Its still 2570.
If you have understood the above program, you need to give yourself a treat. Stand
before the mirror and the person you now see is a transformed person. A person who
understands pointers. A person who has proved that when the going gets though,
he/she gets going! Good work! Take a deep breath and try this program:
Run the program to get output.
Typical output of the program 5.3
Memory location of i= 0063FE02
Value of i= 300
Memory location of i= 0063FDFC
Value of p= 0063FE02
Value of i= 266
Value of p= 0063FE03
Value of i= 2570
Value of p= 0063FE04
Value of i= 2570

Manipulating a short value with a short type of pointer


Program 5.4
#include<stdio.h>
/* Standard input output header file.
main()
/* main function.
{
/* Starting point of main function.
short i;
/* Declaring a short type variable i.
short *p;
/* Declaring a short type pointer p.
printf(Memory location of i= %p\n, &i); /* Address of i.
i=300;
/* Initialising i.
printf(Value of i=%d\n,i);
/* Printing value of i i.e. 300.
printf(Memory location of p = %p\n, &p); /* printing address of p.
p=&i;
/* Initialising p with the address of i.
printf(Value of p = %d\n,p);
/* Printing the address of i.
*p=10;
/* Inserting value 10 at the position
pointed by p.
printf(Value of i = %d\n,i); /* Printing the changed values of i, after

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software

p++;
printf(Value of p = %d\n,p);
*p=100;
printf(Value of i= %d\n,i);
}

12

the above insertion.


*/
/* Incrementing the value of p. A pure
mathematical operation.
*/
/* Previously, the value of p was, the
address of i. Now, it contains the next
memory location.
*/
/* Putting 100 in a memory
location, which is now the current value
of p.
*/
/*
Printing the value of i to see
whether its value has changed.
*/
/* End of main function.
*/

Another program. Another pointer program. Not fair!! Relax! We have made just
made one change in the program. Line 5 now says:
short *p; instead of char *p;
We are intentionally copying the words of the explanation that we just gave you. This
should not be considered as a sign of a lack of originality, but should be appreciated
because now you can understand this program all by itself. No flipping pages. In other
words, we have given you a stand alone explanation. Also, comparing program is a
lot easier.
Here, we have,
short i;
We are reserving 2 locations in memory and calling them i. Two locations, since size
of a short is 2. For the sake of understanding, we assume that the memory locations
reserved are locations 100 and 101 as in Fig 5.10

Then,
short *p;

MSc. In Software

13

p is a pointer. What does that mean? It means that it has 4 memory locations. Here
we assume p occupies locations starting from 200. What does it also mean? It
further means, that the value of this variable is treated as a computer memory
location. Also, p is a pointer of data type short. The significance of this will be clear
shortly(refer Fig 5.11).

Next line,
printf(%p\n,&i);
Tell yourself; & means address of memory location of variable i. %p means that
the output will be a computer memory location. This statement will display the actual
address of memory location that is named i. But we have two memory locations
under i. So what does this printf display? The first memory location, 100.
i=300;

MSc. In Software

14

We are just making the value of i 300 (refer Fig 5.12).


printf(%d\n,i);
Simple printf statement. We do not trust our computer to be responsible enough so
we check to see if i is actually stored as 300. This statement will make you trust the
computer more. The value displayed is indeed 300. Understand another thing:
whenever you want to call a variable you call it by its name. This causes the C
compiler to go that memory location and pick or place the value according to what the
statement asks it to do. So:
Variable name = Memory Location
printf(%p\n,&p);
Aha! Inquisitive, arent we? We now want to know the address of p in memory. Your
trusted companion (the computer) will faithfully tell you where in memory p gets
stored. Anything else worth noting?? Yes!! Dont you see a %p, indication that the
output is a computer memory location! People who are paying real attention to what
we are saying would ask : p is a pointer, hence it occupies 4 memory locations, but
the size of short is 2 so isnt this a contradiction? Read on,
p=&i;
&i is a computer memory location! Right or wrong? Right! We also know that p is a
pointer, which means the value stored in it is understood as a computer memory
location. So what? So, in this line we are simply putting the address of i into p.

MSc. In Software

15

*p=10;
Wake up! Wake up!! Understand this right now or it will give you sleepless nights for a
long time to come. This small statement packs quite a punch. Time to ask ourselves
questions! What is p?? (Refer Fig 5.12) A variable which occupies 4 memory
locations and whose value is understood by C as a computer memory location. What
is the current value of p?? It is 100. So when we type this line what happens?? The
compiler runs to p (memory location 200) finds out its value (100), goes to memory
location 100 and puts the value 10 in memory location 100.
short *p;
It will be clear now. Since p is a pointer of data type short, and we know that short
has of size 2, the number 300 stored in i will now be replace by 10.
So what is effectively happening is:
*100=10;

(Compare this with the previous program)

MSc. In Software

16

The important thing to note here is that, since p is a pointer to a short, the value
10 is written to 2 memory locations, 100,101 (since size of short is 2). Refer Fig
5.13.
We suggest you read the previous statements again and again until it is absolutely
clear.
printf(%d\n,i);
Checking time again. We ascertain if the value of i has really changed. This printf
tells you it has changed to 10.
p++;
You see the ++ sign after a variable and you say: I know this one. You are
incrementing the value of the variable. But dont stop at that. Ask; By how much is
the value being incremented? Stop and ponder. Are you in a position to answer this
question? Yes you are! How?? Flee back to line 5. Remember, we defined p as a
pointer of data type short. You know that size of short is two. So, the value of p
now becomes 102.

printf(%p\n,p);
You know our habit. We make a change and check to see if all is fine. This printf tells
you all is fine, and that the value of p is indeed 102 (Fig 5.14).
*p=100;
Now this should not be too difficult. Go to p (memory location 200). See what it
contains (102). Go to that memory location and put the value 100. Effectively it
means:

MSc. In Software

17

*102=100 ;

printf(%d\n,i);
If you notice, we have been taking great pains in the diagrams to show you the
position of i. Now, the time has come for you to know the significance of our labour.
When we put 100 into memory location 102, do you think i changes? One look at
the diagram (Fig 5.15) will tell you, NO! i represents the memory locations 100
101. What we do to other memory locations does not have any affect on i. So, the
value of i is still 10.
We just hope that the pointers in your brain havent gone haywire. If you havent
followed the previous example sit with them, sleep over them, do whatever but get it
absolutely clear. This is the last program in this marathon series. Jump right into it:
Typical output of program 5.4
Memory location of i= 0063FE00
Value of i=300
Memory location of i=0063FDFC
Value of p = 6553088
Value of i= 10
Value of i=6553092
Value of i= 10

MSc. In Software

18

Manipulating a long value with different type of pointers


Program 5.5
#include<stdio.h>
main()
{
long i;
char *j;
short *k;
long *l;
printf(%p\n,&i);
i=65536+515;
printf(%ld\n,i);
printf(%p\n,&j);
j=&i;
printf(%p\n,j);
*j = 10;
printf(%p\n,i);
j++;
printf(%ld\n,j);
*j = 10;

printf(%ld\n,i);
i=65536+515;
k=&i;
printf(%p\n,k);
*k=10;

printf(%ld\n,i);
k++;
printf(%p\n,k);
*k=10;

printf(%ld\n,i);
i=65536+515;
l=&i;

/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file.


*/
main function
*/
Starting point of main function
*/
Declaring a long type variable
*/
Declaring a char type pointer
*/
Declaring a short type pointer
*/
Declaring a long type pointer.
*/
Printing the address of variable i.
*/
Initialising i with an arbitrary value.
*/
Displaying the value of i.
*/
Printing the address of pointer variable j.*/
Storing the address of i in j.
*/
Printing the address of j.
*/
Putting the value 10 in an address which
is stored in j
*/
/* This shows the address of i.
*/

/* Incrementing the value of j, i.e. to


the address next to what i occupied. */
/* Printing the value of j
*/
/* Putting value 10 in a memory
location, which is now in j or pointed
by j, i.e. trying to change the value
of i.
/* Printing the value of i again.
/* Reinitialising i with the original value.
/* Address of i being stored in k.
/* This line gives the address of k

*/
*/
*/
*/
*/

/* Placing the value 10 in a place pointed


by k, meaning by trying to change the value
of i.
*/
/* This gives the value of i.
*/
/* Incrementing the value of k.
*/
/* Again printing the address of k.
*/
/* Placing the value 10 in a place pointed
by k. But this time the value of k is different
*/
/* This gives a new value of i, because of
all those manipulations
*/
/* Again reinitializing the value of i.
*/
/* Initialising l with the address of i.
*/

MSc. In Software
printf(%p\n,l);
*l=10;
printf(%ld\n,i);
l++;
printf(%p\n,l);
*l=20;
printf(%ld\n,i);
}

19

/* Printing the address of l.


*/
/* Placing 10 in a place pointed by l. As you read
the explanation, it will become clear to you that this placing
depends on the type of pointer.
*/
/* This statement shows the changed value of i. */
/* Incrementing l by 1.
*/
/*Value of l after incrementing by 1
(actually incremented by 4)
*/
/* Placing 20 in a place pointed by l.
*/
/* Value of i ,what do you expect?
*/
/* End of main function.
*/

Phew!! But, hey who is scared of long programs, anyway? We will assume here, that
you have grown up from being pointer-kids to pointer adults. For kids we need
break the dose into small doses, adults can take it all at once. So enough of spoon
feeding lets act like grown-ups.
Here we define i as a long, which means that we are reserving 4 locations
somewhere in memory and calling them i. We will assume that those locations begin
from 100.

Then, we have a flood of pointers. j is a pointer to a char, k is a pointer to a short


and l is a pointer to a long.
In the first printf we display the actual address of i. We have assumed it to be 100.
Then, i is given a value of 65536+515. Dont you dare our mathemetical prowess!
We have left the addition incomplete because that way our representation of memory
makes more sense (Fig 5.17). Thus:

MSc. In Software

20

The next statement is:


printf(%ld\ni,);
here we display the value of i. Notice that we have used %ld in the print, since i
is a long.
Now we check on j and find its location in memory. The next printf displays the
memory location of j. Let us assume it to be 200.
In the next statement, we innocently put the location of i into j. To check if the
location of i has indeed reached j, we have the next printf, which displays the value
of j.
The next statement is:
*j=10;
This statement is equivalent to saying:
*100=10 (Fig 5.18);
Thus, we put the value 10 into memory location 100. Note, that since j is a pointer
to a char, the value 10 has gone into l memory location only. i.e. 100. Now the
memory location represented by i looks this (Fig 5.18):

MSc. In Software

21

The value of i displayed in the next printf tells us this new value of i.
Next, we increment j. Again, the data type of the pointer (char) will ensure that the
value of j is incremented only by 1. In the next printf we check the value of j after
the increment and find it to be 101. Then we again have the statement:
*j=10;
which now is like saying:
* 101=10 (Fig 5.19);
Thus, we put the value 10 into memory location 101. Note, that since j is a pointer
to a char, the value 10 has gone into 1 memory location only. i.e. 101. Now the
memory location represented by i looks like this (Fig 5.19):

MSc. In Software

22

Thus i now has a new value, which is displayed by the next print.
Now, we make the value of i the same as what we started with, i.e. 65536+515.
We then put the location of i into k. Thus, k now has a value 100. We display the
value. Then, we have:
*k=10;
which is equivalent to saying,
*100=10;
Aha! but k is a pointer to a short. Thus, we are effectively putting the value 10 into
2 memory locations (size of short is 2), 100 and 101. Thus a snapshot of the location
i looks like this (Fig 5.20):

MSc. In Software

23

The next printf tells us that the value has changed. Then, we increment k. Since k
is of type short, incrementing k results in a jump of 2. Thus the value of k now
becomes 102. Then we again have the statement:
*k=10;
which is equivalent to:
*102=10;
This will result in a change of memory locations 102 and 103, since k is a pointer to
type short. Thus, location i will now looks like this (Fig 5.21):

MSc. In Software

24

The value of i is displayed by the printf.


As before, we make the value of i equal to 65536+515. Then we put the location of
i into l. Thus, l now contains 100. Then we have the statement:
*l=10;
This means (refer fig 5.21):
*100=10;
Now, l is a pointer to a long, thus the value 10 has gone into 4 memory locations.
i.e. 100,101,102,103. Now the memory location i looks like this (Fig 5.22):

MSc. In Software

25

The printf gives us this new value of i.


Then we increment l. l is now incremented by 4, since it is a pointer to a long.
Thus the value of l now becomes 104. Then, when we have the statement:
*l=20;
It is understood as (refer fig 5.22):
*104=20;
20 is assigned locations 104, 105, 106, 107. Thus, location of i looks like:

MSc. In Software

26

The value of i remains unchanged since i represents locations 100,101,102 and


103. But we have not touched these memory locations. Thus, i still has a value 10.
But now, since we are writing into memory locations not reserved by us, there is
always a danger of the computer hanging.
A typical output of program 5.5
0063FE00
66051
0063FDFC
0063FE00
0001020A
6553089
68106
0063FE00
65546
0063FE02
655370
0063FE00
10
0063FE04
10

MSc. In Software

27

Summary
# Address Variable - Ampersand
Pointers and addresses are two sides of a coin. To begin with, pointers are some sort
of variables of size 4 and it stores address. This address is obviously an address of
another variable. Address means at what byte number the particular variable is
stored. Address of a variable is represented as &.

# Different type of pointer


Like different types of variables, different types of pointers are also possible. But
there is something interesting. We know size of different variables is different. As a
matter of fact different sizes make different variables. On the contrary, size of all the
pointers is 4. When arithmetic of pointer comes into picture its type becomes vital. To
learn more about pointer arithmetic login to the WEBSITE.

# Manipulating a short value with a char type of pointer


This is the first program to make you understand the type of pointers. Read the
program once again, there cannot be any summary for it. For more applications, visit
our WEBSITE.

# Manipulating a short value with a short type of pointer


Read the program under this heading again and visit our WEBSITE for more
examples.

# Manipulating a long value with different type of pointers


No shortcut for this example also. For practical examples visit out WEBSITE.
Zee Interactive Learning System

MSc. In Software

6
Structure and Unions
Main Topics Covered

Structure

How To Access Structure Members

Manipulation of Member data

Structure Tag

Unions

Link list

Summary

MSc. In Software

Introduction

o solve the shortcoming of arrays, structures have come into the picture. You
already know that a simple variable can be used to hold one piece of information
at a time and arrays can be used to hold a number of pieces of information of
the same data type. These two data storage mechanisms can handle many situations.
However there may be a case, where the programmer may wish to operate upon data
items of different types together as a unit. In this case, neither a variable nor the
array is adequate.
So, we know that a structure contains a number of data types grouped together.
These data types may or may not be of the same type.
To understand structures let us start with an example. When we have reached the
end of the program structure will be absolutely clear.
Program 6.1
#include<stdio.h>
main()
{
struct
{
short i;
char j;
long k;
}zzz;
}

/* Standard input output header file.


/* main function.
/* Starting point of main function.
/* A structure declaration.
/* Starting point of this structure .
/* First member of this structure.
/* Second member of this structure.
/* Third member of this structure.
/* End of the structure and the name of the structure.
/* End of main function.

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

What have we done here? Created a structure called zzz! What is a structure? It is a
collection of variables, which is given a name. All that C will now do is at 100
(Assumed memory location, Fig 6.1), it will create a structure called zzz. 100, 101
will be a short (i), 102 will be a char (j), the next four positions 103,104,105, 106
will be a long (k).

MSc. In Software

Structures are just a covering for a collection of variables. Nothing more!


If you run this program, only a structure will get created in the memory and nothing
more will happen.
Let us make the above program a little bigger.

How To Access Structure Members


Program 6.2
#include<stdio.h>
main()
{
struct
{
short i;

/* Standard input output header file.


/* Main function.
/* Starting point of main function.
/* Structure declaration.
/*Starting point of structure declaration.

*/
*/
*/
*/
*/

/* Declaring a short type variable within


the structure*/
char j;
/* Declaring a char type variable within
the structure.
*/
long k;
/*Declaring a long type variable within the structure
*/
}zzz;
/* End of the structure and name of the structure */
printf(%d\n,sizeof(zzz)); /* Gives the total size of all the variables contained
in zzz .
*/
printf(%p\n,&zzz);
/* Gives the address of zzz i.e. where zzz
starts in the memory.
*/
printf(%p\n,&zzz.i);
/* Gives address of i.
*/
printf(%p\n,&zzz.j);
/* Gives address of j.
*/
printf(%p\n,&zzz.k);
/* Gives address of k.
*/

MSc. In Software
}

/* End of main function.

*/

A typical output of program 6.2


7
0063FDFC
0063FDFC
0063FDFE
0063FDFF
This program has got extra 5 lines. Do I need to explain it?
Let us start from line 9
printf(%d\n,sizeof(zzz));
This line should display 7. How? 2(int) + 1 (char) + 4 (long) = 7 (zzz)
Then,
printf(%p\n,&zzz);
This displays 100. You remember that is where zzz starts in the memory (we have
assumed).
Then,
printf(%p\n,&zzz.i);
printf(%p\n,&zzz.j);
printf(%p\n,&zzz.k);
zzz.i ?? How does C interpret that? This means the address of variable i which is in
a structure called zzz. The . is used as a separator between the structure name and
its variable.
Thus the first printf will display the same address as that of zzz,100(since it is the
first member). The second printf will display 102. and the third one will display 103.
If you run this program at this stage you will get three memory locations where you
will find that the difference between second and first is 2 and difference between third
and second is 1.
Run this program to verify it.
Let us now make our program a little bigger.

Manipulation of Member data

MSc. In Software

Program 6.3
#include<stdio.h>
main()
{
struct
{
short i;
char j;
long k;
}zzz;

/*
/*
/*
/*
/*
/*
/*
/*
/*

printf(%d\n,sizeof(zzz));

/*

printf(%p\n,&zzz);

/*

printf(%p\n,&zzz.i);
printf(%p\n,&zzz.j);
printf(%p\n,&zzz.k);
zzz.i = 10;

/*
/*
/*
/*

zzz.i++;

/*

printf(%d\n,zzz.i);

/*

/*

Standard input output header file.


main function.
Starting point of main function.
Declaring a structure.
Starting point of structure.
First member of the structure.
Second member of the structure.
Third member of the structure.
End of the structure and end of
the structure.
Gives the total size of all the
variables contained in zzz .
Gives the address of zzz i.e. where
zzz starts in the memory.
Gives address of i
Gives address of j
Gives address of k
Initialising the first member of
the structure.
Incrementing the value of the first
member of the structure.
Displaying the value of the first member
of the structure.
End of the main function.

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

A typical output of program 6.3


7
0063FDFC
0063FDFC
0063FDFE
0063FDFF
11
Try to guess the output of the last printf. Yes it will be 11. But ask yourself why.
Now we move one step ahead.

Structure Tag
Program 6.4
#include<stdio.h>
struct zzz
{

/* Standard input output header file.


/* Declaring a structure tag globally called
zzz.
/* Starting point of structure declaration.

*/
*/
*/

MSc. In Software
short i,j,k;
}
main()
{
struct zzz a;

Declaring three short type of variables. */


End of structure declaration.
*/
Creating main function.
*/
Starting point of main function.
*/
Declaring a structure a, which looks
like zzz.
*/
struct zzz b;
/* Declaring a structure b, which looks
like zzz.
*/
struct zzz *c;
/* c is a pointer to a structure that looks
like zzz.
*/
a.i = 1; a.j = 2;
/* Initialising the first and second member
of structure a.
*/
printf(%p..%d..%d\n,&a,a.i,a.j); /* Printing the address of a and the
value of two of its members.
*/
b.i = 10; b.j = 20;
/* Initialising the first and second member
of structure b.
*/
printf(%p..%d..%d\n,&b,b.i,b.j);/* Printing the address of b and the
value of two of its members.
*/
printf(%d\n,sizeof ( c ));
/* Printing the size of the pointer c. */
c = &a;
/* Initialising the pointer with the
address of the structure a.
*/
printf(%p\n,c);
/* This shows the address of a, i.e.
the value contained in c.
*/
printf(%d\n,c -> i);
/* This shows the value of first member
of structure a.
*/
c->j = 3;
/* Initialising the second member of
the structure a through the
pointer c. */
printf(%d\n,a.j);
/* Printing the second member of
the structure a. */
c = &b;
/* Initialising the pointer with the address
of the structure b.
*/
printf(%p\n,c);
/* This displays the address of b.
*/
printf(%d\n,c->i);
/* Displaying the value of the first member
of structure b through c.
*/
c->j = 4;
/* Initialising the second member of
the structure b through the
pointer c.
*/
printf(%d\n,b.j);
/* Printing the second member of the
structure b.
*/
}
/* End of the function.
*/
A typical output of program 6.4
0063FDFC..1..2
0063FDF4..10..20
4
0063FDFC

/*
/*
/*
/*
/*

MSc. In Software

1
3
0063FDF4
10
4
The order of statements in which this program is explained has been changed, for
better understanding.
Do you notice any change? For the first time we have written zzz, next to the word
struct. This is a big change because this is now called a structure tag. It is like a
label. How much memory do you think gets allocated for this tag? ZERO. Why?
Because, we are only giving basic information about the structure and nothing else.
Then we say:
struct zzz a;
In simple English this means, a is a structure that looks like zzz. What is zzz? It
is a structure tag that we just created. Now we can safely say,
a.i = 1;
a.j = 2;
a is a structure that looks like zzz. It has 3 members i,j,k. So when we say,
printf(%p..%d..%d\n,&a,a.i,a.j);
we will get, 0063FDFC..1..2
Run this program to verify the output. In your case you will get a different memory
location.
Along the same line we have:
struct zzz b;
b.i = 10; b.j = 20;
printf(%p..%d..%d\n,&b,b.i,b.j);
The output will be 0063FDF4..10..20
Remember the memory location will be different in your case. In the above line a
typical memory address is shown.
Thus a and b are structures that look like zzz. In other words whatever zzz
stands for, now a and b stands for the same.

MSc. In Software

zzz stands for 3 shorts i,j,k .


Hence a and b also have 3 members, i,j,k all shorts.
Now an interesting statement.
struct zzz *c;
c is a pointer to a structure that looks like zzz. Pointer to anything is of size 4.
Thus if we now
say:
printf(%d\n,sizeof(c));
We will see 4.
A snapshot of memory at this stage will look like this (Fig 6.2).

When you say c is a pointer to a structure that looks like zzz, it is your job to
initialize the pointer (Fig 6.3).
So in the statement,
c = &a;
printf(%p\n,c);
this is what happens.

MSc. In Software

What begins at 100? A structure that looks like zzz(a). The next printf displays the
location to which c points (i.e. address of a).
You should have one thing very clear:
a is a structure that looks like zzz.
b is a structure that looks like zzz.
c is a pointer to a structure that looks like zzz.
Which structure c points to, is not specified. It is our responsibility as programmers
to initialize this.
It is like when we say:
long *i;
We are not saying long i points to what. Here also we have to initialize the pointer.
Next we see,
printf(%d\n,c->i);
We know that c is a pointer to a structure that looks like zzz, a is a structure
that looks like zzz. When you have a name of a structure (a), according to the
syntax of C we use a ( . ) dot to separate the structure name and its member. When
you have a pointer to a structure ( c ), we have to use -> sign to separate the
structure name and its member.
Thus the above printf displays: 1. How?
Remember we had made the value of a.i = 1, and
since c points to a, c->i is also 1.
Similarly when we say:

MSc. In Software

10

c->j = 3;
printf(%d\n,a.j);
we make the second member of the structure to which c points equal to 3.
Hence we see : 3
Then we have:
c = &b;
printf(%p\n,c);
This printf will display the address of b, because c now points to b. Hence when
we say,
printf(%d\n,c->i);
This printf displays 10. Why? Because we had said :b.i = 10.
Now if we say:
c->4;
We are now making the second member of the structure to which c points, equal to
4.
Consequently when we say:
printf(%d\n,b.j);
It displays: 4.
Please run the program to see the output.

Unions
The next set of programs deal with structures and unions, and tell you about the
differences between the two.
Program 6.5
#include<stdio.h>
main()
{
struct
{

/*
/*
/*
/*
/*

Standard input output header file.


main function.
Starting point of the main function.
Declaring a structure.
Starting point of the structure.

*/
*/
*/
*/
*/

MSc. In Software

11

char i;
short j;
long k,l;
}zz;

/* Declaring a char type variable.


*/
/* Declaring a short type variable.
*/
/* Declaring two long type variables.
*/
/* End of the structure and the
structure name.
*/
printf(Addr of zz
%p\n,&zz); /* This gives the memory location of zz. */
printf(Addr of zz.i
%p\n,&zz.i);/* This gives the memory location of
the first member of the structure.
*/
printf(Addr of zz.j
%p\n,&zz.j);/* This gives the memory location of
the second member of the structure. */
printf(Addr of zz.k %p\n,&zz.k);/* This gives the memory location of
the third member of the structure.
*/
printf(Addr of zz.l
%p\n,&zz.l);/* This gives the memory location of
the forth member of the structure.
*/
zz.k = 65536 + 515;
/* Initialising the third member of
the structure.
*/
printf(zz.k = %ld\n,zz.k);
/* Displaying the value of the third member
of the structure.
*/
printf(zz.i = %d.zz.j = %d.zz.l = %ld\n,zz.i,zz.j,zz.l);
/* Displaying the values of the first, second and forth member of the structure.
*/
printf(sizeof(zz) = %d\n,sizeof(zz)); /* Displays the size of the structure. */
}
/* End of the function.
*/
A typical output of this program 6.5
Addr of zz
0063FDF8
Addr of zz.i 0063FDF8
Addr of zz.j 0063FDF9
Addr of zz.k 0063FDFB
Addr of zz.l 0063FDFF
zz.k = 66051
zz.i = 40.zz.j = 16480.zz.l = 256
sizeof(zz) = 11
Run this program and verify the output. In your case you will get different memory
locations. The value of zz.i, zz.j, zz.l will also be different since you have not
defined any value for that. In our typical output also we got some junc values.
The members of the structure are arranged as shown below (Fig 6.4). Only the first
variable has the same address as that of the structure.

MSc. In Software

12

We have initialized only one of these variables, namely k, to 65536 + 515.


Obviously, when we display the other variables, we cannot predict what values will get
displayed, as we have not initialized them. The size of the structure is 11.
The next program is almost similar, except for the fact that instead of having a
structure called zz, we now have a union called zz. The union is made up of
exactly the same members as that of the structure zz. Thus, we are saying, that
when you consider syntax of both a structure and a union, they are exactly the
same.
The rest of the program is also the same.
Program 6.6
#include<stdio.h>
main()
{
union
{
char i;
short j;
long k,l;
}zz;
printf(Addr of zz
printf(Addr of zz.i

/* Standard input output header file.


*/
/* main function.
*/
/* Starting point of the main function.
*/
/* Declaring an union.
*/
/* Starting point of the union.
*/
/* Declaring a char type variable.
*/
/* Declaring a short type variable.
*/
/* Declaring two long type variables.
*/
/*End of the structure and the structure name
*/
%p\n,&zz);/* This gives the memory location of zz.
*/
%p\n,&zz.i);/* This gives the memory location of
the first member of the union.
*/

MSc. In Software
printf(Addr of zz.j

%p\n,&zz.j); /* This gives the memory location of


the second member of the union.
printf(Addr of zz.k %p\n,&zz.k); /* This gives the memory location of
the third member of the union
printf(Addr of zz.l
%p\n,&zz.l); /* This gives the memory location of
the forth member of the union.
zz.k = 65536 + 515;
/* Initialising the third member of the union.
printf(zz.k = %ld\n,zz.k);
/* Displaying the value of the
third member of the union.
printf(zz.i = %d.zz.j = %d.zz.l = %ld\n,zz.i,zz.j,zz.l);
/* Displaying the values of the first, second and forth member of the union.
printf(sizeof(zz) = %d\n,sizeof(zz));/* Displays the size of the union.
}
/* End of the function.

13

*/
*/
*/
*/
*/
*/
*/
*/

A typical output of this program is 6.6


Addr of zz
0063FE00
Addr of zz.i 0063FE00
Addr of zz.j 0063FE00
Addr of zz.k 0063FE00
Addr of zz.l 0063FE00
zz.k = 66051
zz.i = 3.zz.j = 515.zz.l = 66051
sizeof(zz) = 4
You now realize that all the variables that are members of the union begin at the
same address. Also, the size of the union is 4, as compared to 11 for the equivalent
structure. This means that the size of the union doesnt depend on the number of
members within the union, and is not the sum of the size of each member, as in the
case of structure. A union simply occupies an area of memory that its largest
member occupies. In the case of our union, the largest member is a long, so the
union occupies 4 bytes, as shown in the figure below. This is a major difference
between a structure and union. The consequence of this difference is also quite
drastic. By changing merely a single byte, we may end up changing the values of all
four variables that are members of the union.

MSc. In Software

14

For example in our program 6.6 , we have merely initialized a single variable, namely
k, as we did in the program 6.5. In that program, initializing a single variable had no
effect on the other variables. As all the variables occupied different memory locations.
In this program, however, the other variables will take the values based on the values
of k. As k was initialized to 65536 +515, the four memory locations occupied by
the union will have the values 3, 2, 1 and 0 (Fig 6.5).
Since i is a char, it occupies the first location in the union and is equal to 3.
The short j occupies the first two memory locations, and therefore will be equal to
515.
Both the longs, k and l occupy all four bytes, therefore both are equal to 66051.
Try changing the value of char, and see what effect it has on the other variables.

Link List
As per our rule, let us start with a program, and we will understand how structures
are used as the basic part of the link list.
Program 6.7
#include<stdio.h>
struct zzz
{
char a[100];
struct zzz *b;

/*
/*
/*
/*

Standard input output header file.


Declaring a structure with a tag zzz.
Starting point of structure declaration.
Declaring a character type array of
length 100.
/* Declaring a pointer to a structure that
looks like zzz.

*/
*/
*/
*/
*/

MSc. In Software
};
main()
{
struct zzz z;
printf(%d\n,sizeof(z));
}

15

/*
/*
/*
/*
/*

End of structure declaration.


*/
Creating main function.
*/
Starting point of main function.
*/
Creating a structure z that looks like zzz.*/
Gives the total size of the structure z
that looks like zzz.
*/
/* End of main function.
*/

This is a program to confuse you, and thereby make you understand. When we create
a structure zzz, it has an array a and a pointer to a structure that looks like
zzz, which is again essentially consists of an array a and a pointer which is
What????? Are you lost?
Just try to guess the output.
Output of program 6.7
104
The next program is a little bigger. Follow it.
Program 6.8
#include<stdio.h>
struct zzz
{
char a[100];
struct zzz *b;
};
struct zzz z,*root,*new,*prev;
and three
point to a
that these
main()
{
gets(z.a);
while (strcmp(z.a,QUIT))

{
abc();
gets(z.a);

/*
/*
/*
/*

Standard input output header file.


*/
Declaring a structure with a tag zzz.
*/
Starting point of structure declaration.
*/
Declaring a character type array of
length 100.
*/
/*Declaring a pointer b that looks
like structure zzz.
*/
/* End of structure declaration.
*/
/* Declaring a structure z that looks like zzz
global pointers called root, new and prev that
structure that look like zzz. You now know this
pointers are initialized to zero.
*/
/* Creating main function.
*/
/* Starting point of main function.
*/
/* This function is to get input from user into
the array a.
*/
/*While loop, with a condition. As long as z.a
is not QUIT, the strcmp function will return a
non-zero value. So, the loop will continue.
When the user puts QUIT in z.a, this condition
will become zero, and that is the end of the
loop.
*/
/* Starting point of while loop.
*/
/* Calling a user defined function, abc.
*/
/* Asking for a value for z.a from the user. */

MSc. In Software
}
pqr();
}
abc()
{
if (root == 0)
{
root = malloc(104);

strcpy(root -> a, z.a);


root->b=0;
prev =root;
}
else
{
new = malloc(104);

strcpy(new->a,z.a);
new->b = 0;
prev->b = new;
prev = new;
}
}
pqr()
{
while (root!=0)
{
printf(%s\n, root->a);
root = root->b;
}
}

16

/*
/*
/*
/*
/*
/*

End of while loop.


*/
Calling user defined function, pqr.
*/
End of main function.
*/
Creating abc function.
*/
Starting point of abc function.
*/
If condition. At first the value of root
is zero, since declared globally.
*/
/* Starting point of if condition.
*/
/* 104 bytes of memory have been
reserved somewhere in the memory,
whose starting point i.e. address is being
recorded by root pointer.
*/
/* Copying the value of z.a into
root->a, i.e. to some other location. */
/* Initialisiing root -> b to zero
*/
/* Initialising prev to root
*/
/* End of if.
*/
/* else part of if.
*/
/* Starting point of else
*/
/* 104 bytes of memory have been
reserved somewhere in the memory,
whose starting point i.e. address is being
recorded by new pointer.
*/
/* Copying the value of z.a into
new->a, i.e. to some other location. */
/* Initialisiing new -> b to zero
*/
/* Initialisiing prev -> b to new
*/
/* Initialising prev to new
*/
/* End of else.
*/
/* End of abc function.
*/
/* Creating pqr function.
*/
/* Starting point of pqr function.
*/
/* While loop with condition.
*/
/* Starting point of while loop.
*/
/* Printing the value of a pointed currently
by root pointer.
*/
/* Initialising root with the value of b of
the structure currently pointed
by root.
*/
/* End of while loop.
*/
/* End of pqr function.
*/

Since this is a structure tag, no memory gets allocated. Then we say;


struct zzz z, *root, *new, *prev;
This means that root , new, prev are variables (pointers) that point to structures
that look like zzz. Since these are global variables, all 3 are initialized to zero.

MSc. In Software

17

We have : char a[100];


Thus, a is an array that is 100 large. Then we have
main()
{
gets(z.a);
while (strcmp(z.a,QUIT))
gets(z.a) is used to accept input from the user. Whatever the user type is stored
into the array z.a. Then we have:
while (strcmp(z.a,QUIT))
When the user types QUIT strcmp becomes true and we exit from the while
loop. Till such time all the input from the user is stored into the array z.a and the
while loop is executed. Within the while loop we have:
while (strcmp(z.a,QUIT))
{
abc();
gets(z.a);
}

Thus, till the time the user types QUIT, the while loop is executed, meaning the
function abc() is called. Within the loop also we have gets(z.a) which allows the user
to keep typing characters(until such time as QUIT is typed)
When he user types QUIT, function pqr() is called . Now its time to peep into the
function:
abc()
{
if (root = = 0)
{
root = malloc(104)
strcpy(root -> a,z.a);
root->b=0;
prev=root;
}
else
{
new = malloc(104);
strcpy(new->a,z.a);
new->b = 0;

MSc. In Software

18

prev->b = new;
prev = new;
}

If the user types 10 words before typing QUIT, abc() gets called 10 times. Within
abc() we have:
if (root = = 0)
root is a global variable. Hence the first time abc() is called , we know for sure that
root is definitely zero. Hence the if statement becomes true and we have:

root = malloc(104);
Thus malloc allocates 104 memory locations starting from 100 (assumption, as in
Fig 6.6) . root now has the value 100. since root points to a structure that looks
like zzz, root gets the members of zzz. Thus we have as in Fig 6.7:

Then we say:
strcpy(root->a,z.a);

MSc. In Software

19

This means that we are copying the contents of the array z.a into locations starting
from 100. Thus, if the user types Hello it would be stored as Fig 6.8;

Then we say;
root -> b = 0;
Thus Fig 6.8 transforms into Fig 6.9

MSc. In Software

20

Next, suppose the user types Bad. At this point root is not 0, it is 100. Thus the
if statement is false, the else will get executed. Here we have:
new = malloc (104);
malloc allocates 104 memory locations starting from 300 (assumption) . Thus new
points to the start of these 104 locations, i.e. 300 . Now we have:
strcpy(new->a,z.a);
thus Bad is now stored into the first member location of new. Pictorially as in
Fig 6.10:

MSc. In Software

21

Like before we say;


new-> b = 0;
Thus we have as in Fig 6.11:

We now realize that the words Hello and Bad get stored in two separate areas of
memory. How could that be done? In the if statement we say:
prev = root;

MSc. In Software

22

This means prev now has the value 100. prev is a pointer. Thus by saying this we
have now made prev and root point to location 100. Thus as shown in Fig 6.12:

In the else part of the code we include:


prev-> b=new;
What have we accomplished by doing this? Look at the above statement carefully
prev is 100. Thus we are saying:
100->b=new;
new is 300. Thus:
100->b = 300;
Diagrammatically (Fig 6.13):

MSc. In Software

23

Then we say;
prev=new;
Now we have ensured that prev points to 300. Why? Read on
Next suppose the user typed Good. root is 100, hence the else part of the code
is executed . Here again 104 locations are allocated by malloc(). new points to the
start of these locations (say 500) Due to the statement.
strcpy(new->a,z.a);
new->b=0;
Good gets stored as follows( as shown in Fig 6.14):

MSc. In Software

Then again we say;


new->b=0;
Thus as in Fig 6.15:

24

MSc. In Software

25

prev ->b=new;
This is equivalent to saying
300->b=500;
300 is the address of the last word the user typed.
So, by putting the address of the place where the last word is stored, we have been
able to successfully line the separate area of memory. Thus the link list is formed.
Refer Fig 6.16.

Are we forgetting something? Yes! What about the function pqr()? It looks like this:
pqr()
{

while (root!=0)
{
printf(%s\n, root->a);
}

}
When is pqr() called? When the user types QUIT and we exit out of the while loop
of main(). Thus when C enters pqr() the value of root, in our case will be 100.
Thus the while loop is executed. Within the while loop we have:
printf(%s\n, root->a);

MSc. In Software

26

root = root->b;
This printf displays the content of location root->a, i.e. 100->a, i.e. Hello.
Next we say:
root= root->b;
Thus the value of root now becomes 300. This is not equal to zero. Hence the
while loop is executed again. The Bad gets displayed and root gets the value
500. This causes Good to be displayed. Now the value of root->b, i.e. 500->b is
0. We exit out of the while loop and the output is :

Hello (this is what the user types)


Bad
Good
QUIT (this marks the end of input from the user)
Output of program 6.8
Hello
Bad
Good

Summary
Structures are the collection of different data members. There is no limit of the
number of data members in a structure. In a program you can have more than one
structure. There is also a concept of structure tag. In this case a structure gets
declared, but no memory location is allocated for that structure.

# How To Access Structure Members


Generally a dot (.) is used between the structure name and the variable name to access the
data. In case of a pointer to a structure an arrow (->) is used in between the pointer to the
structure and the variable name.
Structure within structure or nested structures are also possible. To know more about nested
structure visit our WEBSITE.

# Unions
Unions are different type of structures. Size of a union is not the summation of the
size of all its data members. The size of the union is defined as the size of its biggest
member. Apart from this difference union is same in all respect to a structure.

MSc. In Software

27

Link list

Link list is the real application of structure. We have discussed here a simple link list.
Double link list and binary tree are also a part of this link list. To know more about it
visit out WEBSITE.
Zee Interactive Learning System

MSc. In Software

7
File Handling
Main topics covered

!
!

!
!
!
!
!
!
!

Why do we need a file


How Copy Command Works
file pointer
Modes
Trapping Errors
Line Copy
fseek()
beginning of the file.
current position .
end-of-file.
rewind()
fprintf() & fscanf()
atoi()
Reading a file and displaying it on the screen
Editing a File
The importance of binary mode
Summary

MSc. In Software

Why do we need a file?

ou are now a master of writing programs. Try to understand what all these
programs are doing for you. After writing a very right and long program what do
you really expect from it? When you run your program in most of the cases it
asks for some input from you, which you honestly keyed in and it faithfully shows the
desired output on the screen. Once your computer is off all the data is lost. Dont you
want to store all these data in a file so that you can get it anytime you desire? So, read
the concept of files.
The simplicity of file input-output in C lies in the fact that it essentially treats a file as a
stream of character. Functions are available for single character as well as multiple
character input-output from/to files.

How Copy Command Works


Program 7.1
#include<stdio.h>
main()
{
FILE *fp1,*fp2;
fp1 = fopen(a.dat,r);
fp2 = fopen(b.dat,w);
}

/*
/*
/*
/*
/*
/*
/*

Standard input output header file.


main function.
Starting point of main function
Declaring FILE type pointer.
Opening a file in read mode.
Opening a file in write mode.
End of main function.

*/
*/
*/
*/
*/
*/
*/

No need of explanation for first two lines. Then we have,


FILE *fp1,*fp2;
*fp1 and *fp2 are called file pointers. They are of type FILE.
We already possess some information of header files. The header file stdio.h also
contains the declaration of a structure called FILE. The structure FILE contains all
information about a file to enable your C programs to perform I/O easily.
This FILE is a structure. The declaration is as follows:
struct
{
int_cnt;
char *_ptr;
char *_base;
short _flag;
char _file;

MSc. In Software

}FILE;
Here,

_cnt
_*ptr
_*base
_flag
_file

Refers to the number of bytes left in the buffer.


Is a pointer to the current buffer position.
Is the pointer to the beginning of the buffer.
Is the mode in which the file is opened.
Is the file descriptor number.

As you see, the structure contains all the information that your program would need to
know about any file. If you wish to handle a file in your C program, you would first
declare a pointer of type FILE. We will refer this as file pointer. The pointer to the
FILE is like any other pointer to a structure. It is thus possible for you to access the
contents of this structure FILE, using the pointer. However, the standard I/O library
takes care of this by making its use transparent to you.
A word that is not new, yet unfamiliar is perhaps buffer. In the first chapter we have
already dealt with buffer. Let us examine this again.

Buffer
A buffer is a location in memory that gets created when one of the I/O functions like
fopen() opens a file. Any kind of further reading or writing to the file from that point
onwards happens using this buffer. Buffering is a feature provided by standard I/O
library to increase I/O efficiency.
Assume that you have file of size 1K, and you are reading from the file character by
character. This means there will be total of 1024 reads or disk accesses. This certainly
is an overhead and slows down the program considerably.
The stdio.h header file defines a constant BUFSIZE, the value of which is ideal for I/O
in your system. This size is normally 1k (1024 bytes).
With buffering, the access is such that BUFSIZE number of characters is read into the
buffer from the file every time. If your program needs one character at a time, it picks
it up from the main memory. As there has been only one disk access for BUFSIZE
number of characters, I/O speed increases.
For more details refer our WEBSITE zeelearn.com
So, again from,
FILE *fp1,*fp2;
Here, *fp1 and *fp2 are two pointers. These pointers are of type FILE. FILE is a
structure in C-language. With the help of these file pointers we can easily access
the components of FILE structure and thus we can read from a file and write also to a
file.

MSc. In Software

fp1 = fopen(a.dat,r);
fopen is a function of C-language. It opens a file in the appropriate access mode. In
our case we are opening a file called a.dat in the read mode.
fp2 = fopen(b.dat,w);
This line is identical to the above line except the mode. We have changed r with
w to ensure that we want to open the file b.dat in the writing mode.
There are few more modes like this.

Modes
a Append mode.

r+
Mode

Read

The append mode allows data to be added at


the end of the file, without erasing the existing
data. Therefore, to add data in the existing
data files, the append access mode is used.
However, if a file by the specified name does
not exist, the file gets created.

Write The r+ mode allows editing of existing data.


Later on we will discuss it in detail.

W+ Write + Read This mode operates in the same manner as the


Mode
w mode, except that it allows data to be read
back after it is written.
a+ Read + Append This mode allows the existing data to be read,
Mode
and new data to be added to the end of the
file.
rb Reading
binary file.

of

a In case of a binary file you have to write a b.

If you run this program nothing will happen actually. It is always advisable to create
two file named a.dat and b.dat before you run this program.
Now, to continue with your copying program read on.
Program 7.2
#include<stdio.h>
main()
{

/* Standard input output header file. */


/* main function
*/
/* Starting of main function.
*/

MSc. In Software
char c;
FILE *fp1,*fp2;
fp1 = fopen(a.dat,r);
fp2 = fopen(b.dat,w);
while(c = fgetc(fp1))
{
fputc(c,fp2);
}
fclose(fp1);
fclose(fp2);
}

/* Declare a character type variable called c */


/* Two file pointers already explained */
/* Opening a file called a.dat in read mode . */
/* Opening a file called b.dat in write mode. */
/* While loop with condition. As long as
this condition remains true, the loop
will continue.
*/
/* Starting point of the while loop.
*/
/* Another function of C world, functionality
will be explained later.
/* End of while loop.
/* Closing a file represented by *fp1.
/* Closing a file represented by *fp2.
/* End of main function.

*/
*/
*/
*/
*/

You met two more new functions i.e. fgetc() and fputc() here. If you remember the
function getc() and putc() in the first chapter, your life is easy. These new functions
behave exactly the same way. The only new part is the prefix f. Since in this chapter
we are dealing with files, this prefix is quite reasonable. So let us start a detail
explanation from line 7.
while(c = fgetc(fp1))
Let us start from the innermost part of it. We repeat here fp1 stands for file a.dat.
So before you run and enjoy the program it is very essential that you create a file
called a.dat in your working directory. Write any small line or your name in this file
and save it. fgetc() will pick up the first letter from your file (a.dat) and store it in c,
the character type variable you have defined. We will come back to the while part
later.
fputc(c,fp2);
Here again fp2, the file pointer stands for the file b.dat. You really do not need to
create this file. Since you have opened b.dat in write mode, if b.dat does not exist,
our program will create this file in your working directory. The duty of fputc() is to
put whatever c contains in file b.dat.
Going back to while part of it, this process continues as long as data is there in the
file a.dat. So, in this way the whole contains of a.dat comes to b.dat. Yes!! You
now know how our favourite copy command works.
Do the whole process on your own and see how it works.

Trapping Errors

MSc. In Software

Sometimes you may face some sort of problem in opening up a file with fopen().
There could be a lot of reasons for that. So, you like to know whether your fopen() is
successful or not.
Program 7.3
#include<stdio.h>
/* Standard input output header file.
*/
main()
/* main function
*/
{
/* Starting of main function.
*/
char c;
/* Declare a character type variable called c*/
FILE *fp1,*fp2;
/* Two file pointers already explained
*/
fp1 = fopen(a.dat,r);
/* Opening a file called a.dat in read mode */
fp2 = fopen(b.dat,w);
/* Opening a file called b.dat in write mode */
if(fp1 == NULL)
/* Testing condition.
*/
printf(The file a.dat is not opened properly);
/* If the testing condition is true, this line
will get displayed.
*/
while(c = fgetc(fp1))
/* While loop with the testing condition as true
and at the same time fgetc() picks up characters one
by one from file a.dat and stores the same in c for
each cycle of the loop.
*/
{
/* Beginning of while loop.
*/
fputc(c,fp2);
/* Putting the value stored in c into the
second file.
*/
}
/* End of while loop.
*/
fclose(fp1);
/* Closing file a.dat.
*/
fclose(fp2);
/* Closing file b.dat.
*/
}
/* End of main function.
*/
In this program we have added only one more condition. You can do a similar checking
for the second file. When you are trying to open a damaged file or a file that does not
exist, fopen() sends back a null value called NULL. NULL is a word that C- language
understands.

Line Copy
The earlier example of the file-copy program to copy the file a.dat to b.dat can be
rewritten such that the contents of a.dat are copied to b.dat, line by line. Read
on.
Program 7.4
#include<stdio.h>
main()
{
char c[181];
FILE *fp1,*fp2;

/* Standard input output header file


/* main function
/* Starting of main function
/* Declare a character type array called
c of length 181
/* Two file pointers already explained

*/
*/
*/
*/
*/

MSc. In Software
fp1 = fopen(a.dat,r);
/* Opening a file called a.dat in read mode
fp2 = fopen(b.dat,w);
/* Opening a file called b.dat in write mode
while ((fgets(c,181,fp1)) != NULL)
/* While loop with a condition as well as
a function. As long as this function provides
a true value, the loop will continue.
{
/* Starting point of while loop.
fputc(c,fp2);
/* Putting the content of c into the second
}
fclose(fp1);
fclose(fp2);
}

/* End of while loop.


/* Closing a.dat.
/* Closing b.dat.
/* End of main function.

7
*/
*/

*/
*/
file.
*/
*/
*/
*/
*/

Remember array. The size of the array is 181. Here we have used 181 supposing that
180 is the maximum length of the line to be copied. This is because fgets() actually
reads one character less than the number specified and adds a \0 (NULL) at the end
of the string. However, if a new line character (\n) is encountered before the
specified number of characters are read, fgets() puts the NULL (\0) after the new
line character (\n).So to use the fgets() function, the maximum length of the line
must be known.
So what happens? In the array c[181] the whole line gets copied and with the help of
fputc() the full line is written into b.dat. The while loop continues till a.dat gets
over.
Write your own program and test it out.

fseek()
Although a number of input-output functions have already been discussed, there are
still few more functions. One of them is fseek(). To understand the functioning of
this function read these few lines.
An input or output operation on a file results in shift in the current position on the
file. The current position on a file is the next byte position from where data will be
read in an input operation or written to in an output operation. The current position
advances by the number of bytes read or written. When the file is open, the current
position of the file is 1, i.e. the beginning of the file. A current position beyond the
last byte of the file indicates end-of-file.
The function fseek() is used for repositioning the current position on a file opened
by the function fopen(). The syntax of the function is
x = fseek (file-pointer, offset, from-where);
where,

MSc. In Software
int x

is the value returned by the function fseek ().


If successful, it returns 0. Otherwise it returns 1.

FILE file-pointer
long offset

is the pointer to the file.


is the number of bytes that the current position will shift on
a file.

int from-where

is the position on the file from where the offset would


be effective. Three values it can take.

0
1
2

offset is effective from the beginning of the file.


offset is effective from the current position .
offset is effective from end-of-file.

We repeat when a file is opened for input/output, the current position is 1.


Enough of reading. Do a small exercise.
Program 7.5
#include<stdio.h>
main()
{
FILE *fp;
int i;
fp = fopen(z.txt,r);
i = fgetc(fp);
printf(%d..%c\n,i,i);
fseek(fp,3,0);
i = fgetc(fp);
printf(%d..%c\n,i,i);
fseek(fp,7,0);

i = fgetc(fp);
printf(%d..%c\n,i,i);

/*
/*
/*
/*
/*
/*

Standard input output header file. */


main function.
*/
Starting point of main function.
*/
Declaring a file pointer.
*/
Declaring a variable
*/
Opening a file called z.txt in
read mode.
*/
/* Picking up one letter from the
file, z.txt and storing it in i.
*/
/* Displaying ascii value and
character picked up from the file.
*/
/* Placing the file pointer on the
fourth character from the beginning since
C starts counting from 0.
*/
/* Getting that character into variable i
*/
/* Displaying ascii value and
character value of the character
picked up from the file.
*/
/* Placing the file pointer on the
eighth
character
from
the
beginning since C starts counting
from 0.
*/
/* Getting that character into variable i.
*/
/* Displaying ascii value and

MSc. In Software

fseek(fp,0,0);

/*

fseek(fp,4,1);

/*

i = fgetc(fp);

/*

printf(%d..%c\n,i,i);

/*

fseek(fp,3,1);

/*

i = fgetc(fp);

/*

printf(%d..%c\n,i,i);

/*

fseek(fp,-4,1);

/*

i = fgetc(fp);

/*

printf(%d..%c\n,i,i);

/*

fseek(fp,0,1);

/*

i = fgetc(fp);

/*

printf(%d..%c\n,i,i);

/*

fseek(fp,-2,2);

/*

i = fgetc(fp);

/*

printf(%d..%c\n,i,i);

/*

character value of the character


picked up from the file.
*/
Positioning the file pointer at the
first byte of the file.
*/
Shifting the file pointer four
bytes from the current position of
the file pointer.
*/
Getting the right hand side
character of the character pointed
by the file pointer into variable i.
*/
Displaying ascii value and
character value of the character
picked up from the file.
*/
Shifting the file pointer three bytes
in the right hand direction from
the current position.
*/
Getting that character into variable i.
*/
Displaying ascii value and
character value of the character
picked up from the file.
*/
Shifting four positions from the
current position in the backward
direction.
*/
Getting the right side character of
the character pointed by the file
pointer into variable i.
*/
Displaying ascii value and
character value of the character
picked up from the file.
*/
Placing the file pointer one byte
from the beginning of the file. */
Getting the right hand side
character of the character pointed
by the file pointer into variable i.
*/
Displaying ascii value and
character value of the character
picked up from the file.
*/
Placing file pointer two
bytes backward from the end of
the file.
*/
Getting a character which is at
the right side of the character
pointed by the file pointer into the
variable i.
*/
Displaying ascii value and

MSc. In Software

10

character value of the character


picked up from the file.
*/
/* End of the function.
*/

For this program you need to create a file z.txt.


In this file enter ABCDEFGHIJK. Follow our direction then it will be easier for us to
explain and for you to understand.
Just to help us understand we will write:

These numbers are not to be included in the file. We have numbered the characters
contained in the file starting from 0 to 11, to help us understand better.
fp stands for file z.txt which is open in read mode. You can assume that at any
given time there is one number that is active in the memory. When you say, fopen()
it is the first byte of the file. Thus, this can be called as a file pointer. (This file
pointer has nothing to do with *fp). This program lets you move the file pointer to
anywhere in the file, to the beginning, to the end or anywhere in between. Now when
you say:
i = fgetc(fp);
fgetc() will ask about the file pointer. The answer is on the first byte of the file. So,
the printf will display:
65.. A
fgetc() does not stop at this. It now moves the file pointer to the next member of
the file, which is B.
Next we have:
fseek(fp,3,0);
fseek() is a function. When C sees 0 in fseek () it doesnt ask where the file
pointer is. As far as C is concerned it does not matter. It will consider the file
pointer to be at the first byte of the file. It looks for other number, which in our case
is 3. The 3 means move the file pointer by 3 positions from the first byte of the file.
Thus effectively we move the file pointer to byte number 4 of the file (Remember C

MSc. In Software

11

starts numbering from 0). Thus the file pointer will be at D. In the next two
statements:
i = fgetc(fp);
printf(%d..%c\n,i,i);
i gets the ASCII value of D i.e. 68 and the following printf displays
68..D
fgetc() now moves the file pointer to the next number, i.e. E.
Craving for more examples? Here it goes. The next statement says:
fseek(fp,7,0);
Should not be difficult to figure this statement. As before, 0 means it doesnt matter
where the file pointer is. Just pick the eighth number from the file. The next two
lines are:
i = fgetc(fp);
printf(%d..%c\n,i,i);
Thus i becomes 72 and printf displays:
72..H
The file pointer now points to the next member, i.e. i
In the next statement:
fseek(fp,0,0);
We are getting the file pointer back to member 0,i.e. to the beginning of the file.
fseek(fp,4,1);
i = fgetc(fp);
printf(%d..%c\n,i,i);
Aha! time to pay attention. This fseek() means move the file pointer by 4 positions
from the current position. Whenever C sees a 1 in the fseek() it wants to know
where the file pointer is. In our case the file pointer is on the first byte i.e. on A.
Thus the file pointer will go to the position E. So, in the output we will get
69..E
The file pointer now points to F.

MSc. In Software

12

Next 3 statements are:


fseek(fp,3,1);
i = fgetc(fp);
printf(%d..%c\n,i,i);
This time the file pointer moves by 3 positions from the current position. So, we
will get
73..I
fgetc() makes sure the file pointer now points to J.
The next statement is:
fseek(fp,-4,1);
-4 Hmmmm. What does that mean? If you notice, the file pointer so far has
been moving only in one direction, i.e. forward. The minus reverses this. This fseek ()
causes the file pointer to move 4 positions in the backward direction, relative to the
current location of the file pointer. Since the file pointer points to j, 4
positions back will make it point to F. The next two statements:
i = fgetc(fp);
printf(%d..%c\n,i,i);
Prints
70..F
fgetc() is still adamant on moving the file pointer to the next number in the
forward direction. Thus the file pointer is now on G.
The next statement seems tricky but is simple enough.
fseek(fp,0,1);
This fseek() instruct C to find out where the file pointer is and moves it by 0
position, i.e. dont move it at all. Thus when C encounters the next 2 statements
i = fgetc(fp);
printf(%d..%c\n,i,i);
It displays:
71.. G

MSc. In Software

13

More permutations and combinations are left for you to explore.

rewind()
One more useful function in this context is rewind ().
This function is used to bring the file pointer to the beginning of the file i.e. after
this function the current position of the file pointer becomes 1.
The syntax is
rewind(file-pointer);
Where file-pointer is the pointer returned by the function fopen().

fprintf() & fscanf()


Now a few words on formatted input and output. In introduction to programming we
have discussed thoroughly, the meaning of formatted input and output. But at that
time we were only interested in standard input and output devices i.e. keyboard and
monitor. Now we are dealing with the data transfer between two files. There we had
two standard functions e.g. scanf() and printf() . In case of file input output these
functions become fscanf () and fprintf ().
For the syntax of these two functions read this.
Program 7.6
#include<stdio.h>
main()
{
FILE *fp;
fp = fopen("x.txt","w");

/* Standard input output header file.


/* Creating main function.
/* Starting point of the function.
/* Declaring a file pointer.
/*Opening the file x.txt in the writing

fprintf(fp,"%d -- %d",10,12);
fclose(fp);
}

/* Usages of fprintf.
/* Closing the file referred by fp.
/* End of the function.

*/
*/
*/
*/
mode.*/
*/
*/
*/

In this example, we are opening a file named x.txt in the write mode. Then, we are
writing two numbers in a formatted way in this file. For this reason, i.e. writing
something in a formatted way in a file we need fprintf (). After running the program,
if we open the file x.txt, we will get the desired output.
Output of program 7.6
10 - - 12

MSc. In Software

14

atoi()
Next we write a program and name it cc.c
Program 7.7
#include<stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
int i;
i = atoi(argv[1]);
printf(%d\n,i);
printf(%s\n,argv[1]);
}

/*
/*
/*
/*
/*
/*
/*

Standard input output header file


main function with two arguments
Data type of the first argument
Data type of the second argument
Starting point of main function
Declared a local variable
Initialising i with the int value of
first argument
/* Displaying the value of i
/* Printing the first argument as it is
/* End of the program

*/
*/
*/
*/
*/
*/
*/
*/
*/
*/

Run this program by saying: cc 123


When we press enter here, C allocates memory for cc.exe. The important question
that we need to ask ourselves is, how will it allocate memory for the first argument
123?
Now, look at this statement,
i= atoi(argv[1]);
The memory location of the first argument, i.e. argv[1] i.e. 123 is assumed to be
location/address 100. So, C goes to location/address 100 and multiplies the contents
of the memory locations as follows:

MSc. In Software

15

In command line arguments everything is treated as ASCII. Also, the arguments are
considered as strings. Thus 123 gets stored as 49 50 51 0 (since ASCII values of
1,2,3 are respectively 49, 50, 51).( Refer Fig 7.2.)
Arent you curious how this ASCII representation is converted to the actual value? Very
simple, C does,
49 48 = 1
1* 100 = 100

50 48 = 2
2 * 10 = 20

51 48 = 3
3*1=3

Adding all these numbers we get 123. But why all the fancy multiplication? The reason
for this is that atoi() converts a number that looks like a string into an actual number.
Understand a subtle difference. When you say,
i= 123;
Assuming that i is stored at location 500 we have (Fig 7.3),

Thus there is a difference when 123 is stored as a string and when it is stored as a
number. We have specified 123 as a string, but we want to convert it into an actual
number. Hence we use atoi().

Reading a file and displaying it on the screen


Read this program.
Program 7.8
#include<stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
int i; int j=1;

/*
/*
/*
/*
/*
/*
/*

Standard input output header file


*/
main function with two arguments
*/
Data type of the first argument
*/
Data type of the second argument
*/
Starting point of main function
*/
Declaring a file pointer
*/
Declaring two variables and initializing one*/

MSc. In Software
fp = fopen(argv[1],rb);
while(( i == fgetc(fp)) ! = -1)
{
printf(%c,i);
}
}

16

/* Opening the first argument in binary


read mode
*/
/* while loop, the condition means until EOF */
/* Starting point of while loop
*/
/* prints each character of the opened file
*/
/* End of while loop
*/
/* End of the program
*/

We are opening this file in the binary read mode. Why we are so interested to open it
in the binary mode will be clear a little later.
You name this program as aaa.c. When you run this program by saying:
aaa z.c
This will print the contents of file z.c on the screen.

Editing a File
Write this program and call it bbb.c
Program 7.9
#include<stdio.h>
main(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
int i; int j;
i = atoi(argv[1]);
j = atoi(argv[2]);
fp = fopen(argv[3],r +b);
fseek(fp,i-1,0);
fputc(j,fp);
}

/* Standard input output header file


*/
/* main function with two arguments
*/
/* Data type of the first argument
*/
/* Data type of the second argument
*/
/* Starting point of main function
*/
/* Declaring a file pointer
*/
/* Declaring two variables
*/
/* Converting first argument into integer
*/
/* Converting second argument into integer */
/*Opening third argument in binary edit mode*/
/* Putting file pointer in a specific position */
/* Changing the content of the file by
second argument
*/
/* End of the program
*/

To run this program, at the command prompt we type,


bbb 2 65 z.txt
bbb has 3 parameters (2,65,z.txt). Thus when we say,
i = atoi(argv[1]);
argv[1] refers to 2. The atoi() converts this string 2 into an actual number and
stores this number into i. Similarly, when we say,

MSc. In Software

17

j = atoi(argv[2]);
argv[2] refers to 65. As before, atoi() converts this string 65, into an actual
number 65 and stores it in j.
Next,
fp = fopen(argv[3],r +b);
The third argument is z.txt. Thus we are opening the file z.txt. r+b means we
are opening a file in editing ( read/write ) binary mode.
To understand the next statement,
fseek(fp,i-1,0);
we assume that the file z.txt consists of ABCD. Thus,
what we write:
How it stored:
How C numbers the bytes:

A
65
0

B
66
1

C
67
2

D
68
3

Our aim is to replace the B of file z.txt with A. As shown, B is the second byte of
the file z.txt and hence has number 1. The value of i is 2. Thus to access B in file
z.txt we say,
i 1.
In the next statement,
fputc(j,fp);
We replace the second byte of z.txt B with j, i.e. 65 i.e. A.
Hence we get the desired output,
AACD

The importance of binary mode


Now, we suddenly have an intense desire to reuse code. After all, we have written so
many programs so far. There is no law that prevents us from reusing our code.
Before we venture into reusing our code, we need to change z.txt. Make it look like
this:
Hello (Press enter)

MSc. In Software

18

Hi (Press enter)
We have put 9 bytes into the file z.txt. These bytes are,
H e l l o (enter) H i

(enter)

What we want to demonstrate here is that each time we press enter, internally, two
numbers, 13 and 10 are added to the file. Thus, the file z.txt will in fact be 11 bytes
large. Thus (as shown in Fig 7.4),

What happens when we press enter? The control goes to the beginning of the next
line. Here 13 means move the cursor to the beginning of the line. 10 means move
the cursor one line down.
Now, type this at the command prompt,
aaa z.txt
This will faithfully display,
Hello
Hi
Now type,
bbb 6 32 z.txt
Remember bbb.c, the program you have written earlier.
What we are saying here is to replace the sixth byte of file z.txt with a space. (32 is
for space). The sixth byte in our file is 13, which is responsible for taking us to the
beginning of a line. Thus when we say:
type z.txt
we get
Hello_
_Hi

MSc. In Software

19

(We have used _ to represent a space).


Note, that we have not touched 10. Hence we move to the next line but do not go the
start of the next line. (because 13 is now replaced by a space.)
Then we restore normalcy in our file by saying,
bbb 6 13 z.txt
We are putting 13 back as the sixth byte of file z.txt. Check it out by typing
type z.txt.
Then we try this stunt,
bbb 7 32 z.txt
Again type
type z.txt
You will get a funny looking word. How in the devils name did this happen? What we
did was replace the seventh byte of the file with a space. The seventh byte was 10,
whose responsibility was to take us to the next line. By replacing 10 with a space we
are writing to the same line. Thus the H of Hello is replaced by a space, the e of
Hello by H of Hi and the first l of Hello is replaced by i of Hi.
Output:
_Hilo
(Again _ represent a space)
It is a long story but you realize that 10 and 13 have a special status, i.e. C associates
these numbers with a particular action each time they are encountered. Now, we are
not saying if thats good or bad. What we should be concerned is whether there is a
way to nullify or neutralize the special status of these characters. So, read the next
program.
Program 3.10
#include<stdio.h>
main()
{
FILE *fp;
int i, j;
j = 0;
fp = fopen(z.txt,r);
while((i = fgetc(fp)) != -1)

/*
/*
/*
/*
/*
/*
/*
/*

Standard input output header file


Creating main function
Starting point of main function
Declaring a pointer of type FILE
Declaring two variables
Initialising one variable
Opening a file in read mode
Continue the loop until EOF

*/
*/
*/
*/
*/
*/
*/
*/

MSc. In Software
{
j++;
printf(%d\n,i);
}
printf(j = ..%d\n,j);
}

20

/* Starting point of while loop


*/
/* Incrementing j in each cycle, meaning
by counting the number of bytes
*/
/* Printing all the letters of the file
*/
/* End of while loop
*/
/* Giving the total number of bytes in the file*/
/* End of the program
*/

Here, j counts the number of bytes in the file and i tells you what those bytes are.
Again modify your z.txt and make it look like
ABC(enter)
DE(enter)
So, you have practically entered,
65 66 67 (13 10) 68 69 (13 10)
Now run the above program.
The output you will get,
65
66
67
10
68
69
10
j =..7
If you notice, the 13 is not there. This is because the r in the statement
fp = fopen(z.c,r);
is like a hungry beast. It eats up the 13. The result is that we have only 7 bytes
remaining in the file.
But this is not fair. You want to see the bytes of the status quo. No omission! What do
you do? You make this small change in the program.
fp = fopen(z.c,rb);
Now you run the program and you see the complete file all 9 bytes.
The b in rb is responsible for this change. The presence of rb means that the
special status associated with 13 is nullified.
The output in this case will be,

MSc. In Software

65
66
67
13
10
68
69
13
10
j= .. 9

Adventure..
Run your bbb program with
bbb 1 26 z.txt
Here if bbb.c contains
fp = fopen(z.c,rb);
and after that if we type aaa z.txt
The output will be,
65 66 67 13 10 68 69 13 10
But if bbb.c contains
fp = fopen(z.c,r+b);
Remember now we are opening it in the editing mode.
Now if we say,
bbb 1 26 z.txt
and then aaa z.txt
we will get,
26 66 67 13 10 68 69 13 10
26 stands for 1.
So if you say,

21

MSc. In Software

22

type z.txt
you will not be able to see any file as -1 stands for the end of the file.

Summary
# Why do we need a file
We need a file to store our data.
This chapter deals with file input output. Some commonly used functions for file input
output is given below.
fopen()
fclose()
fputc()
fgetc()
fseek()
fprintf()
fscanf()
feof()
remove()
rewind()

Opens a file
Closes a file
Writes a character to a file
Reads a character from a file
Seeks to a specified byte in a file
Writes formatted text to a file
Reads formatted text from a file
Returns TRUE at the end of the file
Erases a file
Resets the file pointer to the beginning of
a file

These functions are contained in the header file stdio.h.

# file pointer
File pointers are pointers of type FILE. FILE is a structure that keeps all the necessary
information about a file. For more arithmetic on file pointer visit our WEBSITE
zeelearn.com

# Modes
Since here we are dealing with files, we can understand that we have to open this file.
Now, the information that what do we want to do with this file, is given in the forms of
mode. There are different modes available in which you can open a file. Three main
modes are read mode, write mode and append mode. For more application on this
more visit our WEBSITE zeelearn.com

# fseek()

MSc. In Software

23

The function fseek() is used for repositioning the current position on a file opened
by the function fopen(). The syntax of the function is
x = fseek (file-pointer, offset, from-where);
where,
int x
FILE file-pointer
long offset
int from-where
3
4
5

is the value returned by the function fseek().


If successful, it returns 0. Otherwise it returns 1.
is the pointer to the file.
is the number of bytes that the current position will shift on
a file.
is the position on the file from where the offset would
be effective. Three values it can take.

offset is effective from the beginning of the file.


offset is effective from the current position .
offset is effective from end-of-file.

We repeat when a file is opened for input/output, the current position is 1.

# Current Position
The current position on a file is the next byte position from where data will be read
in an input operation or written to in an output operation. The current position
advances by the number of bytes read or written. When the file is open, the current
position of the file is 1, i.e. the beginning of the file. A current position beyond the
last byte of the file indicates end-of-file.

# rewind()
This function is responsible to bring the file pointer back to its first position, i.e.
beginning of the file. It takes file pointer as its parameter.

# fprintf() & fscanf()


These two functions are used for formatted output and input from and to a file. The
syntax is same as printf() and scanf() except that it takes the file pointer as the first
parameter. For example of fscanf() visit our WEBSITE zeelearn.com

# atoi()
This has been discussed in array chapter also. It converts a string into its integer
equivalent.

# atof()

MSc. In Software

This is also done in array chapter. For examples on this function visit out WEBSITE
zeelearn.com

# Editing a File
Under this heading we have discussed how can we edit a file through a program. We
have written here a C program and shown how can we replace a particular letter of a
file with another letter.

# The importance of binary mode


In binary mode the special feature associated with ENTER key can be nullified.
For more program on binary mode visit our WEBSITE zeelearn.com
Zee Interactive Learning System

24

You might also like