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

INDEX

S. No Topic Page No.


Week 1
1 Lecture 1 Part 1: Introduction 1
2 Lecture 1 Part 2 : Introduction 13
3 Lecture 1 Part 3 : Introduction 21
4 Lecture 1 Part 4 : Introduction 34
5 Lecture 2 Part 1 : Problem Solving using Computer 50
6 Lecture 2 Part 2 : Problem Solving using Computer 63
7 Lecture 2 Part 3 : Problem Solving using Computer 70
8 Lecture 2 Part 4 : Problem Solving using Computer 87
9 Lecture 2 Part 5 : Problem Solving using Computer 98
Week 2
10 Lecture 3 Part 1 : Basic Elements of Program 108
11 Lecture 3 Part 2 : Basic Elements of Program 120
12 Lecture 3 Part 3 : Basic Elements of Program 134
13 Lecture 3 Part 4 : Basic Elements of Program 144
14 Lecture 4 Part 1 : Program Design 151
15 Lecture 4 Part 2 : Program Design 157
16 Lecture 4 Part 3 : Program Design 166
17 Lecture 5 : Simple cpp Graphics 180
Week 3
18 Lecture 6 Part 1 : Conditional Execution 199
19 Lecture 6 Part 2 : Most general form of if 210
20 Lecture 6 Part 3 : More general form of conditions 216
21 Lecture 6 Part 4 : A somewhat large program example 225
22 Lecture 6 Part 5 : Switch statement and logical data 231
23 Lecture 7 Part 1 : Loops 243
24 Lecture 7 Part 2 : Mark averaging 251
25 Lecture 7 Part 3 : The break and continue statements 257
26 Lecture 7 Part 4 : The for statement 264
27 Lecture 7 Part 5 : Euclid's algorithm for GCD 279
28 Lecture 7 Part 6 : Correctness proof for GCD 290
Week 4
29 Lecture 8 : Computing Mathematical Functions Part 1 : Taylor series 300
Lecture 8 : Computing Mathematical Functions Part 2 : Numerical
30 integration 313
31 Lecture 8 : Computing Mathematical Functions Part 3 : Bisection Method 322
Lecture 8 : Computing Mathematical Functions Part 4 : Newton Raphson
32 Method 332
Lecture 9 : Loops in various applications Part 1 : Loops in various
33 applications brute force algorithms 343
Lecture 9 : Loops in various applications Part 2 : Finding Pythagorean
34 Triples 350
Lecture 9 : Loops in various applications Part 3 : Modelling a system:
35 bargaining 361
36 Lecture 9 : Loops in various applications Part 4 : Simulating a water tank 367
Lecture 9 : Loops in various applications Part 5 : Arithmetic on very large
37 numbers 376
Week 5
38 Lecture 10 : Functions Part 1 : Basics 388
39 Lecture 10 : Functions Part 2 : Examples 403
40 Lecture 10 : Functions Part 3 : Reference parameters 414
41 Lecture 10 : Functions Part 4 : Pointers 421
42 Lecture 10 : Functions Part 5 : Graphics Objects and Lecture conclusion 431
43 Lecture 11 : Recursion Part 1 : Introduction 437
44 Lecture 11 : Recursion Part 2 : Recursive objects, Tree drawing 449
45 Lecture 11 : Recursion Part 3 : How to think about recursion 464
Week 6
46 Lecture 12 : Virahanka Numbers Part 1 : Introduction 478
47 Lecture 12 : Virahanka Numbers Part 2 : Recursive Program 484
48 Lecture 12 : Virahanka Numbers Part 3 : Iterative Program and Conclusion 495
49 Lecture 13 : Program Organization and Functions Part 1 : Introduction 501
50 Lecture 13 : Program Organization and Functions Part 2 : Splitting into files 511
51 Lecture 13 : Program Organization and Functions Part 3 : Namespaces 521
Lecture 13 : Program Organization and Functions Part 4 : How to use C++
52 without simplecpp 526
Lecture 14 : Advanced Features of Functions Part 1 : Introduction and
53 passing one function to another 532
54 Lecture 14 : Advanced Features of Functions Part 2 : Lambda expressions 543
Lecture 14 : Advanced Features of Functions Part 3 : Default values to
55 parameters 553
Lecture 14 : Advanced Features of Functions Part 4 : Function overloading
56 and lecture conclusion 559
Week 7
57 Lecture 15 : Array Part-1 : Part 1 : Introduction 567
58 Lecture 15 : Array Part-1 : Part 2 : Marks averaging problem 576
59 Lecture 15 : Array Part-1 : Part 3 : Histogram computation 586
60 Lecture 15 : Array Part-1 : Part 4 : Marks display variation 594
61 Lecture 15 : Array Part-1 : Part 5 : Polynomial multiplication 608
62 Lecture 15 : Array Part-1 : Part 6 : Queues in dispatching taxis 614
Lecture 15 : Array Part-1 : Part 7 : More efficient Queues in dispatching
63 taxis 624
64 Lecture 15 : Array Part-1 : Part 8 : Disk intersection 634
Lecture 15 : Array Part-1 : Part 9 : Arrays of graphical objects and
65 conclusion 641
66 Lecture 16 : Array Part-2 : Part 1 : Introduction 649
67 Lecture 16 : Array Part-2 : Part 2 : Interpretation of aname[index] 656
68 Lecture 16 : Array Part-2 : Part 3 : Arrays and function calls 666
69 Lecture 16 : Array Part-2 : Part 4 : A function to sort an array 675
Week 8
70 Lecture 17 : More on Arrays : Part 1 : Textual data 696
71 Lecture 17 : More on Arrays : Part 2 : Functions on character strings 709
72 Lecture 17 : More on Arrays : Part 3 : Two dimensional arrays 721
73 Lecture 17 : More on Arrays : Part 4 : Command Line Arguments 742
74 Lecture 18 : Arrays and recursion : Part 1 : Binary Search Introduction 750
75 Lecture 18 : Arrays and recursion : Part 2 : Binary search analysis 770
76 Lecture 18 : Arrays and recursion : Part 3 : Mergesort overview 778
77 Lecture 18 : Arrays and recursion : Part 4 : Merge function 784
78 Lecture 18 : Arrays and recursion : Part 5 : Mergesort conclusion 791
Week 9
79 Lecture 19 : Structures : Part 1 : Definition and instantiation 800
80 Lecture 19 : Structures : Part 2 : Operations on structures 807
81 Lecture 19 : Structures : Part 3 : An example program 815
82 Lecture 19 : Structures : Part 4 : Pointers and lecture conclusion 826
83 Lecture 20 : Structures Part 2 : Part 1 : Introduction to Member functions 833
84 Lecture 20 : Structures Part 2 : Part 2 : Vectors from Physics 839
85 Lecture 20 : Structures Part 2 : Part 3 : Taxi dispatch 850
86 Lecture 21 : Classes : Part 1 : Introduction 858
87 Lecture 21 : Classes : Part 2 : Constructors 863
88 Lecture 21 : Classes : Part 3 : Operator overloading 871
89 Lecture 21 : Classes : Part 4 : Access control 881
90 Lecture 21 : Classes : Part 5 : Classes for graphics and input output 886
91 Lecture 21 : Classes : Part 6 : General remarks 893
Week 10
92 Lecture 22 : Representing variable length entities: Part 1 : Introduction 904
Lecture 22 : Representing variable length entities: Part 2 : Heap memory
93 basics 909
Lecture 22 : Representing variable length entities: Part 3 : Pitfalls of using
94 heap memory 920
Lecture 22 : Representing variable length entities: Part 4 : Automating
95 memory management 927
Lecture 22 : Representing variable length entities: Part 5 : Implementing a
96 class with automated memory management 1 936
Lecture 22 : Representing variable length entities: Part 6 : Implementing a
97 class with automated memory management 2 945
Lecture 22 : Representing variable length entities: Part 7 : Using the
98 implemented class and conclusion 952
99 Lecture 23 : The Standard Library: Part 1 : Class string 963
100 Lecture 23 : The Standard Library: Part 2 : Class vector 971
101 Lecture 23 : The Standard Library: Part 3 : Classes map and unordered_map 978
102 Lecture 23 : The Standard Library: Part 4 : Iterators 982
103 Lecture 23 : The Standard Library: Part 5 : Iterators 988
Week 11
104 Lecture 24 : Data structure based programming : Part 1 : Introduction 1000
105 Lecture 24 : Data structure based programming : Part 2 : Set and pair classes 1003
Lecture 24 : Data structure based programming : Part 3 : Implementation of
106 standard library data structures 1012
Lecture 24 : Data structure based programming : Part 4 : Composing data
107 structures 1021
Lecture 24 : Data structure based programming : Part 5 : typedef and lecture
108 conclusion 1029
Lecture 25 : Medium size programs : Part 1 : The new marks display
109 program 1033
Lecture 25 : Medium size programs : Part 2 : Manual algorithm for new
110 marks display 1039
Lecture 25 : Medium size programs : Part 3 : RSMTAB and rest of the
111 program 1054
Lecture 25 : Medium size programs : Part 4 : Sophisticated solutions to
112 marks display 1070
Week 12
113 Lecture 26 : A graphical editor and solver for circuits : Part 1 : Outline 1088
Lecture 26 : A graphical editor and solver for circuits : Part 2 : Main
114 program and organization 1093
Lecture 26 : A graphical editor and solver for circuits : Part 3 :
115 Mathematical representation of the circuit 1113
Lecture 26 : A graphical editor and solver for circuits Part 4 : Extensions
116 and concluding remarks 1130
Lecture 27 : Cosmological simulation : Part 1 : Introduction and First order
117 Euler method 1138
118 Lecture 27 : Cosmological simulation : Part 2 : Second order Euler method 1149
119 Lecture 27 : Cosmological simulation : Part 3 : The program 1160
120 Lecture 27 : Cosmological simulation : Part 4 : Concluding remarks 1179
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 1 Part - 1
Introduction
Introduction to the course and a simple program
Hello and welcome to the NPTEL course on an introduction to programming through C++. I
am professor Abhiram Ranade of IIT Bombay, and today's lecture will be an introduction to
the course, and some material will also be covered.

(Refer Slide Time: 0:33)

So here is what I am going to do today. I will begin with an introduction to computers and
computing then I will show some simple programs. I will make some remarks on
programming and then I will close with the spirit of the course.

(Refer Slide Time: 0:50)

1
Let me begin with the observation that computers are everywhere. Cars, phones, laptops,
game consoles, cameras, televisions, refrigerators, practically anything you name contains a
computer. You might have used a computer to book train and plane or bus tickets, you might
have used a computer to search the internet, predict the weather; maybe play games, lots of
things. The goal of this course is to learn how to make computers do things such as those that
we have mentioned.

(Refer Slide Time: 1:29)

So let me begin with the question - what is a computer? A computer is an electrical circuit, it
is a giant electrical circuit but nevertheless a circuit which can do the following things - It can
receive data from the external world, and by data we typically mean numbers. Now it can
receive images and sounds but as we will see these will be represented as numbers. A
computer can perform calculations on the data that it receives, and it can send the results back
to the rest of the world. Now what kind of computations does a computer perform is
determined by a ‘program’ that has to be loaded in the computer.

(Refer Slide Time: 2:12)

2
What is a program? A program really is a precise description of the calculations we want the
computer to perform. By feeding different programs to a computer, you can make it do
different calculations. And this course tells you how to construct programs or how to ‘write’
programs, which is what the process is normally called. Programs are written in a special
notation called a programming language.

(Refer Slide Time: 2:43)

In this course we are going to learn the C++ programming language. This was designed by
Bjarne Stroustrup in the 1980s, and it evolved out of the then-existing and still existing C
programming language. C++ is a very powerful and somewhat complex language. We are not
going to be studying all of it. We will study a subset of it which is still going to be much
more convenient, and in fact safer to use than C. And we will lay the foundations of learning
advanced features for later courses.

(Refer Slide Time: 3:24)


3
In this course, in the initial weeks the programming environment will be C++ augmented
with simple cpp, where, simple cpp is a C++ library developed in IIT Bombay. Simple cpp
provides facilities which are convenient for learners. For example, it allows you to do
graphics; it allows you to draw pictures. This is certainly going to be more fun and probably
learners, or beginners will appreciate it. Then, it provides an easy to understand statement
called the ‘repeat’ statement and we will see that today itself.

It will also provide a “main program” keyword which also we will see today. Simple cpp can
be downloaded from this URL shown here: www.cse.iitb.ac.in/~ranade/simplecpp. It is
available on Linux and Mac OS as a library, or as an IDE for Windows and Linux. Later
weeks of the course we will just use C++; we may not use the features of simple cpp. But, on
the other hand if you want to do graphics the features of simple cpp will definitely come in
handy.

(Refer Slide Time: 05:01)

4
We are going to be using the following textbook: the title is “An Introduction to
Programming through C++”, written by me, published by McGraw Hill Education in 2014.
Here is the web page for the book: ​www.cse.iitb.ac.in/~ranade/book.html​. It is available in
physical and online bookstores, and it is integrated with the use of simple cpp. Today's
lecture is based on chapter 1 of the book and you are recommended to read that chapter.

(Refer Slide Time: 5:44)

This course does not have many prerequisites. Well, you do need to know the science and
math of standard 11​th and 12​th​, because we will be using examples from that science and
math. No knowledge of computers is expected, you will learn all of that in this course. In
addition to lectures, we will have instructions and maybe even videos talking about use of
computers. And more than anything you need enthusiasm. You should want to do things with
computers, you should want to have fun with computers, that is really most important.

(Refer Slide Time: 6:10)

5
So, let us get on with the main business. We are going to write some very simple C++
programs. These programs are going to draw pictures on the screen, and they will use a so
called ‘Turtle Simulator’, which is contained in simple cpp. The ‘Turtle Simulator’ is based
on ‘Logo’, which is a language invented for teaching programming to children by Seymour
Pappert and others in the late 1960s. It is pretty old, but you will see it is a lot of fun and later
on in the course, you will realize that it is really an interesting and a useful set of tools.

The point of logo programming and the turtle simulator is to ‘drive’ a ‘turtle’ on the screen.
So, you will see a small triangle typically on the screen and you are going to drive it and the
way you are going to drive it is you are going to write a C++ program. The C++ program will
tell the turtle what to do.

Now the turtle has a pen, so as it moves, it will draw. So that is how you will be able to make
interesting drawings. Now you might think, are we learning the serious subject of
programming, or are we learning drawing pictures, which seems to be too much fun? But,
you will soon see, that if you master picture drawing, you will actually be mastering
programming.

6
(Refer Slide Time 7:45)

Alright, so here is the first program. So I have shown it over here. I am going to explain it
one statement at a time. So the first statement ‘include<simplecpp>’ in those funny-looking
brackets simply tells the computer, “Look, I am going to use the simple cpp facilities”. Then,
the ‘main_program’ is a keyword which says that look, what follows is the main program, so
starting from the open brace all the way till the closed brace at the bottom of the page.

Then the ‘turtleSim()’ command starts the turtle simulator. What this does is that it is going
to create a window, it will have the turtle at the centre, facing right.

Then, you see the command ‘forward(100)’, well in general this command is forward(n),
where ‘n’ can be any number. So in this case the turtle is being commanded to move ‘n’
pixels in the direction in which it is currently facing.

‘right(D), where ‘D’ is expected to be the angle in degrees tells the turtle to turn right. You
can have a similar left command as well. And ‘wait(t)’ tells the turtle to do nothing for ‘t’
seconds, so these t seconds or in this case 5 seconds are what you are given to admire the
drawing that the turtle has drawn.

7
(Refer Slide Time 10:03)

Now, let us see what drawing the turtle will actually do by looking at the program. So, this
will start the turtle simulator and it will create a window, then the turtle will move forward by
100. So the turtle moves forward 100. So if the turtle is over here and facing in this direction
it will move forward by 100 steps, then it will turn right 90 degrees, so then it will start facing
in this direction, it will then move forward 100 pixels. It will again turn right 90, then again
move forward 100 steps, then again turn right 90, and then again move forward 100 steps. So
what has the turtle drawn as the result of this? It has drawn a square of side length 100 pixels.
And after that that turtle is going to wait, and then the whole window will vanish, and the
program will come to a halt. So this is what the program is supposed to have done. And let us
see now how do we run this program?

(Refer Slide Time 10:27)

So, for that purpose we need to install simple cpp on your computer. How do you do this?
Well you have to see the instructions at this webpage. Then you have to type in the program
8
into a file or the IDE, whatever you have downloaded, and let us say you call it square dot
cpp then you have to compile it. So compilation can happen by typing s++ square dot cpp if
you installed a library on UNIX. If you installed the code blocks IDE, then you simply have
to press the compile button. Then you have to execute it. So on UNIX you have to type ‘dot
slash a dot out’, which is the result of that compilation process. So we will explain to you
what compilation means in a little bit. But, the result of the compilation process is a file
called ‘a dot out’, and you just have to execute it. On code blocks you just need to use the
Run button.

(Refer Slide Time 11:41)

So now, I am going to show you exactly how this happens and I am going to use the simple
cpp library, and I will compile the program for you. So here is the program that I showed you
earlier. This program is slightly different. So you had seen that there was a wait 5 seconds at
the end of that program, but here I have also put in these additional waits. So these waits -
0.5, 0.5 are going to tell the turtle to wait for about half a second after each forward and right
step. If I do not do that, then a computer works very fast, so the turtle will move very fast and
before you see it, everything will be drawn. And you will not really be able to see the
movement in any nice way. So therefore, we have put in these waits in these additional waits.
So this has been typed into an editor and it is now in a file called ‘square dot CPP’, the name
of the file is appearing over here as far as the editor is concerned, but you might you might
have it in your IDE.

9
(Refer Slide Time: 12:32)

So, let me now try to compile that file so for this I am going to say s++ square dot CPP. So
this will compile the file. And now I am going to execute it.

(Refer Slide Time: 12:50)

So as you can see, the red triangle appeared it drew a square and now it is gone. So this is
what that program did. And this is what you can do, you can change the program, you can
draw other things as well, as we will see soon. So you saw that program execute.

10
(Refer Slide Time 13:46)

Now, I will suggest that you become familiar with that program and maybe you change that
program a little bit. Do not make many major any major changes, but see if you can change it
so that it draws maybe a square which is 50 pixels on the side. Basically we just have to
change that 100 to 50. But do it, so that you get confidence of running something on a
computer. Likewise, a slightly bigger change is to make it draw an equilateral triangle. Well,
for an equilateral triangle, you will just have to draw 3 lines instead of 4, and furthermore, the
angles will have to be different.

For this purpose, remember that the external angles of a polygon add up to 360 degrees. And,
if the polygon is a triangle, then there are only 3 angles, and all of those exterior angles are
equal. So therefore each angle must be 120 and that should be the turning angle.

(Refer Slide Time 14: 25)

11
So, what have we discussed so far? We have discussed general information about the course,
we have talked about how to install simple cpp and, we have talked about a program to draw
a square. So we will take a break and resume in a bit.

12
An Introduction to through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 1 Part - 2
Introduction
Repeat, input-output, and some basic commands
In the last segment, we discussed some general information about the course, how to install
cpp and we wrote a programme for drawing a square.

(Refer Slide time 0:33)

So now, I am going to show you a better way of drawing a square. So here, you can see that,
we have the same first 3 lines but instead of typing in forward(10), right(90) several times, I
have put it inside a ‘repeat’ statement, a so called repeat statement. So as you can see, after
repeat there is four which tells you how many times to execute what is in the braces
following the repeat.

So basically this statement is going to execute forward(10), right(90), 4 times and after that it
is going to wait for 10 seconds. This will also draw a square but it is a nicer way to draw a
square because I do not have type it so much. Imagine if I wanted to draw a 100-sided
polygon, I would have had to type things 100 times. But with repeat statement, I can just say
repeat 100 times.

13
(Refer Slide time 1:25)

Well, what does repeat statement in do in general? And what does it look like? Its form in
general is going to be this: ‘repeat’ followed by parenthesis inside which there is going to be
a number, let us call it x and then there are these braces inside which there can be as many as
statements as you like and collectively let us call these statements yyy. So what a repeat
statement does? Well it causes these yyy statements inside the braces to be executed x times.

So we already saw an example, we had x equal to four and yyy was forward(100), right(90).
So those two statements were executed 4 times. In general ​whatever is inside those braces is
called the ‘body’ of the repeat statement and each single execution of yyy is called the
iteration. So this repeat statement causes x iterations of the body yyy.

(Refer Slide Time 2:29)

Now, we can use the repeat statement quite nicely to draw a polygon. So, here is the program
and we will execute this later, but let us just see this. So it begins with include<simplecpp>
14
and main_program as before, then we start up turtle sim and now there is a different
statement. So this statement is a ‘cout’ statement, its form is cout << ”message”.

Now cout over here can be thought of as a command but you can also think of it as the
screen. So this statement will print whatever you type after those less than less thans on the
screen. So in this case you typed “how many sides?”, so this message how many sides will go
on the screen.

After that, another statement that we have not seen: ‘int nsides’. int nsides is a rather
complicated and interesting statement. So first of all, it tells the computer “please reserve a
cell in memory for me in which I am going to store some integer value”. How to store that
value? I will tell you a little bit later, but what we are doing over here is we are reserving a
cell in memory, not only are we reserving, but we are going to tell the computer that look
from now on, if I use the term ‘nsides’ you should treat it as referring to this cell. So
essentially, I am giving nsides as the name for the cell that I just reserved.

Now you can choose the name as you wish, ok? We will see that in some later lecture and I
just want to point out over here that ‘int’ is an abbreviation of integer so you are telling the
computer that I am going to store an integer and instead of writing down i-n-t-e-g-e-r, you
just type int which is the abbreviation.

After that, there is another new statement ‘cin >> nsides’. Well what does this statement do?
Well, it commands the computer to wait until the user types in a value from the keyboard. So
the statement asks the computer to wait until a value is typed. So the user will see the
message ‘how many sides’ and therefore, the user will type a value. So this value whatever it
is, let us the user types a 10 that value 10 will come in into the computer and the cin
statement will throw it into the cell ‘nsides’ which you just reserved.

So think of ‘>>’ than as arrows and think of cin as a representing the keyboard. So this
statement is going to cause a value to flow from the keyboard to the cell in memory called
‘nsides’. Of course, this statement will cause the program to wait until you actually do the
typing. If you do not type, then the program will just wait so you should type.

After that we have the ‘repeat’ statement, but now the repeat statement has gotten more
interesting. We do not have a number inside the parenthesis, but we have the name of a cell.
So what does this mean? So it says repeat as many times as whatever is the value that is
contained in the cell nsides. So we just said that the user might have typed 10 when ‘cin >>
nsides’ statement executed. So if 10 was sitting in nsides then the loop, the body that is going
to be following will be repeated 10 times.
15
So what is in the body? Well we are going to go forward 100 and now we are going to turn
right but instead of turning right by 90 or some fixed value, we are going to turn right 360
divided by nsides. What is this 360 divided by nsides? Well it is a mathematical expression
and you are instructing the computer to evaluate this mathematical expression. So, you are
telling the computer divide 360 by whatever is contained in the variable nsides.

So, if we type 10 then nsides will contain 10, so as a result of this we will have 36 so the
computer will turn 36 degrees. Notice that if there are 10 sides to a polygon then there are 10
exterior angles, if there are 10 exterior angles, each of which adds to 360 then each angle has
to be 36. So this is exactly the angle that we need in order to draw a decagon. So this is what
this repeat loop is going to do. After that the program will wait for 10 seconds and then the
program is over.

(Refer Slide Time 7:50)

All right, so let us again see a demonstration of this. So this is the same editor and this is the
program that we just saw. So I am going to go
16 to the new program – ‘​polygon.cpp’, which is
what we just wrote. So you can see it is reserving a cell in memory called nsides and these
cells in which we store values are often called variables. And then it is turning right by 360
by nsides and the repeat loop goes nsides times. I put in a wait 5 over here whereas earlier I
had said wait 10 does not really matter.

(Refer Slide Time 8:21)

So, let us compile that programme. So this is polygon, and let us execute. So we have our
turtle, so it has asked us a question, “How many sides?” I am going to respond 10. Let me
just move this so that I can see both. So I am going to type 10, but the statement does not
work just by typing 10, I have to hit a return as well. So now, it ended up drawing a polygon.

Well there is some problem over here, that polygon was little too big and did not fit in that
window we have. Well that is not a big deal. Even if the polygon part of the polygon went
outside, the turtle knows how to come back.

(Refer Slide Time 9:18)

17
But let us just execute it one more time, so that you can see a full polygon. So this time, when
it says “how many sides?”, let me type 6. So now, it draws a hexagon and you will see that it
has turned exactly the right amount. How did it know how much to turn? Well, it turned 360
by nsides and so in that case it turned 360 by 6 which is 60 degrees. Ok, so we have seen one
more program to draw a polygon and I just now want to point out that there are many more
commands available at our disposal. So we do not have to always turn right we can turn left.

(Refer Slide Time 9:51)

And if you want to turn left through A degrees, we can say turn left A degrees. Well actually
we do not really need that left command, because if we say ‘right(-A)’, then that is really
equivalent, but just for convenience that left command is also provided.

Two additional commands are there - ‘penUp()’ and ‘penDown()’, and these respectively
cause the pen to be raised and lowered. What does that mean? Well the drawing is going to
happen only if the turtle moves while the pen is low. If you raise the pen, if you issue the
‘penUp()’ command, and then move, only the turtle will move, no drawing will be done, so
after that you need to put down the pen again by giving the ‘penDown()’ command, and only
then will any drawing happen (from that point onwards)

You can do mathematical calculations, so for example, you can use the commands ‘sqrt(x)’.
So this is going to cause the square root of x to be computed, and instead of this square root
of x, essentially that actual square root will appear and so, then you can use it directly in your
calculations.

Similarly you can use sine(x), cosine(x), tangent(x) and so on. So here ‘x’ should be in
degrees. In scientific computation it is more customary to use radians, so actually, the

18
abbreviated forms are allowed. There also are commands for arcsine, arccosine and lots of
useful mathematical functions, so for that, please see the book.

(Refer Slide Time 11:24)

Okay, so some remarks. Now, you can use commands without worrying about exactly how
they do the work. So if I write ‘sqrt(17.35)’, or indeed whatever number, it will get calculated
somehow, you do not have to worry about it. The computer knows already, how to calculate
square roots.

Similarly, when I say ‘forward(100)’, the computer already knows how to move the triangle
forward 100, so you do not have to worry about exactly in which direction it is, and so on. So
that is the point of what happens when when we talk about a command, it promises that it
will do something and you do not have to worry about how that something is actually done, it
will just happen.

(Refer Slide Time 12:12)

19
So here is a small exercise based on what we have seen so far. So draw a square of side
length 100 as before, but, on top of this, you are to draw a square obtained by joining the
midpoints of the sides of the foursquare. So now, you will have to calculate what the side
lengths of this new square are. So now, you can use Pythagoras’ theorem to determining the
length of the sides of the inner squares and then you will typically need to do a square root
calculation, but you know how to do square roots and so you can use that to decide how
much the turtle is supposed to move.

Here is another exercise, instead of drawing a straight line, draw a dash line say for example a
dash of 10 pixels, then gap of 10 pixels and so on 10 times. So what this will require you to
do, is you will have to raise and lower the pen 10 times, but, DO NOT, and I emphasize, DO
NOT write these commands 10 times, put them inside a repeat statement. So that is that is
really a very important part of saying that I know programming. One of the major things
about I know programming is that I know how to use repeat statements.

(Refer Slide Time 13:55)

So what have we discussed? We discussed the ‘repeat’ statement, which is a really important
statement which causes repeated executions of some statements which are in its body. ‘cin’
and ‘cout’ statements also we discussed, and these can be used to read from the keyboard and
to type messages to the screen. C++ has commands to compute mathematical functions as
well as lift the pen up and down. So, we will stop here for a short break.

20
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 1 Part – 3
Introduction
Program Structure and Syntax
Welcome back. In the previous segment, we discussed the following things: We discussed the
repeat statement, and the cin, cout statements and some commands to compute mathematical
functions. Actually, we also discussed the statement by which we can reserve locations or cells
in memory.

(Refer Slide Time: 0:46)

Now, in this segment, I am going to make some general remarks about C++ programs. First of
all, let me observe that a program is really a sequence of statements or commands, and it has to
be written in a particular manner. So the keyword ‘main_program’ must appear first, followed by
an open brace. After that, the sequence of statements representing the main program have to be
put in, and finally, the closing brace has to be put in.

A statement or a command is typically terminated by a semicolon. So the semicolon is the C++


equivalent of the full stop of the English language. Just as in the English language, a sentence

21
ends with a full stop, in C++ a statement or a command ends with a semicolon. And just as you
read sentences top to bottom, left to right on a page written in the English language, similarly,
C++ programs are also executed by reading the statements top to bottom and left to right.

Now, some of the statements require additional data for them to do their work. For example, if I
write ‘forward’ I need to tell the computer how much I want to move forward, so such data is
called an ‘argument’. Similarly, ‘right’ needs to be told how much angle. So this is another
argument, there can be commands which require more than one argument, and we will see them
soon. And there can be commands which do not require any argument at all. So, ‘turtleSim()’ for
example, did not require any argument, and so in that case, we just put that opening and closing
parenthesis immediately.

(Refer Slide Time: 2:53)

Often in the discussion about languages or especially programming languages the term ‘syntax’
is used. The term syntax is used to refer to the form or the grammar which the language is
supposed to follow. So syntax refers to the grammatical rules indicating how commands must be
written and the syntax of programming languages is very strict. What do I mean by that?

Well, ‘right(90)’ cannot be written in any other form. For example, you cannot write it as
right-space-90. That is not allowed, the parentheses are necessary. However, you could put a

22
space before and after the parenthesis; that is allowed. However, you cannot split the word
‘right’, so you cannot write r-space-i-g-h-t, that is not allowed. You cannot even capitalize the
‘r’, okay? So it is strict in a certain sense and you have to understand in what sense the language
is strict, and you have to adhere to it very very very very precisely.

So, ‘penUp()’, for example cannot be written as ‘penup()’, so the ‘u’ is expected to be
capitalized. Similarly, the parentheses are needed, so you cannot just leave out the parentheses.
There are other statements also which we will learn and they will also have their syntax and
programs will have to be written strictly in that syntax. You might say that look oh what is the
big difference between ‘penup’ and ‘penUp’, is not it common sense? Well it may be common
sense to you and me, but a computer requires you to be exact, so a computer will think of
‘penUp’ as something different from ‘penup’. So, if you want ‘Up’ you have to say capital up.

However, in spite of all this, there is a lot of flexibility allowed. So for example, I already said
that you can put spaces which do not split a word or split a number, so you can put a space
before or after the parentheses. In addition there are some other natural features as well. So,
wherever we say that look put a number over here, usually you will allow a numerical expression
also. So for example in a repeat or in a right rather in the right we can put an expression such as
360 divided by nsides, or it could be n, if n is the name of a variable.

So, wherever a number is going to appear you can put in the name of a cell in memory or you
can put in an expression, which depends on some values, so that kind of flexibility is there. And
also there is another flexibility which is that we talked about the repeat statement which has a
body and we said that the body consists of several statements, well one of these statements could
be a repeat statement itself.

23
(Refer Slide Time: 5: 57)

We will come to the example of a repeat inside a repeat, but let me make a few additional
remarks. So first of all I am going to tell you something called ‘comments’. Now, a program is
going to be executed on the computer, but it will also be read by people. So you might write a
program and your teacher might read it. If you are working, your boss or your colleagues might
read the program you have written, or you might write a program and it might be so good, that
you may give it to several other people, all of whom might read that program.

Now, if you write a program, it has to be understandable. So you have to you might want to say
something more in addition to the statements on it. So for this purpose, you can place something
called ‘comments’ in your program, okay.

How do you place comments? Well you can put comments between a ‘/*’ sequence of characters
and a ‘*/’ sequence of characters. So whatever appears between these two sequences will be
thought of as a comment. Alternatively, I can put ‘//’ and then I can put a comment after it and
the comment ends when the line ends. So typically, the first from is used to define a long
comment which extends over several lines, the second form is used to define a short comment
which really extends over a single line or which really put at the end of a line okay.

24
Now a comment is only meant for the human readers, and the computer completely ignores, the
computer does not care what you put in a comment.

(Refer Slide Time: 7:40)

So we had our program for drawing that polygon, so I have put two comments in this, so at the
top I have put a comment which tells who the author of that program is, and it tells the purpose
of that program. So this is usually good practice. You should put your names on programs so that
if somebody has questions, they can come and talk to you and also you might as well tell them
what is that program going to do and then over here, we did something like dividing 360 by
nsides.

A reader might look at this and say, “Look, why are they dividing 360 by nsides?” Now, if you
want to help out those readers, you can say that the exterior angle of an nsided polygon is 360 by
n. I want to draw an nsided polygon and therefore, I will turn by the angle 360 divided by n, or in
this case, nsides.

So that is how comments help, they do not help the computer but they help human readers and
you are extremely extremely emphatically encouraged to write comments. For one thing, you
will help your friends and boss and your teacher, but you will realize that you write a program
today, in a week or so you will completely forget what you have written. Maybe you look at this

25
program and ask yourself oh why did I write 360 upon nsides? To help yourself at least, put in a
comment. You will be really really grateful and this is a required good practice if you become a
professional programmer.

26
(Refer Slide Time: 9:22)

Another important practice and another part of how you write a programs is so called
‘indentation’. So here is the same program and I am going to tell you what indentation is inside
it. So, notice that at the beginning of some lines some space is inserted. So for example, before
this turtleSim, some space is there. Iin the body of the repeat there is a space which offsets it
from the repeat statement itself, so this space is called indentation. The indentation allows you to
quickly see which statements constitute the body of the repeat, or which statements are parts of
the main program. So for example, this ‘include<simplecpp>’ is not a part of the main program,
whereas all these statements are, so by offsetting, I can visually quickly know that look this is the
main program over here or I can visually quickly note that oh this is not only in the main
program, but it is also in a repeat statement inside the main program.

So you may guess the general rule if some x is inside some y, then typically you will put two
additional spaces before every line of x. So that is what has happened over here - for the body of
the repeat which is sort of supposed to be inside the repeat statement and these are the statements
inside the main program so we have put two spaces over here.

Then there is also a style that you have to master, as to how you write the opening brace and the
closing brace. So you can see that the closing brace reverts back to the old indentation. So again
it is considered extremely unfriendly if you do not use indentation. And again, for your own

27
benefit, you should use indentation because when you come back to the program it will make it
much easier for you to understand what you yourself have written. And of course indentation is
useful for human readers, but it is ignored during execution.

(Refer Slide Time: 11:49)

Now, we said that the body of a repeat itself can contain a repeat statement. So here is an
example. So we have a repeat(4) and inside that, there is a repeat(3) and a right(90) statement, so
how does this execute? Well the first rule is that whatever is inside this outer repeat is going to
be executed 4 times. So what is inside this outer repeat? Well there is a repeat(3) and a right(90),
so we are going to execute this statement 3 times, then we are going to execute this statement
once, then we are going to go back again execute thrice, execute once and so on, do this 4 times.
That is what the rule is there is no real mystery as such, so let us try to figure out what this is
doing.

28
(Refer Slide Time: 12:44)

So let us just forget one just iteration of this repeat, what is it doing? So it is going to go forward
10 steps, so let me draw that, and to begin with, let us assume that the pen is down. So here is the
turtle and it goes forward 10 pixels. At this point the pen goes up, once the pen goes up the turtle
goes again forward 10 steps, but it goes forward and this time the pen is not down so there is no
line drawn, but at this point the pen is put down again, so this finishes one iteration, what
happens in the second iteration? Again forward line is drawn again a movement is there without
any line being drawn and one more iteration a line is drawn and there is a movement again okay?
So this finishes one iteration of that repeat 3 statement.

After that we continue forward and now there is a right(90), so earlier the turtle was pointing in
this direction, so right(90) will cause it to point in this direction. So that ends an iteration of the
outer repeat. So again we start from the very beginning, so we go back to the top of the repeat(4)
and we start executing, so now we are executing the second iteration. So for the second iteration
again the repeat(3) is going to be executed, so this will again cause forward(10) and then penUp,
and forward, but this time the pen is high so that nothing will be drawn.

So that is just one iteration of the inner repeat, so one more iteration movement, one more
iteration which consists of this movement and again we come to the bottom of the repeat(4), this

29
time at the end of the second iteration. So at this point the turtle was pointing in the downward
direction, it now turns right and points in this direction.

So now one more iteration we will call again this movement forward so drawing but forward
without movement. Movement and drawing, forward without movement. Movement and
drawing, forward without movement and again we will turn right, so the turtle will start pointing
in this direction, so again it will execute forward and draw, forward without draw, forward and
draw, forward without draw, forward and draw, forward without draw. So the turtle will end up
at the same place after that it will again turn right so it will end up facing in this direction.

So, the turtle will start facing right over here, it will draw these dashed lines, turn, draw these
dashed lines, turn, draw these dashed lines, turn, draw these dashed lines and again turn and
come back to the same position and have the same orientation okay. So notice that repeat within
repeat is very very useful. Imagine, if I had wanted to draw a long line with lots of dashes, I just
have to make that repeat(100). If I wanted 100 dashes, I do not have to write 100 statements.

(Refer Slide Time: 15:47)

So again, a quick summary of what I just said in that example, in general if I have a
repeat(x){yyy statement}, it means execute ‘yyy’, ‘x’ times. Now, if ‘yyy’ itself contains

30
repeat(w){zzz}, then ‘zzz’ is executed ‘w’ times in each execution of ‘yyy’, or, in each iteration
of that outer repeat(x), this repeat(w){zzz} is going to be executed.

And in a single execution of repeat(w){zzz}, ‘zzz’ is actually executed ‘w’ times. Now I can
have as many repeats going on inside each other, or ‘nested’ inside each other. So what is the
logic there? Exactly similar.

(Refer Slide Time: 16:32)

Alright, so as a quick exercise, what do you think this program is going to do? So figure this out
yourself and only then advance forward. So, give yourself a few seconds. So I will not explain it,
but I will just show you the solution and so you can compare your answer with it. You can also
type this program in, and you can see exactly what it does.

31
(Refer Slide Time: 16:58)

So the program will print this.

(Refer Slide Time: 17:10)

So now, I want to talk about some terms which you will hear commonly when you discuss
programming. So you will hear people say that ‘control’ is at statement ‘w’, this means that the
computer is currently executing statement w. Or people talk about control flow. Control flow is
how the control moves or the order in which statements get executed. So execution starts at the

32
top and goes down and the execution is retraced if there is a repeat statement. So the control
flows over and over the body of a repeat statement.

The term ‘variable’ is also used. A variable is simply the region of memory designated for
storing some value that you need. So the nsides that we define is actually going to be called a
variable. So we said that we use a cell in memory but that cell is going to be called a variable
because we have asked for it, and we are going to store some specific kinds of values over there.
Why is it called a variable? Well, because we are allowed to change the value that we store over
there, exactly how this change happens, we will see a little bit later okay?

(Refer Slide Time: 18:32)

So here is what we discussed at this segment: we discussed the general notion of a program, we
discussed the notions of syntax and terms such as control flow, and then we made this
observation that repeat statements can be nested inside other repeat statements. So we will take a
quick break.

33
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 1 Part – 4
Introduction
About the spirit of the course, demo
(Refer Slide Time: 0:27)

In the previous segment, we discussed the general form of a program, we discussed the notions
of syntax and terms such as control flow, then we also observed that repeat statements can be
nested inside other repeat statements.

34
(Refer Slide Time: 1:16)

In this segment, we are going to take a review of what has happened, and we will answer some
questions that you might have in your minds. So for example, we have been doing picture
drawing in this lecture sequence and let me now say why we are doing picture drawing. So, let us
ask what happens in general when you solve any problem. So when you solve any problem, you
will need to do some calculations, you will need to take some actions.

Now those actions will typically contain patterns, and you will have to understand those patterns.
And a pattern might be something like a certain sequence of calculations is repeated. So what do
you do in that case? In that case you use a repeat statement. So this is a key programming
activity. The pattern in the calculation must be mirrored by an appropriate statement in the
program.

So if it is a simple repetition, then you should have a repeat statement okay. If something is to be
repeated 5 times you should not write that 5 times, but you should write a repeat statement with
repeat count 5 and put whatever is to be repeated inside the body.

Now, if you look at pictures, they also contain patterns okay and to draw interesting pictures you
need to use repeat statements competently. So, by drawing interesting pictures you are really

35
getting practice at representing patterns in your programs. And believe me, this is a really
important activity, a really important skill while writing programs.

(Refer Slide Time: 2:29)

There are some other reasons as well, so graphical input and output is actually very convenient
and useful. This is because often, our programs are about pictorial objects, and graphical output
is very important because of the adage that a picture is worth a 1000 words. Sometimes, what
you want to tell is much better expressed by a picture and by a picture I do not mean a drawing
of a square or a rectangle or a line drawing of some figure or some of a tree or a human face or
anything like that, I might mean drawing of a graph, so graphs are very common in science and
technology. So what we are learning as we learn picture drawing, is also how we are going to
draw graphs which are common in science and technology.

In fact, data visualization is an upcoming area of computer science precisely for this reason that
it is very useful in science and engineering. So really you can think of this whole exercise as a
very solid step towards understanding this whole issue of data visualization. And of course
drawing is a lot of fun. I hope you will agree with me and I certainly think you will agree with
me when I show some additional examples okay.

36
(Refer Slide Time: 3:53)

So, what is the spirit of the course? So first of all you have to learn C++ statements and concepts.
And I would like to tell you that today, already we have covered a lot of ground, even though it
might have hopefully seem like just some fun, but believe me we have done a lot. We have
understood patterns, and we have understood that when you program you need to understand
patterns. So this is one important point of the entire course - understanding patterns. We have
taken a step towards it, but this is a really important part. There can be other types of patterns
which we will see a little bit later. And as I pointed out, this is really important in all of
programming.

So, what is the goal of the course? Well if you can solve a problem by hand, possibly by taking
an enormous amount of time and doing a lot of calculations patiently, by the end of the course or
end of reading the book, you should be able to write a program for doing that. And, typically you
will see that what you take, what you need hours to calculate, the computer will do in a few
seconds. So that is really the goal of the course. Whatever you can do by hand by laborious
calculation, you should be able to do using the program.

37
(Refer Slide Time: 5:47)

And of course, there may be some things right now, some problems that you do not know how to
solve. So for some of those problems, we will also learn some problem solving techniques. One
more point about the course is that you have to understand that the computer is your friend. Do
not be afraid of using the computer. If you are thinking to yourself “what if I write x y z in my
program instead of p q r?”, do not worry about it, do not fret over it. Just do so, just write a
program just change that p q r to x y z, compile it and run, and see what happens. The computer
is not going to explode, okay?

So there is no cost to being adventurous, there is only gain, you will learn. And a very important
thing you have to realize right now is your knowledge is only good if you exercise it and how do
you exercise your knowledge? How do you say that I know C++? or how do you say that I know
programming? Well you have to write programs, that is the real test. So that is definitely the
spirit of the course, programming, practical not theory, well theory and practice okay?. So that
really is the spirit of the course. So based on what you have learned so far you can do these
exercises.

38
(Refer Slide Time: 6:51)

So for example, the first exercise asks you to draw a 5 pointed star. So let me tell you what I
mean there. So this is the star that I am talking about. So it will be drawn using 5 lines and some
turning. The question is how much turning we have to do and the hint tells you how to do that.
Now, why stop at stars with 5 corners? Why not draw 7 pointed stars? And you could also ask is
there only one kind of 7 pointed star? or are there several kind of 7 pointed stars? You should be
able to figure this out and you should be also able to draw them.

39
Now, you can also draw circles, because what is the circle after all, a circle is an n-sided polygon
in which n goes to infinity and the side length becomes really small so that is how a circle is
drawn in a computer. So go ahead and draw an n-sided polygon where n is large and you will see
that it looks like a circle.

Then this problem asks you to draw 7 identical circles such that they touch each other. So the
expected figure is something like this. My drawing is not great, but I intended these circles to
touch each other. So you can do this. And then the last one is about drawing array of tiles which
are slightly separated from each other.

(Refer Slide Time: 8:27)

This is a slightly harder exercise, you can think of this design as the design that might appear on
the border of a plate. So use your turtle to draw this. Actually you know enough program to do
this okay. So basically, you are going to have to combine the ideas that you will have learnt in
the previous exercises. So one important hint: do not give up and one more important hint: try
out whatever ideas come to your mind try out. You will see that some of them work. In fact you
will see even if the ideas do not work they may produce an interesting drawing. They may
produce a drawing which is even nicer than this, but anyway persist and get to this drawing.

40
(Refer Slide Time: 9:40)

So I am going to conclude this lecture at this time, but before that I am going to give you a demo
which shows you what kind of programs you can write at the end of the course. Some of these
programs are slightly more advanced than that, but only slightly more advanced. In any case they
are discussed in the book. So here are some of the things, so we will show you a sequence of
drawings, interesting drawings that the turtle can draw and you will learn these in the very first
few lectures. You will see an animation of cars moving on the screen, you will see animation of a
bouncing ball, then you will see a simulation of an airport, you will see some drawings of trees,
so trees and some abstract diagrams, and you will see simulation of planetary movements,
planets moving around the stars.

So this has been done by actually modeling Newton’s laws of motion, and Newton’s law of
gravitation, this is kind of the code that an astronomer would write. Well the astronomer would
write slightly more sophisticated code, but this is actually somewhat sophisticated. But you will
see that it is actually not that complicated. You know enough science and math to be able to
understand these codes, and these codes most of these codes are really very small, 20, 30 lines,
only a couple of them are slightly bigger than 100 lines. So we will stop over here, but I will
show you a demo and then the lecture will end, so hold on okay, so let us do this.

41
(Refer Slide Time: 11:02)

So, I am going to click this video, so the turtle has appeared and it is going to wait a little and
then it is going to start and it will draw the square first, so you can treat this as an exercise. How
will you draw such a pattern, okay? These expanding circles by the way, have also been drawn
using simple cpp, so again that would be a good challenge for you to draw after a little bit of this
course is over.

(Refer Slide Time: 11:28)

42
So here is the turtle executing the program which will draw the plate design okay. Now, I should
tell you that in this plate design that the pattern repeats 36 times, but when you write the
program, you should really write the program so that if I want the pattern to repeat 100 times,
you should be able to do that okay, so here is one use of computers - so a computer can
generalize. So if you, so for a human being, you may sort of take a lot of trouble and you may
draw the single pattern, but once you write a program, you can generalize it and you can write
the program so that it draws pattern with 100 such repeated figures.

(Refer Slide Time: 12:26)

So this is a curve, which is called a ‘Hilbert space filling curve’. You will see that the first
pattern appears in the second, the second appears in the third, the third appears in the fourth, and
there is not going to be any fifth pattern because the fifth pattern will become really big, but this
is an interesting figure named after the German mathematician Hilbert.

43
(Refer Slide Time: 12:56)

So here, the turtle is actually making copies of itself and then each of those copies are doing the
part of the drawing, so I like to call this a gulmohar tree, because the color is really like the
gulmohar flowers which appear in summer in India, and I think this is a really pretty tree.

(Refer Slide Time: 13:27)

So this is a stylized diagram also called a tree in computer science, so you can not only draw
diagrams, but you can also put numbers and that is what that example shows.

44
45
(Refer Slide Time: 13:40)

Here is a little bit more complex drawing and in this we have these two cars. So they really are
made up of several small elements, so they are made up of circles and they are made up of lines
and they are made up of polygons. And it takes a little bit of coordination to make sure that all
these elements are moving the way you want them to, but that is what programs are for. You can
actually write program which do these things.

(Refer Slide Time: 14:12)

46
Here is a kind of Physics experiment if you will, you have a ball which is bouncing inside a
rectangular region and it is obeying the rule that the angle of bounce back is equal to the angle at
which it approaches the ball and of course it has a pen, so it is tracing the path, it is showing the
path that it traces. The pen is at the centre so the line is not going all the way till the end of the
ball okay, all the way till the ball.

(Refer Slide Time: 14:58)

Now, you will see something interesting happen as it makes this drawing and that is because the
velocities the x and y coordinates of the velocities have small multiples with respect to the sides
of the square. Anyways now hat is going to happen is it will retrace that same pattern.

(Refer Slide Time: 15:08)

47
Here is probably the most complicated example in this, and that is the simulation of an airport.
So you will see that the aircraft actually keep some distance from them. At one point, they
seemed as if they were too close that is because I have made the picture of the aircraft larger than
what it actually is. So you can see that on any line segment there is only one aircraft at a time.

(Refer Slide Time: 15:46)

So this is the planetary simulation and this is what will need some sophisticated physics, actually
not that sophisticated, nothing that you did not learn in standards 11th and 12th. With that we

48
conclude this first lecture of the first week of An Introduction to Programming hrough C++.
Thank you.

49
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 02 Part - 1
Problem Solving Using Computer
Introduction. Real life problems as math problems.
Hello, welcome to the second lecture sequence of the first week of the NPTEL course on an
introduction to programing through C++. I am Abhiram Ranade and the reading for this
lecture sequence is chapter 2 of the textbook. So in this lecture, we are going to ask some
basic questions, really one basic question and provide some very high level answers to it.

(Refer Slide Time 00:50)

So basically the question is, how can a computer do so many things? It can search for
information, predict weather, process pictures, play chess. In this lecture we want to provide
some high level answers, not detailed answers. But certain just sort of make things ​plausible.
So, all these tasks seem too difficult and too unbelievable, so we are going to provide you just
the small amount of information which will make them seem a little bit more understandable.

So, the answers are going to be of the following kind, we are going to argue, we are going to
propose really, not a detailed argument, we are going to propose that most real life problems
can be viewed as mathematical problems or problems on numbers. And a computer can be
made to solve mathematical problems. Well this statement is a little misleading, because a
computer does what it told, so if we can solve that mathematical problem, then we can tell the
computer go ahead and solve it. So, in that sense a computer is good at solving math

50
problems. So these high level answers we are going to provide and the hope is that these high
level answers will give you enough background for whatever happens later in the course.

(Refer Slide Time 02:28)

So here is what we do - we will see how to express real life problems as numerical problems.
So we will take examples picture processing, predicting the weather and processing text or
language. Then I will talk about algorithms and programs, then I will tell you how a computer
really does all these things. So this will be a really whirlwind introduction to digital circuits.
So a topic which can take courses in electrical engineering but we are going to again go
through it at a very high level, so I will tell you how a digital circuit works, how numbers are
represented using the electrical quantities. I will tell you what are the parts of a computer are
and I will tell you the notion of the machine language program and compilation. So all these
things together will be background material for what happens later in the course.

51
(Refer Slide Time 03:20)

So let we start with this question, so you see this colorful picture in front and if I ask you
what is in this picture, you could tell me right away that there is a chameleon, by the way this
is taken from a Wikipedia page. Now, we would like a computer also to do it and in fact
today computers can do it, the computer will tell you that there is a chameleon.

(Refer Slide Time 03:42)

How does a computer do this? Well for that we need to know, how to represent pictures using
numbers. So I am going to start off with black and white pictures, so how do you represent
black and white pictures using numbers? Suppose I have 10 centimeter by 10 centimeter
picture, so I am going to divide it into tiny squares. So each square of say 0.1 millimeter by

52
0.1 millimeter. So the side length is 10 cm and the side length of the small square is 0.1
millimeter. So, really there are 1000 squares on each side, so 1000 by 1000, that is the total
number squares or 1 million squares or pixels are there.

Now, if one of those million square is mostly white, we are going to represent that whiteness
as a 0. If it is mostly black, we will represent it as 1. So for a 1000 by 1000 squares, in the
picture we will have a million numbers. So we will have a sequence of million numbers
which will represent that picture.

(Refer Slide Time 04:54)

Here is an example, so that smiley face on top of that I have a put smaller squares and as we
can see say a square somewhere over here is mostly white, so I get a 0 over here, whereas this
square is mostly black and so I get 1 over here. And so in this manner I have put 1’s and 0’s.
So this is going to be representation of this picture. Now, I would like to note this
representation is not perfect. So really, if you give me this, I will be able to say that look the
picture could be something like this as well. And this is not really the same as this picture, but
it is close enough. And in fact you can observe that if I make the square smaller and smaller I
will get a better and better representation of this picture.

53
(Refer Slide Time 05:52)

So, if instead of having 1000 by 1000 pixels I divided into a million by million pixels, then I
will get a nearly perfect representation. In fact, it turns out that really 1000 by 1000 is not
bad, your screen, this screen for example is probably something like 3000 by 2000 or
something like that. And yet you cannot make out that it is made up of small squares.

Then other things are also possible. So, a square may not be completely white or completely
black, so there may be some gray levels, so instead of using 0 or 1, you could also use the
numbers 0, 0.1, 0.2 and so on. So you might have different gray levels, so numbers to
represent different gray levels, so your number are not just 0’s and 1’s, so it is not just
sequence of 0’s and 1’s, but sequence of 1 of 10 numbers whatever or whatever 11 numbers.

What if we have color? Well, colors can be broken down. So a picture now is going to made
up of 3 sequences - a sequence for the red component, a sequence for the blue component and
a sequence for the green component. The actual colour is made up by adding these
components. So, that is how a picture is represented.

54
(Refer Slide Time 07:38)

Now, what can we do with such pictures? Well, we can ask questions like is there a
chameleon in it or what is in it? Alright, so typically what do these problems look like? So we
are given as input a sequence let us call it P of a million numbers and let us take our
simplistic picture which is a black and white picture 1000 by 1000 pixels. So there are a
million numbers 0 and 1 and these pixels are given to us in top to bottom, left to right order.

So these are representing a 10 cm by 10 cm black picture given in left to right top to bottom
order. Like the way you would write text on that page. Now, instead of worrying about
chameleons, let me pose a very trivial, not even a problem which might be of interest to a

55
child, but a really, really trivial problem. What is that problem? Is there a vertical line in this
picture?

So let me draw it, here is my picture and suppose there is a line in it so I am asking is there a
vertical line? That is all, that is all that I am asking. So, what do you do with such a question?
How do you represent this question using numbers? So, you have to ask what properties does
the sequence need to have, if it is to contain a vertical line? Well if I take this picture and
convert it into numbers, what is going to happen? So I am going to get lots of 0’s but
suddenly there might be a 1, again lots of 0’s, then lots of 0’s over here, then there is a 1 in
the same column, lots of 0’s, 1 in the same column, 0’s here, 0’s here, and may be all 0’s
here.

So the point is that there is a 1 for some rows, some consecutive rows of some column,
alright? So, can I describe what pattern this sequence of 0’s and 1’s is going to possess? Well,
here is the pattern, suppose, the first 1 is in the ith position, where is the next term going to
be? Well how many steps are you going to go from here to here? So you will go all this
distance, you will go all this distance.

Remember that there is a 0’s and 1’s are given to you in the left to right top to bottom order.
So if an 1 occurs in the i​th position the next 1 will appear in the (i+1000)​th position because
this distance is 1000. The 1 after that we will appear in the (i+2000)​th position, (i+3000)​th
position and so on.

So in fact, that is exactly the pattern. So there are going to be 1’s a position i, (i+1000),
(i+2000) and so on for some i. So at this point, we have described what it means in
mathematical terms for there to be a vertical line. So, is there a vertical line is as good as
saying does the sequence P of 1’s and 0’s satisfies this property, that for some i there are 1’s
in positions i, (i+1000), (i+2000) a few such entries.

Now, how do you solve this problem? So this problem is actually quite easy, you can try out
different values of i. So you can check is there this pattern valid for i equal to 0, if it is valid
for i equal to 0 that is as good as saying that there is a pattern right here, there is line right
here. So, this effectively for different values of i will give you different lines and then if you
find that is for some values of i this pattern is actually there, then you can claim, yes, I have
found the vertical line.

56
57
(Refer Slide Time 11:33)

Now the question, does this picture contain a chameleon, in principle is identical, why?
Again you need to identify a set of properties that the sequence of numbers representing the
picture must satisfy in order for the picture to contain a chameleon. These properties will be
really complicated, but some properties will have to be identified, there is no escape in this
step. Then, you will have to decide, how do I check whether these properties are satisfied?
Again this is a difficult mathematical problem, but it can be solved. And, in principle, it is the
same problem that we solved. That problem was a trivial problem, but again for the vertical
line, but again the problem was similar in principle that you needed to identify a set of
properties and you needed a procedure for checking whether the pictures satisfied those
properties.

So in practice this requires enormous ingenuity, but people have displayed that enormous
ingenuity. In fact, this is the main concern of a deep subject called computer vision. We are
certainly not going to study computer vision in this course, but all that I wanted to point out
you was how basically that subject works. That subject works by representing pictures in
terms of 0’s and 1’s, by associating a property where that sequence of numbers has to have if
it is to contain a certain object, and designing computations which will decide whether that
property is satisfied by a given picture.

58
(Refer Slide Time 13:32)

Let us turn to one more interesting problem you hear the weather report and you may wonder,
how they do that? So here is what happens, again at a very, very high somewhat superficial
level. So they divide the surface of the earth into small regions, just like you divide the
picture into pixels. And for each region, you are going to have variables say pi, ti, and hi
which represent the pressure, temperature and humidity in that region.

Now, we know enough physics to say that if you tell me the pressure, temperature, and
humidity in a certain region and not just in a certain region, but the regions nearby, so
adjacent regions or regions which are not too far something like that. Then I can calculate, by
using laws of physics which are mathematical in nature, what the future temperature, pressure
and humidity are going to be. So, if we measure the current pressure, humidity, and
temperature then we can calculate what happens, say, 1 second from now on, but then we can
calculate 2 seconds, 3 seconds and we can eventually calculate what will happen tomorrow

Now, I have greatly simplified what is actually going on, but what is going on is in essence
this. So we are using physics, we are talking about values of things like pressure,
temperature, humidity and we are using laws of physics to say how they are going to change.
And this requires lots of computations, but that is what computers are for.

Again like picture processing, if we make those regions smaller and smaller, then we will get
better accuracy, why? Because if a region is large, then it does not make sense to ask what is
the temperature in that region because in one part of the region the temperature might be

59
high, in another part the temperature might be low, but if the region is really tiny then you
can say roughly it is the same temperature in that entire region just like picture processing.

So if you make the region smaller than that means are actually having to do more
calculations. But again as i said that is what computers are for.

Computers can also process the language of course they we can do searches and you might
be wondering, how to they do that? Well here is a very simple scheme, again this is too
simple. Lot more sophisticated things happen, but let me just tell you one plausible idea.

(Refer Slide Time 16:15)

So first, we begin by defining the code for representing letters. And the code that is
commonly uses is the so called as ASCII code which stands for American Standard Code for
Information Interchange. In this code the little a letter is represented by the number 97, the
little b is represented by 98, the little c by 99 and so on. So consecutive numbers are given for
consecutive letters, lower case letters and similarly, some numbers are given for uppercase
letters as well.

And not only letters but symbols say the equality symbols has an ASCII code, digits also
have ASCII codes, so 9 as number is different from 9 as a symbol that use on the screen. And
the space character also has an ASCII code. So what is a word? A word can be thought
simply as a sequence of ASCII codes for the letters in that word. So ‘computer’ for example
can be represented by the ASCII code for ‘c-o-m-p-u-t-e-r’. If you check, 99 is the code for c,
in fact, it is the next code after 98 which we said the code for b, so clearly it is the code for c,

60
but if we check the rest of the numbers are in fact consistent with this idea and they are in fact
the codes that are used in ASCII.

So a word is a sequence of numbers, what is a sentence or a paragraph? Well there are simply
lager sequences. Now, you can ask, does the word computer occur in a certain paragraph?
What is that question? That question is simply the question, does a certain sequence of
numbers occur inside another sequence of numbers? that is it. So if you can answer queries
like this very quickly, you can do searching for words in books, or webpages, or whatever
you have.

(Refer Slide Time 18:22)

Alright, so here are some thought exercises that I would like you to do. So, these are mental
exercises, I just want you to think about it, because these are the kinds of questions we are
going to ask later on, and later on we will try to have very precise answers. So for example,
we talked about how do you represent the fact that a certain picture has a vertical line? Well
in a similar manner I would like you to think about what patterns of 1’s and 0’s would
correspond to a plus of any size being present at the center of an otherwise white pictures?
Another question that I would like you to think about is, suppose you are given a sentence in
a language you cannot understand, but you are given ASCII codes. Would you still be able to
count the number of words in the sentence? So could you express this as a question on the
sequences of numbers representing the ASCII codes of the different characters?

61
How will we represent chess playing as the question on numbers or how will you represent a
chess position, for example? So once you can express a chess position as a number, then you
have a foot in the door to asking questions about oh what is next good move? What does it
means for the white rook to capture a certain pawn or something like that, when can a rook
capture upon? So those questions will start becoming amenable to analysis once you first
decide, what does it mean to represent to chess position?

(Refer Slide Time 20:12)

So, what have we discussed? We have said that questions about that pictures, weather,
documents can be converted to questions about properties of number sequences. And these
are just examples, the implications is, that basically any question we should check whether it
can be converted to a question about numbers and that is when we can solve those questions
on a computer. But answering these questions requires solving interesting math problems, so
it does require a lot of ingenuity. So we will stop here, and take a break.

62
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 2 Part - 2
Problem Solving using Computer
Problem Solving and Algorithms without Computers
(Refer Slide Time: 0:23)

Welcome back! In the previous segment, we discussed about following - we said that questions
about pictures, weather, documents can be converted to questions about properties of certain
number sequences. And we also said that finding answers requires solving interesting math
problems.

63
(Refer Slide Time: 0:45)

Now, I am going to begin with a historical remark in this segment. So, computers are used to
solve problems. We know that, we see computer solving problems. But it is useful to remember
that problem solving is really not new, human beings have been solving problems, numerical
problems for thousands of years.

For example, astronomical calculations were done really thousands of years ago and
astronomical calculations are quite sophisticated. They were done for navigation and of course,
they were done for purposes of astrology as well. Land records were maintained and for that
interesting geometric calculations had to be done. Turns out that in ancient India poetry raised
some interesting computational problems and these were solved rather elegantly.

In the last 500 years, we have seen the development of differential equation which are being used
to analyze structures, weather and lots of things. So these things really are problem solving and
they deal with numerical problem solving and they are used on computers. But all of these has
happened well before modern computers were anywhere in the picture. Okay, so what does the
phrase “solving problems” mean? Well it means deciding what operations to perform to calculate
the required answer and as I said, human beings have been solving problems or deciding what

64
operations to perform to calculate the required answer for quite some time. And an algorithm is
simply a precise description of the operations needed.

(Refer Slide Time: 02:38)

Now, this might be a new term and you might think that it is a term associated with computers
and you may think it as an alien term but actually it is not. I want to assure you that you already
know many algorithms. So, you are already half-way there into learning the subject of computer
programming. So the procedures you have learned in primary schools for arithmetical numbers,
say, addition of 2 numbers with many digits are really algorithms.

Primary school algorithms, say on arithmetic, contain all the ingredients and that is really all that
is important when you talk about solving these other more fancy problems. So, what does an
algorithm contain? Well, it requires you to perform arithmetic operation. Your primary school
algorithm for doing addition required you to do something like this - "Add the least significant
digit of the first number to the least significant digit of the second number". This was what you
needed to do in order to do addition.

There was also a conditional operation. So there was going to be a carry. So carry was 1 if the
previous sum was greater than 9. So these conditional operations also appear in computer
algorithms. And there is also repetition, so if you are adding one 10 digit number to another 10

65
digit number you will repeat this basic step 10 times and on a computer also, you need to repeat
steps or you need to repeat a sequence of steps.

And really you do not need to do much more than this. You may do a lot of calculations, you
may have to multiply numbers or do something, maybe something slightly different. But really
these are the three kinds of steps that you are going to be doing when you execute a computer
program. And algorithms is simply a description of such steps.

In addition to arithmetic you know actually many other rather sophisticated algorithms. So you
know whether a number is prime. You know how to find the greatest common divisor of 2
numbers. This is a really pretty algorithm invented, say 2000 years ago and it is still really
useful. In fact, we will write a program to implement this algorithm on a computer. You can
draw a polygon and drawing a polygon is also an algorithm. It is a procedure. It is a very very
clearly stated procedure.

So I should really point out that you do not need to worry only about numbers when we talk
about algorithms, okay. Drawing is also a systematic procedure drawing for drawing is also an
algorithm. Well you might say that look a systematic procedure for anything say making tea is
also an algorithm.

But let us not worry about that. We are going to be concerned with numbers and it is vital that
you understand what algorithms or numbers are, and my contention is that you already
understand that. Something like what you did in order to add two multi-digit numbers is an
algorithm. And an algorithm nothing really very much more. It really contains operations of that
kind arithmetic operations, conditional operations, repetitions.

66
(Refer Slide Time: 6:33)

So what is a program? A program is simply an algorithm written in a precise syntax or a precise


language. C++ is only one such language. There are other such languages like Fortran, Basic,
Lisp. All these languages can be used to specify arithmetic operation, conditional execution and
repetition. You have already seen how to specify repetition, use the repeat statement. So this is
actually a fairly important crucial statement.

(Refer Slide Time: 7:12)

67
So some thought exercises for you. So try to write down the algorithm you learned whatever in
standard 3 for multiplying an n-digit number by another n-digit number okay. Well the teacher
probably did not tell you the algorithm for multiplying n-digit numbers, but just showed you how
to do the multiplication. And by now you know how to do it for an arbitrary number or digits.
How are you going to write that? Well, you should break up the description into parts. So maybe
you will say that in the first part we are going to do some multiplications and in the second part
we are going to do some additions. Then, in order to describe what operations to perform, you
may want to give some names.

So you may say that let Qi and Ri denote the ith least significant digits of the multiplicand and
the multiplier and then you may say that look let us multiply Qi by Rj or something like that.
Then you may also want to ask are there phases in the algorithm in which you do similar
operations? If so, can you say what may happen in the ith phase? So what might happen in the ith
phase might depend on i, but, if you can find a pattern, then you have really captured the essence.
Then you will be in a much better position to write it down nicely and indeed convert this into a
program.

(Refer Slide Time: 8:52)

68
Okay, so, what have we discussed in the segment? We have discussed that the notion of problem
solving and algorithms is old, literally thousands of years old. And sophisticated algorithms were
present thousands of years ago. Euclid’s GCD algorithm is one example. One really fantastic
example is the square root finding algorithm that ancient Babylonians knew.

What is an algorithm? It is a specification. A precise specification of a sequence of operations. It


may contain arithmetic operations. It may contain operations to be executed conditionally. It may
ask for a sequence of operations to be repeated. And you should remember, you should always
remember in this course, that you really know algorithms. So you do not have to be worried. Of
course, you do not have to be scared of computers. You do not have to be scared of algorithms.

The algorithms that you know are arithmetic on numbers, primary school, matrices this is what
you learnt in standard 11th and 12th, root finding that is also something that you might have
learned in high school or 11th and 12th. This knowledge that you have acquired in your
schooling is going to be very useful for programming and as I said, you are already halfway there
as far as being ready to program because you know algorithms already. Then we said that the
programs are very formal, very precise descriptions of algorithms in specific languages having
specific syntax.

So we stop this segment over here and continue later.

69
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 2 Part - 3
Problem Solving using Computer
Representing numbers on a computer
(Refer Slide Time: 0:41)

In the previous segment we said that the notion of problem solving and algorithms is quite old
and it predates computers. And that human beings have been solving numerical problems and
using really sophisticated algorithms for a long long time. We said that an algorithm can contain
operations which are precisely specified. They could be arithmetic operations, there can be
conditional operations and there may be at some operation sequences how to be repeated. And it
is important for you to remember throughout this course that you really know algorithms. You
have learned algorithms throughout your schooling and what we want to do is simply translate
them into programs. Translate what you know into this stylized syntax of a programming
language.

70
(Refer Slide Time: 1:28)

So, in this segment I want to talk about how a computer works or how a computer solves
numerical problems. So here is a quick outline of this segment. I am going to talk about circuits.
In particular, I am going to talk about something called digital circuits. Then I will talk about
how numbers are represented in circuits and then I will describe at a very higher level the parts
of a computer. Then I will talk about a machine language program and what is the process called
compilation that we have alluded to means.

(Refer Slide Time: 1:55)

71
Okay. So, let us begin the digital circuits. Digital circuits are really the building blocks of
computers. So, a digital circuit is simply a circuit in which we human beings interpret the
voltages and currents as numbers. There are some voltages and there are some currents and we
are going to interpret those as numbers. So here is a way in which we interpret, here is a simple
convention. We may say that in a particular circuit, in a particular wire really, if the voltage go
above 1 volt then we will think of it as the number 1. If it stays close to 0, then we will think of it
as number 0.

Now, digital circuits are typically designed so that voltages will never be in between this 0.2 and
1. So, we will always be able to interpret a voltage as a number in a very unambiguous manner.
So, from now on I might say something like the voltage is a 0 or the voltage represents the
number 0 or there is the number 1 on this wire or there is the number 0 on this wire and that
really should be thought of as that there is a voltage of 1 volt or higher than 1 volt on this wire or
there is a voltage of roughly 0 volts on this wire.

We might also talk about currents. We might say that current smaller than some value represent
0, larger than some value represent 1. And we might say that the charge stored on a capacitor
also denotes numbers. So, low charge may mean number 0, high charge may mean number 1.
These are just conventions. Whatever the conventions we use, we have to stick to them entirely.

72
Now, note that capacitors are particularly interesting. Because once we store a charge on a
capacitor, it can stay there, unless we connect the two end points of the capacitors. So, if the
charge is stored because it can stay there, a capacitor is typically used as a memory element.

Now, I have told you how to represent 0’s and 1’s. But once you know how to represent 0’s and
1’s, you can represent anything really, and we will see this in a minute. Now, the point of all of
this is we, and by that I mean electrical engineers, can design circuits which perform arithmetic
in the following sense. So, we can design a circuit such that, if you feed a set of voltages to that
circuit, which represents a certain set of numbers, then the circuit outputs, the voltages that come
out of the circuit will precisely the numbers which represents the sum of the numbers fed on the
input.

So, such circuits can be designed. It requires ingenuity, but people can do this. Not only sums,
we can design circuits which perform multiplication, so they compute products, they perform
quotients, they perform square roots, essentially whatever you want. So that is that is the reason
why circuits work so beautifully for computation. So, we know how to represent 0’s and 1’s.

(Refer Slide Time: 5:50)

So now, I am going to tell you how to represent non-negative numbers. Basically the idea is, we
are going to use many capacitors or many wires to store or represent a single number okay. So,

73
the typical numbers of wires or capacitors we use are 8, 16, 32, 64, maybe even 128 numbers,
maybe 96, 128 something like that, okay. So, how does it exactly work? So suppose I want to
store 25 using 32 capacitors, or 32 wires or, in abstract terms we can say 32 bits. How do we do
that?

Well, we are going to first convert 25 to binary. So, what is 25 into binary? It is this it is this last
thing at the end, 11001. So, that is 25 in binary. But, we are going to use it using 32 bits. So we
are going to have a total of 32 binary digits or bits over here. But of course the more significant
bits are going to be all 0’s. So this is the representation of 25 using the binary system. So, that is
the first step that we are going to do. And if you want to store this value in a computer then we
are going to store a charged pattern where H represents high or the number 1 and the L
represents low or the number 0. So, we will have 32 capacitors and they will have the following
pattern of charges stored.

So, this capacitor will have the have low charge, low charge, low charge and essentially that will
mean the number 0 will be stored this capacitor, this capacitor, this capacitor whereas some
capacitors which have high charge representing the number 1, okay. Again, 2 low charges, high
charge. So, this is how you will store 25 in our computer using 32 capacitors. Or, if we are going
to send the data from one part of the computer to another part we will use a pattern of currents or
maybe a pattern of voltages of this kind, low high depending upon whether the bit value of
binary is 0 or 1.

Now, if we are restricting ourselves to using 32 bits, how large numbers can be stored? Well, we
can have the pattern consisting of all 0’s okay. So, all these numbers, all these bits are 0, then
that will represent the number 0. Or we can have all these numbers be 1’s, so that is going to be
the largest number okay in binary. And in decimal that number is 2 to the power 32 minus 1. So,
any number between 0 to 2 to the power 32 minus 1 can be represented using 32 bits or 32
capacitors or 32 wires. This is not a small number. This is something like about 10 digits. So,
you can if you want a larger number than that, for some reason you need those numbers, then
maybe you can use 64 bits, or maybe even more bits okay. Now, if you want to transmit numbers

74
then you have to send high or low voltages on as many wires. That is all. That is all that is
needed.

75
(Refer Slide Time: 9:14)

So, I have been talking about binary representation, but here is a quick revision of what binary
representation really is: what binary representation is. So, binary number is a sequence of bits or
binary digits. So, binary digit is 0 or 1. So, I might have a digit a bit a n minus 1, a n minus 2, a1,
a0 and so on and in fact, there is a point there which now probably we should call a binary point
and then the digits following that I have numbered minus 1, minus 2, minus k. In fact a subscript
indicates the significance of the digit. As an example, I might have a binary number, 101.11.

So what is the decimal equivalent of it? The decimal value simply is, whatever that digit is
multiplied by 2 to the power the same i. So for here, 0 will be used and this will be 2 raise to 0,
so it will be 1, but in other place whatever the other things are used. So what is the value of
101.11? Well we just have to do exactly what I said.

So, this 1 is a2. So I am going to have 1 times 2 to the power 2. This 0 is a1. So I am going to
have 0 times 2 to power 1. This 1 will have value 1 times 2 to the power 0. This 1 will have
value 1 times 2 to the power 1, minus 1 and 2 to the power minus 2. So, this number is really
5.75. So in this way if you give me a binary number I can convert it into a decimal number. I can
convert a decimal integer v to binary and here you may know that if I divide v by 2, the
remainder gives me a0 and I can repeat the previous step with the quotient that I get when I

76
divide by 2. So the previous quotient I take and if I divide it again, then that will give me a1. If I
divide one more time, then the remainder will give me a2 and so on. Converting fraction f to
binary is sort of natural. So for example, you may note that if this fraction f is bigger than 0.5
then the first binary digit or the first bit after the binary point this will have to be 1. Then you can
throw that, you can subtract that value. For example, there are many ways to do this. And if what
remains is bigger than 1/4th, then the next bit will also be 1. Otherwise it will be 0 and so on.

So, this is just a very quick way, a quick introduction or a quick revision of binary
representation. You really do not need to know carefully what happens to fractions. But atleast, I
am sure you know how to deal with integers, binary integers and this is just a quick revision of
that okay.

(Refer Slide Time: 12:41)

So, going back to representing numbers. So we talked about how positive integers can be
represented. But suppose, you want to represent negative numbers, negative integers, how do
you do that? Basically the idea is, one sort of idea is that one of the bits is used to indicate the
sign. So let us say sign bit is equal to 0 means a positive number, equal to 1 means a negative
number. So if I want store minus 25, I am going to do exactly what I had earlier. So this is the
representation of the 25. But the most significant bit, that the first bit in this entire number, I am

77
going to make it a 1. So this does not mean 2 to the power 31 okay. It mean minus 1. So this is
just a matter of convention now. So we have to decide some kind of convention and we have to
stick to it. So if our convention is the first bit designates the sign, rather than being a part of the
number, in that case this sequence of bits is going to represent minus 25. So here, we are saying
that the left most bit is a sign bit. But once we do that, we know now that the largest number is
going to be 0 followed by all 1’s. So this is going to be at most 2 raise to be 31 minus 1. So the
range has reduced a little bit, okay. So this is going to be our largest positive number. So, I can
have the negative numbers also. So if I put in a one over here then that becomes a negative
number.

So the number now starts with minus 2 to 31, whole thing minus 1 it should be, 2 to the 31 minus
1. The actual representation that computers use is not exactly like this. It is something called
“Two’s Complement”. So we are not going to discuss that and these specific details are not
really important, but you should know roughly what happens okay. So that you have a good idea
of what is reasonable and what is not reasonable. So we will see why we are going through all
this.

(Refer Slide Time: 14:51)

78
So in our very first lecture you wrote this statement int nsides. So when your program executes I
want to tell you what is going to happen okay. So, C++ will typically designate some 32
capacitors in your computer for storing the variable nsides. So later on when we talk about
nsides, the computer will refer to the specific capacitors, and the value stored in these capacitors,
the big pattern that get stored the low high charges that get stored or the 0 1 values that get stored
on each charge will be interpreted as a positive or a negative value.

So say the first the first charge or the first 1 or 0 will decide whether the number is negative or
positive and the rest of it will decide what the magnitude of it is. So, that is how the
representation works. You get some 32 capacitors and depending upon how you decide, once and
for all, how the numbers are going to be stored, the patterns of bits stored in those capacitors will
be interpreted according to the convention you fixed.

Now, C++ actually allows you to write the statement and unsigned int nsides as well. So in this
case you will get 32 capacitors, but now you are telling your computer that look I am never
going to store a negative number in this variable. So please interpret the entire 32 bits as the
magnitude of the number that I stored. In this case if you store the number 1 followed by all of
these things it will really mean 2 raised to 31 what this bit position represents plus 25. Whereas,
if you are stored this pattern in a variable which is just declared int then it would be interpreted
as minus 25. So, how you declare, how you define that variable, what type variable you say it is
will tell the computer how to interpret those, interpret the value of the bit pattern stored in that
variable or stored in those capacitors.

(Refer Slide Time: 17:32)

79
Now, the terms bits, bytes, half-words, words are also used. I should just mention them once. A
bit is 1 binary digit. So in other words just one number it can only be a 0 or 1. Byte is 8 bits.
Half-word is 16 bits. Word is 32 bits and the double word is 64 bits. 1 byte of memory really
means a memory capable of storing 8 bits or typically it means 8 capacitors. Of course there are
ways of representing or remembering numbers without capacitors in which case it will mean
some other kind of devices, maybe 8 other kinds of devices. But it is safe to think of memory as
being capacitors for most part.

(Refer Slide Time: 18:32)

80
How do you represent real numbers? Because after all, we need to deal with real numbers.
Temperatures, humidity all these things are real numbers, not integers. Here we are going to use
the analog of scientific notation. So, what is the scientific notation? We write a real number as a
part called a significand times 10 raised to an exponent. So for example, Avogadro’s number is
6.022 into 10 raised to 23. So we are going to use exactly this on a computer as well, okay. But
the significand and the exponent are in binary and so the number is going to be interpreted as
significand times 2 raised to the exponent, okay instead of 10 raised to exponent, it is 2 raised to
exponent. That is all. That is the reference.

So the question is, how many bits do you allocate for a significand and the exponent? So, this
representation scheme called “single precision” says, that in my representation scheme I am
going to store the significand using 24 bits and the exponent using 8 bits, okay. So one important
point is when we are storing floating point numbers it really is in two parts. So there is a
significand part and there is the exponent part and you may further note that the significand also
might have a sign and the exponent might also have a sign. So, each of these things really are
also in two parts okay.

Now, why are we choosing these numbers for single precision? Well turns out that these
numbers are sort of good. They have been found to be good in practice, okay. And one other
reason is 24 plus 8 is 32 which is one word. So, a single precision real number or a single

81
precision floating point number as it is called fits in one word. So I should also say that a 24 bits
of significand really represent precision of 7 or 8 decimal digits, okay.

Then there is also something called “double precision”. So here you are not going to use one
word but two words. So you will have 53 bits. You will dedicate 53 bits to store the significand
and 11 bits to store the exponents. So you will have a bigger range in the exponents as well as
more precision in the significand okay. So it is like scientific notation. How many digits you are
going to write in the significand? The more digits you write, the more precise, the more accurate
your representation is. And whether you are going to allow exponents to be larger is simply
going to say how big numbers can you store. So it is exactly the same when it comes to binary as
well, okay.

So a double precision number will fit in a double word and you should know 53 bits of
significand are equivalent to 16 to 17 decimal digits. So that is really a huge amount of precision.
So you, I do not think anybody really will require more precision than that. But, if they do, there
are ways to get it, okay. The actual representation for single precision and double precision is
more complex and it has more features as well and it is the so called “IEEE Floating Point
Standard”, which your computer implements and which the C++ language also implements.

(Refer Slide Time: 22:14)

82
So, just a very quick indicative example. So just to make these things more real, I am going to
tell you how we might represent Avogadro’s number. This is not exactly how Avogadro’s
number is represented on your computer. But this is indicative how it might be represented. So
first we convert it to binary. So binary might be this, 6.022 might be this, and 10 raised to 23
might be that, so that number might be 2 raised to so many. So now, we are going to represent
the significand using 23 bits of fraction okay. And 1 bit for the sign of the fraction. So 24 bits
totally and 7 bits for the magnitude of exponent and 1 bit for the sign of the exponent, okay.

So, 2 raised to 1001110 so that is what I have replicated over here okay and I have put a sign bit.
And this pattern I have stored over here and what I get over here is this pattern okay. Okay, so
there is a 0 and so these are positive numbers and that is what this is. So the decimal point is
assumed after the second bit. So there is assumed to be a decimal point over here. So, this is what
it is. These black bits, what are these black bits? Well, they are bits which were not there but we
needed 24 bits of significand and so these bits are just padded up as 0 bits.

Notice that this presentation is inherently imprecise and the fraction is only represented to a
certain finite number of bits and in fact this is not really a property of binary system. Even in the
decimal system, even in the standard scientific notation this problem is there. So nothing new
really, okay. And as again I will point out that the actual representation is really more complex.
So this is not IEEE Floating Point. This is just something similar to IEEE Floating Point which I
have given over here just to tell you what it might look like. So the actual thing is more complex.

(Refer Slide Time: 24:56)

83
So, one quick thing for you to think about, so suppose I want to represent 8 digit telephone
numbers. So which representation should I use? So should I use an 8 bit representation, 16 bit
representation, 32 bit representation or a 64 bit representation? And should I use unsigned or
signed? So you are expected to fill in the blanks over here. So what you are supposed to do is not
use too many bits because you are using memory unnecessarily, but not use too few bits either
because if you use too few bits then that number will not fit there.

Then these are just question for you to check whether you are paying attention. Which is bigger,
byte or half-word? What is roughly the largest number that can be represented represent using 64
bits? And I want the answer in decimal. So here you might want to note that 2 raise to 10 is 1024
which is about 10 raise to 3. So this way you can calculate what 2 raise to 64 is very easily, at
least approximately.

84
(Refer Slide Time: 25:54)

Okay so, what have we discussed in this segment? We have discussed that numbers are
represented in the sequence of 0’s and 1’s. And we discussed the same sequence may mean one
number as an unsigned integer, a different number as a signed integer and a third number as a
floating point interpreted as a floating point number, single or double precision floating point
number.

Now it is important to note that the capacitors only store high or low charges. They are not aware
in any sense that the charge represent the numbers. So we have to keep track. So, when we write
a program, we designate a memory location as having a memory a variable as having type int. So
that is when we are telling the computer that look, please remember that is what we stored in this
has to be interpreted as a signed integer or if we call the type unsigned int, as an unsigned
integer, okay.

And there are ways to specify the types so that the computer interprets it as a 32 bit floating point
number or a 64 bit floating point number. So it is our responsibility to remember what type of
number we are storing and if we remember it consistently then there will be no problem. I should
also point out that please do not be scared you really do not need to know binary number system.
So whatever you type has to in decimal and C++ will convert it to binary.

85
So you do not have to type binary. Do not get scared. And C++ will also do the other things. It
will convert binary numbers that it has on the computer and print out decimal numbers. So both
ways it will do it. So you can only think about the familiar decimal system, okay. But then, why
are we teaching you this? We are teaching you this because you need to know roughly what is
going on. You need to know that whatever you are storing has finite precision and how many
digits of precision you are getting roughly.

So, if you are going to want to think about how much error my calculation containing, this
discussion will be important for you. Okay. So you should know roughly what range of numbers
and how precisely the numbers can be stored in different formats. So that concludes this
segment. We will take a break.

86
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 2 Part - 4
Problem Solving using Computer
Representing numbers on a computer
(Refer Slide Time: 0:36)

In the last segment we discussed how numbers are represented using sequences of 0’s and 1’s.
So we discussed how integers are represented, with or without signs and how real numbers are
represented. And we also said that you do not need to really worry about binary representation
when you write a program because you are only expected to write something in decimal and the
computer will convert it to binary for its internal processing. And likewise, when the computer
prints or something, although it might be holding things in binary, it will print that out in the
decimal, so that we can understand it very easily.

87
(Refer Slide Time: 1:13)

Now, I want to give you at a very high level how a computer works. So I am going to start by
telling you the overall organization of a computer. And then I will talk about how the parts work.

(Refer Slide Time: 1:21)

So here is what a computer looks in a very simplified form. So there are some important
components. So, one important part is this memory. It has capacitors to store different bites, and
it has something called an address port or a data port. And it has also controlled ports. So there

88
can be a read control port in the write control port or there can be just a single control port which
tells memory whether writing has to be done or reading has to be done.

Then there is a network, which connects these different components together. So perhaps the
most interesting part of the computer is this so called arithmetic unit. So this receives, this can
receive inputs and it has some control ports and based on what value is sent on the control ports,
these numbers will get added, multiplied, subtracted or something like that and they will appear
on the output port. And they can go back into the network and they can be sent back to the
various components.

Then there can be a keyboard connected through the network and the values from the keyboard
can go into the rest of the computer. There can be a monitored or a screen, there can also be a
disc. And finally, perhaps the most complex part of this is the so called of control unit, which
really controls all of these things.

(Refer Slide Time: 2:51)

So then we talked a little bit about the memory. So typically memory is organized into bytes. So,
groups of 8 capacitors. Okay. So modern memories will contain few gigabytes where, a Giga
represents 2 raise to 30 or about 10 raise to 9 or about a billion. So a gigabyte is a billion bytes.
Each byte in the memory is assigned a distinct number or a distinct address. So these are very

89
much like house numbers on a street. So think off the capacitors as sitting on a long road
andeach group of 8 capacitors has a number.

So in a memory with N bytes, the addresses go from 0 to N minus 1. And I can say that look now
do something to house number 57 or rather I should say byte number 57. And those capacitors
may get something written into them, or you may say look tell me what is in those capacitors?
The memory, circuit communicates with the rest of the world using 3 sets of wires or ports. So
these are the address port, data port and the control port. The control port could be a single wire
or it could be multiple wires. So in the picture I had shown two wires the read port and the write
port, but we can also have a single wire. So here I am going to talk about what happens if it is a
single wire. These details are not important and we are just using those details just for making
this picture a little bit more detailed and therefore more real.

(Refer Slide Time: 4:50)

So how do you store or write data into memory? So, suppose I want to store a number D and D
could be whatever, say 37 and I want to store it in the byte which has address A, so whatever 57,
so in the 57th house or the 57th byte on this long road, I want to store the number 37 something
like that. How do I do that? Well, on the address port, I am going to store the number A. So the
address port consists of several wires, and basically when I say put the number A on the address
port, I mean think of A as a binary number and place the bits of A on the respective wires. So

90
that is what I am going to be in general, so if I say place a number, then I mean think of it as a
binary number and place the corresponding voltages the corresponding wires.

In a similar manner I can place the number D on the data port. So you had that memory and it
had those two ports and I have set the voltages on the corresponding wires at this point. Then I
have this single wire control port suppose, and maybe I place the number 1 on it or if I had a two
wire control port, I will place the number 1 on the right control port, it does not really matter, this
is a minor detail. So now all these values I am going to hold steady for a period which is called a
clock cycle. This is the time in which the circuits to their work. So at the end of that period, the
capacitor at address A will get that data D. So something will happen because of which the
circuits will work and the data will move. Those voltages will move from the data port to the
capacitors themselves and not to any capacitors because, but the capacitors at address A. So that
is what writing data into memory means.

Now you may ask what is this clock cycle business? Well, that is something that is determined
by the memory designer. So the memory designer will look at that circuit that he or she has
designed and we will say that look this circuit requires 10 nanoseconds for it to do its work. And
so the clock cycle will be 10 nanoseconds or something like whatever it is.

(Refer Slide Time: 7:35)

91
Now you do not just want to store data, but you also want to read what is stored. So suppose I
want to know where is stored in accuracy of the memory. Again, what does that mean? So A
could be 57 and if you think back about our picture where capacitors are sitting on this long road,
groups of capacitors are sitting on this long road, I want to look at the 57th group. The A-eth
group and figured out what is in those capacitors. How do I do that? So I am going to place A on
the address port. Again, that means converting A to binary and storing the corresponding values
on the wires in the address port. Place 0 on the control port, or if we had a two wire control port,
we will place a one on the read control port, so again equivalent. And we will wait for one clock
cycle, so again, the circuits will do their work and somehow they will copy the values in the
capacitors at address A on to the wires in the data port. Now this copying is not destructive. That
is the capacitors will still continue to hold those values. But, now those values will also appear
on their data port. Now the data port connects to the rest of the word by wires and from there you
can move those voltages or those that value wherever we want. So reading the value at any
address does not destroy it. So even after this operation, address A will continue to hold the
value that it was holding earlier.

(Refer Slide Time: 9:21)

All right, so this description is really very superficial. I have not told you what the circuitry, what
circuitry represents. I just said that their exist circuitry, which will do this movement and I have

92
just told you that this box, this black box called memory has these 2 three openings through
which it communicates with the rest of the world. And now this organization can be somewhat
different. So again, this is all schematic. So I just want to tell you that this organization need not
be exactly what I said earlier. So for example, instead of reading one byte at a time, you may
read one word, so a word starting at address A maybe read or written into. In such a case, the
memory is called the world oriented memory. Well, what does the phrase word starting at
address A means? It simply means the data stored in bytes having address A, A plus 1, A plus 2,
A plus 3. So remember that the byte is 8 bits, a word is, 32 bits. So 4 bytes make a word and so
we have to regard, we have to consider the data stored in 4 bytes and the notion of words starting
at address A is simply the 4 consecutive bytes at starting at address A. And typically in such a
memory the data port will have 32 wires so that all the bits in that word can be brought out
simultaneously. Similarly, we can have a double word oriented memory or maybe a half word
oriented memory, whatever you want.

(Refer Slide Time: 11:12)

Next I am going to look at the arithmetic unit. So here the ports are input, output. So there may
be there typically are 2 inputs and there is an output. And then there are, there is a controlled
port. Input and outputs will consist of w wires, where w is typically the size of the memory data
port. So if it is a word oriented memory, then this will typically be a word oriented ALU, but not

93
necessary, this is just a typical organization. Control could be several wires. So the numbers
appearing on the control wires will say what operation should be performed.

(Refer Slide Time: 12:04)

So, what happens over here? So, let me draw a picture. So typically the ALU is pictured in this
funny fashion. So this is data port, input port. This is input 2 and this is the output port and there
is a control port over here. So, if you want say something to be added up, what do you do? You
place the value to be added on these wires, then you place the second value to be added on these
wires. And then, there is this control port and it may have several wires. So there might be one
wire which is the add wire. So you raise this wire to become one instead of 0 and everything else
should of course be zeros that is going to command this arithmetic unit to take these two values
and put out there sum over here. So that is how the arithmetic unit works. So arithmetic unit is, I
guess sort of the heart of it because this is where the calculations are performed, but in principle
it is fairly simple, the organization is fairly simple. So values come in, what is to be done with
them should is fed through the control port and outputs go out. Of course, it has to contain
circuits for doing multiplication, addition, division, whatever it is that you want to be done.

94
(Refer Slide Time: 13:54)

Next, there are the so called peripheral devices and which might include keyboards, screens and
disks. So these also have a control port and the data port like organization. So I am going to
describe this again in a very simplistic manner. We are going to place values on the control port
and those really tell the peripheral to what is to be done with the value in the data port. Or, it may
say, look this value that I am placing on the control port really indicates that you should place a
certain value on the data port. So let me give an example. So if you take the screen as a
peripheral, then the data port value is going to be suitably interpreted and shown on the screen.
So the control port might say where that data value is going to be shown. That might be how a
screen works. Or if it is a keyboard then you may say that the keyboard itself will place some
value on the data port and the rest of the world will be able to read it. So your computer may be
able to read it. So the control port of the keyboard may signal to the keyboard that now look now
and I am waiting for you to send me something. So the value placed on the data port or keyboard
can be sensed by the rest of the computer.

95
(Refer Slide Time: 15:15)

Then the final unit that I want to discuss is the so called control unit. So this control unit is what
you might call the manager or the brains of this entire thing. This is the controller as the name
says, it is going to tell the other parts what to do. How does it do that? Well, it sends numbers or
commands on the control wires of each unit. So we said that the memory unit control wire has to
become 1. So it is made 1 by the controller. Or the add control wire of the arithmetic unit has to
become 1, who does it? The control unit, does it. The control unit decides what to tell other units
by reading a machine language program stored in the memory. So of course the question arises,
how does the control unit itself know? So for that there is the machine language program. A
machine language program is a sequence of numbers representing machine language instructions
and machine language instruction examples might be something like this. So there might be
machine language instruction which says make the ALU add the numbers in addresses x and y
and store the result in address z or maybe another instruction which says make the ALU. The
ALU is an abbreviation for arithmetic and logic unit, which is the abbreviation which is
sometimes used, but another abbreviation is also AU and which is just the arithmetic unit. So
arithmetic and logic unit or ALU and AU arithmetic unit are abbreviations, which really mean
the same thing for practical purposes. So you might have on machine language instruction which
commands the AU or the ALU to do multiplication or do division or addition or whatever it is.

96
(Refer Slide Time: 17:28)

All right, so what have we discussed in this? So we have discussed that a computer has several
parts like memory, ALU or arithmetic unit or AU, peripherals and these communicate with the
rest of the world through data port, address port, control port, ports like this. Then there is a
control unit, which tells other devices what to do by placing values on the control ports of those
devices. The control unit arranges for data movement to happen between other parts of the
computer, and the control unit knows what to tell others by reading a machine language program
which is sitting in the memory of the computer.

So we will conclude this segment at this point.

97
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 02 Part - 5
Problem Solving Using Computer
Machine Language and How a computer works
(Refer Slide Time: 0:34)

Welcome back. In the last segment we discussed the different parts of a computer, in particular
memory ALU peripherals and the Control Unit and we noted what their respective functions
were. And we said that the Control unit knows what to tell the other parts of the computer to do
by reading a machine language programme. So in this segment we are going to talk about this
machine language programme which is made up of machine language instructions.

98
(Refer Slide Time: 0:58)

Okay, so, what is a Machine language instruction? It is a sequence of numbers and here is a
possible structure or possible format for a machine language instruction. The first number might
say what operation to perform and in this literature, you may often see the term “operation code”,
the phrase “operation code” being used for this first number. So the first number tells what
operation to perform or it codes the operation to be performed. The second and third number
could be addresses in memory from where the operands are to be taken. And possibly the fourth
number might be the address in memory where the result is to be stored, okay? So I just made up
this format, but somebody has toot make up a format. The machine language format as well as
the instructions are designed by the computer designer. So the computer designer says that the
structure is going to be this or some other structure, but just for concreteness let us just assume
that the structure is exactly this. So the computer designer has to design instructions which will
be able to perform every operation that we need or alternately a computer will be able to perform
some operation only if the computer designer has designed a machine language capable of
performing that operation or maybe a sequence of instructions which are capable together of
performing that instruction.

99
(Refer Slide Time: 3:12)

So, just to make this, this description more concrete I am going to give an example, but of course
this is a fictitious example, there is no computer which has the machine language instruction that
I am going to talk about, but it is an indicative, it is an indicative machine language instruction.
So my hypothetical instruction consists of these four number, the first number 57 is what we call
the operation code and this might mean multiply for example let us say it means multiply. Then,
on reading the above instruction and assuming that the format or in the structure that we
described on the previous slide, what should the control unit do? Well the control unit will tell
the memory to read the words at first two addresses and send them to the arithmetic unit because
what we said in the previous slide was that the words at addresses 100 and 200 need to be
multiplied so they are being sent to the arithmetic unit. Then, the control unit has to tell the
arithmetic unit to perform the multiplication. For this it has to send the appropriate number on
the control wire of the arithmetic unit which will cause the arithmetic unit to perform a
multiplication. And finally, the control unit has to arrange for the result from the output port of
the arithmetic unit to be moved back to the memory and then it has to tell the memory that look
whatever you have just got on your data port has to be stored in this third address which in this
case is 300 so that address also has to be sent back on the address port of the memory.

100
So these are roughly the five steps that the control unit has to do on seeing that instructions. Now
this seems like a fairly complicated thing, but it will indeed cause the product of the numbers
stored in addresses 100 and 200 to be stored in address 300, okay? Now you might have another
hypothetical instruction in which 58 might mean the same thing as above, except that maybe the
numbers have to be added. And I should point out one more complication, so when I say I want
the numbers to be added, I need to really say what format the numbers are in. So maybe the 57
represents, says that look interpret the numbers as unsigned integers and then do the addition and
store them back, okay?

So, so the operations actually end up being somewhat complicated because of the different
number formats that we have. The machine language instructions have to be sensitive and have
to specify whether the operation has to be with respect to one kind of number representation or
another kind of number representation. Okay, so I gave you an example of a machine language
instruction, now I am going to give an example, again a hypothetical example of machine
language programme.

(Refer Slide Time: 6:18)

So here is a machine language programme, a really simple machine language programme, it only
contains two instructions. So the first instruction is 57, 100, 100 and the second instruction is
also 57, 100, 100. So if the programme is present in memory, the control unit will first execute

101
the first instruction and then it will go and execute the second instruction. That is how the control
unit will behave. So suppose the control unit does that, what will happen? Well both instructions
are really identical so both instructions will cause the word at address 100 to be multiplied by
itself because the first word as well as second word, the second address is the same and in fact
the destination is also the same. So the words in address 100 will be multiplied with itself and
stored at 100. So after one instruction is executed the address 100 would contain the square of
the number that was present before. And so what happens after the second instruction is also
executed? Well it would repeat the squaring operation so as a result at the end we will get the
fourth power. So you can say that this sequence of two instructions is really a machine language
program to compute the fourth power of a number.

(Refer Slide Time: 7:59)

Okay, so here is quick exercise for you just play with this, with this notion. So you are expected
to modify the program, which we gave you earlier so that if that instead of computing the forth
power it computes the cube of the number stored in address 100 and instead of storing the result
in 100 itself, it is going to store it in address 200. Okay so now I have told you what a machine
language program is and now I want to complete the description of control unit, how it operates.
So the machine language program is going to be somewhere in memory and the control unit must
be told that look from this address the machine language program is present. So what does the

102
control unit do? The control unit fetches the instructions constituting the program, interprets the
code and performs the required operations. After one instruction is fetched and executed, it
fetches the next instruction and just repeats the process, that is what the control unit does. And,
there could be more complicated instructions of course which say to the control unit that look,
repeat these instructions several times, so something like a repeat statement could also be there in
machine language and something like a conditional statement could also be there in machine
language. But we are not going to worry about all those details, this is enough level of detail for
our purposes. And yes, the circuitry in the control unit is quite tricky to design, but it can be built
and it has been built.

(Refer Slide Time: 9:31)

Okay so some remarks, we said that 57 is the code for multiplication, of course this is fictitious,
again I just want to emphasize that. Different machines will have different codes, and of course
you do not have to remember that 57 means multiplication, it does not, we just made up that
number, just as an example. And actual machine languages are a lot more complex, will have
many more instructions, but the point of this discussion is for you to understand what is machine
language. So this is indicative of the types of instructions that you have in a machine language
and therefore, this sort of tells you what a machine language program looks like.

103
Now, machine language program are actually important in the sense that when you execute a
program, what actually executes on the computer is a machine language program. And if you go
back to early computers, as a user you would have to write the machine language programs, what
does it mean? So then you have decide what operations you want to perform. Then you go and
look up the manual and find the code which will cause that operation to be performed.

So you enter the code into the memory of the computer, then enter the address of the operands
and the result - where the operands are going to be present, where the result should be put, you
enter those addresses. And then you repeat this for as many operations as you want done. Now
this process is really, it looks really painful and it actually is painful, not only it is laborious and
painful but it is also very error prone. So thankfully, in this course we are not going to do any of
that.

(Refer Slide Time: 12:03)

So now I want to tell you the relationship between machine language programs and C++
programs that we are going to teach you how to write. So on a modern computer you will write a
C++ program and there is already a program written called a compiler which will translate your
C++ program to a machine language program. So it will generate the equivalent machine
language program. When you type ‘s++ square dot CPP’ or when you type, when you hit the
compile button, this is exactly what happens, your C++ program is translated into an equivalent

104
machine language program. So on Unix the machine language program is called a.out. And when
you type ‘./a.out’, a.out gets loaded into the memory by a loader program and it executes. And
similarly, if you hit the run button on your IDE the created machine language program will be
loaded into memory and it will be executed.

(Refer Slide Time: 12:58)

So we really have covered a lot of ground at a very high level, a bird’s eye view so to say, so
what have we learned? We have said that in order to solve problems on a computer they must be
formulated as problems on numbers, then if things are not immediately numerical then we have
to use some codes, say for example for language or text we need to use codes, okay. Then we
said that algorithms are precise sequence of calculations that are needed to solve a certain
problem. And we said that algorithms are not new, human beings have been using algorithms
well before computers were invented. And these algorithms were used for pencil and paper
calculations but that is fine. Some of these algorithms are terrific algorithms and not only that,
you know many of these algorithms already. Computer algorithms are very similar to algorithms
which are needed for pencil paper calculations. So a very natural strategy for designing
algorithms it is as follows, think about how you would solve the problem using pencil and paper
given enough time. Understand the structure of the required calculations and then express those

105
calculations in the programming language, and this last step is what the rest of the course is all
about.

(Refer Slide Time: 14:38)

Some more remarks, we also talked about how numbers are represented and we have said that
numbers are represented using currents, charge, voltages. Larger numbers, larger than 0 or 1 can
be represented using sequence of bits, or sequence of 0’s or 1’s. And an important point to
remember of course is that if you have a certain fixed number of bits, then you can only
represent fixed number of numbers. So if you want to represent a larger range of numbers or if
you want to represent numbers more precisely you will need to use more bits.

Then we said that circuits can be designs so that they take as input voltages representing numbers
and produce voltages representing their products sum or whatever you want. We also said that
memory in a computer is organised as a sequence of bytes, each byte can be identified by its
address.

106
(Refer Slide Time: 15:28)

Then we said that a machine language program is a sequence of machine language instructions
and this program must be present in memory. And the control unit reads machine language
instructions and interprets them, and decides what is to be done, and sends control signals to
other units to make them do the needful.

Then we said that the users write a program written in high level language, say C++ and user
program is compiled into machine language by the compiler. Loader loads the compiled program
into memory and then executes it, that is the end of this second sequence of lectures for the first
week.

Thank you.

107
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 3 Part – 1
Basic Elements of Program
Variables and data types, Introduction.

Hello, and welcome to this second week first lecture sequence of the NPTEL course on an
Introduction to programming through C++. What I am going to do today is something like the
following.

(Refer Slide Time: 0:34)

I am going to talk about how to perform some basic operations that are needed in all programs.
So the first amongst these is using the memory of the computer, how do you store numbers in the
memory of a computer? Then, how you read numbers from the keyboard into the memory? How
do you print the numbers in memory on to the screen? How do you perform arithmetic? Clearly
this operations are required in all programs and they sort of form the base of whatever here we
are going to the study next and we are going to talk about all this today. Okay, and during the
lecture and towards the end we will see programs based on all of this.

108
(Refer Slide Time: 1:19)

So the first task is reserving memory for storing numbers. So before you want to store the
numbers into the memory, you must explicitly reserve space for storing them. And in this course
whenever we talk about “space” we will mean region of memory. And this reservation done by a
“variable definition” statement. The term ‘variable’ is used to denote the space that we have
reserved. It is the name of a the region of a memory, and you get to decide this name, how? We
will tell you in a minute. The value of variable likewise means the value stored in that region of
memory that is just reserved. Then, in addition to defining the variable while giving its name you
also must state what kind of values will be stored in the variable. So basically these value are
indicative of the type of the data and we will see this in a minute.

109
(Refer Slide Time: 2:34)

So, a statement for creating variables or defining variables. So this has the form ‘data-type-name’
and ‘name-of-the-variable’. We have already done this in chapter 1 or in lecture 1 and the
example that we had there was int nsides. ‘int’ here is the data type name and it is short for
“integer”, it indicates at values that we are talking about storing are going to be integers. So this
statement is going to reserve space for storing integer values positive or negative, of a standard
size. And the standard size these days tends to be the 32 bits on most computers. And the values
that are being stored in this variable are going to be interpreted as Two’s complement values. So
this sort of like having the sign bit and then a magnitude but it is not quite, but if you think about
it as sign bit and magnitude that is okay. nsides is the name to be given to this region of memory
that has been reserved for us, or, the region of memory is also called the variable that we just
created and so nsides is the name of that variable.

110
(Refer Slide Time: 4:02)

Now, names in C++ including names of variables are called “identifiers”. So an identifier can be
a sequence of 1 or more letters, digits and the underscore character. Now, a name cannot begin
with a digit. And some words such as int cannot be used as variable names. So these terms int
and so on are reserved by C++ for its own use and so they cannot be used as identifiers.

In C++ case is important, so whether you write something in the lower case or upper case does
makes a difference. So I can have capital ABC as an identifier or I can have little abc as an
identifier and these will be considered different identifiers. And the only characters used to make
up a name and once mentioned above - letters, digits and underscore. So this means for example
that you cannot have space inside the name of a character or once you give a name to a character
you cannot break it up. If you break it up it might mean something else, you cannot break it up
by putting spaces. So here are some examples, nsides is an example we have already seen, you
can have a name called ‘telephone_number’, you can have a name called ‘x’ , you can name
called ‘x123’, you could have a name or an identifier called ‘third_cousin’. What is not allowed
however as identifiers or names of variables are something like ‘#sides’ this is not allowed
because hash is not allowed in identifiers. ‘3rd_cousin’ looks okay but begins with a digit and we
have to abide by the rule that names of identifiers cannot begin with digits. And ‘3 rd cousin’ is
not a valid identifier because it contain spaces.

111
Now this gives you a lot of choice in what to select as names and you are urged to use
meaningful names, so basically name should describe the purpose for which the variable is going
to be used.

(Refer Slide Time: 6:42)

Besides the int data type, C++ has several other data types. So for example there is the ‘unsigned
int’ data type, this is used for storing integers which are guaranteed to be positive, or alternately
whatever is stored in such a variable will be of course a bit sequence as always but it will be
interpreted as a non-negative value. And typically one word will be allocated, or 32 bits will be
allocated. And in these 32 bits whatever will be stored interpreted as an ordinary binary number.

Char is also kind of integer, but it is small variable and it is used for storing characters or small
integers. So it only has 1 byte width so it only consist of 8 bits and often the value which is
stored in it will be interpreted as the ASCII code of some character so will see this in a minute.

Float is a data type which is use for storing real numbers and typically 1 word will be allocated.
And this word will be used as per the IEEE floating point representation, using 8 bits from the
word as exponent and 24 bits for the significant.

The double is another data type of C++ and this is also for storing real numbers, in this case 2
words will be allocated. And this will be floating point and 11 bits will be exponent and 53 bits
will be used for significant.

112
(Refer Slide Time: 8:35)

So here for example is a name a ‘telephone_number’ which I can give for an unsigned int
variable. I might want to have variables to store mass and acceleration and these clearly will be
real numbers and I could define them by writing ‘float mass, acceleration’.

So here, in a single statement I am defining several variables of the same type though. Now,
along that these definitions I can attach a keyword long and long basically says that I really want
a bigger variable or I want more precise numbers so something like that, so give me more than
the usual space. So I could have long unsigned ‘int cryptographic_password’ . And this might
very likely give me 64 bits of storage. So unsigned int, so I really get to stored 64 bit binary
numbers in such variable.

‘long double more_precise_acceleration’, defines a variable which I have just decided to call
more precise acceleration. And since double is already 64 bits long double will probably give me
something like 96 bits. So the exact values of this you will know by looking at the manual for the
language, or really the manual for the compiler that you are using, or the standard.

113
(Refer Slide Time: 10:22)

Now a long with defining a variable we can also ask that a certain value be stored in it. So this
value will be stored right at the time the variable is created. So for example, I could write ‘int
i=0, result;’ in this the variable i, I have chosen to initialize, whereas result is uninitialized, I can
also write ‘float vx=1.0, vy=2.0e5, weight;’.

So in this vx and vy have been initialized and note the 2.0e5 is how you write the floating point
number, or the number 2.0 into 10 to the power 5 of scientific notation. So that value will get
stored in vy. Weight will not get an initial value. Now, as we can see although inside the
computer the binary representation is used then you communicate with the computer when you
tell what to store you are just using ordinary decimal notation, scientific notation or whatever it
is, okay.

Here is another initialization, I set variable called ‘command’ to the character ‘f’ while defining
it, so here I am defining it as a type of character and inside it, I am storing the character ‘f’. Now,
this ‘f’ is something called a character constant and these three characters together, this string of
characters really simply means the ASCII value of the quoted character. So this happens to be
102 and so really what is going to be stored is this ASCII value.

114
(Refer Slide Time: 12:34)

There is also keyword called ‘const’ and I can attach it to a variable definition and here for
example I am saying ‘const double Avogadro=6.022e23’, so this says that I do wants space of
type double to store Avogadro, but, I am not going to modified this value once I have stored. So
normally value stored in a variable can be changed, but here I am just telling I am just declaring
beforehand that look, I do not intend to change this value and therefore, if by mistake I change it
then the compiler will warn.

(Refer Slide Time: 13:25)

115
I can read values into the variables and we have seen one example in chapter 1, okay. So I can
write ‘cin>>nsides’ so this will wait for the user to type in value from the keyboard and that type
value will be stored into nsides. And I do not have to just read one value, I can read several
values in the same statement. So I could write ‘cin>>vx>>vy’ so this will expect that the user
will type in two values. The first of those values will go into vx, the second will go into vy.

Now, when the user types something when the computer is waiting for vx or vy or the computer
is waiting for a floating point number, it is expected that the user will type a floating point
number or the user will type an integer. Well, when a computer is waiting for a number it really
does not matter what, what kind of number a user types, it is okay so long as the user types a
number. But the user should not type other characters. So the user should not type ‘a’ because ‘a’
does not mean anything as a number. So it is important that when such a command executes, the
user types a number of a value of the correct type. While typing in values the user can put in
characters which are often called white space characters, and these are simply the space
character, tabs, newlines. And these serve to delimit two values. So after typing the value for vx,
the user can type a space or the user should type a space before typing vy. But the user could
type as many spaces as he or she wants, or the user could type in a newline or several lines so
how many new lines, how many spaces are type is ignored. But, some white space has to be
there between two values. Inside the typing of a single value of course, you cannot put in any
white space. And this is a little bit of a tricky point for beginners initially, just because I typed
1.0 does not mean that that 1.0 value is accepted, to make the computer accept that value you
have to hit the newline after this. If you are typing in several values the new line could be hit
after typing the last one that is perfectly fine. And finally, if you are reading values into a char
type variables then it is acceptable to type a character and what goes into the variable is the
ASCII value of that character. So, if I define a char variable called command and if I the execute
statement ‘cin>>command’, then C++ well wait for the user to type in a character, even here if
the user types white space that will be ignored. But anything other than these white space
characters if the user types, the ASCII value of that character will go into this variable called
command. So, if for example if you type the character f, its ASCII value, 102 will get stored into
f.

116
(Refer Slide Time: 17:19)

Printing variables on the screen is reasonably simple again we have seen an example of it in
chapter 1. The general form most cout less than less than and the name of a variable, or it could
be a message as well, okay. And, if I want a newline to be printed, I use the reserve keyword
endl, e-n-d-l. And I can print a message and I just have to enclose that text inside quotes, okay.
And, if I want to print several things I can do that I just have to put this less than less than
between those things that I want to print. The less than less than as well as the greater than
greater than is actually some kind of an operator. So I might say letter on that they less than less
than operator or the greater than greater than operator.

So here for example, is a statement which is going to cause the message ‘position’ to be printed
and of course the quotes will not be printed. After that the values of the variables x and y will be
printed with the comma in between them, and then a newline will be printed. If you print a char
variable, then the content is interpreted as an ASCII code, not as a number, and the
corresponding character is printed.

So here for example, I am creating the variable ‘command’ in which I am storing letter ‘G’ and a
second character variable called ‘command2’ into which I am storing the number 97, but if you
remember 97 is the ASCII code of the little case a, okay. So I could have written command2
equal to ‘a’ as well. In any case, if I print out these two characters, by writing
‘cout<<command<<command2’, then whatever is the content of these variables that content will

117
be a interpreted as an ASCII code, and the corresponding letter will be printed. So of course,
command contains the ASCII code of G and so the little g will be printed, the command2
contains the ASCII code of letter little a and therefore, ‘Ga’ will be printed on the screen. Now,
when you want output to appear on the screen, you really need to put an end;, and only a endl
forces the output to appear. Until then C++ may just keep collecting whatever you are asking it
to print, but C++ is forced to print it, if you print a newline so that is the sort of the signal to the
C++ saying that whatever we have been collecting print now. Or, C++ will print whatever it is
collecting. If you decide to read something, so if you are giving a message and then reading a
something yes, the message will appear and then you can type after the message.

(Refer Slide Time: 21:02)

So here is quick exercise for you, so create double variables temperature, pressure and initialize
pressure to 0. Create a constant double variable PI initialized to 3.141592 and the idea here is
that from then on you can use capital PI without having to remember what the value of PI is.
Create a char variable y or No which is initialized to the character y. And here is something that
you need to thing about often-what name should I give and here is the question is what name
would you give to a variable in variable which is meant to store the number of students in a class.

(Refer Slide Time: 21:51)

118
Okay, so what have we discussed in this segment of this lecture sequence? We first discussed
how to define variables. We discussed how to initialize variables. We discussed how to read a
value into a variable and print the value of a variable. So we will take a break here.

119
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 3 Part - 2
Basic Elements of Program
Assignment statements, arithmetic expressions
(Refer Slide Time: 00:21)

In the previous segment we discussed how to define variables, initialize them, read into them
from the keyboard and print.

(Refer Slide Time: 00:44)

Now, we are going to discuss the assignment statement which is useful for storing a value
into a variable defined earlier. So you might have initialized it, but you can change the value

120
and that is what the assignment statement does. The statement has the form
‘variable=expression’. So here is an example, I might have variables s, u, t, a defined earlier,
I should have such variables and if I have these variables I can write a statement ‘s=u*t +
0.5*a*t*t’ and what this does is what you might expect. So the text on the right hand side of
the assignment is what is called an expression and it is a formula involving constants or
variables, essentially like you write formulae in mathematics and in the execution, the value
of expression is calculated and that value is stored into the variable which appears on the left
hand side of the equal to symbol. Now, if expression contains variables then they must have
been assigned values earlier. If they are not, then it is wrong to write such a statement. Ok.
And if for example, ‘a’ has been assigned a value then the value used in place of ‘a’ in this
expression will be whatever that value is.

So for example, suppose u, a and t have values 1, 2, 3 respectively assigned before the
statement is executed. Then when the statement executes then this expression will be
calculated. So the value 1 of u will be used, the value 3 of t will be used and the value 2 of a
will be used. So we will have the evaluation ‘1*3 + 0.5*2*3*3’ and the result of this 12 will
get stored into the variable s. Now, when you store a value into a variable then whatever
value was there before you did the store goes away. Because, after all the variable contains
some capacitors and now you are saying, look I want a different value to be stored in these
capacitors. So basically, whatever value was present is lost or its also said that the new value
overwrites the old value. When you evaluate an expression which contains references to
variables, then the values of those variables are taken from those variables but they continue
to remain in those variables as well. So for example, in this case while we will need to use the
value stored in u, a and t, just because we are using the values, does not mean that they are
going to be destroyed. So even after the statement is executed the variables u, a, t will
continue to have continue to have those values that we were given earlier. In fact, this
statement only changes the value of the variable s. Whatever other variables we might have
defined those variables will remain as they are.

121
(Refer Slide Time: 4:09)

Now, when we write expressions there are several rules. Some of which are slightly unusual,
but you will see that they are quite natural. The first rule is that multiplication must be written
out explicitly. So you cannot write ‘s = ut + 0.5att’ while in mathematics if we want to write
x times y we just write xy this is not allowed on a computer. Simply because if we write u
and t together then there is a question, does it mean u multiplied by t? Or does it mean a
single name ut of some variable? So because of such considerations the designer designers of
C++ and many languages decided that if you want multiplication to happen you have to say
multiplication so you have to explicitly indicate the multiplication operator. So between u and
t and between the other things that you want multiplied you must put a ‘*’ operator.

Now, multiplication and division have higher precedence than addition. So this is like
mathematics. So for example, in this case u*t will be computed then 0.5*a*t*t will get
computed provided you had put in the multiplication operators and only after that will the
addition be computed. So, between multiplication and division the precedence is the same
and between addition and subtraction also the precedence is the same. So operators of same
precedence if they appear and you have to make a choice between them then evaluation
happens left to right. So the operator that is on the left side will get evaluated first.

So we will see examples of all this and inside expressions you can use parentheses with the
usual meaning. Now, spaces can be put between operators and values if you like, but of
course if you have an identifier which consists of several letters, you cannot split it with a
space. So the first example there are no spaces but in the second example there are spaces

122
between on either side of the equality symbol as well as the plus. So whatever you think is
easier to read is fine. So that is the choice left to you.

(Refer Slide Time: 06:48)

Some examples, so suppose we create these variables and initialize some of them. So now,
what happens if I write r=x*y+p*q? So in this expression, we want to pick x and y first and
perform their product. Then, the next multiplication has higher precedence so that product
will be computed and finally the two products will be added. So since x and y have value 2
and 3 and p, q have value 4, 5 we are going to multiply 2*3+4*5 and get 26. So r will get the
value 26 if you execute these two statements.

If you execute s=x*(y+p)*q then notice that here the parentheses are evaluated first. So y+p
will be calculated first. So the result will be 2*(3+4)*p or in other words s will get the value
70. If you write t=x-y+p-q, the evaluation is left to right. So 2-3 is evaluated first which will
give you -1, plus p or 4 will get added so you will get 3 and then you will do minus 5 so you
will get minus 2. So minus 2 will go into t.

If you write u=x+w in this context this statement is a little questionable. Because it is not
clear whether w has been defined before or not. So if w has not been defined before, then this
statement is wrong. Otherwise whatever the value of w is, and it had better have been given a
value that value will be added to x and the result will be stored in u.

123
(Refer Slide Time: 08:51)

Now, division is a little tricky and suppose we have these four variables and if I write u=x/y +
z/y. So notice that x and y are both integers and z and y are also integers. So in this case C++
has a somewhat unusual rule. So if the dividend and divisor are both integers then C++ will
somehow produce an answer which is also integral. So the most natural answer to produce is
to use the quotient. So basically, the division will be performed and the remainder will be
ignored. So in this case 2/3 will produce the quotient 0, 4/3 will produce the quotient 1 and so
the answer will be 0+1 or 1. So u will become 1 after this. And if you divide an integer by 0
then you will get error because within integers division by 0 is not defined.

124
(Refer Slide Time: 10:15)

Now, C++ allows numbers of one type to be stored into variables of another type. And in
such cases C++ tries to do the “best possible” it can under the circumstances. So suppose I
have int x, float y and suppose I say x=2.5. Well x is integer. I cannot really store 2.5 into it.
So what is the best possible? So here C++ says that I am going to be simplistic and I am just
going to take the integer part of it. You could have said, why not round it? But C++ does not
do that. C++ just rounds it down or takes the integer part.

If I am storing something into a floating point number, again the value that gets stored will be
in in that scientific notation and further more if I have float y, then that only has about 7
digits of precision. Ok. So 123456789 has 9 digits which cannot be represented. So probably
something like 1.234567 or may be even 1.23456 will get stored. But the magnitude will be
roughly right and the exponent will be 9. So what is going to be stored here is 123456700.
Ok. So instead of 123456789, 123456700 will get stored. So this is sort of an inhabitable
consequence of using the scientific notation or using the float data type.

So these remarks will apply also to the double data type. But the only thing is that the double
data type can store far larger number of digits. Something like 17, 18 digits can be stored. So
in this case the representation will still be exact. If you had used a double.

125
(Refer Slide Time: 12:23)

Now, C++ also allows you to mix different kinds of numbers when you operate on them. So I
could write an expression, A some operator B where A and B have different types. So here
are the rules that C++ uses to evaluate such expressions. So if A and B have different data
types then they will be converted into the more expressive of those types. So, what does that
mean? Well basically integers are less expressive than floating point. So floating point
floating point can potentially represent integers exactly but integers can very rarely represent
floating point numbers exactly. So that is kind of a reason to say that float or double are more
expressive. And furthermore shorter types are less expressive than longer types. So
something which use as 64 bits is certainly more expressive. So A and B you use, then both
will get converted to the more expressive data type, you perform the operation and the result
will have the type of the more expressive type.

126
(Refer Slide Time: 13:28)

Some examples, so int nsides equal to 100, but anyway so suppose we have that and after that
we write int iangle1=iangle2 and now if I write iangle1=360/nsides. So let us see what
happens here, so 360 is int, nsides is int, so the result of division will be an int, integer
division will be used and the result will be 3. Because the it is only going to take the quotient.
So 3 will get stored into iangle1 which is an integer ok.

Then iangle2 suppose it is 360.0 divided by nsides. So then what happens over here is a little
tricky ok. So 360 upon nsides the numerator is double. So if you if you write any constant by
default it is double. So the numerator here is double, so denominator is also converted to
double so 100 is converted to double then we do the division. So the result in this case will be
3.6. So the result of the expression on the right hand side 360.0 divided by nsides is actually
going to be 3.6 now.

However, notice that iangle2 is integer. So while storing only the integer part will get stored.
So we are going to do the same thing when the destination, the left hand side variables are
going to be floats. So suppose you write fangle=360/nsides. So, what happens? So 360 and
nsides are both integer so the result for the expression is 3 and 3 will get stored into fangle1.

If on the other hand we write 360.0/nsides then the result will be 3.6 and that will be stored in
fangle2. So if you are expecting 3.6 to get stored then that will get stored only in fangle2. So
this is something that you have to be careful about; especially when you mix integers and
floating point values. One solution to this which is kind of a simple solution, but is a solution
of worth, is really just to work with the data type double. So it has 16, 17 bits of precession

127
and it will not do this type of truncation. So that is that is something that you can think about.
But anyway very likely you will use doubles and ends mix together. And in that case you do
need to know these rules.

(Refer Slide Time: 16:45)

Alright, now when you use either double or float or the equivalent of scientific notation then
there are some other things that you have to watch out for. So suppose for example, I define
the variables w, y and Avogadro and I initialize y to 1.5 and Avogadro to 6.022e23. Now,
what happens if I write w=y+Avogadro. Well, ideally what might happen is that I would have
to write that entire Avogadro out in whatever 23 digits or so and then add 1.5 to it and the
actual sum will be something like this. However, this actual sum is going to be stored in w
which is a floating point number. So w can only accommodate 23 bits, which is about 7
digits. So really only the first 7 digits will be considered. Ok. So everything after the 7th will
get truncated. So to 7 digits of precision Avogadro is really the same as y+Avogadro. ‘w’ will
receive the truncated value that is the Avogadro itself. Ok. So basically if you are adding a
very small number to a very large number then the addition may not have any effect at all.

128
(Refer Slide Time: 18:12)

So let us put together whatever you have learnt or some of what we have learnt to write a
simple program. So in this program we are going to define two variables; centigrade and
Fahrenheit and you may you can guess what I am going to put into them. So I am going to
print out a message saying “give the temperature in centigrade”. So after that I will wait for
the user to type in some value and the Cin statement will cause that value typed by the user to
be stored in centigrade. Now, I can calculate Fahrenheit, right? So the formula is the
Fahrenheit value is centigrade value times 9 upon 5 plus 32. So that is what I have written
down over here. So as a result of this the variable Fahrenheit will actually get the equivalent
value of temperature in Fahrenheit equivalent to whatever was typed by the user which we
interpreted as a centigrade temperature value. And finally this statement is going to print out
a message saying that in Fahrenheit the temperature is so and so. And we are putting in endl
which forces the value to go out and of course an endl to a line to also appear.

Now, let me just ask you, ok, do I need to write 9.0 or will this work? Well think about it for
a second before you hear my answer perhaps; so here centigrade has been defined as a double
variable, so when we do the multiplication itself the result will be a double. So again when
we do the division it will be a double divided by 5. But when you divide a double then the
result is going to be a double and therefore, we will not have any truncation and will indeed
get the result calculated correctly. Ok.

129
(Refer Slide Time: 20:20)

So I am going to stop the slides for a second and I am going to show you a demo of this
program. Ok, so here I have the program that I showed you earlier all typed out. So I am
going to now compile it. So I go back to my shell again and now I am going to compile it. So,
it has compiled and now I can execute it. So as soon as I execute it, as soon as I run it, I get
the message, “give temperature in centigrade”. So,we can give some temperature, so I guess
if you want to check whether the program is behaving properly. May be we should type in
some value whose Fahrenheit equivalent we know. So say we type in 40 whose Fahrenheit
equivalent is 104. So indeed it does print 104 and so our program is in fact running correctly.

130
(Refer Slide Time: 21:17)

Ok, so now I want to make some comments about expressions, specifically, where can
expressions appear in the program? So basically expressions can appear on the right hand
side of an assignment that we have already seen; but in general, you could say that
expressions can appear wherever a plain number can. So for example, in this code I can put
numbers to initialize; but I can also put expressions. Ok. So instead of putting in a number I
have putting in a expression. Instead of putting in a number over here I have put in an
expression. So now, the initialization happens left to right. Ok. So u will get initialized, t will
get initialized, a will get initialized. And then v and s will get initialized. So this is important
because when you initialize v, you are using the values of u, a and t. So because the
initialization is happening left to right, the correct values will be available over here and
similarly for this. So for example, if you define variables in this manner where you are
referencing a variable which has not yet been defined in the left to right order, then this is
incorrect. To have this correct, you should really write y=2 first and then x=5*y. Now, you
could have printed just a number if you wanted or you could have printed a variable but you
can also print out an expression. So this will cause this expression to be evaluated and that
value will get printed. Similarly, when you are passing an argument to a command you could
place a value, a numerical value or you could place the name of a variable or you can put an
expression. So before that value is actually sent off to that command, the expression is
evaluated and only the resulting value will get sent off.

131
(Refer Slide Time: 23:38)

Now, very often we might want to find the remainder and in C++ the remainder is found by
using the operator ‘%’. The character percent is actually the remainder operator. Ok. So x%y
evaluates to the remainder when x is divided by y and x, y must be integer expressions. So for
example, I might write something like this, int n=12345678, d0, d1. So if I write d0=n%10,
d0 will get the remainder of n modular 10. So it will get 8. d1 I am writing as (n/10)%10. So
what will n by 10 be? n by 10 will just be the quotient when divided by 10, so that will be
1234567. That when taken modular 10 again will get be 7. So basically what is going on over
here is that by using the remainder operator we have a way of extracting the digits of a
number, by taking remainder and dividing by 10 as many times as we want.

132
(Refer Slide Time: 24:34)

So here are some exercises, these are going to test whatever you have learnt in this segment.

(Refer Slide Time: 24:41)

So, what have we learnt? So we have learnt about assignment statement, we have learnt about
how arithmetic happens when expressions contain numbers of different types and we should
also note that real numbers are represented only to a fix number of digits of precision. So
adding very small values to very large values may not have may have no effect. What we did
not discuss but what you should read from book are things like overflow and representation
of infinity. So, we will stop this segment will end this segment here.

133
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 3 Part - 3
Basic Elements of Program
Reassignment, sequence generation and accumulation

(Refer Slide Time: 0:21)

In the previous segment, we discussed the assignment statement and rules for expression
evaluation.

(Refer Slide Time: 0:25)

134
So, in this segment we are going to look at reassignment. This looks simple enough basically
changing the value given to a single variable ok, but this actually is turns out to be rather
powerful and very very common operation and it needs to be understood properly. Ok, so let
the rule for evaluating expressions is that when a variable appears in a statement its value at
the time of execution is used. So suppose I write p=3 , q=4, r, and I write r=p+q. So, the
values of p and q at the time of executing this are 3 and 4. So, what is going to happen is that
those values are going to get used and 7 will be stored. So, if I print r out then 7 will get
printed.

Now, suppose I write r=p*q, then the current values of the p and q will be used and 12 will
get stored into r. Now, if I print out r the current value of r which is 12 will get printed.

(Refer Slide Time: 1:48)

Now, reassignment can lead to some interesting expressions. So, suppose I have int p=12.
What will happen if I write p=p+1? Is it even legal? So, in C++ it is actually legal. So, the
rule for executing such a statement is something that we have already discussed. So, the usual
rule says first evaluate the value on the left hand side so, the current value of p is 12, you add
that 1 so, you get 13 and then the whatever the result is stored into the variable on the left-
hand side. So, 1 is added to 12, the current value of p and the result 13 gets stored in p. So,
basically it will cause the value of p increase by 1.

Now, this statement is sometimes found confusing by people because writing p=p+1 is
nonsensical in mathematics and the equal to operator is very very strongly linked in our
minds to mathematics. So, this says that the equality in mathematics and in programming is
quite different. In mathematics its more like equality, in programming it means, this says take

135
the value of the expression of the right-hand side and put that value into the variable whose
name appears on the left-hand side. So, basically equals to in C++ is different from equal to
in math and you should be aware of this very much.

(Refer Slide Time: 3:40)

Now, reassignment turns out to be quite interesting with repeats. So, here is a program I am
going to have int i=1 , repeat 10 times and let us say I write cout<<i<<endl; and then I write
i=i+1. So, what happens when I execute this? In the first iteration, when the loop is when the
repeat statement body it is entered then i will have value 1. So, because of that 1 will get
printed and i=i+1 will change i to 2.

In the second iteration, what is going to happen? Well, the value that i now has is 2 so, 2 will
get printed and i=i+1 will change that 2 to 3. So, at this point i will have the value 3 and if
you keep on going in this manner in the 10th iteration 10 will get printed and i will change to
11. So, something quite interesting has happed over here this set of statements has been able
to print out the numbers between 1 and 10 for us.

So, basically this idiom we can call a sequence generation idiom. So, if you want to ever
generate sequence of numbers 1 through 10 then, this idiom will do it, which idiom? Repeat
10 times and i=i+1, the cout<<i is not really an essential part of idiom we put it there only
because we wanted the sequence to be seen.

Now, suppose we put in the statement turtleSim() and we put in the statement forward(i*10),
and right(90) what do you thing this does? So, notice that in this green portion we are not
changing the value of i at all. So, i will have the same values in each iteration as it did earlier,

136
but this means that the distance by which the turtle goes forward is going to be different in
each iteration. So, first it will be 10, next it will be 20, then it will be 30 and so on. So, this is
sort of like drawing a square but the side length is increasing. So, what do you think happen?
So, this going to cause something like a rectangular spiral, let us take a look at this.

(Refer Slide Time: 6:12)

137
So this program also I have written and it is called spiral.cpp. So, here the program and I
guess what I have not put in over here is this wait. Let me indent this properly because
otherwise it does look little confusing. So, it is what we have written over there? Yes, it is so
it is also going to print i but it is also going to cause movement, ok so, let us see what it does.
So, let me compile it and let me run it. So, it did the spiral just as we expected.

(Refer Slide Time: 7:31)

Now, you should realise that we just do not really need to generate sequence 1 through 10,
you can generate other sequences also. So, it is an easy exercise for you to generate the
sequence 1, 3, 5, 7 and so on, or you can also generate the sequence 1, 2, 4, 8, 16. Basically,
you can generate these sequences by making slight modification to the previous program.
May be change what you add, may be instead of add do something else. So, just try it out.

138
(Refer Slide Time: 7:48)

Now, using the assignment statement or rather the reassignment statement inside a repeat
loop can allow you some other things as well. So, here is a program which reads 10 numbers
and adds them together. So, so we declare variables int term, s. ‘s’ is going to be 0, s is going
to have the sum, maybe we should actually call that variable sum, but that is ok. So, we are
going to do repeat 10 times and so, we are going to have cin>>term so, the value goes into
the term and then we add this value to s. So, whatever value we get we are going to add to s.
So, notice that initially s is 0, but in the first iteration of this loop s will change and whatever
you receive through keyboard is going to be added to s, what happens in the next iteration? In
the next iteration, whatever the user types with the keyboard the second time around is stored
into the variable term and that will get added to s. So, at the end of 2 iterations, s will have
the sum of 2 variables. So, at the end of 10 iterations s will have the sum of 10 variables. So,
if you type s at the end of it you will get the sum of 10 variables.

Now, s is serving like an accumulator, it accumulates by summation whatever values are read
from the keyboard and so this idiom we might as well call the accumulation idiom. So, you
could do other type of accumulations as well, you can accumulate by using products for
example, or you take the maxima and keep accumulating the maximum. So, all kinds of other
things are possible.

(Refer Slide Time: 9:52)

139
Now, an interesting thing happens we can compose these two idioms and write a program
which calculates n factorial. So, here is our basic program, ok. So, this is the first idiom. So,
this is the sequence generation idiom and it is generating the sequence 1 through n. Now,
what do we need to calculate n factorial? Well we want that sequence but we just do not want
to leave that sequence alone we want to multiply all those numbers. So, this is easily done by
writing a new variable out called nfac, it is initially 1 and then we simply write nfac=nfac*i.
So, the first time around nfac will get multiplied by 1, the second time around nfac will get
multiplied by 2, 3, 4 all the way till n. So, at the end if we print nfac we will get n factorial
printed. So, the idioms as we can see are quite powerful, we can sort of mix them up as well.

140
(Refer Slide Time: 10:58)

Now, because the assignment statement and the reassignment statement are so commonly
used C++ defines the addition operator. So, here for example i=i+1 is something which
appears very frequently and so, in C++ it can be abbreviated as i++. So, ++ is an operator and
and it is a unary operator and it can be written as i++ which simply means i=i+1. So, it is an
increment operator it is a unary. And similarly, you can have --, which means j=j-1 and -- is a
decrement operator.

(Refer Slide Time: 11:43)

Now, ++ and -- are actually quite tricky. ++ and -- can be written after the variable, or before
the variable. So, I can write ++i or I can write i++. Both are allowed. Now, furthermore, I can
also write expressions such as k=++i and k=i++. So, these expressions are legal and as it

141
happens, they produce different results and so, here ++i and i++ are different. If I just write
i++ and ++i in isolation then they change the value of i and they change the value of i in a
similar manner, but here they produce some different results as per as the k is concerned.

Now, such assignments are described in the book, but, I believe, and many programmers
believe that such expressions are really difficult to understand. So, it is like using very
complicated words when you do not need to use them. So it said that when you speak, you
should use simple words as simple words as possible. So, what has happened over there is
that these variables were defined in the language but more and more people are saying do not
use these complicated forms like k=++i and k=i++.

So, indeed in this course we are not going to use them and I will recommend to you that do
not use them in your carrier as well so just stick to the simple forms, same for --.

(Refer Slide Time: 13:43)

Now, the fragment of the form sum=sum+expression also occurs frequently, so C++ allows
such fragments to be shortened to sum+=expression. So you can also have *=, -=, to
represent sum=sum*expression or sum=sum-expression. So, if I write x+=z, then really it is
x=x+z so x is going to become 12 because x is 5 and z is 7.

Similarly, I can write star equal to, so here, if I write y*=z+w note that z and w do not
change, I mean this is not this is not something new that I am telling you if you get confused
remember that it is really exactly equivalent to writing y=y*z+w and this when you evaluate
the expression z and w do not change.

(Refer Slide Time: 14:50)

142
So here are some exercises to you to try out based on the material that we are seen in this
segment.

(Refer Slide Time: 14:56)

So, what have we discussed in this segment? Well we said that the value of a variable can be
changed and assignments such as i=i+1 and j=j*2 are allowed they are useful for generating
sequences, then once you are able to generated the sequences you can compute the expression
such as n factorial and several other users are there. And because we do things like i=i+1 and
j=j*2 operators such as ++ or *= have also been provided. So, we will stop at this point we
can continue later.

143
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 3 Part - 4
Basic Elements of Program
Blocks and scope

(Refer Slide Time: 0:21)

In the previous segment we discussed the assignment statement further or rather we discussed
how values can be reassigned and especially reassigned inside a loop we generate sequences
and do interesting computation in general. And we also discussed some operators such as ++
and *= to.

144
(Refer Slide Time: 0:39)

Now, we are going to discuss one idea which is related to how you write programs and how
you define variables or rather where you define variables. So some technical terms first, the
code that you write inside the braces is called the block. So, so far you have seen blocks
along with repeats. So a repeat is repeat and in parentheses the count of how many times
repeat which has to be followed by a block which gives you the body. But you can define
blocks otherwise also and inside blocks also you can declare variables. Okay, so here is how I
might choose to write the summing programs slightly differently. So in this summing
program the main differences that this term variable has been define inside. Otherwise the
entire program is the same. So this program is equivalent to the previous program, but it
really executes slightly differently. And it really says that look I want a term variable and it is
being used over here. So I might as well put the definition of it close by so I can quickly tell
that it was not initialized to anything and that it is an integer variable. So this is a device for
bringing the definition close to the users. So to that extent the program become a little bit
more readable. But the execution of this code is a little bit tricky.

145
(Refer Slide Time: 2:28)

So, how the definitions in a block execute? Well the rule are as follows. So a variable which
is define inside a block will get created every time the control reaches the definition. Then all
the variable define in the block are destroyed every time control reaches the end of the block.
Sso this term variable which we just saw will get created at this point and get destroyed again
at this point. So this as you can see does not really hurt us, because it really is useful only
within this region. So you read in value and you add it to s, s stays around because s is not
defined inside this, s was defined outside. So the rule of getting destroyed does not apply to
S. But whatever value we read in we actually got into s, so we do not care if term gets
destroyed. This means this program is going to be work exactly like the way we wanted to.
‘s’ will accumulate the values that get typed, the sum will get placed in s. But notice that
there is one more implementation that the variable term will not available over here. Okay, so
in some sense it is sort of a private or a local variable for this loop. That is in fact also a term
that often get used-that term is now made local to the body of this loop.

Now, when you talk about creating, you may think is not that of work. But in this case
creating is not really a much work or is not really any work, basically the compiler from that
point onwards starts using a certain piece of memory which it has any way. Okay, destroying
is also not any work because the compiler stops using that piece of memory. But yes, in some
other cases which we might see later, creating variables inside might has some cost. And for
that reason you may choose to not has variables define inside in but rather have the variables
defined once and for all outside if that is indeed what you want.

146
But in this case, it is a good idea to define the variables inside because it really says that that
variable term is not really important for the final result. It is something that is being use only
locally, whereas s is an important variable. It is variable which is more global.

(Refer Slide Time: 5:21)

Alright, now, once we have mechanisms to define variables at different places, we need to
carefully understand what a certain variable name refers to. So, if a variable is define outside
a block then it can be used inside a block just as the variable S was defined outside and it got
used inside the block. However, this can happen only if no variable of the same name is
defined inside the block. If a variable of the same name is defined, then from the point of the
definition to the end of the block the newly defined variable get used. So what is happening is
this the new variable is said to “shadow” the old variable. The region of a program where the
variable defined in a particular definition can be used is said to be the scope of the definition.
So the scope of the variable defined inside a block starts at the point of the definition and
ends at the end of the block.

Well why do we are care of all these things? So in some sense the programming is also like
writing text. Say you are a writing a long document. So in a single English language
document you might write “let x denote” in several places, so if you write on page 5 and on
page 7 then there is simplicity to understanding that the x on page 5 is different from the x on
page 7. So essentially we can say that the scope of that definition on page 5 is maybe from
the page 5 to page 37 or something like that or maybe it is from the page 5 to the end of the
chapter or maybe even the end of the section.

147
So in English language the scope is not very formally specified it is sort of left as understood.
But in programming since the computer has to do something with it, we have to be really
careful and talk about the scope. Okay and further more if you do not have an intervening “x
denote” then you can say that maybe the two x’ are the same of course you really do not want
the same x to be used so far apart or at least if you are using so far apart then you will warn in
an English language document, but in a program unless there is an intervening “x denote” and
if the x is not inside a block which is like a chapter where the scope ends, the two x’ really
can be considered to refer to the same concept or in case of the program the same variable.

So this is the motivation why we are being so finicky about scope and shadowing. If you do
not use the same names then this really does not apply but you will see that it does make
sense to use the same names and so this discussion will actually come in useful.

(Refer Slide Time: 8:32)

So here we can take an example, so we have a variable x so if we print it out then 5 will get
printed. And this x will refer to that definition. Now, if you print it again, again 5 will printed
but now if you write int x=10 since it a new block we are started a block this definition is
actually allowed. If we have not started a new block then this definition is actually not
allowed. C++ will say that look you already have variable called x how can you define
another variable?

But since we have started a new block, C++ most that you can have another variable. So now,
if you print x it will print 10. So say the block ends over here and suppose over here you print
x in this case 5 will get printed.

148
Okay, why? Because the scope of this x is limited to this region and over here or this point is
in the scope of this definition so 5 will get printed. So when you come out, name x will start
to referring to this variable over here. Now, I will leave you with a question if instead of this
int x=10 suppose I wrote x=10, then what to change? I would like to think this and write this
program and check your answer I am not going to tell you the answer.

(Refer Slide Time: 10:04)

So some remarks, we have come to the end of this lecture and I want to summarize what we
have done in this. So first we defined the variables are regions of memory which can store the
values. Variables have types and this type is used to interpret how the bits stored in that
region are going to be interpreted. Then, you are advised to choose variable names so that
they describe the purpose for which the variable is defined. And we said that when we use a
variable when that name if it appears at left hand side of an assignment actually refers to the
variable itself it refers to the region of memory. On the other hand, if it appears on the right
hand side then you really do not care of about the memory but you are saying give me its
value. So there is sort of dual view or this name sort of is interpreted depending on its context
and you should keep this is in the mind or may be this is in your mind but anyway.

(Refer Slide Time: 11:33)

149
So more remark, expression in C++ are similar in those in mathematics, except that value
may get converted from integer to real or vice versa and truncation might happen. Truncation
may also happen when values get stored into a variable. And sequence generation and
accumulation are very common idioms. Increment, decrement operators and compound
assignment operators also are commonly used.

(Refer Slide Time: 12:01)

And then we said variables can be defined inside any block. Variables defined outside a block
may get shadowed by variables defined inside. And this is, these are basically the main ideas
covered in this lecture. And at this point we have seen some rather interesting programs that
you could write and indeed by now you have to the point at which you can write several quite
interesting programs and we will see these programs in the next lecture. Thank you.

150
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 4 Part - 1
Program Design

(Refer Slide Time: 0:21)

Hello and welcome to the course on an introduction to programming through C++, this is the
second lecture sequence of the second week. The topic for today is a program design example
and the reading for this is from chapter 4 of the book.

(Refer Slide Time: 0:34)

151
So the main problem that we are going to consider in this lecture is how to write programs
and we have been writing some programs, we have written some simple programs and we
sort of wrote them automatically or intuitively if we will. Now, if you want to write more
complex programs, even slightly more complex programs, we need to approach this with care
because we might make mistakes and we might find it difficult to get out of mistakes and we
really should be worried about mistakes and also about how much time we spend on the
writing process.

So we should make our writing process efficient and we should also make sure that our
programs do not make any mistakes. Now, that is because the program could be doing here
very important calculations, maybe controlling the flight of a plane or maybe deciding how
much radiation to give to a patient, so you really cannot afford to make any mistakes in this.
And, so we should do sort of due diligence and it is important to learn what are the things that
you should do in order to ensure that your programs work correctly.

(Refer Slide Time: 1:59)

152
So the goal of the chapter is to develop a slightly more complex program, then what we are
seeing so far. And while doing this, we will follow a typical program development strategy,
so what is this? So this begins with the description of the specifications, the specification
simply and very concisely usually states what the input data is and what the output required
is. Now, if you are writing a program to solve a real-life problem, then the statement that
might be given to you, might be ambiguous or might be incomplete and so when you write
down the specification, you should try to make it as precise and as complete as possible.

Then we construct the test cases. So for what input, what output do you expect? Then we
think about how to solve the problem using pencil and paper, this is kind of the first
important seriously creative step. Now, here what you are expected is to really just mimic
manual computation, so the creativity is a little bit less important right now, but you really
need to pay attention to how you solve the problem manually, so you need to figure out what
the structure of that manual solution process is. Which means, for example, to decide whether
something is repeated, if so, how many times? And after this, you get to the program writing
stage and here the manual solution process will help you because the structure will get
reflected in the program and you also need to decide what variables to use, you can again
reason it out from the way you perform the manual calculations. Once your program is ready,
you run the test cases and if the program does not work correctly as might happen from time
to time, then you need to figure out what went wrong and you need to fix it.

153
(Refer Slide Time: 4:12)

The problem that we are going to look at is a very simple problem, so we have a series whose
value approaches e as n increases we have sum, so this sum is 1/0! + 1/1! + 1/2! all the way
till 1/n!, if you add the terms up, and as you take n larger and larger, you can see, you can
prove in fact that, that this sum is going to get close to e, is going to tend to e. So we are
supposed to take a program, we are supposed to write a program which takes n as input and
prints the sum of this series, whatever the value of n might be.

(Refer Slide Time: 4:49)

So first, let us come to the specification, well, the input there is only one, the integer n. So we
have clarified that n has to be non-negative integer, the problem does not make sense if we
have n negative and output is the sum 1/0!+1/1!, all the way till 1/n!. So notice that 0 as input

154
makes sense because then that is means that you get the first term, which is 1, that is, of
course nowhere close to e, but we did not really promise that it would get close to e for such a
small value of n in any case.

Now in this particular example, for this particular problem, the specification is fairly
straightforward. However, notice that even here we have added a bit of value, so when we
said that input is n, we also wrote down that it had better be larger than or equal to 0, in
general, when you write the specification or maybe say after you write the specification, you
should ask yourself, well, I have written this down, but are there any tricky points to it? Can
something be misunderstood? Even by mistake, because you do not really want any
misunderstanding because those misunderstandings may creep into your program as well.

So in this case, you may realise that, if you are careless you may think of n as also being the
number of terms to be added up, but that is not correct, 1/0! might be regarded as 0th term,
than 1/1! is the first term, 1/N! is the nth term, so they really are n plus 1 terms to be added
up, however, the number of additions you perform is actually n, so n does have some
significance, but not as the number of terms.

(Refer Slide Time: 6:54)

The next step is to construct the test cases, so here you just pick some input values, and you
calculate the required output values So for example, if we say n is 0, then the required is 1/0!
or 1, if we say n is 1, the required output is 1/0!+1/1!, which is equal to 2, if n is 2 than the
required output is 1/0!+1/1!+1/2!, which is 2.5 and this program really is meant for
calculating e and that happens at some large enough value.

155
So maybe we will see that if you pick say n equal to 10 over something like that, you would
like the answer to be close to the known value of e, which to so many decimals it is
2.718281828. Now, test cases will be really needed after you finish writing the program,
however, if you construct them early it is just the confirmation to yourself that look, I
understand what is expected of me, I have not missed out any point.

(Refer Slide Time: 8:17)

Okay, so what have we discussed so far? So we said that the first steps of the program
development process consist of the specification, writing the specification and constructing
the test cases. Next, we are going to turn to how to solve the problem manually, we will take
a break.

156
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 4 Part - 2
Program Design
Translate manual algorithm to a program

(Refer Slide Time: 0:22)

Welcome back, in the previous segment, we discussed the specification and the construction
of test cases. Next, we are going to look at how the problem is solved manually and what can
be derived from it. How do you sum this series manually? Let me remind you what the series
was, very quickly, this was the series, 1/0!+1/1!+1/2! all the way till 1/n!.

157
(Refer Slide Time: 0:47)

Okay, so you might say look, this is fairly straightforward in step 0, you may calculate 0
term, or 1/0! and that is just 1. In step 1, you calculate the first-term 1/1!, which is also 1 and
you add that to the preceding sum that you had, so the sum until this point was 1, so you add
this new one to that sum, then you calculate the second term, that is 1/2! and you add that to
the sum so far and so on, you calculate the third term 1/3! again add it and you do this until n.
Now, here is an interesting question, will you calculate each term independently? If you
actually try to do it, you will very quickly realize that you do not need to, very likely you will
calculate the third term by dividing the second term by 3, so the third term is 1/3!, the second
term is 1/2!, so that just needs to be divided by 3, in order to get 1/3! and this is a general
pattern, so in step I we need to calculate 1/I! and that is simply 1/(I-1)! divided by I. So in
step I you will take the term which was calculated in step I minus 1, divide that by I and add
it to do sum which you are keeping track of. Now, notice that general pattern is applicable to
steps 1 through N, not the step 0, because in step 0, there was no previous sum, nor was there
a previous term, so this means, for example, that you might think of having a loop to do the
work of steps 1 through N and step 0 might be something that you do before that.

158
(Refer Slide Time: 2:53)

Okay, so we have a reasonable understanding of what the manual computation is, now we are
going to move towards a program. So as we said the general pattern for step I is calculate the
Ith term by dividing the (I-1)th term by I and then adding it to sum. Now, we also said that
this pattern is applicable to steps 1 through N and not to step 0, alright, so this suggests an
overall program structure which is we perform step 0 separately and steps 1 to N put in the
repeat loop.

So that is good we have made progress towards the structure of the program and now the
question is what variable should we will using? So here you should ask a very standard
question, which is what do we need to have with us at the beginning of each iteration or in
particular iteration I. So these are the things you need, so you need the sum calculated in the
previous iteration. You also need the term calculated in the previous iteration, why? Because
we said that we will take that term and divide it by I okay, this is the number of the iteration
and then get what we want to add during this iteration and of course we need to know the
value of I, since we divide by I.

So these are the things we need to have and we need to have them from the previous iteration,
so which means we need to remember them, we need some mechanism to remember them, so
we are going to have 3 variables respectively to remember the sum, term and I and we are
going to call the variable capital S, capital T and capital I.

159
(Refer Slide Time: 4:53)

Okay, so now we are going to develop the program. So, what we have said so far allows us to
write this skeleton, so we have the main program, first we are going to read the input, of
course we are going to define the variable N, then we are going to define the variables we
said we need I, T and S and then we also said that we need the repeat loop and so we are
going to have repeat with count of N, and then finally we are going to have to print out the
sum, which we are hoping will be in the variable S.

And we also said that for the Ith iteration we would like capital I to have the value little i, we
would like capital T to be the value of the term added in the I minus 1 iteration or in other
words 1/(I-1)! and we also want S to be the sum calculated in the first I-1 iterations or the
value 1/0!+1/1! all the way till 1/(I-1)!, so this is our skeleton and now we are going to build
it up.

So, what we really need to do to make sure that the plan that we have written down. Okay,
can be realized. So, let us talk about the first iteration itself, can we make sure that the values
of I, T and S are as we have asked for? So for example, in the first iteration that is little i
equal to 1, we want capital I also to be little i or we want capital I to be 1. Likewise we want
T to be 1/(I-1)! or 1/(1-1)! or 1/0! or 1 again and S must be to 0 term of this series, so it is
also desirable to have S equal 1.

Well, the only way we can make sure that this happens at the beginning of the loop of the
very first iteration is, if we initialize the variables to the values, so that is what we are going
to do, so we are going to write an assignment statement I equal to 1, T equal to 1, S equal to 1

160
or separate statements and this implements our plan for iteration 1. How do you implement it
for the subsequent iterations?

Well, one thing you said was that in the Ith iteration we need to divide the previous term by I
and we have the value of the previous term, we are expecting to find it in the variable capital
T, so we should be dividing T by capital I. Now, the question is where should we put it? So
we are going to put it in T itself, and here is a reason for it, the value that T originally had
was 1/(I-1)! and this value we are not going to need, we are going to need the value that we
just calculated T upon I, which is 1 upon I factorial and since, T is going to be the variable
which in the next iteration is anyway expected to hold 1/I!, we might as well store that value
in T itself.

Next, we said that we are going to add the newly calculated term to the sum and in fact the
right statement used for that is just to say S=S+T, so note that this now means that
S=1/0!+1/1! all the way till 1/I!. And finally to prepare for the next step, we really should be
changing capital I to I plus 1, so that is what we are doing over here. So with these 3
assignment you can see that I, T, S now have the correct values for the next iteration.

So our work in this iteration is done, but not only that T, S and I we have changed, so that
they have the correct value for the next iteration, why is that? Well as we can see capital T
has the value 1/I! now, in the next iteration, which is (I+1)th iteration, it really should have
this value, then sum in the (I+1)th iteration should be the sum of all the terms from 1 over 0
factorial to 1/(I+1-1)! or 1/I! and that is exactly what we have here as we have written down
in that comment. And finally capital I should take the value I plus 1 at the beginning of the
(I+1)th iteration and that exactly is what we have done.

So we have followed our plan, not only that we have done exactly what we used to do in the
manual computation and therefore, we have finished writing the program. Now in this
program we put down some comments about what plan we are going to follow. So this is,
these are the black lines over here. So these two lines tell the user what our plan is, this is
absolutely necessary.

161
(Refer Slide Time: 10:43)

If somebody else is reading a program, they should know this and if they know this it will be
much easier for them to follow what is going on. Now, one more important point - the order
in which we updated T, S and I is very important. So for example you cannot update I first,
that would not really work, you cannot exchange the order of this statements, so since in
these statements each variable is going to have an old value and new value, we had better be
very careful as to taking into account what value it is that we want to add to which variable or
multiply each variable or whatever that case might be, and then make sure that the update to
that variable happens at the right time, in other words statement like these will have to be
handled carefully and the order of the statements is going to be really important.

So yes, so the considerations will be we want to divide T by the old value of I or the new
value and depending upon that the ordering should be done, the ordering of the statements
should be done or similarly, do we want to (see it, we want to, you want to ask) we want to
add the new T to S or old T?

162
(Refer Slide Time: 12:05)

163
Okay, so after this we are going to execute the program, so for this of course we should type
the program into a file or into the IDE, compile it, and then run and we should use the test
cases constructed earlier. So let see this. Here is the program that we just wrote. So that is
compile it and let us run it and let us try our 3 or 4 test cases, so the first was 0 and we were
expecting the value 1. So we got the value 1, let us try one more case, so when we type 1 we
expect the value 2 yes and when we try 2 we expect the value 2.5, let see if we get that? Yes
and finally, let us try some large value, say maybe 10 and we get 2.71828, which is in fact
exactly the value to 5 decimal places, so our programs seems to be doing just fine okay, so
here is what we discussed.

164
(Refer Slide Time: 13:20)

So we said that translating manual algorithms into computer programs is important and what
you are supposed to do during that is figure out the structure of the manual algorithm and this
will tell you how many iterations are needed for the repeat loop that you might use in your
computer program. Then you are supposed to identify what you need to remember at
different points of time in the manual algorithm and this will tell you what you should be
storing in what variables and this thinking about manual algorithm and figuring out its
structure and so on is probably the most important activity that you will learn in the course
okay, so please, please get it right. So we will stop over here and in the next segment, we will
see what to do if you make a mistake.

165
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 4 Part - 3
Program Design
Debugging

In the last segment, we looked at how to translate manual algorithms into programs. We ran one
program and in this segment we are going to see how we might recover if we make some mistake
in writing the program.

(Refer Slide Time: 00:38)

Okay, so here is an example. So this is the same program from last time except that these two
statements, so this statement and this statement their order has been exchanged. So in the real
program this statement came later and this statement came earlier, so we have exchanged it,
exchange the order.

166
(Refer Slide Time: 01:06)

Okay, so first of all this is a bad program, it will not give the correct answer and let us see that.

(Refer Slide Time: 01:15)

So here is the program in which the value of the statements has been exchanged. So I have called
it e-buggy.CPP. So let us compile that program. So it compiles fine. So now, let us run it. So let
us try our test case 0 so this seems to run fine.

167
(Refer Slide Time: 01:55)

Let us try our test case 1, oh this also seems to run fine. So maybe well, let us see. Let us try our
test case 2, so here there is a mistake. We were expecting a value 2.5 but we have got the value 3
okay all right. So, how do you recover? Well, there are three possible courses of action that you
can take and you really should learn all three because once in a while one will be more useful
than the other.

(Refer Slide Time: 02:29)

168
Sort of the simplest thing to do is to put print statements to see whether not just the final value
but whether the intermediate values are correct. What I mean by that is, you put print statements
the program will print out the intermediate values and then you go over the intermediate values
and you check are these the values that I was expecting or is something wrong?

Another possibility is not to put print statements, but do the same thing yourself. So you pretend
that you are the computer you walk over the program and on the side keep writing what values
different variables are and at the same time keep on reasoning - are these the values you expect
to see? And if not, then you have found a mistake. And the last way is to do the same thing but in
a symbolic manner. So rather than saying variable capital T has the value 1, we are going to say
what if the variable capital T has the value 1/I! and we are going to symbolically try and reason
out and see if everything is correct.

(Refer Slide Time: 03:43)

Okay so how, what do I mean when I say I put print statements? Well this last this red line okay,
so we should remember that as it is usually convenient to put print statements at the beginning of
the loop. So that is because our plan has also been made for the beginning of the loop. So we can
look at the values get that get printed and we can look at the plan and we can see whether
everything is fine. So our plan contains variables capital I, T and S. So those are the variables
that we are going to print okay so let us again see this in action.

169
(Refer Slide Time: 04:17)

So I have put in the statement in a program called eDebug. So this here is here is the line where
the print statements are there okay. So let us now compile and execute this. Okay, compiled and
let us say run. We know that this program makes a mistake for the value 2, so let us see what
happens over there. So if we print 2 we are going to see the intermediate values during the
iterations. Okay so here are the intermediate values. So the first time around when I was 1, T was
1, S was 1 okay this is as we expect, okay this is the very first iteration and in fact at this point
the variables just have the values that we gave to them.

170
In the next iteration, when capital I is 2, we expect the term to be the previous term that got
added and that was 1/1!. So in fact it is 1 so this is perfectly good. Then we expect capital S the
sum at the beginning of the second iteration to have the value 1/0! plus terms until we get the
term 1/(2-1)! or 1/1!. So there are just two terms 1/0! and 1/1!. So the value is going to be 2
which is also what we have expected.

So this means that there really was no error as far as the values were concerned in our variables
until the beginning of iteration 2. So let us just go back to the program. Okay so we have
discovered that this value is printed correctly and the values printed over here are correct and
therefore, something must be wrong over here in this statement because until now S was correct,
at this point S was wrong, so something is wrong over here. So if this statement is wrong, then
we are pretty close to the mistake and then all that we need to check is are we adding the right
thing over here?

So here we are adding 1 whereas we expect to add ½! to this, not 1/1! and therefore, we can see
that this is definitely wrong and now we can realize that look, this statement should come before
this and then everything will be fine. Okay, so we discovered what the error was and by the way
errors are called bugs in computer parlance at times and so we have figured out what the bug is
and this is also saying that we have debugged the program.

171
(Refer Slide Time: 07:29)

Another way of debugging the program is through manual program tracing. So here is our same
program and now we are going to pretend that we are a computer and we are going to execute it,
execute the program and keep track of what values the different variables have.

(Refer Slide Time: 07:40)

So to facilitate this it is often recommended that you make a table. So you have a column for
every variable. So let us not keep a column for n because n is going to be fixed once and for all
and it is not going to change. So let us keep a column for I, let us keep a column for T, let us

172
keep a column for S. So when we execute the first statement, which is this here, then these
variables get the value 1, 1, 1 okay then when we go to repeat n so let us say iteration 1. What
happens during that iteration 1? So first we are going to change S to S plus T, so as a result we
are going to get the value 2 over here. After that we are going to do T equals T upon I, so T
equals T upon I so we will get the value 1 over here and then we will have I=I+1, so we will get
the value 2 over here. Then we are going to go to iteration 2. So in this way we continue and will
realize that at some point the values that we have over here are different from the values that we
expect. So again at that point we proceed in the way we did in the print statement case.

(Refer Slide Time: 09:09)

So once we once we do that, we will again figure out that oh here is the mistake and then we can
remove it okay. Now, many experienced programmers prefer doing this manually rather than
putting print statements because somehow it feels that as you do this, you are getting to know
your program better and sometimes the print statements sort of are too confusing, there are too
many things that happen at once and yeah so it really depends on your temperament, but you
should definitely consider this.

173
(Refer Slide Time: 09:43)

Then the last and by no means the least important method is symbolic tracing. So again it is the
same program and the question that we are going to ask is let us assume that things have worked
out until this point. Well, we can check whether they have worked out at the first iteration. So,
how do we check that? We look at I equals 1, T equals 1, S equals 1. So that in fact has worked
out according to plan because I, T and S have exactly the values recommended over here. Now,
we are going to check symbolically whether we did the right thing that is whether our updates
are in fact doing what we want them to do. So, what is this update doing? It is taking the old
value of S and adding it to the value T. So we are going to we are assuming that the T value is
this, the S value is this. So now, if we add this value to this value what happens? Oh something
wrong. The last time over here was 1/(I-1)! and we are adding 1/(I-1)! to it, whence we should
have added 1/I!. So clearly we have made a mistake and again, if you think a little you will
realize that oh we really should have divided first so this statement should come first all right.

174
(Refer Slide Time: 11:06)

Okay, so let me conclude, so first I want to say that you must write down specifications clearly.
In this particular program things were quite simple, but if you take a real life problem, the
experience is that in many programming projects there are delays and people write wrong code
because they did not understand what was required of them. They did not understand what the
specification was. So please take the time to make sure that you are understanding clearly what is
expected of you. Then you should construct test cases because first of all they are useful when
the program is ready, but because they also are an indication that you are actually understanding
what is expected of you.

175
(Refer Slide Time: 12:00)

For much of this course, it will be sufficient for you to write a program that mimics what you do
by hand or what you do manually. For this you have to be quite conscious, you have to be very-
very intimately knowing what exactly you do manually. So think about what you do and think
about what structure it has. So for example you may ask, when I am doing solving this problem I
am doing these phases which look very similar. So you might ask how many phases? Because
that is going to tell you that oh I should use a repeat Loop and it should have so many iterations.

You should also state in general terms what each phrase accomplishes. So in terms of that phrase
number, so you should say something like phase number, in phase I, I am going to take the term
calculated in phase I minus 1 and whatever okay so it had better be general because generality is
what helps you write programs and as I said phases become iterations of the repeat statement and
you should note that you may want to number the phases, so you can number them conveniently.
In our case we started with fun but there may be other situations where may, it may want to start
with 0 and you should determine what you need at the end of the phase or at the beginning of the
phase. So the end and beginning are really very similar because the end of phase I is the
beginning of a phase I plus 1. So in any case you need to know what it is that you need to
remember at that point and those - the things that you need to remember will need variables.

(Refer Slide Time: 13:58)

176
Okay, so the structure that we had in this program is actually very common. So what is that
structure? You have a set of variables and you want them to assume specific values at the
beginning of iteration I, where I is anything, I could be anything for all possible values of I you
know what values they need to take. So this knowledge should be put in the code in form of
comments, and this knowledge, what values are desired is often called the invariant for the loop,
okay. So for all loop iterations this statement has to be true and therefore it is called an invariant.

You can ensure that the invariant is true for the first iteration by initializing variables correctly
before you enter the loop. Now, for the subsequent iterations, you can assume that the invariant
is correct at the beginning and then you should change the values of the variables so that it
becomes correct at the end, okay, so that is what the code in each iteration is supposed to be
doing and to get this right it is good to be careful, it is good to ask-look I want the value of this
variable to be divided by this variable. Now, it could be the value at the beginning, the value at
the end which value am I supposed to use? So be very careful about that and then it will make
sure that your statements, your updates will happen in the right order.

177
(Refer Slide Time: 15:45)

If you write a program and it does not work correctly, you should not give up hope, you can
make sure that it runs, you can attempt to remove the bug, the error so for this you can put print
statements to check with the variables have the values you expect in each iteration. You can trace
or manually execute your code or you can symbolically execute your code.

(Refer Slide Time: 16:14)

Now, I am going to leave you with an exercise and this is again the same series that you are
supposed to calculate, except the plan or the invariant given to you is slightly different over here

178
okay. So the invariant is stated in those comments and you are required to complete the
initialization and the loop steps and make the program work correctly.

(Refer Slide Time: 16:41)

Okay, so this is the end of this lecture sequence and I will strongly urge you to try the other
exercises given at the end of chapter 4, which is the reading for this lecture sequence. Thank you.

179
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 05
Simplecpp Graphics
(Refer Slide Time: 0:41)

Hello and welcome to the third lecture of the second week of the course on an introduction to
programming through C++ for NPTEL. The topic of this lecture sequence is Simplecpp
Graphics, so in simplecpp graphics a lot more is possible besides moving turtles. So you can
have other shapes also besides turtles. You can change the colour and size, you can have absolute
coordinates, so relative to canvas and graphical input is also possible.

180
(Refer Slide Time: 0:56)

So to start up this more general graphics, you have to use initCanvas and not turtlesSim. So the
first form of initCanvas is, initCanvas() without any arguments and this will just open a window
or the canvas for drawing. And the second form, you can give a name to that window and you
can also say how wide that window is going to be and how high it is going to be, okay so the
name should be quoted string and w and h should be numbers.

(Refer Slide Time: 1:32)

Now, the drawing area or the canvas has a coordinate system. So the canvas origin is in the top
left corner, the x axis goes rightwards as you are normally accustomed to, the y axis on the other

181
hand goes downward rather than upward as you might be more commonly using in math. Then
the commands that you use, may not all use the coordinate system but there will be some
commands which will use the coordinate system.

(Refer Slide Time: 2:06)

Okay, so how do you create other objects? Well, let us start with how do you create many turtles,
rather than use just the one that is given to us. So the general form is to say something like turtle
n1, n2, nk where n1, n2, nk are the names that you are going to give to the turtles that you are
going to create. So this is going to create k turtles having names n1 through nk and of course any
identifier can be used.

Initially all the turtles are at the centre of the canvas and all are facing right, like our single turtle
but that single turtle which you got by default is no longer going to be there if you used
initCanvas. You can selectively move the turtle whose name is ni by writing ni.forward(50) or
whatever rather than just forward(50). So since, you have several turtles you have to say which
turtle you are talking to. And others command like left, right can also be used instead of forward.

182
(Refer Slide Time: 3:16)

Okay, so just to give you a sense of what we can do, here is a programme and in it we have the
first statement is just this initCanvas statement so the canvas is created, then we are going to
create three turtles and as I said they are going to be at the centre and facing right, but now we
are going to tell different things to the turtles. So the first, t1 will leave as it is, turtle t2 we’ll ask
to turn left by 120 degrees, t3 we’ll ask to turn left by 240 degrees.

(Refer Slide Time: 4:14)

And now we are going to get the turtles to move, so all of them are going to move forward and
all of them are going to turn left by 360 by 8 degrees, so each one of them is going to be drawing

183
an octagon, okay. So lets us see what happens, okay so the program that we wrote and let us now
executes it.

(Refer Slide Time: 4:19)

So we will compile it first, so let us execute it. See that? each turtle was moving as we
commanded. The turtle went out but again came back in as soon as it’s coordinates became
consistent with the material of the canvas okay, so we just did this.

(Refer Slide Time: 4:46)

184
Now, we are going to turn to creating other graphical objects, in general to create a general
object, you do something like what you do to create a variable. You are going to give the type,
this time the shape type and then the name along with the arguments. So the shapes that you can
create are circle, rectangle, line and text, so the name that we have in this basic form is the name
to be given to the created object and you can move the created object forward or in general
manipulate it by writing name dot whatever operation. So if you write name.forward(100) then
you will be moving that object forward by 100 pixels, so each object will have a current direction
in which it is facing and that, and forward will cause that object to move in current direction.

And we already saw this that multiple objects of the same type can be created by giving comma
separated names with arguments. And all these objects also have pens, but unlike turtles whose
pens are down by default these other objects have their pens up, so they will not draw by default.

(Refer Slide Time: 6:10)

Okay, so how do you create circles? So we are going to supply 3 arguments, the first two are the
x, y coordinates of the centre and then the radius. So for example, if I write Circle
c1(100,100,10) that gives me one circle at centre (100, 100) of radius 10, the second c2
(100,100,20) will give me another circle at the same centre but with radius 20, so these two will
be concentric circles.

185
(Refer Slide Time: 6:41)

I can make rectangles, so I can make a rectangle called r1 and the first two numbers are going to
be interpreted as the x, y coordinates of the centre. So in this case (200,100) is the centre of the
rectangle and the width is 20 and the height is 40.

(Refer Slide Time: 7:01)

I can create lines and I just have to supple the coordinates of the first endpoint and then the
coordinates of the second endpoint. So for example, here I have a line starting at (20, 20) going
to (20, 30) So (20,20) the x coordinate remains the same, the y coordinate goes from 20 to 30, so

186
this going to be a vertical line. The second line is (25,15) going to (25, 25). So, this also is a
vertical line, it is going to be a vertical line at x coordinate 25 and it will go to 15 to 25.

(Refer Slide Time: 7:44)

Okay, I can create text if I wish, okay so I supply the x coordinates of where the text is to be
centred, and then the text itself in quotes and along with text I have these two additional
commands, text width of the text tells me how wide the entire text is going to be and text height
of t tells me how high the text t is in pixels. And using this I know what the size of the text is and
so I know, I mean, I can do my layout a little bit better.

So here is an example, first I am going to create the text centred at the point (100,100) and
having the text itself being C++, so C++ will be written at (100, 100). Then I am going to create
a rectangle, this rectangle is also centred at (100, 100) and its text width is, the text width of C++
plus 4, so it is going to be two pixels outside on each direction. And text height is also similar, so
it is going to create a rectangle which sort of borders this text, okay so it sort of fits reasonably
snugly. So this way you can sort of create nice, nice buttons, if you like so you might have seen
programmes in which there are buttons so buttons are maybe rectangles with text and this how
you might create buttons.

187
(Refer Slide Time: 9:19)

Okay so, there are some commands allowed on shapes so for example I can say move shape s to
coordinates x, y, so x, y are absolute coordinates over here, the shape which was created at some
other point has moved to coordinate x, y. So by the way when I say move a shape, what moves is
its centre, so the centre of the circle moves, the centre of the rectangle moves and for lines also
the centre of the line moves.

I can move by giving a relative displacement, so if I say s.move(dx, dy) then it its original
position was x1, y1 then the new position is x1 plus dx and y1 plus dx, okay. I can scale a shape,
so if I say s.scale(2) then that shape will become twice as big, its centre will remain where it was
earlier, so around that centre it will become twice as big. I can rotate it and it rotates again
around the centre so here I specify the angle, okay and this angle must in radians, okay so it is,
and radians is actually the more common measure on the computer just as it is more common
measure in scientific work. Now rotation and scaling, as of today cannot happen on text, but
there are, there are efforts to change that.

188
(Refer Slide Time: 11:02)

When a graphic subject is created it has the colour black except for turtles which are red, but the
colour can changed. So you can write if s is the graphic subject or s is the shape that you created
then you can change its colour by writing s.setColor(col) so notice that the spelling over here is
c-o-l-o-r sort of paying homage to the American spelling which was used in the logo language
from which we said this turtle graphic has been inspired. So this will change the color of s to col,
col must be specified as this text color and in parentheses the actual name of the colour red or
whatever so common colour name are recognised so you can just specify them.

Another way is to said the colour to whatever fine shade you want and as you might know
colours on a computer are obtained by mixing the primary colours red, green and blue, so you
specify what fraction or what amount of red you want, what amount of green you want, what
amount of blue you want and you get their mixture. And these numbers red, green and blue must
be between 0 and 255. Let me just observe that if you make all of them 255, you will get the
colour white, and if you make all of them 0 you will get the colour black.

189
(Refer Slide Time: 12:36)

If you assign a colour to a shape, it only really changes the border, but if you want it to change
the interior them you have to say, you have to fill the shape, so for this you have to say
s.setFill(), so setFill you can set to true or false and true means that I want the interior filled and
false means I want the interior left white. So this is allowed only when s is a circle or a rectangle
and for others this does not really makes sense.

(Refer Slide Time: 13:13)

Once you have drawn a shape you can ask where is the shape currently and s.getX() will return
the x coordinate of that shape or the x coordinate of the centre and similarly, s.getY() will give

190
you the y coordinate of the centre. Similarly, s.getOrientation() will return the current
orientation, that is the angle through which s has been rotated so far. So remember that the
originally all shapes start facing the right direction and so from that the orientation is measured.

getScale(), returns to you the current scale factor, so you might have done fair amount of scaling
so the end result of that is return if you right this command. So this command evaluates to the
current scale factor used for s. So you could have known that yourself because after all you were
the one who issued the scale commands, but this is a way by which you do not really have to
keep track of all things which you did.

(Refer Slide Time: 14:27)

One useful operation is to imprint a shape, so s.imprint() will cause an image of s to be


permanently drawn on the canvas at its current position. Okay so even after s moves, the image
will be present. If you wish to create a static picture involving 100 circles or some other objects
then it is better to follow this procedure, so you create one circle, you move it to the appropriate
positions and you imprint the circle in those positions. Rather than that you could have also done,
create 100 circles, but that usually is going to be cumbersome and that usually also takes more
time because C++ will have to keep track of all those circles as it draws and things like that. So if
you are, if you are not going to have circles which move then it is better to get them into your
picture by imprinting them.

(Refer Slide Time: 15:39)

191
You also have graphical input and for this you have the command getClick(), so this will cause
the program to wait until the user clicks on the screen. This is sort of like the cin command, the
cin command causes the program to wait until the user types something, getClick() program
causes to wait until the user clicks. This command returns the value 65536, which is 2 raised to
16 incidentally, times x, plus y, where x and y are the coordinates of the cursor position at the
position of the click. So you can wait for the user to click and you can get the point where the
user clicked.

So, how do you get the points? Well this is how, so you do not just issue the getClick()
command, but you say int w equals to getClick so that expression 65536 times x plus y will get
put into w. Now if you take the quotient that has to be your x coordinate and if you take the
remainder that has to be the y coordinate, so this how you can discover the coordinates where the
user clicked, okay. And this will work provided y is smaller than 65536, but of course the
number of pixels in any device that you might have is likely to be way smaller than 65536 and
therefore, this scheme works quite nicely. So you may also write just getClick() and not
something equal to get clicked, in that case your program will just wait for a click to happen and
whatever value that it receives by looking at the positions of the mouse cursor those are just
going to get thrown away.

192
(Refer Slide Time: 17:41)

So let us do an example, so here is a main program, so we are creating a canvas and we are
calling it projectile, so this is going to be the title that will appear on the window and I am going
to have an integer int start=getClick(), so immediately after creating the canvas, I am going to
wait for a click to happen. So I am going to create a circle next, but its x coordinate, the x
coordinate of the centre is going to be start divided by 65536 or it is going to be that the x
coordinate of the click position. And the y coordinate is going to be start mod 65536 or in other
words the y coordinate of the click position, so this means that the circle is going to be centred at
the point at which you clicked and its radius is going to be 5.

193
So, circles normally do not have their pen down, so we are going to make the pen go down and
now we are going to do something fun, we are going to have velocities for this circle. Well there
is no formal velocity as such but we will sort of make it appear as if there is a velocity, so we are
going to say that the x velocity is 1, the y velocity is minus 1 and then there is gravitational force
of 0.01. So notice that we have our vertical velocity is minus 1, so what is vertical velocity? So
what is minus 1? So minus 1 nearly says that our object will want to move in the negative y
direction, so what is the positive y direction? So the positive y direction is going downwards as
we said at the beginning of the lecture. So the positive y direction is going downwards and so the
negative y direction is going upwards. So initially, our object has been assigned velocity. So
suppose we clicked at this point, then a circle will be created over here and unit velocity will be
assigned in both directions. So our object will be disposed to move in this direction. Now, we
will make the object move, so we will make the object move for 500 steps. So in each step the
object will move by vx, vy. However, in each step the velocity will also change, the velocity will
change by 0.01 which is going to be the effect of gravity of course, this is just make believe but
this says that the y velocity will increase by 0.01, remember that y velocity initially is negative
so as it increases by 0.01 its velocity is going to be decreasing so it was going, it was moving
very fast in the upward direction. It is going to slow down in the upward direction and eventually
it is going to start moving fast in the downward direction.

Notice that this is exactly what happens to a stone when you throw the stone in the air, initially it
has a vertical upward velocity and gravity acts on it and gravity pulls the stone down and also its
velocity faster and faster in the downward direction. So in order for you to see what is going on,
we are going to wait for about 100th of a second, okay and that is it. So after the whole thing is
finished we are going to wait for you to click so that you get a chance to see what has happened.

194
(Refer Slide Time: 21:28)

195
So alright, let us do a demo of this, so the program is called a projectile. So this is the program
which I showed to you, okay. So let us, let us compile it and let us run it. So you can see that a
window has been created, the name, projectile appears at the top and now the program is waiting
for me to click on the screen. So suppose, I click on the screen you see a circle got created, sort
of a ball and it is moving, it is moving against gravity, gravity is pulling it downwards and it is
going to move for 500 steps. So it is going to move for 500 steps and in this case the 500 steps
took it outside the canvas but that is okay. But once that entire thing has been drawn, it is waiting
for me to click so let me click and that is the end of the program.

196
(Refer Slide Time: 22:53)

Okay, so you can do lots of interesting things with what I have told you, so for example you can
draw a plot of arbitrary functions say y equals to sin(x), so, how do you do this? Well you have
to decide where exactly that plot has to be drawn, so you will not supply the actual x coordinates
and you may have to scale this whole thing a little bit, but I will let you think about it, but the
one point that I must mention here is that it is a curve which you will have to approximate by
lines. And those lines will be drawn by imprinting because there will be lots of small lines and
you really do not want to create all those lines. Then there are a couple of other exercises and
well you can just have fun drawing some nice designs or doing some nice animations.

197
(Refer Slide Time: 23:42)

Okay so, to summarise, you can have graphical shapes with names and circles, lines are only
allowed, but can move them, you can rotate them, change their colours. Text is also allowed and
the book gives more details. Later on in the course we will see that polygons can also be drawn
and later on we may see how dragging and things like that can also be done.

So these are basic things that you have learned in this lecture and you can already use them to
create interesting drawings and animations and in fact even graphical editors, we will see that
very soon. Thank you.

198
An Introduction to Programming through C ++
Professor Abhiram G . Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 6 Part - 1
Conditional Execution
Hello welcome to the NPTEL course on an introduction to programming through C++, I am
Abhiram Ranade. Today’s lecture is about conditional execution and the reading for it is
chapter 6 of the book.

(Refer Slide Time: 0:39)

So let me begin with an example, suppose, we want to calculate income tax. So, let us say we
want to write a program which reads the income and prints the income tax and the rules are as
follows: if the income is less than 180 thousand or 1 lakh 80 thousand, then tax must be 0. So
0 should be printed, if the income is between 180 thousand and 500 thousand, then the tax
should be 10 percent of the income over and above 180 thousand.

If the income is between 500 thousand and 800 thousand, then the tax should be 32 thousand
plus 20 percent of the income above 500 thousand, and if the income is above 800 thousand
or 8 lakhs, then the tax should be 92 thousand plus 30 percent of whatever income is there
above 8 lakhs. Now, you will realize that you cannot write this program using what you
already know so we need to know something more.

199
(Refer Slide Time: 2:11)

So here is what we are going to do in this lecture, I am going to talk about a new statement
called an ‘if’ statement which will be useful in writing this tax calculation program and
several other programs. So we will begin by looking at the basic form of this if statement. We
will use that basic form to solve a simplified tax calculation problem well actually we are not
going to be calculating tax, we will see this simple problem in a minute. After that we will
see second form of the if statement or the so called ‘if-else’ statement. Using this we will be
able to write a better program to solve the simplified problem. Finally, we will study the most
general if statement form and using this we will be able to do our full tax calculation
program. After that, we will write, we will see how to express compound conditions. So I
have written complex over here, but I really mean compound. After that we will do a case
study we will have a somewhat larger problem that we will solve and this will be about
controlling the turtle in a different manner. Then, we will learn about the switch statement
and we will see yet another way of controlling the turtle. Finally, we will study something
called logical data.

200
(Refer Slide Time: 3:55)

Okay, so let us start with the basic if statement. So the form of this is ‘if(condition)’ and then
the consequent. Here, condition is Boolean expression and I will explain what this means in a
minute. A Boolean expression is something that evaluates to true or false, we will see this.
Consequent is a C++ statement, for example, it could be an assignment statement and
consequent could also be a block, again what I mean by a block is a set of statements
enclosed inside parentheses. Now, the way this condition executes is as follows. So if, so we
evaluate the condition and it if it evaluates to true, then the consequent is executed. If
condition evaluates to false, then the consequent is ignored. I have not told you what exactly
the condition is and what it means to evaluate it. I will do so next.

201
(Refer Slide Time: 5:12)

Okay, so a condition is as follows, so I am going to first tell you what a simple condition is.
A simple condition looks like some expression followed by something called a relational
operator followed by another expression. So a relational operator can be the less than symbol
(<), the less than followed by equal to characters which together constitute the less than or
equal operator (<=) or two equal to characters (==). So these two equal together constitute the
relational operator equal. Notice that, if I just write the equality then in C ++ this means the
assignment operator. So since we have already used the equality for the assignment operator
now we have to use something different and C ++ designers decided that we will write equal
to equal to, to denote the relational operator which compares two expressions. Similarly, we
have a greater than (>) as a relational operator, greater than or equal to (>=) as relational
operator and not equal (!=), so not equal is the exclamation mark followed by the equality
character. So remember that there should not be any spaces between the exclamation mark
and the equality and similarly between greater than equal and so on.

So, the condition is considered true if expression 1 relates to expression 2 as per the specified
relational operator ‘relop’, so let me take this through examples. So suppose we have x=5,
y=10, z=100. Then if we write x>=y, then that is going to be false because 5 is not greater
than or equal to 10. If we could write x*x>y, now x is 5 and x square is 25, 25 is greater than
y because y is 10. So therefore, this expression, this condition x square greater than y is going
to evaluate to true.

So another example, I could write x*y-z==10, so, what is x times y? x times y is 50 minus z
minus 100 the whole thing is minus 50 and minus 50 is not equal to 10 and therefore, this

202
entire condition is false. So what I told you over here is I have told you what conditions are
and what does it mean to evaluate that. So now, I have told you everything that you need to
know in order to understand the ‘if’ statement.

(Refer Slide Time: 9:17)

Okay now, it is customary to describe the if statement as a flow chart and what is a flow
chart? It is a pictorial representation of a program or a statement. So in this, statements or
even parts of statements are put inside boxes and if box C will possibly be executed after
some box B then we put an arrow from B to C. So this allows us to understand how control
flows in between the statements so the arrows indicate how the control flows and therefore,
such a chart is called a flow chart.

Now, this is specially convenient for showing conditional execution because in conditional
execution there can be more than one next statements. So if I have a condition, if something
consequent, then I may execute the consequent after checking condition, but I may not, I may
directly go on to the next statement. So this is possible to be shown very clearly using a
flowchart and assignment statements are usually put in rectangular boxes. Diamond shaped
boxes are used for condition checks, so we will see this in a minute.

203
(Refer Slide Time: 10:38)

So, if I have a statement if condition consequent then its flowchart is as shown in this picture
okay so this statement will be preceded in the program by a previous statement, so its flow
chart will come over here this program this statement will be succeeded in the program by a
next statement and its flow chart will come over here. So the idea is that previous statement
will get executed followed by after that it is executed then a the control use this arrow to enter
the if statement and now the condition is going to be evaluated. Now, this diamond indicates
the condition and if the condition comes out to be true, then the control moves out in this
direction where we have put true. So if the condition is true then after that the consequent will
get that evaluated, after the consequent is evaluated the control will come out and it will go
on to the next statement. If on the other hand the condition was false, then this branch is taken
out of the diamond and it will directly go to the next statement. So what I have told you using
this flowchart is not really different from what I told you earlier. However, I believe that this
is likely to be perhaps clearer or more easy to see, it is probably more easier to see what is
going on over here rather than when I wrote down that text where I gave you that text
description.

204
(Refer Slide Time: 12:33)

Okay, so now, we can write the code to just determine if any tax is owed, so this is a
simplified problem, our original problem was calculate the tax actually. Now you are saying
let us just do something simple first, just determine if any tax is owed. So we are going to
read in the income, but having read in the income we are just going to print a message saying
yes tax is owed or no tax is owed. Okay, so here is what the program looks like you probably
will be able to write it so I am not going to make deal of explaining it and let us just jump
into it.

So first I am going to have a variable in which we are going to store the income and maybe
we will have a variable tax. In this case variable tax is useless, but it does not matter we have
it, then we are going to read in the income, so we are going to read the income form the
keyboard, we could have put in the message saying cout give your income, but that is okay.
So, let us say that is understood when the user invokes our program the user will type that
message anyway without receiving any prompt for it. If, now we check if the income is less
than 180000 you remember from the rules that in that case there is no tax, so what do we do?
So then we are going to cout “no tax owed”, alright? However, if income is bigger than
180000 then we are going to print out “you owe tax”, okay so we read the income then we
compare that with 180000 okay so this is expression 1, this is relational operator and this is
expression 2.

If the income is actually less than 180000, we execute the consequent which is this and the
consequent simply requires us to print this message. So, if we execute this and if it comes out
to be true, we execute this and we come on to this statement, if this comes out to be false that

205
is this income is bigger, then we directly come to this statement without printing anything so
far.

So in any case after executing the statement we come over here control comes over here and
we check is income bigger than 180000, if it is bigger than 180000 than we are going to print
a message saying “you owe tax”. Otherwise, we are going to directly equal go to the next
statement so the next statement is not there so we terminate the program okay so very simple.

Now, from the description that I just gave you will observe that I am going to check both
these conditions on every execution, okay. So I will this condition and maybe I will print out
this message or maybe I do not printout this message, but I again so I subsequently check this
condition, okay. So the program is correct, okay it does what we want to do, but you may
observe and you may be think it surprising that the program needs to check both of these
conditions because after all if the first condition is true then we know that the second
condition must be false so why should we check it. So, we will see that this can be remedied
and we can write a slightly better program for this okay so anyways to summarize this, this is
a perfectly fine program it does the job we want except that it checks a condition 2 times and
you would like to know if we can avoid checking twice and indeed we can.

(Refer Slide Time: 16:48)

Okay, so for this we need another form of if statement so this form is ‘if(condition)-
consequent, else-alternate’, so in this the condition is first evaluated, if it is true then
consequent is executed, if condition is false than alternate is executed and alternate as well as
the consequent can both be blocks.

206
Okay, so what does it mean to have a block over here? So it means that if condition is true all
these statements in the block will be executed and likewise if the condition is false all these
statements in the block over here can be executed will be executed.

(Refer Slide Time: 17:37)

So here is, if else is a flow chart so after executing the previous statement before the if else
statement we enter the flow chart of the if else and the action that we perform is we evaluate
the condition, if the condition is true we proceed out of this branch and then we execute the
consequent after executing the consequent we go on to the next statement in the program. If
the condition is false we proceed out of this branch we execute the this branch we execute the
alternate and we after that we go to the next statement.

207
(Refer Slide Time: 18:30)

So, you will see that this statement was sort of design to improve our tax calculation program
so here it is we are we have the same part so far but now instead of checking whether income
is greater than 180000 since we already know we can just say “you owe tax” because the else
is going to be executed exactly if income is greater than 180000. So the else part or the
alternate part will be executed only if income is bigger than 180000 in which case “you owe
tax” will be printed. So in other words what we have do is, we are done is we are checking
the condition only once, only one condition is being checked and so in that sense this
program is a little bit more efficient than the previous program and also it is a little less
verbose. So by writing else you immediately understand what is going on, otherwise if you
write the whole condition again then you have to carefully observe that oh that this condition
is really the compliment of this condition, by else you know much more clearly that this is
going to be executed or this is going to be executed, one of the two is going to be executed.

208
(Refer Slide Time: 19:56)

Okay, so an exercise write an program that reads in a number and prints its square root. If the
number is positive, it should use the square root function, your program should use the square
root function. If the number is negative, your program should invoke the square root function
on the negative of the number. So that will be a positive quantity therefore, you can invoke
square root on it and so you should print the result followed by the letter ‘i’ to indicate that
the result is imaginary.

(Refer Slide Time: 20:36)

So, what have we discussed? We have discussed 2 forms of the if statement. Next, we will
discuss the more general form, but before that let us take a quick break.

209
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 6 Part – 2
Conditional Execution
Most general form of if
(Refer Slide Time: 0:22)

Welcome back, in the previous segment, we discussed 2 forms of the if statement and now we
are going to discuss the most general form of the if statement.

(Refer Slide Time: 0:30)

210
So this is as follows, it begins with; if (condition) consequent. But now we are going to have
many condition and consequent, so now we will just write condition 1 consequent 1. elseif
(condition2) consequent2, and you can have several such elseif, condition 3 consequent 3,
condition 4 consequent 4 and so on. And finally the last statement the last condition, will be
if(condition n) consequent n. And followed by that you can have else alternate. And this else
alternate is optional. So how does this work? Well, we are going to evaluate conditions in order,
okay, so condition 1, condition 2, condition 3 and so on. If some condition turns out to be true,
then we execute the corresponding consequent. But once a condition is found to be true, we do
not evaluate subsequent conditions. So we, deem the execution of this statement to be over at
that point and we go on to the next statement of the program.

If all conditions are false, so condition 1 through condition n, all of them turns out to be false,
then we execute the alternate, if it is specified. If it is not specified then we just declare that, this,
the execution of this if statement is over. This entire, this entire statement say from here to here,
gets over if these conditions are all false, and the alternate is not specified. And as always
consequents and the alternate can be blocks, or single statements.

(Refer Slide Time: 2:39)

So I want to describe the if statement, suppose it has 3 conditions, then what it would look like?
We draw the flow chart for it. So let us see, so over here, we have the flow chart of the previous
statement. So control executes the previous statement and now enters, this is now trying to

211
execute our if statement. So our if statement has 3 conditions so it executes the first condition,
condition 1 is executed, if it is true, then what happens? Well in the case, consequent 1 is
executed, not only consequent 1 is executed but we know that after that, none of the other
conditions are executed or their consequents are executed, we directly go on, to the next
statement of our program. Declaring that this if statement execution is over, so that is what, this
branch is saying. If this condition 1, that we executed turned out to be false, then we execute,
then we execute condition 2. If this condition 2 is true, then we take this branch and execute
consequent 2. And then we go to the next statement of the program. If this condition 2 is false,
we execute condition 3 and then if that condition 3 is true we go on this side, execute consequent
3 and go on to the next statement. If this condition 3 is false, we go on this side and if there is an
alternate specified, it will appear over here otherwise this branch will directly go on to this part.
So that is how an if statement with 3 conditions, would look like if you drew it as flowchart.

(Refer Slide Time: 4:39)

Alright, so what about our tax calculation program. So now you should be able to write it, so as
before we are going to have, variables; tax and income. And we will read in the income into the
variable income. Now, if income is less than or equal to 180000, we are going to say tax is 0,
okay. And now we will use the more general if statement, so else, that means if this condition is
false, then we check this condition, if income is less than 500000 then what do we do? Well then
we say that the tax is equal to income minus or excess of income over 180000, 10 percent of that.
So that is what this expression is implementing. So remember, that this expression is going to be

212
executed if this was false and this is true. So what does that mean? So if this is false, then the
income is above 180000, but if this is true then it means the income is less than 500000. So
indeed, this statement will be executed only if the income is greater than 180000, but is less than
500000 exactly as we wanted. But if the income is greater than 500000, then we come to this
part. But again we are going to make one more check, if the income is less than 800000, okay.
Then the tax is income minus 500000, 20 percent of it plus 32000.

Again let me indicate, when is this statement is going to, when is this statement is going to be
executed? Well for that statement to execute, this condition must be false, this condition must be
false. But this condition must be true and that happens precisely when, income is bigger than
500000, but less than 800000, okay. And finally, if the income is bigger than 800000, then the
last part of a rule is used which is the excess income above 800000, 30 percent of it plus, 92000.
And so, that concludes this if statement. So this general if statement looks, very large that is what
is concluded. And then we print out the tax.

213
(Refer Slide Time: 7:39)

I have shown, this program, the entire program as a flow chart now. So first we are going to read
in the income, then we are going to check, is it less than 180000, if it is, then there is no tax.
Otherwise, we check is it less than 500000, if it is then the tax is 10 percent of the excess.
Otherwise we check, if it is less than 800000, so then the tax is as per this box. If it is bigger than
800000, then it is as per this box and at the end, we just print the tax.

(Refer Slide Time: 8:18)

Okay, now I am going to show you a very small modification of the previous program, okay. So,
so far it was the same but here instead of writing else if income less than 500000, tax is and so

214
and so. Else if income is less than 800000, tax is so and so, okay. So I would like you to,
mentally execute the program. And tell me whether this program is doing exactly the same thing,
as the previous program. When I say tell me, I mean think for yourself, okay. So, for which
values of income, will it do exactly the same thing? For which values of income possibly will it
do something different? Or in other words, if it does the same thing for all values, then it is
exactly the it is a correct program. It is a program that which does the same thing as the previous
program, which we said was correct.

But if it does something different for some values of income, then it is a wrong program and I
would like you to tell me whether this program is right or wrong and if so, state what error it
makes that is for what values of income will it produce an error?

(Refer Slide Time: 9:44)

So what did we discuss in this segment? We discussed the most general form of if and we used it
in our tax calculation program. Next, we are going to see more general ways of specifying
conditions. So we will take a break.

215
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 6 Part – 3
Conditional Execution
Most general form of conditions
(Refer Slide Time: 0:23)

Hello, welcome back. In the previous segment we discussed the most general form of the if
statement, in this segment we are going to see a more general way of specifying conditions.
Sometimes the simple conditions that we used may not be adequate. So now, we will see a more
general way of specifying conditions.

216
(Refer Slide Time: 00:46)

So for example, we might want to say that look do this if some two condition are met rather than
just 1 some 2 conditions were true or we might want to say that do this if one of the one of some
two condition is true. So for this we need something called compound conditions and this is how
we write them. So here is an “AND” compound conditions so the way it is written is condition 1
“&&” condition 2 okay.

So we will see example of this but say if we could we could write this as if X>5 && Y>7
something like that. So when is this condition, is true? Well it is true only if both these
conditions are true okay. So if you put this in a “if” statement if say you write “if” this whole
thing as your condition as your compound condition then, the consequent is going to be executed
if both of these conditions are true okay. I can have an “or” condition as well so an “or”
condition looks like condition 1 “||” condition 2 okay and the whole condition this whole
compound condition is deemed to be true only if at least if and only if at least 1 of these
conditions is true. Both not need to be true if one is true that is good enough. So again if we put
this as a condition this entire thing as a condition in an “if” statement then the consequent will be
executed if one of these is true and finally we have a “NOT” compound condition this is written
as exclamation mark followed by a condition and this is true if and only if this is false. So,
sometimes we want that we want to do something if the given condition is false rather then, if it
is true. So in that case you can write by putting a “NOT” over here.

217
Now the components or the conditions included inside compound condition may themselves be
compound conditions okay. So for example, you might write something like condition 1 &&
condition 2 || condition 3 so this is allowed, so how does this work? Well we first evaluate
condition 2 || condition 3 or condition 3. So that means we check is one these conditions true. So
we want one of this condition to be true and we want condition 1 to be true actually the order
image we do the checking is from left to right so we first check whether this is true and then we
check whether one of these is true. So if this turns out to be false then we do not even have to be
worried about checking this because we know that both need to be true for this entire thing to be
true. If one of them is false then the entire thing is false anyway so why bother to check these
conditions. So that works here as well. On the other hand if this was an “or” so in this case we
would check this condition and then if this is true we do not even worry about checking this
condition because at least one of them has to be true and we have already found if we have
already found one to be true we do not have to be worry about checking the second condition
okay. Anyway so we can have conditions which are “AND”s and “or”s and we can have even
more complex conditions. So compound conditions which are themselves containing compound
conditions.

218
(Refer slide Time: 4:56)

So let us take an example, so I can have a condition if income is greater than 180,000 and
income less than 500,000 okay. Do something, so do what? Tax equals to income minus 180,000
excess of income over 180,000, 10 percent of that. So, when will this be executed? So when will
be this tax statement be executed, this tax assignment be executed? Well, so suppose income is
1,000 then this condition itself is false okay if this condition is false we do not even worry about
evaluating this conditions okay. So because both of these condition need to be true for this entire
condition to be true.

So in that case the entire condition is deemed as false if income is 1,000 and so this consequent is
not executed or this assignment statement statement does not get executed. Suppose, income is
200,000 or 200,000 in which case what happens is this condition true 200,000 is indeed bigger
than 180,000 so this condition is true. But we do not stop over there because we need to we need
to check whether both are true okay. So then we execute this so 200,000 is less than 500,000. So
this condition is also true. So as a result a complete compound condition is true so in which case
this statement this consequent will get executed. So tax equals, now income is 200,000 so this
statement will get executed so we will get this will become 20,000 times 0.1 or the tax will be
2000. Finally, let us say income is equal to 600,000. So in which case what happens is this
condition true is 600,000 bigger than 180,000? Yes it is true. So if this is true we should check
whether this is also true so in that case 600,000 is not less than or equals to 500,000 so this
condition is false. So as a result this compound condition is false and therefore, the consequent is

219
not executed. So this is not executed so what I mean by nothing happens is that the consequent is
not executed.

(Refer slide time: 7:40)

All right, so the same condition may be expressed in many ways. So I can write income greater
than or equal to 180,000 or I could have written 180,000 less than or equal to income. But I
could also write this as not of income less than 180,000 okay. And similarly, I could write this
condition as this and therefore the previous statement can be written by using these forms rather
than these okay. So this is just this is just alert you that conditions can be written in the same
condition, in the same constrain that we are talking about can be written in, many many ways.

220
(Refer slide time: 8:29)

Let me take another example suppose, we have rectangle in X, Y plane so this may, so this will
arise in graphics or in geometry. So this is my X, Y plane so this is the X- axis and this is Y- axis
in graphics the Y- axis goes down wards but let us not worry about that right now okay. So the
rectangle lies between lines X equals to 0 so this is sorry so this is the line X equals to 0 and the
line X equals 10 so this is the line say X equals 10 and it also lies between the lines Y equals to
50. So maybe this is the line y equals to 50 and let us say this is the line Y equals to 70. So this is
the rectangle that is of interest okay. So so we are going to we are writing program in which
somehow say this rectangle is figuring okay. So maybe maybe what is going on is that we have

221
drawn this rectangle on the screen and then maybe we click and we want to know whether the
click point is inside of this rectangle or not okay. So let X, Y denote the coordinates of a point
possibly the click point okay, and we want to know whether this point is inside the rectangle so
when would a point be inside of the rectangle? So for this, we will require that the X coordinate
should be between 0 and 10. So X coordinate must be somewhere in this region, okay and Y
coordinate should be between 50 and 70 or between this region or in other words the point
should be somewhere inside this. If any of this conditions does not hold, then the point will be
outside somewhere. So these are the condition that we need to check. So can we express this
condition? So we can write this condition as (0>=X && X<=10) && (Y>50 && Y<=70)1. All
right, so if all of this conditions hold then really these conditions are holding and then the point
will be inside. So if you want to check whether the point is inside we will have to say something
like if this then take whatever action whatever needed for the point if the point is inside or else
take action if the point is outside okay. Now, I just want to make one remark okay you will be
tempted to write these two conditions jointly in this manner okay, but this is not allowed this is
not this is not how you suppose to write these common these 2 condition you have to separate
them out and write then in this manner okay.

1
In fact, there a slight error here. The statement should be (X>=0 && X<=10) && (Y>50 && Y<=70) and not (0>=X
&& X<=10) && (Y>50 && Y<=70)

222
(Refer slide time: 11:46)

All right, so what did we discussed? We discussed general ways of specifying conditions and
here I should point out that we had these operators “NOT” “AND” and “OR” and the “NOT”
operator has higher precedence than “AND” operator which have higher precedence than the
“OR” operator so what do I mean by this. So if I have this condition okay now there is some
ambiguity over here so the ambiguity is do I mean, should I do P and Q first and then take
“NOT” and then take “OR” or should I do it in some other order?

Okay this says that “NOT” has the higher precedence so that means this “NOT” P should be
done first. So I have indicated with in this manner by putting parentheses. Then “AND” has
higher precedence than “OR” so after that I want “AND” to be evaluated. So that I have
indicated in this manner okay and after that sorry “AND” to be evaluated so I have indicated that
in this manner and I finally the “OR” should be evaluated. So that happens now. So you can
always put parentheses explicitly, but if you do not put parentheses explicitly if you write it in
this manner then C++ will use precedence rules and then precedence rules will say look this is
what we will, what C++ will execute okay. Now, my preference is not to rely on precedence
rules, my preference is just to write the parentheses so that it is very very clear you do not, you
do not want to tax anybody’s memory if you are you are yourself reading the program later if
you put the parentheses then it is very clear and you do not have to tax your memory.

223
So in the next segment, we are going to take some what large example what we have, based on
what we have learned so far okay full program, but before that we will take a quick break.

224
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 6 Part – 4
Conditional Execution
A somewhat large program example

(Refer Slide Time: 00:22)

Welcome back. In the previous segments we discussed general ways of specifying conditions. In
this segment we are going to take a large, a large-ish program example. It is not going to be its
actually going to be small but it will actually do something in that sense it is a large example, it
is a it is a full program which does something.

225
(Refer Slide Time: 00:39)

Ok, so what we want to right is the different way of controlling turtle. What do I mean by this?
Well here is here is what I mean. So write a program which reads commands from the user, and
accordingly controls the turtle. So, the way the turtle moves is not specified in the program, but
the user tells how the turtle moves by typing in programs. So if the user types ‘f’ then the turtle
should execute forward(100), if the user types ‘r’ than the turtle should turn right(90). If the user
types ‘l’ the turtle should turn left by 90 degrees. Ok this are just rules I made up. Ok you could
have made a different set of rules and in you will be encouraged to make a more interesting or
nicer rules later on in exercises. And this whole thing should stop when 100 commands are
executed. Why hundred? Again just a number I made up.

226
(Refer Slide Time: 01:47)

So again this program by now should appear reasonably, reasonably obvious. So, we are going to
have a character which will call command and then we will start the turtle, turtle simulator and
then since we want to execute 100 commands then we will have a loop with 100 which will
repeat 100 times. Then we will read in each iteration we will read in into command. So,
depending upon what the user types command will have that value.

If, the user type f and f went to into command, then we will execute forward(100). If, the user
type r then we will execute right(90), if, the user type l, we execute left(90) otherwise and when
will this be executed? Well if the user typed some other letter may be the user typed g in that
case we will help out the user by saying look you typed something which is not a proper
command, ok? And we will tell user what command he or she typed. And this will repeat 100
times and that will be the end of the program.

227
(Refer Slide Time: 03:16)

Alright so, let us do the demo of this. So ok what is this program? This is the program that I have
just showed you ok nothing else. So let us compile it ok. Ok so let me just type out the program.
So this is the program that I showed you. And now let me compile it. And now let us run it. Let
me adjust it. So now let us say we type f. So the turtle has moved forward hundred. So let us say
I typed r, the turtle has turned right, maybe I type an f again it has type it has gone forward may
be I type another f, it has gone forward further. So, maybe I will hit r again so it has turned right
and I will type f and instead of hitting, hitting enter immediately may be I will type f two times
or three times let us see what happens. So it has actually taken three commands, ok? So, so it has
done f three times ok? And may I can turn left here, so it has turned left and it can go on in this
manner. So I am not going to go at 100 times but you, you see the program is doing exactly what
we wanted. So, let me break out of it. Ok, so we just did this demo and let me now give you an
exercise.

228
(Refer Slide Time: 05:45)

So the exercise is: write a program that reads a number and prints 1 if the number is a multiple of
5 but not 3 and otherwise prints 0. And you are encouraged to write this in as many as ways as
possible ok? So for example, you could write this using only simple conditions. So for example,
you could write something like, you could only have conditions of the form expression 1 equal to
equal to expression 2 or whatever, whatever or not equal to greater than or equal to or so on ok?

But here, you may have to put if statements nested inside one another ok so inside say a
consequent or alternate u may have an if statement, ok? Or, you can use a single if then else
statement with a compound condition ok? So this is really and exercise for learning the if
statement and different ways of expressing the same program using different possibilities that
that language gives you.

229
(Refer Slide Time: 07:03)

Alright, so, what did we discussed in this segment? We discussed a detailed program a detailed
program example. Next, we are going to discuss the switch statement and logical data but let us
take a quick break.

230
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 6 Part – 5
Conditional Execution
Switch statement and logical data
(Refer Time Slide: 0:34)

Hello welcome back in the last segment we did a detailed example somewhat a complete
program using IF statements. Now, we are going to discuss the Switch Statement and Logical
Data.

(Refer Time Slide: 0:48)

231
So first the Switch Statement. So this is a little bit complicated and so will have bear with me
as I describe it. So I will start by describing the general form. So it looks like this Switch
followed by an expression then there is the keyword case and then there is constant 1 so here
you are expected to have a number like 5, 7, 1, 2, 3 and then you are going to have a group of
statements. Okay, usually these statements will end with a break. Then there is a another
constant, another group of statements and so on. And then there will be a key word default
and there will be another group of statements which will be called default group of
statements. So that is what the Switch Statement looks like in general. And expressions and
constants are required to be integers. How does this execute? So first the expression is
evaluated, so after the previous statement is executed when we want to execute the Switch
Statement first the expression is evaluated. Now, this value is compared with constant 1,
constant 2 and so on. If some constant i is found equal say may be constant 2 is found equal
and constant 1 is not equal. So the first constant that is found equal let us say that is constant i
or in this case constant 2, then all statements starting group i are executed. So from here
everything is executed okay. If a break statement is found, so we said that it usually ends with
a break is found then we deem that this switch statement execution is over and the control
goes on to the next statement following the switch. If there is no break statement then it
executes the next group of statements and the next group of statements and so on okay until a
break statement appears or you execute the last statement in whatever group. So that is what
the switch statement looks like. If no constant i is found equal to this expression then the
default group of statements will execute, alright?

232
(Refer Time Slide: 3:24)

Okay, so this statement looks like it is designed for our turtle controller. So remember what
was happening in the turtle controller? We were reading in a command and command is a
character but you know that a character is actually an integer. A character is a numeric type.
So a character only when you print it gets printed behaves like a character. But for calculation
purposes it is actually an integer. So this is a perfectly fine this is a perfectly fine numeric
type as we required it to be. So this is we wanted this switch command we wanted an integer
to come out of this and the command being a character, its value is in fact an integer. If the
value of this integer is equal to ‘f’ the ASCII value of F then forward(100) will be executed,
but after forward(100) is executed because there is a break then the control will go on to the
next statement following this. So it will go on to the next part, next repeat . If command was
‘r’ then this will be executed, if command was ‘l’ then this will be executed okay. And if
none of these were present then the default this will be executed. So notice that this looks
quite nice.

233
(Refer Time Slide: 5:00)

On the other hand there is a slight problem, what is the problem? You may forget to write the
break, okay so go back here.

(Refer Time Slide: 5:06)

It is very it is very likely that you may just forget it if you just forget say this break, what
happens? You execute this and you also execute this, so that is not such a good idea, okay.

234
(Refer Time Slide: 5:20)

So this statement is actually such as that you do not use this statement, instead just use the if
then else, okay. So the statement looks elegant because of the way it is designed because of
this break part it is actually a little bit dangerous to use because you may forget the break.
And you may say that look sometimes it might be necessary to use to execute several groups
and the book indeed gives you an example just for completeness, but really my
recommendation is do not use the switch statement. And in fact in this course I will not be
asking you anything about the switch statement, I just described this because for the reasons
of completeness if you read real code, code written by somebody else, you should not get
surprise when you see this switch statement.

235
(Refer Time Slide: 6:20)

Okay, so the next topic I want to cover in this segment is Logical Data. So we have seen that
we can evaluate conditions and we can also combine together conditions, so we can write
something like if x greater than 5 and y less than 6. So we are really performing, we are really
doing operations on results on conditions as well okay. So then you might ask why should we
not allow storing the results true or false of such computations. So we evaluate a condition it
came out to be true or false so let us say I want to remembers that that condition came out to
be true or false. So can I remember it can it put it in some variable? Indeed I can, so C++ has
a data type bool into which values of conditions can be stored. Bool is named after scientist
George Bool who formulised the manipulations of conditions and logical data. In fact he
invented something called a Boolean Algebra. So we are not going to see Boolean Algebra as
such, but we will discuss this bool data type next.

236
(Refer Time Slide: 7:44)

So here is how we can declare a bool type of data. So I can write bool high income or low
income. Of course these are going to be standard identifiers with the usual rules for identifiers
okay. I can assign to this okay and I can write something like high income equals and I can
put down a condition over here. So this condition will get evaluated and depending upon the
value of the condition either a true or a false will go in over here. I can also write something
like declare a Boolean variable fun and simultaneously initialize it to true if I want. If this
true is a constant or a key word. So the first statement will set high income to true if there is a
variable income contains value larger than 800000 and the second statement will just set fun
to true and true and false are Boolean constants. And what is the use of these variables? Well
Boolean variables can be used wherever conditions are expected. So I can write something
like if(highincome), tax equal to so and so. Of course before this it is expected that I will have
set high income to true or false by writing a statement of this kind. Okay, so now I want to
give you and exercise which is write a program to test if a given number n is prime. So we
are going to do this and let us see how we would do it. So first of all we would do this, so we
would ask look how we do this manually?

237
(Refer Time Slide: 9:38)

So there is an algorithm that you may or may not remember or may or may not know called
the Sieve Of Eratosthenes. So, how does that work? Well very quickly we start with 2 and we
keep on checking whether a certain number a certain number divides n okay and this we
make it a little bit more efficient by saying look if we want to check whether a given number
i divides n we first have to check whether it is a prime number itself or not.

So that is the Sieve of Eratosthenes, we are not going to follow that method so it does not
matter if you did not understand what Eratosthenes’ Sieve is okay. We are going to do
something slightly different, we are going to do which is something slightly less efficient, but
it will do things without requiring us to remember too many things okay. Here is what we
will do, we will start with 2 and go all the way till n minus 1 and check if any of these
numbers divides n.

If one of these numbers divide n, then clearly n is composite. If none of these numbers
divides n, then n is a prime okay so that is going to be our algorithm. So start with 2 as a
candidate divisor and check if it divides n, otherwise go on to the next candidate, next
candidate until n minus 1 and check if any of those candidate divisors divides n okay. And if
we find any such numbers we will we will conclude that in fact that number is composite,
otherwise that number will be prime.

238
(Refer Time Slide: 11:44)

Okay so let us write the program we will include simplecpp and will have the main program
and n is the number that we want that we want to decide whether it is prime or composite and
divisor is our candidate divisor which we are going to start of at 2. So the first thing that we
do is, we read into read n so we expect the user to type in whatever number he or she wants to
check whether it is prime or not. Then we are going to have a Boolean variable okay so
remember we said we are going to go over a candidate divisor starting at 2 and this is our first
candidate divisor over here. So I should have perhaps used a bigger name candidate divisor
but that is what is mean okay. So this is our candidate divisor and we are going to start with
this and go up till n minus 1. And if ever I find that candidate divisor divides n, then I will
make divisor found to be true. So, so far I have not found any divisor for n okay so I will
make it false, I will set it to be as false. So we will check if divisor divides n as it varies from
2 to n minus 1 okay and then thereby set divisor found. So if the divisor divides n then said
divisor found equal to true okay and how do we do this? Well we have to check for all
number between 2 and n minus one so there are n minus 2 such numbers. So we are going to
have a repeat loop of n minus 2 steps n minus 2 iterations and we are going to check if n mod
divisor is 0 or in other words is n perfectly divided by divisor. If it is, then we have found a
divisor and so we will say divisor found to be true. And then we want to check the next
divisor and therefore, we will set divisor equal to divisor plus 1 and that is it okay. After this
if divisor found is true then we know that the number is composite, so we will say if not
divisor found then cout prime. We could have written if divisor found then print composite,

239
but we just wrote it in a different order, else we are going to print that this number is
composite okay that is it.

So, what has happened over here? We have used ‘divisorfound’ a Boolean variable okay to
accumulate whether or not we have found a divisor as we go through the loop. Okay so this is
one use we can put Boolean variables to. So we are remembering the previous whether or not
divisors were found previously and that is a Boolean value whether a divisor was found is
either true or false. So that information can be accumulated, can be put in Boolean variable
and so we have given it an appropriate name and inside that we are putting this information
and at the end if divisor found is false that is we did not find any divisor at all then we are
going to print out prime otherwise we will print out composite.

(Refer Time Slide: 15:27)

So I would like you to execute this program mentally for n equal to n equal to 100 and I
would like you to verify that it produces the correct answer, but I would also like you to think
about whether you think the program is a good program or whether it is perhaps doing too
much work. And if it is and you will indeed see that it is doing unnecessary work we will find
ways of remedying that a little bit later in the course.

240
(Refer Time Slide: 16:09)

Alright, so what have we discussed? We have discussed the switch statement and we have
recommended that it should not be used. We discussed logical data and said that it can be
used to remember results of conditional evaluation. In the next brief segment, we are just
going to summarize this lecture sequence, but before that let us take a short break.

(Refer Time Slide: 17:05)

Welcome back in the last segment we discussed the switch statement and logical data in this
segment we are nearly going to summarize the lecture. So first of all I should observe that
conditional execution makes life interesting, we noted at the beginning that the tax
calculation program cannot be solved, cannot be written without something like conditional

241
execution. Something like an if statement. Then we discussed 3 forms of if, plain if, if
condition consequent, if then else, if condition, consequent else alternate and then the most
general with several consequents and a single alternate. And I should point out that you can
nest if statements inside each other okay so the consequent can be a block and that block can
contain if statements. But there are some pitfalls in it and those pitfalls are discussed in the
book so please read the book. We also looked at compound conditions so conditions which
are made by saying look I want this condition to be true and this condition to be true or may
be this condition to be true or this condition to be true or this condition should be false. Then
we also talked about logical data we did talk about the switch statement but I am not
mentioning it over here because I really do not want you to use it. And before I finish this
lecture as usual I will ask you to try the exercise not at the end of the book but at the end of
the chapter. So please do that that is absolutely necessary and I hope you will like those
exercises, so that is it that is it for this lecture sequence. Thank you.

242
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part – 1
Looping Statements
Loops

Welcome to the second lecture sequence of third week of the NPTEL course on an introduction
to programming through C++. I am Abhiram Ranade and the reading for this lecture sequence is
the chapter 7 of the textbook.

(Refer Slide Time: 00:41)

So let me begin with the problem the problem is that of averaging marks. So, you have to read
your program is to read the marks of the students typed by the user from the keyboard and then
print out their average. Now there are some conditions. So, the number of students are not given
explicitly, instead if a negative number is entered as mark then it is signal that all marks have
been entered and you may assume that at least one positive number is given. If no numbers are
given, then the average is undefined and therefore, you have to assume that at least one positive
number is given. So let me first construct some test cases or examples of input output. So, for
example the input might be 98, 96, -1.

243
So, this indicates that the first two numbers 98 and 96 are student marks and -1 is the indication
that no more input is to be given. So in that case there are two marks 98 96 so their average is 97.
Another example 90, 80, 70, 60, -1. So again the actually student marks in this case is 90, 80, 70,
60 and clearly the average is 75 which is supposed to be output. Now, this cannot be done using
what you know so far. So far you only know one single repetition statement which is repeat, and
that statement repeats a fixed number of times. So it is not useful here because here you are
going to repeat as many times as there are students but how many students there are is not given
to you beforehand. So, we need something new and there are a number of C++ statements that
can do what is needed over here so these statements are the while statement, the do-while
statement and the for statement and the statements as well as the repeat statement are sometimes
called looping statements. So, loop is just another, another term for repetition. So, loop is doing
something in a circular manner so repetition basically.

(Refer Slide Time: 02:59)

So, the outline is this lecture sequence is I am going to first discuss the while statement, I will
talk about a simple example and then I will get to the mark averaging problem. Then I will talk
about the break statement, then a statement called a continue statement. Then, I will mention the
do-while statement but I am not going to discuss it in great detail. It is described in the book.
Then I will talk about the for statement and then I will talk about loop invariants and this going
to be discussed with the Euclid’s algorithm for the greatest common divisor as an example.

244
(Refer Slide Time: 03:47)

So, let us look at the while statement. The form of the while statement is while, then in
parenthesis: a condition, and then the body. So, the way this works first we are going to first
evaluate the condition, the condition is simply something which evaluates to true and false ok?
So we studied this last time, then if the condition is false then the execution of the while
statement ends. If the condition is true, then the body is executed, body can now be a single
statement or a block anything is possible, but if it is a block, then all the statements in the body
will be executed. After that, after the execution of the body the execution again resumes from
step 1. So again the condition is evaluated. Again if the condition is false, then the statement
ends. So the statement only ends when the condition turns out to be false. So otherwise until the
condition turns out to be false the body is executed as many times as needed for the condition to
become false. Now the condition should become false in a well written program, otherwise the
program is not going to halt. And not halting is not an acceptable outcome we want our programs
to produce an answer and stop execution as quickly as possible or certainly in finite time. So, this
means that if the condition is true originally, then the value of some variable which appears in
the condition must change during the execution of the body and only in this case can eventually
condition become false. Just like what we said for repeats, each execution of the body is also
called an iteration.

(Refer Slide Time: 05:22)

245
So, the while turns out to be a slightly complicated statement so it is nice to look at its flow chart,
so in the left we have the while statement as a part of hypothetical program so there is the
previous statement, then there is the while statement and then there is the next statement. So how
is this going to execute? So that is given here on the right. So, the previous statement in the
program is executed after that the condition stated in the while is executed so this statement over
here this this condition over here.

If this condition is false then you go off and execute the next statement over here. If the
condition is true however, you execute the body as many statements there might be in the body
you execute them one after another and after that you again go back and evaluate the condition
and you keep on doing this until eventually at some point the condition is false, in which case
you can go on to the next statement. So that is how a while executes.

246
(Refer Slide Time: 07:04)

Let me begin with a silly example, so here is a main program in which we have x is equal to 2 to
begin with and then there is a while loop and after the while loop a message is printed. So, let us
see how this executes. So, first as the code executes from the top this statement will get executed,
so x will be set to 2. After that we look at the body, so we encounter the while statement and as
you might remember we have to check the body first so you check is x bigger than 0? So since x
is 2 it is bigger than 0 and therefore a body is going to be entered so when the body is entered the
first statement in the body is x-- or you want x to be decremented. So this means x will be
decremented and the value will become 1, after that you have a cout statement or the current
value of x is printed the current value of x is 1 so that will get printed. So 1 is being printed over
here. Now, that ends one iteration of the while loop or one execution of the entire body. But at
this point the statement does not end ok? So at this point we are going to go back of the top of
the loop and we are going to recheck the condition. So, at this point x has the value 1, because
we decremented it in the first iteration x has the value 1, so 1 is still bigger than 0 so the body is
going to be entered. Now again there is a decrement statement so x will be decremented, and its
value will become 0. So after that there is the print statement so the current value affects which is
0 is going to get printed so that is what is happened over here ok? So in this statement itself x has
become 0 and the while condition seems to say do this only while x is greater than 0, but it does
not mean that we are checking before every statement, we are only checking at the beginning.
So, even though x is not actually greater than 0 we will still execute this statement ok? And 0

247
will be printed. After that we are going to go back at the top that is what while tells us to do and
again we are going to check the condition. So this time however x is 0 and 0 is not bigger than 0
and therefore the body is not entered and in fact at this point the execution of the while ends and
you move on to the statement following which is this print statement. So as a result of which
done is going to be printed. So this was a silly example but it tells us it shows exactly how a
while statement executes. Now it is good idea to think about the comparison between the while
and the repeat.

(Refer Slide Time: 10:22)

So let me first observe that anything you can do using repeat can be done using while. Why is
that? So suppose, you have this repeat statement. So n is some value xxx are some group of
statements, so I will show you how you will write a program, how you will translate a program
which contains this statement and replace it by an equivalent while statement. So here is the
translation so instead of that single repeat statement, you will have these two statements. So first
you will say you will have a variable i which you are going to assign to n so that the same value
whatever many times you wanted to repeat is now going to go into i. Now you are going to check
is i greater than 0 so while i is greater than 0 you are going to execute xxx but you are going to
decrement the value of i in each iteration. So if, so whatever, whatever value this had so
whatever integer value if had say it was 10 then this loop will be executed 10 times because you
would have to decrement this i 10 times only after which I would become 0. And at that at that
point this condition would fail and then you would go on to the next statement.

248
Now this, this we created a new name just for doing this translation. But if this name i is used
elsewhere in the program then this might produce an error so what I should write over here or
what, what I should advice you is that pick variable name which is which does not appear in your
in your program and then just use that but it must be the same variable name that you use over
here as you are using over here. So if i is being used then pick a different name.

(Refer Slide Time: 12:20)

Ok, so let me give an exercise so here x is 306, y is 77, z is 0 and we are doing this loop while x
is greater than 0 so we are adding to z, y and we are decrementing x so I would like you to tell
me what is printed at the end. So I am not expecting you to actually execute the by hand, but
rather what I am hoping you will do is you will may be do one iteration or two iterations and
then you will guess the pattern and you will say that at the end this number or this expression
where the value of this expression will be printed as said. Then I would also like you to translate
this familiar code fragment which uses repeat into an equivalent code fragment which used while
loop.

249
(Refer Slide Time: 13:21)

Ok, so what did we discuss? So we looked at the while statement and we said that the while
statement says the we need to iterate while a condition that we specify holds and then in
comparison to repeat, the while statement does not need to know how many iterations are there
before the execution starts.

So in the while statement a condition has to be specified and a iterations happen so long as that
condition holds. Then we also saw that whatever we can do using repeat can be done using while
and off course the converse is not true because in the repeat you need to know before hold how
many times the loop body has to be iterated. So we will take a break here.

250
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part – 2
Looping Statements
Mark averaging

(Refer Slide Time: 0:25)

Hello, in the previous segment we discussed the while statement and compared it to the
repeat statement. Now, we are going to look at how to do the mark averaging problem. So, let
us begin with the manual algorithm for mark averaging. So here it is, so we are going to keep
two variables, so one is the variable sum into which we are going to get the sum of all the
marks and then there is going to be a variable called count and in this variable we are going
to keep track of how many marks we have read, so we are going to start by making these
variables 0.

Then we are going to read the next value and the next value is going to be read and let us say
we read it into variable called nextmark. Well in a manual algorithm we will not really have
variables, of course, but since you now know variables, we might as well bring him in just to
make our discussion clearer. Okay, then we are going to check is the value, the mark value
that we just read which is in nextmark, is it less than 0, if it is less than 0, we then we know
that we need to terminate, so we need to at that point, print the average and stop. So therefore,
we are going to go to step 7, and step 7 indeed prints the sum divided by count, which is
going to be the average, well, if nextmark is greater than or equal to 0, then what do you do?
Well then which is continue, so we go to next step which is step 4 and now whatever mark

251
we just read, which is a valid mark now we know and we added to sum, but we also read one
more mark and therefore, we increment count by 1 as well and then we have to repeat the
process, so we can go back to step 2, which is the starting point of the loop.

(Refer Slide Time: 2:20)

Now, let us first draw a flowchart of this. Just to make sure that we understand exactly the
control flow, that is what happens after what? So here is the flowchart, so we are going to
start off by setting sum and count to 0, then we are going to read in nextmark, then we are
going to check whether nextmark is greater than 0. Okay, if it is false or it is less than 0, then
we are going to print, calculate and print the average, otherwise we are going to add nextmark
to sum, we are going to add 1 to count, and then we are going to repeat again from this
statement. Now, our goal is to implement this using the while loop and therefore, it might be
instructive to compare the structure or the connections in this flowchart with the connections
in a while loop. So here also there is this condition, here also there are some statements which
are being executed. Okay, but there is an important difference between these two pictures,
what is the difference?

After the body is executed the control goes back to the condition checking, over here if this is
the body then after that body is executed the control does not go back to the condition
checking, but it goes back to an additional statement before the condition checking happens.

So because of this difference, it is not clear that how we can use the while statement, because
if this is the condition and this is the body, what is this? Okay, that is not very clear. Okay,

252
we cannot directly use this. Okay, because the structures don’t match. Okay, so we are going
to than do something to the flowchart.

(Refer Slide Time: 4:26)

So we are going to have a different flowchart for mark averaging, in this slide we have given
two flowcharts for mark averaging program and I am going to observe that they are really
doing the same thing. So what is it that we wanted? We wanted that this path should join not
at this point, but it should join directly at the condition check. But we cannot just take this
path and join it over here, if you do that, then along this path we would be doing something
different. So, if we are going to make any changes, we should make sure that along every
path the same operations happen, maybe they happen before the merge in one case, or in the
case they happen after the merge. So if we do not like that these block is present between the
point of joining and this condition check, what we could do is, we could push this block
above on this path, but we cannot just push it on one side, on one of the paths because then if
it come down the straight path and if the block is not present, then we would be doing
something different around the straight path. So what we can do is that we can take this
condition, this statement and we push it back on both paths okay. So what happens now is,
that if we come down for the first time, then the operations that we perform are still going to
be the same, so we are going to execute this statement, then the statement, then the condition
check. Similarly over here, we are going to execute this statement, this statement and the
condition check. On a subsequent iteration as well after the condition check we are going to
execute this statement and we are going to execute this statement and the condition check
again, even here after the condition check we are going to execute this statement exactly the

253
same as before, then we are going to execute this statement exactly the same as before, and
then we are going to execute the condition check exactly the same as before. So, the general
claim is that if a certain block is executed after two paths merge, say as over here this block is
executed, then we might as well execute it separately on the two paths, before they merge and
then we do not have to execute it after they merge because we just executed them before. So
essentially, what happens over here is exactly the same thing that happens over here.

Now, why is this helpful for us? Well, now we can make this be the condition and we will
make this followed by this as the body of the loop, so I can sort of bring this back and just
bring it back and sort of blend it into B, so then this will be my condition check and this
followed by this will be my body.

(Refer Slide Time: 7:32)

So here is what the program is going to look like, so I am going to declare the variables
nextmark and sum and sum is going to be 0, I am also going to declare count and count also
going to be 0. Okay, so I am at this point I have executed this statement, and I have executed
this statement. Now, I need to execute this statement and this statement is not within any loop
or anything, so I have that, so this is this block A which I have marked here, just to indicate
the correspondence. Now after this, I come to the condition check of the while, so I am going
to have a while and that is going to be my condition check, so this C block over here is going
to be this statement. After that, I am going to have the body, so the body first has this
statement from B, it then has the second statement from B, but as it executes it has to execute
this statement from A again. So that is also going to be a part of the body and this is a copy of

254
A, so that is what I have indicated over here in the comment. So at this point the body
execution ends, so we have this and then again the control will go back and start from this
statement which is exactly what happens in the flowchart over here. So if the condition is
false, then I want the average to be calculated and printed. Similarly over here, if the
condition is false, we will come and execute the statement over here and so we will put the
average calculation and printing statement over here and that is what our program is going to
be, so this program now uses the while statement and it directly implements this flowchart,
but we know that this flowchart is really the same as this flowchart.

(Refer Slide Time: 9:32)

So here is an exercise for you, write a turtle controller which we saw last time but which this
time has an extra command, so if from keyboard you type ‘f’, then the turtle should move
forward 100 pixels as before, if you type ‘r’, then the turtle should right 90 degrees. But now
if you type ‘x’ the turtle should finish execution, you will see that you will have to pretty
much have the same structure as before, so maybe repeat some part of the code before
entering the loop and so on.

(Refer Slide Time: 10:08)

255
Alright, so what have we discussed in this segment? So we said that in while loops, the first
step is check whether we need to execute the next iteration. In some loops that we want to
write, the first step may not be the condition check, we might have have to do something
before we check the condition. In this case we can modify the loops or we can modify the
flowchart associated with the loops by making a copy of the steps that we need to do before
the condition check and they have to be performed before the entry into the loop as well as at
the end of the body of the loop. So this is one way of dealing with such slightly tricky loops,
but there is another way in which we will see in the next segment, so will take a break here.

256
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part - 3
Looping Statements
The break and continue statement

(Refer Slide Time: 0:17)

In the previous segment, we discussed how we could modify the arrangement of code in our
program or in our flowchart so that it matches the structure of the while loop, so that we can
use the while loop in our program. Next, we will discuss a different way of doing the same
thing. But without too much rearrangement of any code. For this we need the so called break
statement, the break statement is perhaps the simplest statement. The word, break is a
keyword, which by itself is a statement okay, so you will see an example soon. What happens
when control reaches a break statement? Well, the break statement had better be inside a
while and if you reach the break statement the execution of the while statement, which
contains it is terminated. So the control then goes to the statement following the containing
while statement, that is about it

257
(Refer Slide Time: 1:21)

So here is an example of a break. Okay, so main program, float nextmark, sum as before,
count is 0 and now we are going to run the loop, but we are going to run it with a condition
true, so I will explain this in a minute, so we are going to read in the mark and if the
nextmark is less than 0, then we are going to break okay. So the consequent over here is the
single word statement break, otherwise we are going to add nextmark to sum, we are going to
increment count, and that is it as far as loop is concerned and that we are going to print. So I
will claim that is program actually does what we want. So why is that? So first of all, let us
go to the new part, the first new part is the while which contains true, so the condition of the
while statement is given as true, which means that this condition will always evaluate to true,
so which means whenever you try and check the condition, it will come out to be true and
you will always enter the body, so you will always enter the body, so you will always read in
the nextmark. The next element is, if nextmark less than 0. So if nextmark less than 0, then
there is the break statement and which means that the loop will terminate, the execution of
the while statement will terminate and you will execute, you will come to this point and
execute the statement. So remember that was exactly what you wanted, if nextmark was less
than 0. nextmark was signalling the condition that no more input will be given and therefore,
you want that is to be calculate it and printed, otherwise you want the currently read mark to
be treated as a real mark and you wanted added to sum, so that is what is going to happen
over here any also want count to be incremented.

So the nice part over here is that we did not need to copy this code, remember in the earlier
case we have to pull it out over here, we had to move it to the end, here we do not need to do

258
anything like that and this pretty much resembles the way we think about this logic. So when
we wrote down, then we thought about it manually, you would see okay, read the next mark
if it is less than 0, then go off and terminate, otherwise I read to sum and so on, so this is
exactly the way we think about it. However, some programmers do not like break statements
because the continuation condition. So this condition, this is really the condition, which tells
whether or not you want to continue the loop or break the loop, this continuous condition
now is hidden inside the body, whereas earlier, it was at a nice obvious place. So therefore,
some programmers have preference for not having a break statement, but using a proper
continuation condition over here and at the cost of maybe moving some code outside and
moving it end of the loop body. So I think programmers do both of these things, so you
should pick the style that you are most comfortable with and then I should note that the
condition for breaking, is nextmark less than 0, whereas the condition for continuing
however, is nextmark greater than 0, so while nextmark is greater than or equal to 0, I should
execute this. So they of course complimentary conditions, but clearly one is the condition for
continuing and the other is the condition for breaking out, so we should expect them to be
exactly the opposite of each other.

(Refer Slide Time: 5:33)

So there is another single word statement that I should tell you about and this is the continue
statement. Okay, so if it is encountered in any execution, then the control directly goes to the
beginning of the loop for the next iteration, so basically the statement from the continue to
the end of the loop body are skipped.

259
(Refer Slide Time: 6:00)

Okay, now you might see why you might need such a statement, so here is an example. So
we look at the same mark averaging problem, but now we have an additional condition, so
what is this condition? So suppose, somebody types a number bigger than 100, than we are
going to see that look that must have been a mistake, so if it is a mistake what should we do?
We should just ignore it or in other words, we should just not execute the statement that
comes after this reading statement. And therefore, the continue statement will come in handy.
Okay and as before we want to stop and print average only when a negative number is read
and so the other parts will remain the same.

260
(Refer Slide Time: 6:42)

So here is the new program with this new additional requirement, so the main difference is
this statement if nextmark is bigger than 100 we continue which means we will skip this
entire part and we will start again. Okay, so essentially, this last mark that you read is going
to be ignored, otherwise if it is less than or equal to 100, then it is a valid mark and so we do
everything that we were doing earlier.

(Refer Slide Time: 7:13)

Now, I should probably talk about one more statement, the do while statement, but I am not
going to do so because it is not very common. And it has been discussed in the book, so I will
leave it for you to read, but I am not really going to ask any problems regarding this

261
statement, and you do not really need to know it, to solve any of the problems that we are
going to discuss in this class, in this course.

(Refer Slide Time: 7:46)

So you can use the break statement to advantage in writing that turtle controller program as
well, so instead of replicating you can use the break statement and so that is a good exercise
just to check whether you have understood the break statement.

(Refer Slide Time: 8:01)

Alright, so what have we discussed? So we have discussed the break statement which enables
us to break or exit from a loop inside the body. Now a point to be noted is that if break
appears inside a while statement, which itself nested inside another while, then the break only

262
breaks out of the inner while, not out of the outer while. And then you also discuss the
continue statement which enables us to skip the rest of the iteration, so will take a break here
and return later.

263
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part – 4
Looping Statements
The for statement

(Refer Slide Time: 0:17)

In the last segment we discuss the break statement and the continue statement. Now, we are
going to discuss another statement called the for statement, this is a bit of a complicated
statement and so let me state a problem which will sort of need the statement and where the
statement will fit very nicely. So here is a problem, we would like to write a program to print
a table of cubes of the numbers from 1 to 100, so what do we want? We want on the first-line
1 and 1, on the second line 2 and 8, on the third line 3 and 27, the fourth line 4 and 64, 5 and
125 and so on, all the way till 100. Now of course you can write this using the while or you
can also write it, even using the repeat, because you know that you are going to do exactly
100 iterations, so there is no real mystery about that. So, what would you do? So for example
you will write this int I=1, repeat 100 times, cout<<I<<’ ’<<I*I*I<<endl; have a space in
between. And of course then you would have to increment I, so that would be the program or
that would be the program fragment which will do what we want.

Now, if so happens that this idiom and by that I mean doing something for every number
between some X and Y, so this idiom occurs very frequently and therefore, C++ provides you
a way to describe it very succinctly and that is exactly the for statement. So this is how the
statement works, so you want things to go between 1 and 100 and we want that variable to be

264
called I, so we are going to write for(int I=1, I<=100; I++) and we want the value of I to
change by I++, so we also specify that right here. And then what we actually want to happen,
we are specify after this and this is the body of the for, so we will get the exact statement in a
minute. But this code is equivalent to the four lines, I have written earlier and this code is
very stylised and as a programmer, you will get very, very familiar with it and just by looking
at it, you will know that oh I is going from 1 to 100 and this is going to be done for each
value, whereas in the previous statement these limits and this systematic update is kind of
lost, whereas over here it is an exactly a predictable place and therefore this makes for better
readability. So exactly how this work, we will see in a minute.

(Refer Slide Time: 3:23)

So the general structure of the for statement, so it is used like a following, so for then inside
parenthesis first we have the initialization, initialization followed by semicolon, followed by
a condition, followed by a update and then the body, the initialization and the update are
typically assignments, they could be other things, but they could be typically assignments and
of course the semicolons are not included, of course there is an semicolons immediately after
the initialization, but after the update, there is no semicolon, so that something that you have
to keep in mind. Condition as usual is a Boolean expression and the body, well the body
could be a single statement or it could be a block, alright, so how does this execute? So,
before the first iteration of the loop the initialization is executed. So we will see the example
in a minute, but first the initialization is executed, then the iteration begins, then at the
beginning of each iteration the condition is tested, if the condition fails, if the condition turns
out to be false then the rest of the iteration, which includes the body is not going to be

265
executed, and in fact the loop will end, the loop execution will end and you will go to execute
the next statement following the for statement. If on the other hand, the condition turns out to
be true, then the body is executed and after the body is executed, the update is also executed,
then after the execution of the update the next iteration begins, what does that mean? Again
the condition is going to be tested, again, if it fails the loop ends.

(Refer Slide Time: 5:25)

Alright, so let us look at the flowchart. So shown here is the flowchart for the for, then the for
statement itself and an example. So what is happening over here? Well, this is the for
statement, so the initialization is executed first as in the flowchart, then the condition is
checked, if the condition is false, then the statement goes to the next statement in the
program, if the condition is true then the body is executed, so this body is executed and then
if after the body is executed, the update is executed. So the update it is stated earlier, but it is
executed at this point and after that again, the entire condition testing happens and so on.

So, what happens over here? So I equal to 1 is the initialization, so we start by saying int I
equal to 1, so I becomes 1, then we are going to check the condition, so this step happens, if
this condition is true which in the current case it is because 1 is less than or equal to 100, so
then we are going to execute the body, so see that is what is happening over here. After we
execute the body then we are going to execute the update, so at the end of the body, after the
body really this update is executed, so after this we increment I, so now I becomes 2. So we
printed for I equal to 1, we printed 1 and 1, now I has become 2, so I has become 2 and we go
back and we start from the condition check again, so we again execute this is I less than 100,

266
so 2 still less than 100, so we again print 2 and 8 and so on until we get to a value of 101 over
here, so 100 will pass this and so we will print 100 and 100 cube, but 101, this condition will
not be true and therefore, will exit this and we go on to the next statement following the for.

(Refer Slide Time: 7:43)

Now some remarks are in order, so as we saw in our example new variables can be defined in
initialization. Now these variables are accessible inside the loop body, including the condition
and update but they are not accessible outside, so they are within the scope of that for
statement. So that something to be kept in mind, the intention is that those are sort of internal
to the for statement and therefore, we should not expose them outside, so sometimes, so by
and large this is useful and sometimes if we need something different, we can of course do
something different.

267
Now variables which are defined outside can be used inside, unless they are shadowed by the
newly defined variables. So in the previous case over here. I define that ‘I’ over here, but
suppose an I was defined over here, then inside the body. I am going to get this I, not I
defined outside. On the other hand if I just wrote I equal to 1 and I did not write this int I then
that means this I will refer to the variable that was outside, so then no shadowing will happen,
so I am not obliged to declare a new variable over here, but if I do, then that variable may
shadow the variable which of the same name if any defined outside. Otherwise, I will just get
a new name and that new name will vanish as soon as my for loop execution ends and break
and continue can be used with the natural interpretation that is the moment you come to a
break, the statement of the for will end, if you come to a continue then you do the update. So
the rest of the body is going to be skipped.

The typical used of the for is that is a single variable is initialized and updated, and the
condition test whether it has reached a certain value and the loop execution really depends
very strongly on the value of this variable and therefore, this variable is called the control
variable of the for statement. So in the previous table of cubes program ‘I’, whose cubes we
were printing, the variable I was the control variable for this for statement.

(Refer Slide Time: 10:15)

Okay, now I am going to take a somewhat elaborate example, a problem that you have seen
before determining whether a number n is prime. So the manual algorithm is simple, and in
fact we have seen this manual algorithm earlier, so the algorithm was check whether any of
the numbers between 2 and n-1 divides n, so we are going to systematically go from 2 to n-1

268
and check whether those numbers, any of those numbers divides n. We looked at this
problem last week, but there our program was a little bit inefficient, once we found that a
number between 2 and n-1 divides n, we know already that n is composite and we do not
need to do any additional divisions. Okay, now, our program will be efficient in that it will
indeed not to any additional divisions, whereas our last week’s program would be doing those
additional divisions, even though the answer last time was also correct, last week’s program
was a little bit inefficient and this time we will be eliminating that inefficiency. So, let us
begin by making a flowchart of the manual algorithm and then we will try to use the for
statement because it seems that the for statement is rather nice over here, you could think that
the divisors which we are going to try out should sort of be the control variables for a for
statement that you might write. Okay, so yes, so that is our goal to see if this is a flowchart
can be put into the format of the for statement.

(Refer Slide Time: 12:02)

So here is the flowchart for the manual algorithm. Let me sort of tell you how this works, so
first we are going to read n and then we are going to set a variable called divisor to 2, so this
is the current divisor with which we are testing. Now, if this divisor is smaller than n, then we
have to do something. But if it has already become larger than n okay, it has become n or
larger than we take this branch okay, so when does it become n or larger? Well, it becomes n
or larger if we have tried out all the numbers between 2 and n and they have not been able to
divide okay,

269
So there was always reminder when we tried to divide n by those numbers, so in that case, we
know that we can get out of the loop and we can in fact print the message ‘prime’. If on the
other hand, the current divisor that we are trying out is smaller than n, then we are not yet
sure but the number is prime, so we are going to check is n mod divisor equal to 0 or does is
n divided exactly by the divisor? If it is true, then we have found a divisor and therefore, we
can immediately declare that the number is composite and we can stop, so that is what this
branch is doing. But if it is false then we know now that this divisor did not work, but at this
point we still cannot be sure, we still do not know whether the number is prime or composite,
so, so far we have not found any divisors, but we may find some divisors going further. So
what do we do? Well, we are going to increment the divisor by 1, so we are going to try the
next divisor and then we are going to go and check again. So again, if the new divisor is
smaller than n or let say it is bigger than n then we go out on this branch, but then that means
we have tried out all divisors only then has divisor become equal to n okay, so in which case
we have tried out all divisors and we can get out and we can stop after printing prime over
here. So that is the overall logic.

(Refer Slide Time: 14:34)

270
Now, this logic is perfectly fine. Okay, however, flowcharts that you draw are expected to be
structured and let me explain to you what that means, so basically when you draw flowchart
you can have paths flowing all over the page. So let me show you one possible flowchart, so I
am going to test something. Then from here, if it is then I am going to do and go and execute
this block, then again I am going to test something, then if this is false, I am going to go and
execute this block, and then from here maybe I come back and I merge with this point and if
this was false, maybe I go off and check something. Okay and then may be from here also I
merge at this point and otherwise I continue, maybe I do another check. Okay, maybe I
execute something and so on.

So if your flowchart is really complicated like this, then it is rather hard to understand. Okay,
so such flowchart or such flow of program is often called spaghetti code, why? Because you
could imagine that these lines which are going in sort of random manners all over the place
are like that pasta, noodles or whatever, which are just lying around and I mean it just look
like a mess. Okay, so you really do not want your code to look like this.

(Refer Slide Time: 16:22)

271
So, what kind of a code do you want? Well, the code that you want is called a structured code
or structured programs sometimes. So what does that mean? So it means that I am going to do
something, I am going to do something in the next. I am going to do something in the next.
Okay, maybe I am going to have may be after at some point I am going to have a test, but the
test I may do something over here and eventually I am going to come back to the same point
over here, I may do something, I may go back but, so there might be a complicated blob over
here, but again I am going to come back to the same point and this complicated blob should
be again some kind of a while loop, it should be a while loop or it should be a for loop or
something like that, so I might have nesting, so I might have straight-line code like this, one
of which, one of the elements in it is a for loop and inside the body of the for loop maybe I

272
can have a while loop okay, but the point is that this nesting should be sort of perfect in that
manner. So it should not be like this where suddenly this line comes back and merges with
here and this line comes back and merges with over here, because if it is complicated like
this, then it is harder to understand, so basically we want that if we, even if we have multiple
conditions, so if we have blob over here, then thing should enter over here and only one path
of control should exit from this.

(Refer Slide Time: 18:14)

So now, if we go back in this code two paths of control are exiting, one path is exiting over
here, another path is exiting over here, we do not want that, we have one entry into this, so
coming from the top and we would also like the code to exit in exactly one place. Alright, so
how do we do this? So here is what we should do? We should merge those two, merge these

273
two paths okay, but now if we merge these two paths, then on one side I am printing prime,
on the other side I am printing composite, so I cannot just merge them, I have two somehow
print only one of the messages. So what we need to do is we could merge them, but we could
decide based on some information that we might have, what message to print okay, so that is
exactly what we are going to see in next.

(Refer Slide Time: 19:07)

So here this earlier portion is the same. Okay, but instead of having two outgoing, two paths
going out, we have that same path coming into this, two paths into this same block. Okay,
and here we are again to check is the divisor greater than or equal to n, if the divisor is greater
than or equal to n, then we know we came out on this path, but if we came out on this path we
wanted to print prime, so we print prime. Otherwise, we must have come out on this path and
therefore, we want to print composite, so we are printing composite. So with this
simplification or rather, maybe this is not simplification, maybe this is complication, but let
us say with this modification our new flow chart it matches the structure of a for statement.
So let me tell you how. So here for example, I can think of as the condition in the for
statement, this divisor equals to 2 is the initialization in the for statement, this divisor++ is the
update part of the for statement and what is this? Well this is the body, but the body now
contains a break and this break is going to take me outside, but you know that the condition
also takes me outside, so this is really the outside part, I should draw it over here saying that
it is coming next after the for statement, but it would be really congested over here to draw
and therefore, I have drawn over here okay.

274
But that is really the idea that this is the condition check, this divisor equals to 2 is the
initialization part of the for, this is the body of the for and this is the update part of the for, so
now we are ready to write a program.

(Refer Slide Time: 21:06)

So here is the program, so we are going to read in n, then we are going to initialise the
divisor. Well, here we have pulled out the initialization and what we have done is, we have
kept the initialization empty, but I could have declared the divisor over here and I could have
initialize it over here it does not really matter. So both are equivalent okay, so long as I put I
do not redefine divisor over here, then things are fine, divisor is a control variable and I will
set its value over here.

So, what does this loop say? It says that starts with value 2 for divisor and if that value, so
long as that value is smaller than n execute this body, after this body is executed, execute this
update statement and then go back and repeat. And, at the end of the for divisor now has
certain value, so this divisor have already become n, if it is no longer smaller than n, then we
know that it must, that we must have tried out all the values between 2 and n minus 1 and so
we print out prime okay. Otherwise, we are going to print out composite and we are going to
stop.

(Refer Slide Time: 22:31)

275
So we have left the initialization part of the statement empty and this is allowed as we said
earlier and we could have placed divisor equal to 2 in the initialization, but not the n. Okay,
and why do we not want n to be placed because we want divisor to be used over here, so that
divisor had better be defined earlier, if it is defined here, then we would not be able to use it
here.

(Refer Slide Time: 22:59)

276
Okay, so an exercise for you, suppose we indeed wrote int divisor equal to 2, what would this
program do? So this is something for you to think about.

(Refer Slide Time: 23:11)

Then here is one more exercise write a for loop which prints out the sequence 1, 2, 4 all the
way till 65536, which is simply 2 raise to 16, and the hint given to you is that the update part
of the for does not have to be addition, it can be other operations like multiplication for
example.

(Refer Slide Time: 23:30)

277
Alright, so what did we discussed in this segment? We said that many times we need to
iterate such that in each iteration a certain variable takes a simple sequence of values. Say the
variable values, variable I goes from 1 to n, in such cases the for statement is very useful. The
variable whose values form the sequence is called the control variable, essentially that
sequence is driving what is happening in each iteration.

And we also noticed here as well as in while that matching the flowchart of the manual
algorithm to the structure of while or for is going to take some amount of work. So we’ll stop
over here for the segment.

278
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part – 5
Looping Statements
Euclid’s algorithm for GCD

(Refer slide time: 0:43)

Hello and welcome back, in the previous segment we discussed the FOR statement. In this next
segment we are going to discuss somewhat elaborate algorithm including we will derive the
algorithm and it will be coded using the, the WHILE statement, but it will not be possible to
coded using the repeat. Of course it can be coded the FOR statement because in some sense the
FOR statement is as powerful as the WHILE statement. What I mean by that is whatever you can
do using FOR you can do using WHILE and vice versa.

So here we are going to use the WHILE because in this particular programming problem we will
not have anything like a single control variable and therefore, it will be much natural to use the
WHILE statement. So we are going to derive the algorithm and argue its correctness because the
correctness is not going to be too obvious.

279
(Refer slide time: 1: 27)

Okay so, what is the problem? So we need to find the greatest common divisor of 2 numbers and
we are going to see or we are going to derive Euclid’s algorithm. So, what is the greatest
common devisor positive integers m and n? It is the largest positive integer p that divides both m
and n. So for example the greatest common divisor of 36 and 24 is 12 because 12 divides both 36
and 24 and there is no larger number which divide both of them. There is a standard method for
doing this which you probably learned in primary school which is to factorise m and n and then
multiply out the common factors. Euclid’s algorithm is a very old algorithm and is different and
actually it runs much faster and in fact, the program based on Euclid's method will also run faster
than programs based on factoring. So Euclid's algorithm might have been developed for manual
computation, but it is a very commonly used method on computers.

280
(Refer slide time: 2:47)

So what is Euclid’s algorithm? So there is a very basic observation which is actually fairly
simple. So the basic observation says that if “d” divides both m and n, then “d” divides m minus
n also and here we are assuming that m is bigger than n. So why is this? Well the proof is just a
single line, so because “d” divides m, m must be ‘a’ times “d” for some a, “d” divides n so n
must be ‘b’ times “d” for some b, so m minus n must be a minus b times “d” but that just shows
that m minus n has “d” as a factor, done.

Also true is sort of a converse. It says that if “d” divides m minus n and n then “d” divides m as
well okay. So, why is that true? Again the argument is very similar okay. So “d” divides m
minus n, so m minus n must be ‘c’ times “d”. Then “d” divides n so n must be some ‘e’ times “d”
and so m which is m minus m plus n must be c plus e times "d". So we have written m as a
multiple of c plus e times "d". So “d” is the factor of m as well.

So together what does it mean? It means that so whatever divisors m and n have m minus n, n
also have so if “d” is a common divisor of m, n it is a common divisor of m minus n, n as well.
So it means that the largest divisor of m, n is also the largest divisor m minus n and n, because if
m minus n had an even larger divisor that would have to be a divisor of m, n so that could not be
larger than the largest divisor of m, n. So which means and this is the big insight is that instead of
finding GCD of m, n we might as well find GCD of n and m minus n. Now this is useful in the
following sense, if you look at the numbers m, n and n, m minus n and we are assuming m is

281
bigger than n then we know that theses two numbers are smaller than m, n. At least one of the
numbers is smaller. So, so that means if you are going to this by hand we have gotten our
numbers to be smaller and of course that helps when doing things by hand, but interestingly it
helps also while doing things on a computer and we will see the reasons for it.

(Refer slide time: 5:44)

So let us take an example, so suppose I want the GCD of 3977 and 943 So if we apply the
previous idea then we know that this must be the GCD 3977 minus 943 or m minus n and n. But
I can apply the idea and so if will do the subtraction I get GCD of n 3034 and 943, but I can
apply this idea one more time, who is stopping me? So again I subtract 943 from that so I get
2091 but I can apply one more time and I supply 943 one more time so I get 1148 and 943. If I
apply one more time, I am going to get 1148 minus 943 GCD of 205, 943.

Now, if you think about this you will realize that 205 is just 3977 mod 943. So we did not have
to go through subtracting 943 one at a time we could have just subtracted as many times in one
shot and just taken the remainder okay. So, so that what exactly we should do instead of going in
these several steps. So what should we do? We should write GCD of 3977, 943 is equal to GCD
of 3977 mod 943 and 943 because that is what this process is going to get us to.

282
(Refer slide time: 7:21)

Alright, so does that mean that GCD of m and n is GCD of m mod n and n. Well we have to be a
little careful because if m mod n is 0, and since we have defined GCD only for positive integers
then we cannot write this. But we could we could say that look lets define GCD for 0 as well or
we could do something less dramatic and we could say maybe like what reasonably Euclid did.
So we will write a statement which we could call Euclid’s theorem, which is that let m and n be
positive integers they have written as 0. If n divides m then GCD of m and n is n, if n divides m
than clearly the largest number dividing both m and n must be n, But, if n does not divides m,
then GCD of m and n must be equal to GCD of m mod n, n. So yes, so what we wrote at the top
of the slide is almost true except when n divides m and I am not going to prove this, you can
prove it I mean we almost have proved it but if you really want you can prove it again by writing
m as some k time t and so on.

283
(Refer slide time: 8:56)

Okay, so now we can go and do that problem again. So which is GCD 3977, 943 is equal to 3977
943 mod 943. Okay, so we have got GCD of 205 and 943, but now we can use the same idea
again so GCD of 205 and 943 mod 205. So that is what 205, 123 but again the same idea 205
mod 123, 123 so that is 82, 123; 82, 123 is 82 and 123 mod 82 and that is GCD of 82, 41. But
now, if we take 82 mod 41 we see that 82 is a multiple, 41 divides 82 so that means 41 must be
the GCD. Because 41 divides 82 so 41 must be the GCD of this but the GCD of this is the GCD
of this, this all the way till this. So we have found the GCD of 3977 and 943 and that happens to
be 41.

Now let me point it out as an aside that we have done some number of divisions over here, but it
will turn out that the number of divisions we do in this method is much smaller than the number
of divisions you would have done if you would have actually done the factoring, forget the
multiplications here. So that we are not going to proof, but you can take examples and you can
persuade yourself. So, so we have manual algorithm now, are we ready to write a program? Well
before that I would like you to make sure that you understand this and I would like you to find
Euclid’s GCD of say 26 and 42.

284
(Refer slide time: 10:47)

So what is algorithm? So input “R” value is capital M and capital N which are stored in variables
m and n, little m and little n. And in each iteration we will either discover the GCD of M, N
capital M and N, so that will happen if we have the division and we have the larger number is
perfectly divided by the smaller number. Or we will find the smaller number whose GCD is the
same as GCD of M and N.

So that is, that is basically the idea of the iteration, so what are the details of the iteration? At the
beginning we have the numbers stored in little m and little n, whose GCD is the same as GCD of
M and N, well at the beginning of we will store capital M and capital N in m and n okay. So this
statement is obviously true, but in each iteration we will try to maintain the statement. So if n
divides m well we have we declare n to be the GCD, okay so that is by Euclid’s theorem. But if
it is not, then we know that GCD of M and N or the GCD of m and n which is equal to the GCD
of M and N must be equal to GCD of n and m mod n. So as a result we have changed the
numbers n and m mod n, we have changed the numbers which we have in our hand. But we
know that their GCD is still the same as the GCD what we wanted. So what we can do is we can
now store the n and m mod n in m and n. So here we are effectively assuming that the larger
number is always in m and the smaller number is in n okay. So that is what is the algorithm is,
okay.

(Refer slide time: 12:48)

285
So what is the program so the main program is int m and n and we read values of m and n. So the
values read are capital M and capital N. Now, so we will check whether m mod n is equal to 0.
So if it not equal to 0 then we have something to do. So what is it that we have to do? We will
calculate the next value of m which is going to be n, the next value of n which is going to be m
mod n and then we simply said m and n to be the next values. And if this iteration finishes that is
if at some point we discover m mod n to be equal to 0 okay then we know that n must be the
divisor. So we print out n.

So now there are some settle points over here which I should note, so if I want to store n and m
mod n into m and n I cannot just write m equal to n, n equal to m mod n. Why? Because if I write
m equal to n then when I try to do this m mod n this m would already have the value n so then I
would be doing n mod n, so that would just give me 1. So that is not good. So that is why we
need to do something elaborate like this just to be careful we are saying what is the next value of
m and of n and we are doing that okay. Alright, I guess I will resolve that for you okay.

286
(Refer Slide Time: 14:25)

Alright, so next m and next n have been defined for clarity we could have just used 1 variable
instead of both and that is what is shown over here, but you do not have to really worry about
these details you can just use two variables, who is counting. Now, intuitively it should be clear
that we have followed Euclid’s theorem or the idea from the Euclid’s theorem. But, we already
said that there can be one mistake that we could make we could just write m and n the new
values of m and n directly into m and n and that could be one mistake. Then you might also
worry is m always going to be larger than n, are we taking care of that, do we need to take care
of that okay so these are things that we need to worry about because if those things are not
working out then maybe our program will not run correctly.

287
(Refer slide time: 15:27)

So here is a wrong program which seems to be following exactly the idea that we have discussed.
So it does all of those things, but in this update mistakenly we put what we intended for m into n
and what we intended for n into m, small mistake, right? But as a result of this the program will
not run. So you are asked to figure out what is the mistake or whether there is a mistake. And
maybe you can check that by exchanging the values assigned to m and n we get the right answer.
But this exercise makes the following point that once we write the program, we claim that we are
following Euclid’s idea, but have we, while doing this, have we introduce some mistakes into it?
So we need some ways of checking that okay and so we will look at that in the next segment.

288
(Refer slide time: 16:21)

So what did we discussed in this segment? We discussed Euclid’s algorithm for determining the
GCD of two positive integers and we said that the program appears easy to write, but there is
room to make mistakes and in the next segment we will check for correctness of our program
and make sure that we have not made any mistakes. We will stop here.

289
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 7 Part – 6
Looping Statements
Correctness proof for GCD
(Refer Time Slide: 0:25)

In the previous segment we discussed Euclid's algorithm for determining the GCD of two
positive integers. And we said that the program is simple, but we also said that it is possible
to make mistakes and therefore, it is a good idea to do some cross checks later on to ensure
that we did not make any mistakes. So that is what we are going to do in this segment.

(Refer Time Slide: 1:05)

290
So basically we are going to try and produce some kind of a correctness proof. So a
correctness proof I guess has two things it does. It sort of says that we have implemented the
major ideas correctly, so that Euclid's theorem correctly, but we have not make any silly
mistakes. So if the program just happens to be one statement after another without any loops
then we can visually check because the loops really sort of confuse the issues right. I mean
the loop say oh in the previous iteration what happened in the previous iteration before that
what happened and all that. So we have to make sort of precise statements about what
happens in each iteration. So therefore, we need to be a little bit careful and we sort of need
some special machinery for that.

(Refer Time Slide: 1:37)

Okay, so, how does a correctness proof of a program look like? So, we need to prove that the
program must terminate because this is one way in which a program could do something
wrong, so a program may go into an endless loop. So we do not want that. And we want that
the program should give correct answer when it terminates. So typically this is done by
defining something called a potential which tells us that the program terminates and then we
also define something called the invariant which says that the program will sort of give the
correct answer. So we will see these two things now.

291
(Refer Time Slide: 2:26)

So invariants, so let us say that capital M and capital N are the values typed in by the user
into the variables little m and little n. Then we would like to make the following claim just
before and just after every iteration the values of the variables m and n might be different
from iteration to iteration. However, GCD of what is in m and n is exactly the GCD of capital
M and capital N which is the GCD of the numbers that we wanted. So this basically says that
yes you are allowed to do something to those values m and n, but we are not losing any
information so hopefully the numbers are decreasing, but we are not losing any information.
So that is what the statement says or this claim says. So such a claim which says that a certain
property does not change due to a loop iteration is called a loop invariant or sometimes just
invariant.

292
(Refer Time Slide: 3:55)

So now, I am going to give a proof sketch of our invariant. Our invariant was that the GCD of
the values contained in the variables m and n is equal to the GCD of capital M and capital N
the values typed by the user in the beginning and that this holds at the beginning and end of
every iteration. So at end and beginning of every iteration the variables little m and little n
contain values whose GCD is the answer that we want. So while the values in m and n
changed their GCD remains what we want.

So here is our main program. Now, the way to prove this is to first see what happens on the
very first iteration. So on the very first iteration you can see that we are reading in values
capital M and capital N into these variables. So when you enter the iteration then clearly m
and n will have exactly, the variables m and n will have exactly the values capital M and
capital N, so this will be trivially true. So on the first iteration everything is easy. So, so, let
us worry about the second iteration or in general the ith iteration because we are going to
assume that it is true at the beginning of some ith iteration and we are going to prove that it
will hold at the end of the ith iteration. So since we have proved that it is true at the beginning
of the first iteration, then what if we prove it for general i the fact that it is true at the
beginning of the first iteration will guarantee that it will true at the end of the first iteration,
but being true at the end of the first iteration is the same thing as being true at the beginning
of the second iteration. So the fact that it is true at the beginning of the second iteration will
guarantee that it will be true at the end of the second iteration and so on. So we just have to
make this assumption that it is true at the ith entry and from this we have to derive that it
must be true on the end of the ith iteration. So let us see what happens in this iteration. So the

293
next value of m this next m is going to be n, the next value of n is going to be m mod n. So
note first that by Euclid’s theorem the GCD of the original values in m and n is equal to the
next values of n and m mod n. Why? Euclid’s theorem and Euclid’s theorem in the case m
mod n is not 0. So why is m mod n is not 0? Well the very fact that we entered over here says
that m mod n must not be 0. So by Euclid’s theorem, the GCD of these values must be the
GCD of the original contents of m and n. But at the end what are we doing we are placing
these values inside m and n so therefore we have proved the invariant holds also at the end.
So what we have done? We have proved that the final values of m and n which are these,
where GCD is also the same as the original, the GCD of the original values. So we have
proved that if the invariant is true at the beginning then the invariant must be true at the end.
And therefore, we have proved that it must be true at the beginning and at the end of all
iterations.

Now, I want to argue that this invariant actually implies that the correct value is printed in
this last statement as well. The correct value is printed over here. Why is that? If the correct
value is printed then control comes over here only from this point. So at this point m mod n
must have been equal to 0. But if m mod n is equal to 0, then m must divide n not only that n
must be greatest divisor of both little m and little n. But the loop invariant assures us that
little m and little n have the same divisor as capital M and capital N. Therefore, the divisor
the greatest divisor of little m and little n is exactly the answer that we are looking for and
that is the answer that we have printed. Of course, so we have only proved right now that the
correct answer is printed if control ever gets to this point. So next we have to argue that the
control actually gets to this point, so that is the proof of termination.

294
(Refer Time Slide: 8:54)

So again this is our program. And the key point to be noted over here is that the value of n the
second argument is always going to decrease. So, why is that? So the second, the next value
of the second argument is going to be m mod n. Okay, but m mod n is always smaller than n,
the remainder when something is divided by n is always smaller than that number. So
therefore, this second argument value is always going to decrease.

So the second argument value starts off as capital N it is going to decrease and it is an integer
so it decreases at least by 1. And so if n iterations happen, then what would happen? Then
this n would become 0, but we know that it does not become 0. We know that but we should
really prove it but that is an easy proof, I will let you figure it out that it never becomes 0. So
that means, n iterations can never happen. So that means fewer than n iterations happen or in
particular some finite number of iterations happen and this algorithm terminates, alright?

So we have argued that not only does the algorithm prove the correct answer if it terminates,
but we have also argued that it terminates and therefore, we know that it terminates and
produces the correct answer. Now, I would like you to go back and ask yourself, what
happens if these two were exchanged? You would see that then this termination would not
happen because the value of n would not decrease. So just a silly mistake would prevent the
termination from happening. This is the answer to the problem that was asked on an earlier
slide.

295
(Refer Time Slide: 10:40)

So we have said basically that it terminates and it prints the correct answer and therefore, we
have proved that it actually terminates and prints the correct answer. So we argued that the
program terminates and we also argued that if it terminates it prints the correct answer. So
therefore, we can say that it terminates and prints the correct answer. So this is just a writing
down of that.

(Refer Time Slide: 10:53)

So let us summarize, so we claimed that in each iteration, m and n may change but their GCD
does not change. So essentially this is saying that means we are not losing any information
although we are making the number smaller and smaller. So eventually if we get GCD at any
point that will be the correct value and we said that in each iteration the second argument

296
reduces but it can never become 0 and therefore, since it reduces by at least one, the number
of iteration has to be smaller than the first value that this variable m takes.

(Refer Time Slide: 11:56)

Now, we had another example of for loop this time which shows the cube table program.
Now, you may ask does this idea of proof of correctness, invariant, does it apply to the cube
table program as well? So this was our cube table program it is a rather trivial program, so in
the first place its correctness it is pretty obvious just by looking at it. We do not really, there
is no there is no real room for confusion over here. But we can write an invariant if we really
want. And the invariant could be something like this. When iteration i begins, cubes until i
minus 1 will have been printed. So that is true and this invariant is actually useful in the sense
that it tells us very explicitly what progress we have made until that point. And the potential
we could say is the value of I, and that it must increase in every step, but cannot increase
beyond y. So the potential cannot beyond i it starts at 1 and therefore right away we know
that there are 100 equation, so this part is rather trivial, but this part is still somewhat
interesting because it is saying what progress we have made until step i. So as I said for such
simple programs invariant seems to make the simple things more complex okay. So it is not
recommended that you should write invariants. But the invariant does say something useful.
So you should, you should have it in mind that it does make progress. So while formally an
invariant is not needed, but it does say something interesting.

297
(Refer Time Slide: 13:44)

Okay, so some concluding remarks. So we have looked at while, do while and for, which are
the C++ statements that allow you to loop. Repeat allows you to loop, but it is not a part of
C++, it is a part of simplecpp. And we introduced it because it is very easy to understand. But
now that you know while, do while, for, you should stop using repeat, for one thing because
you want to learn the C++ statements and another because the C++ statements are more
general and more powerful and they can do things which the repeat cannot do.

(Refer Time Slide: 14:30)

So, some more concluding remarks. The important issues in writing a loop are, ensure that
you do not execute iterations indefinitely. If you cannot terminate the loop using a check at
the beginning of the repeated portion, you can either duplicate the code or you can use a

298
break. So some work is needed in order to match the structure of your manual algorithm
which might have that condition checking step at different places so that it matches with
whatever statements you write.

The remarks that we made in chapter 3 about thinking about the manual algorithm. Making a
plan and identifying the general pattern of action apply here also. And in some sense what is
happening over here, the invariants and the termination are sort of the part of the plan. So
when you write a loop you should have something like the invariant in your mind which is
kind of a plan. Then the actions in the loop may include preparing for the next iteration. So
incrementing the variable or setting new values of m and n as in the GCD program. So
typically, the loop may have some initial values of the variables, then maybe you do
something with the variables like may be print them and then you change the value so that
they are ready for the next iteration that is they satisfy whatever, if invariant is needed for the
next iteration.

Thinking about invariants and potential is a good thing in the sense that you are checking that
your loop is doing the right thing and that it will terminate. I would suggest that you should
write these down when the algorithm is even slightly clever. You should think to yourself
look am I completely sure that this loop is going to terminate? So for that, defining something
like a potential is a really good idea. And it is really good idea also to write invariants
because they tell you what your program is doing. So if you make a mistake, if you have a
bug, then the invariant and the potential will help you find that bug. So the potential will tell
you why is my program not terminating, the invariant might tell you why is my program not
giving the correct answer, so at some point quite presumably quite possibly the invariant may
be violated by your program so you want some property to hold, but while writing the
program you made a silly mistake and that property is not holding any longer.

Now, the proof of learning to program is in writing lots of program so at the end of chapter 7
many problems are given. So I will strongly encourage you to write programs corresponding
to these, to those problems and with that I will conclude this lecture segment, thank you.

299
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 8 Part – 1
Computing Mathematical Functions
Computing common mathematical functions: Taylor series
Hello and welcome to the NPTEL course on an introduction to programming through C++. I am
Abhiram Ranade, this is lecture sequence 3 of week 3. The reading for this is Chapter 8 of the
textbook.

(Refer Slide Time: 0:35)

The goal of this lecture sequence is to learn methods for performing common mathematical
operations. So we often need to evaluate mathematical functions such as sin x, log x and we
often also need to integrate functions. So these things can come up in Engineering or Science or
even mathematics. And integration can of course be performed symbolically but sometimes it is
not possible to get a closed form solution. In that case we can do numerical integration. So
integration is useful intrinsically, but in addition we can also cast the problem of evaluating
certain function as an integration problem. So we will see that soon.

Finding roots is another important mathematical operation. And of course we have seen
examples of such things, quadratic equations, solutions of simultaneous equations. So in general
the goal here is to find an x such that f(x) equal to 0 is satisfied. And of course we may have

300
several x that we might want to find simultaneously. But here let us consider we have an
equation in 1 variable and we have to find a solution for that single variable. So this is an
intrinsically useful problem, but in addition as we will see we can cast the problem of evaluating
certain functions as root finding problem.

Now all these problems have methods which will give approximate answers. And in fact, exact
answers are generally not possible for any of these problems. And by that I mean exact answers
which use a certain finite number of arithmetic operations. However, the method that we
describe will have the property that by doing more and more work we can reduce the error as
much as we want. So we can make the error be as close to 0 as we want, but for that we might
have to do more arithmetic operations. So there will be some kind of a tradeoff.

On the other hand, the programs that we will write for doing these computations will be
extremely simple. They will just involve 1 loop and maybe 2, 3 variables. So in that sense they
will turn out to be good problems for developing and practicing your programming skills.

(Refer Slide Time: 3:15)

So here is the outline of this lecture sequence. So first I am going to talk about methods based on
Taylor series, then I will talk about numerical integration, then I will talk about a method called
the bisection method and then a method called Newton-Raphson method.

301
(Refer Slide Time: 3:41)

So let me start with an example for a Taylor series. So the question over here is how do we
calculate functions such as sin x, cos x, ln x, tan x whatever square root x. Now, it turns out that
these functions can be expressed as a sum of infinite terms. So let me give an example right
away. So sin x can be written as x–x3/3!+x5/5!-x7/7!+, as you might guess x9/9!-x11/11! and so
on.

So as you can see the power of x increases by 2 as we go from the from one term to the next.
And the factorial also increases by 2. So you can see that there is a very clear pattern. And the
nice thing about this is that each term is easy to evaluate. So x^5/5! can be evaluated by doing
say 5 multiplications and 5 divisions. And another very important and nice thing is that even if
we take the first few terms we do get a fairly good answer. And if we want a better accuracy we
just have to take additional terms.

So this is very good, but in fact it has an even nicer property; which is that we can get a good
estimate on how bad our error is. So suppose, we evaluate this sum to the first k terms. Then we
can prove, we are not going to do it in that in this course, but it is possible to prove that the error
is going to be smaller than the k plus 1th term. So if we use the k terms, then the next term
actually just even tells us the bound on the error.

(Refer Slide Time: 6:09)

302
So let us try it out let us see how we can write a program to compute the value of sin x. And you
may you may observe perhaps and it is true the program is going to be similar to our calculation
of e, the base of the natural logarithm that we did earlier. So let us compute sin x using this
formula, this infinite sum. So our plan is going to be that in the kth iteration we will add the kth
term of the series to a running sum which is initialized to 0. In some sense this is similar to the
plan we made for calculating the value e, sometime ago. So, let us use t sub k to denote the kth
term of this series, for k equal to 1, 2, 3 and so on. So looking at this sum we can say that t1 is
equal to x or which we might in fact write as x^1/1!, t2 is equal to x^3/3!, but there is a minus
sign over here, t3 is equal to x^5/5! and I will just write a plus sign over here just to emphasize.

303
And so the point is that the first sign is plus, then there is a minus, then there is a plus and so on.
So the plus and minus signs are going to alternate.

Alright, so these are the terms and now I can write this tk as -1^(k+1). Why? Why k+1? So, if I
just wrote minus 1 to the power k then minus 1 to the power 1 would give me a negative number,
so I will write minus 1 to the power k plus 1. And the minus 1 to the power increasing power will
make sure that signs will alternate.

Then I have x^(2k-1) let us check whether this is correct. So for k equal to 1 this gives 1 and then
there is 1 factorial over here. So for K equal to 2, this 2k-1 will give us 4 minus 1, 3 which is
right upon 3 factorial and so on. So tk is indeed this. So these are the terms that we are going to
calculate in subsequent consecutive iterations. And we are going to add them to a running sum
which we are going to initialize to 0 at the beginning. Then we know that t1 is given to us as
input. So t1 is available to us at the beginning of the first iteration. So we would like t2 to be
available at the beginning of second iteration, and t3 at the beginning of the third iteration and so
on. So our plan is something like this at the beginning of the kth iteration, we will ensure
somehow that we have tk in variable capital T. We could have made a different plan, we could
have said that we just want tk minus 1 in the capital T at the beginning of the kth iteration. And
in the kth iteration we will somehow calculate tk. So that plan will also work, it will give rise to a
different program. So here you are just going to stick to the plan that I have written down over
here. Which is that at the beginning of the kth iteration we will ensure we have tk invariable T.

And then that means that at the end of iteration k what should we have? Well we have said at the
top that S must equal the sum of the first k terms, so including tk, and so tk should get added to
S. And for the k plus 1th iteration, we would like capital T to have tk plus 1. So therefore, at the
end of iteration k we must make capital T equal to the k plus 1th term or tk. And what is this tk
plus 1, well I am going to substitute k plus 1 over here. So I am going to get a k plus 2 over here.
And then this is going to be 2k minus 1. So if I substitute k equal to k plus 1 over here, then I
will get 2k plus 1 over here. And then similarly, I will get 2k plus 1 factorial over here.

So somehow, I have to get into variable capital T, this value, whereas originally in capital T I
had this value. How do I do that? Well, if I observe these two values, I can see that they are not
that different. So to what extent are they different? Well, here there is an extra multiplication by

304
minus 1. So I should multiply this term by minus 1 if I want to make look it like this. But that is
not enough there is x to the power 2k minus 1 over here, and I want 2k plus 1 over here. So I
should also multiply it by multiply it by x square. And I had 2k minus 1 factorial over here. So if
I multiply it by 2k and also 2k plus 1 or rather it is in the denominator. So if I divide it by 2k and
2k plus 1 I will get this. Another way of stating the same thing is that tk plus 1 is tk times
whatever factors I mentioned earlier. So I need a minus 1 and then I need an x squared and then I
need to divide by 2K and 2K plus 1. So what needs to happen is that I already have tk and that
has to be modified a little by multiplying or dividing by these terms. Once I do that I will get tk
plus 1 in capital T as I want.

So in iteration T what is it that we are supposed to do? We are supposed to add the value that we
have at the beginning in T into S. And then we are going to multiply T by this term over here. So
T originally contain this. So when we multiply it by this term it will contain tk plus 1, which is
exactly what we wanted over here. So this allows us to write a program.

305
(Refer Slide Time: 12:23)

So we are ready to write a program. So we will declare a variable x and read it, this is the
variable whose sin we want to calculate. So let us print out a message saying what exactly we are
doing. And then we wanted a variable s in which we are going to accumulate the sum, and a
variable t in which we are going to keep the successive terms of the series. So the first term is x,
so which is how we initialize t. Then we are going to do this for 10 iterations. So we could have
chosen different numbers, but 10 is as good as any. So in the first iteration we want sum to be
initialized to 0 which we have done. And we want t to have the value of the first term of the
series which also we have done. Then, inside the iteration we just said that we are going to add
the term to the sum. So we write s equal to s plus t. And then we want to calculate the next value
of the term. So the next value of the term we said can be obtained by multiplying the previous
term by -1 and x square and then dividing by 2k and 2k+1. So which is what we have done over
here.

So at this point we have evaluated the sum to k terms. So we are going to print that. Just to see
how the sum changes as the number of terms increases. So this is the number of terms k and we
have evaluated the sum and that value is over here. That is not complete and we can also print
out the error estimate. So as we said the error estimate is nothing but the new term value that is
what happens to be the case for the sin x series so we are going to print that so when we run this
program we will see how the sum is changing or how our calculation of sin x is progressing, but

306
we will also get an error estimate. So we will see that look the error in this current in this current
value that we have computed is at most how much.

So that is the loop and then at the end what we are going to do this we are going to print out the
value of sin x from the C++ library function. So there is a C++ library function called sin. And
we apply it to x and we are going to get that value. And this is kind of the gold standard value or
the value which we can regard as the correct value. And we will be able to check whether our
value is the same or different from this value. So that is the end of the program.

(Refer Slide Time: 15:10)

307
So before we go to Taylor's theorem let us execute this program and see what happens. So this is
our program, this is the program that we had typed. So let us try running it. So let me first
compile it and let me run it. So let me give a value of sin so let us say I give the value 0.1. So let
us see so what does it say? So for 0.1 the value calculated is 0.1 itself and the error estimate is
already not so bad. The error is at this point just about 0.0001. So already our value is pretty
good. But if we go to the next step, the error estimate goes down even drastically, very
drastically and our value comes becomes something like 0.998. And then we can see from the
third term after adding 3 terms our answer continues to remain the same basically. So very little
improvement happens. So what has happened over here is that we have pretty much got the
correct answer in just about 3 terms. And we can see that this is the answer that the library
function is also going to give us. So in 3 terms we have got the correct answer.

(Refer Slide Time: 16:49)

308
Let us just run it one more time, maybe for a different value so let us say 0.5. So here the error is
a little bit worse after the first iteration and also the second iteration, but from the third iteration
onwards the error seems to be really negligible. And from the fourth iteration the value is exactly
the value that the library function gives. And of course the error is small. So this seems pretty
good. This series is giving us quite good results.

309
(Refer Slide Time: 17:37)

So now, let me talk in more general terms. So we just did something for sin, turns out we can do
something similar for many other functions. So Taylor's theorem is what allows us to do this.
And Taylor's theorem says that many interesting functions can be written in the following form.
So f(x) can be written as f(x0)+f’(x0), so the derivative of the function evaluated at x0, times x-
x0+f’’(x0), or the second derivative of f evaluated at x0, times (x-x0) squared upon 2 factorial
plus f’’’(x0) times (x-x0) cubed upon 3 factorial and so on.

Now this equality holds assuming we add up infinite number of terms. If x is within some
particular distance of x0, and this distance is called the radius of convergence. So this is some
distance that we can estimate mathematically and so long as x is close to x0 as compared to this
distance, then this theorem, this expression is correct.

Now, why does this expression help us to evaluate f(x)? I mean sin x? Why does it, why would it
help us to evaluate sin x? The point is that is you can often choose x0 such that not only is it
possible to evaluate f(x0), but also we can do it for f’(x0) and so on. f’, f’’, and f’’’. So we can
often choose x0 such that it is possible to easily evaluate f and its derivatives of x0. So let us take
the example of sin, so we will choose x naught equal to 0. So then, what we know? So we know
that f of 0 or sin of 0 is 0. f’(0), what is the derivative of sin x? It is cos x. So cos of 0 is actually
1. So again we could evaluate the derivative of f(x) at x0 equal to 0. What about the second
derivative? The second derivative of sin is -sin and again at 0 -sin is 0.

310
The third derivative is -cos. But at 0 it is -cos of 0 is -1. After this the pattern is actually going to
repeat, the fourth derivative is going to be cos and so it is going to be 0, 1, 0, -1, 0, 1,-1 and so
on. So where does that leave us for sin? So sin(x), if you substitute x0 in this you are going to
f(0), so you will get a 0 over here. Then over here you are going to substitute 0, so f’(0) is you
are going to get a 1 over here. And this is 0 so you are going to get an x over here. So you got an
x. Then for f’’, f’’(0) is 0. So this term will go away, f’’’ is minus 1, so we are going to get a
minus term over here and there is going to be an x minus x0 cube term. But x0 is 0 so you are
going to get x cube upon 3 factorial. And as you can see the even terms are going away and the
odd terms are coming out with alternating signs which is exactly what we started off with before.
So what we did was exactly an application of Taylor's theorem. And it turns out that this will
work no matter what value you substitute. So if you go to large enough terms this will get very
very close and in the limits it will become exactly f(x).

311
(Refer Slide Time: 21:37)

Alright, so what have we discussed? We have discussed that Taylor series are available for many
functions. And in fact I will ask you as an exercise to construct the series and write down the
program to calculate cos(x). And Taylor series is just one infinite expression which has been
used for calculating math functions. But people have written similar infinite expressions, say
infinite products or continued fractions. And these can also be used to evaluate mathematical
expressions. So these are discussed in the book and in the exercises in the book. So we will stop
here.

312
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 8 Part – 2
Computing Mathematical Functions
Numerical Integration
(Refer Slide Time: 0:32)

Welcome back, in the previous segment we discussed Taylor series and its use in evaluating
mathematical functions. Now, we are going to look at numerical integration. So in many
scientific calculations we need to integrate and if the closed form is not available, which is often
the case we can integrate numerically. So here we just go with the definition which is that the
integral is nothing but the area under the curve. So here is the curve for f and we want the
integral from p to q. So it is just the area between in this inside this region from p to q. So
underneath so this area, so this is the area that we want to find which is the integral from p to q
of that function f.

Now, how do we estimate this area? Well we are going to approximate it by rectangles, so as I
have shown over here. So we sort of try to put down the rectangles and the way we are going to
put down the rectangle is that we are going to draw these vertical lines. So at this point we draw
a vertical line which hits the function and then we put down the rectangle. Then at this point
again we draw a line which hits the function and we put down another rectangle. Again at this
point we put line and hit the rectangle and so on.

313
So we put down the rectangles in this manner and our error will be something of this order. So
the difference between the rectangles and the area under the line, so say this will be the error. But
it should be clear that if we put down the rectangles we are going to get a reasonable estimate
and the more rectangles we put down the more accurate our estimate is going to be.

(Refer Slide Time: 2:22)

Now we can make a plan to write this program. So first we should read p and q. So these are,
these are the limits of the integration and in this picture so this x-coordinate and this x-
coordinate. Then we should read how many rectangles we want, so let us say we want n
rectangles. As we said the bigger the value of n is the nicer the fit of the rectangles into that area
is going to be.

So then, we calculate the width and for simplicity we are going to assume that all rectangles have
the same width. So our width is going to be q - p, so this distance from 0 minus this distance so
this width q - p upon n. So, now we want to know the areas. So let us consider the ith of these
rectangles. So it is convenient to call this the 0th rectangle, this is the first rectangle, this is the
second rectangle and so on. So what is the height of this 0th rectangle? Well, what is this
coordinate? So this is p. So the height of this is simply the point at which this vertical line meets
the ‘f’ function. So that is simply f(p). What is the height at this point? It is p + w which is the x-
coordinate over here. But not p + w, f applied to that. This is going to be f(p+w) and so on. So in
general you can see that the ith rectangle is going to begin at p+iw. And its height is going to be

314
f(x) equal to f(p + iw). So this point is going to be p + iw and this height is going to be f(p+iw).
So if f is the function that we want to integrate, we had better be able to calculate this. And of
course the area is what? The area is the width of each rectangle. So this is w which we calculated
over here times f(p+iw) which is the height of that rectangle. So the integral is just the sum over
all i.

(Refer Slide Time: 4:38)

So this is our generic plan, I have just rewritten it over here and now we can write the program.
So our program goes as follows, we are going to declare variables p and q and we are going to
read them. So these are the limits of the integration. Then we are going to read in the number of
rectangles that we desire, so that is n. Then we will calculate the width of each rectangle that is
going to be (q-p)/n.

So I am really just following along what I have written over here. So after that we are going to
do have a loop in which we are going to look at all those rectangles. So of course, we want to
have a variable to accumulate that integral and so that is the variable will call area. So now we
have the loop and in the loop we are just going to account for the areas of all these rectangles
which are numbered 0 through n-1. So that is what this loop is going to do. So the numbering of
the rectangle is exactly going to be the control variable inside this loop. So, what do we do
inside? Well we are going to take this old area and to that we are going to add the area of the new
rectangle. And, what is the area of the new rectangle? It is w times the height of that rectangle

315
which is f(p+iw). So right now I am writing a program which is generic in the sense that it will
work for whatever function it is. But you will have to put in code over here which calculates this
function. So at the end of it we are going to print out the area and that is about it. So we just need
to put in the code over here to calculate this area and we will be done.

(Refer Slide Time: 6:44)

Now we are going to apply this to another specific problem which is the problem of numerical
integration. So here we are going to find ln(x) or the natural logarithm of x. And as you might
know this is exactly equal to the area under the curve f(x) equal to 1/x from 1 to x. So in other
words, what we have over here is that f of x is 1 upon x. So here is our old program and in over
here we had f(p+iw). But instead of that we know now that what a specific is, so that is just
going to be f(p+iw) is just going to be 1/p+iw. So our program for calculating ln x is going to be
exactly this. Now since we are calculating ln x, we can actually print out over here the official
value or the C++ library log function value, which gives us ln of x. And then if we compare these
two things we will know how good our calculation is.

(Refer Slide Time: 7:42)

316
Now, we can do that and it turns out that that gives fairly good results. And now here is some
analysis of the error that we can do. So the first error is due to the gap between the width of the
rectangles and the curve. So we said that we can reduse the gap by increasing the number of
rectangles. So maybe I should draw a picture just to see how that might happen, why that might
happen?

So let us say this is our x axis, this is our y axis and say this is our function which we want to
integrate between this p and this q. And what we did was, we put in these rectangles and that
area of these rectangles was approximating the actual area. Look what will happen, if we had
twice as many rectangles but of half the size. So if we did that these rectangles would get closer

317
to the actual curve. So originally the error would have been this this red triangle. Now instead of
that, the error is limited to this triangle and this triangle. So that extra line that we put, knocked
off this part from the error. So that is one way to reduce the error. But that is not the only error.

In the area of each rectangle also we have some error. Why is that? Because each number is
expressed to precision of a few digits. So if our numbers are floats then only 7-8 digits we get. If
we are, if our numbers are doubles, then we only gets 16-17 digits. And furthermore when we
multiply two numbers, we lose additional precision. So the end result is that every time we add
up two numbers, the error that we have in each of those numbers is going to accumulate.

So in each area we have an error of about 10 to the power minus 8 fraction. Because only the
first 8 digits we have. So our error is going to be 10 to the power minus 8 or 10 to the power
minus 17 per rectangle. So if you add n such areas, the error can increase to n times 10 to the
power minus 8 or n times 10 to the power minus 16. So it means that you should not add too
many too many rectangles, certainly not for float. So, if you are having double then adding many
rectangles is ok. So, how do we decrease the errors? So the way to decrease the errors is first of
all use trapeziums instead of rectangles.

318
(Refer Slide Time: 11:16)

So let me explain that. So let us say these are our 3 rectangles that we used. If we were to use
trapeziums we would use this region. This would be our trapezium. You can see already that the
trapezium is going to hug the curve much better and so the error is going to be much less.
Another idea is to set the height of the rectangles slightly differently. So we are going to keep the
same rectangles but here we use this as the height. Instead of that we are going to take the
midpoint of the, the midline of the rectangle and make it hit the function. So this is the rectangle
that we are going to use. So even here our line will pass through this middle region, even here
this line will pass through this middle region. So if I have to explore this a little bit, so this is our

319
function, these, this is our original rectangle and this is our new rectangle the top of the new
rectangle. So what has happened is, that we are overestimating the area in this region but we are
underestimating it in this region. So as a result the agreement with the actual area is better for
this rectangle.

(Refer Slide Time: 12:57)

So some exercises, so in the picture that we do drew it appears that the answer we calculate will
be smaller than the actual integral. So I want you to think about that and just observe that just
happens because of the way we draw the function. So if I (drew), the way we drew the picture of
the function. So if we drew the picture in a different way, so a hint is have a decreasing function
then you would see that our estimate is actually going to be larger than the actual integral. So I
would like you to do this exercise and persuade yourself.

Then to check whether the error will be less if we take the height to be the function value in the
middle, I want you to do the following thought experiment. So suppose I am using this to find
the integral of f(x) is equal to x. Of course, this can be easily integrated but we are using this as a
thought experiment just to check what happens if we take the midpoint of the integral. You will
see that in this case the midpoint that the taking the height at the middle of the rectangle works
beautifully.

320
(Refer Slide Time: 14:15)

Alright, so, what did we discuss in the segment? So we said that integration is needed in many
places in scientific computing. And numerical integration can be useful if closed form solutions
are not available. In order to perform numerical integration we just need to be able to evaluate
the given function at an arbitrary point. And we also said that the error will depend upon how
many and what kind of rectangles you use. And of course we use numerical integration to find
the value of ln x the natural log of x. So this finishes the segment and will take a break.

321
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 8 Part – 3
Computing Mathematical Functions
Bisection Method

Welcome back! In the previous segment, we discussed numerical integration. In this


segment, we are going to discuss the bisection method for finding roots.

(Refer Slide Time: 0:31)

322
So, the root a function F is a value x such that F(x) equal to 0. Or in other words, it is the
point, where F(x), the graph of F(x) crosses the x-axis. Now, many problems can be
expressed as finding roots. For example, if I want the square root of some number W,
then I claim that is the same thing as the root of the function F(x) equal to x^2-W. Why is
that? Well, if we do find root, that is if we find F(x) such that, if we find x, such that F(x)
equal to 0, then we know that x^2-W is equal to 0. Or, x must be square root of W.

Now, the bisection method has relatively few requirements as to when it can be
applicable. So for example, we require the ability to evaluate F, given an x. So, we should
be able to calculate F(x) given an x. Then, we want F to be continuous. And then, we
must be given points xl and xr, such that F(xl) and F(xr) are not both positive or not both
negative. So these are three relatively simple requirements, but once we have these then
we can use the bisection method. And the bisection method can be used for finding roots.
But, as we just remarked, finding roots is really itself useful for finding, for calculating
functions, such as say the square root in this case, okay. So, again to reiterate, we need to
be evaluate F. F must be continuous. And, we must be given points xl and xr, such that
F(xl) and F(xr) are not both positive or both negative.

Or in other words, what must be the case? So, if we plot the graph of X, graph of F. So,
this is the X-axis. This is the Y-axis. And, let us say, this is the point, this is the point
with X co-ordinate xl. This with xr. Then, the points F(x), the value of F at xl, say it is

323
here, then xr should be on the other side. Or, it could be at 0. But, both of them cannot be
on the same side, okay. So that is what the point is. That is what the requirement is.

So, I am going to describe the bisection method now. But, we will assume these three
properties. So, in other words, we will assume that we are given xl and xr satisfying this
property.

(Refer Slide Time: 3:36)

So the basic iteration of the method is as follows. So we will start with the user given xl
and xr. And then, we will bring them closer. As we bring them closer, we will maintain

324
the invariant, then, that xl and xr must have different signs or they are 0. If they are 0, it
does not really matter. Now, I want to observe that at the beginning this invariant is true.
That is because the user gave us two such, two such numbers. Now, before proceeding,
let me discuss the implication of this. So, suppose F(xl) is indeed positive and F(xr) is
negative. Now, because this function is continuous, what does it mean? The graph of the
function must start somewhere over here. Maybe it will increase. Maybe it will do
whatever it needs to, but it is continuous. So this graph, this line must be continuous. And
being and while it is continuous, it must still reach this point. So, what does it mean?
Then that means it must cross this X axis at some point. Otherwise it cannot go to the
other side. But the point at which it crosses is exactly the root. So, what we know is that
the root must be contained in this interval. So effectively when we said to the user please
give us xl and xr. The user is effectively giving us an interval, which contains the root.
So, invariant plus continuity implies that the root exists between xl and xr. And the root
might be exactly at xl or exactly at xr. So, F(xl) or F(xr) are allowed to be 0. So, we are
going to execute this basic iteration until the distance between xr and xl, becomes smaller
than some error bound. Let us call it epsilon. If, epsilon is really small, then these two
numbers are really close, and the root is somewhere in between them. Which really
means that we can declare one of those numbers, say xl as the root. So, we will have error
in this. But, the error is at most epsilon.

So, that is the whole, that is the whole; that is the gist of the argument, okay. So we are
going to get; we are going to get an approximate answer. But you will see that the
approximation can be as good as you want. No matter what epsilon you give us, we will
be able to iterate until that point.

So, let me, let me tell you now, how this iteration is going to happen. How we are going
to shrink this interval, okay. So, first we calculate xm, which is (xl+xr)/2. So, what is
that? Well, that is the midpoint of this interval xl to xr. Next, we check the signs of xm
and xl. If, these two signs are the same, okay, then we are going to set xl equal to xm. So
again, let us come back to this picture. So, this is xl, xr. We find the mid point, which is
over here. Then, we look at F(xl), okay. So the sign of F(xl) and the sign, the sign of
F(xm). So this is xm. So the sign of F(xm) is positive. And the sign of F(xl) is positive.

325
So that means, F(xl) and F(xm) have the same sign. So in which case, we will execute xl
equal to xm. Or in other words, we will move this point over to this point.

So, I claim now, that this is going to keep our invariant without violation. So, why is
that? Well, xl and xm had the same signs. So the signs did not change as we moved xl to
xm. As we assigned xl equal to xm, the signs did not change, okay. So that means the
sign of xl continues to remain different from the sign of xr. So, if it was different before,
then it will remain to continue to remain different. But, we are assuming that in, that this
invariant was true in the beginning of the iteration. And therefore, what we have proved
that in this case the invariant will hold even after the iteration. Or in other words, the root
will now be contained in this smaller interval, which is true in this case, in our picture.

If, this condition is not holding that is if xm and xl do not have the same sign, then we are
going to set xr equal to xm. So, why is that? Well, in that case xr must have the same sign
as xm. And so again, we can conclude that the sign of xr has not changed. And so even in
this case, we can conclude that the invariant is going to hold. So basically what we have
is a simple method by which we can shrink this interval.

(Refer Slide Time: 9:37)

So, let us now see the code file. So, we are going to write this code for the problem that
we mentioned earlier, which is finding the square root. And we will make the problem

326
very concrete by saying that we want to find the square root of 2. So in that case, as we
discussed earlier, we should be finding the root of F(x) equal to x^2-2. Because if x is
root of this, then x^2-2 must be equal to 0 or x^2 must be equal to 2 or x must be square
root of 2. So the root of this equation will indeed give us this square root of 2.

So first we need to supply xl and xr. So I claim that xl equal to 0 will work. So let us see
what that means. So xl equal to 0 means, F(x) equal to 0 minus 2. So F(xl) is negative.
So, so long as we can supply an xr, such that F(xr) is positive, we will have satisfied of
requirement .So we are going to set xr equal to 2. So F(xr) is 2 square or 4 minus 2 and
therefore, it is positive. So our xl and xr are really satisfying, what we set out that their
signs, the signs of F(xl) and F(xr) are indeed different. So then we need to have a variable
to store this xm value. And we need an epsilon as well. And let us say, just for, just as an
example that we pick epsilon to be 10 to the power minus 5, 10 to the power minus 4. I
am sorry, 10 to the power minus 5, okay. Anyway it does not matter. Now, we are going
to just have to write our basic iteration. And, what is our basic iteration? Well, we check
whether the interval xr to xl or the length of this interval which is xr-xl is bigger than
epsilon. If, it is bigger than epsilon, then that means that our interval is still larger than
what we want. So in that case, we should execute our basic step. So, what is our basic
step? So, we are going to find xm, which is the midpoint of xl and xr. And, so it is
xl+xr/2. Then, we are going to check whether xm and xl have the same signs, okay.

So, what is this checking? This is checking whether F(xl) is bigger than 0. So, does xl
have the positive sign? And, this checks whether xl has, xm, F(xm) also have the positive
sign. So, this is checking one side of the condition that we want, that F(xl) and F(xm),
both have positive side, positive signs. So, either they both; so if they both have positive
signs or if they both have negative signs, which is the second condition over here, then,
that means they have the same signs. xl and F(xl) and F(xm) have the same sign. In
which case, we are going to set xl equal to xm. Otherwise, we are going to set, xr equal to
xm. This is exactly what we said on the previous slide. That is it. So we are going to
repeat this. We are going to repeat while this condition holds. We are going to stop as
soon as this condition stops holding or in other words, when xr-xl becomes smaller than
epsilon. Or in other words, our interval have become smaller than epsilon. So at that point

327
we are going to print out xl as the root, alright. So, this is, this is what we said on the last
slide and this is what we have here. So, this should work, and we will yeah. So, before
moving on, I just want to ask you a simple question. So suppose instead of finding the
square of 2, square root of 2, I want the square root of some other number. So, say square
root of 3. How, could you choose xl and xr? So, we can follow; we can see what is
happening over here and maybe we will try to do something that is over here. So here we
have 2. So let us try if we put, what happens if we put 3 over here. So indeed we will see
that it works. Because, again this will be negative and this will be 9-3, so this will be
positive, okay. So, you can use the same idea to solve this for any number larger than 1,
for any number yeah. And, we are, we are, yeah. So, let me leave it at that.

(Refer Slide Time: 14:49)

So, let us do a quick demo of this. So, this is the program that we had on the slides. There
is a slight difference. So we are printing our final answer that we calculated over here.
But, in addition, in each iteration, we are also printing out the current interval. So the
current values of xl and xr. And we are doing this at the end of iteration. So at the end of
the first iteration, we will calculate what xl and xr are and so on for each iteration. So we
are calculating the intervals. We are calculating the final answer. And then we know that
there already exists a library function sqrt which gives us the square root. So we will print
that also. So that will tell us, how good our answer is.

328
(Refer Slide Time: 15:40)

So, let me compile this. Okay, so let us see, what it has printed. So at the end of the first
iteration the value, the interval was 1 to 2, okay. Does not makes sense? Well, we stared
off with 0 to 2, okay. xl was 0 and xr was 2. But then we moved xl to the midpoint, so it
was 1 to 2. And so the interval keeps on shrinking. And eventually it has got down to
this. So it take some amount of work, number of iterations. But it eventually did get to
this. And as you can see this is indeed identical to what the library function tells us. Of
course, there may be additional digits after this, which are not being printed over here.
And maybe the final answer is different. So, if you want to check that, you can print the
additional digits also. But anyway to 5 digits, this is certainly the same.

329
(Refer Slide Time: 16:55)

Okay, so let us get back to the slides. So a few remarks. So because we are picking the
midpoint in each iteration, this interval xl to xr is halving. So in each iterations the
interval halves. So the uncertainty in our, in our estimate goes down by the factor of 2. Or
in other words, we get one more bit of our final answer. And the size of interval gives the
error in the root, we said. And so the error halves. And so if you want to answer correct to
K bits you should use K iterations.

Now, the code that I have given over here is doing a few additional calculations over and
above what is strictly needed. So I do not want to get into that detail right now in this
lecture. But, you can take a look at the book and see how some of the work that you are
doing could be reduced. And let me leave you with an exercise. I would like you to
modify the program, so that it calculates the cube root of any number W. So the number
W should be read in from the keyboard. And your program should correctly initialize xl
and xr now. So think about how you would do, how you would have to do that. And then
we should print out the cube root this time, not the square root.

330
(Refer Slide Time: 18:27)

Okay, so what did we discuss? So we discussed the bisection method, which is a very
simple method for finding the roots of a function. So it requires that we should be able to
evaluate F for any x and that F should be continuous. And we need to have xl and xr,
such that F(xl) and F(xr) do not have the same sign. So if these three requirements are
met, then we can use the bisection method. And I should point out that the method is
simple but it is slow, in the sense that there are faster methods available. And next we
will see the Newton-Raphson method, which is one such method. But before that we will
take a break.

331
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 8 Part – 4
Computing Mathematical Functions
Newton Raphson Method

In the last segment we discussed the bisection methods for finding roots. This is a very simple
method. In this segment we are going to discuss Newton Raphson which is perhaps the most
sophisticated among the methods that we have discussed in this lecture sequence.

(Refer Slide Time: 0:38)

So the Newton Raphson method, it is again a method for finding the root of some function f(x),
that is finding x such that f(x) equals 0. This method is going to work if the following conditions
are met. We should be able to evaluate f(x) and its derivative f’(x). And we should have
available a good initial guess. So sometimes this condition is not quite necessary, but it definitely
helps. So we should, if we are close to the root then this method will quickly take us even closer
very close. But if we are far then this method occasionally may wander around too much.

So again we are going to use this method to find the square root of y. So as before we are going
to say that our function is f(x) is x^2-y. Now, in this case we want a derivative as well and we

332
might as well write this down immediately, so f’(x) is to 2x. So notice that given an x value, we
can evaluate f(x) as well as f’(x) quite easily in 2, 3 arithmetic operations.

We also need an initial guess and for this square root finding problem it turns out that x0 equal to
1 is a good guess. Actually for this problem the guess requirement is easily met. I think
essentially (any) any number will be ok.

(Refer Slide Time: 2:24)

So this is again and iterative method and the key step over here is to get a better approximation
of the root than the one that has been given to us. So let us say we have been given xi, which is
our current approximation to the root. So now, I am going to tell you how I can (get) how we can
get a better approximation and that better approximation we are going to call xi+1. So initially
we know this point A. So A is xi, 0, x coordinate is xi and y coordinate is 0. It is a point on the x-
axis. Next we are going to calculate f(xi). So f(xi) is just f(xi) is just the function value at this
point or it is this height upto this point. So in fact it is exactly this point. The B point is the point
over here. Because its x coordinate is the same as that of A and the height is f(xi). So we have so
we can determine the point B if we know xi because we can get the coordinates of point B.

Next step is we are going to approximate this function by a tangent at this point. So we are going
to approximate it by a tangent and we’ll ask where does the tangent meet the x-axis. So let us say
C is the intercept of the tangent on x-axis. So C is going to be our new guess. So its coordinate is

333
going to be (xi+1, 0). I have not told you exactly what that value is but that is what it is going to
be. And of course the Y coordinate is going to be 0. So all that remains now is that I have told
you how to geometrically get to C. But I have not told you how to algebraically get to C. So that
is all that remains. So you can observe that xi plus 1 is this distance from origin to C. So it is this
distance origin to A minus AC. So that is what this first equality case mean, xi+1=xi-AC. Now I
am going to write is AC in this funny form. I am going to write it as AB upon AC. Of course if
you simplify this you will get AC. But then why did I write it in this funny form. Well I did that
because I know what the value of AB is for one thing. What is the value of AB? Well it is just
f(xi) so I am going to put f(xi) instead of this AB over here. What is AB upon AC? AB upon AC
is this height upon this and that is simply the slope of this tangent or it is the value of the
derivative at point xi. So that is what I have written down over here. So AB upon AC is f’(xi).

So what have we got? We now have a formula for xi plus 1, given in terms of xi, f(xi) and f’(xi).
So xi+1=xi-f(xi)/f’(xi). So this is the formula which we are going to use to get to a better
approximation. And in this picture you can see that C is likely to be a much much better
approximation. In fact, if the tangent over if the curve over here is almost a straight line. Then
we would get to the root at one shot. But of course it will not be a straight line in general, but you
can see that we are likely to get closer to the root.

Alright, so let us now use this formula xi+1=xi-f(xi)/f’(xi) to find the square root of a number. So
square root of a number y. So that is our formula and we want to find a square root of y.

334
(Refer Slide Time: 6:59)

So for that we said that our function f(x) is x^2-y and we said that its derivative is 2x. So all that
remains is now to substitute these quantities into this expression. So what do we get for f(xi)?
xi^2-y and for f’(x) we get 2x. So we get xi+1=xi-xi^2-y/2xi. And this if you substitute is going
to turn out to this, why? So xi squared upon 2xi is going to give me xi upon 2. So that will take
off half of xi from this so I am going to get an xi but notice that there is a upon 2 over here. And
what about this (term) this side? So here I am going to get a y, but there is an upon 2xi over here.
But this y on the this minus sign and this minus sign will cancel each other out. So I am going to
get y upon xi with that 2. So xi+1 is just going to be (xi+y/xi)/2. So our basic iteration is quite
simple. So starting with x0 we are going to use this to compute x1, then compute x2 and so on.
And it turns out that if we keep on doing this we can get as close to square root of y as required.
The proof is a little bit involved but calculus a little bit of Calculus will help. Certainly first year
calculus of Science and Engineering should be adequate to prove this. But anyway it is not a part
of the programming course, the proof is not the part of programming course.

335
(Refer Slide Time: 8:54)

So the code is very simple so we are going to have y in which we are going to read the value
whose square root we want to calculate. Then our xi is going to be kept in a variable xi which we
are going to start off with 1. This is a guess and as I said for this square root almost anything
works and we are going to stick with x because this does work. And then first I am going to
repeat 10 times. xi equal to our basic iteration. So this is the old value of xi that we are going to
use. We are going to calculate the new value of xi. And Right away we are going to put it into xi.
So we are just going to do this 10 times. And at the end we are going to print out the result. So
this is this is fairly straight forward.

336
(Refer Slide Time: 10:03)

Now we have said that we are going to do to this 10 times. So if we are going to do this 10 times,
we do not really know how much the error is going to be. Ideally we would like to say that look
do this until the error is small. Let us see if you can get not exactly that condition but some
similar conditions.

So here what I have done is I have plotted my function f(x). So this curved line is my function
f(x). What is that function? xi squared minus y, that is my function. This curved line. Now my
current xi is this. The actual xi that I want the actual root that I want is this. So I want this
distance because that is my error. Or I want an estimate of this distance. I can never get the exact
error because if I got the exact error I would just add it to my current estimate and then I will get
the exact answer. So that is that is not we are not going to be so lucky.

So, but if we get an upper bound on the error that is also fine. But here even determining an
upper bound on distance is a little tricky at least not immediately obvious. Instead of that what
we can see is that this distance is relatively easy to calculate, well almost. So how much is this
distance? So, so this function is xi squared minus y. So it is the distance between the square of
my current guess and the root. So it is sort of an error it is sort of the vertical distance from this
point to this curve. What I really want is the horizontal distance from this point to this curve.
Whereas, this value is the vertical distance from this point to this curve.

337
So I can do that, I can use that if the slope is not too bad and in the case of the square root it is ok
I guess. So if the slope is not too bad. Then I can in fact get a good estimate from this.

(Refer Slide Time: 12:06)

So here is how my function might change. So my program will again ask for y, it will again set
xi to 1. But now instead of running for 10 iterations it is going to say, okay have I come close to
this curve, has my xi come close to this curve along the y axis, in the y direction. I really want in
the X direction, but have I come close in the Y direction and if it is if I am not come close and
whatever error we want we can put over here then we are going to iterate again and again. Until
this condition becomes false. At the end of it we know that our vertical error has become smaller
than this. And even though we want the horizontal error to become small that is ok, at least we
are making some effort. But not but you have to remember that this is not the actual error this is
the some kind of a very heuristic estimate of what the actual error might be. So in any case at the
end of it we are going to put out our current our current xi as our answer.

338
(Refer Slide Time: 13:16)

Now, the error analysis can be done and in fact it turns out that the number of correct bits
essentially doubles with each iteration that is a remarkable result. It is not its proof is not easy.
But with a little bit of effort and you should be able to understand it, it is given in several places.
But let me just tell you what that result is saying. So it is saying that suppose you start off with 1
bit correct, then if you run it once you will get 2 bits if you run it twice you will get 4 bits, if you
run it three times we will get 8 bits, if you run it 4 times you will get 16 bits, if you run it 5 times
you will get 32 bits, if you run it 6 times you will get 64 bits correct. So basically it says that you
have to run this just about six times only 6 iterations have to happen. So that is that is really fast
convergence to the correct answer. It is not exactly doubling, so it maybe it will take 7 or 8, but
not much more than that.

339
(Refer Slide Time: 14:34)

So let me make some remarks on this, some interesting points. So one interesting point is that
Babylonians used this method to find square root 3500 years ago! They did not, they did not
know this whole tangency, and they do not that does not seem that they knew that they could be,
this could be used to find the roots of any function for which we can evaluate f and f’. So for that
for that realization we have to wait for Newton and Raphson. But 3500 years ago getting square
roots as accurately as you want is an amazing achievement. Now, I should mention that Newton's
method is very commonly used in many many places. And it is also useful in multiple
dimensions. So, what is the multiple dimensions problem? We are given several functions of
several variables. So we want to find values to x, y, z, w. One set of values to x, y, z, w such that
this equation is satisfied, this equation is satisfied, this equation is satisfied. So x, y, z, w the set
the set of numbers defines a point in high dimensional space. And what we want is a single point
in this high dimensional space at which all of these functions f, g, h get take the value 0.

So essentially we want to find a point in high dimensional space which is the simultaneous route
of all these functions f, g, h. So you can use Newton's method to solve such problems however,
solving such problems is very tricky. So you have to use Newton's method very carefully and
sometimes it just does not work. But anyway Newton's method is a great method, very very
useful and it is also remarkable that one part of it or aspect of it was known to Babylonians 3500
years ago.

340
(Refer Slide Time: 17:11)

So that concludes this lecture sequence, let me just make some final remarks. So in general what
we talked about here or sort of the major problem that we talked about here is to evaluate f(x),
where f(x) is some interesting mathematical function, but which is not easy to calculate directly.
So if you want to do that then you can use Taylor series. If f and its derivatives can be evaluated
at some point x0 of your choosing. And that point should be close to x or x should be in that
radius of convergence of that point x0 for that function f.

Then we also said that we can express f as an integral of some easily evaluable function, not
easily integrable, easily evaluable function. Then we can numerically integrate this function g,
and we can calculate f. We can also calculate f we can express it as the root of some easily
evaluable function g, and then we can use the bisection method or Newton Raphson method.

We also said and it is worth definitely keeping an important thing in mind that all these methods
are iterative. So the accuracy of the answer improves with each iteration. So we do not get the
exact answer, but we can get answers which are as close to the actual answer as we want and
since we are representing numbers only to a small number of bits or say a large number of bits
whatever it is still we do not really care for answers which are more precise than what is possible
in that many bits. And therefore, these methods are actually quite good enough for using on a
computer. We do not really have to worry about deriving some kind of exact methods because
there is no such exact thing on a computer anyway, at least if we use the standard data types.

341
Now, we also said that ideas of ideas if these chapters are very fundamental. And in fact, if you
do numerical calculation you will see them again and again and even in the book they appear in
two places chapter 19 and chapter 29. And I would also like to say that the ideas might be
mathematically involved, the programs are actually quite simple. Once you understand what is to
be done, the programs are quite simple. And they essentially have one loop which could be a for,
which you could use as a for loop or you could use, even the repeat loop sometimes. But
certainly a while loop or a for loop and I suggest you get practice in writing all these things using
for loops and while loops.

And that was also one of the motivations we have had in doing all this to get practice and learn
programming and get practice in writing loops, writing simple loops with a small number of
variables. So that concludes this lecture sequence. Thank you.

342
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 09 Part - 1
Loops in Various Applications
(Refer Slide Time: 00:32)

Hello and welcome to the NPTEL course on an introduction to programing through C++. I
am Abhiram Ranade, the topic for this lecture sequence is Loops in Various Applications. So
we are going to study three themes today, one theme is brute force search. So often we find
that we may not have any clear clever algorithm to solve a certain problem. However, we can
identify potential solutions and we can just examine all of them. On a computer this can
happen very fast even if the number of possible candidate solution is large, but finitely many.
So this turn out to be an interesting way of solving problems. So we are going to see two
examples of this.

Then we are going to talk about modeling a system. So, in this we will have some kind of a
system which will respond to stimulation from the outside world. The first system we
consider will be rather simple it will respond to the outside world. But it will not really have
any state. So between responses it does not have to remember much.

The second system we talk about will be affected by what the world does to it and its
responses will therefore, depend upon what has happened earlier. So modeling such systems
is a very important use of computers and we will see that, just by using a single loop you can
sort of do a lot. You can model systems very very nicely.

343
And then we will consider a problem relating to computer arithmetic. So, we will talk about
arithmetic on integers which have many many digits. So as you know such integers cannot be
easily processed. So we will see what kinds of things need to happen for us to be able to
process such large integers.

(Refer slide Time: 02:43)

So, let me begin with this idea of brute force search. So to tell you that, I need to tell you
about constraint satisfaction problems on finite domains. So, a constraint satisfaction problem
looks like this, it asks find x, y, z such that they satisfy some set of constraints. You can have
a constraint satisfaction together with optimization. So, this problem looks like find x, y, z
such that they satisfy these constraints and in addition something should be as small as
possible, or may be as large as possible.

344
So, here are a few examples, so we have seen the GCD problem earlier. So, the problem is
given two integers A and B, we to find their greatest common divisor. Now, we can think of
this as a constraint satisfaction problem. How? Well, x is what we want to find and the
constraints that x has to satisfy are that x must divide A and B both. So it must be a common
divisor, it must divide A and B both without leaving a remainder. And there is also an
optimization angle. We want x to be as large as possible, satisfying these constraints.

So earlier we have seen algorithms for solving this problem. Now, those algorithms in
particular Euclid’s algorithm was a very cleaver algorithm. What is we are going to do today
is, solve this using a very simple algorithm. But it will take a long time, but that is okay.
Suppose, we are not cleaver enough and suppose, or suppose in some problem we are not
able to have any cleaver algorithms. Then the approach that we are going to talk about today,
will still the useful.

So, that is the point of discussing GCD so we want to, we have formulated GCD as a
constraint satisfaction and optimization problem, and then we can use the idea of brute force
search as we will see soon.

The second problem is that of discovering or that of listing out Pythagorean triples. So
specifically we want to find x, y, z integers such that, x^2+y^2=z^2, and we want these
numbers to be distinct. And we have put down a condition, additional condition that these
numbers should be smaller than 20. Why are these called Pythagorean triples? Well, you
know the theorem of Pythagoras. So it says that, if you have a right angle triangle then, the
sum of the squares of the two sides. So, let us say x and y are side lengths and the squares are
x^2 and y^2. Then, the some of the squares is equal to the square of the hypotenuse. So
z^2=x^2+y^2. You know that you can have a Pythagoras and a right angle triangle, of side
length 5, 4 and 3. Because 5 squared is equal to 4 squared plus 3 square. And because of the
theorem of Pythagoras, these numbers 5, 4, 3 constitute what is called a Pythagorean triplet.

So, people have curious about such numbers and what we are doing over here, is we are
going to look for them. We will not to anything clever, but still will be able to find such
numbers reasonably easily. So here is, the simple way of GCD of finding GCD that, I was
talking about so, so let we make the first observation which is that the GCD itself, the
greatest common divisor of ant two numbers must be at least 1. And the common divisor
cannot be larger than the smaller of the two numbers than the minimum of the two numbers.
So, what is its mean? So this means that x can potentially only be one of these numbers. 1, 2

345
all the way till minimum of A and B, it cannot be a number beyond this, it cannot be number
smaller than this.

So, here is the strategy, so we are going to tryout each integer between 1 and then A, B and
we are going to check, does that integer perfectly divide both A and B, if it does, of those
integers we will pick the one that is the largest. Simple enough? Notice that strategy is much
much simpler when Euclid’s algorithm for which you need at a fair amount of cleverness.
This on the other hand is very simple, it will take more time, than Euclid’s algorithm. It will
require more arithmetic operations. But maybe you do not care, or maybe you did not, you
are not clever enough to discover a good algorithm for finding GCD. Of course there is the
high school algorithm as well. So, there are several choices and this is just one way of doing
things and as I said, I am showing you this, so that you get a feel for this notion of constraint
satisfaction and searching through all, through a set of possible candidates.

Now, here is a way to find Pythagorean triples again it is a very similar way so, we can
observe that x, y, z all the three numbers must be at least 1 and at most 20. Well, we said that
z must be smaller than or equal to 20. So clearly these numbers must be at most 20. And why
should may be at most 1? Well, if they are 0, and we want they have to be integers okay. If
they are 0, then what happens? Then we will get a trivial solution. That y square equal to z
square okay, so we do not want such trivial solutions. We want these numbers to be nonzero
and therefore, they are expected to be distinct as well, it follows that they have to be distinct.

Well, if the numbers lie between 1 and 20, or another way of saying that is that the domain of
each has to be the set mentioned over here, the numbers 1 through 20. So if this is the domain
for each number each x, y and z then what can we say about all possible triples? Well there
are just 20 times, 20 times, 20 - 8000 triples and we know that, so we need to know which
one of these triples satisfy the Pythagorean property.

So, the algorithm naturally is, that we are going to try out, we are going to generate and
tryout all possible triples. And for each triple we are going to check does it satisfy this
equation? If it does, we will print it out. So, again we are being very clever over here, we are
just doing something really brute force, we are trying out everything. But computers are fast
and so therefore, sometimes it is okay, if we want to tryout everything, computers may do it
fast enough.

(Refer Slide Time: 11:06)

346
So let us see more detail, how we solve this GCD problem. So the problem again is, find x
such that x divides A and B and is as large as possible. So the idea we mention was tryout all
possible values of x between 1 and minimum of A and B and pick the largest which divides
both. Now, we have to examine the values between 1 and minimum of A and B, but we
could, we have a choice of examining these numbers in whatever order we want. So, let us
consider the natural order first so, we first try out x equal to 1, see if divides? Of course it
divides x equal to 2, see if it divides, x equal to 3 and so on. And then we list out all such, all
whether or not, any of this numbers divides A and B perfectly. So we consider x in this order
1 through minimum of A and B and we remember which number, which x is dividing both?
And now from those we pick out the largest. So, that is one way of doing things.

So this will work, but here is another order so in this we are going to start with the minimum
of A and B, we are going to consider the largest possible candidate. We check if that divides
both A and B. What if it divides A and B? Do we need to check the next smaller candidate?
Well we do not because the next smaller candidate will be smaller and we want the largest
solution. So this is just going to be a better way of doing things. So as we go down this list,
once we find an x that divides both A and B, we can stop. So indeed we should consider these
numbers in this order.

So any common factor that we discover later can only be smaller than common factors which
we have discovered earlier. So therefore, we go in this order and stop as soon as we find an x
which is a common factor of both A and B.

(Refer Slide Time: 13:40)

347
So, now the program is immediate, so here is the program fragment. We will use variables A
and B and into it we will read the numbers whose GCD we want to find. Then we are going
to start with x equals minimum of A and B and we are going to keep on decrementing it, so
long as it is bigger than 0. And what do we need in it iteration? Well, we check whether A is
divisible by x perfectly, and B is divisible by x perfectly. If it is, then we are going to print it
out. But, we can also stop the loop right here, so we are going to break. That is it, so that is a
program.

(Refer Slide Time: 14:29)

So, some remarks, this turns out to be much slower than Euclid’s algorithm. I mentioned that
earlier and in general brute force algorithms are slower that clever algorithm. That should not
be a surprise, but the point is that you should consider brute force if you cannot think of

348
anything else. You should not give up because computers are fast enough, and if and if you
have to examine a large number of candidates. You may be surprised how quickly computers
can go through all such choices.

What are the requirements? Well, the candidates that you want to search over the possible
values that you want search over must be finitely many, they could be a large number but
they have to be finitely many. And we should be able to generate each possible value, in this
case the generation was very easy. We just have to count okay, count down or count up it
does not any matter. And given a candidate we should be able to check the constraints.

Now, if we generate the candidates or if we generate the values largest to smallest then the
first solution we find, will be the largest possible. If we generate values smallest to largest if
the candidates we generate are in the order smallest to largest then the first solution we find
will be the smallest possible. So, depending upon whether you want the smallest possible
solution or the largest possible solution, you should pick one of these orders.

We are going to take a break now, but when we come back, we will have a more involved
example, the Pythagorean triples which we will again solve using brute force search. Thank
you.

349
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 09 Part - 2
Loops in various applications
Finding Pythagorean Triples
(Refer Slide Time: 00:31)

Welcome back, in the previous segment we looked at how to solve GCD using brute force
search. We said that this is slower than Euclid’s algorithm, but we said that brute force search
will be useful if we do not have clever algorithms for some problem provided the number of
possible candidate solutions that we need to consider are finite in number.

(Refer Slide Time: 00:51)

350
Now, we are going to take another example of this, and this example is finding Pythagorean
triples. So the problem as we discussed is find x, y, z such that x^2+y^2=z^2. And z is
smaller than 20, and of course x, y, z are positive integers. The idea we mention was that let
us try out all possible triples x, y, z where, x, y, z lie between 1 and 20. So, how do you
generate such triples, that is the natural question. And that actually very easily done.

So we are going to have a loop which is going to have control variable or index variable x
which will go between 1 and 20. Nested inside that will have a loop with control variable y,
which will go between 1 and 20 as well. And then we will have a loop with control variable z
again ranging between 1 and 20.

So now, whatever we put over here, we can use the variables xyz and in different iterations,
they will assume all the possible 8000 triples of the form xyz where, xyz are integers between
1 and 20. So, if you want to check for all possible triples, the check has to be put over here,
and that is the check. We want to know whether x^2+y^2=z^2. And if it is we want printout
that triples. So, that is it, that is the program.

(Refer Slide Time: 02:46)

So, let me show you a demo of it, have called it naivePythagoras dot CPP and you will see
the reason for it.

351
(Refer Slide Time: 03:26)

So, this is our program exactly what we have written earlier, so let me compile and run it. So,
it has printed, all the triples, let me move it out a little, okay, it has printed all the triples, 3, 4,
5 4, 3, 5 5, 12, 13 okay these are all the triples that it found, satisfied the property, that the
sum of first number squared plus the second number squared equals the third number square,
you can check it out. So, first of course we have the familiar triples, 3 squared plus 4 squared
equal to 5 square.

352
Now, is this a satisfactory list? Well it is not, why? Because, this triple and this triple, we
would like to think of as the same triple. Right, I mean if we want to send this to somebody,
they will say look why are sending me this twice? I know, these numbers the order is not
really important in these numbers. So, and of course is that has happened in many places. So,
8, 15, 17 is there, 15, 8, 17 is there. So the question is, can we avoid this? And yes, we can
and we are going to do that in just a minute.

(Refer Slide Time: 05:05)

So we are going to look at this problem again, and make a modification which will allow us
to generate similar triples only once. So this is our problem again, and this was our idea, and
this was our problem. So, we want 3, 4, 5 to be printed, and not 4, 3, 5 or may be the other
way around. But we could not say that look, why do not we print this in ascending order,
rather than this looks a little funny.

So, we only want one of these things to be printed, so how can be enforce that? Well here is
the idea. So, in addition to the constraints which are already there, in the problem, we will
additionally assert that x should be less than y. What does this do? So, this will allow, this
solution because this is x and this is y, and x is instead less than y, but this solution will be
avoided. Because this is not less than this. So that is the idea, so we are going to have the
previous program, but in the previous program we are somehow going to enforce the
condition that x is less than y there are various ways of enforcing this condition, but we are
going to pick a particularly nice one.

And by the way note that, x equal to y does not have to be consider, why? Because, if we
look at x^2+y^2, then that if they are equal, would be root 2 times x squared and that cannot

353
be a perfect square. So it cannot equal any z square. So, x equal to y does not have to be
considered, we do not want x greater than y, and therefore, we only be asserting x less than y.

And in fact, you can see that the conditions really could be something like, this. Because we
know we are asserting that y is bigger than x, and of course z has to be bigger than y. because
its square is strictly more than the square of y and x. So, let us see how we can assert these
conditions somewhat indirectly.

(Refer Slide Time: 07:17)

So, let us look at the code, so here is the code. So, the first loop is exactly as before, x goes
from 1 to 20. The next loop however, has y skipping all the values including whatever the
value x is currently taking and smaller values. So, y only starts at x plus 1, and it goes on till
20, and z similarly, skips all the even, all the smaller values. Because we know that, has to be
bigger than y. And so, it starts off at y plus 1, and goes on till 20. And the condition is still the
same. If x squared plus y squared equal to z square, then we print it out. So, let see this.

354
(Refer Slide Time: 08:05)

So, let us compile it, and run it, so that is it, it has indeed done the right thing, it has printed
every triple just once, and so, 3, 4, 5 is printed as 3, 4, 5 but not as 4, 3, 5, which was
happening earlier.

355
(Refer Slide Time: 08:47)

So, let us get back to our presentation. So, I want to give you some exercises. So, the first
exercise is dealing with something called, perfect numbers. A number is said to be perfect if
the sum of all its divisors smaller than itself. So 6 for example, has divisors 1, 2, 3 smaller
than itself, and 6 is indeed the sum of those divisors. So therefore, 6 is said to be perfect.

The problem that i am asking you, to write a program for is, to find or print all the perfect
numbers between say 1 and 10000. So, you have to go through all the numbers between 1 and
10000, and check if they are perfect, and if you find that a particular number is perfect, just
print it.

(Refer Slide Time: 09:39)

356
A harder exercise relates to something that, the famous mathematician Ramanujan is
supposed have said. So he said, sometime that 1729 is the smallest number that can be
expressed as sum of cubes of two integers in 2 ways. In particular, 1 cube plus 12 cube is
1729. Because 1 cube is 1, 12 cube is 1728, 9 cube is 729 and 10 cube is 1000 and therefore,
9 cube plus 10 cube is also 1729. So this is an interesting fact and you may wonder suppose, I
did not know this, could I have figured it out?

So, that is where, what our problem is going to be about. So, I am going to assume that
suppose, you did not know this, and you were told however, that such a number exists and is
smaller than 2000. Can you find it? And in fact, you could ask look I want the smallest such
number, so that is the problem. So, write a program which finds the smallest number, and you
know and assume, you are assuming that it is smaller than 2000. So, the smallest number
which can be expressed as sum of cubes of two integers in 2 different ways.

So, you are expected to do brute force search. So we will have to figure out exactly how to
organize that brute force search. So we have expressed as a constraint satisfaction problem.
So, think about it, it will as I said, it is a slightly harder exercise. So the number that you want
to find is certainly one of the variables that you want. But what about those numbers 1 cube,
12 cube, 9 cube, 10 cube. So, how do we exactly get them into our constraints? So that is
what you make to figure out.

(Refer Slide Time: 11:59)

357
I want to list out an even harder exercise but which may challenge some of you and which
some of you may like, and this is the so called, 8 queens problem. So, this problem asks you
to place 8 queens on a chessboard such that, no queen captures another. So, for those of you,
who do not know chess, here is a quick explanation. A chessboard has 64 squares arranged in
8 row and 8 columns.

So, it looks like this, so there are going to be 8 rows and 8 columns, whatever this is not 8 but
there should be 8 rows and 8 columns. So, how many is this, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6.
So, if you had 7 and 8, and 7 and 8, then it would be a chessboard. Now, that is what a
chessboard is and this says if 2 queens are in the same row or in the same column then, they
will capture each other. So, if we have queen over here and a queen over here, then they will
capture each other. So, if you place a queen over here, then you should not be placing the
queen over here. That is what the constraint tells you. And similarly if you place a queen over
here, you cannot be placing queen in any square in the same row. So, you cannot place the
queen over here. Because, they would capture each other, and you want place queens, such
that they do not capture each other, but this is not only way queens capture each other. So
queens capture each other, even if they are sort of on the same diagonal or since the notion of
diagonal only refers to the principle diagonal which is from corner to corner, we can say the
same thing in different manner. So, suppose there are 2 queens, so these 2 queens, and if we
draw the line joining them, then this line is at 45 degrees angle with respect to the rows and
the columns. So, even then they can capture each other so, this is also not allowed. So for
example, you could have a placed, if you want to place 3 queens, you could place one over
here, another one over here, the third one over here maybe.

358
So now, no queen is capturing each other, may be even a fourth one over here. So, in this
manner you could have place the queens. And turns out that in this case, you can place the 6
queen over here. So, you have place 6 queens on a 6 by 6 chessboard, but you want to do this
on in 8 by 8 chessboard.

Well, that is the original problem, but we do not want get carried away with having too many
variables and writing too much code, and in particular the spirit of the problem is still the
same even if you are looking at the 4 by 4 board. So, if you want place 4 queens on a 4 by 4
board, how will you do it? You want to write a program which will do it for you. So basically
the idea is that you try out all possible placements of the queens on the board. So, you will
have to figure out, how do you represent this problem using numbers, and suppose you say
that this queen is placed on the square, and other queen is placed on this square. What does it
mean for the queens to not capture each other or capture each other?

So the constraints here are expressed in terms of this geometry, but you have to get them into
arithmetic. So you want that constraints to be in terms of numbers. So that is what makes this
exercise harder. But once you do that again after that you are not expected to be clever. After
that you are just supposed to try out all possible ways of placing the queens.

(Refer Slide Time: 16:30)

Alright, so, what did we discussed in this segment? Well, these 2 segments actually. So, what
we discussed was that, for many problems we may not know any clever ways of solving
them. But, if there are only a finite number of candidate solutions, then we can go through
them systematically. We can check which candidate solutions satisfies all constraints, and we
report that as the real solution.

359
This can take very long, but it is better than not having an algorithm. But, of course there is
room for cleverness. We may have to do things like, let that enforce additional constraints,
say x is less than y or something like that. And notice by the way that that actually also
reduces the amount of searching we have to do. So, some any kind of cleverness that we may,
that we are capable of in reducing the number of possibilities always helps, it allows you to
solve bigger problems in the same amount of time.

So, that finishes this topic of brute force search, and now I am going to take a break, and after
the break, we will discuss how to write programs that model a physical system.

360
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 09 Part - 3
Loops in various applications
Modelling a system: bargaining
(Refer Slide Time: 00:39)

Welcome back, in the last segment we discussed brute force search for solving problems, for
which we do not know anything cleverer. In this segment we are going to see, how to write
programs to model the working of a system. We are going to start off with a simple and
problem that you might perhaps consider to be a fun problem. Modeling of the bargaining
that goes on when we go to a market.

So, pretend that you are a seller who wants to sell a certain object. Now, you will be happy to
accept to sell the object for say 500 rupees. So, you will accept 500 as a price and of course,
if somebody says on I am offering 600, you will certainly accept it, but you do not, you are
not going to accept a smaller price than 500. That is sort of your, that is the minimum price
that you want.

And you could say 500, and you could put a tag saying it is 500. But sometimes, in some
places the customers want to bargain, so if you just say 500, then the buyers will tell you, oh
please reduce, please reduce. And they will not accept it. And if you at accepted may be, you
could reduce and you could come down to 500 or something like that. That might be
acceptable, so it is just a psychological game, I am sure which you must have seen happening
in markets.

361
So, how do you deal with this as a seller? Well, so here is the strategy that we are going to
employ in this program. So you are not going to tell your price at all. So you are going to say
to the buyer, look why do not you tell me, how much you are willing to pay? So if the buyer
offers a price bigger than 500, then you are done, you can just take it, you are happy, the
buyer are happy, and the whole thing ends over here.

But if, the buyer offers a price smaller than 500, some price p, then what should you say?
Well you are going to make, let us say that your strategy is to make a counter offer q, such
that the average of p and q is 500. So, once you do that the buyer can accept it, or may be
make another offer. And this can go on.

So here are some examples. So suppose, the buyer say look I am willing to pay 400 rupees
for it. What are you going to do? Well you will say 600, why is that? Because the average of
600 and 400 is 500. Why the strange thing, why do not you say 500 right away, again you
want to keep yourself some leeway in case you need to reduce further. So, this is how you are
going to work.

After this may be the buyer says 450, so in this case you will say 550, why? Because again
you are sticking to your rule, the average of 550 and 450 is 500. So you must have seen
something like this happen, it is not always exactly like this, but let us just say for fun that in
fact, well there could be a seller, who uses this strategy. So what you are going to do is? We
are going to show, or we are going to write a program to show what is going to happen. If
there is a seller like this, and a buyer comes to that seller. And of course this cannot go on at
infinitum. So, may be if this happens 5 times then the whole thing has to stop, anyway. So,
may be it means that you did not come to an agreement and then, the buyer just walks away.
So, this is what you want to your program to enact or simulate.

362
(Refer Slide Time: 05:02)

So, let us design that program, so clearly there can be at most 5 iterations. And you can see
that the iterations are independent there is nothing from the first iteration that is necessary in
this second iteration. Now, we have to figure out one thing however, that if the buyer a
demands a price p, or rather the buyer offers to pay a price p, then what price q should you
make as a counter offer?

Well, we said that p and q should be such that their average is 500. So, what does that mean?
So the average of p and q is (p+q)/2, and this must be 500. So, let us simplify that so let us
take 2 to the other side and p to the other side, so what do we get? So, we get q must be equal
to 1000 minus p. So, this in fact tells you precisely, what your counter offer should be.

So, you could think of this as solving an algebraic equation, so you know the value of p and
you are trying to figure out the value of q. So that is exactly what this is, and all I am just
alerting you to the possibility that when you write a program, you may need to solve
equations, and this is just an example. So do not worry about it, equations can be solved we
have shown you, how to do it.

So, q is this price you should name, and that is about it, and of course if the price was the p
itself was already above 500, then you should stop. So, how does this is work? So we are
going to have a loop which runs 5 times at most, so you are going to tell the user, tell the
buyer to make an offer. So, may be the buyer is going to make an offer, if the buyer going to
type something and that is going to into p, if p is bigger than or equal to 500, then you are
going to accept the offer, so you are going to printout accepted, and you will break.

363
So, the loop ends, otherwise you have to make a counter offer and how much offer, how
much value should that counter offer be for? Well we just calculated that, so we are going to
make an offer q equals 1000 minus p. So, you could say I am going to sell it for q, and that is
the end of iteration. So, at this point the user, the buyer may make another offer, may be the
buyer, so in this precool the buyer is not really allowed to say accepted. The buyer has to
come back and make the same offer at which the seller says accepted, but anyway so, if you
make an counter offer the buyer can accept at that price by repeating that offer. Alright, so
that is the program.

(Refer Slide Time: 08:25)

364
So, let us see that, so this program I have coded as bargain.cpp and let see it, so this is the
program so, let us compile it, and run it. So, it says make an offer, so what am I going to say?
Maybe I will say 700, so already accepted. Because, why? Because we said that, the program
accepts if you quote a high price or price 500 or more. So, let us try something different.

So this time let us be really annoying, let us say 50. If you are in the real market, and if you
see something which is over 500, you know that this is a really low offer, but sometimes you
do that, you are fooling around. So, at that time the seller also plays here, game and here, he
says no no not 50, 950, what are you talking about? So, now you have to make another offer
which is presumably more reasonable, so you might say 200, or sorry 20 I said, so of course
sells a 980, but I mean 200. So, at that point a seller will say 800, so if you are reasonable
then, the seller will also try to be a little bit more reasonable. May be at this point you say,
400. Then seller is even more reasonable. So, if you say 600 at this point seller will accept, if

365
you had said something else, then as you know the loop would have go on, would have
continued, and it would have stop after 5 iterations. Because, you cannot go on arguing at
infinite term. Alright, so let us get back to the presentation.

(Refer Slide Time: 10:49)

So, what have we discussed? So we discussed, a fun problem, it is a very simple example of a
real life problem, it has this notion that, there is some system which is conversing with the
user. So, the program is conversing with the user, just as the real life system is interacting
with the user. But it is a really simple system, so that is okay, it is a little bit of fun. Next we
are going to look at, a slightly more interesting real life problem. So, we will take quick
break.

366
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 09: Part - 4
Loops in various applications
Simulating a water tank
(Refer Slide Time: 00:24)

Welcome back in the previous segment we discussed a very simple real life problem, and we
wrote a program for it, this was the bargaining problem. Now we are going consider a slightly
more complicated problem which is also resembling a real life problem.

(Refer Slide Time: 0:41)

So, this is about simulating a water tank, so we have a water tank which has capacity some c,
c liters and initially it is empty, and you can perform one of 3 operations with respect to this

367
tank. So, you can add water to it, and let us say this operation will be performed and as far as
the computer is concerned to add water into the tank, you will type plus followed by the
amount you want to add in litres.

Now, if you add water to a tank it may overflow, so you may be adding too much water. So,
in which case, water will be wasted, so you are expected to report, your program is expected
to report, how much water is wasted, or you may attempt to take q litres out of the tank. So,
somebody say walks to the tank, and says give me 15 litres, now if the tank has 15 litres then
you will give 15 litres, but if the tank does not have 15 litres, you will give whatever is there,
but you will say how much you actually have given.

And these commands will keep on coming at you, and have to respond to them properly, and
note that means that you need to know, at each step how much water is there in the tank. So,
this is an example of a system in which there is some state, the state is how much water is
present, and what the external world is doing to the tank? Well it is sending some commands,
as were result of which the system reacts and it produces some output and in additional its
state also changes. So, it may give you some water, it may take some water from you, and at
the same time its state will change, and it will printout some massages. So, these are the
things that we want our program to do.

So, this kind of thing happens quite frequently you may, you are trying to keep track of a real
life system, and you are trying to see, how it responds as external communication happens to
it? So instead of a water tank for example, this might be a bank account, and you may be
withdrawing money from it, you may be depositing money from it, it is all here, very similar.
And of course, there is an additional command possible x so, if you type x that is a signal to
the program that look, stop. Close everything, just exit the program.

368
(Refer Slide Time: 03:42)

Alright, so now what we are going to do is? We are going to write the code for this, and this
time I am going to write it along with you. So, let us see, this going to bit of a long code, but I
will write it with you.

(Refer Slide Time: 03:53)

369
So, let me try it out, so let me open a new file, say newtank.cpp. So let me put down
#include<simplecpp>, (ohh what am I doing, so 1 m) then let start the main program. So,
how we go about this, what do we need to, what variables do we need to have? Well, we need
to clearly keep track of how much water is there, in our tank. So, we need to know what is the
current content. So we will need the variable that, and we also would like to have, we also
would like to know, what is the capacity, so we will have variables for both of these.

So, let us just for fun, make the capacity be 30 litres and then, let us have a variable say
called current, and let say initially it is empty, so this variables current tell you how much
water is there in the tank at the current time. Alright, now, so these are the sort of main
variables we need, this is not a variable capacity is not a variable, but instead of putting in 30
everywhere in our program, it is better to give it a name. So, could have even made this a
constant, but never mind, it is so important right now.

So, what happens next? So now, we are going to simulate the execution of the system. So this
has to be done as a while loop, we just keeps running, so while, and since it keeps running we
are not yet ready to decide whether it to terminate it, we will give the condition as being true.
So, what is the first thing we do in each iteration? Well, in each iteration we have to ask the
user to type something so, we have to expect the command from the user. So, that command
is going to be a single letter command followed by possibly a number, so we want to have
some variable in which to receive that command. And so, it is customary to have say char
command, and then we will do cin into command.

So, at this point we have got the first letter that the user has typed into our variable called
command. So, if that letter is x then we have to exit. So let us just put that down, so if

370
command==x and let us say it is just lower case x, then we will break, so break and that will
the end of the program as well, there will be nothing following this loop.

Otherwise, we should check whether the user wants to add water, or the user wants to take
out water. So if command is equal to say plus, then what should you do, just we want to put
over here, so if the user typed a plus, then we know that the user is going to add water, and so
we should expect the user to type in a number. So, for that we will have int some quantity and
we will say cin into quantity. Now here, I am assuming that quantity is going to be an integer,
sorry lets make it double, we said this is supposed to be double, so our capacity is double, so
might as we will make this double. But we want this quantity to be a positive number, so if
somebody types add, I want add negative minus 30, so this is probably something wrong, so
we should probably be checking. But lets say that such mistakes are not made, and after a
plus the user will be sensible enough to type in a positive number. So then this is fine.

So, what should we do at this point? So the user wants to add qty into current, so there is the
possibility of an overflow, and we are expected to report, how much overflow is there. So,
here is what I am going to do, I am just going to first add it to current, so I am going to say,
current=current+qty. Now I will check, if current equals, sorry if current is, greater than
capacity then what should I do? Now I have to printout, how much water is wasted, so how
much is wasted? So, the amount of wastage is, so how much is wasted? Well, everything
above the capacity is wasted. So, this quantity the wasted quantity is current minus capacity.
Is that all? Well no, our current is above capacity and we just removed something out of it, so
we should leave it at the actual current value, so when we port it went above capacity, but we
know that it cannot go above capacity, so whatever goes above capacity is wasted. So, we
should leave current equals capacity. If current is less than or equal to capacity, we have to do
nothing. And therefore, that is enough.

So, this is the processing we need to do, if our command was a plus, else if command is
minus, what do we need to do? Well, again we need to do something similar, we are
expecting the user have to type in a number, a quantity. So, let us do that, so double qty and
cin into qty. So the user typed in something, and may be the user has demanded something
more than what we have available. So I guess at this point, we should check. So, we should
say if qty is bigger than current, then what happens? So, if the quantity demanded is bigger
than the current quantity, then how much are we going to give? So, we are going to give,
giving qty. And we should change the current values, so how much value remains? Well, we

371
are giving, sorry we are not giving qty, we are giving current because qty was bigger, so how
much remains? So then current is equal to 0.

(Refer Slide Time: 13:47)

So this is what happen if qty is bigger than current, what if it is less than or equal to current?
In which case, how much are you going to give? I should have not typed semicolon over
here, but a colon, how much are we giving? Well, in this case, we are giving whatever is
demanded. And what is the new value? So this is equal to current minus what we give. So,
that is it. So, that is the end of this minus command processing.

Now here, may be the user types in some other character, so maybe we really should put an
else, cout<<”invalid command”; And that is the end of the loop. So, this is going to get
repeated and this if you exit out of it, that is going to end the program.

372
(Refer Slide Time: 15:30)

So, to make this little bit more understandable, let us say that, before if the user types
anything, we will printout, how much water is there currently? So we can print say cout,
currently we have, so much water, so let us see, how this works?

(Refer Slide Time: 16:19)

373
So, let me try compiling it, it seems to have compiled, no errors may be I did not make any
errors while typing it out. So it is telling me currently we have 0, so let us say, let me add
something. So let me add may be 50, so it says you wasted 20, currently you have 30. Is that
right? Well, it is because the capacity of that tank is 30. So may be let us take away
something, so let say minus 15, so it is giving 15 and what remains is 15. So let us try minus
20, so you asked for 20, but it is only giving you 15, is that reasonable? Well yes, it only has
15. And after giving you 15, it only has 0. Which is good, which is as you might expect. So,
let us try to take a little bit more, so may be minus 10. So it is not giving you anything,
because it does not have anything. And it continuous to have nothing. So maybe we will add
say, plus 35. Let us say let us add plus 25, so it says currently we have 25, but notice that it
did not printout a massage saying, something was wasted, because nothing was wasted.

374
So, this seems like, a reasonable, a correct program, so we can get out of it. Let see we will
be get out of it, yes, so that is it, so that is this program, so let me get back to the presentation
now.

(Refer Slide Time: 18:28)

So, we did this, so, what did we discussed in this segment? So we discussed a simple example
of a real life system, this system does have state. How much water is in the tank, and the
system has well defined operations, add water or remove water, and the operations are
slightly complex because of the possibility of overflow and underflow. So, I want to point out
that this may seem like a trivial system, and in a sense it is, but it is an example of a system
which has a state and which has operations allowed. So you will see systems which are just
more complicated versions of this, and there is a basic loop, when dealing with such a
system, that you wait for the environment to say something, may be make a request, then the
system responds to it, and prints out the massage and it changes its state. Alright, so that is
what we wanted to see in this topic, in the next segment we will talk about different topic that
of arithmetic on very large numbers. So, we will take a break.

375
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 09 Part - 5
Loops in various applications
Arithmetic on very large numbers
(Refer Slide Time: 00:39)

Welcome back, in the last segment we discussed how to model a real life system, system with
some state using a program. In this segment we are going to discuss arithmetic on very large
numbers. Now, standard representation that C++ contains, allows you to have numbers with
only a certain precision and certain range of exponents.

So for example, if you are looking at floats, you will have some 23 bits of Mantissa or
significand and you will have 11 bits of the exponent. And similarly, for integers, there is so
say if you have unsigned int, then you will have 32 bits given for representing the integer. If
you say long you may get 64 bits, but what if you want to represent very high number of
digits? So these digits that C++ provides are usually very adequate. But sometimes you may
want to represent numbers to very high digits, say for example, you might have seen the
value of pi calculated to a 1000 places. How to they do that? So that is sort of the topic, that
we want talk about right now.

Now, it turns out that sort of the central idea in this is to mimic, what you do manually, so
what you do manually? You deal with each digit separately. So when you do the arithmetic
you look at digit 1 at a time. So in your program as well, you typically will do something like
look I am going to have 1000 iterations to process a 1000 digit number, something like that.

376
Now this turns at to be somewhat involved, but what we are going to do in this segment is,
we are going to give you a glimpse. A very brief introduction to how this is possibly done, it
is going to be a very simplified example, but it will give you some idea.

(Refer Slide Time: 02:51)

The specific problem that we are going to consider is the following, so you are asked to read
a 1000-digit number divided by 2 and print the quotient. Now, the moment you talk about
1000 digits, there is very natural question. How do we store a 1000 digit number? Do we
need 1000 variables? Especially, if we say that we want have, we want to separately store
each digit, well seems like there is no getting away from having the 1000 variables. And do
we have to write int digit 1, digit 2, digit 3 and so on 1000 times? Even that sounds just
completely painful.

Well, in general, you will need to do that, not right now, not with the program that I am going
to show you, thank god, you will need to do that. And very soon we are going to see some,
we are going to see a C++ feature, called an array, which will enable you to do this very
easily. But right now, we do not know it, today what we are going to do is, we are going to
not bother storing all the digits, instead we read 1 digit, we do everything that needs to be
done with that digit and then we forget it. This may not always be possible, but it is possible
for the problem that we have on our hands today. It will not work in general. In general, you
will need to remember all the 1000 digits, and we will do, you will see how that can be done
when you have learned arrays, but the basic principle can be understood even right now.

(Refer Slide Time: 04:49)

377
So, suppose we have some way of getting to the digits, how do we manually divide, how do
we divide? So we said we do it manually, so let us try to understand how that happens. So, let
us say we want to divide this large number by 25, how do we divide it? So let me write the
down.

So, our number is 123456789, how do we divide this? We want to divide this by 25, then
probably we write something like this, then we look at the very first number so can this
number be divided by 25, or is it, is this too small, if it is too small we put a 0 over here. Then
we go on to the next number 12, can it be divided? Well no, so we put a 0 over here, again.
Then we bringing the third number, can it be divided? Well yes, now it can be divided. So
what kind of a quotient can we try out, well we can try out a quotient 4 in which we get case
we get 100 over here, and then we subtract. So, we get a 23 over here.

378
Alright, so, what is going on? So we are going to look at some most significant digits of our
dividend. And this part is what I am going to call as the temporary dividend. So we are going
to divide the temporary dividend by 25. Actually we are going to divide even this 1, this 1
was also a temporary dividend. But say in this case, this is the temporary dividend we are
going to divide it by the divisor and we are going to get a quotient. So we are going to
subtract the product of the quotient and the divisor from over temporary dividend. And we
are going to get the remainder.

What do we do with this remainder? So we bring in the next digit, so 234, so we bring in the
next digit, and attach it to the end of the remainder. But what does it mean, attached to the
end? So this simply means we are taking the remainder, multiplying it by 10 and then we are
adding the new digit. So the remainder was 23, the new digit was 4, so we got 234, so this is
our new temporary dividend.

So again we are going to try and divide this temporary dividend by the quotient. So what do
we get? So this time we will get a 9 over here. So we will put a 225 over here, and we will
get 9 as the remainder over here. Again we continue, so we are going to get a 95 again we use
this step, remainder times 10 plus digit. As this is over new temporary dividend. So now this,
we are going to have 3 as over quotient, so here not we get a 75, and then we are going to get
as remainder 20.

So then again we are going to bring the 6 down over here, and that is going to be our
temporary dividend. So, this was the temporary dividend, this was the temporary dividend,
this was the temporary dividend and these were also the temporary dividends. How do we
find temporary dividend? We have a remainder from the previous iteration, so at this point
we can think of the previous remainder being 0. But if there was a previous remainder, we
multiply it by 10. Then we add the new digit, and that gives us our temporary dividend. Then
we tried to divide the temporary dividend by our divisor. And the quotient goes into our
solution.

So, you will notice that we are processing the digits a left to right order. Once we process
123, then this 1 is completely useless, we do not have a remember it, so after we process 234,
these digits are completely useless. So, we are at any time we are at most keeping 1 extra
digit beyond the size of this divisor. So, all the previous digits we do not have to worry about.
So that is have we are going to get by without storing everything we are not even reading
these digits, we are initially. We are going to read them only when we actually want to look

379
at them. So, that is the idea, that is how we can get by without maintaining too much state,
without remembering too much stuff.

So again, let me summarize the basic iteration, so the ideas we are going to construct a
temporary dividend. So the temporary dividend in the very first step is simply the first digit
of the dividend. So this is the huge dividend that was given to us, we just pick up the very
first digit. In other steps, the temporary dividend is formed in this manner, so which is what
have a written down it here. So it is formed by taking the remainder from the previous
division and attaching it the next digit, on the right. So that means multiplying this previous
remainder by 10, and adding the next digit to it. So that is how we get the temporary
dividend. Then we divide the temporary dividend by the divisor. The quotient goes to the end
of the overall quotient generated so far. So 4 went here, the 9 went here, 3 went here and so
on. Are we keeping track of the quotient? Are we remembering the quotient? No, we do not
have to as soon as we know that this is a digit of the quotient, we just print it. And we know
that we are going to be printing digits in this order, so they will get, they will come out in the
right order.

And the remainder from this division, so we did a division over here, so from this division we
got a quotient, which goes to the end of the overall quotient generated so far. And the
remainder is used in the next temporary dividend. So I just written down what I have shown
you in this division over here and that is exactly, what we are going to mimic in the program
that I am going to show you next. Well, before I get to the program, there is a small technical
problem.

380
(Refer Slide Time: 12:11)

So we said we want to read in the digits of a 1000 digit number one at a time, but how do we
read it? Does C++ even allow us to do that? So here is what might seem like the natural
strategy. So we might say int digit and then we might read each of those 1000 digits one at a
time. Will this work? Well, if we type in the digits consecutively in this manner, then it will
not work, we will not get 1 the first time we read it. The first time this command executes
C++ will try to construct this whole thing into a single number and put that into the digits. So
that is not going to might work. If we put a space in between the 1 and 2 then, C++ will get a
1 for us. So that is one possibility, so you instead of typing in 123456 whatever the digits are
we put spaces in between, then each time we read, we will get exactly 1 digit.

381
(Refer Slide Time: 13:25)

But there is an alternate idea which is slightly nicer, which I think you should know about
and therefore, I am going to discuss it. So I am going to not read integers at all, I am going to
read in characters. So I am going to have a character variable c and I am going to read in into
that character variable. Ohh I am sorry, this should have been c here, not char, just a c over
here. So we are going to read in into c. So it will read the ASCII representation of 1 character.

Now, I have what was typed into this variable c. So, what is in the c? So suppose I typed 6, it
contains the ASCII representation of that character 6. So I am going to subtract from that
ASCII representation of character 6 the ASCII representation of character 0 and put the result
int digit. I claim that this is going to be the digit that you really want it to read. Let us see
why? So the point to note first is that the ASCII representations of 0, 1, 2 the digits, are in
order and they in particular they are 48, 49, 50 and so on.

The 0 has 48, 1 has 49, 2 has 50, 3 has 51, 4 has 52, 5 has 53, and 6 has 54. So at this point
when I have just read in, and they should be c and not char. At this point c would get the
number 54 inside it. This 0 is the ASCII value of the character 0. Which is 48. So when you
perform this, this result will in fact be 6 and so digit will in fact become 6. So, this is how you
extract digits from characters. You subtract the character representation of 0.

382
(Refer Slide Time: 15:51)

So now we are ready to write the code, so let me remind you, we have this notion of a
temporary dividend that we are going to form. And for that we need to know what the
remainder from the previous time is. So, we are starting with this at this point there is nothing
previous so the remainder is 0.

Then, we are going to process each digit. So, there are 1000 digits let us say, and we are
going to process them, and so what happens? Well, we are going to read in each digit, then
we are going to extract the actual digit value. So as we just said it is going to be c minus 0 the
ASCII for 0. Then this is the temporary dividend that I am going to form. So what was that?
We said that earlier it is going to be the remainder times 10 plus the digit that we just read.

And now this is going to be divided by the divisor. So, the divisor in this case let us say we
have fixed it to 2. So we just want, in the problem statement we said that we want to have it.
So this is the quotient dividend upon 2 and if you remember, coming back to this picture we
divided this temporary dividend by the divisor, and whatever the quotient was 9 we just
declared as a digit of the final answer. So that is exactly what you are doing over here, this is
a digit of the final answer and we are printing it out right away. We do not have to do
anything to it further.

So we are just going to print it, we are going to print it out. So every time we figure out the
digit of the final answer, we are just going to print it out. So that is what is being done. But
that is not enough, we need the remainder as well, so what is the remainder? The remainder is
simply dividend mod 2. So, if you want it to divide by 25, we could just have 25 over here in
both of this places that is it, that is the only change, and that is it, we just repeat this so many

383
times and at the end of it we will have quotient as we want. We will also have the remainder,
the variable remainder will contain the remainder at the end of the division. So, we could
print it out if we want, but in this code we have not printed it.

(Refer Slide Time: 18:24)

Alright, so in this manner we will be able to divide any number, which fits in a single C++
integer variable. So as I said instead of the 2 over there, you put in whatever number you
want. But not you cannot say I want to divide a 1000 number, a 1000 digit number by another
1000 digit number. So for other operations you will need to read the entire numbers. First you
need arrays which will be taught soon and in this code we supplied how many digits there are
in our number. You might say look why cannot we have, why do we need to do that is in that
inconvenient? So can we have the number we terminated by space, unfortunately this arrow
arrow command, this greater than, greater than command, this operator ignore spaces, so
there is some other kind of command which we need to learn, which we will learn a little bit
later, but for now it can be done. However, if you want to terminate it by a semicolon or stop
or comma or any other printable character, that is possible.

384
(Refer Slide Time: 19:43)

385
Alright, so before I conclude actually I think maybe we should take a look at the code and run
it. So, let us say I look at this code called halver.cpp. So this is exactly the same program, I
think I have called my character x rather than c and I have put in 20 over here. I do not want
to put 1000 because I do not want to put, I do not want to have a 1000 digit, in fact, I do not
even really want to have 20 digits when we are testing.

So let us say we will just put 5, of course you will say 5 we will fit, so let me put say 11. 11
certainly not fit, or let me put say 13. 13 digits will they fit? No, 15 is certainly not fit in a
single int. So, let us see what happens, so let me compile that, and run it. So now I am
supposed to give a 15 digit number, so let me do that. So 123456789012345. What happens?
So this is half of that number. Does it seem right? Well yes, so 2 gets me 6 over here, 3 gets
me 1, so 14, 7, 5, 2, 6 carry from 1 here, so 8 okay it seems reasonable. So I am getting the
right answer. And well, you could say look why can we do something, so that this leading 0
is not printed? Of course we can do something, but that will require a little bit more
programing and may be that is a good exercise for you to take this code and modify it.
Alright, so let me get back to the presentation, actually we are at the end of not only just this
segment, but the entire lecture, this segment sequence.

(Refer Slide Time: 22:13)

So, this is, these are concluding remarks on the entire sequence, so I want to observe that
loops are really fundamental. You can do a lot using the loops. So we already have seen lots
of things, even before today’s lecture sequence. But even in today’s lecture sequence, we saw
lots of interesting things.

386
So for example, loops are sort of the primary structure that you need, the control structure
you need to use, in order to go through a domain and figure out which elements in the domain
satisfy all the constraints that you are interested in or a loop can allow you to step through
and process the interaction with the world one at a time. So in each iteration, you process one
command that the world is throwing at your system and you generate how your system as
responding to it, so again a loop is absolutely a crucial control structure. And we looked at
reading in from the keyboard, and we said that if you type a 15 digit number, then you have
to read it out, read it in as a character, and then convert it into a digit. And then we can string
those digits together to make a number.

But this whole process, which I just showed you, it is something that C++ routinely, so when
you would type in a number to your program C++ is doing something like that it is extracting
the digits, when it is saying ohh is this digit ending over here, or is this the next digit and the
previous digits that I have accumulated so far should be multiplied by 10. And then this new
digit should be added to it.

So, that code that I showed you something similar is used by C++ just to read in what you
type. So, so far we have being saying that when you type 365, 365 magically goes into the
variable you are ‘cin’-ing into. That is not really what happen C++ is taking each of those
digits as characters and then converting them and accumulating them together and that is how
the number actually goes and sits in your variable.

So all this is being done with a single loop program, and note that single loop programs do a
lot. Well, sometimes you will have to nest a loop, nest loops of course. So if you have a, if
your domain has two variables or in other words you think of it as a two dimensional domain
then you will have to have nested loops, but it is loops. Alright, so that concludes this lecture
sequence. We introduced a bunch of new application themes over here, and we saw that loops
are very powerful and we got a lot of practice using loops. Thank you.

387
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 10: Part-1 Functions Basics

Hello and welcome to week five of the NPTEL course an introduction to programming through
C++. Today's lecture sequence is about functions and the reading for this is from chapter 9 of the
textbook. So the central question that functions address is how do we define new commands? So
we really already have a whole bunch of commands for example sqrt(X).

(Refer Slide Time: 0.44)

So ‘sqrt’ is a command and if you pass it the argument X then you get the square root of X.
‘forward’ is a command and given an argument d it causes the turtle to move d pixels. So you
might ask are these the only commands that we can have or can be ourselves make new
commands? For example, we would like to make a command gcd(m, n) which should evaluate
the GCD the greatest common divisor of m and n. Or suppose we want the turtle to draw dashed
lines as it moves rather than solid lines, continuous lines. Perhaps, you would like to have a
command dash(d) which would do this. Where d is the number of pixels that you want the turtle
to move. And, in fact, you can do this and the name that the technical name for what we have
been calling the command so far is a function.

388
(Refer Slide Time: 01:51)

So, in this lecture we are going to do the following things. We are going to give first some
examples of defining and using functions, then we talked about how to define a function in
general. How a function executes? We will talk about what is called the contract view of
functions. So, how should you think about functions informally. Then we will talk about how the
arguments can be given or what is called parameter passing and there are various ways of doing
this. One is the so-called parameter passing by reference which we will talk about. And we can
also pass parameters using pointers. So this is also a concept that we will introduce and finally
we will talk about how functions can interact with graphics objects such as rectangles circles
and, of course, turtles, the turtles we will already have discussed in the earlier part of the
sequence. So let us begin with a problem.

389
(Refer Slide Time: 03:06)

Our problem is write a program that prints the GCD of 36, 24 and of 99, 47. Here, I have
explicitly stated the numbers but in general you can say that I want to write a program which first
finds the GCD of one set of numbers maybe finds a GCD, does something and then finds the
GCD of some other set of numbers maybe does something else and finds a GCD of third set of
numbers and so on. So, this is just a representative program representing the kinds of things you
might want to do.

So how would you do this? Well using what you already know. You might make two copies of
the code that we wrote earlier for finding the greatest common divisor. The first copy would be
used to find the GCD of 36 and 24 and the second copy to find the GCD of 99 and 47. So, here is
what it might look like. So, we have a main program in which we first define m to be 36 and n to
be 24 and then while m mod n is not equal to 0, we set r equal to m mod n, m equal to n, n equal
to r and this is just the code that you saw earlier. So, let me not explain that code but the result,
the GCD will be contained in the variable n at the end and so we can just print out that GCD. So
that finishes the first part of what we were required to do. The second part is doing the same
thing for m equals 99 and n equals to 47. So, here we might start off by saying m equals 99, n
equals 47. Note that we are not really clearing the variables. The variables have been declared
earlier and we can just use those variables.

390
Then we have the same code again and at the end again we print out whatever is contained in m.
So this is, this is a program which does what we wanted. Which is printed GCD of 36 and 24
first and then the GCD of 99 and 47. Now, this contains code duplication. Code duplication is
not really good okay. So, if I am copying code maybe I will make mistakes in copying. So, why
increase the chance of making mistakes?

And suppose I need to have GCD - The Greatest Common Divisor computed at 10 places in my
program then it does not seem a good idea to make ten copies of this code and this is, this
becomes worse if we need to make a change to the code that we wrote. So, now I have to
remember to make the change in ten places. So all this is rather inelegant. Ideally, you should not
have to state anything more than once and functions allow you to do exactly that.

(Refer Slide Time: 06:17)

So, I am going to show you the code which uses functions and it has two parts. The first part
which you will see in the red is the function definition and then there is the main program. So
here it is. The red part is the function definition and the green part is the main program. The main
program calls or invokes the function. So, the first call is GCD of a, b. Now, I could have put 36
in place of a that would have been perfectly fine but just to show you that I can also have a
variable I have put in int a equal to 36, b equal to 24 and then called or invoked the function
GCD with names of the variables rather than the values directly. And notice that I am invoking

391
the function, and I am expecting that the value that comes will sort of sit in the place where that
call is, where GCD of a, is and then I can directly print.

In the next line I am invoking or calling GCD again and this time the arguments 99 and 47 I am
passing directly. I am sending, I am writing them down directly. So, in general the call is going
to include the values whose GCD is to be calculated. The values at a, b in the first call and 99
and 47 in the second call. So, the values supplied as a part of the call are called arguments to the
call. The red part is the function definition. So, first it contains a function name. Well gcd is the
name. Before that there is this int, so that is not the name the name is the gcd and after that it
contains int m, n, and that says so gcd together with int m and int n says how the function is
going to be called. So GCD needs to be supplied an integer argument which could be referred to
as m, which will be referred to as m, inside the GCD code, inside this red code and it needs to be
supplied another integer value. So, that is what the top line is saying and the first int, the int at
the beginning of that code is saying that the value returned is going to be an integer value. So,
this int is saying that this gcd, the call to gcd is going to return an integer value and (this part)
this part is the so-called body of the function and this says what you need to execute in order to
compute the GCD.

392
(Refer Slide Time: 09:23)

Now, I have given an example over here. But I just now want to state what is going to happen in
general, or how would you write functions in general? So, in general you would have a return
type. The first word of the function definition is the return type. So indeed this int is the return
type. It tells you the type of the value that is going to be the result of the function execution.
Then there is the name of the function over here and then the parameter names. So in the calling
program these are called arguments and in the function these are called the parameters. So the
parameters, you can give a list of parameters but each list has two parts. First is the parameter
type, parameter one type, parameter one name, then parameter two type, parameter two name
and so on as many parameters you want. So, in this case we only give two parameters and then,
there is the body. So the function body has to be placed inside braces. So, in our code this is the
function body. The explanations I have already given you the return type is the type of the value
returned by the function. So, for example, int in our case and sometimes functions may not return
anything at all and this is discussed later but in this case the return type will be written as void.
We will see an example soon enough. The name of the function could be any identifier name. So,
for example, gcd as we have used over here and parameters are variables. So that will be used to
hold the values of the arguments to the function. So, in this case these are the parameters m and n
and these will hold the values of the argument. So, we will see the exact execution process in a
minute and the function body is the code that gets executed.

393
(Refer Slide Time: 11:31)

So, how does a function execute? So let us say you compile this and you load it and now you are
executing the main program. So, the main program starts execution. Then the main program
executes, you execute this. So, a gets the value 36, b gets the value 24 and then the main program
or the control, the control in the main program reaches this statement and you see that there is a
call over here. So at this point the main program is going to suspended. So, this execution of the
main program is going to stop over here. But the main program is not going to go away, it is
going to wait. So, suspend means that it is going to stop but it will wait. We can ask it to start
again at some later time. So the main program has stopped at this point it is said that look I need
this expression to be evaluated.

So now you make now C++ makes preparations to run ‘gcd’ and in some languages this is
actually called a sub program, so it really is pretty much like another program but it is not the
main program and so you may call it you think of it as a subprogram. So some preparations are
made in particular, an area is allocated in memory where the GCD will have its variables. So, of
course, the program needs some area in which its variables are to be stored and main program
also has it and main program will have an activation frame in which these variables will be
stored. So, similarly, C++ will create an activation frame for gcd as well. So gcd’s variables will
somehow is told over there as and when needed. Now, immediately as soon as this activation
frame is created C++ also creates variables m and n. So, these parameters actually become

394
variables during the executions of gcd. Not only that the values of the arguments from this call
are copied into m and n. So, the value of this first argument is copied into m and the value of the
second argument is copied into n and because the values are copied, so it is the value that is
copied, this is called passing arguments by value. So, you will see there are other ways of
passing, so right now we will just say that this is passing arguments by value. So, a, which has
the value 36, so 36 will get copied in m over here and b which has the value 24 and therefore, 24
will get copied in n.

(Refer Slide Time: 14:42)

Now, at this point execution of gcd will start. So what happens? So, this is exactly like the
execution of the main program. So, these are the variables so far and now we execute this code.
So, you have seen how this code executes. So, 36 and 24 we know that this is going to calculate
the correct GCD. So, n at the so then all of this is executed ‘n’ will have the value 12 at the end
of this. So, all, how to execute all of this is very clear to you, so when you come to this statement
this is a new statement, so let us explain, what that return means. So, n equal to 12 is calculated
and the execution comes to an end essentially when we encounter a return statement and the
return statement is going to somehow send back the value. So, what value it sends is this the
word following return, the expression following return. So, this value is going to be sent, but this
value n has value 12. So, somehow we are going to send back 12 to the calling program and
where does this value go? So it goes and effectively sits instead of the call. So, we are going to

395
essentially have a 12 coming over here. So at this point the purpose for which we started off
running the GCD sub program is done. Its code has been executed, it has returned its value. So,
the activation frame that we created for it has been will be destroyed by C++ and, in fact, these
variables m and n will also go away at this point. So, this memory will be taken back by C++,
and at this point we will resume the suspended execution of main program, remember we
suspended the execution when we were, when they encountered this call. So, now that value has
been evaluated the value of GCD of a, b has been evaluated as 12 we resume the execution. So,
when we resume the execution what happens, well if there were 12 over here we just want to
bring 12. So, 12 would get printed, sorry 12 would get printed and after that this main program
execution would continue and everything would start with GCD of 99, 47 so the same thing will
happen. Again 99 and 47 would be copied to m and n and again every so in gcd, the first an
activation would be a frame would be created, m and n, GCD of m and n would be copied and so
on. So, this is how this means this program is going to resume and it is going to print values or it
is going to calculate values and send them back to the main program and the main program can
do whatever it wants with the values. So, maybe before I go to the remarks let me stop here and
let me just show you this program in action.

396
(Refer Slide Time: 18:04)

So, this is our program. So, the only change I have made to the code is that inside GCD I have
put in a line saying calling GCD with arguments m and n. So, what we are expecting over here is
that when we execute the main program gcd will execute, but as it executes everything that we
said a moment ago will happen but in addition it will also print this message. So, the first time
we should see a message 36, 24 the next time we should see a message 99, 47 and in between we
should see the GCD is calculated, so let us see that.

(Refer Slide Time: 18:47)

397
So, let me just compile this code and let me execute it. So, what has happened is that it indeed
printed the message saying calling gcd with arguments 36, 24. 12 got printed because we were
printing out the GCD and calling gcd with arguments 99, 47. 1 got printed because here the GCD
is one okay. So you could ask what if I print the value to be returned before I return it yes you
could do that. So you should try it out. Take the program, add that cout statement and you will
see the value 12 printed twice and also the value one printer twice and maybe you could even
print a message saying returning value so and so from gcd.

(Refer Slide Time: 19:42)

So, let me make some remarks about what we have seen. So, we have a set of variables in the
calling program. So, here the calling program was the main program and this set of variables
lives in the activation frame of the main program and it is completely different, it is completely
disjoint from the set of variables in the called function. So, in in this case the call function was
gcd. Now both may contain the same name. So, I had a and b in the main program and m and n
in GCD but that is not needed. I could have named the parameters a and b if I liked. So, that is
not a problem okay. So, when I execute the calling program, the code that is written there is
expected to refer to the names in its body and in its parameter list.

So, if there was m and n in both places and if there was code, the code for gcd contained m and
n, that m and n would refer to whatever m and n is defined inside the body of the GCD or inside

398
the parameter list. So, it had better be defined only there and, of course, the called program, the
calling it is, so it is the same rule for the calling program and the called program.

So, whatever variables appear in gcd are accessible in the code of gcd and whatever variables
appear in the main program are accessible in the code of the main program. So there is no
problem using the same name in both cases. So, it is clear which, so if you refer to a name in
your code which declaration, which definition of that name you are referring to.

One more point, when you pass the values of arguments, here we had written either the numbers
99, 47 or names of variables but that is not necessary. You might have done some calculation
and then decided what value to pass. So you could put an expression instead of either the values
directly or instead of putting the names of variables which contain the values. So, if you put an
expression then that expression is first evaluated and then copied to the parameters of the called
function.

An important point is that in C++, there is a very general rule that if you are referring to a name,
that name must be defined earlier. So, in the main program we refer to the name gcd. So the gcd
has to be defined earlier. If GCD is defined later then that would not be correct. C++ compiler
expects that GCD should be defined before it is actually used.

So some more remarks, the body of a function can contain practically anything. Anything that
say the main program can contain. So, for example, it can create new variables internally if it
wants to, and the same rules apply. So, if you create a new variable inside a block and the body
of gcd is a block in fact, so those variables will go away when the execution of that body ends.
Inside the body of GCD or inside the body of any function I can read values from the keyboard. I
can use cin and also cout statements to produce output. So you already saw an example. We put a
cout statement inside the gcd function and just to clean this up completely let me just observe
right now and this will become more obvious a little bit later. The main program is actually also
a function. So, gcd is also a function. So, essentially the same rules apply in both cases. Well in
the main program we have not been writing return but that is something that some that is a
concession which is given to the main program. So we could write return there and we will talk
about that later as well. But in general for a function you really should be writing return and we

399
have already seen in case of gcd we returned the value that was meant to be the evaluated value
of the call GCD whatever our arguments being supplied.

Then inside the body of a function you can access the canvas and you can access turtle, the turtle
created using turtleSim. In fact, you can make the call turtle swim also inside the body of the
function that is. So, that will also create a window and that window can then be used even after
you return to the main program. In fact, you can create other graphics objects also inside the
body of a function okay and we will discuss that a little bit later, you can create the objects, you
can pass objects to a function, a graphics objects but that will we will talk about that a little bit
later.

(Refer Slide Time: 25:37)

So, here is a quick exercise. I am going to give you the solution. So you should try and do this
yourself before proceeding further okay. So, what is the exercise? Write a program to determine
whether a number is even. So, I would strongly request you to pause the video here and try and
write this program. So, assuming you have paused and assuming you have written the program
let us now see how that program could be written. So, I am going to show you two ways. So the
first way is okay, first of all we have to define the function. So, what is the value that is going to
be returned? So, we are asking we want to determine whether a number is even? So, the answer
expected over here is, yes, the number is even or, no, a number is even or true the number is
even, false the number is not even.

400
So, indeed even we will write a function called even, and it is expected to be returning a true or
false value and therefore, we have the return type as bool okay. So, if you remember bool is
return is a type whose acceptable values are true or false. Then this is the name of the function
and it takes one argument. So, this is the number or the parameter is n and this function is going
to tell you whether this number is even or odd. So, if it is even it should be returning true if it is
odd it should be returning false. Now, how do we determine whether a number is even? So, if
you remember, we have the percent operator which gets the remainder when one number is
divided by another. So, what we want to know over here is what is the remainder when n is
divided by 2, is it 0 or is it not 0. So, if it is 0, if n mod 2 is equal to 0 then we want to return true
because then the number is true otherwise we want to return false. So that is the function. Now,
this is a perfectly fine function but I just want to alert you to the fact that you can write this much
more compactly. So, here is the compact form. So, here what I have done is I have put in an
expression over here. So instead of having an if statement, I have put in an expression. So, what
let us just check that, so if n is n mod 2 is equal to 0, then this expression will turn out to be true,
otherwise it will turn out to be false. So, depending upon what this expression evaluates to a true
or false will be returned.

But when will this expression be true? It will be true only when n is even. So, when n is even it
will return a true and in this expression, if n is odd, this expression will be false and therefore, a
false will be returned. So, both forms are acceptable but this is a more compact way of writing it
and just I just want to alert you that you can have an expression over here and, in fact, this is a
Boolean expression, so Boolean expressions are also perfectly fine.

(Refer Slide Time: 29:10)

401
All right! So, what have we discussed so far? So, we discussed what is a function, we discussed
how to define a function? How it executes? And next we are going to take more examples and
we are going to see how we are going to think of functions. So, let us take a short break.

402
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 10: Part-2
Functions Examples

(Refer Slide Time: 00:21)

So, in the last segment we discussed what is a function how to define it, and how it executes.
Now, we are going to start by taking more examples.

(Refer Slide Time: 0:29)

403
So, another exercise, so, let us write a function to compute the LCM or the least common
multiple. So, here we are going to write this code but we are going to use the identity that the
LCM of 2 numbers and m and n is their product divided by their greatest common divisor.
So, now, we already know how to calculate the greatest common divisor, so we might say
that why do not we use this and calculate LCM as well.

So, here is the code, we are going to write int LCM of m and n, it is going to take two
arguments so it will have 2 parameters m and n and we are going to just return that
expression, so return just that, that is it, and, of course, this assumes that we have a GCD
already defined and where should that be defined, it should be defined before it is used. So it
should, so the definition should come above LCM.

(Refer Slide Time: 01:34)

So, your code should look something like this, so first in your file, you should have a GCD
program, then you should have the LCM program and I have not given the full GCD
program, it is a little bit long but, it will return n eventually and I am. So n, of course, with
the value of n will have changed inside this, and here I am going to, it is going to return the
LCM and then I am going to have the main program. So, the main program is going to make
call on lcm, lcm will make a call on gcd which is given over here.

404
(Refer Slide Time: 02:13)

So, how does this execute. so let see that. So, the execution begins with the main program so
the main program starts executing. So, it encounters this statement and it say see there is an
LCM to be computed. So, since, there is an LCM to be computed, the main program suspends
and an activation frame is crated for lcm, then 50 and 75 are copied to m and n, so 50 and 75
are copied to these m and n and lcm starts execution.

Now, the call to gcd as this executes, the call to gcd is encountered, this execution of lcm
tries to construct this value and it encounters a call to gcd, so because of that lcm is
suspended. So now, note that we have two things suspended, we have the main program
suspended and we have the lcm suspended and at this point the activation frame for gcd is
created because this value has to be calculated. So, 50 and 75, these values are copied to these
m and n, so in the activation frame of gcd. So execution of gcd starts, gcd computes the
correct result the GCD of 50 and 75 which is 25, so gcd computes this result and the result is
copied to the activation frame of where this came from. So, this call came over here, so 25
gets copied over here. So, now, gcd execution is complete and so the activation frame of gcd
goes away and lcm execution resumes.

So, lcm continues execution so sorry this, so m times n divided by 25 is calculated, so 50


times 75 divided by 25 which is 150 is calculated, but this is a return statement so this value
gets copied in place of this expression, so the value is returned to the main program and the
activation frame of lcm is now destroyed. So, remember what happened, so main program
had its activation frame and activation frame was created for lcm and activation frame was

405
created for gcd. The activation frame or gcd was destroyed, the activation frame of lcm was
destroyed and the value 150 was returned from here, and it is in at place. So at this point the
main program resumes execution and prints 150, and then it exits.

(Refer Slide Time: 04:57)

So one more quick function, so we want to draw dashes while moving, so we have over turtle
and normally if you just say forward it draws a line so now, we are going to draw dashes. So
here is a function. We are going to have, the name is going to be dash and we are going to say
how many pixels we want to move, so we want to move forward d pixels, and we want to say
over here, how many dashes should there be so this distance is going to be divided in to these
many dashes. So, how does this work, so this first of all this function, let me observe is not
going to return a value it is going to cause some drawing to happen. So, because it is not
returning a value we are going to state its return type as being void, if you wanted to return a
value in addition to drawing something we could have put that type over here, but as it is we
do not, we are not interested in returning a value. So we want to draw 10 dashes or whatever
n dashes so we are going to have a repeat statement, so repeat n times and we are going to go
forward, d by 2n so a distance d by 2n we are going to go forward, and during this we are
going assume at the beginning that the pen is down so a line will, be drawn. Now, at this
point we will raise the pen so at this point again we will start going forward so we will have
forward d by 2n again so this time the turtle will move the same distance but, with the pen up.
So, no line will be drawn. Then we will put the pen down again and that would be the end of
the loop. So this whole thing would be executed n times and so the turtle will cover d over 2

406
distance twice in each iteration, so d distance in, d by n distance in each iteration so overall it
will indeed cover d distance.

And at the end it will return. So, here note that we have not set return something, so here, we
are not expecting to return anything and therefore, we just say return followed by semicolon.
So that is it, so the main program could look something like this, turtleSim repeat(4) dash
100, 5 and right 90, so this should be drawing a square we have put and get click just to see
that, that square has been drawn. Alright, so let me suspend the program over here and let us
see this, dashes program in execution.

(Refer Slide Time: 07:56)

407
So here, I have the dash program so let us compile it and run it, so see the turtle draw a dash
rectangle we can finish we can stop the execution by clicking and that is it. So, at this point
we have seen several examples of functions, and now, I want to say something about how
you should think about functions.

408
(Refer Slide Time: 08:32)

So a function if you think of as a peace of code which takes the responsibility of getting
something done. The specification is a description of what the function is supposed to do, so
typically the specification look something like this, “if the argument satisfies certain
properties then a certain value will be returned, or a certain action will happen,” that is what
the specification is going to look like.

The certain properties are sometimes called preconditions, so, for example, for gcd, we might
say that if positive integers are given as arguments, then their GCD will be returned, so this is
a specification for gcd. If precondition is not satisfied so if you, for example, give negative
values, then what happens well, nothing is promised. The program may run forever, the
program may return some non-sense, of course, but nothing is guaranteed to you.

The writer of the function gcd is not making any claim about what will happen, you could say
that, if the values supplied are incorrect, then the function should say so, but that is not really
always required, so the function writer has to say that these are my preconditions, so it is your
responsibility to check if the arguments satisfy the preconditions, if not, I do not know what
is going to happen. But, you could have other function definitions in which there are no
preconditions because if the wrong arguments are given, the function may take some action
and return some value saying that, “Oh, you gave me wrong arguments.” Before you write a
function, you should write its specification as a comment in the code, so this is just so that
you are sure yourself that you know what it is that you want to do.

409
So, there is a certain kind of humility that you have to have when you write programs and I
think most programmer have that humility because they might write programs and might
claim that, “Oh this program is going to do this,” but actually when they execute they find
that “No, the program does something else,” and then they have to spend lots of time figuring
out why the program made a mistake. So, because of this humility it is a good idea that you
start up the whole process saying, “Let me be clear to myself what is it that, my program is
supposed to accomplish, and therefore, let me first write down the specification in as clear
words as possible.” Now all this is really taking you towards some kind of a contract view,
what does it mean, the writer of the program is promising something.

(Refer Slide Time: 11:43)

So a function is a contract between the programmer who wrote the function, and the
programmers who use the function, sometimes both of these parties could be the one and the
same party but, they need not, so if they are not, then there is the contract view sort of make
more sense, the programmer who uses the function says that “Look, I trust the function writer
to make sure that the execution satisfies the specification.” So when I make the call I am not
going to worry about how the function is actually going to execute, that is not my job, so the
whole programming process is sort of to do things like this. So, once I write a function
subsequently when I use it myself I am not going to worry about how that function executes.
Because when I wrote the function, when I tested it, I have satisfied myself that it runs
correctly and from that point on wards, I am not going to worry about how it works
internally.

410
And if it is some other party’s function, that some other party wrote that function, then, of
course, I am not going to care how that other party wrote the function, but, in fact, I am not
going to care even if I wrote it myself because when I wrote it I would have tested it and have
sort of made sure that it works correctly so now I do not want to be bothered with it.

Programmer who wrote the function, does not care which program uses it, so I write a
function, when I am writing the function I am making, trying to make sure, that it is going to
run correctly no matter who uses it, no matter what arguments are supplied to it, so it sort of
like giving cloth to a tailor, so when I give the clock the tailor promises to give me a good
shirt, if the cloth is good, and the wearer does not care how the shirt was stitched, and the
tailor does not care who wears it, so it is a contract between them, that I give you cloth you
give me shirt. Similarly, where a function, it is a contract between the function writer and the
function user. So, the contract is made so that the responsibilities are clearly delineated and
each party does not reduce, it is meant to reduce the worry for each party so, the user does not
worry about how exactly the function was written, how it executes, and the party that wrote
the function, does not worry about where is it going to get used. Because while writing the
has made sure that it is going to pick correct in all cases. When the function finishes
something is promised and in particular something might be promised about the state of the
computer.

411
(Refer Slide Time: 14:51)

So, for example, after the dash finishes its execution, if you go back and look at it, it was
going to leave the pen down and it is also expecting the pen to be down but you may change
this you may say look, I would like you do assume that the pen is up so maybe you should
yourself make sure that the first command is pen down and I want you to leave the pen up, so
maybe you should do that.

So, whatever it is, whatever the expectations might be it is a good idea to spell them out
clearly, so that the user of the function is not surprised and the user of the function does not
expect more than, what here she is going to get.

So, in this case here is a small exercise, modify that code so that, these post conditions will be
satisfied and, of course, the post conditions must also be mentioned in the specification, and
this is, this cannot be stressed too much writing clear specifications is very important for the
writer of the function as well as for the user of the function alright. So what did we discuss in
this segment?

412
(Refer Slide Time: 16:10)

So, we started off at the very beginning by saying that if you are going to execute the same
codes several times, possibly with different values, then you define a function that executes
the code. You call the function with the appropriate values. Functions can have their own
variables which are created in the activation frame or activation area of the function. And the
names can be the same in the main program and in the functions.

We also said that the function is like an independent program, except that it gets it, get some
values the arguments from the calling program and returns results to the calling program.
Next we are going to talk about reference parameters and we will take a short break.

413
An Introduction to programming through C++
Professor Abhiram G Ranade
Department Of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 10 Part – 3
Functions Reference Parameters

So, in the last two segments we have discussed various aspects of functions. We began by
saying where functions should be define and used. And then we talk about how they execute,
how they can have their own variables. And then finally we said, how should we be thinking
about functions? So, basically we should not be thinking about how a function executes, once
we have designed and made sure it works correctly. From that point onwards we should worry
about how we use it. So, we should not, when we make a call to a function we should trust
that the function is going to return us the correct value so long as we are following the
specification. In this segment we are going to discuss something called reference parameters.
And, let me began by saying why these are necessary.

(Refer Slide Time: 01:09)

So, what we have so far has some shortcomings. So, we are not able to write functions to do
the following things. So, for example, we cannot write a function that exchanges the values of
two variables. So, you may think that often we might want to say look exchange the values of
these two variables. So, should not we have a function to do that? Yeah, it seems like a
reasonable requirement but, you cannot do that using what I have just taught you. So, we will
see that in a minute and we will also see it how to fix it.

414
Similarly, sometimes you might want a function which not, which does not produce just result
may be two results. So, suppose you want to produce polar coordinates given Cartesian
coordinates. So, given X and Y I want to produce R and theta. So, the return statement
enables you to return one value so, how do you return two values? So, that is another problem
that we will see how to fix.

(Refer Slide Time: 02:15)

So, let us come to the problem of exchanging two values. So, the first attempt. So, here is the
potential function that I could write. A possible function that could write so, the function
could be called exchange. And, it takes two parameters or the call will have two arguments M
and N the, values that I want to exchange. So, I place the value from M into temp, then I place
M into N, and then I place N into temp. So, at this point clearly the value of M and N are
exchanged and, I am not expecting to return anything. And presumably in the main program I
can do something like this. So, might I have A is equal to 1 and B is equal to 2, I exchange A
B and when I print out I should expect that, hopefully A will be 2 and B will be 1. However,
this does not work. 1 and 2 will get printed over here and let us see why that happens. So,
when exchange is called 1 and 2 are indeed place into M and N. So, our rule, our usual rule is
that when we make a call the value of arguments 1 and 2 are copied into M and N. Now,
execution of exchange does exchange value of M and N. But, unfortunately the change in M
and N happens in the activation frame of exchange and this does not change anything over
here, in the activation frame of the main program. So, when you return the program has same
values and so 1 and 2 will get printed. Now, how do you fix this? It turns out that the fix is

415
actually very-very compact, very slight. It is just a matter of adding two characters but they
are kind of important characters so, let us see that.

(Refer Slide Time: 04:30)

So, these are the two &s that you have to add if, you add those two &s then this code will do
what, you expected to do. So, let me explain what these &s do and why they produce the
behavior that we wanted. So, if I write an & before the name of the parameter, then it means
the following things. It says, “Did you create the activation frame for this function.” “Do not
allocate spaces for this parameter, but instead make this name refer to a variable, the
corresponding variable from the following program.” So, in this case this means that this M,
there will no variable allocated for M in activation frame of exchange, but instead M will refer
to the corresponding argument, so A. So, whatever you do with M in this will actually be
done using A. So, A is just going to be, M is just going to be an alternate name or a reference
for this A. So, that is why this is called a reference parameter. So, M will really refer to A, M
will not have the value of A but M will refer to A. And N is also a similar variable, so N will
also refer to B and it will not be a new value. So, when this exchange call happens nothing is
actually copied. So, instead these parameters are thought of as referring to the variables in the
calling program. So, now when the function changes M and N it is really changing A and B.
Because everything over here, so these M’s and N’s over here are really A’s and B’s, so, they
are just alternate names, so if I say, put an & over here, this is just an alternate name for
whatever name you had in call. So, such parameters are called reference parameters and, in
fact, in this case what you expect 2 and 1 will get printed.

(Refer Slide Time: 07:01)

416
If a certain parameter is a reference parameter, then the corresponding argument is said to be
passed by reference. And now this reference parameter enables us to not only exchange
values, but also compute polar coordinates given Cartesian coordinates and somehow convey
the values back to the calling program.

So, basically the idea is that we are going to use two reference parameters and the called
function will store the polar coordinates in the reference parameters. And this changes can be
seen in the main program. And by the way, this is not the only way of returning two values,
we just see later that there are other ways as well, but this is one of the ways.

417
(Refer Slide Time: 07:50)

So, here is the Cartesian to polar program. As you can see X and Y are ordinary parameters
there are passed by value. R and theta on the other hand are reference parameters. So, what
does that mean? So, when this call CtoP happens the values 1 and Y are copied into X and Y,
but the values of R and theta are not copy. Now, this function is going to execute and plays
some value in R and this R is really the same value of R because this is a reference parameter.
So, this value will actually get stored in the activation frame of the main program and in
particular, in the variable R in the activation frame of the main program, and similarly, this
theta, because it is the reference parameter and because the fourth argument here is the theta
of this main program, this theta is just a name for this theta. And therefore, water ever is
calculated over here, will get stored in the activation frame of the main program in the theta
variable over here.

So, as a result what gets printed is going to be the R which was calculated over here and theta
which was calculated over here. So, changing them in CtoP change is the value of R theta in
the main program and hence, what is get calculated, so square root of a 1 and 1, 1 square plus
1 square, so square root 2 will be printed for R and, atan 2 of 1,1 is 45 degrees so pi by 4 will
get printed over here.

418
(Refer Slide Time: 09:33)

Alright so, here is a quick exercise, so write a function which takes length and inches and
returns the length in yards, feet, and inches. So, this is the so called a British system which is
not really in use, but which does get used once in a while. So, you should note that 12 inches
make a foot and 3 feet make a yard. So, as an example, if you have 100 inches then that is
equivalent to 3 yards 2 feet and 4 inches. So, that is what you are supposed to print. So,
clearly you are expected to be returning 3 values. And, therefore you should have 4
parameters 1 in which will pass the given length and, other 3 in which the function will put
the number of yards, number of feet and number of inches. Alright so, what did we discuss in
this segment.

(Refer Slide Time: 10:33)

419
So, we said that if you return more than 1 results, we can do so by using reference parameter.
If we use a reference parameter R in some function and pass as argument a variable A, then
any change that the function makes in R, will be seen by the calling program as a change in A.
In the next segment we are going to discuss pointers which will perform a similar function,
but pointers are quite useful in other places as well so we will see that shortly. Let us take a
break.

420
An Introduction to Programing through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-10
Part – 4
Functions
Pointers

Hello and welcome back. In the last segment we discussed reference parameters. In this
segment we are going to talk about pointers which do something similar.

(Refer Slide Time: 00:34)

So, if the memory of a computer has N bytes, then you may recall that the bytes are
numbered 0 through N minus 1 and this number of a byte is different from what is stored in
the byte. So, the number of byte is said to be its address. So, if you remember our analogy
was the thing of the bytes as sitting on the long street and you give them the number say left
to right along the street. So, from one end of the street to the other end of the street and each
byte is given a number according to its position on the street and, of course, in the bytes you
can store some other values so that is different, so that is different from the address or the
number that has been given which is the positon of the byte along that street. So, the number
is called the address and, of course, we can store anything in every byte.

The term pointer is used to denote a variable that can store an address. So, an address is also a
number but we are going to make a distinction, because addresses are going to be used for
very different purposes than ordinary numbers and therefore, we really do not want to mix up
addresses and ordinary numerical values. So, in any case you know that everything on a

421
computer is a sequence of bits, so an address is also a sequence of bits, a number whether it a
floating point number or a fixed point integer is also a sequence of bits but we have to treat
then differently. And so an address is a variable that can store addresses or some times you
might use the term pointer to refer to addresses themselves. What we accomplished using
reference variables can also be accomplished using the pointers. So, that is the motivation for
studying pointer right now and pointers will also be useful elsewhere, so we will study that
later.

(Refer Slide Time: 02:55)

We said that pointers are variables to store the address of a variable, but let us now see, how
do you first get to the address of a variable. So, the operator & can be used to get the address
of a variable. Now, the same & is used to mark reference parameters, but which one we are
thinking of will became clear from the context. In fact, if you remember we also had an and
to denote the conjunction of two conditions. Again it is that same character but in this context
we are using a single && so do not confuse it with that and or either the & that is used to
mark reference parameters. So, here is a statement which creates a variable t and t. Now, if I
write cout<<&t then this is going to print out the address of t not what is contained, what is
stored in t that it is going to print out the address of t. So, in particular, so it is an int variable,
so you remember that an int variable takes 4 bytes, so this is going to be the address of the
very first byte amongst those four bytes. Now, when you do printing like this and you can try
it out customarily the radix used for printing addresses is the hexadecimal radix and, in fact,
so your value will consist of a sequence of hexadecimal digits which are 0 through 9 and then

422
A, B, C, D, E and F. And they are also prefixed by 0x, 0x sort of stands for hexadecimal, so if
you print this you will see some string looking like that.

(Refer Slide Time: 05:14)

And now we know how to print out address or how to get to address, now we see how we are
going to construct variables which can store addresses. So, how do we create a variable for
storing addresses of variables of type int, so this is how, so, we are going to write int *v as I
just pronounced it this is going to be read or pronounced as int-star-v. And, of course, again
there is a confusing usage, the star when used in the manner is not to be read as
multiplication, it is meant to be read as something else. So, in fact, we are going to think of
the star as joining with int, so we can think of the entire int star as the type of v and you can
think of int star to together meaning address of int, so it is a value and the type of that value is
address of int. So, suppose we have int p define later on, now I can write v=&p, so what does
this do? So v is a variable see supposed it contain addresses and p is an address of int, this is
supposed to contain addresses of int and &p is an address of int and therefore, we can store
such values inside v. So addresses can be stored, addresses of int can be stored in v. So, in
fact, C++ will check whether in fact the values you are storing are of the right type otherwise
the compiler will flag an error. Now, if I print out v and print out &p you will see that exactly
the same value will get print, so v now is the name of a variable but if I say print me the value
of print me v, what gets printed is its value. So, v is not an integer so the value that v contains
is an address and so that is, that gets printed, but here I am asking the address itself to get to
be printed, so both will really print the same thing. Here is an interesting statement what if I
right v is equal to p? Now, v is a variable of type address of p but p is not and address of type

423
address of end, but p is not an address of int, p is an int. So, C++ says that look both of them
may be bit strings but I do not think you really want to do this, so there is no occasion where
we really want to mix values and addresses and therefore, C++ will flag it as an error during
compilation. So, in general we can create pointer to arbitrary types of variables, so not just
ints may be doubles, may be chars whatever we want.

(Refer Slide Time: 08:51)

So, to create a variable w to store addresses of variables of type T, we will write T *w, so just
as we wrote int star w we can write double *w, double *y or char *x whatever it is, whatever
if you want. An assignment statements in general require the types of the left hand side of the
assignment and the right hand side assignment to match, so if you create something which
has type T * and you assign something to it then the value on the right hand side must also be
of type T *.

Now, this type matching rule is not quite applicable if both sides you have numeric types, so
we saw that earlier, right, so you can take a float value or a double value and store it into an
int or vice versa, but that is an exception made to the very general rule of type matching on
both sides of the assignment statement when both sides are numeric, but if both sides are not
numeric then there is no automatic conversion made from one type to another. And, in fact,
the compiler will flag an error, so there is no conversion rule between pointers of one type to
values of another type or pointers of one type and pointers of other types.

(Refer Slide Time: 10:23)

424
So, we have the address of operator and we also have the dereferencing operator and the
dereferencing operator is *, so again they should not be confused with multiplication. So, if v
contains the address of p, then we can get to p by writing *p, so here is an example, so int *v
declares v to be a variable of type address of int, then int p says p is just a variable of type int,
then we can write the assignment v=&p, so v now contains the address of p. And, now, if I
write *v, so * is the dereferencing operator. What that says is this entire expression should be
thought of as referring to the variable whose address is contained in p, well so which
variables address contained in p? p itself, in v the address of p and therefore, star v should be
thought of as p and therefore, this entire statement should be thought of as p is equal to 10.

So these stars and ands are really very simple, very straight forward, but they are not the
same, they are, in fact, inverses of each other. So, one says, so and says give me the address
of this variable, * says give me the variable whose address is in this variable, so and p is the
variable of p and *v is the variable whose address is in v. So, this gives us a slightly different
way of thinking about the definition of v, so the definition of v is in *v. So, sometime ago we
said that we can think of this definition as v is an address of an int, so this is what we said
earlier, the second line, v is an address of int because we think of int * as an atomic term and
int * we think of as an address of int, so here we are declaring v to be address of int. But there
is a different way of thinking about this as well which says that, “This is not really a
declaration of v directly, it is a declaration of what is contained in v.” So, what is contained in
v? ints and therefore, v is of type address of int, perhaps the more accurate way of viewing
this is that this is a declaration of *v or whatever is contain inside v. So, sometimes this view
is little bit more important and we will see a use for that, but both are sort of good but this

425
view that, the first view written over here is slightly better for a reason. So, now we are going
to see a use of pointers when we write functions.

(Refer Slide Time: 14:00)

So we are going to write the function which converts Cartesian to polar, so it is going to
receive the Cartesian coordinates by value in this parameters x and y, but in addition it is
going to have two parameters pr and ptheta so pr has type double * or it is an address of
double value and similarly, ptheta is the address of a double value. So, let me just write down
the function first and then I will explain.

So, what happens over here, so the main program contains the statement which has address of
r being passed and address of theta also being passed, so what is this? So, first of all C++
requires that whatever type you have over here had better match the type of the parameter
over here, so what is the type of this parameter pr? So, it address of double, so that is what
this double stars say that pr has type address of double. And this, in fact, is address of double,
so this type matches, this says ptheta is address of double and, in fact, and theta is the address
of theta which is a double variable, so the pointers are the types of the arguments are
matching. So, what happens, so the types are matching, so the call will copy the values 1 into
x and 1 into y but it will copy the address of r into pr and address of theta into ptheta. So, now
something interesting has happened, CtoP which is executing in its own activation frame has
received addresses of variables defined in some other activation frame, in the activation
frame associated with the main program. So, when I execute this what is going to happen,
what does this mean? The rule is as before, so *pr means that variable whose address is in pr.

426
Now, when this when I do this, this variable is not living in the activation frame of C to P, but
I have its address and I can dereference, I can use the dereferencing operator and therefore,
this entire expression really now will mean the r variable which is appearing in the main
program in the activation frame of the main program, so it will refer to this variable. So
whatever value we calculate over here will get stored, actually stored in this variable of the
main program.

Similarly, ptheta is the address of some variable well it’s the address of this variable theta
because that is what we passed over here and when we do star of ptheta this expression is the
same as this variable and therefore, atan2 of x, y is going to get stored in this variable theta.
So, as a result, so in this case 1, 1 so square root of two in the in r because of this statement
and atan2 is going to be placed in theta because of the statement. So, when the call finishes
what you are going to get is one is going to get square root 2 over here and pi by 4 over here
or 45 degrees over here, as we got when we used references parameters. So, again CtoP is
going to change the variables of the main program but the mechanism is slightly different
here we have been we have send them the address and there we sort of say that look you treat
your r and theta to mean my variables. Where as over here we have actually send then the
address, it like saying to somebody look I am not going to send you the value, I am not going
to send you the money, I am going to send you the address of the bank from where you can
get the money or you can, I am going to send you the address of the bank where you can
deposit the money, so that is what is happening in this function and that is what pointers
enable you to do. So this will exactly do what we wanted.

(Refer Slide Time: 19:20)

427
So there is a remark to be made which is that star in definitions has a slightly unexpected
behaviour, so the star actually associates to the right, so suppose a right int *v, p and inclined
to read this as that the star sort of I read it as int * and then v is int * and p is also int *. That
could be one way C++ could have define this but that is not C++ ha defined it and the
definition that C++ has is perhaps slightly unfortunate but it is there. So what is the
definition? So it says that we think of this as is the type of the variable which are contained in
v, not the values that are contained in the v but is the type of the variable that contained in v,
so basically it does say that v contains addresses of int variables but it is saying that in a
roundabout way. So int is, this whole thing is an int and similarly when I write this, this p is
an int, so this means int *v and int p, not int *v and int *p because this star sort of binds to v
and not to int. And for now assume that the only operation you can perform on a variables of
type T * or an address of something are that we can dereference it, so I can write *v if I have
a variable of type address of int, or I can store into it a value address of v. So, you an example
of this earlier.

(Refer Slide Time: 21:46)

So, I can have int *v and int p and I can say v=&p, so this is a variable of type int star and
what I can do with it is, I can store a value into it which is address of some int variable, so
this is what I can so with it or I can say cout<<*v or I can say *v++, what would this do? If v
has being said to be address of p this is going to be the same thing as p++.

I can so one more thing, I might have int *w in addition to int *v, so in that case I can write w
is equal to v, so whatever variable address was in v now is also stored in w. So this is

428
completely consistent but you may find it unusual, simply because you are not accustomed to
dealing with pointers and addresses and dereferencing addresses. But think of it one line at a
time and it should be quite clear to you, so look at every expression, look at what the
definition that is and if you do this a few times it will be became second nature.

(Refer Slide Time: 23:39)

You can pass it to a function as an argument provide the corresponding parameter is of the
right type that T *, so if you have a variable of T *, then you can pass it as a parameter to a
function in which as an argument to a function if the corresponding parameter is of type T *.

(Refer Slide Time: 24:05)

429
So, now here are some exercises for you. You have to point out the errors in this code and
you are also to tell what gets printed as a result of executing this code. So what did we
discuss in this segment?

(Refer Slide Time: 24:21)

So we said that a pointer is an address or a variable containing an address. A pointer to a


variable can be created in the main program and dereferenced during a function call. So, this
way a function can be allowed to modify variables in the main program, or the variables in
other function as well however, wherever we create the pointers and if we pass it, pass to
other functions.

Pointers in some sense are doing the same thing as references, but the notation is slightly
more means is clumsier in the sense you have to explicitly say that now dereference it,
whereas in the case of a reference you declared at the beginning that ‘Oh this name is just
going to be in this other name,’ whereas here the name does not really mean the other name,
this name is means the address of this name and then you have to say that, “Ok, I want to get
to the name, the variable itself whose address I have and therefore, you have to use that
dereferencing operator.”

So, pointers can do what references can do, but they can do other thing as well and we will
see all of that later. So, we will take a break here.

430
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 10 (Part-5)
Functions Graphics Objects and Lectures conclusion
In the last segment we talked about pointers. In the next segment we will conclude this
general discussion of functions, the basics of functions, but before that I want to say
something about functions and graphics objects.

(Refer Slide Time: 0:38)

So here, I have a program in which I am using graphics and I am using a canvas on which I
have rectangle created and then and calling that rectangle using a function Rev360 using this
rectangle r, passing this rectangle r as an argument. So, I can do this and I want to explain
how all this executes, ok. So, you can pass graphics objects to functions as happened over
here. Now, a parameter must have the same type that is the same, it must be the same shape.
So, indeed this r is a rectangle and, in fact, this r is also a rectangle. But not only is it a
rectangle, but it is a reference parameter so that means this r will really be the same as this
graphical object. So, whenever I referring to r in this body it will refer to the same graphical
object that I had created in my main program. If I had not put this & over here than the usual
rules apply, what are the usual rules? Whatever argument is this argument its value is copied
into this.

431
So, at this point I want to tell you that when I talk about a graphics object. So say something
like this r over here, this r is really doing some kind of double duty. So, nominally it is
actually a variable also. So, it is a variable created in the activation frame of the main
program, and it is actually the variable which contains all the information about that
rectangle. I am not going to tell you what information it contains but just assume that it
contains whatever information there is.

So, whatever information is needed to say draw it on the screen, so in some sense the drawing
on the screen is kind of a by-product, so we are really creating a variable, when we write this
we are creating something on the screen but we are also creating a variable. So that variable
gets passed over here, but it is passed by reference, so really this r refers to the same
graphical object on our screen. If, I passed it by value or if I did not have that and over here
what would happen is, that a copy would get passed. So not only would the variable be
copied but the way this graphic system has been designed, the graphical object will also be
copied, when that copy is made initially the object will be at the same position as the object
from which the copy has been made, but you would get a new copy. But that is not what is
happening over here right now. we are getting, we are really passing the object by reference
and therefore, this r is really the same as this rectangle over here.

(Refer Slide Time: 4:25)

So, what is this going to do, it is going to repeat but it going to rotate by 10 degrees, so then it
is going to be imprint, so it will rotate and at every point it will imprint so what will happen

432
is, you will see a rectangle first, but it is going to be it will rotate and as it rotates it will
imprint. So all these rotated positions imprinted on the screen, and so on.

(Refer Slide Time: 4:47)

But at the end the rotation, the total rotation is 360 degrees because 36 times and every time
we are rotating by 10 degrees, so at the end of original position will be attained. So it starts
off in some position and at the end the same it will come back to the same position. But as it
does that it will be imprinting, it will be imprinting on the screen. Now, the point is that the
imprinting of the screen is going to survive. So even after, even after it returns the imprinting
will stay there, alright. So, we said this if you pass by value a copy is of the variable is made
and the copy of the graphic object is also made and I should say that as well, that if you made
a copy of the variable and a copy of the graphics object, the variable as well as the graphics,
the graphics object would get destroyed when you returned. Whereas in this case there is no
destruction, so that r of the main program is going to stay around and that is the r that is going
to get used up over here.

If you imprint that imprint happens on the screen and it will survive after the call finishes.
And by the way I mean this copying business is allowed otherwise as well so I might as well
state that here. So, for example here, I have created the rectangle by defining r but I create
another rectangle s, and I say I want s to be exactly equal to r so I assign it. So, I can do that
as well, so really when I make this copy is really sort of like an assignment statement.
Anyway the point of this is that when I have graphics objects I can pass those graphics
objects, and I can do things with them if I want.

433
(Refer Slide Time: 6:43)

I would like you to think about a few exercises, so here is an exercise which might be quite
interesting, might be quite useful if you are going to design some bigger programs. So you
have to write a function which takes a rectangle and coordinates x, y as input and decides
whether the points x, y lies inside the rectangle. So, this might be used to say that ok I am
going to draw a rectangle on the screen and then I am going to do a get click, and I would like
to know whether the user clicked inside that rectangle. So this function would come in handy.
Now, you would have to pass that rectangle to our function and inside the function you want
to get information about that rectangle and compare that with the x, y arguments that are also
being passed. So, if you do R.getX() then you will get the x coordinate of the center of the
rectangle, if you do R.getY() you get y coordinate of the center of the rectangle, if you do
R.getWidth() you would get the width of the rectangle.

So, now you could see that by getting the width and the height and the x, y coordinates you
can check whether the point x, y the x, y coordinates that have been given to you, for the
point which lies inside the rectangle. So, this way you can see whether the user is clicking on
a rectangle and if the user is clicking on a rectangle, may you could write a program which
changes the colour of the rectangle, colour of that rectangle if the user clicks on it. So this
could be a fun program, alright. So, as I said I am going to conclude in this segment but the
conclusion is for the entire sequence of this lecture, so this basic lecture about functions.

(Refer Slide Time: 8:35)

434
So, what did you say, we said that if you are find that you are performing the same operation
at several places in your program, then consider putting it into a function, and do not
duplicate code but make a call. You can think of a function as a contract that we talked about
earlier but you can also think of it as a packaged software component, so just as you buy
packaged hardware components. So anything that you buy practically is a packaged hardware
components say you buy a television you do not know what is going on inside it, or if you
buy a refrigerator you do not know what is going on inside it.

You are told, you are given some specifications and that exactly is how you should view
functions, so its, its package packaged and its specification are told to you but you really do
not need to look inside to see how that whole things actually works. You can just believe the
specification you are expected to believe the specifications and if that does not work then you
can of course sue the manufacturer or warranty period you can get things replaced, but that is
what really all this is.

So, the function the packaged component idea is sort of like the contract idea that we talked
about earlier. Then, we said that arguments can be passed by value, and here if the
corresponding parameter is modified in the function no direct effect happens in the calling
program. Arguments can be passed by reference, in which case if corresponding parameter is
modified in the function, a variable, the variable in the calling program will change.
Argument if the argument is a pointer to a variable in the calling function, then the code in
the calling function can access the variable by dereferencing the pointer.

435
(Refer Slide Time: 10:32)

Now, there are lots something that you can do with functions, so for example, you can write a
function that draws an n sided regular polygon such that each side has side length s, and
returns the parameter of n times s as the result. Or you can write a function which that returns
the cube root of a number using Newton’s method. So, really all the algorithms, all the
methods that we discussed in an earlier week, you can package it as functions, and then you
can just make calls so you do not have to copy code any longer.

And there are other similar exercises given at the end of chapter 9 and I definitely suggest
that you try them, so that concludes this basic lecture on functions and will stop here, thank
you.

436
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 11 Part - 1
Recursion
Introduction
Hello, and welcome to the course on An Introduction to Programming through C++. The topic
for today's lecture sequence is recursive functions and the reading for this is chapter 10 of the
text.

(Refer Slide Time: 0:33)

So, to introduce the topic of recursion, let me observe that many physical and abstract objects
have the following interesting property - the object has parts, which are similar to the object
itself. So, the natural question is, what role is this similarity going to play in the computation and
that is where recursion comes in. So, such objects said to be recursive or said to possess
recursive structure.

Now, one such object could be computation itself. Computation may also possess recursive
structure. And in fact, you have seen an example of this already. While computing the GCD of M
and N, we said that we really should compute the GCD of N and M mod N. So, it might seem
that a function that finds that you GCD of M and N should call itself with arguments, N and M
mod N.

437
It turns out that this idea works beautifully and such recursive functions are extremely useful.
Recursive functions are also useful for processing recursive objects. And in this lecture
sequence, we are going to see all of these things.

(Refer Slide Time: 2:04)

So, let me remind you of Euclid's theorem on GCD, which we used earlier. So, the theorem says,
If M mod N is equal to 0, then GCD of M and N should be N, as N. Else, the GCD of M and N is
the GCD of N and M mod N. If you look at this theorem, it almost looks like a program, it looks
like an if and else statement and nothing more. So, you might think could we perhaps write it like
that? So, int GCD M N, and inside that the computation that you perform is if M mod N equal to
0, then return N because in this case the theorem says the GCD is N, otherwise, we return the
GCD of N and M mod N. That is it. So, this seems like a, like a reflection of the theorem and a
really compact program. The question is, will it work? It looks too good to be true perhaps.

438
(Refer Slide Time: 3:20)

Ok, so, let us see, let us let us use the rules that we have mentioned for how functions execute
and let us see what will happen if we try to execute this function. And so, I have the function on
the left hand side and the main program on the right hand side. And the main program is doing
nothing much, it is just invoking the function with arguments 205 and 123 and printing out the
result.

So, when this program executes, so, of course, first the main program starts executing and for
that, the activation frame is created for main program. Now, when the main program encounters
the GCD statement, the GCD call, then you know that the main program suspends and we create
an activation frame for GCD. So, this activation frame will get created.

So, GCD will now start executing with M equals 205 and N equals 123. So, when it executes M
mod N will not be equal to 0. So therefore, it will go to the else part and it will return the GCD of
N which is now 123 and M mod N, which is 82. So, that will create another activation frame. So,
another call, so another activation frame, and then the first call is going to suspend.

So, after that, the second call is to start executing and this time M has the value 123 and N has
the value 82. So, again in the first step of execution M mod N will not be equal to 0. So, the else
statement will be executed. In this case, we are going to return the GCD of N which now is 82,
and M mod N which is 123 mod 82 which is 41. So, we require that the GCD of 82 and be 41
returned.

439
So, this will naturally require this call to suspend and a new call and a new activation frame to be
created. So, this is it. So, now we have an activation frame of the GCD called with arguments 82
and 41. So note that at this point, we have actually 4 activation frames in memory. So, the main
program had suspended and therefore its activation frame is present the GCD the first call has
suspended so its activation frame is present, the second GCD call has suspended so its activation
frame is also present and the last GCD call that we are currently executing, is executing. So, it
also needs an activation frame. So, this GCD calls has arguments at 82 and 41. So, when we now
try to execute this call, so, M has value 82, N has value 41. So, this time M is a multiple of N, 82
is just twice a 41. So, this expression will turn out to be 0 and therefore, we will return N. So,
this call is going to return 41 so, that 41 will be sent back. So, the 41 will be sent back and we
come back to the activation frame of GCD 123, 82.

(Refer Slide Time: 7:10)

So remember, this call had been waiting to receive a value from so that it can return whatever
value it receives back to its caller. So it has received the value 41 so it can return 41 back to its
caller, but of course before that the activation frame of 82, 41 will disappear. And now this, this
call will return when 123, 82 and that will activate the very first call we made. So, this call will
get activated because it has received the value.

440
(Refer Slide Time: 7:51)

But and it will attempt to pass this value back. But of course before this, this activation frame
will go away. And then M mod N, we will this last this very first call actually will pass the value
it receives from the call that it made, it will be passed back to main. So main will have finally
received the value that it wanted over here.

(Refer Slide Time: 8:14)

And then this activation frame will go away and main will actually do the printing. And so, it
will turn 41. And as you can see 41 is indeed the greatest common divisor of 205 and 123. And
so all this seems to have worked quite well. And indeed it does, we will see in little bit more

441
detail why it does? And it is actually quite similar, the execution it actually turns out to be quite
similar to the execution of the program, the non recursive program that you wrote earlier.

(Refer Slide Time: 9:01)

So, let us take a demo of this just to make just to see that this actually runs and get a little bit
more comfort with this. So, this program is the same as the program that you saw except for a
few minor changes. So, first of all, just to just to let us see what is going on I have put out this
print statement at the very beginning of GCD. So, so, before the GCD executes, it will tell us
what arguments it has received. So, that is what this print statement is doing. Next at the end,
before GCD exits, I would like to print out what value it is going to return. So therefore, I have
created a variable result into which the result to be return is first put in, ok. So, if an M mod N is
equal to 0, then we put n into result, otherwise, we make the call GCD and the result of that is
put into result. So this execution is really the same as the execution that we had on the slides,
except that we are able to print some messages and to print those messages we are having one
extra variable. So after the result is put over here we print out what is return and then we return
the result.

Similarly, from the main program, we want we are printing a little bit more descriptive message
so that we can get, get to know what result was actually returned. So, we print out this message
and print out the result and even for this the GCD is not directly printed, but we first put it inside
a result variable.

442
(Refer Slide Time: 10:42)

So, let us compile this and execute this. So, I hit ./a.out and this is what happens. So, what has
happened? The first call was indeed as we expected, it was executing GCD with arguments 205,
123. After that, the second call was made when 123, 82, after that the 82, 41 call was made, this
is exactly what happened on the slide as we saw, then the last call that was made, returned and it
returned the result 41 then the call before that returned and that returned the result 41 and then
the call before that returned and again the result that was returned was the same and this is the
print statement that we put in, in the main program. So, the main program also receives the value
and that value is indeed 41 and so, everything is fine, ok.

443
(Refer Slide Time: 11:53)

So, what have we seen here? Well, we have seen the recursion and let me just define it so to say.
So, recursion is simply the phenomena of a function calling itself. Now, it might seem like we
are defining the function in terms of itself and that is not a good idea. So, if we are defining a
term then we should define the term using some other terms.

But here, that is not a problem actually. So, there is no circularity in this definition. Because
when we make the new call, the arguments to it are different from the arguments in the original
call, ok. Now, further, yeah, so, so, (that is not) there is no circularity over there. And a new call
is going to execute in its own activation frame. So, we have also seen that, and we have also
seen, and, and I guess, I should point out over here, that this process can go on indefinitely if you
are not careful and that will, that is what might happen. If the arguments to the new call, for
example, are the same as the arguments to an old call, because then they exactly the old
execution will happen. So, we do not want that to happen.

So, we wanted, we want to make sure that some execution, some call must return without any
recursive call. And if you remember, that did happen in our execution. And if that if that does not
happen, then we have a problem because there is infinite recursion.

Now, in this example, in this GCD example, in the body of GCD, there was just one recursive
call. We can have several recursive calls if we wish, and in fact, we will see an example very
soon.

444
(Refer Slide Time: 14:00)

Before we go to more examples, I just want to observe I just want to compare how the recursive
and non recursive versions of GCD work. So, first, this green portion is the recursive GCD and
red portion is the non-recursive GCD that you saw some time ago in the in the last lecture. So
now, let me first mention that if we look at the recursive calls in GCD the so we were calling this
with GCD of 205, 123, then that call made a recursive call GCD 123, 82 that made a recursive
call at 82, 41 and then that returned. Now, let us see what are the computations that happen in the
non-recursive function. So, here we are going to look at what values M and N take in
consecutive iterations of the call to GCD of 205, 123. So the first time around, when we call
GCD with 205, 123 M and N will take values 205 and 123. Now, some iteration will this
iteration will take place and as a result of it M and N will change. And you will see that in the
next iteration the values are 123, 82. And in the iteration after that the values are 82 and 41. And
after that, the answer 41 will be returned.

So, if you notice the M and N, which were the arguments over here, really are taking the same
values as the variable variables M and N over here. So, in a sense, the recursive and non-
recursive GCDs are really doing the same computation. So, so, in a sense we really do not need
to worry about is this going to be correct. So, so, long as we can actually establish
correspondence and we can establish that correspondence, then we will know that the recursive
GCD should also work. So, so, that is certainly that is certainly a reassuring fact over here.

445
However, I should point out that for every recursive function there need not be a natural non
recursive function that does the same thing. So, the question of how, how to think about
recursion and how to argue that recursive functions are correct, it is still there, but here for this
GCD you can sort of see that it really the execution of the recursive function really mirrors the
execution of the non recursive function.

And but, the point to note is that on the surface they look very different, the non recursive
function is a bit longer and somehow it seems to be doing a lot more stuff.

(Refer Slide Time: 17:09)

So it should, it should be observed that recursion often produces compact and rather elegant
programs, elegant because the program is sort of following the main theorem that is the basis of
that function. Now, I should also point out that recursive programs might be slightly slower,
because they need to create the activation frame and destroy the activation frame, which the
iterative or the non recursive programs do not have to do.

The exciting point about recursion and we will see this in a later lecture is that recursion is also a
way to discover algorithms. And you may say that Euclid quite possibly did this, possibly he
thought something like the following. “Instead of doing laborious computation to find the GCD
of 205 and 123, can I find two smaller numbers whose GCD is the same as that of 205 and 123?”
This is exactly recursion, this is recursive thinking and it is quite common in mathematics and
therefore, and it is certainly a powerful tool in designing algorithms.

446
And we are going to see more examples of recursion in this lecture sequence as well as in
subsequently lecture sequences.

(Refer Slide Time: 18:47)

So, here is an exercise it asks you to write a recursive program and you are supposed to consider
our GCD program and sort of follow it but for this new function that has to be for which the
program has to be written.

(Refer Slide Time: 19:05)

So, what did we discuss? So, he said that recursion is a function calling itself during execution.
When we said that recursive function we found we saw a recursive function to find the GCD.

447
Then we made a comparison between the recursive and non-recursive GCD functions and we
saw that recursive GCD is more compact and elegant even though both of them are doing the
same computations. Next, we are going to talk about recursive objects, but let us take a break.

448
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 11 Part - 2
Recursion
Recursive objects, Tree Drawing
(Refer Slide Time: 0:36)

Welcome back, in the previous segment we defined recursion and we saw an example of it. In
this segment we are going to look at recursive objects. So I am going to give you some examples
of recursive objects and then also an example of processing recursive objects using a recursive
function.

449
(Refer Slide Time: 0:40)

So, here is a picture of what is often called an organization tree. It is called a tree because you
can think of this as the root and then these are the branches. And so here, the tree sort of is
growing downwards, but that is ok. So, the important point is that there is something that this is
sort of the, the original the root or the original trunk or whatever and then there are these
branches coming out coming out of it.

Now, an organization which is represented by this tree, can somehow be thought of as a


recursive object. Why? Because this part or this division of that organization is itself a mini
organization and in this sense it confirms to what we said earlier that a part of the object is like
the object itself. And even here, this is kind of a mini organization.

450
(Refer Slide Time: 1:50)

Here is another example. We have an arithmetic expression written down over here, ok. So, this
expression can also be represented by this tree like diagram, so let me tell you what this diagram
means. So over here, these boxes are representing just the numbers 57 and 123. So, these two
numbers. Now these numbers feed into this box, which is a multiplier box. So, this box takes the
numbers that it receives computers their products and sends them off to the output that it has
upwards over here.

This box receives 329 from this box and the product over here. So, this is exactly like this plus,
this plus and plus are really doing the same duty. So, this plus says that add up whatever values
are being received and send them off to the top star, which is the star over here, and this star also
receives values from the side. So, these values are 358 divided by 32. So, this operator is
represented by this box and the quotient will be sent off to the side and finally the product will be
sent off from this route.

So, this expression is also a tree like but it also has parts which are similar to itself. So for
example, this portion is another small expression or a sub expression. So again, the entire object,
which is this big expression is made up of parts, which are of the same kind, so, which are also
expressions.

451
(Refer Slide Time: 3:42)

Here is a physical object which is which also has this property. So, this is a tree and this has been
drawn by using the turtle. So therefore, you see this triangle the turtle over here but, never mind,
do not worry about that right now. So, what does, so, what are the parts of this tree? So, first of
all, there is this part, which is the trunk, ok? But, then if you look at this side, this portion is itself
a tree. Ok, it is a small tree, but it really can be thought of as a tree. And on this side, there is
another portion. And in this case, this portion really happens to be identical to this, this is sort of
just a rotated version of this. But in any case, this is another portion, which is a part of this big
tree, but which is also like a tree.

So indeed, this big tree is an object which has parts which are smaller trees. And in that sense,
this big tree is a recursive object. Just like expressions were recursive objects and organizations
were also recursive objects. Now, we will have occasion to process recursive objects on a
computer. In fact, we want to process everything. So certainly recursive objects. And the natural
strategy to process recursive objects turns out to be the following.

452
(Refer Slide Time: 5:12)

So the processing, the entire object is the same as processing all parts. And how do we process
the parts? So, we are going to use a recursive call if the part is similar to the entire object. So, if
it is just a smaller version of the entire object, we do not need to write new code, but we can use
the code that we were writing for the bigger object itself, ok. And in fact, this is exactly what
happened when we wrote the code for GCD.

So, if you want to process organizations, or mathematical expressions, you really must
understand recursion. And recursion indeed is sort of one of the cornerstones of computer
science. The other, the other cornerstone is iteration in some sense, and iteration and recursion
together could be said to be sort of 2 really major ideas in computer programming and also in
computer science.

So, what we are going to do next is we are going to draw a recursive object on the screen. So,
this is going to be an example of processing recursive objects. So, it is kind of a nice fun
example, but it will contain all the elements, the major element that we want, that when we want
to process the parts, we just have to make a recursive call. So, what are we going to draw?

453
(Refer Slide Time: 7:00)

So, here is a picture and this is a picture of a very stylized tree, you can think of it as a tree, that
perhaps somebody who does modern art might draw. It is actually very pretty. And you might
think that maybe, maybe there are some, actually there are some bushes that grow in Africa,
which look like this. But anyway, this is what we want drawn. And you can see that this does
have recursive structure, ok.

(Refer Slide Time: 7:34)

So, this big tree is really made up of two small trees, and I am calling this stylized tree because
maybe some of you might think that oh, this does not look like a tree. So let us call it a stylized

454
tree. So this part, this covered with this blue rectangle is a small stylized tree. And on this side,
we have another small stylized tree, and together they make up a big stylized tree, but of course
we have to have this bottom portion, which is which I am calling it calling a V over here. So
there is a V and then there are two small stylized trees which make up this big stylized tree.

What are its parts? Well there is the root. So by root, I mean this point over here. So, we are not
really going to be drawing points, but you might as well note that that point is sort of present.
Then there is the left branch and then there is the left subtree. So this is the left branch and this
top thing over here over here is the left subtree. And similarly, there is a right branch and then
there is the right subtree.

Now, we need to have a definition, which is that of the number of levels. So we define the
number of levels to be the number of times the tree has branched going from the root to the top.
So the top is also often called leaf in a metaphorical sense, I mean the bottom is root and the top
is a leaf. So this tree, how many times has it branched?

Well it has branched over here, it has branched over here, it has branched at this level, it has
branched at this level, it has branched at this level. So, there are 5 levels at which it has branched
or this tree, we will say has 5 levels.

(Refer Slide Time: 9:32)

455
Alright, so we can now think about drawing the tree so the tree could be drawn using turtle, but
we are going to try it using coordinate based graphics. So, how are we going to try it? Well, so if
we are going to draw an L level tree, ok if L is equal to 0, so it is just the route, then we are really
not going to do anything, I mean we could put down the point, but we will just be sloppy and not
even put down a point.

So, if L is greater than 0 then we have to do something. So, what is it that we have to do? So,
well we are going to draw this left branch, ok then we are going to draw this tree on top of it, but
this time the number of levels in it has reduced because we have used up one level of branching
over here. So, we are going to draw a level L minus 1 tree on top of it. Then we are going to
draw the right branch which is this branch and then draw an L minus 1 level tree on top of it. So,
that is this tree portion. So, that is basically it. But of course, in order to draw we need the
coordinates. And so when he say draw, we need to specify the coordinates, we need to tell our
program where we want the tree drawn. So maybe we will one of the arguments could be RX
and RY which define the point at which the root is supposed to be drawn. So, the root we are
going to tell our function that it has to be drawn at RX, RY, ok. Then we also should tell our
function what is the total height of the drawing. So by height I mean this entire the extent the this
extent. So, let us say we tell that and we use the name H for it. Similarly, we tell that the width is
W.

Now, we have told our function that the root must be present over here and the width must be W
and the height must be H. So, we have done our job in the sense of specifying the region in
which the tree should be drawn. Well, we will make some ad hoc decisions say that the levels in
this picture are equally spaced. So once we say that we have we have done our job.

Now, the recursive call must figure out where the smaller trees should be placed. So, when it
when the recursive call is made, it should be made with the proper height and width and also the
proper route positions. So, we need some calculation of these coordinates and we are going to
see this next.

456
(Refer Slide Time: 12:36)

So this is what we said was the requirement for drawing the big tree. So we are given RX, RY.
We are given W and we are given H. What we want to know? We want to know the position of
this root because then we could, we could issue the command for the smaller tree to be drawn
and also we could issue the command for drawing this branch. Similarly, we need the position of
this root and we need the height and width of the smaller trees, ok. So, let us try to work it out.

So this distance, this is going to be the y coordinate this level is the same as the level of the y
coordinate of the roots, ok. So we said that the levels are going to be equally spaced, so the entire
distance is H and therefore, this height is going to be H upon L. Then this is the route and its x
position is going to be half day of this, ok. So, what is it going to be?

So this distance from here to here is RX, let us say, ok, and this entire distance is half of the W
and therefore, this distance is W by 4. And the y coordinate of this point is RY minus H upon L,
why minus? Because if you remember the coordinates y coordinate goes downwards. So we are
going back a distance (HY) H by L. So, we have figured out what the coordinates of this position
are going to be.

So now we can instruct our recursive call as to where its root has to be drawn. What are going to
be the coordinates of this? So well, that is easy. So, instead of going back W by 4, we have to go
forward W by 4and therefore, the x coordinate is RX plus W by 4, the y coordinate is the same

457
RY minus H by L. So all that remains now is to say how much the height and the width are going
to be the of the small trees.

So, the height of the sub tree is going to be this entire portion so going from here to here. So, we
just have to subtract H by L from it, ok? So, it is going to be H minus H by L and the width is
going to be just half the width. So, this is going to be W by 2. So, we are more or less done, ok.
So, we just have to write the program now, but we know all the coordinates. So, one more point
we need to draw the branches. So the branches should go from this point to this point. So we
know that those coordinates as well. So basically, we have we have done that we have we are
done with the calculations.

(Refer Slide Time: 15:38)

Ok, so here is what the program looks like. We have, we will call this function tree. It is not
going to return anything, but it is just going to draw, ok. And its first, the first argument to it or
the first parameter of this function is going to be L, the number of levels. It is going to have as
parameters RX, and RY which are the positions of the roots and the height and width of the
region in which the tree has to be drawn. So, let me just write down sort of the main, the, the,
some explanation about what these arguments are, L is the number of levels, the root is at RX,
RY and the height is H and the width is W, ok?

Now, this code is pretty much like what we had written in the slide earlier, if L is equal to 0,
nothing is to be done. If L is greater than 0, then we are going to draw a line which represents the

458
left branch, and it is going to start at the root and it is going to go to the root of the sub tree. So
these are the positions of the x and y coordinates of the root of the sub tree the left sub tree, then
the right branches are we are going to start at the root of the main tree. And it is going to go to
the root of the left the right sub tree. And as you if you remember from last, the last slide, these
are exactly those coordinates.

Now, these left and right, the left and right branches are created locally inside, inside this inside
this call, ok? And they are going to go away once we exit. So, if we want the tree picture to
survive, we have to imprint them. So that is what we are doing. We are doing over here, we are
imprinting the left and right branches.

And then we are going to draw the sub trees, so this, the left sub tree is being drawn over here. It
is going to have L-1 levels. These are going to be the coordinates of where the route is going to
be located. This is going to be the height of the sub tree and this is going to be the width of the
sub tree. Similarly, we will draw the right sub tree. The only difference is that the x coordinate
will be further to the right, that is it. And I can have a main program which does this. And in fact,
this will end up drawing the entire thing.

(Refer Slide Time: 18:28)

Ok, so at this point, let me stop and this is the exercise that you are supposed to do. But let me
stop for a second over here and let us actually draw this tree. So now we are going to see a demo
of this. So, let me get out of the presentation.

459
(Refer Slide Time: 18:52)

And here, I have the program typed in, there are a few small changes. So, the program is the
same except that after during each line I am putting a wait statement, because if I do not put
these wait statements, then the drawing will happen very fast. And you will not see the order in
which things are getting drawn. So, it is the order in which things are getting drawn is actually
quite interesting. And finally, I also put in a get click statement, so that the program does not
execute and remove the picture immediately.

(Refer Slide Time: 19:26)

460
So, let us compile this. And let us run it. So as you can see, the left branches are drawn first, then
the left sub tree is drawn, then the right sub tree is drawn. And you might notice that even within
each sub tree, the left part is drawn first, and then the right part. So, this is in fact, exactly the
way the program is written. So, in the program, we first draw the left and right branches, then we
draw the left and right sub trees.

So, if you are worried about recursion, if you feel that you do not understand how recursion
works, then this example is really nice because it is showing you exactly how recursion unfolds.
So, what executes first, what executes next, and how does it correspond to the way the program
is written.

461
(Refer Slide Time: 20:39)

So, then I am going to leave you with an exercise. So the exercise is also there in the book and
some more hints are given there. So you should certainly look at that. But, you are supposed to
draw the real tree, the botanical tree that I showed you earlier, and some ideas on how to draw it?
Well, break it up into parts. So say there might be the trunk, there might be the left sub tree and
right sub tree.

And this time it turns out it is convenient to try it using the turtle rather than using these
coordinate based graphics, so what you should do is, you should get turtle to first draw the tree
and on top of it, draw the left sub tree or somewhere attached to that. Ok, after the drawing is
finished, and this is the crucial part, you want the turtle to come back to the original position
because only then you can draw the next because if the turtle did not come back to the original
position, that is not good because you want it to be at a proper position. So that only then you
know where to move it, so as to get to the right position.

And then, if you observe that the structure of the tree you will see that the left and right sub trees
are not exactly the same. So, the right sub three is, first of all, it does not originate at the same
place and second it is rotated a little bit, ok. So, you will have to play around, you will have to
play around a little bit to get this. And a suggestion is that do not try to draw the whole thing at
once. But first draw a tree with small number of levels. So maybe just start with level equal to 1

462
and just see whether your program is trying just the trunk that should be easy, but then move on
to level 1, level 2 and so on.

(Refer Slide Time: 22:38)

Ok, so what did we discuss in this segment? So, we said that recursive objects have parts similar
to themselves. And we saw examples of many interesting objects which have this recursive
structure. Then we said that processing recursive objects requires recursive functions. And
drawing recursive objects is a good example of how you might process recursive objects.

But, later in this course and certainly in other courses, if you care to take them, there will be
there will be much more substantial processing of recursive objects that you will have occasion
to do. So, this is the end of the current segment. In the next segment, we are going to say a little
bit more about how we should be thinking about recursion. So, let us take a break.

463
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 11 Part - 3
Recursion
How to think about recursion

Welcome back, in the previous segment we discussed recursive objects. In particular we


discussed trees and how to draw them. And for this we used a recursive function. In this
segment, we want to say something about how to think about recursion. And after that we will
conclude this (segment of) sequence of segments.

(Refer Slide Time: 0:53)

How do you think about recursion? On the face of it recursive a program seems very complex
when it executes typically multiple calls are in progress. And how do we reason about all of
them? How do we even visualize what is going on? So the good news is that we do not need to
do any such visualization, there is a much more direct simple way of thinking about recursive
algorithms.

464
(Refer Slide Time: 1:20)

So, let me begin with some high level ideas. And let me first consider the case when you are
trying to design the recursive algorithm. Now, you may think that designing recursive algorithms
is tricky, and indeed Euclid's algorithm is pretty tricky. However, if you are dealing with
recursive objects, then recursive algorithms are quite natural. And you may well find yourself
designing such algorithms.

So, how do you do this? Well, you first attempt to solve the problem given to you by
constructing and solving a smaller problem of the same type or what you might more accurately
call a smaller instance of the same type. And I want to observe that this is exactly what we did
for GCD as well as for drawing. So, when we wanted to solve, when we wanted to find the GCD
of M and N we instead requested to find the GCD of N and M mod N and why did we do this?
Because, these numbers in fact smaller than the given numbers. So, in some sense, we are
reducing, we are simplifying the problem or we are reducing its size. So when I say size, I mean
it in a metaphorical sense. So, we are reducing its size in some sense.

Even in drawing, when we were when we were asked to draw a tree which had L levels, we
reduced it and we said oh let us first draw trees which have just L minus 1 levels. So, again this
is a simpler problem in the sense this is a smaller tree that we are going to draw, it has fewer
number of levels. So, if you can do this ok. So, if you can say that I want to solve this big
problem, but I want I can break it up into problems which are of the same type, but smaller in

465
some sense, then you have already, already taken the first solid step towards designing the
recursive algorithm. And then you should be able to solve the simplest instances directly. So, that
is the second step, ok. So, for example, in the case of GCD this was the simple instance if M was
divisible by N, then you can directly say that N is the GCD or in the case of drawing if you
wanted to draw a tree with 0 levels, then you can directly do it, well actually in this case, that is
nothing to be done. But that is trivially doing it.

Now, I want to say something about how do you think of a recursive algorithm that is given to
you by somebody? How do you understand it? So, the first step is sort of the analog of this step
over here. So, can you sort of interpret or is the designer telling you that look, this is the problem
size that is reducing in successive calls. So, that is the first question. And let me make this
discussion more precise. So, for the GCD, you can argue that this second argument is always
reducing, as you execute the program. It does not have to be the second argument. It could be
some complicated function of the arguments in general, but in this case it happens to be the
second argument. And for drawing, it is in fact the very first argument. So, here it was L then we
said that this tree could be drawn by drawing several trees with L minus 1 levels. So in fact, here
you have you can think of the second argument and the first argument as the problem size. So, if
I give you a recursive algorithm, then you should look for a problem size in it, something that is
reducing as you do the recursion. And then the question that you should ask is, will be eventually
get to problem sizes to problems that are solved without recursion?

466
(Refer Slide Time: 5:45)

All right, so now we are going to look at these things in a little bit more detail. And so, for that, I
will need some terminology. So I am going to define something called a top level recursive call.
So this is the call made from the main program or the first call made to the recursive function. So
again taking examples, for the case of GCD the top level call is the GCD of M, N or this is in
fact you can think of this as the call as identified by the signature of the function, and for the
drawing it is this call, so this would be the call that could be that in the signature of the function,
then there are other level one recursive call, so, these are the calls which are made directly while
executing the top level call. So for GCD the next call was GCD of N and M mod N. So this is the
level 1 recursive call for this top level call and for drawing, for drawing this tree, the recursive
call was this and also this, so these are the two level 1 recursive calls, ok. So, this is just notation
could define level 2 recursive calls in a similar manner, but I do not need to. So, the whole point
of this discussion is that we can just think about one level of recursion to understand what is
going on.

Then there is a notion of a base case. So, these are simply the input values for which the top level
call returns without recursing. So in the case of GCD if M and N are such that M is divided
perfectly by N then that is a base case, because in this case you can return N directly as your
GCD. So M, N such that M mod N is 0 are the base cases for the GCD, GCD function. Then for
drawing similarly, if L 0 then you are not going to recurse, you are just going to return in this

467
case without doing anything but that is that is how you that you are going to return. So L equal to
0 is the base case; L equal to 0 and other arguments, whatever they might be.

(Refer Slide Time: 8:07)

Some more terminology. So we have defined this earlier actually, but I am just going to restate it.
So for every for every problem for every call really, there is a notion of a precondition. So this
simply says what are valid values for the inputs. So in the case of GCD, the two arguments have
to be 0 only then this is a reasonable call, only then is the GCD define.

And similarly for drawing, the number of levels must be greater than or equal to 0. And the
height and the width have to be greater than 0, greater than or equal to 0. And RX and RY, the
coordinate where, the position where, the route is to be placed, well they could be negative, ok.
So, that might just force the drawing of the screen. Or if you want it inside a screen then you
should say ok I want I want the tree to be inside the screen. So, I will require these also to be
positive and in fact maybe smaller than the size the so, they should be smaller than the width of
the screen, they should be smaller than the height of the screen, ok. But we are just ignoring
those conditions for now.

Then, there is a problem size and we gave an example of this, but let me just say a little bit more.
So this is something which is indicative of the amount of work needed to find a solution. Or this
is something which suggests how difficult or how complex this problem is. So we said that the
number of levels is indicative of how difficult the problem is - the more the levels, the more

468
work period and similarly, for GCD the values of these numbers, the magnitude of these
numbers are indicative of the problem size, but more specifically, we looked at the second
argument this N. So, this we said was the problem it could be considered the problem size.

And they should be chosen creatively. And as I said, this is how you might choose. So there is
no, there is no obvious way of what, what it should be, but as a designer you would have to say
that look, I want to reduce this, because if I reduce this then I can I can recurse.

(Refer Slide Time: 10:30)

So now, I want to say what you need to do to verify that a given recursive function is a
reasonable function. So the first thing that you need to check is whether there are any base cases.
So if there are no bass cases, then clearly your program will not terminate and therefore, base
cases must be there. And then, for those bass cases, function must produce the correct results. So,
that is one check that you have to make. So, for the GCD, the base cases were values of M, N
such that M mod N equal to 0. So in this case, the answer was N, is that correct? Well, yes, if M
is divisible by N, then N must be the GCD. So, which is being returned and so the program is
working correctly for the base case base cases.

For drawing, the base case was L equal to 0 or maybe I should write L==0 over here. But in this
case, what did the program do? It did nothing, ok. Was that correct? Well, if the tree has 0 levels,
then it is an empty tree and so nothing should be drawn. So even here, for both of these

469
programs, this is how you would check that the bass cases that there are bass cases and they are
being correctly handled.

(Refer Slide Time: 12:02)

Then we turn our attention to the level 1 recursive call. So, first thing we should check is whether
they are valid? So, are the arguments in the level one calls valid? Or in other words, do they
satisfy the preconditions of the functions? So, in the GCD the top level call was GCD of M and
N and the level 1 call is GCD of N and M mod N. So, what are the preconditions here? So, we
require that the argument must be non-negative integers, so these must be non-negative integer.

So, can we argue that these are non-negative integers? Yes, N must be bigger than 0. Why?
Because N is an argument to the top level call also. And the top level call we are assuming
satisfies the preconditions. So assuming the top level calls satisfies the preconditions the level 1
call must satisfy the precondition. So, which is what we can argue over here. And what about the
second argument? Well, if you go back to the code you will see that this level 1 call is made only
if M mod N is bigger than 0, because if it is equal to 0 then we just return N, so only if M mod N
is bigger than 0, then we make this call and therefore, this argument must also be positive. So, in
other words, we have verified that the preconditions are correct.

What about drawing? The level 1 calls are these - so the original call, the top level call was had L
levels, here we have L minus 1 levels. So, are these are these arguments satisfying the
preconditions? Ok, well level one calls are made only if L greater than 0. So if L is greater than 0

470
than L minus 1 must clearly be greater than equal to 0 or in other words L must be bigger than or
equal to 1. So, so, this argument must also be bigger than 0. So, we have checked that this
argument must be bigger than or equal to 0 sorry, bigger than or equal to 0. And you can check
and I am not going to go through it right now, but you can check that these other arguments will
also satisfy the required preconditions.

(Refer Slide Time: 14:35)

Then, we come to the next check that you should make. So, the next check is that does the
problem size reduce and can it reduce indefinitely? If it cannot, if it can reduce indefinitely there
is a problem, if the problem size does not reduce there is a problem. So, the answer to this first
question should be yes, the problem size does reduce, but can you reduce indefinitely? No, it
should not, it should not be possible to reduce the problem size indefinitely.

Alright, so the GCD level 1 call is GCD N, M mod N and top level call was GCD M and N. And
we said that this second argument is the problem size So, second argument has reduced, why?
Because originally it was M, N so it was N and now it has become M mod N, and we said that
this was the problem size and M mod N is certainly smaller than N, so the second argument has
reduced. So, that is a good thing.

Now, can it reduce indefinitely? Well, the remainder has to stay above 0. So it means that it, it
cannot reduce indefinitely, ok. So this essentially saying that look, you cannot have unlimited
indefinite recursion, you cannot just have one call after another because in every call, this

471
argument is going to reduce. But if it reduces, then eventually it is going to go down to 0 which
is not possible. So, the answer to this question is indeed yes and no for GCD, so that is a good
sign.

Drawing: So, the level one calls are these ok. And we said that the first argument was the
problem size. So has that reduced over here? Well, in the original or in the top level call it was L
and it has become L minus 1. So it has indeed reduced, can it reduce indefinitely? Well, it cannot
become negative, because we are checking if L equal to 0 then we do not make a recursive call.

And so this cannot become negative. And therefore, again, we have checked that this function is
a good function. The problem size is reducing but it cannot reduce indefinitely.

(Refer Slide Time: 17:18)

The last requirement to check is will the top level calls returned the correct results if level 1 calls
do? So GCD, we know that the GCD of the arguments to the top level call M and N is the same
as the GCD of the top level calls to the level 1, the GCD of the, the level one recursive call
which are N and M mod N. So the GCD of the arguments to the level 1 recursive call is the same
as the GCD of the arguments to the top level call. And now what does the function do? So the
function is going to return the GCD N M mod N, ok, if it is, if it does this correctly, ok, then the
top level call will be correct. So, we are not checking whether it is going to correctly return this
but it is returning this, ok. If this is correct then this will also be correct because they are exactly
the same thing. So, we have checked this for GCD.

472
In the case of driving the level 1 calls ask for a small smaller trees to be two smaller trees to be
drawn. Ok. And we had to check that the two smaller trees are drawn in the right position. So,
what happened there? So yeah, so, so we asked we wanted to draw a level L tree and we said that
oh if you want to draw such a level L tree, then we can do that by doing by doing these small L
minus 1 level trees, ok. So, if those were correct, then our program or this, this function simply
drew the branches in the right position.

(Refer Slide Time: 19:22)

So, what it was doing was so, we wanted to draw a tree starting from this point. So it said look,
you first draw two smaller trees over here. And then in the top level call, you just do this we just
drew these branches. So, if these trees got drawn correctly, then we know that oh there, there are
just these two branches to be drawn and the top level call is drawing them correctly. So
therefore, the total thing must be correct.

(Refer Slide Time: 19:55)

473
Alright, so let me summarize this part. So how do we check if a recursive function is correct? So,
what should we check in order to do that? First we should check that there are base cases and
correct, correct results are obtained for the base cases, then we should check that the level 1
recursive calls satisfy the preconditions, then we should check that the problem size reduces, ok,
that there is such something called the problem size and that it reduces, but the code is such that
it will not it is it is not possible that it can reduce indefinitely. And finally, we should check that
if the level 1 calls work correctly, then the top level call will also work correctly that is it.

In particular, what is it that we do not need to argue? So, we do not need to argue explicitly that
the level 1 calls, in fact work correctly. Ok? We do not need to do this. We do not even need to
think of what the level 1 calls do. Are they going to make recursive calls? Are they just going to
return the result directly? We do not have to worry about it. So, basically what is going on is that
these first three points are ensuring for us that this computation is going to terminate eventually.

And this last point is going to say that look, if the recursive calls were correct, then we will
return the correct answer. Ok. And this really this whole thing together says that effectively, not
only does the top level recursive calls call works correctly, but it effectively proves that the level
1 call works correctly level 2 call works correctly, because this argument really is applicable to
all the calls, ok? And we do not really but we do not really have to worry about that we do not
have to think about all the calls, ok.

474
(Refer Slide Time: 22:15)

Alright, here is an exercise for you. So, I give you this function, and there are it has its
precondition and the post condition that is what it is supposed to be returning, ok. So, I want you
to tell me whether this function is correct, ok, or whether there is a problem over here. Now, you
should apply what we have discussed in this segment and tell me where things go wrong, ok.
This is a bit of a trick question. But the questions the strategy we decided enable you to say what
is wrong, to figure out something is wrong and say what is wrong.

475
(Refer Slide Time: 23:10)

That brings us to the end of this lecture segment as well as the sequence of segments. So, I want
to make some concluding remarks about recursion in general. First, I want to observe that
recursion allows many programs to be expressed very compactly. For example, GCD recursive
GCD is certainly more compact than iterative GCD. The idea, that the solution for large problem
or a problem whose problem size is large can be obtained from the solution of a similar problem,
a similar smaller problem of the same type. I should really have the word smaller problem here.
This idea is very powerful, ok, it is.

Euclid probably use this idea to discover his GCD algorithm. He probably did say it himself that
look, I want the GCD of these large numbers. Is it sufficient if I find the GCD of some smaller
numbers instead? But, the moment you take this single step you can, you are implicitly
developing a capability of applying it again and again. And that is exactly what recursion gives
you.

And recursion is also very natural, in fact, much easier to understand and much more natural,
much less clever for objects which have a recursive definition, say for example, trees. And here
we saw tree drawing as an example. To understand, why a recursive function works, we need to
make a few simple checks outlined earlier and I just want to observe that some programs can be
written recursively and iteratively.

476
So for example, GCD or the factorial, but some others are best written recursively. So for
example drawing trees, it will be pretty complicated to write this program using iteration or
rather I should say write this program without recursion. So, that concludes our discussion of
recursion. It concludes this sequence of segments. Thank you.

477
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 12 – Virahanka Numbers

(Refer Slide Time: 0:37)

Hello and welcome to the NPTEL course on An Introduction to Programming through C++. I am
Abhiram Ranade. The lecture of today is on Virahanka Numbers. Virahanka was an ancient
Indian prosodist from 6th or 8th century and prosodists are people who study patterns of rhythm
and sound in poetry. Virahanka asked a question about poetic meters and interestingly enough,
solved it using recursion. So that is what we are going to study today. So let me tell you a little
bit about today what a poetic meter is.

A poetic meter is characterized by the number of the number of syllables in the meter and the
duration of each syllable. So syllables have either a short duration or a long duration and a long
duration is just twice the short duration. So for example a poetic meter could be described by the
sequence of characters SLSSLS. So that means that there are 6 syllables and the total duration is
8, the additional two counts come from the two long durations.

478
(Refer Slide Time: 1:41)

So let me give you an example for a poetic meter and actual poetic meter, and here is a poetic
meter called Shardulvikridit. So this is used in many many poems and many many shlokas and
perhaps here is a familiar shloka that, that is in this meter. So I am going to I am going to sing
this shloka and you will note that some of the syllables are going to be short and some of the
syllables are going to be long and it is the long and short, the long and shortness of the syllables
which gives it, gives this shloka a certain character and that is what a poetic meter does.

So Ya kun den du tu shar haar dhawala yashubh ra vas tra vru ta. So as you can see the first Ya is
a long syllables, kun is a long syllable, den is a long syllable but then you sing Ya kun den du tu,
so du tu are short syllables. So over all there are 19 syllables and the total duration is 30 if you
count if you count it. So prosodists were concerned with such poetic meters and they ask
questions such as how many different poetic meters can there be and they sometimes even
wanted to enumerate the poetic meters.

479
(Refer Slide Time: 3:19)

So Virahanka’s question was how many poetic meters exist of total duration D? So let us try this
out, let us take a few simple cases. So if D is equal to 1, so you want a poetic meter of duration 1,
well you do not have a choice. The only poetic meter possible of duration 1 is sort of a very
trivial thing, a poetic meter which has just 1 short syllable.

If you go to duration 2, then the duration 2 can be made either by one long syllable or it can be
made by two short syllables. So at this point you have two possible meters. 3 if you work this out
if you try this out and if you try to do this exhaustively, what do you get? Well, you get that
duration 3 can be made up by three short syllables or a short and long or a long and a short. So
there are three poetic meters of total duration D. Then for D equal to 4 you may again work this
out, so there might be all four shorts or you might have SSL, SLS, LSS, or just two longs.

Now, you want to ask this question in general and so let us that V(D) denotes the number of
poetic meters of duration D and what we have worked out is that V of 1 is 1, V of 2 is 2, V of 3
is 3, and V of 4 is 5. Virahanka wondered whether there is an easy way to calculate V(D). So that
was his question and we are interested in this not because this is a course on poetry or prosody or
anything like that, but because this question has some interesting things to say about recursion.

480
(Refer Slide Time: 5:26)

Okay, so let me tell you Virahanka’s solution. So Virahanka observed that the first syllable of
every meter must be S or L. Of course, I mean there is nothing much over here but that is that is
just the first step. So then he said that look let me let me use S(D) to denote the set of meters of
duration D in which the first syllable is in S.

So let us take an example to make sure that this notation is clear. So if you take D equals to 4
then the set of all meters of duration 4 which we just worked it out is this and of these the first
three have the first syllable S. So S(4) is just those first three meters, then L(D) we are going to
use to denote the set of meters of duration D with first syllable L. So clearly L(4) are the
remaining, so these three belong to S(4). These two are the remaining ones from the all the set of
all meters of duration 4 and they clearly belong in L(4), okay.

And clearly V(D) the total number of meters of duration D must be equal to the short meters plus
long meters and since S(D) and L(D) are sets, we are just taking the sizes of those sets. So
checking it for D equal to 4 what we have is V(4) is 5 which we counted over here and three of
these comes from the ones with the short syllable first and two of these come from the set which
has the long syllable first, so just I am just using D equal to 4 just to make sure that our notation
is being well understood.

481
Now, here is the key question to ask which Virahanka did. So, suppose I remove the first letter
from every meter in S(D). What happens? Okay, what is what remains what remains in S(D)?
Okay, well if you remove every the S from anything, the duration will decrease by 1. So you
started off with meters of length D, so if you remove the first meter which is going to be S in the
set S(D) then you will be left with meters that have duration D minus 1. Okay, and interestingly
enough, not only will we be left with meters which have duration D minus 1 but in fact you are
guaranteed to have all meters of duration D minus 1 after you remove the first syllable from the
meters in S(D).

So again let us go to a running example. So we have S(4) which is this and let us remove the first
syllable from these. So what do we get? Well, from this four SSSS we get three SSS and SSL
gives us SL and SLS gives us LS. So indeed if we look at the durations of these meters they are 3
okay and if you look back into what we did earlier, these are exactly all the meters of duration 3,.

Now, we should probably prove this. So here is very simple proof. Okay, so I am going to I am
going to do it with respect to this set. But you can see that it is really a general argument. So
suppose this was not, so this was not the entire set of meters with duration 3 and may be there
was some additional member that we did not have in this set, so suppose I take that additional
member which has to be different from this and I add an S in front of it, what do I get? So I will
get a meter which starts with S and has total duration 4. But then that would have to be present
over here. So either, so but that clearly is not the case, so that means this is a set which contains
all meters of duration 3 and since the the number of all meters of duration 3 is V of 3, in general
I can say the size of the set S(D) must be V(D) minus 1 because after I remove one letter from all
the meters the number of meters in this set does not change, so that continues to be cardinality of
S(D). And now we have established that that is the same as the number of meters of size D minus
1 and therefore that must be equal to V(D-1). So we can do the same thing removing the first
letter from all the meters in L(D), so what do we get?

Well, if you remove the first letter from L(D), L has duration 2, so now everything that remains
will have duration D minus 2. So in fact not only will the meters that remain have duration D
minus 2 but in fact by the same argument all meters of duration D minus 2 will be present, okay.
So again let us check this. If I look at this L4, if I remove the first L, what do I get? I get this and

482
indeed these are all meters of duration 2, there are only two meters of duration 2 and these are
here, okay.

So again the number, the the size of L(D) must be equal to V(D) minus 2. So combining this, this
and this, what do we get? Well, V(D) is cardinality of S(D) but that is V D minus 1 plus L(D),
that is V D minus 2, so this is what we get and I should observe that this is valid only for D
greater than 2. Because if D is not greater than 2 then V(D) minus 2 would not be bigger than 1
and our formulae, all our discussion is for having at least one at least one syllable in the meters
that we are talking about. So our discussion is really about so in our discussion whatever sets we
are talking about should be should have say V(D), so this has to be bigger than bigger than zero.
So D had better be bigger than 2, okay.

(Refer Slide Time: 12:23)

What have we discussed at this point? Well, so we have introduced Virahanka’s problem and
that was find the number V(D) of poetic meters having duration D and we can work out by hand
that V of 1 and V of 2 equals 2 and we said that working out larger V(D) by hand is tedious and
error prone and so we derived the relationship which is that V(D)=V(D-1)+V(D-2) for all D
greater than 2. Next we are going to write a program to calculate V(D) but let us take a short
break.

483
An introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 12_Part 2
Virahanka Numbers (Recursive Program)

Welcome back, in the last segment we discussed Virahanka’s problem.

(Refer Slide Time: 00:27)

So this was about finding the number of poetic meters having duration D. In this segment we are
going to discuss a program to calculate V(D).

484
(Refer Slide Time: 00:39)

So it seems that it is natural to use recursive function, okay. So since you were told that for D
greater than 2, V(D)=V(D-1)+V(D-2) the natural, the recursion sort of stairs is in the face and we
were also told that for D equal to 1 what the values were for D equal to 1 and D equal to 2 and
therefore D should be the base cases. So, this might be a natural program to write.

So V(D) which is what we want to calculate, where the precondition is the D is bigger than 0. So
if D is equals to 1 then we return 1. If D equals 2 then we return 2, else we use this relationship,
that is it. So, the question is, is this a reasonable program? We just wrote it but can we be sure or
can we be, can we somehow check whether this is a good program?

485
(Refer Slide Time: 01:54)

Well, so here is our program and in the last lecture we listed out some 4 requirements that we
should check when we write a recursive (algo) recursive function. So what were those? So first
all, our concern was, is the correct value return for the base cases? Okay first of all are there base
cases? So are there base cases? Yes, there are 2 base cases, okay, sorry before that this is one
base case and is the (current) correct value being returned? Yes, because it was specified in the
problem definition or we worked it out and for D equal to 2 is the correct value being returned?
Yes, we worked that out and that was 2 okay. Now does the level 1 call satisfy the precondition?
So which are the level 1 calls?

So this is one level 1 call, this is another level one call and what is the precondition? D should be
bigger than 0. So when we make this level 1 call, is this satisfied? Well, originally this was
satisfied for D. If D was 1, then we would have returned 1, if D was 2, we would have returned.
So when we come to this point, we know that D has to be bigger than 3, 3 or bigger. So then
V(3) minus 1 or something bigger than 3 even this number will be positive. So then that means
this precondition will be satisfied, and this number will also be positive because we said that D
has to be bigger than or equal to 3 at this point. So, even for this case, we will, even for this case
the precondition will be satisfied.

Now thus the problem size reduce? Can it reduce indifferently? So clearly in this case the
problem size is D, there is no other candidate really. So does it reduce? When we make the

486
recursive calls as it is reducing in the level 1 calls? Yes, it is going to D minus 1 and D minus 2.
But as it reduces can it go below 1? Can it go to 0? Well, we just said that, that when we make
the recursive calls the preconditions are satisfied and therefore they 0 is a limit, so the recursive
are the size cannot go to 0, cannot go below 1 and therefore the set of recursive calls will have to
terminate in some sense.

Final, the last check that we need to make is that if we assume that the level 1 calls returned the
correct value, then can you argue that the top level calls that the top level call is correct? Okay so
this is the top level call V(D) and we are assuming that these values are correct V(D) minus 1,
okay. So we have D minus 1 plus V(D) minus 2 so this is correct and this is correct. So in that
case are we supposed to return this? Well we got to this only if D is bigger than 2 and in that
case, indeed we are supposed to return this. And therefore, the top level call is going to be
correct if our level 1 calls are correct. So this really does look like a good recursive function.
Yes, so that is what I had written down over here.

(Refer Slide Time: 05:41)

All right so let us now do a demo.

487
(Refer Slide Time: 05:43)

Okay so this is the program that I showed to you and I have the main program and I am calling V
of i. So I am just doing this for all value of i between 1 and 50 okay. So let us see how this goes.

(Refer Slide Time: 05:58)

So let us run it, okay. So it is calculating answers pretty fast, but well now it seems to have
slowed down, slowed down, okay. So let me terminate it over here. Oh no-no 45, I think 44 it
took a long time, 45 maybe it will take even longer and even longer for 46. So let me not make
you wait through all of this but it is clearly the program has slowed down over here. So let me
terminate and (I) yeah.

488
(Refer Slide Time: 06:48)

I forgot to tell you one thing which is that when we write this program, we are going to use long
int okay, why? Because as you saw, the numbers were getting bigger than what can be held in a
single word. So this will be long int and because of that you could print you could get all those
numbers correctly, okay.

Alright, so at this point we have a puzzle, we wanted to calculate the first 50 Virahanka numbers
but the program seemed to be taking too much time at about 45, okay so we need to figure out
why that is the case.

489
(Refer Slide Time: 07:29)

Yeah beyond D equals to 45 the time for V(D) seems to increase a lot.

(Refer Slide Time: 07:34)

Okay, so for that why that is happening? Let us try to understand the execution of V(D) okay.
Now the execution of any recursive program can be visualized by drawing its execution tree or in
this case what might be called its recursion tree, okay. The execution tree is really like the tree
seen earlier, okay. The root correspond to the original call say V(10), then V(10) will make
recursive calls to V(9) and V(8). So we will have branches going out to nodes for V(9) and V(8).
From those we will have further branches going according to the further recursive calls that get

490
made and V(1) and V(2) returned without recursion. So, no branches leave the nodes
corresponding to V(1) and V(2). So what I am going to do now is to show you this recursion
tree, okay.

(Refer Slide Time: 08:43)

So for sum execution of Virahanka and in fact that I am going to do by running another program.

491
(Refer Slide Time: 08:54)

So I have written a program which will draw the execution tree or the recursion tree of
Virahanka, okay. So let us see how it gets drawn. So this is the recursion tree, okay let me
explain what is going on. So there are 2 sets of numbers appearing on every node, okay. So the
red numbers are the numbers which are the arguments to the call.

So this is asking for V(8) to be calculated. In order to calculate V(8) there is a call made to V(7)
and also to V(6) then to calculate V(7) there is make a call is made to V(6) and also to V(5) and
so on. And the blue numbers are the results, okay so these are the arguments, the red numbers are
the arguments to Virahanka and the blue numbers are the results of the cause or this is V(8), this
is V(7), this is V(6) and so on, okay. Let me run it again so that you can see the order in which
the numbers get printed.

So first all the red numbers will get printed that is because first I will know only the arguments.
So in order to calculate V(8), I need to calculate V(7). But the blue numbers will get printed
when from bottom up so to say as soon as this Virahanka returns then you know that the result
over here is a 1. When this returns you know that the V(3) is 3 and so on. So here finally when
everything is done 34 will get printed indicating that V(8) is 34. So let me just run it again so that
you can see the order in which things are happening.

Okay so right now only on the left side, only the arguments are known and now as things get
built up then the results are also known, that the values of V are also known, okay. So now let us

492
look at this and let us see if we can find anything interesting, indeed there is something very
interesting in this. So we want to calculate V(7) and this sub-tree is what is useful for calculating
V(7). So this sub-tree is responsible for calculating V(6). But even while calculating V(7) we had
to calculate V(6), we did calculate V(6).

So this is that calculation and what I want you to notice is that this calculation is exactly the
same as this calculation, and that is really not good because this work is exactly the same as this
work and we duplicated it over here. But that is not all, things get much worse. So for example,
let us look at V(5), this sub-tree sorry, let us look at V of what this number is? V(4) okay so let
us look at V(4). So we want to calculate V(4), so that is what this sub-tree is doing. But V(4) is
being calculated here as well and here and here and here. So V(4), the calculation of V(4) is
being done in many-many-many places. So clearly something is wrong, I mean if you want to
calculate V(45) in this manner, several-several Virahanka numbers will be calculated far too
many times and in fact that is why it was taking so long to calculate the Virahanka of 45. Of
course everything is taking long but that length really shows up when you get to 45, okay.
Alright, so what can we do?

(Refer Slide Time: 13:26)

Okay so first of all let us go back to our slides. Yeah so, we said that the (several) that several
sub-trees are doing the same calculation.

493
(Refer Slide Time: 13:43)

And so what have we discussed at this point? We have discussed recursive function to calculate
Virahanka numbers okay, V(D) and we observed that the time takes, function takes a lot of time
for D greater than 45 and when we plotted the execution tree or the recursion tree it shows that
we are performing the same calculation several times. So in the next segment we are going to see
how to avoid this duplication of work. So before that will take a quick break.

494
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 12 Part 3 – Virahanka Numbers (Iterative Program and Conclusion)

Welcome back. In the last segment, we discussed recursive function to calculate Virahanka
numbers and we concluded that it was taking too much time and that was because we were
seeming to repeat work. In this segment we are going to see how to avoid that. So, what
exactly were we doing? And what should we do? Well, we should really not calculate
something more than once. Okay?

(Refer Slide Time: 0:48)

So, to begin with our function knows V(1) is 1 and V(2) is 2. So, our function was V(1) and
V(2). Okay. It then calculates V(3) and V(3) is calculated using V(1)+V(2). Okay. So, after
that you can calculate V(4) is V(3)+V(2).But notice that when we when we issue this call
V(4), we do not really need to recalculate V(3). If we could somehow remember what we,
that we calculated V(3) earlier then we could just use that value and V(2) of course we know.
So, in general we could think of doing this in a loop. So, in iteration i, where i goes from 3 to
D, we will calculate V(i) because for i equals 1 and 2, there is nothing to be done. Those
values are already known.

And how do we calculate V(i)? Well, V(i) requires us to take V(i-1) which we must have
calculated in the previous iteration and V(i-2) which we must have calculated in the iteration
previous to that and add up these two values. So, which means these values we could print
out if we wish. But we do not really need to print them out, if we are only interested in the

495
final V(D). But in any case, in ith iteration we should be remembering these values. These
values should be there so that we can add them up and we can generate V(i).

So, to keep these values V(i-1) and V(i-2), we will have two variables. So, we will have a
loop. We are now going to have a loop and in that loop, we are going to have 2 variables and
at the beginning of the ith iteration these variables will contain V(i-1) and V(i-2). And we will
also use a variable V(i) in which we will construct V(i).

So, V(i) is a variable, V(i-1), V(i-2) are going to be our variables and the important point is
that the beginning of the iteration i we want V(i-1) and V(i-2) to contain V(i-1) and V(i-2)
which were calculated earlier.

(Refer Slide Time: 3:41)

So, based on this we can create this program. So, this program is going to calculate V(D). So,
as we said we are going to have iterations going from 3 to D and at the beginning V(i-1) and
V(i-2) must have the values V(i-1), V bracket i minus 1 and V bracket i minus 2, so those
values must be there. And then we add them up to get the value of V(i).

Now I have to fill up, fill up the rest of the code over here. So, let us see, so in the iteration 3
when we first enter this loop, what do we need? So, we need, so we are going to calculate
V(3), i is going to be 3 so we want to calculate V(3) over here. So, at that point we need this
to be V(2) and we need this to be V 1, so these values will get set only above outside the
loop. So therefore, we should initialize these variables to 2 and 1 respectively. And then when
we go the next iteration of the loop, what happens? So, first of all in this iteration, what
happens? In the beginning we calculate this which is as far as the plan we were talking about
on the last slide and then we have to prepare for the next iteration.

496
So, for the next iteration what is it that we want? Well, the value that was V(i-1) in the
current iteration, so is the value of calculated in the previous iteration. But now for the next
iteration that will be the value calculated in the second previous iteration. So, that should
really go to V(i-2) and V(i-1) for the next iteration is the value that was calculated in the
current iteration and therefore that must become V(i). So, our loop must be this. And finally,
what should be returned?

So, at the end of this loop V(i) will contain V(D) and therefore we should return V(i) over
here, okay. Now if you look at this code you will see that this code works only for D greater
than 2. Basically, if D is equal to 1, what happens? This V(i) is not even defined. So, but for
for the other D it works fine and so, let us just put a comment to that effect.

(Refer Slide Time: 6:08)

497
Alright. Let us see. Let us run that program and let us see what happens with it. So, this is the
program, okay. So again, the function is what I just showed you, okay. And in the main
program I am going to have the same thing again. I am going to go from 2 to 50 as before. I
did not go from go with 1 because we know that this program does not work for 1, okay. And
as you can see again to accommodate the large numbers, I have had long ints, okay. D does
not have to be long because D does not contain long numbers, okay. So, the arguments to D
does not contain long numbers. So, that does not have to be long.

(Refer Slide Time: 6:49)

So, let us compile this. So, this time it produced an answer instantaneously essentially, so as
soon as I hit return the answer was there. There was no waiting at all. And that is to be
expected because in each iteration of the loop we are doing really very little work.

498
(Refer Slide Time: 7:20)

So, so there is this repeat and in this, oh, yeah so there is a slight change over here, we really
did not need those i’s and therefore we can also use repeat over here. So, you can compare
these two codes and see that they are really the same. But I could have put for here as well,
does not really matter. But the point is that we are having iterations of this loop and the time
required for each value, for each V(i) is exactly the same and therefore the loop runs really
fast, okay. So, we have done this and we were able to get V(D) to be calculated very fast.

(Refer Slide Time: 8:09)

So, what do we learn from this? So, we can see that recursion is a very powerful tool for
solving problems. Recursion helps us solve problems and discover algorithms, but the natural
recursive algorithm might be very slow. By examining the algorithm, by seeing what it does
we might be able to discover a better algorithm. Then we also saw that the recursion trees are
a nice way of seeing how a recursive algorithm works.

499
And I will leave you with an exercise: Write the program which draws out the recursion tree.
So, for this you need to take the ideas from the basic recursive Virahanka algorithm and also
the tree drawing algorithm. And you sort of have to fuse these two programs together, okay.

Now this sequence, these Virahanka numbers V(1), V(2), V(3) which are 1, 2, 3, 5, 8, 13 is
actually a famous sequence and it is well known as the Fibonacci sequence named after the
Italian mathematician, Fibonacci who lived, Fibonacci or Fibonacci, who lived in 12th century
AD. But Virahanka discovered it much earlier and we probably should be calling it the
Virahanka sequence or call these numbers Virahanka numbers, isn’t it?

So, with that we will conclude this lecture sequence noting some rather interesting facts about
recursion. Thank you.

500
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 13 Part 1 – Program Organization and Functions (Introduction)

Hello and welcome to the NPTEL course on An Introduction to Programming through C++. I
am Abhiram Ranade, the topic for this lecture is program organization and functions and the
reading is from the chapter 11 of the text. So the central question that we are going to answer
in this lecture sequence is how do we write large programs.

(Refer Slide Time: 0:45)

Now designing or building anything large becomes easier if we can think of it as being made
of small parts. So for example, a book is made of chapters and if we say that look, let we
concentrate on chapter 1 now then concentrate on chapter 2, then the whole thing becomes
easier to think about.

Say you are designing some object like a car, then a car has many subsystems and you do not
design everything together, you do not have everything in your mind at the same time. But
you say that look, let me now design the engine, let me now design the electrical subsystem
and we sort of break it up into small pieces and work on the pieces one at a time or at least
one person works on a piece at a time. For programs such smaller units are functions. We
break up the overall requirement into separate, small, somewhat independent computations
and code up these separate parts as separate functions.

501
(Refer Slide Time: 2:10)

Now we are going to think of a program as being made up of functions and we have already
said that even if our main program which was which has been looking different from
functions so far is actually also just a function. So let me make that clear right away. In C++,
the standard way to write the main program is to write it as a function. The function must be
named ‘main’ and its return type must be int. Why is it int? That is really for some historical
reasons. The main program doesn’t really returning anything but for some historical reasons
it has stuck that its return type must be int.

Ok and for now the main program is not going to take any arguments. So instead of
main_program and a body containing appropriate statements, in C++ you really should be
writing int main(), so main which does not take any arguments and the body containing
whatever statements.

Ok, simple CPP is just doing a translation for you, ok so when you write main program
simple CPP translates this main program into this text. There is a feature in C++ called
preprocessor macros which are being used over here in case you are curious but for this
course you do not need to understand preprocessor macros but if you are curious they are
discussed in the book.

Ok, so why did we do this? So simple CPP provides this feature so that on the very first day
you do not need to understand what is a function, what are arguments to a function and why
is it int or should we care that it is an int. We did not want you to ask all these questions or
we did not want you to worry about all these questions and therefore we made this thing

502
called main_program and which we convinced ourselves the simple CPP was translating into
what is actually required.

Ok, but now that you know functions or by the way the function main is allowed not to have
a return statement, so this is the concession that is given for main because the value returned
is not of any consequence anyway, so we have not been returning the value inside inside the
main program.

Now that you know what the thing is really required in C++, we are going to stop using this
phrase ‘main_program’, so we will write int main and then the body and this is how we will
write our main program as a function whose name is main.

Your compilation procedure will still work if you are using an IDE. If you hit the compile
and run button or just the compile button, that will work. Ok, if you are using S++ command
under Linux that will still work, ok and I will encourage you to use int main because after all
that is sort of what will be available if you go outside simple CPP and anyway it is not really
a major convenience at this point to be able to write main program.

(Refer Slide Time: 6:15)

503
Ok, now that you understand what functions are, ok so let us come back to the question of
dividing code into functions. So, why does it help? Ok, so if you if you have a lot of work to
do you would like to get many people to do it. So, similarly if you want to write a big
program, presumably you want to assign it to many people and certainly if you give different
functions to different people then that is easier to, that makes it easier for people to
collaborate.

Another very interesting feature of functions is that they are self-documenting. What do I
mean by this? The function name, parameters give clues as to what the function is doing. If
you just write the code inside your main program, then there is no such clue. So, going back
to the functions that we had if we write int gcd, then the very fact that we have a name over
here tells us that look something like a gcd is being computed and ‘m’ and ‘n’ are there, so it
says that look, ok maybe the gcd of 2 numbers is being computed something like that.

504
(Refer Slide Time: 7:22)

Ok and here the things are even clearer, ok that a tree is being drawn or something like
something is happening to something involving a tree. Even that is better than just putting
this kind of a code inside your program. Ok and of course if you are going to recurse,
functions are of course essential but even if you are not going to recurse just the fact that
there is a name over here forces you to say something about what is being done. Of course,
all this works only if you are choosing the name nicely and we hope that you choose the
name nicely, we hope that you choose the names of the parameters nicely.

So for example, you really could say over here int level not just ‘l’. I have been using level
over here because I want to put this inside a slide and inside a slide if you put big names then
it would not fit in the slide but really good programmers will use much longer names. So, you

505
could even say instead of rx, you could say root x if you want or x root whatever whatever
style you prefer. And when you write a function there is a natural expectation that you should
write the pre-conditions and the post conditions.

So we have written pre-conditions and post conditions here in a very compact manner and
here in a little bit more descriptive manner. In fact, this last comment says a little bit more as
to what area what specific area the picture is going to fill out.

So what happens is that in the long main program it may not be obvious as to where as to
where and how to put the comments, whereas in a function there is a proper place for it, there
is a natural place for it, ok and I cannot overemphasize the need to document your code. As I
said earlier, your code will be written will be read by you later on and you would want to
know what it does and believe me you will forget why you wrote some piece of code and of
course if somebody else is going to read the code, they will need to know why you are
writing, what you are writing and so functions say that in this small piece of code this is what
is going to happen, ok. The names implicitly say what is going to happen and furthermore if
put in comments giving the pre-conditions and post conditions, great.

Functions also allow you to adopt a strategy. Write a little bit of code, test it, write some
more, so basically you can test your program one function at a time and you do not have to
write the entire program and then test the whole thing. That is really tricky to do because you
will not easily know where the error is. If you write a small function and it makes an error, it
is much easier to fix the error. And finally a function is a good way to package and share a
code.

If you have written some code and you want to give it to someone else, you can give them a
file containing a function which contains the code. Ok, so a function is sort of is a nice
wrapper into which you can put code. So in some sense a function is a logical unit of code,
the physical unit of code. The physical units are files. If you want to give anything like code
to anyone, you have to give a file and of course if that has to make sense it had better it is
nice to put a function in it rather than sort of code by itself does not make sense.

Code just a loop by itself or just a declaration by itself does not make sense whereas a
function is kind of a nicely packaged piece of code but that is sort of logical packaging.
Physically you have to give a file. So, that raises a bunch of questions.

506
(Refer Slide Time: 11:39)

So, suppose several people write different functions of the same program. It is convenient for
each person to use a different file and so the question that is raised is, how will a function in
one file call a function in other files? So, we are going to answer these questions fairly soon.

(Refer Slide Time: 12:07)

Now you may be thinking at this point, look in this course am I going to be writing large
programs? Or is this discussion about large programs really not relevant for this course? Ok,
so some answers are due. So it is true that you are not going to be writing very large
programs in this course. So any program that we ask you to write will be at most 150 lines.
Most of the time they will be fairly short, so maybe there will be 20 lines. A 20 line program
does not, can fit in the file and does not, it probably does not need to be divided into small
functions. Ok, on the other hand a 150 line program should be divided.

507
Ok. So, you do not write 150 lines as a main program, it is too long, it is too hard to figure
out what is going on. So you break it up into pieces and the maximum size recommended for
the main program or for a re-function is less than 20 lines. Why 20 lines? Because 20 lines
you can sort of see at a glance. Anything bigger you sort of have to move your head around
or you have to at least move your eyes around and if you are not seeing things at a glance
then it is harder for you to sort of keep everything in your mind.

The bigger the chunk that you have to keep in your mind the harder it is for you to work with
it. So if you can break things into pieces which are about 20 lines then that is great. Yeah, so
you are more likely to understand that code fully and write it without errors. So again, you
may notice that I am really worried about making errors when I write programs. And that is
for two reasons, the first reason is that if I want to write program that I write a program that I
give to someone else, I want it to run correctly because I know that that person might be
using that program for something really important and I would be failing in my duty if I if my
program does not work correctly.

The second reason I am worried about errors is that experience has thought me that I will
make errors when I write programs and I should be prepared for that, I should be I should
take as many precautions as possible and I should not become proud that oh, I am going to
write this program without errors in the first shot. Sorry, it does not work like that for most
people, so be a little humble, write the program, write it very carefully, write it by cultivating
the style which prevents you from making errors as much as possible. Ok but anyway be
willing to test it and so yes, I will be pre-occupied about making errors and I will be
suggesting strategy so that you do not make errors and breaking things into small pieces is
one such strategy.

Actually, many experienced programers even recommend smaller size for functions longer
than 20 lines. Ok, yeah, so now how do you break code into small functions? So, that is not
quite what we are going to talk about here, ok that is something that we will consider when
we write large programs, when we ask you to write programs. At that point we will suggest
how to break things into small pieces. Ok, the consideration this time is a little bit different.
Ok, so this is this is the second consideration as to why we are talking about large programs.

508
(Refer Slide Time: 16:14)

So as we said it is ok to put a 150 line program into a single file but not larger programs and
again we may say that look, ok so we are not going to write bigger than 150 line program, so
why are we bothering? In fact, yes, the novice IDE of simple CPP requires you to only have a
single file program.

Ok, the first simple CPP IDE on the other hand does allow multiple files, but we are not
going to discuss it. Ok, so then why are we talking about all this? Here is the point. When you
write even your simple 15-20 line program, you will be using code which is written by others.
So effectively, what you call your program is going to be a large program. Effectively, you
are cooperating with others who have written the simple CPP functions for you. So your
program really contains all those simple CPP functions effectively. The math library
functions such as square root, sin, cos whatever that you are using have been written by
somebody else and they have to be a part of your program if your program is making calls to
square root. So in some sense you should know how a large program works, how a program
which exists across several files, how do you put that together? And that is really what this
part is about.

So you are collaborating with others without knowing it and you are using functions from
many files, so you really should know how all that works. So to this extent even though you
are not writing large programs what we discuss will be relevant to you.

509
(Refer Slide Time: 18:15)

Ok, so what have we discussed in this last segment? We have said that the main program is a
function and then we have articulated the need for splitting a program into many functions
and we have articulated the need for splitting a program into many files. Next, we are going
to see how to split the programs into files and how your program will effectively use code
written by others and finally, we will see how you can use C++ without simple CPP. So we
will take a break.

510
An Introduction to Programming through C++
Prof. Abhiram G. Ranade
Department of computer Science and Engineering, IIT Bombay
Lecture 13 Part 2
Program Organization and Function
Splitting into files

Welcome back, in the previous segment we discussed that the main program is a function and we
motivated the need for splitting the program into function as well as into several files. In the next
segment we are going to in the rest of this lecture sequence actually, we are going to see how to
actually split programs into files and that is what is going to happen in this segment and then in
subsequent segments we will see things like how your program uses code written by others and
features that C plus-plus provides for that and also finally we will see how you can use C++
without simple CPP.

Ok so how do you split program split, split a program into many files?

(Refer Slide Time: 01:16)

Okay so a program may contain several functions and all of them need not be placed in the same
file, so if a code in file capital F calls a function little f then the function f must me declared
inside F, textually before any call to it. Now a function definition that we have been talking is a
declaration but that is not the only way to declare a function.

511
So, the definition could be in another file and so long as there is a declaration in the file capital F
which contains calls to this function that is enough okay, so every function must be defined in
just one of the files that are used for a program. But it must declared in all the files that make a
call to that function.

(Refer Slide Time: 2:26)

So what is a function declaration? Well it is essentially the definition without the body, so
declaration of the GCD function looks like int gcd(int m, int n) so after that you could have given
the body but that is being omitted in the declaration okay. Also acceptable is int gcd(int, int).
Now you may notice that this is really like declaration of a variable, so I might have written int X
okay so it looks like a declaration of a variable but it is the parentheses are saying it is not a
variable but because of those parentheses following the gcd the compiler can tell that oh this is a
very this is a function that we are talking about. So, basically that is what a declaration tells the
compiler. It tells that look gcd is a function and should the name gcd appears, appear later on in
this file, think of it as a function which takes 2 arguments and the arguments had better be of the
specified type.

512
(Refer Slide Time: 03:43)

So this way the compiler checks that subsequent uses of the name gcd adhere to what you have
said about gcd, again the general strategy over here is to say what gcd is and then check whether
you are using gcd in the manner that you have just described. This is also because we are worried
about making mistakes. So the compiler tries to prevent, tries to help you out and tries to see if
you are possibly making a mistake and therefore it needs to know what every name is over
whether it is a function, it is a variable and therefore, the declaration has to be given preceding
the use of that name.

513
(Refer Slide Time: 04:42)

Now if a file contains a call to a function but does not contain its definition, the compiler will
assume that it will appear elsewhere. In fact, that is the whole point of putting in a declaration, so
putting in that int gcd(int nm, int n) without the body okay. But the compiler will not be able to
compile it as a main program okay as a in fact unless the main program is there it will not be able
to compile but further more if some function body is missing again it will not be able to compile.
What it can compile your file into is what is a called an object module and we will see that.

To get an executable program all the object modules containing the call function must be linked
together only then you can produce an executable program. We said this long ago when we were
talking about how the hardware works but now you will see a little bit a few additional details
okay. The function declaration that we have talked about so this line, this portion, this or this is
called a declaration but it is also called the signature of the function or the prototype of the
function. So some examples, so here is an example of a program which is split over multiple
files.

514
(Refer Slide Time: 6:17)

So you can have a program in a consisting of a function in gcd with the body also given and
perhaps you can put it in the file gcd.cpp okay, you can also have a second file lcm.cpp a third
file main.cpp okay. So what is in these files? So the green portions are function definitions and
the red portions are the function declarations and each file you will see has a declaration,
declarations of the called function. So, in this file there is call to gcd and the definition the
function is not defined over here, but the function is declared in this file. So this is the
declaration.

So the compiler can compile this file at least partially into an object module. Then in this file
main.cpp, lcm is being called and it is not defined over here but there is a declaration saying that
oh it contains it has 2 arguments and in fact compiler can check that indeed 2 arguments of type
integers have been given. Now, if you have these files and want to compile and link them
together okay you would issue the command s++ main.cpp lcm.cpp gcd.cpp if you are operating
under Unix and these files were in your current directory. If you are operating, if you are using
the full IDE then you would have defined something called a project in which these files would
have to be present. But the contents of the files would have to be exactly these, that if file a uses
a function makes a call to a function and if the function is not defined there then there has to be a
declaration of it above the use or the call to that function.

515
If you want to compile each file separately, this is what you do you write s++ but you add this
compiler option -c which essentially says compile only or do not link lcm.cpp. So this produces
lcm.o which is an object module which you can think of as something which is partially
compiled. And if you have all this object modules then you can compile them together by writing
s++ again, s++ does everything as you can see the compiler does everything. You can write
main.o lcm.o gcd.o. So this will actually produce your executable.

Now, what you typically do is not quite this, what you typically do is that you write a program
say in a file called pgm.cpp. On Unix you compile it but the s++ command itself supplies all the
additional modules that you want, so if you are using square root that module is supplied, if you
are using simple CPP the modules required for simple CPP are supplied okay so this compilation
is really quite similar to this compilation or even this compilation even though you are using only
a single file.

So yeah, so this s++ is compiling your program pgm.cpp but you are also linking it to object
modules which are developed by others. So where are they? Well they are in some places that
this s++ knows and some of them might be present as libraries okay, so its not only object
modules that you can compile together you can also compile together libraries. So the libraries
might also get listed over here. So we are going to omit that detail because s++ places those
libraries for you, but they are sort of like object modules, they also contain code for functions.
Okay so for all this to work correctly your program must have the right declaration.

516
(Refer Slide Time: 11:12)

So if this is your program then it will better have a declaration of the function that you are going
to use. Now you may say that look I used square root, I used right, I used turtleSim, I used in it
canvas but did not put declarations to all those in my in the program that I wrote okay. So, there
is a different mechanism for putting in the declarations which now I am going to tell about.

517
(Refer Slide Time: 11:53)

So this mechanism is called header files. So it is tedious to remember what declaration to include
in each file, so it is tedious to remember what declaration to include in each file. So what do we
do instead? We put all the declaration into a file called the header file and include the header file
into every file that we use. So here for example is the header file gcdlcm.h so well I just made up
a name okay. So this file contains int GCD int LCM so it contains the declaration of GCD and
LCM.

And now the file gcd.cpp does not actually contain the declaration but it says include this file, so
all those declarations would go in okay, LCM similarly just includes this file and main also
include that file okay, so basically I do not, I am not worrying about oh include the declaration
for this function, I am not going to worry about this function, that function. I am just going to say
look whatever functions I need those and maybe be more than those are present in this header
file and I just going to include my header file and that will automatically bring in these lines.

So the directive include file name just copies the contents of that file into your file okay, so it
gets replaced by the contents of the name file. And it is acceptable if we declare functions that do
not get used okay, so for example in this if we include gcdlcm.h this file itself directly does not
need the declaration for GCD but it is ok to have it okay. It just says that GCD is a function
whether I am using it or is not important okay.

518
It is acceptable if have both declaration and then the definition, so that is going to happen over
here. So this include is going to be replaced by int gcd(int, int) which is just a declaration but it is
also going to contain a definition okay but that is okay we can a declaration and a definition. So
long as they are consistent ofcourse. We what we cannot have are 2 definitions, so 2 pieces of
code cannot be given. You will also have noted that there is another include over here, include
simple CPP. Now it is in this braces but anyway that simple CPP file is included it is picked up
from some specific places and that file contains the declarations of all things like turtleSim, right,
left okay also things yeah so all those things okay and that is why you have not been needing to
actually include put in declarations for all the functions that you have been using so far. And that
file simple CPP also includes and include file itself called cmath okay which contains the
declarations of square root sign and all of that. So the include files have been putting in all the
declaration that you really needed.

(Refer Slide Time: 15:13)

So a little bit more on header files, header file customarily have the suffix ‘.h’ which is what we
just used they could also be ‘.hpp’ or sometimes they do not have any suffix that is also allowed.
If the header file is mentioned in quotes it is picked up from the current directory okay and if it is
mentioned in angle braces then it is then it is picked up from some standard place, for example
simple CPP is present in some in some standard place which the compiler knows about. So you
say include simple CPP s++ will pick it from that standard place.

519
(Refer Slide Time: 15:49)

Alright, so what have we discussed? We have discussed how to split a program over many files
and effectively how do you assemble a program out of functions in many files and I guess this is
really what is most relevant from for you because you are not going split a program but you are
going to use functions which are there in several program. So, you want to know how to use
those functions. Then we have discussed what are function declarations and definitions and we
also talked about header files. Next we are going to talk about namespaces which is a C++
feature which helps in writing program across multiple files. So we will take a break.

520
An introduction to programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology, Bombay
Lecture Number 13, Part-3
Program Organization and Functions
Namespaces

Welcome back. In the last segment we discussed how to split a program over many files,
functions declarations and definitions and header files. In this segment we are going to
discuss Namespaces.

(Refer Slide Time: 00:37)

e
So, suppose many people cooperatively develop a single program. Now, it is possible that
several people may define functions with the same name. So, it is a little bit cumbersome for
you to coordinate if you are writing a small function that you say, oh I am going to use a
function called F, you please do not use a function called F as well. So, it is so I that
cooperation is that coordination is cumbersome and if you do not have the coordination then
you may have some name conflicts. So, how do we avoid this? This can be avoided using
something called as Namespace. A Namespace is basically a catalog of names. So, effectively
the “full name” of a function F defined in the namespace N is N::F . So, if F is defined in two
namespaces N and P then, N we can specify which one we mean by writing N::F or P::F and
there are other ways of specifying as well which we will see soon.

521
But basically now, we can have unambiguous ways of referring to different functions even if
their name is same, because their full name is going to be different. So, effectively each
programmer could use a different name space if there is need.

(Refer Slide Time: 02:21)

So, how do you define a Namespace? Declaration is simple, defining a namespace is simple,
you just write namespace followed by the name of that namespace. In this case the name is N
and then inside that block you put in declarations or definitions of names.

(Refer Slide Time: 02:41)

This creates a namespace with the name N and also defines or declares names inside it. You
can add more names into a name space, simply by writing namespace N again and putting

522
names inside that new block in the new position. A name g which is defined without putting
it inside a namespace is said to belong to the global namespace. So, all the names that you
have been defining so far are in the global namespace. So, where full name is ::g. So, you
could refer to then in this way but if you wish.

(Refer Slide Time: 03:27)

So, here is an example of using the namespace. So, first I’m defining a namespace N and it
contains declaration actually, it contains definition of g series. So I have put (…) to say that
entire definition, the entire body will go there. Similarly, there is the definition of lcm. Now,
in my main program, I need to write N::lcm because I want to access this lcm which is
defined in this namespace N.

523
(Refer Slide Time 04:10)

Now, there is something called the ‘using’ directive which comes in handy often. So, if you
have defined a namespace N and you have many names defined in it and you want to access
them quite frequently, so you may get tired of writing N:: all the time.

(Refer Slide Time: 04:31)

So, what you might do is you put the following (line), you might put the following line at the
top of your file. So, I say using namespace N, this is the line you put. Subsequently or for all
other references in that file, you will be allowed to use any name from N without having to
write N:: before it. So, N:: will become implicit.

524
(Refer Slide Time: 04:58)

So, if I write this directive then the previous program becomes like this. I will write
namespace N int gcd int lcm and then I have this using namespace over here. So, this using
namespace says when I use lcm over here it is implicitly interpreted as N::lcm and I will get
to the definition which is given in this namespace.

(Refer Slide Time: 05:31)

Alright, so what have we discussed, we have said that namespaces help many people to use
the same name and yet combine their work together if needed, then we discussed the using
directive, okay. In the next segment we are going to use C++ without simple CPP and we are
also going to conclude this entire lecture sequence. So, let us take a break.

525
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 13 Part – 4: Program Organization and Functions
(How to use C++ without simple CPP)

Welcome back, in previous segment we discussed namespaces and the using directive. In this
segment we are going to talk about how we can use C++ without simple CPP and we will
also conclude this entire lecture sequence. So, how do you use C++ without simple CPP?

(Refer Slide Time: 0:44)

So, if you want to use it without simple CPP, first of all you will not be able to do graphics,
but that is not all. When you write hash include simple CPP that itself includes the following
lines for you. So it includes a line called, line with goes #include<iostream> and also a line
which goes #include<cmath> and it also includes this line using namespace std, these lines
are useful. The name in the cin the cout and endl all related to input output are defined in the
namespace std and this definition happens in the standard header file iostream.

So therefore, you need to include iostream so that you get these names. And if you want to
use them directly without having to write std::cin, you also need to have this line using
namespace std. So, if you do not include CPP, if you do not have this line then you should
have all these lines and you should have the line cmath because if you want to use functions
like sqrt and all of that, sqrt, sin, abs, whatever.

526
(Refer Slide Time: 2:22)

So let me give you a very simple example of how you can use C++ without simple CPP. So
you might say #include<iostream> using namespace std, int main, int n, cin n so read n and
say print out it is cube. So, this could be really simple program which you could write
without having to use the simple CPP features. But because simple CPP was including these
things and because you need to use cin, and endl, you need to have these lines. Here is
another way of writing the same thing, so you could write iostream, int main, int n.

And now because you did not write namespace std, you will have to write std using
namespace std, you would have to write std::cin and not just cin and likewise std::cout and
even std::endl. So that is basically how you are going to use C++ without using simple CPP.
And of course had you needed to you use any math functions, you would also have to include
#include<cmath>.

527
(Refer Slide Time: 3:52)

528
So just to make sure just to persuade you that this works, I am going to show you both of
these programs and run them. So this is the first program that we saw where you are using,
you are not including simple CPP, but you are including iostream and you are using the using
the namespace std and you are putting and you are writing the program.

So, let us compile it, we can compile it with s++ still, but we can also compile it with the
basic C++ compiler and that is called g++ on Unix. So, I can compile without simple CPP. So
it has done its job, so it expects me to type in a number, so let us say I type (n) 9 and indeed it
is printing out the cube of 9 which is 729.

(Refer Slide Time: 5:06)

Let me show you other program without simple CPP. It is called and here I have not put in
the line using namespace std, but instead I have included the prefix std:: before all the names

529
which are belonging to that namespace std. So again let me compile that, so s++ so I could
compile it with s++ as well, but I could compile it with g++, let us use g++ again because that
is what you would do if you are not using simple CPP.

So withoutSimplecpp2.cpp, so it is compiled dot slash a dot out, again it is expecting me to


give a number. So let say I type 7 and yes, the cube is 343, so that is done. So, if you wish
you can run your programs without using simple CPP, but then you would have to type these
lines and if you are feeling tired about typing these lines, you can continue to use s++, (no) it
will work in anyway. Alright, so that concludes the part about how to use C++ without
simple CPP and specifically what include files you need to use.

(Refer Slide Time: 6:53)

Now, I want to conclude this entire lecture sequence on how to write large programs. So, the
first point that we made are functions are building blocks of programs. So just as when you
write a book, you typically break it into chapters, if you are designing a device you break it
up into subsystems, systems and subsystems. Similarly, when you are writing a program you
kind of (break it up) break it down into functions. There will be other things that will also
come up, but we will talk about those later.

Functions can be put into many files provided each file contains a declaration before the use
of the function. Declarations can go into header files, it is convenient if you put declarations
into header files. And when you put declarations into header files, there are some additional
details which you might want to learn if you use really if you yourself try to write really large
programs. Some of these details are discussed in the book. Names can be put into namespaces

530
and you do have some namespaces which are defined as a matter of, as standard by default in
C++ and the namespace std is one of those namespaces.

So different programmers can put their work in different namespaces and the same name may
be defined in many namespaces. So, in fact this says that you could have a variable called cin
in your program, I would recommend that you do not do that because you will confuse
yourself, but in principle you could do it because the cin that you are using so far is a name
defined in the namespace std.

So if you carefully want to differentiate it and put cin in your own namespace that is possible,
but again as I said, not recommended. The details of all this are discussed in the book, and
that concludes this lecture sequence. Thank you.

531
An Introduction to Programming through C++
Professor. Abhiram G. Ranade
Department of Computer Science and engineering,
Indian Institute of Technology Bombay India.
Lecture 14
Advanced Features of Functions Introduction and passing one Function to another

Hello and welcome to the NPTEL course on an introduction to programming threw C++. I
am Abhiram Ranade and the topic for today is some advance features of functions and the
reading for this is from chapter 12 of the text. So, here is an outline for the, this lecture
sequence. I am first going to talk about passing functions as arguments to other functions.

(Refer Slide Time: 00:43)

And this will be in two ways - functions function parameters there will be two subtopics sort
of and I will also talk about something called lambda expressions. Then I will talk about how
to assign default values to parameters of a function. And I will also talk about something
called function overloading. So, let me start of with the function bisection that we wrote some
time ago to find the square root of 2.

532
(Refer Slide Time: 01:18)

Let me begin with the function bisection to find square root of 2. So, here is the function. So
this function meant to find root the root of any function and we are going to use it to find the
square root of 2 by finding a root of the function x square minus 2. So, x square minus 2
would be 0 at square root 2. So, if we found root of this function x square minus 2 we would
have found square root of 2.

So this function does do that and we could use this to find other things also. So say we want
to find the cube root of 3, what should we do? Do we need to write everything again? Well
not really. We should only right things which have to be different as compared to finding the
square root of 2 and there really are two places. So this is the place where we were evaluating
the polynomial x square minus 2 and here is a place again we were evaluating the
polynomial.

So only in this two places the actual polynomial that we are evaluating is important and for
this we would need to evaluate the polynomial x cube minus 3. So over here there should be
x cube minus 3 xm cube minus 3 and there should be xl minus 3 again so that is the change
that we want to make. So we could we could change the text but is there a better way of
doing it? So the general question is can we right a bisection function which finds the root of
any mathematical function what so ever provided satisfies the requirements of bisection and
those requirements were that we need to supply to bisection two values xl and xr such that the
signs of the function who’s root we want to find are not identical at xl and xr. So that is what
bisection depended on and we should satisfy that but we would like it like a single function to
be used to find the root of any mathematical function. So a natural idea for doing this is -

533
(Refer Slide Time 03:46)

Well to bisection we should pass somehow to pass the mathematical function whose root we
want to find so there is an extra argument and that argument should specify the mathematical
function of whose root we want to find. Now how do we represent mathematical function
how do we tell bisection that look here is the function. A natural idea again is that after all we
have C++ functions which compute the function with whose root we want to find.

So suppose we could somehow send that C++ function that should somehow be adequate. So
in the case of our square root of 2 we were trying to find the root of this function f(x) equals x
square minus 2 or the new thing we want to do use bisection to find a cube root of 3 we want
to find the root of this function.

So, somehow we should supply this function f and g to the bisection function through that
extra argument and maybe that should some we should somehow be able to make it work. So
now the question is that we have a C++ function bisection and to it we want to pass another
C++ function ok f or g whichever one is a be might be interested so how do we do that.

534
(Refer Slide Time: 05:13)

So, in short this is what we would like to right as far as rest of the code goes. So here, we
have define our f we have define our g and in the main program we have an extra argument
so this time we have given the argument f presumably they should somehow send this
function over to bisection to the function bisection and bisection should print the root of root
corresponding to this that should find and print the root of square root of 2 and similarly in
this case bisection should be sent this function this g over here and after it executes bisection
should print the cube root of 3.

535
(Refer Slide Time: 06:10)

Now exactly how do we pass a function h to another function b well let us see - suppose h has
this declaration So, written type h and the parameter test then in parameter list of b to which
we want to pass s we need to put in the type of h. Now it turns out the type of h of a function
defined in this manner is something like this so it’s this funny looking funny looking
quantity, funny looking string. So, it begins with this word function and angle braces, return
type all of these things.

Now this a general h but the function we want pass to bisection takes a single double
argument and returns the double all such functions that we want to pass are going to take a
single double argument and return a double. So, we can say the type of all such functions is
function return type double and single parameter type also double.

So, we have discovered how we can declare what should be the parameter list of b or of
bisection so we need to put this in the parameter list of bisection. So, bisection is going to
have this declaration so these were the original parameters and this now is the new parameter.

So this way, the extra argument that we send f or g will be received by bisection as this
argument h and in fact inside bisection we can write calls to h so bisection can be just directly
used we do not need to modify the function. Modify function to include the code for h
explicitly of course we need to modify the function because we have indent that parameter.

536
(Refer Slide Time: 08:11)

So, here I am showing you the new version of bisection. So, what has happen over here is
that the red portions are were some changes happened. So, first of all we need to have we
need to include a new header file ok so this header file is called functional. So, this file
contains code which allows you right something like this. So, function is the name which is
defines in the standard name space ok. So, you want to use all this things you must include
this header file functional. So, we have the bisection function and we have a extra parameter
now and then if you remember here we were calculating that function who’s root we wanted
to find and now we wanted to find the root of h so we are going to calculate that h(xl) and
here also we were calculating that function xm and again since we now want to find root of h
we are just going to h(xm). What this going to do is this is going to call h is after all a
function which is present in the memory of the computer. So, it will call h with argument xm
and xl here and get that value and use that value that’s it ok. So, now we can use this together
with the same main program that we have written ok.

537
(Refer Slide Time: 09:41)

This together with the bisection function that we just showed will allow us to do what we
found desirable over here so this will indeed print the square root of 2 and the cube root of 3.
So let us do a quick demo of this.

(Refer Slide Time: 09:57)

So, many roots is this program so at the top I have written down the bisection as we had in
the slides then we have f and g also has in the slides and then over here we have our main
program.

538
(Refer Slide Time: 10:08)

So, main program is doing just what we said. So, ideally if this runs correctly we should
expect square root of 2 to be printed and cube root of 3 to be printed ok. So, lets run it so let’s
first compile it and then run it.

539
(Refer Slide time: 10:34)

So, indeed it prints out 1.41418 which is a good approximation to square root 2 and 1.4422
which is a good approximation to cube root 3. So, here is a exercise for you.

(Refer Slide Time: 10:59)

Now what is given here is a function which does take an argument a function f which takes
two integer arguments and returns a integer and it is somehow using this inside and it is going
to return this result value. What you are suppose to do is write a main program which calls
this twice with appropriate functions past for f. So, that the first time around it should return
the sum of the numbers between 1 and n. The first call should return the sum of numbers and
in the second call should return the product of the numbers one through n. So, this should be
n factorial.

540
(Refer Slide Time: 11:49)

And here is a little bit more detail exercise was you supposed to take a function and range of
x values and y values. So, you should plot the values of the function which start at x0 and go
to x1 and which lie in the range y0 and y1. And to look nice you should do things like maybe
plot that rectangle or show that rectangle maybe leave some margin just try to make it nice.

But here is a really good use of how you might pass a function. If you want to find or show
the plot of the function then you might want to write a single function which does the plotting
and to which you can just pass functions whatever functions we want.

541
(Refer Slide Time: 12:36)

So what we have discuss. So, we say that we often want to right function that operate on
functions. So, say for example functions which find roots of their function or plot function.
Such functions can be written conveniently because C++ provides a mechanism to pass a
function to another function and for this you need to include the header file functional which
tells you which allows you to define the type of the functions you are passing. This concludes
this segment in the next segment. I am going to talk about lambda expression which are
which is one more way of doing all this and a little bit more convenient way at time. So, we
will take short break.

542
An Introduction to Programming through C++
Professor. Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology Bombay India
Lecture 14
Advance Features of Functions Lambda expressions
Welcome back, in the last segment we discussed functions which operate on functions. We
are going to continue the theme and now we are going to describe something called lambda
expressions, which make it easier to pass functions to other functions. Lambda expressions
originated from lisp, and in lisp they were present maybe in the 50’s-60’s something like that,
1950s-1960s and in C++ they have been present at least for 15-20 years now.

(Refer Slide Time: 00:57)

So, a lambda expression is an expression which represents a function and the function does
not really have a name. So, it is just sitting there but it does not have a name. Here is an
example: so, square bracket into parentheses double x into braces return x times x minus two,
is an expression and it represents a function. And in this case, it represents a function,
f(x)=x^2-2. The general form of this is the square brackets first, and the square brackets; we
will tell you what they do in a little bit later, but first there is the parameter list. So, x is the
parameter over here. If the function that you want to represent has more parameters, you just
put it here just like a regular old parameter list and then this is like a regular old body, in this
case the function is really simple, so you just have single return statement. But, in general,
you can have a whole a complete function here over here, however complex you want to
make it.

543
So that is what a lambda expression is. Now, what can you do with it, well the simplest thing
that you would expect is can you apply it, or can you use it to operate upon some arguments.
So, yes you can.

So, here I have shown this lambda expression; which is the function x^2-2 and that is
operating on 3.5, so, it is computing, f of x f of 3.5 where f of x is x square minus two. So,
this evaluates, x times x is 12.25 minus 2. So, this evaluates to ten point 12.25 as you might
want and we can certainly write, z equals square bracket double x all of these 3.5 and then z
would be said to 10.25.

The more interesting thing for us is that, you can pass it as an argument I guess I should say
to function such as bisection. So, in the main program that you saw earlier (we had) we were
printing out the value, square root of 2. So, there we wanted to pass a function, where x
square minus 2. So, there we wrote a function and past its name, but here we can just send the
expression for the function x square minus two instead.

So, this is all that is needed, I can write this in the body of my programme, and this will call
bisection with this function. And this will work, so this will indeed produce a square root 2,
the bisection will return square root of 2. So, this is as good as defining a full function
outside your main programme and giving it a name (say whatever) f as we called it and
sending f over here. But you do not really need to do that, you can just make this something
local.

So, here as I read my code, I can see that am just trying to find the square root of 2. I do not
need to go to some other place. So, basically this is going to make your programme less
clutter and it will improve local readability.

544
(Refer Slide Time: 04:49)

Now, am going to, some comments about this general form. So, the parameter list is comma
separated as usual as I mentioned earlier, body is like the body of any function. Now, the
return type is not stated explicitly. So, in a huge-well function the written type will be stated.
And in this case the C++ compiler looks at the return statement and says, the return statement
is inferring this type of value and therefore the return type of function must be this.
Sometimes it is not possible to infer the type, and, in that case, you can specify it explicitly.

So, for example: here is another form, in which am saying that look, this function is supposed
to return something of return type this. So, as an example: I might write all of this and inside
I might have a return statement returning one. But now C++ complier cannot figure out what
one is, one can have several types: one could be short, one could be long, one could be int
and therefore it is desirable to specify the type and that is how you specify, over here.

545
(Refer Slide Time: 6:12)

Lambda general expressions can be more general. So, here is a problem that needs that higher
generality, so the problem says, write a programme that reads a number from the keyboard
and prints its square root using the bisection method. Now, of course you could again go back
and ask, look do you need to modify the bisection method, but (now it) we said, look that
does not seem very elegant and another thing is that you may not have the code, you may
have the object module in which case there is no question of modifying it.

Now, this can also be written with this more general lambda expression. So, here is the code
fragment, so, suppose we want the square root of z. So, what are we going to do, we are
going to first read z. So, we are going to declare a variable to store z, and we are going to
read a value into it.

And after this we are going to have a call to bisection, almost like what we had earlier. So,
double x the function is the same, except that here now we want to calculate the root of x
square minus z and not x square minus 2. So, this root is being calculated, the root of x square
minus z is calculated. And the z is taken or captured from outside of this body, so this is the
body. So, normally you expect everything every variable to be used, that is used over here to
be defined inside the body, just like a regular function.

But, you can do a little bit more, so I can put a variable over here which appears over here as
well or I can put an expression as I have done, which uses variables which appear outside
which have been defined outside. So, now we have to tell the C++ compiler that am doing

546
this because the C++ compiler is always worried, that look, are you doing this deliberately or
are you making mistake.

And therefore, just to indicate, that this variable is being captured from outside, inside the
square brackets, we have to put in z. So, this says to the compiler, I am going to use the value
of the variable z which has been defined outside. And now I can use that variable inside over
here.

So, the z inside those square brackets says that, the lambda expression will capture, that is the
technical term used, the value of z from the function in which the lambda expression is
written. So, this lambda expression is written in this code fragment, which is a part of main
function. And z is the variable defined in the main function and I can use the value of it, the
value of it will be substituted over here, and then this function will be constructed. And then
passed to bisection. And without this, the body of the lambda expression cannot refer to
variables which are defined outside. And furthermore, I should say that if I want to capture
more variables, I can just put them here, separated by comas.

(Refer Slide Time: 9:50)

So, am going to give a demo of this programme, and let us look at it. So, this is the
programme, as you see, this bisection function is the same as before, nothing changed. And
over here and I am indicating this variable capture and finding the root of x square minus z
and I am reading the value over here.

547
(Refer Slide Time: 10:09)

So, lets compile it. let’s run it. So, now I want to give it value, so let us try two, so it is
printing the value that we have seen before, the correct value, nearly correct value, of course
this is an approximation to certain number of decimals of bits. So, let us try one more, so
maybe, let’s give it a value which is perfect square. So, it is printing out 4.9997. So, again as
I said, this is going to print an approximate value and indeed it is a close enough value.

548
(Refer Slide Time: 10:53)

Here is an exercise for you. So, you are given a piece of code and you are supposed to tell
what that function does. So, you should be reasonably you should be able to figure out
reasonably quickly, from knowing, what lambda expressions are. And in any case, you can
execute it to see what it does.

(Refer Slide Time: 11:14)

Here is another somewhat elaborate exercise. Now, in this case I have given a code, in which
a function is being passed. The function that is being passed is not going to return anything
nor is it going to take any arguments. And it is called FD, and that function FD is going to be
called. So, this is going to be something which draws a square presumably and its going to

549
repeat 4 and here you would have seen the line forward 100 or something like that and then it
turns. Now, instead of doing forward 100, you can supply some different command through
FD.

(Refer Slide Time: 12:04)

So, for example: you might say, look instead of just going straight and drawing the square,
maybe I want turtle to do funny things like this. So, what you can do now is, I can write a
single function square and I can pass to it, the function which does this, and that function will
be used to draw the four sides.

So, essentially by supplying the appropriate functions you can do other things. So, maybe the
other thing you could do is supply a function which draws a dotted line. Or you can just
supply FD, forward 100 and it will draw the square. So, whatever it is, but you can have the
same square function draw squares which are sort of decorated in a different manner. Now, it
turns out that you can do more complex variable capture.

550
(Refer Slide Time: 13:08)

So, what you have seen so far is that, if you place names of variables inside this you enable
the values of the variables to be used inside the body of the lambda expression. But you can
also cause the lambda expression to not take the current value but take the value of the
variable at the time the lambda expression is actually evaluated.

So, during the time when the variable when the expression is evaluated and then the value
changes, you can figure out what the value is. And you can do that, and it is discussed in the
book, but it will not be considered this course, because this is just a little bit too elaborate and
we are not going to really make interesting use of it.

551
(Refer Slide Time: 14:06)

Alright, so, what have we discussed, we have said that lambda expression evaluates to
nameless functions. We can evaluate these by suppling arguments or pass them to functions.
We also said that, lambda expression can also capture the values of variables defined in the
function in which the lambda expression appears.

So, this concludes this segment. In the next segment we will discuss, functions, a feature of
functions, were you can write functions so that you specify default values to some
parameters. So, we will take a break here.

552
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 14 Part – 3: Advanced Features of Functions
(Default values to parameters)

Welcome back. In the last segment we talked about the lambda expressions. In this segment,
we are talking we are going to talk about how to specify default values to some parameters of
of a function.

(Refer Slide Time: 0:37)

So as a motivating example suppose we are drawing lots of squares, and say most of these
squares are black but maybe for some we want to specify a color, wouldn’t it be nice if we
can say if I do not tell you what colour to use, make it black. C++ allows this, okay so here is
how: one or more parameters occurring at the end of the parameter list can be given default
values, you can choose. If you have 10 parameters, you may say that the last 3 will have these
default values. So if there are n parameters and suppose you have specified the default values
for last m, in that case you must give in your call, you must specify at least the remaining,
the values for the remaining arguments. So, again say I have 10 parameters and I have
specified default values for the last 3, then in my call I may specify at least 7 values and these
values will go to the first 7 parameters. Well, what happens if I specify 8? Then, instead of
using the default value of the 8th parameter, I will use the 8th value that I specify. What
happens if I use 9? Then, instead of using the default values for 8, for parameters 8 and 9, I
will use the 8th and 9th values that I specify. So, in general if you give n-m+r arguments then
the last m-r will be, will take default values.

553
And r of the arguments for which default values were supplied will not use the default values
but instead will take the values that you have supplied. So I am going to do a somewhat
elaborate example, so it is kind of squares but these circles are simpler than squares and
therefore we are going to use a circle example.

(Refer Slide Time: 03:09)

So the goal over here is that we want to draw a circle or really a disc because it is meant to
be, it could be a solid disc, a filled disc. So what is the function? What is the function call?
Well, we are going to first specify the center of that circle and then where the parameter
requires us to specify the radius but by writing equal to 10 we are saying that look, if the user
does not supply if the call this parameter is not, value is not given then the value 10 should
be used. Then there is an additional parameter where you may specify a colour but if you do
not specify anything, the colour black is assumed. And finally there is a parameter ‘fill’
which is going to be true if you omit it, alright. And what is going to be drawn? Well, first of
all a circle is going to be drawn. Then we are going to set its color to call, the color the
parameter over here. Now the actual value that we are going to use could be black or the
actual value that you specify in the call and finally we are going to decide whether that circle
should be filled with that color or not. And whether to fill it is going to be dependent on this
parameter. If you did not specify an argument corresponding to this parameter then it will be
filled. Otherwise, it will not; if you specify a false argument it will not be filled. Alright. And
then finally that circle that you drew whose colour you set and you decide that to fill it or not
fill it will be imprinted. So you remember that if you call a function then at the end

554
everything that is created inside this function goes away. But if you imprint it then that
imprinted picture will stay on the screen.

So I am going to show you the code which uses this.

(Refer Slide Time: 05:25)

Alright. So, it is the same function first and now I am calling this function with different
number of arguments. So first I am going to call it with 100, 100, 20 which says that the
center is going to be at the coordinates 100, 100 and the radius is 20. And then the color is
going to be blue and the fill value is going to be false. I have specified all the parameters I
have given arguments corresponding to all the parameters, so this should produce a blue
circle but which is not filled and of radius 20. Now here I have changed the center position,
radius remains the same and color remains the same but I have omitted the last argument. So
I have only given 4 arguments but if only 4 arguments are given then this last argument is
taken as true. So this should produce a blue circle which is solid with color whereas the first
one should be a blue outline but no color inside, then have a circle with center 300, 300 and
radius 20. So what will this do? Well, only 3 arguments have been specified. So, this
argument is specified, this argument is specified, this argument is specified.

The last 2 arguments are not specified, so the default values will be used, so the default value
for this is color black and the default value for this is true. So, this should draw a solid black
disc centered at 300, 300 with radius 20 and what does this draw? Well, even this is not
specified, so this if this is not specified the radius is 10.

555
The last call will draw a disc centered at 400, 400; its radius will be 10, its color will be black
and it would be filled. So let us see and then the program will wait until you click so that you
can see what you have drawn. So, let us see what this how this works out.

(Refer Slide Time: 07:41)

So let us compile it and run it. So, exactly as what as we thought, so we have a blue disc here
but not solid, then a blue disc then a black disc and finally when we just supplied the center
even the radius was taken from the default value and that was so we have a smaller a smaller
disc which has been produced.

556
(Refer Slide Time: 08:25)

So here is an exercise based on this notion of default values, so the k norm of a math vector x,
y, z whatever is defined to be the kth root of x to the k plus y to the k and so on. But most the
most common norm that is used is the 2 norm, so this is kind of the Euclidean distance like
thing. If I have a vector, a 2-dimensional vector x, y then the call x, y, k should really give me
the kth root of x to the k plus y to the k. So, the kth root of all of this but I want to be able to
make a call norm x, y without passing the last argument so that in that case the default value
of k should be 2, so this should really return the square root of x square plus y square.

As I said, the default value over here is make to correspond to the to what happens most
commonly and to help you write all of this, you may note that the function pow of x, r returns
x to the r for any r including say 1 over 2 or 1 over k. So if you use that then this should be
simple enough to write but you will have to use the feature of default values.

557
(Refer Slide Time: 09:56)

Alright, so what did we discuss in this? So we discussed how to give default values to the last
parameters in the parameter list.

And one point to note in case it is not clear is that if you want to specify a default value for
the rth parameter, then you must specify a default value for all the subsequent parameters as
well. And as we saw this can help you write programs compactly and you can sort of make
the common case a little bit simpler.

Next, we are going to talk another feature talk about another feature related to how you
define functions - the so called overloading of functions and we will also conclude this
lecture sequence. So we will take a quick break.

558
An Introduction to Programming through C++
Professor. Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology Bombay India.
Lecture 14
Advanced Features of Functions: Function overloading and lecture conclusion
Welcome back, in the last segment we discussed how default values can be given to
some parameters in a function that we are defining. In the next segment we are going to
discuss another feature which can make it easy we can make it more convenient to
write certain functions and that is so called overloading of functions. And in this
segment will also conclude this entire lecture sequence.

(Refer Slide Time: 00:47)

So, C++ allows you to define multiple functions with the same names, provided they
have different argument lists. So, the term overloading is used and perhaps we should
really be saying overload the name, overload in the sense that the same name means
some different things and the same name can be used to refer two different functions.
So that is what C++ allows.

559
(Refer Slide Time: 01:17)

So suppose you want to write a function to compute the area of a graphical object. Now
the name area seems like a good name and perhaps you might want to use the same
name to find the area of a circle or to find the area of a rectangle after all what you are
getting out is the area so why should you use a more complicated name?

Now C++ allows you to do this and there is no explicit new feature that explicit new
construct that I am going to talk about you just have to do it that is all. The only
requirement is that the parameter lists should be different. So long as the parameter
lists are different you can do it and the parameter lists are need to be different.

Because that is how C++ will note that the two functions actually are different,
otherwise if you write f of some x and there are two definition of f of x that is not
allowed but if you write f of x where x is of type real and if you write f of x where x is
of type int, then C++ will know which function to use if you indeed have two separate
functions defined. So I am going to show you this file area.cpp in which I have written
such functions and let us get to that.

560
(Refer Slide Time: 2:48)

So here is the first definition of area and we are having area function area which is
going to written in double and its taking as argument a circle c. So, remember we said
that type of the shape, the name associated with the shape is the shape itself. So, you
can pass that shape over here and we do not want to copy that shape and therefore we
are passing the reference. But whatever we are passing it has type circle and it’s a
reference to a circle object.

Now inside this function we can extract the radius of that circle so there is a command
getRadius so I can write c.getRadius and that will get me that radius of that circle. And
now we know the area of the circle is PI r square. So this is a simple CPP name, the PI
stands for 3.1415192 whatever the expansion is to some large number of decimal
places and we just multiply pie by r by r and written the result. So this area, this
function expects u to send it a circle a reference to it and it will calculate the area and
return that value. Then I have an area of a rectangle so again what is expected over here
is a rectangle object should come, rectangle name should come but a graphical object
but what is actually coming over here is the reference to it. So this r really refers to the
graphical object in the calling function. And, so rectangle can be operated upon by a
command getWidth so that the command gets the width of the rectangle, and this
getHeight will get the height of the rectangle and if you just take the product you will
get the area. So, that is what this area does.

561
So in this main program I have first something which creates the canvas, then I am
going to create a rectangle. This rectangle is centered at 100-100 and it has width 50,
height 70. This circle is centered at 100-100 and it has radius 100 as well. Now the
finally I have command which will calculate the area of circle as well as area of the
rectangle. So, before proceeding further let us see if we can guess what this area should
be.

So, the radius of the circle is 100, so PI r square is going to be PI times 10,000. So it
should be something like 34,109 something-something so it should be that is what it
should be. And the area of the rectangle well the width and the height are 50 and 70 so
the area should be 3500. So let us see whether that what the program prints. So let us
compile this and run it.

562
(Refer Slide Time: 06:07)

So indeed the program has drawn the square and the circle, and this whole thing is a
500 by 500 canvas so it is centered at 100-100 as you might expect. And let us see
what area has it printed out. Yes, it has printed out 31415.9 and you may see the
3.14159 is the value of PI so that is just multiplied by 10,000. And the area of the
rectangle has indeed been printed to 3500 and that is correct because the width is 50
and height is 70 so let us click to stop that program.

563
(Refer Slide Time: 7:00)

So, here is the quick exercise, so the area function that we wrote was taking shapes as
arguments. But you can have additional area functions and you are asked here to write
an area function so that if one double argument is given it should be interpreted as
requesting the area of the circle with that radius. And if two double arguments are
given it should be interpreted as requesting the area of a rectangle with those sidelines.
So the code itself is not complicated but the point is that if you can define these
functions which take, which have different argument lists, in this case the argument list
is a double and for the first one and two doubles for the second ones, and in fact you
can have all the four functions existing at the same time.

Because the argument for the very first one was a circle, and for the second one was a
rectangle, and then the third one is a single double, and the fourth one is two doubles.
So all such, all four can be defined and depending upon what arguments you pass to the
appropriate function will be executed. So that concludes this entire lecture sequence so
let me make some remarks.

564
(Refer Slide Time: 08:34)

So, first I should observe that it is often useful to pass functions as arguments in a
function call and there are many examples of this. So, common examples are writing a
single function that calculates the roots so I will write a single function that calculates
the roots and to it pass the function whose root I need, so I do not have to write a
separate function to calculate the root of different mathematical functions and this goes
not only for roots, but also for numerical integrals or you might want some series.

So for solving series also you can do this and there we saw that you can pass functions
by specifying their name, or by giving the lambda expression and one method that I
have not discussed in this lecture sequence is a C style method.

So, the C language from which C++ has originated had a different method and that
method is a little bit more complicated and if you are using C++ you might as well use
the nicer methods. And I did not discuss it today but for completeness it is discussed in
the book.

Though, in this course we are not expected to know it. Then we said that C++ allows
default values for the last arguments in a function and then we also said that C++
allows defining many functions with the same name provided the parameter types are
different. So that concludes this lecture sequence and as always I will suggest to you

565
that please look at the chapter and the problems given at the end of the chapter and
please solve them for practice, thank you.

566
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 15 Part - 1
Array Part – 1
Introduction
Hello and welcome to the NPTEL course on An Introduction to Programming through C++, I
am Abhiram Ranade and this lecture is going to be on arrays. The reading for this is chapter
14 of the text.

(Refer Slide Time: 0:48)

So let me begin with an obvious observation, so computers should generally deal with large
problems, large computations and large data. So for example, we may want to simulate what
happens when many balls are moving around in a box? Of course, this is not, these are not
real balls, they might be gas molecules and we maybe simulating a gas and what kinds of
effects it has on the balls or pressures and things like that.

Given altitudes of various points in a lake, find how much water is there given the water
level. So this might well be a computation that we might want to do. Or given the road map
of India, find the shortest route between two cities and this is probably something that you
might already have used, you might already have used a trip planning program.

567
(Refer Slide Time: 1:36)

So computers handle a lot of data and how do they do that? So there is a very very basic
problem. If you want to have lots of data you want to have lots of variables presumably. So,
if you need lots of variables, then just writing out the variable names to use would be really
tiring. So maybe you want 1000 variables to represent pressures at 1000 points, then you may
have to write something like this. “double pressure1, pressure2, pressure1000”, nobody
would really want to do that.

So arrays solve this problem and actually a little bit more. And arrays come to us from C
which is the precursor of C++ and in C++ there is a more modern, a somewhat nicer solution
to this problem called a vector class, so we will discuss this a little bit later. But, arrays are in
some sense simpler to understand and they do most of the work anyway so whatever we are
going to do in this lecture sequence will be definitely useful in any case.

568
(Refer Slide Time: 2:58)

So here is what we are going to do, we are going to talk about how to create arrays and how
to access their elements. And then why do we use arrays? So well we are going to use arrays
for storing sequences, storing sets, storing something which we might call a queue and
storing multiple graphics objects. And we will do lots of example programs along the way, so
that is, that is the outline for this lecture sequence.

(Refer Slide Time: 3:28)

So, let me begin with a definition of arrays or rather an example. So, if I want to define the
pressure variables which I mentioned in the last slides, in the last few slides, then I just need
to write this. Now this essentially defines 1000 variables and these 1000 variables are called
array elements and together those variables comprise what is called an array. And the

569
variables you can think of as we named not pressure0 onward but pressure[0] as the first
variable.

pressure[1] as the second variable and so on, till pressure[999]. That is effectively the name
of the last variable we are creating, using this statement. Notice that the numbering starts at 0
and not at 1, so the variables are not named pressure 1 through pressure 1000, but they are
named pressure 0 through pressure 999, all within the indices, the 0, 1 to 999 are in square
brackets.

So the general form is the type of the element data type, array name and the size, the size is
also called the length. So in our previous example the data type was double, every element
was of type double, the name of the entire array was pressure and it had a 1000 elements.
And the moment you say it has 1000 elements you are also saying that the numbering goes
from 0 to 999.

And it is customary to say that array name[index] gives the indexth variable, where of course
index goes from 0 to 999 or in general index goes from 0 to size-1, index has to be smaller
than size. Now, arrays actually end up being a little bit more than just a collection of
variables.

So this is because the index can be given as an expression, so I do not have to say 999 or I do
not have to say 47, I can put another variable name there and the value of that name will be
taken during execution, so this makes arrays really powerful and not only variable names, but
I can put in whole expressions there as I wish. And we will see examples of all of these
things.

570
(Refer Slide Time: 6:28)

So, what can you do with arrays? Well suppose we have declared our array in this manner,
then I can read into its elements. So, if I say cin and instead of putting the name of some
simple double variable I put in this pressure[0], which is also a variable., so this would cause
whatever the user types, the first thing to go into pressure[0] and the second thing to go into
pressure[2].

So you can use array elements basically wherever you can use ordinary variables. So I could
write this for example, this is just saying that pressure[1] so the element of the array pressure
at index 1 is assigned value which is the mean of the values of pressure[0] and pressure[2].
And as I said we could have the index be a variable, so here I have a for loop with the control
variable i going from 0 through 999 and we are reading consecutive words that the user types
into pressure[0], pressure[1], pressure all the way till 999.

So notice that we, this could not be written in general if we were, if we had to write a
constant in place of that square bracket, i square bracket, so it is really important that that
number be coming out of a variable. So in any case this will take the 1000 values that the user
types and place those 1000 values in pressure 0 through pressure 999, in the 0th iteration the
value received will be placed in pressure[0], then the value of i will increment, the next value
received will be placed in pressure[1] and so on.

And I can print out the values as well and again I could have written something like p*3.33
and for any variable instead of any variable I can put in any array element reference. Here is

571
another interesting statement, now this time i is going from 1 and not to 999, to 998, so what
is this doing? So it is saying pressure[i]=(pressure[i-1]+pressure[i+1])/2.

So the pressure in every element is made equal, is being made equal to the average of the
pressure in the previous and the next element, this is not, this is not a real computation, but I
am just giving this as an example to show what kind of expressions we can write. And here I
cannot use the array index i to start at 0, because if I did that then for i equals 0, this value
would be 0, but this value would be minus 1 and that is not allowed. So we want the index to
always be between 0 and the size, so less than the size. So the size is 1000, so this had better
be less than the size and so had this be. So, if in particular i had been 999, then this would be,
this would be 1000 and that would not be allowed. So therefore, we have carefully chosen the
bounds of this loop to be 1 and 999.

So the important point which I have noted is that the array index can be an expression, say for
example, here i-1 and i+1 or even just simple plane i is an expression, which will be
evaluated during execution and then the corresponding element will get used. Now, if we just
had written pressure[0], pressure[1], pressure[2]without the square brackets, we actually had
taken the pain of writing down all the 1000 names, we would not be able to write something
like this loop. Because over there, if your variable is pressure[0] one word then you cannot,
you cannot replace a part of a name by the value of a variable. So this is this, this square
bracket notation and the way we define arrays is really important.

572
(Refer Slide Time: 11:04)

Now here we have again the same definition and suppose I write pressure[1000]=1.2, to look
at it, it does not look bad. However, we said that the index or whatever appears in these
square brackets must be in range and the range in 0 through 1 less than the number of
elements. So this number is supposed to be, supposed to be smaller than 1000. So, if you put
a 1000 over here that is not good, that is a mistake, that is an error.

So here I have put the number minus 5 and that is also a mistake, so both of these mistakes
are said to be caused because the array index is outside the allowed range. And if the array
index is out of range, then it is a mistake and nothing really is guaranteed, the program may
run, but of course it cannot run correctly and so it may produce wrong results or it may halt
with a message. So you really have to be very careful when using arrays, you have to, you
have to be very sure that the indices are within the specified range.

573
(Refer Slide Time: 12:32)

Now, when you define arrays you can initialize them if you wish. So for example, this is an
integer array called squares with 4 elements and I want those elements to be 0, 1, 4 and 9. So
I can write them in this manner, so squares[0] will be 0, squares[1] will be 1, squares[2] will
be 4, squares[3] will be 9. Or, I have put down cubes and I have not specified the size, but
C++ will look at how many values we have specified and make cubes have that size. So here
the size 5 will be inferred by C++ even if you have not put it down and you can mix things.
So in the single statement I am defining an ordinary variable x, then I am defining an array
pqr with 200 elements and I am defining an array y with 4 elements, but I have not specified
its size and C++ will infer it.

(Refer Slide Time: 13:41)

574
So some quick exercises for you, so define arrays of in various ways, so please do try them.

(Refer Slide Time: 13:51)

So, what have we discussed so far? We have said that an array is a collection of variables of
the same type. So if the number of elements in the array is n, then the array, the array, the
elements are named A[0], A[1], A[n-1]. So A is the array name, and i is the, i is called the
index. Now the important point is that the index can be specified by an expression, and the
expression is evaluated and the result is used to determine which variable of these of this
collection you mean.

So we saw how to declare arrays, with and without initialization. How to get values into and
out of array elements. And next we are going to take some examples of use of arrays. So we
will take a quick break.

575
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 15 Part - 2
Array Part – 1
Marks averaging problem
(Refer Slide Time: 0:38)

Welcome back, in the previous segment we saw how to declare arrays with and without
initialization and how to access the elements, how to use them in computation, how to read
and read values into it and print the values.

(Refer Slide Time: 0:41)

576
Now we are going to see some larger examples of using arrays. So we are going to start with
relatively simple familiar sounding problem. So the problem is you are supposed to write a
program that reads in marks of 100 students in a class, and the marks are given in the order of
the roll number. And let us say in this class, the roll numbers happened to go from 0 to 999.
So yes, I know that the numbers usually do not start at 0, but just, just for fun let us say they
do start over 0, over 0. So in this class the roll number, there are 100 students and their roll
numbers go through, go from 0 through 99. So that is the first part of what is the program is
supposed to do.

After that students may arrive in any order, and type their roll number using the keyboard.
The program must reply to that by printing out their marks. So maybe first the student with
the roll number 43 comes, then the program is supposed to print out what marks student
number 43 got, then there will be 67 so marks for 67 will be printed, then there maybe 6 then
the marks for the student with roll number 6 should be printed, and so on. Now, if at any time
an illegal number is given then the program must terminate, so this is this specification, this is
what our program is expected to achieve.

(Refer Slide Time: 2:20)

So, what does the program look like? So we clearly should have an array in which we should
be storing the marks and so let us say we have an array of doubles and of 100 elements, we
need 100 elements because we have 100 students. Now the first step is to read in all the
values, all the marks that the students have received. And we were told that the marks will be
typed in this order. So first the marks were 0, then the marks were 1, then the marks were 2,

577
so it is natural to write this for loop, where in the ith iteration we are reading in the marks
obtained by student i and placing that in marks of i.

And then there is the loop in which we are going to wait for students to come and type their
roll numbers. So for this lets say we have a variable called roll number and we will print out a
message saying roll number, so this will be a queue to the students to type their roll numbers.
So then we will read in whatever the students are typing and now if the students have typed a
valid roll number, then we should print out the corresponding marks.

So, if roll number less than 0 or roll number greater than 99 that is a invalid number, so in
that case we are going to stop execution so we are going to break out of this loop. Otherwise,
we know that the roll number that was typed in lies between 0 and 99, so in fact it is a valid
index as far as the array is concerned, so we are just going to print out marks of roll number
and that is the end of the loop. So if you break out of it, the program will terminate and that
would be the end.

(Refer Slide Time: 4:25)

Now let us do a slightly more interesting version of this where we are going to read in
everything, but we are going to print out the roll numbers of those students who got the
highest marks. So here is the program, so let us say that the marks array was defined as
before and we have read in the marks exactly as before. So now, we want to figure out first
what is the, what are the highest marks.

578
So for this we are going to have a variable called maxsofar, so maxsofar we are going to
initialize to 0 and the way to interpret this is that at the beginning of the ith iteration of this
loop we are going to make sure that maxsofar holds the maximum of the marks between 0
and i or 0 and i minus 1. So indeed, before entering the loop, maxsofar is the value of
marks[0], so it is indeed trivially the maximum amongst all say marks[0] all the way till
marks[i-1] which is 0 itself, so it is in fact.

So there is only one element in this set marks of 0 through i minus 1 because both of these
will be 0 and indeed maxsofar is that value. But this plan says that not only should this be
true at the beginning of the (ith), of the first iteration when i is 1, but it should be true for all
iterations. So if it is true for all iterations, when our body of the loop should make it be so.
So, what do we need to do?

Well so when we enter this loop, we know that maxsofar is the maximum amongst 0 through
i minus 1. So, if the next number marks of i is bigger than this then our marks, our max
should change. Otherwise, our max should be as before. So all that we need to do is to write
maxsofar is the max of maxsofar, whatever we have seen so far and whatever we see next, in
the next marks value.

So this max is a statement, is a function which is already defined in C++. And in fact we
know that C++, functions that C++ defines for math purposes are in this include in this
header file called cmath, so indeed max comes from that header file cmath, that is it. So what
would be, what would be true at the end of it? So on the 99th iteration, what would be true?
So on the 99th iteration what would be true? So i equals 1 and i equals 99, so at that point
maxsofar should hold the maximum of everything from 0 through 99 and indeed that means
maxsofar will have value of the maximum possible marks. So at this point we have identified
what the maximum marks so far are. So maxsofar now holds max value in the entire array.
Now, we just have to check which are the marks or which are the roll numbers really who
have got that many marks.

So again go over all the elements this time even including 0 and we are going to check are the
marks[i] equal to maxsofar? If so then we should print out i so that is it. So there are two
ideas which have been used in this, which are worth noting. So in this first part, we are doing
something which might be called accumulation.

579
So maxsofar is accumulating the maximum value, it is keeping track of the maximum value
and this is a very standard idiom, here we are keeping track of the maximum value, but you
may keep track say of the sum of all the values. Again it is going to be something like that
instead of max of maxsofar, and max i, it might be something like plus of something and
something, something and marks[i], so that is one idiom.

And then in the second part we are going over all the elements again, but we are printing out
only some subset that subset which satisfies this condition. And in other words we are
filtering out things. And therefore, this idiom is often called a filtering idiom.

(Refer Slide Time: 9:25)

580
So let us see a demo of this and this is going to be in file highest.cpp which I have created
already, but I am going to show it to you. So let me get to that file, so highest.cpp is this. So
you can see that we have used marks[100] array as before and then we are doing cin marks,
all of this, and this is our max array. Now this is the program that you have seen, now I am
going to make a change it to it because I do not want to type all the (100 element) 100
numbers. So I am going to change it so that I will only use 10 numbers so I should really
change all the 100’s to 10’s.

(Refer Slide Time: 10:38)

581
Alright, so let us see, so let us compile this and let us run it. Now, when I am going to run
this, I am going to do something slightly unusual, something that you may not have seen so
far, you have not seen so far in this course. So normally I am expecting, so when I run this
program C++ expects me to type the values from the keyboard. But, if I have to test a
program often then typing the values, especially 10 values even is a bit cumbersome.

So what I am going to do instead, is that I have already typed in those values in this file
highest.dat. So maybe I should show you that first. So, if I do this highest.dat, it will show
you that I have already typed in these values, so these are my 10 marks, so marks for student
0, roll number 0 are 65, for student roll number 1 42, 2 78 and so on. So these numbers I have
already typed.

582
Now if I do ./a.out and I say <highest.dat, then instead of taking input from the keyboard this
program will take the input from that file, so let us see that. So it took the input from the file
and then it has printed those roll numbers for which the marks were the highest possible, so
let us check that. So, if we look at this which were the highest marks? Well 91 is the highest
mark and where did this appear? So this is roll number 0, this is roll number 1, 2, 3 so indeed
roll number 3 got 91, 4, 5 so indeed 5 got 91, 6, 7, 8, 9 so roll number 9 also got 91, so it has
indeed printed out things correctly.

(Refer Slide Time: 12:54)

So here we saw that our program this program was executed, but we changed the number of
students so that only 10 students were used.

(Refer Slide Time: 13:10)

583
And here the input data, sorry the data was taken from the file rather than by rather than
through the keyboard because we wrote <highest.dat.

(Refer Slide Time: 13:28)

So a small exercise for you, usually we will have roll numbers starting at 1 rather than 0, to
handle this a simple strategy is to store the marks of roll number i in marks[i-1]. So we have
written two programs so far, so this exercise says modify both the programs so that they
follow this convention. So they follow the more usual convention that student roll numbers
start at 1 and not at 0.

(Refer Slide Time: 14:04)

584
So what have we discussed in this segment? Well, we saw a couple of simple programs
involving arrays. And an important point to note is that although roll numbers are involved,
we did not actually store the roll number anywhere. Because the index played the role of the
roll numbers. So because we stored the marks of roll number 0 first, then the marks of roll
number 1, the marks of roll number 2, we sort of implicitly made a correspondence between
the role number and the mark.

And then the program involved a few important idioms. So going through all the elements of
an array and filtering out the elements to print and also the accumulation the maximum of all
the elements in a variable. And we will continue with more examples, but we will take a
quick break.

585
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 15 Part - 3
Array Part – 1
Histogram computation
(Refer Slide Time: 0:20)

Hello and welcome back. In the previous segment we saw a few simple programs involving
arrays and we discussed some idioms such as filtering and accumulating and we are going to
do more examples.

(Refer Slide Time: 0:31)

586
So this example that we are going to do is sort of a rather interesting example, it shows some
clever ways in which the array index can be used. So, what is the problem? The problem is
that we are supposed to read in marks as before, but we should print how many students
scored between 0 and 9, print how many students scored between 10 and 19, how many
between 20 and 29, and so on.

This is often done by statisticians to get a general sense of how well the people have scored,
so rather that looking at every mark which is lots of numbers to look at, they break it up into
ranges and see how many marks fall into the different ranges. So in this case now, our output
is going to be 11 numbers, so one number for the range 0 through 99, another number for the
range 10 through 19, 20 through 19, all the way to 90 through 19 and also for the range
starting at 100.

Of course there is no range, but since a person can get 100 marks, we need to have a way to
say that some person has got 100. So there are 11, there are 11 buckets so to say including the
last rather small bucket or the last bucket which may think of it, think of it as being between
100 and 109, but of course nobody is going to get more marks than 100 let us say. So we
have 11 possible numbers to output or 11 buckets sort to say into which the marks are
supposed to be put, so we declare an array called hist[length 11.

And hist[i] is going to store number of students getting marks between 10i and 10(i+1)-1. So,
if I use i equals 0, then this becomes 0 and 10 minus 1, and 9. So that is indeed the first range.
If I make this say i equals 5, then it becomes 50 and 60 minus 1 or 59. So those are exactly
the ranges that we want and those are the buckets that we want as they are often called.

587
So, what should we be doing? So, if I read a certain mark from the keyboard, the user is
going to type the marks from the keyboard, maybe the teacher is going to, or somebody is
going to. Then we have to decide which of these ranges it belongs to and we are going to add
1 to hist of that i. So that is what we are supposed to do. So given a mark v, which of these
elements should we increment?

So let us take an example, suppose I am given the mark 58, so what should I do? So I should
increment the bucket corresponding to the range 50 through 59, which is the bucket with
index 5. So we have chosen these indices conveniently, so in fact the most significant digit of
your mark or rather the digit, the number obtained by dropping the least significant digits
gives you the index of the element of hist that you are supposed to increment.

So for example, if I get 23 then I should increment hist[2], if I get 47 I should increment
hist[4], because hist[4] then this 47 is going to lie in the range 40 through 49 and that is and
how many marks lie in this range is exactly what is supposed to be stored in hist[4]. So, if I
get a new mark in this range, then this number should go up. So, how do we do this? Given a
number in the range 40 through 49, how do we get a 4 out of it? Well, that is very easy.

588
(Refer Slide Time: 5:11)

So we just do integer division, so we assume that v is an, or we convert v into an integer if it


is not already an integer and we divide by 10 and we know that if we divide a integer by
another integer, we get the truncated division. So, if we indeed divide say 47 by 10, then we
will get 4 because the remainder 7 will be thrown out. So that is all there is to hist.

So our program is that we start with, so we have 11 buckets first of all, so we are going to
make all those buckets be 0. So at this point we have not read any marks and therefore, the
ranges, all the ranges (containing) contain 0. So no mark has been read. Now, here we are
going to read one mark after another and when we read a mark, so we are supposed to figure
out, which bucket we should increment and increment it.

So as we said we should divide, we should divide the marks by 10, but however, notice that
our marks are double. So of course our marks could be 47.5 for all you know. So, if I write
int of marks then I get first of all, I get the integer part and then I get the integer division, so I
get now by doing the integer division I get to know which element of hist I have to increment
and so I just go ahead and increment that element, that is all there is to it. So after this I can
print out the values.

589
(Refer Slide Time: 6:48)

So let us see a quick demo. So this file I have made a little bit different from what you have
seen. So first of all instead of putting in numbers such as 10 and 11, which are confusing to
the reader, it is much more customary to give these numbers names. So again instead of using
100 students we are going to use 10 students because you do not really want to worry about
100 students in a simple example.

So n students is going to represent how many students there are and therefore, in the rest of
the code if you look at nStudents, you will know, okay that this number is actually
representing the number of students. Then also there are nbuckets, so nBuckets is a variable
which is going to be 11 because we wanted 11 buckets. So we declare an array with 11
buckets and this is the plan that we already had, so there is, so nothing has really changed.

590
So then we set all the histograms to be initially 0, all the buckets to have 0 elements initially
and then we are going to read in all the marks and this time instead of saying 100 over here or
10 over here or whatever it is, we are going to say nStudents. Because we just want to alert
the reader that look this is being done once for every student.

Then we read in the marks and then we divide it by 10 but only after converting it to an
integer. So I could have, this 10 I could have written as what is the width of a bucket and all
of that, I really should do it, but I am being a little bit sloppy here. Alright, and then finally I
am going to print out the contents of all the buckets. So I am going to print a message saying
in the range i times 10 to i times 10 plus 9 there are so many, so many marks, so that is what
it is. So let us do this, let us run it.

(Refer Slide Time: 8:54)

591
Let us first compile it, so s++ hist and then, I am going to use the same sort of numbers as I
had earlier. So let me show you the numbers, so let me do this, highest.dat, so these are the
numbers. And for these numbers this was the histogram, so let us read that, let us check if it is
correct. So the histogram that we computed says that there are no numbers in the range 0
through 9.

Indeed there are no such numbers, nothing in fact all the way till 40 to 49 and there are 2 in
the range 40 to 49, is that true? Let us see, there is 42 and yes, there is only 44. So there are 2
here, nothing in the range 50 through 59, 2 in the range 60 through 69, well there is 65 and
66, yes that is correct, 70 to 79 there is 1 so there is 78, 80 through 89 there is 88 and 83 and
90 to 99 there are 3, 91, 91 and 91 and nobody gets marks in the range 100 to 109, so it has
indeed done the right thing.

(Refer Slide Time: 10:21)

Alright, so what have we discussed? So we have discussed this idea of histogram


computation, which I said is an important statistical operation. So by looking at the histogram
we can get a rough sense of how people have done. So for example, in our histogram there
were no students who were getting marks in the range 0 through 10, 10 to 19, 20 through 29
and all those 0 said that look most students has sort of got good marks. So you can get sort of
a rough estimate, so that is what statisticians often like to do.

592
And the key ideas are that the index for accessing the array element is calculated in an
unusual manner. And integer division plays an important role in this. Next we are going to go
along with this theme of marks and displaying marks and we are going to look at another
variation of that problem. So we will take a quick break.

593
An Introduction o Programming through C++
Professor Abhiram G. Ranade
Department of computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No.15 Part-4
Array Part-1
Marks display variation
(Refer slide time: 00:19)

Welcome back in the last segment we talked about histogram computation. And that showed off
how the index which decides which element you are accessing can be, can be computed in a
somewhat clever manner. Now we are going to take another variation on the marks display
problem.

594
(Refer slide time: 00:44)

So in this variation the roll numbers are not consecutive in the range 1 through 100 or 0 through
99 for that matter but the roll numbers occupy a larger range, so maybe the roll numbers are
whatever 10 digits or whatever many digits that you have in your institution. And of course in
many institutions the roll numbers can containing can contain alphabets as well, but let us keep
things simple for now, let us say that the roll numbers only contain digits and further more let us
say they are at most 9 digits long. So they are actually numbers and in fact numbers which can fit
in an int variable. Alright so in this case, what is the marks display problem?

595
(Refer slide time: 01:37)

Well the teacher now does not have to just type in the marks but the teacher also has to type in
the roll number because there is no implicit roll number for which the ith mark is being typed. So
the teacher has to type 100 pairs of numbers roll number followed by mark, roll number followed
by mark. The teacher has to do this 100 times. Let us say the number of students in the class still
remains 100 and later on,

(Refer slide time: 02:11)

596
The ideas as before students arrive and each student types in the roll number and the program
must print out marks if r is a valid number. If r is -1 then the program must stop. So, what is the
program idea? Well we should use an array for storing marks but we now need an array for
storing roll numbers as well and our idea will be that the ith roll number that the teacher enters
will be stored in element rollno[i], which is our array for storing roll numbers. And the ith marks
will be entered into marks[i]. So, the data corresponding to student i will be present in rollno[i]
and marks[i].

(Refer slide time: 03:11)

So, when the student arrives, we have to examine each element of the roll number array and see
if it equals r. If so, we should print the corresponding marks. Otherwise maybe we should print
out some message. Here is the program it is a reasonably simple program. So let us try to just
write it.

597
(Refer slide time: 03:35)

So first we will declare the 2 arrays that we want and then here is the code that reads in the roll
number and the mark. So earlier we were just reading the marks and now we are also reading the
roll number the roll number is going to be typed in first which is sort of the natural thing to do.
Next this is the loop where the program waits for the students to type in their roll number. So,
this time we have dispensed with the message but I guess, we could have a message and we are
just reading in the roll number into a into a variable called r. And we said that, if r is -1 then we
should exit. So that is what this is going to do. Next, we now are going to do something a little
bit more elaborate we are going to check whether r is present in the array roll number. If it
present, then we should print out the marks corresponding to the index in which it is present. But
if is not present then we would like to print out a message so this found variable will come in
handy for that purpose.

598
(Refer slide time: 05:03)

So, here is the step were we go through all the entire roll number array to see whether the roll
number are that the user typed in is present in that array. So if rollno[i] equals r then we can print
out the corresponding marks and we will set found to be true. So, this is going to say look, I did
find the roll number and because I have found the roll number I do not need to do any of the
future iteration so I can break over here. So, that is really the end of that for statement as well.

(Refer slide time: 05:38)

599
So now observe what happens, so if the program in the control arrives at this statement. How
could the control have arrived over here, it could have arrived either because it came from this
break statement. So from this break statement, if it came from this break statement it is because
the program found the roll number and printed it out, in which case it has also sent set found to
true and therefore, this condition will not be true and therefore this massage will not get printed

And the program will just exit from here as it should. On the other hand suppose it went through
all this iterations, it went through the entire array rollno but did not find the roll number r
anywhere in that array. So, then that means this condition would never be true and therefore,
found would never be become true, so it would come to this point and found would still be false
but found is false then not found will be true and so now the program will print a message saying
the roll that you typed in is not found.

So, that was sort of polite message to say rather then tell the user nothing so that is what the
program is doing it is either printing out the marks, or it is printing out that roll number that you
have typed is incorrect. So that is the program so let us see a demo. This program is in a file
called generalRollNos.cpp

(Refer slide time: 07:17)

600
Now, this program is pretty much the same as we had earlier except for one change, so what is
that change? Earlier I said that the roll numbers would be typed in by the teacher from the
keyboard and the students would also type in their roll numbers from the keyboard. I am going to
make a slight change. Let us say that the teacher has earlier typed in all the roll numbers and the
marks into this file called generalRollNos.dat. Let me show you that file

This is this is a file that you can create however you wish by using an appropriate text editor so
this contains some roll numbers and the corresponding marks and in this case there are only 10
roll numbers and 10 marks.

601
So, this program is going to read the roll numbers and marks information, not from the keyboard,
but from this file and reading from a file in C++ is very simple. So first of all let me take you to
the reading statement so if you remember in this loop you are reading the marks and you had cin
over here so that was saying read in from the keyboard now you have something in here called
marksfile. What is this marksfile? Well it has been defined over here. So marksfile is the name
that you are going to use inside the program and it is going to be something called a stream it’s
going to be something called a input stream.

So, inside the program C++ likes to think of files as streams of information so somehow things
come to you flowing and those are those are input stream. So in fact this a special kind of an
input stream. It is an input file stream so you are declaring something called a marks file which
for your program is going to be an input file stream and which is going to be for the external
purposes. It is going to be this file, so this statement sets up the connection with the marks file
which is appearing over here and the file that you have on your system called
generalRollNos.dat.

So, instead so because marks file appears over here what you type in what you already typed in
into that file will redeemed and that will be taken in roll number I, roll number marks of i and so
on. So, basically in the first iteration the first word that file will be placed into rollno[i] and the
second word in that file will be placed into marks[i]. So, let me show you the file again

So, because of that loop the first time around this would be become rollno[0] then this would
became marks[0] this would become the next iteration this would be placed in mark in roll
number 1 and this would be placed in marks 1 and so on.

So reading from a file is a useful idea especially in situation like this where you have two roles
you have a teacher role and a student role and you can put the marks of 1 role into a file, because
that often is very convenient and I should point you to this header file that is included fstream so
you need to include this file fstream, if you want to use this this name fstream. So if you want to
have files, if you have input files in your stream you should have this header fstream.

fstream also allows you to use output files and will use output files at some point whenever we
need them. But I am not going to worry about files as such. This is something incidental and you
can you can see that it is actually very simple and from now on you can start using files in this

602
manner if you wish and there also discussed in the book by the way not in this chapter but in a
later chapter. So the rest of the code as I said is as before I have put in a variable or a constant
rather a name called nStud for number of students, and I have use 10, I do not want to have too
many numbers to type in and anyway the rest of the code is exactly like this so, that is about it.

(Refer slide time: 12:13)

Let us compile this and lets run it. So now what has happened is that the file that I showed you
has been read in and now I really should type in some roll number and see whether my program
is printing out exactly that roll number. Well I have forgotten the roll number, So what I am
going to do is I am going to do is print minus type in minus 1 if you remember minus 1 says ok
stop everything and quit the program so it did. So just to remind myself what was in that file let
me type out that file

603
(Refer slide time: 13:08)

So, This were the numbers in that file. So now if I execute ./a.out the program will expect me to
type in some roll number which is present over here, if so it will bring the marks otherwise if I
print in a non-existent roll number it will it will say that the roll number is not valid. So let us see
suppose I type 190370051, let us see so this is present over here, so I expect the program to type
91 so indeed it is doing that. But let us say I type in a roll number like 190380051 and this roll
number is not present, so let us see, so it does say roll number not found.So, you could keep
going in this manner but let me just stop and I can do this by typing -1, so let us get back to the
presentation.

604
(Refer slide time: 14:17)

So, a small exercise for you please modify the program, so that there are marks for two subjects.
So, when the user when the user types in the roll number let us say you should print the marks
for both one after another.

(Refer slide time: 14:36)

605
So, what have we discussed in this segment, we have said that if the roll numbers we said that
the roll if the roll numbers are not in range 0 through N-1 where N is the number of student then
we need to explicitly store the roll numbers. So for that we need an additional array and if want
to know the roll number the marks of certain roll number then we have to search through that
that additional array and so here we are storing roll number and marks. And usually we are going
to be given the roll number and we might want to print out the marks. So in such cases the roll is
sort of called the key to this data that we are storing and indeed this whole idiom that you are
given a key you go through your data and you see that key is present so if the key is roll number
you check the roll number array to see if the given key is present over there and if so print out
the other parts of the data so that idiom is a very common idiom.

(Refer slide time: 15:51)

Then we also used this found variable, the bool found variable. Just to see just to record whether
we have found the element we wanted because we were going to the end of the program either
after finding that element, or without finding that element and when we go to that go to that last
statement we would like to know did we come here, did we actually find that element, or did we
not find it. And so if we have an element bull it records what we did earlier and that will help us
decide, at the last statement whether we should print out a message saying you typed in a invalid
roll number which is what we should do, if that roll number was not found. So this bool variable
found tells us exactly this kind of information.

606
Next, we are going to look at polynomial multiplication which happens to use arrays in a rather
nice manner but before that we will take a small break.

607
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering IIT Bombay
Lecture No. 15 Part-5
Array Part-1
Polynomial multiplication

(Refer slide time: 00:19)

Welcome back in the last segment we discussed a variation on the marks display program in
which we needed to store the roll numbers as well as the marks. Now we are going to look at
another interesting use of arrays namely for polynomials representing polynomials and operating
upon them.

608
(Refer slide time: 00:39)

So let us say we are given 2 polynomials A(x) and B(x) this is what A(x) might look like
a0+a1x+a2x2+anxn. And this what B(x) might look like b0+b1x+b2x2+bmxm. In general m may not
be equal to n we would like to find the product C(x) equals A(x) times B(x), so you know the
product is going to look like this. There is going to be a constant term c0+c1x+c2x2+am+nxm+n.

So there are going to be m plus n plus 1 coefficients, So basically what is the problem? As input
we are given this numbers a0 a1 all the way till an so this numbers are given to us. You are also
given this numbers and we are supposed to find these numbers. So we are given n plus 1
numbers this m plus 1 numbers this and we are supposed to find m plus n plus numbers which
are this over here. So the question is-how to we do that? And first where do we store this
numbers? So by now the answer should of this you should store this numbers in an array so, it is
a natural to use an array of n plus 1 elements to store the coefficients of a degree n polynomial.

In fact we should store ai in array element with index i. So now we are supposed to generate the
ci, so how do we do that? So here is sort of the simple idea, so when we do this multiplication
every term over here is going to multiply every term over here so in particular let us say aixi is a
term in A(x) now that will multiply some term bjxj in B(x).

And if you just look at the product of this two terms that will be aibj times x to the power i plus j
what will be the effect of this term? So this is going to contribute to the coefficients of x to the
power i plus j, and what is that coefficients? That coefficients is c sub i plus j. So basically the

609
idea over is that we form every such possible product and then we look at well, if this first the
coefficient of x to the i if this was the coefficient of x to the j.

Then the product that we calculate should contribute to the coefficient of i plus j, so in fact we
should add the product into the current value of c i plus j. So that is exactly whatever algorithm is
going to be. So let us say for simplicity we have two polynomials both of degree 10 and we want
to multiply those.

(Refer slide time: 04:20)

So clearly, a will have 11 coefficient so will reserve an array with 11 elements for it and array of
11 elements for b and c will have 21 coefficient so will use an array of 21 elements for c. So let
us see how do we read them reading is straight forward so we are going to read A first starting
with a0 going all the way till a10, so we so when I say read in the polynomial A(x) well the
polynomial is determined by the coefficient. So I really mean reading the coefficients and of
course you know by now that reading in the coefficients is done simply using a for loop, so by
the way for loops are sort of the ideal things to use with arrays because the index can be the
control variable can simply be the index, next we are going in the polynomial B in a similar
manner and now we are going to generate our polynomial C. So first we have to set all the
coefficients in it to 0 so the coefficients range from 0 through 20 so we are going to set all those
coefficients to 0. And next we are going to form the product of every term in the A polynomial
with every term in the B polynomial.

610
So, i is going to be the index which is going to range over the A polynomial the terms in the A
polynomial and j is going to be the index which ranges over the terms in the B polynomial and if
we form the product ai times bj. We said earlier it should affect c of i plus j. So that is exactly
that has what is we are going to do so we are going to add ai times bj to c i plus j, remember that
this plus equal to the short form for saying ci+j=ci+j+aibj.

So that is it the entire multiplication after that we just have to print out the result. Now I am
going to just describe another polynomial multiplication algorithm and this algorithm uses sort of
an interesting manipulation of the indices.

(Refer slide time: 06:54)

So the problem is really the same we are given polynomials we want to find the product and this
time I am going to note explicitly what is Ck going to equal. So Ck is going to get the product
the value of a0 bk will contribute to Ck then a1 bk minus 1 will also contribute to Ck and so on
until ak be 0. So what now we are going to do is we are going to compute c0 first then c1 then c2
then all the way till c m plus n. So, earlier we sort of did the multiplication in a convenient order
and we updated Ck’s now we are going to say no let us construct Ck’s, let us construct the
complete Ck’s and on c0 then the complete c1 complete c2 and so on. And for that we need this
formula and as you can see if we want to implement this formula we have to access the elements
of a and b in an interesting order.

611
So the elements of a have to be accessed starting with 0 1 all the way till k which is simple
enough but the elements of b have to be accessed starting at k then going down k-1 k-j coming
back down to 0. So that sort of the unusual part of this program. So we are going to do this by
setting ck equal to 0 first and then this loop can written down in this manner so ck, so i is going
to range from 0 to k so this is I, the index of a is i.

So i is going to be 0 first, 1 all the way till k. So that is what this, loop range is telling us so ai
then b of k-i, so indeed if you see the coefficient over here is k minus this coefficient this is k
minus this coefficient and so on. so that is what we end up writing so this will generate Ck for
any fixed k so all that remains is to just put this loop and we are done.

(Refer slide time: 09:19)

So as an exercise I will let you complete the program to multiply polynomials using the second
method and then I would also suggest you to change both programs, so that instead multiplying a
degree 10 polynomial by a degree 10 polynomial you write it for a general m you can put m and
n as constants. But make them different and write them as use the idea define them as const int
m=10, const int m=15 and then write in terms of m and n. Then I would also like you to go over
the loops and estimate, how many multiplications are performed in multiplying a degree m
polynomial by a degree n polynomial, and you should see roughly there are about m times n
multiplications that get performed.

612
So this is just to get a sense of how much is this algorithm is going to take let us say if we are
multiplying really huge polynomials alright, so what did we discuss?

(Refer slide time: 10:30)

So, we said that polynomials can be nicely represented by arrays nicely in the sense that the
coefficient of the ith power can be stored in the ith element and we do not need to store i
explicitly just the position tells us the position of coefficient in our memory tells us what i it
refers to and this actually very similar to the case when we have consecutive roll numbers
starting at 0.

Then we also saw that multiplication can be done in different ways, and especially the second
way is slightly trickier. And I would request you to go over that maybe print out the indices that
get accessed in the loop, if you are not sure but anyway so there are two ways and please also
look at the exercise just that were given.

So, in the next segment we are going to discuss a somewhat longish problem called taxi dispatch
which uses the array in another interesting manner but will take a quick break.

613
An Introduction to Programming through C++
Professor. Abhiram G. Ranade
Department of Computer Science and engineering,
Indian Institute of Technology Bombay India.
Lecture 15 Part-6
Array part- 1
Queues in dispatching taxis
(Refer Slide Time: 00:21)

Welcome back, in the last segment we discuss how Arrays can be used to represent
polynomials. In this segment we are going to discuss another interesting use of Arrays in a
problem called the taxi dispatch problem.

(Refer Slide Time: 00:43)

614
So, in this problem you are at some taxi terminal where taxi drivers arrive and wait for
passengers and the idea is that the driver that arrives first must be given a passenger before
anyone that comes later. So, we need to some kind of a queue over here. So, we need to
somehow record who came first, who came second, and so on.

So, we are going to get the IDs. So, this will be numbers of the driver that arrive and we are
going to put them in some kind of a queue. We will see what exactly how to do this? but you
know what a queue is in real life. So, we need to do something like that. So, we said that the
driver ID going to be an integer for simplicity but later on we can have some more
complicated driver ID as well. Well maybe a customer arrives. So, if a customer arrives and
if a taxi is waiting then the first driver in the queue should be assign to that customer. If no
taxi is waiting then the customer is ask to call again sometime later.

So, imagine that you are the controller of this taxi dispatch centre and you need a program to
keep track of everything that is going on. So, what would that program look like. So, we are
ask to right this program. So, that is the problem which has been given to us.

(Refer Slide Time: 02:21)

So, what are the requirements? Well you need to remember the IDs of the drivers who are
waiting to pick up customer that is one requirement and you also need to remember the order
in which they arrive and when the customer arrives you assign the earliest driver. And when
you assign the earliest driver you should remove the driver ID of the assigned driver from
your memory, that is basically it. When driver arrives you add the driver ID to memory but

615
you kind a put it last. So, how do you remember the driver ID’s. So, if you have to remember
a larger number of numbers of the same types, of course you have to use an Array. So, there
is no escaping from that. So, we will use an Array.

(Refer Slide Time: 03:09)

So, let us say we are going to remember some 500 driver ID’s. So, we are going to use a
name instead of the number 500 because the name tells us what it is that this number is
representing. So, I could have made this name more informative I could have called it say
ndrivers, but let me just keep it simple let me just keep it compact because otherwise my
slides became too large. So, I am going to define an array with 500 elements. So, this array is
going to called driverID.

So, if more than 500 drivers happened to be waiting then we will have a problem. So, we
might have to tell the driver that look please go back and come again later because we do not
have space to record your ID. Ideally this should not happen. But let us say just we have to
take care of every possibility when we write a program. Now the important question is, in
what order should we store the IDs in our Array. Also, besides the ID is there any other
information that we need to remember and we need to say - what should we do when the
customer arrives? what should we do when a driver arrives? So, these are question we need to
answer.

616
(Refer Slide Time: 04:35)

So, here is the first idea for answering these questions. So, the earliest driver who has not yet
been served, let us say we store in the driverID[0]. The next earliest driverID[1] and so on
and we also remember, how many drivers are waiting? So, for that lets say we use a variable
called nWaiting. So, that is basically it we have pretty much decided what variables we need
at this point well these are sort of the important variables. Later on, we may need to have
some local small variables which will be needed for a short while, but really the important
information as far as this program is concern it is going to be stored in this array driverID and
this variable nWaiting.

(Refer Slide Time: 05:33)

617
So, here is the outline of our program. So, we are going to define our arrays and there is the
constant and then there is the variable nWaiting and we should at the beginning make
nWaiting 0 because no driver has come in yet and our basic loop is going to be we are going
to wait for the drivers or the customers to come. So, for this purpose the controller will type
in a command. So, whatever the controller types in will be read into this variable called
command.

So, this variable is going to be type char. So, our convention is going to be that if a driver has
come in then the controller who is going to use our program will type in a d, d for driver. So,
if the controller typed d then we need to somehow process that driver arrival. So, how to do
that will decide in a minute. But if the command is a c, then we should process a customer
arrival c for customer. So, our instructions to the controller are that if you see a driver come
in and you want to tell the program that a driver has come in then you should type a d and
then give the information needed corresponding to driver. If a customer comes in you should
type a c and after that give the information corresponding to a customer. Otherwise if a
command x is given, then we should stop. x starts for exit usually and in this case. And if you
give any other command when the program will say this is a illegal command and it will not
abort it will not stop but it will just go back and wait for another command. So, that is going
to be our overall high level program.

So what am going to do over here is fill in all the details. So, how am i going to fill in all the
details and this is a bit of a complicated program. So, let us really make a proper plan. Let us
decide what exactly our variables are going to mean and then let us stick to those decisions.
So, this is like what we have said long ago. So, before you write complicated things make a
proper plan and right down invariants for our variables.

618
(Refer Slide Time: 08:21)

So, we have already talked about our variable nWaiting this is the number of waiting drivers.
So, we want this variable to take a value in the range 0 through n. n is the largest number of
drivers that we can have waiting. So, we should be careful that we never increase nWaiting
beyond n. Then we should know where the ID of the earliest waiting driver is going to be.

So, let us make our plan and let us make a decision, let us say that the ID of the earliest
waiting driver is always going to be in driverID[0]. Then the next driver is going to be in
driverID[1] and so on. The last driver is going to be driverID[nWaiting-1]. Why this position
well there are nWaiting drivers. So, starting here all the way till this you will have exactly
nWaiting slots. So, if i want to insert a new driver who has just arrived where should i put the
driver that driver should be put in driverID[nWaiting] and so on. The last driver is going to be
driverID[nWaiting-1]. Why this position well there are nWaiting drivers. So, starting here all
the way till this you will have exactly nWaiting slots. So, if i want to insert a new driver who
has just arrived where should i put the driver. That driver should be put in driverID[nWaiting]
and so on. The last driver is going to be driverID[nWaiting-1]. Why this position well there
are nWaiting drivers. So, starting here all the way till this you will have exactly nWaiting
slots.

619
So, if i want to insert a new driver who has just arrived where should i put the driver that
driver should be put in driverID[nWaiting] and so on. The last driver is going to be
driverID[nWaiting-1]. Why this position well there are nWaiting drivers. So, starting here all
the way till this you will have exactly nWaiting slots. So, if i want to insert a new driver who
has just arrived where should i put the driver that driver should be put in driverID[nWaiting].
Alright so what happens when driver arrival if nWaiting is n.

(Refer Slide Time: 09: 47)

And then i am going to say that is the queue is full. Otherwise we are going to get driver ID
for this let us say we have located variable D and then as we have just said that this
information goes into driverID[nWaiting]. So, this D is put over there. So, this is the ID of
the last driver that have just arrived, but because the driver have just arrived what has happen
well the number of waiting drivers has increased.

Therefore, we should increase nWaiting. That is it, that what we need to do if a driver has
arrived. Of course, we have made some invariants, what were the invariants? We should
make sure that nWaiting never goes beyond n. So, if you go through this program you will
see that we incremented only if nWaiting is smaller than n and therefore it will never go.
Similarly the other invariants you should also check they will also hold. What happens when
a customer arrives?

620
(Refer Slide Time: 10: 55)

Well what we need to do is something like this, we can process the customer only if nWaiting
is bigger than 0. There had better be some taxi driver waiting if we want to do something
with these customers. Otherwise we have to just tell the customers that try again but if
nWaiting is bigger than 0 then we have to assign the earliest and unassigned the driver to the
customers. The earliest unassigned driver is stored ID of that driver stored in driverID[0]. So,
we can pick that up and give it. But now the second earliest should become the new earliest
because the earliest has gone away. So, of all the drivers that are waiting the one that was the
second earliest before this driver went away should now become the earliest and so on. So,
we need to take care of that. And also nWaiting should decrease. So, these are the things that
should happen according to the plan we have made.

621
(Refer Slide Time: 12: 07)

So, if nWaiting is 0 then we tell the customer please try again. Else, we are going to say I am
going to assign the driver for this customer and we will just print the driver ID. The ID of the
driver waiting in the 0 position. Will this ID be actually the ID of driver? Yes because
nWaiting cannot be 0 nWaiting 0 case went away over here we know nWaiting has to be
bigger than 0. So, this is a valid driver ID. And then we need to satisfy our other invariants
which are that the waiting driver should be in position 0 through nWaiting-1. So, the position
0 driver has gone away, so, we should shift down all the waiting drivers 1 in this queue. So,
to say that we are maintaining. So, this is what this loop accomplishes. So, the driver in
position i at index i that ID is moved to position i minus1. And after that we decrement
nWaiting. We write nWaiting=nWaiting-1 or nWaiting--. So, that is it

(Refer Slide Time: 13: 37)

622
So, what we have discussed. We have discussed a workable scheme for matching taxis to
customers. So, taxi drivers are recorded in an Array in the order of their arrival and arrival
order is not explicitly stored. So, we are not saying that this is zeroth the driver that arrived
the first and the driver that arrived the second. We are not storing this numbers 1 and 2 just
because those numbers are in a certain order in our array we know when they have or in the
order in which they have arrived. In the next segment we are going to see some
improvements to this scheme but we will take a quick break.

623
An Introduction to Programming through C ++
Professor. Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology Bombay.
Lecture 15
Array part-1 More efficient Queues in dispatching taxis
(Refer Slide Time: 00: 22)

Welcome back in the last segment we discussed a scheme for dispatching taxis that is
matching taxis to customers. Now in that scheme, first of all that scheme was perfectly fine in
the sense that it did the job but it’s seems that the scheme can be improved so let us see why.

(Refer Slide Time: 00: 44)

So, here, what we did was after a customer came in we assigned the waiting drivers but then
after that we sort of moved all waiting drivers one step forward this seems like a little bit of

624
unnecessary thing. So, you will see that can essentially eliminate this movement. So, there
might be a maybe say 400 drivers waiting. So, when we are doing these four hundred moves
so why should we do that. So, you will see now that we can do without actually moving so
many drivers forward.

(Refer Slide Time: 01:30)

So, here is the new idea. So, the previous program seems to be copying data a lot. So, we are
going to avoid copying. So, for this we are going to look at what might happen without
computers. So, this is actually something that you should think about any way. So, if you are
trying to solve a problem and practically anything that you do in this course you are going to
do something which you probably would do manually. You are not going to do something
which is terribly different from what you do manually.

So, therefore figuring out look what would I do manually. So, in this case would I do the
equivalent of that copying manually that is something that you should ask. What would you
do manually. So, maybe you might write the names on a black board. So, what will it look
like.

625
(Refer Slide Time: 02: 27)

So, this is my black board and then I start righting the names of the arriving drivers from the
top. So, I wrote that and maybe at some point a customer comes. So, what will I do? I will
take the first driver over here and give it to the customers and maybe I will erase this name on
the black board. So, I cannot erase when I write it in pen and paper but if it is actually a black
board I can wipe it off. So, I am not going to erase this and push everyone up I am just going
to erase it and say that look now really the front of the queue is over here. If one more
customer comes I will erase a little bit more and I will keep going in this manner but suppose
a new driver comes. So, then I will put down driver information over here all the way till this
point. What happens if I come down all the way and a new driver comes well in that case I
may start from the top - the new driver information would be put at the top. So, now this is an

626
interesting way in which the information is given over here. The information starts from over
here goes down and then continues from the top. So, you can think of this as some kind of a
circular queue so it’s sort of starts over here and comes back over here. So, think of that black
board as sort of a rolling circular board. So, because it is circular board we need to worry a
little about where is the first person. So, we know that the first person is over here if that
person if the driver is given to a customer then the first person becomes the next but we are
really not shifting up the driver names. So, that is exactly what we are going to do in our
solution.

So, arriving driver ID is written top to bottom when board bottom reached we began from top
if the drivers have left of course if the drivers have not left then we cannot do anything we
have to tell the new driver that look my queue is full I do not have space to write down your
number and so please wait to please try a little bit later. But usually this will not happen
because we will allocate reasonably large amount of space anyway. So, we are going to think
of this driver ID as a circular array what that means it that the next position after driverID[n-
1] so, this is index 0 this is index n minus 1 so after this position then the next position is this
after this the next position is this and so on. But after this normally you might tempted to say
that there is no next position but no in this case we are going to say the next position is this so
it’s kind of a circular array. So, that is basically the idea that we are going to implement and
again the idea it is not completely simple, it’s more complicated from the previous idea and
therefore we should make decisions sensibly at the beginning and then stick to those
decisions. So, that’s we are going to do next. So, we are going to say what our invariants are.

627
(Refer Slide Time: 06:27)

So, as before we are going to have nWaiting denote the number of waiting driver. So, that
variable we are still going to have we have to keep track of how many drivers are waiting and
we are also going to have this invariant that nWaiting is going to lie between 0 and n but now
we are going to have a new variable called front. The front is the position of the earliest
unassigned driver.

628
(Refer Slide Time: 06:58)

So, if you look at this picture. So, let us say these two drivers which we have assigned the
position 0 and position 1 these drivers have gone away because they have been given
customers. So, then this position two is the first position where there is an unassigned driver.
So, really front will be equal to 2 at this time in our entire execution. So, front is index of the
earliest unassigned driver so it’s 0 initially. But as driver leaves this front increases but we
want front also to be between 0 and n. Well this time we want front not to equal n because
front is not the number it is an index. So, front cannot be n so it can be most n minus 1. So,
front is an index so it can start at it can be 0 all the way till n minus 1. Then the first valid
driver ID is at driverID[front]. So, that is what we said now this raises an interesting question
where is the next driver ID should we say that it is at front plus 1 the next driver ID shall we

629
say that it is the element driver ID of front plus 1 well there is a bit of problem if front is n
minus 1 as it can will be because after all we have said that front can be n minus 1. So, if it is
indeed n minus 1 then front plus 1 of n which is what we are asking over here is n and that is
not a valid index. So, if front is n minus 1 what we would want this to be we would want this
to be 0 as we said if this is front then the next one from here is 0. So, therefore we are going
to say that the next waiting driver is at (front plus 1) mod n. So, this plus 1 mod N is like
going forward on a circular array. So, if we keep doing that may be I should explain this. So
if, front is n minus 1 then front plus 1 is n but n mod n is 0 which is exactly what we wanted.
So, in this by the same logic last waiting driver ID is not at front plus nWainting minus 1,
which is what would be the case if this was not a circular array because this is a circular array
we have to take a mod n. So, these are the things in green are the proposition that we have to
care about, these are the invariants. So, we have to make sure that these statements are always
going to hold.

(Refer Slide Time: 10:12)

So, here is the pictorial view of the same thing what we have said over here is that this is the
initial position so this part is the entire Array and this entire Array is right now unused. So,
what I have shown over here are antacids 0 all the way till n minus 1. What happens after
some drivers have come in and some customers have also come in well if so many drivers
came in and if so many customers left then this initial position becomes unused. These last
parts are unused and this middle part is occupied by waiting drivers where the ID’s of the
waiting drivers.

630
But now if we continue in this manner what might happen is more and more drivers come
over here they may also occupy the top position and maybe more and more drivers will leave.
So, at some point in execution the situation might resemble this, that there are some occupied
positions by drivers and the middle portion is unused but that is ok this is the front.

So, this is the first driver position or the position of the earliest driver waiting in the system
and this is the next one and so on and this is the one after that and this is the last driver that
came in and then after that there is this empty space. This is just to clarify what these
variables represent and just give you picture of that. So, how do we process a driver arrival ?

(Refer Slide Time: 11: 58)

So, first of all if nWaiting equals n that means that our entire array is full of drivers. So, we
do not have space to put in this new driver so in this case we are going to say well our queue
is full please try later. But if it is not n if we do have space then we get the driver details. So,
the driver might type in some ID or maybe some phone number whatever conventions we
have and we are going to place it in the position where we said the next driver ID should be
put in and that is front plus nWaiting mod n and whatever we read in is going to be put in that
position. And at this point you will increment nWaiting. Because we got a new driver and
there is one additional driver waiting that is it. So, front plus nWaiting mod n is the index of
the empty position after the end of the queue. So, this is just a reminder as to why we use this

631
over here we have discussed this earlier and this is the position where the next driver should
go. How do we process a customer?

(Refer Slide Time: 13: 19)

Well this is kind of a compliment of it, compliment of driver processing. Now this time we
are going to check if there are any waiting drivers at all. If there are no waiting drivers then
the customer cannot be served. So, we have to send a message tell the customer look try later
well of course this program this will be read the output the program will be read by the
controller who is typing the C’s and D’s and details of the drivers. So, the controller will read
this message try later and presumably the controller will tell the customers.

Otherwise, what happens? Well otherwise we are going to print a message saying look here is
a driver for you and which drivers ID will be take? Well according to our invariants the
driver ID in index front is the earliest waiting driver. So, that driver ID is going to be sent or
assigned to that customers. And we have to say that this position is no longer containing
useful data because we assigned that driver.

So, you have to increment front but remember now this is a circular queue. So, we increment
it, but if that increment has gone that n we wanted to become 0, so, therefore we take mod n.
And we decrement nWaiting that is it. We are not going to shift up the waiting driver’s data
in our queue. Instead we are going to shift down what is the index of the first unassigned
driver.

632
(Refer Slide Time: 15:08)

This is another solution a different idea and it is a better idea because it does not do really any
copying but we have had to have extra variable called front. So, we have to manipulate one
extra variable but we saved a lot of copying. So, now, as an exercise I would like you to go
through the programs and check that the invariants are indeed true after each customer or
driver arrival and of course the code is there in the book and I would like you to run the code
and test for yourself whether the code works correctly. So, that concludes this segment in the
next segment I am going to talk about something called the disc intersection problem but
before that we will take short break.

633
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 15 Part-18
Array Part-1
Disk Intersection

(Review Slide Time: 0:18)

Welcome back, in the last segment we saw a second idea for solving the taxi dispatch
problem. In this segment, we are going to take another interesting use of arrays. And this is in
a problem called disc intersection problem. So, what is the disc intersection problem?

(Refer Slide Time: 0:40)

634
635
So, given a collection of n discs in the plane, decide if any two intersect. So, before I get into
the algorithm, I should explain to you what exactly is given as input. So what is given as
input are, say x1, y1, which are the centre of the first disc, and r1, which is the radius off the
first disc. x2, y2 are the co-ordinates of the centres of the first disc, and r2, which is the radius
of the second disc, and so on until some xn, yn, rn.

So, you are given these n triples of numbers, the first two numbers give the co-ordinates of
the centre of the disc, and the last number gives the radius of that disc. So, you are given 3n
numbers, each triple representing a disc, and you want to know wither the discs are
intersecting.

So, pictorially, if this is x1, y1, and if this is r1, then this is the first disc. Let us say this is x2,
y2 the point x2, y2 and this distance is the radius. So, then the disc will look something like
this, and if the radius is large enough then there is an intersection over here. So, in this case,
if this happens for any pair of discs, then we are supposed to print an answer 1. On the other
hand, if all the pairs, all the circles, they do not intersect at all, maybe they look something
like this, they could be really small, they do not have to be of the same size of course. If they
look something like this, then we are supposed to print out a 0 or a false, that there is no
intersection. 1 or 2 if there is an intersection, and 0 if there is no intersection whatsoever.

You could make the problem more general by asking, say, for one thing to print which discs
intersect or say maybe, how many pairs of discs intersect? So, there are many variations
possible, but let us just worry about the simplest. So now how do we solve this problem?
Well we could check all possible pairs.

So, there are some n discs, and in these discs say 1 through n, how many pairs are there? Well
there are n choose two pairs. We could check all such pairs. What do I mean by that, so let i
denote the index of some disc, and let us say it is the smaller numbered disc in a pair. So what
could other elements be, other discs in the pair possibly be.

So, first off all it is the smaller numbered disc in a pair, then i must range from 0 to n minus
2, because if it is n minus 1, then other disc will have to have a smaller number, and we are
saying that i is the index of the smaller number disc within a pair. And what should j be. For
each i, the other disc must range from i plus 1 to n minus1.

So, we want to find such i and such other disc numbers j, so that j goes from i plus 1 to n
minus 1 for every i, which in turn goes from 0 to n minus 2. But that is basically it as far as

636
deciding, how do you go over all the pairs? And the intersection check is reasonably simple,
the distance between the centres must be less than the sum of the radii. So, we have all the
information about the centres and about the radii and we just have to check that.

(Refer Slide Time: 5:12)

637
So, here is the programme, so again I am going to use the name n, which is going to denote
the number of discs. So, I am going to have an array to keep track of all the x co-ordinates of
the centres of all the discs. An array to keep track of the y co-ordinate of all the centres of all
the discs. And an array radius to keep track of the radii of all the discs.

Then I am going to read in this data, so that is all simple enough. Then is the code, which
goes over all pairs of object, all pairs of discs. And this is really the interesting part in this.
So, we have n objects, and how do you go over all pairs of them?

So first, before going over all pairs we are going to have a boolean variable intersect, which
will say whether we have found the intersection or not, so originally, we have not found an
intersection so it is going to be false. And then, our pair is going to be i j, but we said earlier
than i has to lie between 0 and n minus 2, so i less than n minus 1 is exactly what we want,
between 0 and n minus 2. I could have written this as i less than or equal to n minus 2.

So, in each iteration we well consider each such value of i, and therefore we are incrementing
i at the end of the iteration. Now corresponding to every i, j is going to take values from i plus
1 to n minus 1, and therefore these parameters have been set in this manner.

And of course In each iteration, at the end of the iteration am going to increment j. And what
do I do in each iteration. In each iteration, I have to check whether disc i and disc j are
intersecting. So, how do I do my check?

Well, my check is going to be done, normally I should check wither the distance from centre
of i to centre of j is greater than the sum of the radii. But the distance from centre of i to
centre of j is going to be something like or ((xi-xj)^2+(yi-yj)^2)^0.5. If the ith disc is at
centred at xi, yi and the jth disc is centred at xj, yj.

So, I could say, that I need to calculate this and take the square root of it. Instead of that, I am
going to square this distance. So, I will just get (xi-xj)^2+(yi-yj)^2. And if I square it, am
going to take the sum of radius squared. So, I am going to check wither this is r1 plus r2, but
instead of that I am also going to square that.

So, instead of doing a square root, I will just square, because squaring is easier. So, that is
what is happening over here. So, this power of centre of i minus centre j squared is this xi
minus xj square term. This is centre of y minus centre j power 2, so this is yi minus yj
squared. And as I said I could have written square root over here, but instead of that I am
taking radius of i plus radius j and squaring it.

638
So, if I find that the centres are closer than the sum of the radii, or the squares of the distance
between the centre is less than sum of the radii squared, then I know that the intersection is
happening and therefore I am going to set intersection equal to true. And the moment I find
that at an intersection is happening I can break, because my variable intersect is only going to
take values false or true, and I have found it true earlier, and I am have found the intersection
and I must report that. So, if I run through this entire nested loop, saying that, and do not find
an intersection, then my intersection will remain false. So, in any case when I come to this
point, either through the break or after going through all the iterations, intersect will tell me
whether discs intersect or not. So, that is what I am going to print and that is going to be the
end of my programme. And of course I have to put this in a main programme and I have to
include header files and things like that.

(Refer Slide Time: 10:36)

Alright, So what have we discussed in this? We have discussed, given a set of objects, how
do you go over all pairs? So, this is an interesting operation that happens from time-to-time.
And as an exercise I would like you to generalise the idea, so specifically, write a programme
to read in n points, co-ordinates of n points and check if any 3 of them are collinear.

So, you know how to figure out wither 3 points are collinear. You just have to calculate
slopes and things like that. And while doing this calculation, I will suggest that you avoid
division. Because division will create problems, if the co-ordinates have, if the points have
the same x co-ordinate or the same y co-ordinate, and if you are calculating the slope, you are
dividing by the difference of the by co-ordinates and that happens to be 0.

639
So, instead of that you can do a little bit multiplication rather than some division, you cross
multiply the terms and you get the division.

Alright so, that is basically it. In the next segment, we are going to talk about, how you deal
with whether we can have arrays of graphic objects and we will also conclude this entire
lecture sequence. So, we will take a short break.

640
An Introduction to Programming through C++
Professor. Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology Bombay.
Lecture 15
Array Part-1 Arrays of Graphical Objects and Conclusion
(Refer Slide Time: 0:20)

Welcome back, in the last segment we considered the problem of deciding wither a set of
disks is intersecting or not. In this segment we are going to look at arrays of graphics objects,
weather that is even possible, and we are also going to conclude this entire lecture sequence.
So, can we have arrays of graphics objects?

(Refer Slide Time: 0:46)

641
Indeed, we can. So, if I create an array, we will end up creating multiple graphics objects. So,
for example, I can write Turtle t, and that gets me an array of 3 Turtles. So, if I write such a
statement, this statement has to appear after I write initCanvas(). Because when I create the
array of turtles, the turtles will be created on the canvas as well.

So, such a statement has to appear after I have executed initCanvas(). And furthermore, if I
create such an array, I will get 3 Turtles and they will be created at the same position, as what
we get when we create a single turtle. Which is, all of them will be created sitting at the
centre of the screen. And furthermore, they will all be facing right.

(Refer Slide Time: 2:14)

So, in a similar manner, I can also say create circles. I can write say, Circle c[15]. Now there
is a slight difference between Turtles and Circles. So, when I create a circle I am expecting to
give it centre and radius. So, when I create an array, there is no room for me here in this
syntax to give the centre and the radius. So, what I need to do when am creating an array of
circles, or indeed an array of lines or rectangles, is that is subsequently I have to execute
c.reset, with x, y and r for an individual circle or, for a circle from a circle from an array I
have to issue, c[i].reset(x, y, r). And here I can specify the x and y co-ordinates of the centre
of the ith circle, and also the radius of the ith circle.

Reset command is discussed in chapter 5 of the book. So, this for circles, will indeed create
and array of circles, but they will not have radii, they will not have centres, they will be
dummy circles until you do this reset.

(Refer Slide Time: 3:47)

642
But coming back to Turtles, if I issue this you will indeed get turtles on the screen, but it will
be sitting in the same position, which is the centre of the screen and all pointing to the right.
Now, I can talk to one Turtle and I can write, T[1].right, which is what you might expect. So,
this will turn the first turtle, remember there is a 0 turtle as well, which will turn the first
turtle right by 120 degrees.

(Refer Slide Time: 4:19)

So, here is a programme, let us see what it does. So, it is going to first create the canvas, then
it is going to have turtles created. Then it will turn T1 left by 120, T2 left by 240. So, what is
this going to do.

643
(Refer Slide Time: 4:43)

So, I have 3 turtles one on top of the other. t[1] is going to turn left by 120, so one of the
turtle is going to start facing in this direction. So, this is turtle 1. The other turtle is going to
turn by 240, so it is going to face in this direction, this is going to be turtle 2. And turtle 0 is
going to be facing in the same direction. We have not changed the orientation of turtle 0.

Next I have a repeat statement, it is a little bit complicated, because inside it there is a for
loop. So, inside, am going to do something for every turtle. And for every turtle am going to
do same thing, forward 100 and left 360 upon 8. Do you remember what this does? If this had
been just forward 100 and left 360 upon 8, this would have been drawing an octagon, with
side length 100.

644
So, effectively, each turtle is going to draw an octagon. But this turtle is pointing in this
direction. So, it is going to draw an octagon which looks something like this. This turtle is
going to draw an octagon, which looks something like this. And this turtle is going to draw an
octagon, which looks something like this, so starting over here, it is going to go forward then
left. So, that is what it is going to do and then it is going to wait for you, to see what has
happened, and that is the end of it. So, let us see this in action.

(Refer Slide Time: 6:35)

645
So, this is the programme. This is what you have on the slides. So, let us compile it. And let
us run it. So, you can see that the 3 turtles are drawing 3 octagons, but they are drawing
octagons in different positions. And this way, you can create interesting designs or interesting
patterns, or you can choreograph the turtles in interesting ways if you want.

And incidentally you will remember that we did something like this earlier, when we were
studying chapter 5. Over there we just had names t2, t3. But now, we can use an array. And
since we have an array, we do not have to write the commands separately, for separate turtles,
we can put them in the loop. So, this is as far as I wanted to say about arrays and the
application of arrays. So, let me make some concluding remarks for this entire lecture
sequence.

646
(Refer Slide Time: 7:55)

So, first of all, an array is just a way to store many objects of same types in memory, without
having to define a separate variable for each object. So by defining an array, you get many
variables defined in one shot. So, you do get all the variables you want, but you do not need
to define them one at a time separately

The index allows you to choose which of the variables you want to refer to at the current
movement. And the index must be between 0 and the length minus 1 or the size minus 1 the
size of the array minus 1 and it can be an expression. And index may sometimes play an
active role, in the sense that, when the roll numbers are consecutive from 0 to N minus 1, we
do not need to store the roll numbers. So, the index or the position of the element is going to
tell you what roll number it is. So, we do not store the roll number, we do not store the index
either. But we can refer it to the index we can say, give me the ith element of this array, and
that i is the index and that is implicitly present. And when we are dealing with certain kinds
of problems. So, if the case of the roll numbers, if the roll numbers are in 0 to N minus 1, we
do not really need to store the roll numbers. Similarly, in the polynomial representation, we
had n coefficients. But we do not need to store i, we just have to store ci, the ith coefficient.
Because the coefficients are stored in sequence, we know which coefficient corresponds to
which power in the polynomial. In the taxi dispatch, the index also played an active role,
because using that and using that variable front, we could figure out which taxi driver came
earlier and which taxi driver came later.

Sometimes, the index may not have any significance. So, in our example where we had
general roll numbers as well as marks, so we had to store the general variables as well. And

647
essentially what was going on here, is that, we were storing sets of pairs and those pairs could
have been stored in an arbitrary order. One point that we have to note is that, indexing into an
array happens very fast, independent of how many elements there are present in the array. So,
this is something that we will discuss a little bit later, in the next lecture, but this is something
that you have to keep in mind. So, when you write, marks[i], little bit extra time is there
beyond accessing a simple variable. But it is almost the same time accessing an ordinary
variable, just a little bit more. And it does not depend on how many elements you have in the
array.

(Refer Slide Time: 11:26)

Some more remarks, when you have arrays, there are some natural idioms that you should
understand. You may have to go through all the elements in the array, to find the matching
element. So, this is called a linear search. You may do some calculation, which determines
the index of the histogram., index of which element is to be looked at. So, you may not go
through indices in order always. But you may do some interesting calculation. And this is
something that happen in the histogram example. You may use an array like a queue of
elements, which wait for something to happen, after which they leave the queue. And this is
something that happened in the taxi dispatch example. And of course we also saw the
accumulation idiom, we also saw the filtering idiom. So, that is it for this lecture. I will
remind you that in the textbook, there are lots of problems related to arrays, at the end of
chapter 14. And I would like you to start solving those problems. But we are going to have an
additional lecture on chapter 14, which is going to come up next. So let me conclude this
lecture at this point and thank you.

648
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 16 Part - 1
Array Part – 2
Introduction

Hello and welcome to the NPTEL course An Introduction to Programming through C++, I am
Abhiram Ranade and this lecture is about arrays. The reading for this is chapter 14.

(Refer Slide Time: 0:43)

So in the last lecture as well we talked about arrays and so far we have said that you can define
an array by writing something like this, give that name, give the type of the array, then give the
name and give a size and this creates so many variables, each of type elemtype that you have
mentioned in the definition and aname is the name of the array and informally, aname denotes
the entire collection of variables, aname[0] through aname[size-1].

649
(Refer Slide Time: 1:11)

Now in this lecture, lecture sequence we are going to look at how the computer or how C++
views arrays, what exactly happens when we do array operations. So for example, where are the
elements stored in memory? How does a computer index into an array? And what happens if you
give an index out of range? Then we are going to talk about how function calls can be made on
arrays and we will talk about a function for sorting an array. By sort I mean rearrange the
elements so that they are in non-decreasing or non-increasing order. The order that we are going
to use is going to be non-decreasing.

(Refer Slide Time: 2:06)

650
So what is the computer’s view of an array definition? So let us say we have this array q with
integer elements and 4 integer elements and these being the initial values. So in, what I am going
to discuss next, I am going to make the assumption that a single int uses one four byte word. So,
if I want to store this entire array I need four, four byte words or four and they have to be
consecutive, and so four consecutive words of memory are allotted to this array q. And in that
allocated memory we are going to store the variables q0, q1, q2, q3 in order and also when this
statement executes the initial values will be stored in the allocated regions.

(Refer Slide Time: 3:06)

So here is a possible outcome, so I have shown here the address so 1004 at address 1004, I am
going to star storing q0, q0 uses four words, so byte 1004, byte 1005, byte 1006, byte 1007 is
going to be used for q0. And in that we are going to store the content 11. So the data stored in
these bytes 1004 through 1007 is going to be 11 because we said that q0 should contain the value
11.

Then q1 will be stored likewise in bytes 1008, 9, 10 and 11 and these 4 bytes will contain the
binary equivalent of 12. Then similarly, 12, 13, 14, 15 the addresses the corresponding bytes will
be used for storing q2 and 16, 17, 18, 19 will be used for storing q3. And again they will also be
initialized with the appropriate bit strings representing in binary, or actually in binary two’s
complement the numbers 13 and 14.

651
Now, this is fine, this is what, these are details, but now let us come to how does a computer,
how or how does C++ think about the array name, so how does C++ think about q? So the array
name is thought of as not as the collection of all these variables, but simply the starting point of
this region. So this region is allocated, so what is the region that is given to us for storing the
array q? It starts at 1004 and the last byte for this is 16, 17, 18, 19 so 1 0 1 9, so this area from
1004 through 1019 is what is given to this array q. So, the array ‘name’ C++ has decided is going
to be, is going to mean or is going to have the value rather equal to the address of the allocated
region. So in our example or it is also the address of the 0th element and in our example q will
then mean 1004. So this is natural in a way and not natural in a way because it is, so what would
be sort of the right thing to have done over here? So we could have said that q really means the
entire area from 1004 through 1019, but instead of that C++ sort of makes it simple it just wants
to associate one value with the symbol q. And so it says that it is going to be the starting address.
So the starting address of the entire area or the address of the zeroth element, so the address of
the zeroth element is really the same as the address of the allocated region. So q is going to be
1004. Now the value of q has not mattered until so far until so far, until so long, until now, it has
not mattered so far. But we will see that it will, it will matter soon enough, it will be used soon
enough.

And we also have a type associated with this name, so the type associated with this name is
going to be int*. Well that is consistent with its value, its value is 1004 which is an address. And
therefore, the type of an address to an int variable is int* and so the type is defined in consistency
with our first decision. So that is how C++ uses q, its value and its type. And the array name is a
pointer, so it is an address and or a pointer, but its value cannot change. So when we talked about
pointers, when we talked about functions, our pointers could be changed, but this pointer cannot
be changed. So I cannot say in my program q equals 1008, because, in fact you can think of q as
being a ‘const’. So you remember that we can declare variables as being const. So q is actually a
const pointer, so if you write something like this C++ will flag it as an error. The idea is that look
q really is referring to this array, and while it is not telling you till how long the array extends, it
is telling you where the array begins and so please do not change it that is what, that is what this
whole, the rationale of this whole discussion is.

652
(Refer Slide Time: 8:38)

In general what happens, so if you have elemtype aname[alength], a block of memory of S times
alength is allocated. And S has to be the size of a single elemtype variable. And so aname then is
the starting address of the zeroth element or the address of the allocated block just like our q
example. And the value of aname cannot be changed, and the type of aname is elemtype* or
pointer to elemtype. So this is just a generalization about of what we said for our original
definition int q[4].

And of course the type of aname[i] is elemtype, the type of just this is elemtype* and the type of
aname[i] is elemtype and that applies to q as well. The type of q[0] is integer and the type of q
was int*.

653
(Refer Slide Time: 9:54)

So an exercise for you, figure out what is printed when the following executes? And in this you
are expected to make reasonable assumptions if you wish or if you do not want to make any
assumptions say that, that value cannot be predicted. And let me tell you what reason it
assumption might be that you may say that, so as the compiler is making is allocating memory it
sort of allocates memory in increasing order of addresses, so that might be (reasoning)
reasonable assumption.

(Refer Slide Time: 10:31)

654
Here is one more, so again you are given a fragment and you are supposed to point out mistakes
in the program fragment.

(Refer Slide Time: 10:38)

Alright, so what have we discussed in this segment? We said how memory is allocated for an
array? And basically consecutive addresses assigned, contiguous region of memory is given to
you and we also said that if an array has name aname, then the type of the name is T*, where the
array elements have type T. And the value of the name aname is the address of the zeroth
element of the array or the address of the starting or the starting address of the allocated region
for this array. In the next segment we are going to see how a computer interprets the expression
aname of index, but before that we will take a small break.

655
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 16 Part - 2
Array Part – 2
Interpretation of aname [index]
(Refer Slide Time: 0:20)

Welcome back, in the previous segment we discussed, how memory is allocated for an array.
And we discussed what the value of, what value the name of an array has and we also discussed
what type the name of an array has.

656
(Refer Slide Time: 0:45)

657
In this segment we are going to discuss, discuss how a computer interprets something like
aname[index]. So the first observation or the first thing that I should tell you is that square
brackets are actually considered to be a binary operator by C++. So we could have written this
expression as aname[]index, this may look, make it look more like an operator expression, but
because we are familiar with putting things inside brackets we choose to write it as aname open
bracket, index, close bracket. But really the interpretation of C++ is sort of like this.

Alright, so what exactly is the interpretation? Well so first of all aname and index are the
operands of the operator and aname of index means the following. So it means, this expression
means a variable. And which variable? The variable which is stored at aname plus S times index,
where S is the size of a single element of the type that aname points to. So this is a little bit of
complicated definition and I am going to give an example which will make it clear.

And you may say that look when I am doing this interpreting this expression or whenever I write,
whenever I write in my program aname[index], does the computer actually compute something
like this? Yes, it does. So it will multiply the index by something and then add it to the name. So
this is not really entirely an, entirely surprising, because we said that C++ is going to give you a
region of memory and the region is going to start at aname and then you are going to have
element 0, then you are going to have element 1, you are going to have element 2 and so on.

And this distance is going to be the size of each element or it is this S. And therefore, if I want to
get to the ith element I should know how much forward I should go and how much forward

658
should I go? I should go forward S times whatever that index is, that is it. So that is really this
calculation.

Alright, so you have to note that a single multiplication and addition is done, no matter how large
the array is. So this is why an array is often called a random access data structure, so you can get
to any element of that array in essentially the same amount of time by doing just a single
multiplication and addition.

(Refer Slide Time: 4:03)

So here is an example, so this is our old array q, so we defined it by writing int q 4 and we said
earlier that these are the addresses used for q0, q1, q2, q3 and we said that the name q has value 4
and its type is int*. So let us take one of the elements, say q3 and let us see how the computer or
how C++ views q3 and whether that view matches our view. So what is q3? So we said that first
of all it is a variable, so q this indexing operator 3 is an expression and the result of the
expression is, it is variable of the type that q points to.

And what does q point to? q is int*, so q points to an int, so q3 is an int which is good because
we are expecting q3 to be an int. And q has type int*, so q3 has type int. And it is stored at
address q plus S times 3 where S is the size of a single variable of the type that q points to. In
other words, it is a variable of type int which is what we already said and it is stored at q which is
1004, S which is 4 times 3 so 1016, so it is the starting address so it is q3.

659
So it is indeed what we think of q3 as what we think of as q3 so the computers view and our
view actually do match. And it is not a surprise, because I told you more pictorially how the
computer gets to the position in memory where q3 is or which element of which variable in
memory, so it needs to get to that position in memory and that calculation clearly should require
addition and multiplication.

(Refer Slide Time: 6:15)

So, how a computer gets to aname and address? The index is multiplied by the element size and
added to the starting address to get the position in memory where the variable is stored. And
whenever you write aname[index] that variable which you got to by doing this address
calculation is the one which is considered the result of this expression, the result of evaluating
this expression.

660
(Refer Slide Time: 6:46)

Now, in light of this discussion of how aname[index] works, let us try to see what index out of
range means. So here is our old array q and suppose we execute q[10]=34, so what would this
do? So if we mechanically interpret as per our rule and, which is how the computer interprets it.
So it is the variable of type that q points to, stored at address q plus 10 times S where S is the size
of an integer of a single variable of the type that q points to. Again this is a mouthful, but we
know how to interpret it now.

So it is a variable of type int, because q points to int, so it is a variable of type int. It is stored at q
plus 10 times S so q plus 10 times 4 equal to 1044, so this is the position where q of 10 would
have been had q actually had 10 elements, but q does not have 10 elements. So this address is
somewhere beyond the region allocated for q, so 34 if you execute this statement 34 will get
stored in some strange part of the memory which has nothing to do with q. So that is why it is
bad to have indices out of range, so some other variable will get destroyed.

Now the other way is also bad, if I write x equals q of 10 what will happen? It will pick up the
value from this 1044 and so X will get some strange value, who knows what value it gets? So
again it is a, it is a bad idea to have an address which is out of range. And now you see, what
C++ will do in these cases, in in such cases.

661
(Refer Slide Time: 9:05)

But there is a little bit more to be said, if you read or write from an improper address such as
1044, you may store data into wrong, into some wrong place, you may read data from a wrong
place. And sometimes, C++, or your computer hardware may say that look some addresses are
protected, why are they protected? Because they may contain code and you do not want
programs to be writing data into the code region of memory or the program region of memory.

So, if your program tries to do that then the hardware will raise an alarm and it will cause your
program to abort. So any of these things could happen and so therefore make sure that the index
is in the correct range.

662
(Refer Slide Time: 9:58)

Now some programming languages prevent index out of range by explicitly checking, so the
moment you write a[i] the language will have additional code which it generates itself you do not
have to write it, which will check first whether i lies in the range 0 through size minus 1, where
this size is the size of the array in question. If it does not, then it will not make that access, it will
just print an error message saying that oh you made, you gave an index out of range and the
program will stop.

Index checking is not done in C++, why? Because it takes extra work, C++ wants to run very
fast. Of course C++ does not want wrong answers, but C++ says, the C++ designers believe that
it is the programmer’s job you have to ensure that your index is correct and of course you can do
that, I mean you have to think a little and you to be careful but that is your job, that is what the
C++ designers believe.

663
(Refer Slide Time: 11:22)

So here is an example, so we have this code and let us see what it does. So when you come to the
first statement of this code, this statement will cause an array q to be allocated memory, what
happens next? The variable r is created, remember the type of r is int*, so it is meant for storing
addresses so when you execute this r will get the value q, what is the value of q? It is the starting
address, so what will the value of r be? It will also be the starting address, so at this point r and q
will have the same value.

Alright, so now what happens when you execute this? When you execute this, this expression
since r has the same value as q, this expression is as good as q[3]. So 5 will get placed in q[3], so
when you do this printing 5 in get printed. And if you print r[3], this is not, this is also going to
refer to q[3] and so again 5 will get printed. So r and q have the same value and r[3] and q[3]
denote the same variable and therefore this will end up printing 5 in both cases.

664
(Refer Slide Time: 12:58)

Aright, so what have we discussed? So we have discussed that aname[index] is an expression


with square bracket as an operator. When the index is in the range the expression evaluate, when
evaluated tells what variable is meant, if the index is out of the range, then the expression does
not denote a valid variable. And this calculation happens fast, there is only an addition and
multiplication to be done and it happens in time independent of the array length. Aname[index]
is a valid expression if aname is a pointer.

Next all these things are going to have some bearing on how you use arrays in function calls and
that is what we will see in the next segment, we will take a break.

665
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Instutute of Technology Bombay
Lecture No. 16 Part- 3
Array Part-2
Arrays and function calls
Welcome back, in the previous segment we discussed what how aname[index] is interpreted.

(Refer Slide Time: 0:24)

Basically we discussed the semantics of this square bracket operator. In this next segment we
are going to talk about how arrays are passed to functions.

666
(Refer Slide Time: 0:43)

So we really would like to have functions on arrays, right. I mean we might do, we might
want to do the following things, we might say want a function which finds the largest value in
an array.

(Refer Slide Time: 0:52)

Or if you might want a function which decides whether a given value is present in an array or
a function which calculates the average of the elements in array, in an array. And so many
other things could be done, okay. So in this segment we are going to see how all of these can
be done, all of these things can be done.

667
(Refer Slide Time: 1:13)

Let me just plunge into it directly by giving an example. So here is a program which finds the
average of elements in an array or a function rather. So this is the function and this is the
main program which calls this function, okay. So before looking at it too carefully and trying
to see how it executes,

(Refer Slide Time: 1:42)

let us first make some preliminary checks, okay. Let us first check if this is a syntactically
valid program, never mind what it does, okay. So what do I mean by that? Well, when we
make a function call, when we, okay, so, the types of the arguments must match the types of
the parameters to the function, okay, so is that happening here. Well the first parameter to
average has type double star, okay. So this is the first parameter and its type is double*, okay.

668
The first argument in the call is q and its type if you remember is also a double*, why?
Because it’s the name of an array of doubles and its value is the address of the zeroth element
and it points to a double element. So the type is correct, the type of this is indeed the same as
the type of this. So when we execute the function, the value q will indeed be copied into M,
so no problem with that.

The second parameter here is type int and here also is type int, so that is of course absolutely
no problem about that, so that is nothing new about that.

(Refer Slide Time: 3:09)

Okay, now let us see how this is going to be executed. So when we execute this average of q,
4 what is going to happen? Well activation frame will be created for average and the value of
q which is the starting address of this array will get copied into the parameter M. And in each
iteration what is going to happen? M[i] is needed. Now like the example that we took a little
bit earlier, this M has exactly the same value as this q. So if we write M[i] in this, even in
this, M[i] is going to be in the same variable as q[i]. Because M and q mean the same thing,
M and q have the same value, okay. So M has the value starting address of q of type double,
so M[i] means variable of type double at address q plus 8i.

Or otherwise it is the same thing as q[i]. Exactly like the exercise that we just, example that
we justed in the previous segment. So effectively what is going to happen is that we are going
to calculate the average of q0, q1, q2, q3, which is exactly what we want. And so this will
indeed return, it will calculate the sum of the elements and then return divided by four, so it
will actually return the average exactly like we wanted.

669
And the main program will print it out, so that is how the execution will go.

(Refer Slide Time: 5:03)

So how are arrays then passed to functions from this example? So we are passing two
arguments, the starting address of the array and let say the corresponding parameter is A,
okay, and the number of elements in the array. Or maybe I should have written M to keep
consistency with the previous example, but let us say it is A. So now can elements of the
array be accessed in the called function? Well, if you write A[i] in the called function, it will
actually give you the ith element of the calling program. And therefore, you can access the
elements, even though you are not, you are not copying the elements, you are just sending the
starting address of that array. But if the function modifies the elements, then the modification
will be seen in the main program because the function is directly operating with the same
array. It has a pointer and that pointer is operating directly in the activation frame of the
calling program.

670
(Refer Slide Time: 6:32)

So when you pass the name of an array in a function call, its value the starting address of the
array, is copied to the corresponding parameter. But because we pass the starting address of
the array, we are effectively enabling the function to pass the array. You can say the
following about this entire process. You can say that the array name is passed by value. So let
us just, let me just explain this.

(Refer Slide Time: 7:06)

671
So in this, this array name is passed by value, why? Because the value of q is put in the value
of, put in M. And so therefore, M and q have the same value. But indirectly, indirectly
because you are passing the array name, you are allowing the called function access to the
entire array. So you could say that the array elements are passed by pointer. Well effectively,
you are saying that all the array elements are passed by a pointer to the zeroth element,
because if you add the appropriate displacement, the called function can get to every element
which it did in our average function and it can do in any old function.

The interesting part in all of this is the square bracket operator. So it given the address of any
array and an index, it can get us to the corresponding element. Even if the address belongs to
a different activation frame.

(Refer Slide Time: 8:23)

672
Now when we write functions an alternate syntax is also allowed and maybe it is
recommended. So I can write the average function as not double star M, but double M[]. In
this double M[] is synonymous with double *M, okay, it means the same thing. But it is
slightly more indicative that we expect M to be an array name and not just any old pointer.
But this is really for our benefit, C++ treats both of these things as essentially the same.

And I should further note that this M[] syntax is not allowed in other places besides the
declaration or definition of a function. Now the second argument over here okay, is not really
linked formally to this, this element. It is just a second argument, it is just another integer.
What you do with that integer inside the function body, is your problem. So we are choosing,
we are deciding when we write this function that the second argument is supposed to be the
length of the array. So, of course, the average function does not know that. So you can in fact
pass a smaller value of n and then the average function will just take the average of the initial
so many elements, rather than all the elements in the array. All right, so what have we
discussed?

673
(Refer Slide Time: 10:20)

So we have said that, no special mechanisms are needed to pass an array to a function other
than the semantics of the square bracket operator. And also the idea that the array name is a
pointer to the starting address, the starting address of the region allocated for the array. We
pass a pointer to the zeroth element that is we state where the array begins in memory and we
pass the number of elements. This is what we do if we want to pass an array to a function.

The square operator can be used to access individual elements of the array. And this
concludes this segment. In the next segment, we are going to build a slightly more elaborate
function, a function to sort an array, but will take a quick break.

674
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 16 Part- 4
Array Part-2
A function to sort an array
Welcome back in the previous segment, we saw how an array could be passed to a function.

(Refer Slide Time: 0:23)

Now we are going to use those ideas to build a somewhat more elaborate function. So this
function is going to sort an array, okay.

675
(Refer Slide Time: 0:33)

So the input is an array containing numbers. The output, well, the output is going to be
present in the same array and you can think of the goal as being to rearrange the numbers so
that they appear in non-decreasing order. So as an example, suppose the array initially is 35,
12, 29, 70, 18, 29. Then at the end we want this desired order, so 12, 18, 29, 29, 35, 70.

(Refer Slide Time: 1:02)

Okay. So how do we do this? Well before we say how do we do this, I should point out that is
an important operation. And Chapter 16 will give a clue as to why this is the case. So will,
will, we are going to do that, so we will just wait until then. There are many algorithms for
sorting and Chapter 16 we will discuss a clever and fast algorithm. Here we discuss a slow
but an easy to understand algorithm called Selection Sort.

676
(Refer Slide Time: 1:33)

The basic idea of Selection Sort is, find the largest number in the array. Then we exchange it
with the element in the last position. Now we have made progress, why? Because the last
position now contains the largest number which is really what we wanted the last element of
the array to indeed contain the largest and we have placed it there.

So what happens now? We just have to do the same thing for the first N-1 elements. So we
apply the same idea to the first N-1 elements of the array, where N is the length of the array
then to first N-2 and so on.

(Refer Slide Time: 2:24)

677
Okay. So a primitive step in all of this is finding the index of the largest element. Well we
said, we want the largest element, but actually it is more useful to find the index of the largest
element, where is that largest element present in that array.

(Refer Slide Time: 2:46)

So here is here is a function which does that, so this function takes as argument an array well,
an array name, but as you know, it is the starting pointer to the start of the array and the
length of the array. But we can think of A as an array name. As we saw that when the
parameter passing the values are copied, it really behaves like the name of the array.

This function is going to return the index of the largest element in A. So what is the invariant
for this iteration? Well,so for the ith iteration the invariant is that maxIndex which will be a
variable, that we will define soon, will equal the index of the largest element in A0 through i-
1, okay. Or I should say A[index], if there are multiple it will be one of the, a multiple
elements which are maximum, it will be the index of one of those elements.

So we start by setting i equal to one and maxIndex equal to 0. So this makes the invariant
hold. Why? Because if i equals one, A0 through i-1 is just A0 and maxIndex is indeed the
index of the largest element that there is only one element A0 and its index is find index of
the largest element in A, kind of trivial, but will do.

Now we are going to increase i until L-1 and as we increase i, we want the invariant to hold.
So this is like our Max so far, but instead of keeping track of the Max, we are keeping track
of the index. So A[maxIndex] is Max so far and if this is smaller than the new element, then

678
we are going to set maxIndex equal to i, okay. So either way maxIndex will point to the
largest element or be the index of the largest element and so at the end we return maxIndex.

I should note that in doing this the number of comparisons needed is going to be L-1. So for
each value of i going from one to L-1. So L-1 comparisons will be needed, okay. We are,
later on going to estimate the time taken for this and this value will be needed over there.

(Refer Slide Time: 5:26)

Okay. So what is the main function and the main program? So the main function is the
function selection sort. It again receives the name of the array which is the address of the
zeroth element, but which we can pretend is the name of the array and because the name of
the array means the same thing and the length of the array. Then we are going to start with N,
remember we said that, we are going to place the largest element in the Nth position, then the
second largest element in the N-1th position and so on, so that is what is loop is for.

We first calculate maxIndex which is posOfMax(A,i).If you remember posOfMax was going
to return an index of the maximum element in the array A of length i. Now our array A
actually has length N. In the first iteration this will be N, but in the subsequent iterations this
will be smaller. But if you remember according to our discussion in the first iteration, we
wanted to find the largest element in the entire array.

In the next iteration the largest element was already in position N. So we wanted to find the
largest element in the first N-1 positions and that is exactly what this statement will do.

679
Because in the next iteration, i will have come down one step, so this will be N-1. So this is
exactly what we want, okay.

So posOfMax, this function thinks that the array only has i elements, but that is okay. So it is
going to only tell us the index of the largest element in the first i elements, that it is going to
consider from this array.

(Refer Slide Time: 7:40)

Now we want to do the exchange, we want to exchange the i-1th element with maxIndex
okay, i-1th element.

(Refer Slide Time: 7:58)

680
Well in the ith iteration we are going to consider i elements, okay. So this is element 0, 1, 2
and this last element is i-1. So we found some maxIndex over here and we are going to
exchange the element over here and the element over here. So what this will do is, we already
before starting would have had the correct values over here, okay, the largest values over
here. Now the largest value in this entire region is going to be pushed to this point and so the
good region will extent a little bit more, that is what this is doing to do.

So we need to do this exchange. So how is this exchanged done? Well the exchange is simple
enough.

(Refer Slide Time: 8:43)

We copy the value at maxIndex to maxVal.

681
(Refer Slide Time: 8:47)

So this is maxIndex, so this value goes into this variable called maxVal, okay. Then we copy
the value in i-1 into this position.

(Refer Slide Time: 9:09)

And finally, we copy the value over here into this position. So the exchange is done okay, so
that is it, that is our selection sort.

682
(Refer Slide Time: 9:20)

So in our main program, we will create this array and then we will call, we will call make us
call to sort. Yeah, so we will print it, but I will show that printing step when we do a
demonstration.

(Refer Slide Time: 9:36)

Okay, all right. So before we do the demonstration, let us review what we have done a little
bit. So this is our function and let say, let us try to count how expensive, how much time this
whole thing takes. So we said that posOfMax our function will perform L-1 comparisons
where L is the length of the array passed to posOfMax, okay. So this is what I am talking
about.

683
(Refer Slide Time: 10:11)

So this red part, this red part will require me to do L comparisons, L-1 comparisons. If the
array has size L. So if the array has size i or if this argument is i, it will do i-1 comparisons.
The first iteration it will do n-1 comparisons, the next iteration it will do n-2 comparisons, n-3
comparisons and so on, okay.

(Refer Slide Time: 10:41)

So selSort calls posOfMax for L equals N, N-1, 2, so the number of comparisons it does is N
+ N-1 all the rate down to 2 so it is N+2 times N-1 upon 2, okay, so just about N squared by 2
comparisons. So even if I count the number of comparisons, selSort will do about N squared
give or take a factor of 2, and N square turns out to be not such a fast algorithm you can do
far fewer comparisons and we will see that little a bit later, okay. But any way, this algorithm

684
will sort correctly and now we are going to see a demo in which that sorting is going to
happen, so let us take a look.

(Refer Slide Time: 11:30)

So this is our function, okay. So this is our code for posMax, I have added a print statement
because I would like to print the array at different points, so we will see there this is going to
be used.

(Refer Slide Time: 11:49)

So let us just take a look at the selSort function, okay. So I have modified it a little bit and the
modifications are store, shown by these stars. So what I am doing is at the very beginning, at
the beginning of the each iteration, I am going to print out the entire array. So this way you

685
can see how the array is going to change and in, to make sure that, okay, so then this
posOfMax is going to be called and I am also going to tell you where that index is, what
index was reported. So again, we can check how posOfMaxis working, how the entire thing
is working. And I do not want the iterations to go of very fast. So here I am going to just have
a dummy variable, okay, and I am going to read a number into it, I am not going to use this,
but this will just force C++ to stop at this point and wait for me to type in something so that I
can continue. So the value of the dummy variable is not important over here. I will just put in
so that I can force C++ to stop, okay? So the rest of the code is exactly the same and at the
end also, I am going to print out a message and I am going to print out the value of the array,
okay.

(Refer Slide Time: 13:10)

So we had the print function at the top and that simply prints out the value of the array, value
of all the elements in the array. So let us execute, compile and execute this. So let us run it.

686
(Refer Slide Time: 13:20)

687
So this is the printout at the beginning of the first iteration of selSort. And then it, so this is
the, at the at the time when nothing has been done, we are just beginning the very first
iteration. And we have issued Max pos and it says that the maximum value is found in index
three. Let us check if that is true?

So 0, 1, 2, 3, 70 is at index three and it is indeed the maximum value, so Max pos has
behaved correctly. So let us just type in some nonsense value so that the program will
continue.

(Refer Slide Time: 14:11)

So now you see that the second iteration is being executed and at this point 70 has already
gone to the end because of our exchange and we have also issued the call to one more Max
pos. And that is limited to this region. And in this Max pos is found at index zero which is
indeed true. So again let us continue okay.

688
(Refer Slide Time: 14:39)

And now 35 has gone till the end and now we are finding that Max pos is found at index two,
0, 1, 2. Yeah there are two 29’s, but it has picked one of those and so, and it is indeed at this
position there is indeed the maximum, A maximum value.

(Refer Slide Time: 15:01)

689
So let us again making go forward, so this time 29 has gone till the end. Well we do not know
whether it was exchange or not, but presumably there was an exchange. But now again, a
maximum is found at this position, okay.

(Refer Slide Time: 15:18)

690
So let us again type 0, so it has gone forward and this time it is really searching within this
region Max pos is being found within this region. So the largest value is over here and so
index zero is returned by Max pos and so at this, sorry, let me type 0.

(Refer Slide Time: 15:36)

691
(Refer Slide Time: 15:40)

So at this point the function is returning at after returning to main program 12, 18, 29, 29, 35,
70 is printed and it is indeed correctly sorted.

692
(Refer Slide Time: 15:58)

Alright. So posOfMaxwill perform L-1 comparisons where L is the length of the array passed
to posOfMax, okay. So we saw all these things, okay.

(Refer Slide Time: 16:10)

We saw that demo and we can do a variation. We can express selsort as a recursive program.

693
(Refer Slide Time: 16:18)

So I am going to leave this, I am going to show you the code, but I am going to leave this as
an exercise for you, okay.

(Refer Slide Time: 16:28)

In fact, I am going to put out the code as well and you can run it yourself and check it. So that
essentially concludes this lecture. And so I would like to make some remarks.

694
(Refer Slide Time: 16:47)

And in this lecture we saw what sort of happens behind the scenes when we access arrays.
And we said what does an array name mean? And what happens for the indexing operator?
And how do you pass an array to a function. And we said that when you pass an array to a
function, it does not copy values, but it merely copies the address of the zeroth element. And
if you want to access the entire, if you want the function to access the entire array you should
tell the function how many elements the array has, so that also must be passed.

Writing functions on array is useful and this is definitely a skill that you must master.
Selection sort runs in time proportional to the square of the number of elements being sorted
and in Chapter 16 we will discuss faster algorithms. I will stop here, but I will urge you to
solve the problems at the end of Chapter 14 and of course, read, read Chapter 14. Thank you.

695
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 17 Part - 1
More on Arrays
Textual data

Hello and welcome to the NPTEL course on An Introduction to Programming through C++. I am
Abhiram Ranade, and today's lecture is also about arrays and the reading for it is from chapter 15
of the text.

(Refer Slide Time: 0:35)

So, here is an outline, so the first topic that we are going to look at is how to represent textual
data, then we will talk about two-dimensional arrays and in this, one of the examples will be how
to create polygons in simplecpp. And then we will talk about accepting command, accepting
command line arguments.

696
(Refer Slide Time: 0:55)

Textual data, we have already talked about a little bit. So we said that the char type was specially
meant for storing single letters. Now, obviously the natural step would be to use an array of char
to store sequences of letters. So, for example, you could use arrays, an array of char to store
words, sentences, paragraphs, maybe a character string like “India”, maybe a character string like
“C++ is nice” with spaces inside it. And the textual data representation that I am going to talk
about today is derived from the C language. C++ has nicer representations and we will learn
about them a little bit later, but whatever we learnt today will also be useful even in that nicer
representation.

697
(Refer Slide Time: 1:58)

So, character arrays we already know, well we know arrays and therefore, character arrays are
not really different. So as always we define an array by giving the type name, the name of the
array and then in square brackets the size. So, here I am defining two character arrays, one array
called name, of length 10, and another array called address, of length 50 and both have the type
char. So such arrays can be used to store character sequences or character strings as they are
more often called.

And you may, you often use an array of a larger length to store strings of smaller length that is
because often you do not know how long the string is that is you want to store, say in the name in
the in the array name because you may not, you may not always calculate what is the exact name
of this person before storing the name of the person into the array, you may just allocate a large
enough array for storing say the name of a person.

Now the arrays are character arrays are really not any different from other arrays, but there is a
difference in the way they get used. Specially there is a protocol for storing character strings that
is inherited from the C language and here is what the protocol is. So, if you want to store a
character string into an array you store the string in the array starting from element 0. After all
the characters in your character string are stored in the array, you also store the character whose
ASCII representation is 0, often written as “\0”, this character is often also called the null
character.

698
So what you store actually is the string that you want to store followed by this null character. So
the null character sort of signals that look the portion of interest has ended. And indeed, the way
everything happens that character arrays is not using the defined length of the array, but rather
the idea that only everything until the null is a part of the actual string and what comes later is
supposed to be ignored.

So, in fact you will see that when you are processing character strings stored in character arrays,
you do not really talk about the length because the length is never specified explicitly. So you
just process until you find the null character.

(Refer Slide Time: 5:09)

699
Now you can create character arrays with initialization. So for example, you might write char
n1[20], so you are allocating an array of length 20 and in which you are storing “Ajanta” and you
are allocating an array n2 without giving the size in which you are storing “Ellora”. These
definitions are analogous to the definitions that you have seen say for defining arrays of integers.
The initialization form for character strings is slightly different you do not need to, you do not
enclose individual characters in braces, but you can just put up character strings.

So, how does this work? So n1 will be created with length 20 and it will be initialized as follows.
So A will be put, capital ‘A’ will be put in n1[0], ‘j’ will be put in n1[1], the next ‘a’ will be put
in n1[2] and so on. So ‘A’, ‘j’, ‘a’, ‘n’, ‘t’, ‘a’ will be stored in array elements n1[0] through
n1[5], but that is not all, in n1[6] the null character will be stored. So this is this as I said this is
just according to the protocol that we talked about earlier. And the elements n1[7] through
n1[19] the remaining elements of this array “Ajanta” will not be initialized and it is expected in
fact that if you are going to process this array these elements will not be looked at, so only the
elements until the null character will be looked at.

n2 will be created of length 1 plus the length of the string “Ellora”, the length of the string
“Ellora” is E-l-l-o-r-a, 6 plus 1, so 7 the size of n 2 will be 7. And it will also be initialized to the
string “Ellora” followed by the null, null character. So just to draw a picture, n1 will look like
this, so this will be index 0, this will be index 19, and then in n1, we will store A-j-a-n-t-a and
then this null character, so this is 0 1 2 3 4 5 and 6 the null character is stored.

700
n2, because the length of n2 is not given, n2 will be created so that it uses the minimum length.
And so what will it look like? It will look like E-l-l-o-r-a and then the null character, so this
requires 7 characters and in fact exactly 7 elements will be allocated. So element 0 through
element 6. And I should point out that the syntax n1[20]=“Ajanta” looks like an assignment, but
that is not true you cannot, you cannot use this as an assignment, you can only use it as an
initialization.

You can assign individual elements of the array, so you could write n1[0]=’a’, n1[1]=’j’, and so
on. But assignments will be one element at a time and this feature of assigning a lot of elements
simultaneously is reserved only for initialization.

(Refer Slide Time: 9:22)

So we have declared arrays and maybe we initialize them, but we surely want to read data into
arrays, so this is the first way in which we are going to be able to read data. So for example, we
have a character array ‘buffer’ of length 80. Suppose it has been defined as shown here, the first
way to read into it is to you cin greater than greater than our standard mechanism. And this for
the purposes of reading into character arrays works in the following manner. So it reads one
word and what is the word? Well, it is anything which is terminated by white space, white space
is a space character or a newline character, tab character so any of these appears then the word
will be considered to have ended. So whatever that one word was typed in by the user will be
taken and will be stored into this array buffer from the beginning and it will be terminated by a

701
null character. So suppose the user types “C++ is nice”, so there is C++-space-is-space-nice and
after that nice say there is a new line.

If you remember you have to hit a new line before the computer actually starts looking at what
you typed. So say here you hit a new line, so what happens in this case? So in this case as we
have said one word is read, so the first word is C++, so that C++ is read so three characters are
read and they are stored into buffer[0], buffer[1], buffer[2] and following them the null character
is stored.

Now cin>>buffer does not mention the length of the buffer because if you remember the name of
the array is only the starting address, so this is needed of course you need to know where to start
putting in the data that you are just reading. But there is also problem here, so if the user types
more than 80 characters, then this will cause an index out of range error. C++ will attempt to
store whatever you typed into say index 80, 81 how many over characters you need and that will
cause an error.

So, what should you do? So, we will have a more safer way to read, we will show that all in a
minute, but the standard idea is to just allocate a large enough array or the simple idea I should
say. So quite possibly, if you want to write a really good program you should probably not be
doing this, this is sort of a quick, this is a way to quick, write a quick trusting program. I should
also mention that the command cin>>buffer works only for character arrays.

In fact, buffer is constant, so normally cin>> is supposed to have a variable after it. So normally
if you type any symbol that symbol had better be a variable, but for character arrays there is a
special case made by C++ so that it is interpreted as put whatever is read into this array starting
from the 0th character. So if it is not a 0 character, if it is not a character array however, then
C++ does not allow you to read things in this manner, so that will actually cause an error, say
buffer is an integer array then you write Cin buffer would cause an error.

702
(Refer Slide Time: 13:40)

Now here is a different way to read into character arrays, so again we have our same definition
char buffer 80, the safe way to read into it is this we say cin.getline(buffer, 80), here you can
notice that we are specifying the length, so C++ will actually make sure that the reading does not
happen beyond the array boundary. So this will read a line and this time it is not terminated by
white space, but it is terminated by a new line, and if the line is very long then C++ will only
pick up the first 79 characters.

So whatever is picked up will be placed in buffer and it will be followed by the null character. So
this is safe because you do not attempt to write beyond the end of your allocated region and
another difference between this and what we had earlier is that the line that you read may contain
spaces. So, if you want to get in spaces into what you are reading this is the way to do it. As an
example, if the user types “C++ is nice” as before and again after nice there is a new line so the
computer starts processing it, this time that entire text would go into the buffer followed by the
null character.

703
(Refer Slide Time: 15:20)

Printing char arrays is simple, so if you have a char array again the same char array, then say you
somehow put data into it, we have seen one way of the putting data which is to read into it, but
there could be other ways which we will see soon. And I should just point out, that the way you
put data into the elements of any array is the same, so I can put data, I can make assignments to
char buffer[0], so to buffer[0], buffer[1] just like I make assignments to the elements of an any
array.

So suppose you have assigned some value into buffer and you have done it in the right way
which is that the string that you have stored has a terminating null character, so if that happens

704
and then you can write cout<<buffer. So this would push the content of buffer onto the screen.
And how much content? Well everything until the null character. So, for example, earlier be
initialized n1 to be “Ajanta” and n2 to be “Ellora”. So if you write cout<<n1, then “Ajanta” will
be printed because as it is said over here everything until the null character is to be printed. And
for this it is important that your buffer actually contain the null character, if it does not contain
the null character then C++ will just go on printing whatever there is after that address, so again
in a sense this is an unsafe, slightly unsafe mechanism, but it is not that unsafe because it is in
your hands as a programmer to make sure that it contains the null character.

The length of the array is not important because only everything until the null character is going
to be printed. And I should also point out that if buffer is an array of a different kind, then what
would get printed, would be the address of that array because as you may remember in general
the name of an array stands for the address, the starting address of that array. So here when I say
cout, so this is something special intended for char arrays.

(Refer Slide Time: 18:08)

Now, how do you process character arrays? So we are going to do a few examples of this and the
general principle however, is that the array length is ignored and instead we process all the
elements till we find the null. And it is expected that the array will contain a nulll if you are
going to do this for processing. And this is the most common idiom that we do not really keep
track of the array length, but we process everything until the null character.

705
(Refer Slide Time: 18:46)

So, let us write a very simple program. So this program is going to read in a name from the
keyboard and we are going to count the number of letters in the name. So here is the program, so
what does it do? Well first it defines this array name of length 80 to store whatever you are going
to read, then it prints out a message saying “please type your name”, well for short it is just
saying name.

And then I could have used the safe variant but just for simplicity and compactness I am using
the unsafe variant and this variant will read the first word. So whatever you type, delimited by a
white space will go into name. And then the next, the next line is just going to print that out, so it
is going to first print the message you typed whatever and then whatever you type the first word
from it will get printed, the first word will be taken and only the first word will be taken into
name and only that will be printed.

After that we are going to search through the name array, this search is sort of similar to what
you have in other arrays, but it is different in the sense that you are not going to go, you are
going to start at 0, but you are not going to go till the end. You are going to go only until you
find a null and this is the body of the while and in the body you are only going to increment L.
So as a result after this entire code executes, L will be the index of the null character or since our
counting starts at 0, L will be precisely the length of the name. So yeah, so that is what got
printed over here in the last, in the last bit.

706
(Refer Slide Time: 21:08)

So here is a quick exercise for you, write a program that reads a word and prints its reverse. So
just to clarify what you are expected to do, you first find the length of the word using what we
just saw, and then examine the characters in the word from the last character coming back. So
again, now this is not, the second part is sort of standard array stuff, it does not use this
convention about the null character or anything like that. But anyway, so the first part does and
so do write this program.

707
(Refer Slide Time: 21:45)

So, what have we discussed so far? So he said that text stored in an array of char, the length of
this text is not explicitly stored and this is, this is not a, this is not a rule as such, it is just a
convention but it is a very-very stringently followed convention. After the last real character, a
null character or the ASCII character with value 0 is stored. Again this is also a part of the
convention.

And sometimes it is this last null character is called the “sentinel”, “sentinel” means guard so it is
sort of guarding the actual text that you have stored and it is standing at the end and guarding it is
sort of. So next, we are going to look at functions that operate on character strings and also
something called character string constants, so we will take a break.

708
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 17 Part - 2
More on Arrays
Functions on character strings

(Refer Slide Time: 0:22)

Welcome back, in the last segment we discussed how text is stored on a computer and in this, in
this segment we are going to talk about functions that operate on character strings and also the
notion of character string constants.

709
(Refer Slide Time: 0:42)

So there is a standard rule for passing arrays to functions, so what is that rule? You pass the array
name and the value of the array name is simply the starting address of the array, so when you
pass the array name you are telling the function where the array is beginning in memory. And
then you pass the array size, so using these two things the function can figure out how many
elements the array has, and then the function inside the function also you can do the address
calculation to get the different elements.

And the array size, well you can check, you can look at the array size to decide what is
reasonable or what is a legal value of the index. The rule for passing char arrays to functions is
slightly different. So we have to pass the array name, so the function has to be told where the
array starts in memory, from which address the array is allocated. But, there is no need to pass
the array length, because of the of our convention, we only process till the null character, so we
do not really worry about the length of the array in any case. So therefore, there is no need to
pass it.

So again, to reiterate we do not look at the length of the array, but we keep processing until we
encounter the sentinel, which is the null character whoich is the character whose ASCII value is
0, and that tells us that oh the array has ended over here.

710
(Refer Slide Time: 2:17)

So, let us write a simple function for on strings, so this is a function which determines if a
character ‘x’ is present in a string cstr. So it takes as argument the character x itself and character
array cstr, so we are going to call it constant because inside this that array is that cstr is not
changed. As said in the title the purpose of this function is to determine if x occurs inside cstr
and so it will return a true if x occurs and return a false if it does not matter, so how does this
work? So we are going to start scanning the cstr from index 0, so i is going to be our index and
so we are going to write int i=0, and condition now is until we encounter the null character. So
the for loop has this condition and often the condition deals with the length of the array, but in
this case we will just say that look i, the element at index i should not be a null character and
then the update is the same as before, so we increment i, we go to the next index or we scan
forward.

And here, if we encounter x, if at any index we encounter x, then the return true, if we go
through this entire loop and we do not encounter x that is when we will come out, our control
will come to this point. So if control reaches this point, then that means x does not appear in this
string cstr, and so we return false. So here is how this program could be called through, could be,
a function could be called through a main program, so we are going to set a character array to
“India” and then we can say findchar(d) in the name.

711
So in this case d does appear in the string India or in the string stored in name and therefore, they
should print, this will print a 1. As you may remember true is not printed, but 1 is printed instead.
And, if you try say to search for a c, it will not be found and therefore, we will print a 0.

(Refer Slide Time: 5:06)

712
So let us do a quick demo of this, so here is the file. So I am going to compile it now, and then
run it, so as expected 1 was printed followed by 0. So here is another piece of code which is very
similar and I want to ask you whether you think this should also work?

(Refer Slide Time: 5:42)

So in the previous program what we did was we put a string to an array and then called
‘findchar’, but you would think or you would desire that something like this should also work,
why should we have to put that string into an array and then call it, why cannot we send this
string off directly? And similarly, if we try to find ‘c’ in “India” that should print to 0, well this
does work and what we are going to do next is to see how or why this works.

713
(Refer Slide Time: 6:33)

So for this we need the notion of a character string constant. Character string constant, constants
are simply text enclosed within double quotes. For example, “India” is a character string
constant, “C++ is nice” and “please give your name” are also character string constants, they are
constants in the sense that they are not variables, you cannot do, you cannot change things inside
this, you are not expected to change things inside this.

Now, how does C++ deal with such constants? Well first of all C++ stores the string in some
place in memory and of course a null terminator is also stored, so that is the convention and sort
of it is useful to follow conventions sort of, sort of blindly. So the null terminator is used and you
will see that it comes in handy. And now this resembles char array, so C++ denotes character
string constant by the address where it starts. So it really treats it like a char array, but it is a char
array that C++ itself has created.

So when you, when you type this C++ looks at it and it stores it somewhere and it says that oh
look whatever you have typed here is at this address and it is the array stored at this address. So
when you pass a character string constant, the address where you stored it memory is passed, so
this happens just like any array. And I should note that the type of this is const char *, so what
that means is, you cannot modify the content of this inside, inside the function, rather I should
say you will not modify, you are promising that you will not modify the array that is being
passed.

714
And indeed C++ does not want you to do that, so if you send, if you write, if you send this as an
argument to, say, findchar, then C++ does not want you to change the value of this “C++ is nice”
this entire thing. There are reasons for it, C++ may store it in regions of memory which the
computer may have some special restrictions on, so that when the user program executes, that
region of memory is read only, that that may will be possible.

So as a result C++ says that look you are not supposed to change this and the way C++ makes
sure that does not happen is by requiring you to declare this argument as const. In any case you
do not, you are not intending to modify that argument when you try to find a character in some
string, you are not intending to modify that string, anyway so there is no harm for you in
declaring it as a const.

(Refer Slide Time: 9:41)

So that was relatively simple function and that was a discussion of what are character strings.
Now, we move on to a little bit more complicated function, but more than the complexity, it is a
new notion that we want to introduce, this is a notion that is very commonly used with character
strings, that is comparing them using the lexicographic or the dictionary order. So, what is that?
Well words are stored in the dictionary in a certain order that makes it easier to locate the word if
needed, you know this when you search a dictionary, what words come first?

Well all the words beginning with ‘a’ come first, then those beginning with ‘b’, then those
beginning with ‘c’ and so on. And within the words that begin with ‘a’ what is stored first? Well

715
those with second letter ‘a’, then those with second letter ‘b’ and so on. So this is the so-called
dictionary order of words or the lexicographic order of words.

(Refer Slide Time: 10:56)

So, the function that we are going to write has the following specification. So it takes two
character strings and returns ‘=’ if the strings are exactly equal, so it returns the character ‘=’, it
returns the character ‘<’ if the first string will appear before the second in the lexicographic
order. And it will return ‘>’ if the first string will appear after the second in the lexicographic
order. So this is an order, this is an order between words and you can say that something appears
before so it is smaller, so that is also an implied notion, or it is more like an associated notion.

716
(Refer Slide Time: 11:44)

So, how do you write this? Well, here is the function. So let us call it compare, and it is going to
return a char as we said and it should take two character strings as arguments, so the two that we
want to compare. And since we do not intend to modify those two strings, we are going to make
them constant. And of course, if we make them constant then we can also supply as argument
character string constants if we wish.

So, what is this supposed to do? Well, we will start from the beginning of both, and compare
corresponding letters. If they are the same, then, so far two strings look equal, you do not know
which one will be stored before in the dictionary and which one will be stored later. So you have

717
to move on to the next letter of both. If at any point you find that a’s letter is smaller than the
letter of b, then what does that mean? That means that ‘a’ will be stored before in the dictionary
order and so you can immediately return ‘less than’.

Likewise, if you find that b’s is letter is smaller, then you can immediately return ‘greater than’.
If both strings end without finding a, without there being a difference at any position, then you
can just return ‘=’. And if one string ends, its letter will be null and null is ASCII 0, and it is
smaller than any other letter. So effectively this case if you are comparing the two, the
corresponding letters, then the letter which is ending will be considered, the letter will be
smaller. And therefore, by the previous logic queue will be returning ‘<’.

But that is good because the letters which terminate, the words which terminate earlier are
considered to be coming first. So, for example, if I write mat that appears before mate. So that is
exactly, so that will also be handled properly by our mechanism over here. So that is really what
the algorithm is.

(Refer Slide Time: 14:28)

And so here is the solution, we start with i=0, this is the position from which we compare. And
while, while true or we are getting into, we are not, we are always going to the next iteration over
here. So, if we find that both the ith element of ‘a’ as well as the ith element of ‘b’ are null, then
that means we have gone through the loop several times and we have not discovered a difference

718
and we have come to the end of both words. And so we can return equality, we have discovered
that those words are equal.

If we find that a[i]<b[i], then as we said we can return less than, if we find a[i]>b[i] then we can
return greater than. And if none of these is true, so what is that case? So that case is if a[i]==b[i],
then we have to go and examine the next letter and so we do i++, so this code is also discussed in
the book, but this is slightly more compact.

(Refer Slide Time: 15:46)

So you have to, as an exercise you have to write a function which takes as argument a character
string and returns 0, if the string is 0, 1 if it is 1, and so on, and 9 if it is 9, and minus 1 otherwise.
So, you can just compare say the given text string with these text strings and depending upon
what the comparison is, you can just let return the appropriate numeral.

719
(Refer Slide Time: 16:17)

Alright, so what have we discussed? So we have talked about how character strings are passed to
functions, then we also talked about how constant character strings are represented, and how they
are passed to functions? Basically you put a const, then we talked about the notion of
lexicographic order, and we discussed a function to compare strings by the lexicographic order.
We will take a break now and in the next segment we will discuss two-dimensional arrays.

720
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 17 Part - 3
More on Arrays
Two dimensional arrays

(Refer Slide Time: 0:20)

Welcome back. In the next, in the previous segment, we discussed how character strings are
passed to functions. The notion of constant character strings, and we also did example of
lexicographic order, a function to compare strings by lexicographic order. In this segment, we
are going to discuss two dimensional arrays. Now, two dimensional arrays are quite nice,
because we can store matrices or tables using two dimensional arrays and also other things,
which we will see in a minute.

721
(Refer Slide Time: 0:49)

So, this is how you might declare a two dimensional array. So, this is a two dimensional array of
doubles, what does it do? Well, it creates m times n variables. And these variables are accessed,
or we can think they have names xyz[i][j], where i must be between 0 and M, and j must be
between 0 and n the upper bounds not inclusive. So, what does this do, so it creates m times n
variables, and you can think of this, think of these as organized in a table with rows and columns.

So, the ith row of xyz is the one in which the first. the first index is i, the other index can be
anything at all. So, it can take all possible values 0 through n-1. So, so this second index can take
all these values. So that is the ith row. And the jth column of xyz is what you get, if you hold the
second index, fixed j and allow all the, the first index to take arbitrary values. So, in fact, it is
natural to think of these elements as arranged in two dimensions, in a table, so to say.

722
(Refer Slide Time: 2:40)

So, so this is the element [0][1], then this you can think 0, you can think of the element, sorry,
this is the element [0][0], you can think of the element [0][1] as sitting over here, then [0][2] as
sitting over here all the way till [0][n-1]. And in this direction, the first index is going to change,
so this is going to be index element [1][0], this is going to be element [2][0] and this is going to
be element [m-1][0]. And in the last column, similarly, you are going to get the element [m-1][n-
1].

So, this will be the second row and this will be the second column, so that is what it is. So, on a
computer you get m times n variables and for your visualization purpose, we are thinking of
these being organized as rows and columns, but the computer does not really think about them as
being rows and columns. Well you may ask, well how does the computer store them? So, the
computer stores these variables in what is called a row major order.

723
(Refer Slide Time: 4:37)

So, so let me write that down. So, the computer will store these variables. So, row 0 first. So, say
[0][0] and [0][1] all the way till [0][n-1], then it will store the first row. So this is [1][0] and
[1][1], and so on, okay? So, so this is increasing address, address and memory. So, it allocates a
block of memory. At the very beginning of the block, [0][0] is stored, then the next [0][1] is
stored, so the row, all the elements of row 1 are stored, then all the element row 0 are stored, then
all the elements of row 1 are stored, then all the elements of row 2 are stored, and so on. So, you
do not really need to know, but this is how it is stored. For programming purposes, it is not quite
necessary. Well, in a way, we will see in a way it is it is useful to know this.

724
(Refer Slide Time: 6:03)

Okay, now, when you define two dimensional arrays you can simultaneously initialize them as
well. So, for example, here you have an array pqr of 2 rows and 3 columns, so you give the
initialization for 0th row and then 1st row, that is put itself put in braces and inside that you
should supply 3 values because the second dimension is 3, so the number of columns is 3, so 3
and 3 given over here . I could have put them in the same, I could have put the whole thing one
after another also but I just wanted to share you that this is the, this is 1 row and this is a second
row, okay. All right. And, yeah, so the values are picked up from the initialization list also in row
major order, the order in which the data is stored on the computer as well. Now, two dimensional
arrays that I am describing right now, are a little bit, are not really all that useful, so we will see
why in a minute. And later on in the course, we will talk about nicer two dimensional arrays, but
anyway, many of these concepts like having two indices, or, yeah, or even the fact that a two
dimensional array really can be thought of as a one dimensional array followed by another one
dimensional array, are actually important and so, this is something that we get it from the
language C, and we might as well learn it, because these ideas are important for the nicer ideas
that will come later.

725
(Refer Slide Time: 7:49)

Anyway, so some examples, so this says, create a 10 by 10 matrix and initialize it to the identity.
Okay, so value 1 in those elements whose indices are the same? Okay, diagonal elements, and 0
elsewhere? Okay. So, first of all, the matrix will have to be declared in this manner. So 10 rows
and 10 columns and then for i going from 0 to 10 and say, this is the row index, and this is the
column index. And if I and j happened to be the same, then you are going to set A[i][j] to 1, if
they happen to be different, you will set A[i][j] to 0. So, that is exactly what you want, when you
want to create an identity matrix.

726
(Refer Slide Time: 8:39)

Here is another example. This time you want to create an array m to store the marks of 10
students in 5 testes and then you are asked the read the marks and store them in M. And you can
ask that the marks be given in a convenient manner for you. So, so, we want marks of ten
students in 5 tests, so 50 marks in all and 10 students 5 tests, so we should have a row in which
there are five marks. So, a row for every student so 10 rows, so 10 rows, each row consisting of 5
columns. So, that is what we have here, then for every row or for every student, we are going to
print them as say “Give me the marks of student ‘i’. And then we are simply going to read
marks. So, there are 5 marks to be read. So, we are going to have another loop and this time we
are reading the jth mark of student i and, so whatever comes in, whatever is typed in will be
placed in M[i][j], that is it. Okay. One more example, so here we have an array of characters,
okay. So, character arrays are again slightly different from other arrays, even 2 dimensional
arrays are slightly different. So, these are different in the sense that, of course, they have 3 rows
and 20 columns. And if we had not initialized then that would be the same as before but the
initialization is slightly different.

727
(Refer Slide Time: 10:23)

So, here you are initializing it, so that you can supply all the data but again, just as we initialized
1 dimensional character arrays, the initialization is slightly different. So, here you are going to
find as many character string constants as there are number of rows and each string constant is
going to be initializing the corresponding row. So, this will create an array country, countries
with 3 rows of 20 characters and an interesting idea is that a two dimensional array is a collection
of one dimensional arrays. So, notice I said, if you remember when I said that the 2 dimensional
arrays are stored in row major order. So they are stored 1 row at a time, one row following
another row and so, each of those rows can be thought of as an independent array and that is sort
of exploited in these char arrays, okay. So, countries[2] used to denote the third row and so this
will be going to 0th row, this will go into the first row, this will go into the 2nd row, okay,
countries i consist of countries i[0] to i[19] or ith row. So, row i initialized using the ith character
string in this right hand side.

So, what happens so, row 0 gets India followed by the null character, row 1 gets Nepal followed
by the null character and row two gets China followed by the null character. And inside each
row, say the 0th character over here will go to this 0th column, this will go to the first column
and so on. And we can access individual characters as well. So, if I write countries[i][j] then it
will give me the jth character of the ith row or the jth character of the ith character string which
is being stored, okay.

728
So, [1][1], for example, will mean so, the first word, so, this is first, this is 0, this is first, and the
first character. So, this is the 0th character, this is the first character so it will mean this e. So, if I
print, I can print countries[2]. So, although country has 2 indices, I can just use one of them and
that will be in just that row, that entire row. So, the second row, or this is the 0 row, 1st row, 2nd
row. So, the second row stores the character string China and therefore, if I say
cout<<countries[2], that character will get printed followed by the new line.

(Refer Slide Time: 13:40)

Now two dimensional arrays are useful also because they allow us to define polygons in
simplecpp. So here is the way polygons are excepted to be defined. So you write the key word
polygon, then you write the name that you want give to the polygon and then you give two
coordinates which are rotation center of that polygon. And then you give the vertices of the
polygons, and this is going to be a two dimensional array and you will have to tell how many
vertices there are? So, for that you specify n.

So, the vertices is an n by 2 array, but there is something interesting or something unusual about
arrays in C++, which is that you really, you really cannot specify or it is not customary to specify
the second dimension. You can, but usually, these two dimensional arrays are useful only when
the second dimension is sort of a fixed number. So, here the second dimension is a fixed number,
you know, that in on the plane, you always have to give two coordinates.

729
So, we are going to, so this is going to have n rows and each row is going to have two columns,
one column which gives the x coordinate and other column which is going to go y coordinates.
So, here the how many columns are there does not need to be given because we sort of know
that, okay. So, whenever we, whenever we define this polygon you are expected to give an array
of this kind. So, what is not known in this is n that is what you have to specify over here. So,
here is an example. So, this is going to draw what is a house shape, so maybe we should draw a
picture of this.

(Refer Slide Time: 15:43)

So, what does this look like? So, this is, let us say this is (cx,cy), which is the origin about which
these coordinates have to be given. So, (-50,0) is going to be, so X coordinate is -50 with respect
to this, so it will be say somewhere over here, and 0 because it is at the same level, the y
coordinate is at the same level. Then the next point is (50,0), okay, so it is at the same level over
here, but 50, on this side. So, this is, this is point 0, this is point 1. Okay.

Then the next point is (50,-100), so 50 is this and -100. Well, when we write coordinates, we
have to remember that the y axis is actually going in this direction. So, this is 0, then this is -100,
okay. So, this is the second coordinate. So, this is vertex 2. Then after that, we have (0,-50) so it
is somewhere over here and -50 somewhere over here. So, this is the next coordinate and (-
50,100) this is an X coordinate. So, the polygon that will get drawn is this. Okay, so, well, as you
can see, it resembles sort of a very, very schematic house.

730
(Refer Slide Time: 17:35)

So, this command, Polygon house(250, 250) says that I want this house to come up at screen
coordinates (250, 250). So with respect to the screen coordinates, these coordinates are going to
get measured. Okay. So, so this coordinate really is going to be (200, 250), if you look at the
screen coordinates. Now polygons can be translated, rotated, scaled, given color and things like
that, exactly as in chapter 5, okay, of the book.

731
(Refer Slide Time: 18:04)

Okay, so let us see this, let us do a quick demo of this.

(Refer Slide Time: 18:34)

Okay, so this is our, our array, what we just had there, and this is the created polygon. And notice
that I put initCanvas at the beginning, because otherwise, this would be an error. You need to
have initCanvas called because that is where the polygon is going to be drawn. Okay, so let us do
something interesting after that, just for fun. So, what we are going to do is, we are going to
rotate this, so that will show you where the rotation center is.

732
So, maybe I will wait for one second so that you get the chance to see the original position. And
then I am going to rotate. So, repeat, say, maybe say 36 times and what I will do is I will rotate, I
will say house.rotate(10) and we will wait, say, for say 0.1 second so that it does not all happen
to fast and that is it., okay? So, let us see, let us compile this and see what happens?

(Refer Slide Time: 19:30)

733
734
So, see it is rotating? So, see Okay, so see it is rotating. So, I think I am turning it a bit too much.
But anyway, you see how it is rotating?

(Refer Slide Time: 19:55)

735
736
737
So, maybe let us just try, just try to change this a little bit. Okay, so how is that, how it rotates 10
degrees repeat 36 times, so let us maybe I know what happened. So, I should really be saying say
house.left or house.right. Rotate takes the angle in radians so that is why it rotated too fast. By
too much. See, this is rotating about the center and it will come back. Well houses are not
supposed to rotate, but the point of this was just to show you that the center the rotation center
was here. This is the point with which, with respect to which we specified the coordinates and
that is the point which we can use to rotate as well. So, you can do fun things with this this kind
of rotation if you want alright.

(Refer Slide Time: 21:06)

738
So, as an exercise in two dimensional arrays, I would like you to write a program which
multiplies two matrices, say, A and B and computes their product in a matrix C. And for this you
may remember the formula for matrix multiplication. So Cij is equal to Aik times Bkj. But, here to
sum this over all, the values of k. Alright! So, what we are going to do, look at next is how do
you pass two dimensional arrays to functions.

(Refer Slide Time: 21:44)

So, this is, of course, something that is desirable to have, because, of course, you could, you
might want to have functions, say a function which multiplies and n by n matrix by n by p
matrix, so for any m and p. And the natural idea would be to pass the starting address of the
array, the number of rows, the number of columns. Unfortunately, C++ does not quite do this,
right. So it requires you to specify the number of columns as a fixed number at the time of
writing the function.

So, there is a technical reason for this. And I am not going to explain to explain that to you,
because it is kind of a silly reason. It is kind of a complicated, there is a complicated reason for
it. But the upshot is that the second, the second dimension, okay, the number of columns has to
be given in a fixed manner. Okay, so I will give you an example of this just to make it clear. This
is definitely a C++ language limitation, but the more modern thing that we will later on will not
have this limitation and so this will be taken care of later on.

739
(Refer Slide Time: 23:00)

Just to tell you what I mean this is what it looks like, so the second dimension has to the
constant. So, if I want to write it, if I want to have a function for different length 25 over here,
sorry, this function will not work, if I want to pass an array with different length this function
will not work. Anyway let us just see what this might be doing. So, here we have, what are we
doing, we are getting an array with some unknown number of columns but there is an argument
‘n’ which is going to specify how many columns that is and the function then simply prints all
the strings in C. So this is the main function, this is our old array, so it has 3, 3 strings in it, and if
you call it in this manner, then all the three names will get printed.

740
(Refer Slide Time: 24:01)

So. what did we discuss in this segment? So, we discussed the basics of 2 dimensional arrays We
said that they can be used for storing tables, matrices and multiple character strings. We also said
that a 2 dimensional array can be regarded as an array of 1 dimensional arrays. Next, we are
going to come to command line arguments, but we will take a break first.

741
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 17 Part – 4
More on Arrays
How to accept command line arguments

(Refer Slide Time: 0:19)

Welcome back in the last segment we discussed two dimensional arrays. Now, we are going to
talk about command line arguments. This also uses arrays, and arrays, but arrays are not really
two dimensional. So, what are command line arguments?

742
(Refer Slide Time: 0:37)

So far, we have executed our programs from the command line by typing ./a.out at the shell
prompt, or of course, we have executed them from by pressing the run button, but you can
specify arguments from the command line, and even if you are using the IDE, you can get into a
shell prompt and then there you can run the run the program and at that time you can give, you
can arguments when you run the programs.

So, for example, you can say you can type something like ./a.out Math followed by Biology. So,
two words you are typing on the command line in addition to the name of the program that you
want to execute. So, the program can get access to what you type and how to do that is the topic
of this segment. By the way a.out is just the default name given to our program after compilation
by the compiler.

We can ask the program to give it a different name if you wish or we can rename the file ourself
explicitely, but this is just to keep things simple that we are assuming that we are just using the
name that the compiler gives to the executable progarm that it creates on compiling our programs.

743
(Refer Slide Time: 2:11)

So, I am going to show you a program that is the simplest possible thing. So, it does not do
anything with whatever is the typed, it just prints and shows you what is typed. The main
function earlier had a signature int main(). Now, here to get the command line arguments, you
are going to have a different signature.

So essentially your computer when it executes a.out, is going to execute a.out or it is going to
call the main function but it is going to tell the main function that, “Oh! Here are these additional,
here are these things that the user typed when the user started off the program.” So, therefore,

744
there are these additional things. So, what are this additional things? Well before geting into that
let me just show you the program and then we will explain it.

So this is the main function and that is the only function over here but its signature is different
and now we will tell you how this how these arguments are to be interpreted. So argc is going to
give the number of words typed on the command line by the user. So, as you can, as I said when
your computer starts off the main program, it is asking the main function to execute and at that
time, it is calling the main function and it supplies these two arguments, the first argument says,
“How many words are there on the command line?”

So this is just function overloading if you will, so you remember that I can have the same name
with different signatures and this is just a different signature. So, both names are both, both ways
of calling main are acceptable and if you want the program to get access to the command line
arguments, then this is what supposed to be used. So, I told you what argc is, and then, let me tell
you what this complicated looking thing is. So, to understand that, let us just go over what it
could possibly mean or some, let us do it step by step.

So, suppose I typed this as the declaration. What does it say? It say that x is an array of char.
Now, what would this say? So, this would say argv is an array of char *. In other words, each
element of argv is a char star or each element of argv is a pointer to a char array. And argv has
length argc. So, this argc that is given is has length, is the length of this array, so how many
element are there, are argc elements in this array. So, argv is the name of an array it has argc
elements and each element is a char star. So, it points to another char array.

So, I think a picture is necessary, so let me draw a picture, so this is array argv, so it looks
something like this and it has elements 0, 1 all the way till argc minus 1, because there are total
of argc elements. And what is each of these elements? So, this is of type char star, so it means it
is a pointer and it points to the 0th element of an array and this is the first word typed by the user
on the command line. So typhically this is going to be ./a.out, but of course, it is going to have a
null at the end as well. So, this is, so this 0th element is going to type, is going to point to this.
The first element is going to point to an array, which stores the second word typed by the user
with a null terminator, so let us say the second word typed was Math and then there was a null
terminator, so let me get rid of this.

745
So, this is the second thing, and then maybe there was a Biology also, so this points to another
array, so Biology followed by the null character. So, this is this complicated looking structure
that is given to you. So, what is this program doing with this structure? So, it is printing out
argv[i], so let us see what argv[i] is, so this is the array argv, argv[i] is this, but what is this, this
is char *, so suppose I write cout, after which I give char * value, what happens well that simply
prints out this value, prints out whatever it points to.

So, this first thing would just point, print out a.out, and the rule to be used over here is that
whatever gets printed out will be printed out only until the null character. So, cout<< argv[0] will
end up printing ./a.out. Then in the next iteration cout<<argv[1] will end up printing Math and
after that Biology will get printed. So in this case argc, if I had just typed these three things, argc
would have been 3.

(Refer Slide Time: 8:55)

So, I have basically told you how this executes, but let us just do it again very clearly over here.
So, argv is an array of 3 elements, argv 0 contains address of an 8 element array
containing ./a.out followed by null, so why 8 elements “./a.out” and null. So, notice that exactly
C++ will allocate exactly as much space as we want. So argv[1] contains Math followed by null
and argv[2] contains Biology followed by null. So, basically in in a when this things are executed
dot slash a dot out Math and Biology will get printed.

(Refer Slide Time: 9:44)

746
So, what are we studied in this entire lecture sequence. Well we studied array of representing
characters string first, later on we studied the string class which is nicer and safer. But as I said
many of the ideas that are presented over here will be applicable there as well. And these ideas in
any case are used alot in the C language and you may encounter programs which are specially,
which only use the c language facilities, and therefore, this is something that is useful for you to
know. Then we studied two dimensional arrays and basically you can extend that idea, so if I
write int a and give 3 numbers in 3 square brackets than that gets me a 3 dimensional array.

747
(Refer Slide Time: 10:43)

So, what is a 3 dimensional array? So, it is a collection of elements or collection or variables, say
a[i][j][k], so these, you can think of these as the different names and for this, for this declarations
a[10][20][30] i will range from 0 to 19, j will range from, sorry, i will range from 0 to 9, j will
range from 0 to 19, and k will range from 0 to 29. So, in all if you write int, sorry if you write int,
a 10 20 30 you will get, so 600 times 10, 6000 variables. And just as we thought of a two
dimensional arrays as organised in rows and columns, you can think of two dimensional array as
organised as a three dimensional objects, so rows and columns but stacked on top of each other
as well. So, those are also needed in many cases and they can be had over here, as I said earlier
the C++ equivalents will be a little bit nicer and you will see them later on.

748
(Refer Slide Time: 12:10)

And yeah, so the ideas of indexing and things like that are, of course, needed for C++ versions,
the nicer versions that we are going to see later. Then we saw command line arguements and
these are often useful, so you may want to say that look this is the file that I want to use or rather
than, gets some data after running the program, so by cin you can directly get it as you type the
name of the file, as you type the name of the executable, as you start up the executable program.

So, this is very convenient and you should definitely write a few programs of using command
line arguments and master this idea. Alright, so that concluded this lecture, as always the text has
several exercises and I will urge you to solve those, Thank you.

749
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology, Bombay
Lecture 18 Part 1: Arrays and Recursion
Binary Search Introduction
Hello, and welcome to the NPTEL course on an introduction to programming through C++. I
am Abhiram Ranade and this lecture is about arrays and recursion. The reading for it is
Chapter 16 of the text. So recursion is very useful for designing algorithms for data stored in
arrays and as we saw for data stored elsewhere as well, but also for stored, also for data
stored in arrays.

(Refer Slide Time 0:34)

So we are going to talk about two very useful recursive algorithms for which you work on
arrays and these are the binary search algorithm and a sorting algorithm called merge sort.

750
(Refer Slide Time 1:06)

So let me begin by discussing the notion of searching an array. So the input to this is an array
of length n and then we are given a key or an element of a value x which is called, which is
often called the key. And say it is also an integer and we want to know whether x is present in
A, okay? We may also know things like at what position it is present, but for now just for
simplicity, let us say, we just want to know whether this x is present in A.

And if it is present, we should return true, otherwise we should return false. Now this is not a
new problem. When we did the marks display problem, we already did this. So we were
given a roll number and we went through our area of roll numbers and tried to check, tried to
find if the roll number was present somewhere.

So this is just, this is just a simpler, simpler version of it. And I am doing this primarily to
remember to, to jog your memory as to what we have already, what we already did. But then
we are going to do something more interesting with it. So the natural algorithm that you have
already seen is to scan through the array or go through every element starting at the
beginning, and return true if you find it.

But if you go to the end without finding it, then you return false. So here is the algorithm or
here is the program. So as argument, we take this array, array name A. I could have written
this as int A[]. But I can also write as, write it as int *A. Then we are going to start at zero
and n is assumed to be the length of the array over here.

751
And so we are going to go through all the elements. If we ever find that x is one of the
elements, then we return true otherwise we just continue going through the array until the end
of the array. And if we get to this point then that means, we have not, we have not seen x in
the array at all and therefore, we return false. So you have seen this a number of times
actually, but as I said, just to set the context that is why I am saying this. And this is called
linear search, I think we have also used that term. So I just want to observe that this is
somewhat time consuming, to decide whether x is present we essentially have to scan the
entire array. We certainly have to scan the entire array the element is not present.

And say on the average if the element is present, we will scan half the array. So, so it, our
time might be small if the array, if the element is present at the beginning. It might be large if
the element is present towards the end, but say on the average it takes us, we have to go
through half, half the array. So if the array is large, this can be this can take quite some time.

(Refer Slide Time 4:32)

So let us now consider us a different problem that of searching in a sorted array. So what is
the sorted array? Again you know it. But let us just, let me just define it because we are going
to use it over here and sorted when we talk about a sorted array. There can be two orders, one
of two possible orders. So the non-decreasing order is A[0] is less than or equal to A[1] less
than or equal to A[2].

752
And so on until A[n-1]. So there are, so the elements are increasing but with equal elements
allowed. So that is why this order is called a non-decreasing order. We could have a non-
increasing order and that simply means A[0] is greater than A[1] and so on until A[n-1]. So
now we want to search in such an array, say whatever non-increasing or non-decreasing.

We know of course what it is, but yeah, so we want to search in it. So the interesting question
of course is that does the sortedness help us in the search. And if so how much? And
naturally if it helps us a lot, then maybe we will say that look let us keep our array sorted.
Because if you are doing searching, then that our searching might happen very fast. All right,
so let us consider the problem, we are searching for x in a non-decreasing sorted array A[0]
through A[n-1].

(Refer Slide Time 6:13)

Now here is the key idea. We are going to compare x not with A[0] as we did in the case of
linear search, but our very first comparison is going to be with the middle element of that
array.

753
(Refer Slide Time 6:43)

So let me draw a picture. So this is my array A. So this is 0 and this is n-1. In linear search we
compared x to this, then to this, then to this and so on. The new idea is that we are going to
compare it to this middle element. Well what is the middle element? This is the (n/2)th
element element with index n/2. Now this is not exactly the middle element if say n is even it
is sort of on the, on the right side. But we want where I am talking about an approximate
middle and of course division is integer division.

So we get an integer. So x is compared to this element. Now let us see, so what if x turns out
to be smaller than this element. What do we know. If x is smaller than this element, then x is
also smaller than all of these elements. So why? Because these elements cannot be smaller
than this, these elements can only be larger. And therefore it means that our x must lie only
on this side, must lie only in this region. So x can be present only in this region.

754
(Refer Slide Time 7:56)

And therefore, our subsequent search can be restricted to this region. So the first half, again
half I am using approximately.

(Refer Slide Time 8:14)

What if x is bigger than or equal to n/2. So if x is bigger than or equal to n/2 then we know
that x must be present in this region including this n/2, well x could be present here also, but
never mind that, if x turns out to be bigger than or equal to this, then it has to be present in
this second half. And therefore, again, we can say, I will ignore the first half and I will just

755
restrict myself to this half, because if x is present, I am going to, if at all it is present, I am
going to find it in this region as well. So x if present will be present in n/2 through n-1.

And if it may be present, but I am going to ignore that and in the rest of the algorithm will
only search the second half. Now how do we search the halves? This is the beautiful answer.
So we are going to recurse and I have really told you the entire algorithm. Well I will tell
you, the exact exact function in a minute, but I have really told you whatever I really,
whatever the ideas are and let me just make one observation that I have only done one
comparison. But in one comparison whichever way the comparison turns out to be, I have
eliminated half the elements. So in one comparison, I have sort of reduced my problem to
half the size so if I do linear search I will do thousand comparisons. But now even if I do a
linear search after this one comparison, I will still only do 500, but that is not what I am
going to do in any case, I am going to recurse. So the savings that I have will be enormous.

(Refer Slide Time 10:12)

Alright. So let us sort of develop this idea so what is our plan? So we are going to write a
function Bsearch. It will search a region of an array instead of the entire array, of course, the
region could be the entire array, but in general it would search some region and the region is
going to be specified using two numbers, the starting index S and the length L of the region.

756
(Refer Slide Time 10:42)

So maybe I should draw a picture here as well. So this is my array again, and this is 0, this is
n-1 and let us say this is some starting index S. So the length of the region that I am going to
search is going to be some L over here. So there are L elements in this entire thing. So what is
this index over here? This is S+L-1. So I could have specified the starting index and the
ending index, but I could, I can give the same information by specifying S and L. So both are
really equivalent, I am just happening, we are just happening to use L over here.

So Bsearch is going to be given S and L and of course x which is the element to be searched
and B search is going to search this, this array but not the full array, it is going to search only
within this region.

Now if L is 1, then what happens what is this array? So if L is 1, then these two elements
really become the same element. So L equal to 1, so these two elements become the same
right. So we are really, the region that we are talking about is really a single element region.
So searching a length one array or a single element region is very easy.

So we just check whether this A[S] is equal to x. If it is? We return true, otherwise we return
false, as simple as that. Otherwise what do we do? So just as we compared x to the middle
element over here, we are now going to compare x to the middle element of this. So what is
the middle element?

757
So the middle element is somewhere over here and this has index. So I will write the index
over here, so this has index S+(L/2). So remember this was n/2 and this was 0, so it was 0
plus n/2 and this is, this has index S+(L/2). So I am going to compare x with this and again,
the idea is going to be that I will eliminate either this side or eliminate this side. So medium,
the median element, middle element is S+(L/2) and the algorithm is called binary search,
because the size of the region to be searched gets roughly hard at each step.

(Refer Slide Time 13:29)

All right so here is the code. So Bsearch is going to take the starting address of the array. And
the region is going to be given by the index S and the length of that region is going to be 1/L
and x is going to be the element that I want to search. So we are going to search for x in A[S]
through A[S+L-1], as we just said.

So if L is equal to 1, we can check whether A[S] is equal to x. So what does that mean? We
are returning the result of that condition. So if that condition is true then we will return true,
otherwise we will return false. Then we are going to, we are going to look at the middle
element and that middle element is L/2 or so, the half, the halfway point or the half of that
region, half of the length is L/2. And so we are going to check whether x is less than or equal
to S plus H.

758
(Refer Slide Time 14:50)

So in this picture is, this is, this is S+(L/2) or it is also S+H. So this element is A[S+H]. So
we are checking whether x is less than this element or not. If x is less than this element then
what happens? If x is less than this element, we have to search which region, well, we have to
search the region starting at S and going to S+H-1. So that is what we are searching and
indeed if I write search the region (S, H) H is the length, so that is indeed saying S through
S+H-1.

Now this has to be written carefully because you do not want to miss out on these minus ones
or you do not want to write an unnecessary one. So you have to do this, you have to do this
somewhat carefully. Otherwise what do we have to search? Well otherwise we have to search
this part. So starting over here you have to search all the way till this point, just as in the
previous case we searched over this entire region. So what is that region? So that starts with
S+H.

759
(Refer Slide Time 16:09)

So that is what is over here and we go to the end of the region. So that is what the region
which I marked over here and in fact by specifying the length in this manner, I get exactly
this. So why is that? So the final index of the region is going to be this, plus this minus 1, just
as the final index over is this plus this minus 1. So this plus this, is S+L, -1 is exactly the
region that I wanted.

So I have written exactly the analogous code of what I had of the algorithm that I described at
the very beginning, and what is the main program. So say it is given some input like this. So
this is a sorted array and in this sorted array, I want to search for 11. So my call is (A, 0, 8).
Why 0, 8? Because I want to start at the 0th index and the length that I want to search through
is the entire array or 8 and then x is 11.

So that is the call that is, that is the value that I am searching for the key that I am searching
for. So this will print a 1 or 0 depending upon whether 11 is present or not present in the
array. In this case 11 is not present. So it will print a 0, it should print a 0. Now this is our,
this is our function and it is a recursive function, and, we said earlier that the recursive
functions have a certain format. So we should check whether that format is there in this case
as well.

760
(Refer Slide Time 17:54)

So for example, one question we said that we should be asking is, is there a base case and is
the correct answer being returned for the base case. Well let us see this. Is there a base case
over here? Yes. So L equal to 1 is certainly a base case. This is the case then the, the program
returns without recursing further. In this case, does it return the correct answer? So if L is 1
then that means, we are searching an array of length 1 and therefore, and the array starts at S.

So this is, this A[S] is the only element in the array.So if you want to know whether x is
present, we should check whether that only element equals x. So indeed, we are doing that
correctly. So that takes care of that first question. Then, you have to check are the recursive
calls valid?

761
(Refer Slide Time 17:54)

So let us go back. So we are making this as a recursive call. Now as I said earlier, we have to
be sure that the indices are given correctly. So for example, this L-H is crucial you should
not, I mean at the very beginning for example certainly you should not give a bigger index
than 8 over here.

So similarly you should make sure that these array, these indices fall within, within the range
that we want, these are actually the indices, these actually define the region that you want
searched. So we did this check and yes these are the correct regions that we want searched.
No matter what the arguments are, what, no matter what these S and L are. So that is also
done.

762
(Refer Slide Time 19:45)

Now here is an important question. When we are recursing the recursive call should be
solving a smaller problem. If they solve the problem of the same size, then we are not making
progress, then we are likely to run into infinite recursion.

(Refer Slide Time 20:10)

So we should be checking this. So this is perhaps the most important check. So here, there is
a notion, there is a natural notion of the problem size over here. In this case it is captured
quite nicely by this argument L. So we are searching in a region of length L. So what we need
to be sure about over here, is whether our recursive calls are searching in a smaller region.

763
And of course if we keep on doing that, then eventually we will get to a region of size 1, we
can certainly not go below go below 1 and in which case we will hit the base case. So we
have to make sure whether this call is searching a smaller region and this call as well. Well
what we want to know is, is H smaller than L. So what is H? H is L/2. Is L/2 smaller than L?
Well this is integer division. So L by 2 is truncating division, so L by 2 is always going to be
smaller than L. So this is going to search a smaller region, then what we started off. Well you
have to be careful. So L/2 is smaller than L, provided L is bigger than 0. So we have to also
make sure that we are never asking to search a 0 sized region. When will that happen? So it
will happen if L is 1, so if we happen to run this for n equal to 1 and if we come to this point,
then they will be asking to search a 0 size region.

But that is not, that is not happening, because if L is 1, then we are actually, we are actually
returning right here. So if L is 1, then this is never reached. So this is reached only if L is
bigger than 1. And therefore, this is always a proper call. So a proper call is that this is always
larger than or equal to 0, but now we have also checked that it is smaller than L. So yeah, so
earlier I said that this call is proper.

But it actually requires this argument that this H has to be bigger than 0 and this will be
bigger than 0 because if we start with L=1, then it will be returned right over here. And
therefore, here we will come to if L is bigger than 1. So therefore, H will always be bigger
than bigger than 0. Now, is this always going to be a valid call? Well here, can H be equal to
L? Well L/2 is always smaller and therefore, H cannot be equal to L provided H is bigger
than 0.

So this will always be smaller than L and will it always be greater than 0? Well it will always
be greater than 0 because H is going to be smaller than L.

764
(Refer Slide Time 23:31)

So let us run some basic checks. So we said that if this is a recursive program, then there has
to be a base case and a correct answer must be returned for the base case. So clearly in this
program, the size of the region being searched if it becomes 1, then we are returning directly.

So this is where we return directly. And so that is happening, so we have a base case and are
we returning the correct answer for it? Yes. We are returning the correct answer. Then the
next question is, are the recursive calls valid, do they stay within the region? So what does
this mean?

(Refer Slide Time 24:20)

765
So this requires us to check whether these numbers are valid. So this number is a valid index
because we started off with a valid index over here, so that is not a problem. Now when can it
not be a valid index? Well this could, this is potentially a candidate for not being a valid
index. So what do we want this index to be? We want this index to be always bigger than
zero. So will it always be bigger than 0? Well we are doing H=L/2. So if L was one over
here, there is a danger that this index will become 0.

But note that this will never happen because over here. We checked whether L is equal to 1
and we immediately returned in that case. So if we come over here, we know that H is always
going to be bigger than one and therefore, this will never be 0. So what we have checked is
that this call is a valid call in the sense that these indices stay within, within that region.

Now what about this index in this call. So is this going to be a reasonable index? Well what
do we know about the value of H? So H is L/2, so this could be something like S+L/2. So
since L is going to be when we come over here, L is going to be at least 1. So H is going to be
certainly non-negative and therefore, this index is going to be bigger than S. But can it be too
big? Can it go past the end of the array? Well it will not because, S+L/2 is going to be within
this region always.

So this region goes from S to, S+L-1 and you can check that this index will always be within
that region. And therefore, that is a perfectly fine index as well. What about this index S+L-
H? So H is L/2. So this index is going to be, so, so this index is going to be smaller than L
because if H is bigger than 1, then this index is, this index is going to be strictly larger than,
larger than 0. And therefore, L-H is certainly going to be smaller than L. And so in this case
we can already say that the length is going to be, length is going to be shrinking, but it will
not go down below 0, go down to 0. And therefore, again, this is going to be a valid call, this
is also going to be a valid call.

So the next thing is are the recursive calls solving smaller problems? Well again let us go
back and if we look at this, you have to argue that this is going to be smaller than L. So why
is that? Well H is L/2. So L/2 is always smaller. So therefore, this is going to be smaller. L-H
is it always going to be smaller? It is going to be smaller if H is always going to be bigger
than or equal to 1. Is that going to be true? Well H is L/2 and L is at least 1. So therefore, H is
going to be at least 1.

766
And therefore, this is going to be strictly smaller than L. So yes, so both of our calls are going
to be dealing with smaller regions. Now the only reason to go over this so carefully is
because these truncations introduced sort of some surprises because we are familiar with
doing ordinary division where division is sort of exact division. The integer division
sometimes is does things which we do not expect and therefore, it is better to check all these
things.

(Refer Slide Time 28:39)

The final question is if the answer to the recursive calls is correct and will it produce a correct
answer for the top-level call.

767
(Refer Slide Time 28:50)

So again if you look at this, if this answer is correct, then it should be a solution for this
region and that is exactly the region we wanted to search, because x was greater than or equal
to S+H. Similarly this was exactly the region which we wanted to search if x was less than or
equal to S+H. So if these answers are correct, then we will get the correct answer over here.
So, so we have run every basic checks and in fact they seem to be okay.

(Refer Slide Time 29:33)

So now we can sort of run, all right. So what did we discuss? We discussed the search
problem then we said that if it is the array is not sorted, we will do a linear search then we

768
said if the array is sorted, we do binary search. Next we are going to do an execution, we are
going to see how this program executes and then will also analyze that program. So we will
take a quick break.

769
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 18 (Part - 2)
Arrays and recursion
Binary search analysis

Welcome back!

(Refer Slide Time: 0:22)

In the previous segment, we defined a search problem and we also defined Binary Search.
Now we are going to do sample execution through our code.

(Refer Slide Time: 0:29)

770
Okay, so this is our code and I have just removed the comment, so that I can just fit my code
into this, into the slides, so it is really the same code. So, we are searching this array over
here, okay. So starting index is 0, length is 8 and we are searching for 11. So, the first call is
this call is this call. So Bsearch(A, 0, 8) is our first call. So, how does this call execute. So,
when this call start executing, S has the value 0 which comes from this argument itself and L
has the value 8, again from the argument and x has the value 11 from the argument, okay.

So, we are at this point then we do a check, is L equal to 1. Okay. Well L is 8 then certainly
not equal 1, so this statement does not execute. So, we come to this statement. So at this point
we are defining a new variable H whose value is going to be L/2, so H becomes 4. Next, we
execute we execute this statement. So, we check whether the, what is the relationship
between x and A[S+H]. Well what is x, x is 11, what is S+H, so S is 0, H is 4,so S+H is 4.
So, what is A[S+H]? Well this is A, so 0, 1, 2, 3, 4, so A[S+H] is 10. So, the question that we
are asking is this, is 11 smaller than 10, well that is not true, 11 is not smaller than 10. So this
comparison comes out to be a false, so therefore we are going to make this call.

So, this is the call that we make next, Bsearch(A, S+H, L-H, x), but what are the values, the
values are S+H is 4, L-H what is L, L is 8, H is 4, so it is also 4 and x is 11. So, a new
recursive call starts. So, what happens in this recursive call? Well we are going to start from
here. So, S in this recursive call is 4, which is we got from our arguments, so S is 4, L is also
4 and x is 11. So, in this new recursive call these are the values, so we are going to do the
same thing again. So, what happens over here, so we first check if L is 1, well L is not 1, L is
4 now, so in any case the statement is not going to get executed. So, we now create H equals
L by 2, so H so L is 4, so H becomes 2. Next, we are going to ask, how does x compare to
A[S+H]? So, what is the value of x, again it is 11, what is S+H this time, so S is 4, H is 2, so
S+H is 8. So, A[S+H] is 0, 1, 2, 3, 4, 5, 6, so this is 30.

So, we are comparing 11 with A[6] which is 30, so 11 is smaller than 30, so this is true and
therefore, we are going, so this is true so we are going to make this recursive call. So,
Bsearch(A, S, H, x) gets called, so what are these values? So, these value are 4, S is 4 over
here, H is 2 and x is 11. So, the values that are going to get called, that call you are going to
make is Bsearch(A, 4, 2, 11). Alright

(Refer Slide Time: 4:32)

771
So let us examine this call Bsearch(A, 4, 2, 11), so what’s happen in this. So, again the
variables in the activation frame take values, S will take value 4, L will take value 2, these
come directly from the arguments, x also will take value 11, then we are going to execute, we
are going to execute this statement, but L is not 1, it is 2, so nothing will happen. Then we
move on to this, what will happen to H, well H will become 1, half of L and then we are
going to execute this.

So, we are going to ask is x less than A[S+H]. So, what is x again? It has stayed 11 all the
time and S+H is now 5, so we are going to ask A[S+H] is 0, 1, 2, 3, 4, 5, so we are going to
ask is x less than A[5] or 12 and this is also true. So, if it is true, then we are going to make
this call, so in this call S is 4, h is 1 and x is 11. So, we are now going to start another
recursive call, okay. So, again we start from this point and because of the argument list, S is
going to get 4 this value, L is going to get 1 this value, and x is going to be 11.

So, next what is going to happen, we are going to check if L is equal to 1, but, yes, this time
L is indeed 1 and therefore, we are going to return whether A[S] is equal to x, okay. So, what
is A of S, so S is 4, so 0, 1, 2, 3, 4. So, A[S] is x. So, L is equal to 1 is true and therefore, we
are going to return whether 11 is equal to A[5]. So, is 11 equal to A of 5? Well, so A of 5 is
12, so this is not equal and therefore, we are going to be returning false and all the previous
recursive calls will just return the same thing, forward it back, send it backwards, and so this
is the value that will go onto main as we expected, alright.

772
(Refer Slide Time: 7:21)

Okay, so let us do a quick demo of this. So, the function is Bsearch, so let me show it to you.
So, this is Bsearch and Bsearch is the same as what I have shown you, but the only thing is I
am writing over here what the arguments are. So, just you see how the function executes.

(Refer Slide Time: 7:48)

773
So, let us compile it and run it. So, these were this, this is how the search ran, so first it was
called with arguments 0, 8, 11 and, of course, the argument A is there, but I am I am leaving
that out. Then (4,4,11), (4,2,11), (4,1,11) and if you see what we executed, this was exactly
the sequence and even here 0 was written as happen in our execution sequence, the execution
that we did by hand as well. So, let us move on to the presentation. So a few remarks, binary
search is based on a simple but powerful idea but even though the idea is simple, the details
are somewhat tricky and experience shows that even professional programmers may make
mistakes when writing binary search.

774
(Refer Slide Time: 8:57)

So the mistakes are of this kind, so when we are comparing, it should be asking less than or
equal to or less than. So, then there is this question that if the region that we are searching is
odd length, then integer division behaves in a slightly different way, then we might expect, so
we have to be careful about that. And then, the subranges to be searched have to be specified
carefully, so should not be S through H+L-1 or S through H+L, whatever it is, so the way to
get it right is to write down precisely what the function is expected to do, so at least once you
write down what you want to happen, then you can check whether that is happening.

So, at least you are, you have to be sure as to what you want, so please write the specification
very carefully and make sure you are getting these minus ones, minus ones, correct.

(Refer Slide Time: 9:59)

775
Alright, so now let us analyze this and check look if this is so carefully, have to be written so
carefully, is it worth going to the trouble. So, in other words, is binary search better than
linear search, just going through the elements left to right. So, if we consider an array of size
1000, in the second call, we search an array of size 500. In third call, we search an array of
size 250 and so on. So, every time the size of the array we are searching is roughly halving.
So, that means in the tenth call, if you do this 10 times you will get an array of size 1. So, at
that point we know, we do not have, we do not require further and we can just return. And
whatever we return at that point is return all the way back to the main program.

So, what does this mean, so time taken in this case is about 10 calls worth of work and each
call is fairly simple, as oppose to that in linear search we would do 1000 comparisons. Now.
let us see what happens if we were searching through million elements. Then here we would
have million comparisons and how many calls would we have over here? Interesting as it
may you may find, the number of calls over here is only going to be 20.

So, binary search is much-much more efficient, especially if the size of the array being
searched is larger, is large. So, put it another way, this is log n, so the time is proportional to
log n and this is n, so rather than n, so definitely a big difference.

(Refer Slide Time: 11:51)

So, what have we discussed in this segment. We said that binary search is a very fast way to
search for a key in a sorted array. And, in fact, this notion of dividing by 2 is something that
you have encountered, right, so we did in the bisection method, so even there we were
probing in the middle of the, in the middle, in the middle of the range.

776
So, range here is sort of the size of the array that we are searching, searching over. Then if
you are likely to search an array frequently, it seems that you should first sort it and then
search it, because the time to sort array will be compensated for by the time saved in the
subsequent searches. So, this raises the question, how do you sort an array in the first place?
So, this is what we are going to discuss in the next segment. So, let us take a break.

777
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 18 Part- 3
Arrays and recursion
Mergesort overview
Welcome back. In the previous segment we saw binary search.

(Refer Slide Time: 0:20)

In this segment we will see a nice sorting algorithm. So what is the sorting problem? Well the
input is an array containing numbers and the goal is to rearrange numbers in non-decreasing
order. We have already seen one algorithm for it, the so the so called selection sort algorithm.
And we said there that the time taken is going to be about n2 or rather proportional to n2. Now

778
we are going to see an algorithm called merge sort whose time is going to be proportional to
n log n so this is going to be considerably faster than selection sort.

(Refer Slide Time: 1:04)

So let me first describe the main idea of merge sort. So suppose we are given a long sequence
or an array a long array which holds that long sequence. So we are going to take that
sequence and break it into small sequences, then we are going to sort each small sequence
independently separately and this is going to happen using recursion. Then we are somehow
going to merge the sorted sequences into a single long sequence. The hope is that merging the
sorted sequences is easier than sorting the large sequence in the first place. And yes this
works out as we will see soon. So let us take an example just to make sure that this structure
is understood.

779
(Refer Slide Time: 2:05)

So say we want to sort the sequence. So the sequence has seven elements and let us say the
sequence is sitting in an array of size 7. But really let us think about it as sequences rather
than arrays for the minute. So if you want to sort it, our first step was to break it into two
sequences. So let us say the first four elements form the first sequence and the last three
elements form the second sequence. So we are going to sort both, so when we sort both we
are going to get this sequence over here.

So this is the sorted version of this and this is the sorted version of this, so these are the two
sequences we now have, after we have recursively sorted the smaller sequences, then we are
going to merge them. So in the merge, from this input these sequence and this sequence given
to us we want to produce this output. So we want that we want to have the same numbers but
they should be in increasing order or non-decreasing order really. So that is sort of the overall
overall structure of what we are attempting to do. So that overall structure can already be
written into a program and so let us do that.

780
(Refer Slide Time: 3:22)

So merge sort is our main function and this is going to sort sequences a sequence S of length
n, so that sequence is an argument. So there is a natural base case if n=1 then there is nothing
to do, we just have to return, the S itself is already sorted. If n is bigger than 1 then we said
that we are going to break it up into two small sequences so let us call those two sequences U
and V. So you want we are going to break it nearly into halves, so this is going to be n/2 and
this is going to be n-n/2.

Notice that I am not writing n/2 over here that is just to guard against the possibility of n
being odd and things like that. If n is or then that will not work, so what I am doing is this
plus this and just this is making sure that this plus this is equal to n. So that that way I know
that all the elements will either come over here or come over here. Then in this step I am
going to make a copy of the first half into U and in this step I am going to make a copy of the
second half into into V.

So this starts off where this ended and so I am going to get a copy of the second half. So I
have created now my two small sequences, what do I do next? I have to sort them. So how do
I do that? Well this is where recursion comes to my rescue and so I am going to just issue this
call. Sort sequence U whose length is n by 2 and similarly I am going to sort sequence V
whose length is n minus n by 2.

At this point I have those two sequences sorted okay in U, so they went into merge sort in U
and they are coming back in U. And now I am going to merge these two sequences. So U and
V are the two sequences that I had and I am going to get them merged into S. So that is it

781
because S will have the final sorted sequence which is exactly what we wanted over here.
The result had to be in S itself, so that is what we are going to have.

(Refer Slide Time: 5:55)

Now I want to leave you with an exercise before I conclude this segment which is that we
will discuss the merge function next, but suppose it is somehow available, I would like you to
show me how merge sort will sort the sequence 50, 20 the given sequence. Basically I want
you to draw the recursion tree which we have learnt earlier. So in the recursion tree, show the
sequence that is the argument to each call and the sequence returned by each call. So this will
just this will just be a test of whether you understand what the algorithm is doing at the high
level.

(Refer Slide Time: 6:37)

782
So what have we discussed? We have discussed the outline of merge sort and this consists of
split the given sequence into two parts, sort the two parts recursively and merge the two
sorted sequence sequences. Then we also discuss the code for the mergesort function and
what remains to discuss is the merge function. So that we are going to discuss in the next
segment, so we will take a quick break.

783
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 18 Part- 4
Arrays and recursion
Merge function
Welcome back, in the previous segment we discussed the outline of merge sort and we also
discussed the code for it.

(Refer Slide Time: 0:21)

In this segment we are going to discuss the merge function. So let us do an example first.

(Refer Slide Time: 0:32)

784
So let us take the U sequence as 23, 29, 50, 87, so this is the sorted the result of sorting. That
U that we had got by splitting our original sequence and V is the other part again sorted. So
how do we merge this? So we have to produce the sequence S. And if you think about it what
do we want in S? Well the first element should be the overall smallest. Now how do we get
the overall smallest? We need to look at both these sequences in great detail. Well no.
Because they are sorted it is the smaller of the smallest which is present in the first position
and the smallest over here which is also present in the first position.

So if I want the smallest in these two sequences I just need to look at these two positions. So
if I look at these two positions then I know that the smaller is 7, so that 7 must come down
over here. So what we get after this is this picture, so we started over here we looked at the
two elements which are (respects) respectively smaller in U and V. And we do not have to
look at the rest rest of the elements to decide which is the smallest in this entire entire set. So
we picked this 7 which is the smallest over here and we move it to S.

(Refer Slide Time: 2:07)

And this we are going to continue, so what do we do next? So this is our situation, we again
want the smallest of these two. So we really want the second smallest, in what was originally
U and V. But now that S has moved out we can say look what is the current situation of U
and V and we want the smallest amongst those. So how do we get that? So the second
smallest is the smallest in U, V after the smallest has moved out. So which is exactly this
position over here? And to get that we simply have to ask what is the smaller among what is
at the front of U and V? So the front of U is this so here there is 23 the front of V is now this
because this element has moved out. So we have to now pick the smaller of these two

785
elements and move that at the end of S. So if we do that we get this, so the smaller has moved
to the end of S or the back of S and the fronts, the elements which were originally at
difference have gone away and the fronts have sort of advanced.

(Refer Slide Time: 3:30)

So what is the general strategy? So while both U and V contain a number, move the smallest
from those at the front of U, V to the end of S. If U contains only U contains numbers, then
that means everything in V has already been moved to S and so therefore move everything in
U to the end of S similarly for V. So basically elements are leaving the arrays U, V from the
front and joining the array S at the back. Now you have encountered this, this is really what
was happening in this taxi dispatch problem. So the code is also going to be somewhat
similar.

786
(Refer Slide Time: 4:15)

So what are the details? So we are going to maintain a variable uf which is going to denote
the the element of U, the index at which that the front is currently. Similarly, so what that
means is that element 0 through uf-1 have already moved out and therefore the front has now
advanced to index uf. Similarly, there is vf and then we also want to have an index sb to the
back of s. So this is the index denoting where the next element should move into s.

So again 0 to sb-1 contain elements that have already moved in earlier. So this is this is really
pretty similar to the taxi dispatch as you might be noting. So we also need to keep track of the
lengths we need to know the lengths of U and V and so let us say we use the variables Lu and
Lv to denote the lengths. We should we could have a variable to denote the length of S but
we know that S is going to be exactly equal to the lengths of Lu and Lv because we created U
and V in that manner. So we need not define a variable for it separately.

787
(Refer Slide Time: 5:43)

So that is basically it, we can get started on our function for doing the merging. So again let
me explain U is the first sequence that we want to merge its length is Lu, V is the second its
length is Lv. And S is the array into which the result is supposed to go. And uf and vf are the
positions of the fronts. So initially the front is at the 0th index here and the front of V is also
at the 0th index.

We need an element for the back but that will be a part of our main loop. So we are going to
move elements at the back and so the back is going to keep on advancing, so it is going to be
the 0. It will become it will keep on increasing and when we have moved Lu plus Lv
elements then we are going to stop. So that is how the whole overall structure is going to be.
So how do we do this movement? Well if both U and V are non-empty and when will they be
non-empty? Well if uf is smaller than Lu so the front is still pointing to a valid element in U.
And if the front is pointing to a valid element in V, then that means both U and V are non-
empty.

In this case what should we do? We should check which one is smaller. If the U side has the
smaller element than the V side what should we do? Well we should move the U side element
to the back of S. And we should advance the pointer the front of uf. You should advance the
back of uf as well but that will get advanced at the end of the loop anyway because of the
statement over here. So we are not going to do that explicitly here. If, on the other hand, this
V had the smaller element, then we should do the same thing but with V rather than with U.

788
So the front element of V is going to move to the back of S and the front for V is going to
advance. So if one of those U and V is empty so let us say U is not empty. So uf is smaller
than U, so that means V is now empty. So in that case, we do not have to do any comparisons
we just move whatever is at front of U to the back and then we just advance the front for U.
Otherwise, it means that only V is non-empty, so then we are going to do the same thing
whatever is at front of V is going to be moved to the back of S. And we are going to advance
the front of V, so that is it I should have yeah so this brace closes this brace and this brace is
closing this brace over here.

I do not want to put it later on because I just want to keep it otherwise the font becomes too
small. But anyway this is this is the code for merging these two sequences. Now you can
check okay so yeah so we already discussed what exactly happens. And so now we are we
can analyze the time it takes okay. So how much time does this take? Well it has this main
loop so this is the main loop and how many iterations is the main loop going to run? It is
going to run Lu plus Lv iterations and therefore its time is going to be proportional to Lu pus
Lv since in each iteration we are going to do some fixed amount of work, the work may be
different, depending upon whether both queues are non empty or only one is non-empty. But
it is going to be some fixed amount of work.

(Refer Slide Time: 10:09)

So if we are merging two sequences of length Lu, Lv the loop runs for Lu+Lv iterations. We
do a fixed amount of work in each iteration and so the time is proportional to Lu+Lv. So I
could say that the time I can say that the time is proportional to n if Lu+Lv is equal to n or if

789
the final sequence has length n then the time is proportional to Lu+Lv. So now we have
decided what the time taken for merging is.

(Refer Slide Time: 10:46)

So what have we discussed in this segment? We discussed how to merge sorted sequences
and we have discussed that the time taken to merge two sequences of total length is
proportional to n. In the next segment we are going to put together everything and we are
going to do the analysis of the entire merge sort. And we will also have a demo of the merge
sort and then we will also conclude for this entire lecture sequence, so we will take a quick
break.

790
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer and Engineering,
Indian Institute of Technology, Bombay
Lecture Number 18 Part-5
Array and recursion
Mergesort conclusion
(Refer Slide Time: 00:20)

Welcome back, in the last segment we discussed the merge function, and earlier we had
discussed the merge sort function, and now we are going to put together everything and analyze
the entire merge sort algorithm. And then we will also do a demo, and this will conclude this
entire lecture sequence so we will have some remarks at the end.

791
(Refer Slide Time: 00:51)

So, this was our merge sort function. I have just copied it over here for reference, so we are
going to analyze the time it takes, so we need some notation, so let us see that T(i) is the
maximum time required for merge sort to sort any sequence of length i. So, the time required
might be different for different sequences but I am just saying what is the maximum possible
time to sort any sequence of length i, so that is that let me call that T(i). So this is an unknown
and we are going to put down some conditions on this unknown and then we will be able to
estimate this unknown.

In fact this is not just a single unknown. I am defining several unknowns at the same time, so I
am defining several unknowns for an unknown for every value of i over here. So we can say
something about T1. What is T1? The time required for merge sort to sort a sequence of length 1.
Well that is very easy so if you execute this at this point itself we are going to return, so we will
take some time, but it will be some fixed amount of time.

So let us say it will take some time C. So, I could write T1=C over here also, but I am just yeah
so since everything else is going to be less than I will write this also as less than or equal to.

So, now I claim that T(n) has to satisfy this inequality. So let us see why? So this green part, so
T(n) is the time required for executing this entire function for this value of n. So this green part I

792
claim comes from this part, so we are giving mergesort a sequence of length n. So what do we do
with it? So we copy parts of it into U and parts of it into V the total number of elements that we
are copying is n.

So how much time does this copying take? Well it takes time proportional to n and therefore we
can write this as d times n, then we are going to do a merge sort on n/2, a sequence of length n/2.
So that I can estimate by 1 of these Tn by 2 and this is really a merge sort of n-n/2, but let us say
n is even for simplicity, and then therefore this also takes time n/2 at most and so this time must
be 2 times T(n/2).

So for this red part and then finally, we are going to do a merge of these 2 small's sorted
sequences. How much time does that take? So in the previous segment we said that the merge
itself takes time proportional to n, the proportional to the final sequence that results from
merging these two sequences and that we know is n. Yeah, actually I do not need this argument
over here so we can drop this argument we do not need it over here. But, yeah so what I have
said over here is that the green part is creating U, V sort halves and the merge. So I can write I
can simplify this and I can write f for d+e and so I can say that T(n) is fn plus 2 times T(n/2).

As, I as I said earlier we have several such variables T1, T2 T at T3 and similarly over here. So I
am really writing not just one inequality, but I am writing lots of inequalities at once. So every n
will satisfy something like this, all right but what does that mean? This means that this inequality
also applies to T(n/2) and let us say n by 2 is an integer so it applies to T(n/2) also, so what is this
inequality for T(n/2), well so just substitute n/2 over here, so fn will get n/2 over here and if I
substitute n by 2 I get 2 times T(n/4), but now I can substitute this into this.

So, what do I get? So I will get fn plus this fn by 2, 2 this times 2, so this is the 2 that comes
from here. So what is this? So I get an fn over here, then there is this 2 and this 2 cancel. So I
will get an extra fn so that is what comes over here and then this 2 and this 2 will give me a
4T(n/4).

Now, I am going to assume that this n is a power of 2. So I can sort of keep on substituting into
this. So I will ask you to work it out but if you keep on substituting into this what we are going to
get is that T(n) if I do this k times I will get a k over here and as you can see the power over here
is doubling and it is the same in the denominator over here, so I will get something like 2 raise to

793
k times T sub n over 2 to the k so this is a little hard to read, but this is n divided by 2 raise to k
over here. This 2 raised to k is in this fraction over here.

Now, I cannot do this ad infinitum of course. It have to stop then this number this number over
here, say becomes 1 and I said n is a power of 2. So when will this number become 1? Well if n
is 2 to the k, so if I choose k to be such that n is 2 to the k or in other words, if I choose k to be
log2n then this will stop, but at that time what will it be. So at that time it will be k will be log n
so this will become fn times log n and this will be n times T1.

But n times T1 is c. So this whole thing is less than fn log n plus c plus nc, but this n log n term
is going to dominate and therefore I can write t of n has to be smaller than some constant times n
log n. So which is exactly the result that we wanted, so this says that the time taken for sorting is
some constant times n log n rather than some constant times n2, and n log n is really much
smaller than n2, and that explains why or that suggests that merge sort should be much faster.

And I have made an assumption over here that n is a power of 2, but that is only a technical
assumption, I mean just to simplify the algebra over here. If it is not a power of 2 all of these
things actually work out but then algebra gets messier and so let us not worry about it. The main
ideas are already here.

794
(Refer Slide Time: 08:35)

So we are now going to do a demo our program is mergesort. So it is really the same code, but I
want to print our our array at different point, so I have written a function print over here, and that
gets code, so again in the merge I am printing what array gets passed at the beginning and also
the result that is produced at the end.

(Refer Slide Time: 09:04)

795
And mergesort also I am printing a message saying and sorting this array over here, and at the
end I am printing a message saying sorted. And this is the array to be sorted this is mergesort and
that is the main program. So let us compile this and run it, and let us run it.

(Refer Slide Time: 09:23)

796
So there is a certain amount of output over here, let us start at the beginning and let us see what it
is doing. So the first call to mergesort was this these this in the array. Now, if you remember
what this was doing, it was splitting the problem into two parts and it was recursing. So indeed
that is what is happening over here. This is the first half on which it was splitting, and it is
recursing on it but what happens next? It splits on this and it recurses is on this, but if you
recurse on 50 there is nothing to be done and so, this comes back to these returns immediately.

Next, the recursion and this is taken up. So that causes the smaller problems of size 1 to be
created so that those also get returned immediately, so now we have two sorted sequences which

797
were created and they are so we have a call here on the merge function. So, the result of merging
these two things is 29 87.

So this was returned to this sorting call, so there was a mergesort call with this as arguments that
led to this all of this this merge business, and therefore the result of this sorting call is all of this.
So you can keep going in this manner you can look through this just to see, just to understand
how this sorting is happening or better still you really should draw out that recursion tree to see,
to understand how the sorting actually happens.

Or you can just say that look I do not need to know these details, I need to know and the way I
think about recursion is I just look at the top level there the top level call and the recursive calls
and I assume that, the recursive calls happen correctly if in that case can I be sure that the top
level calls also happen correctly, so that is also fine, but if you need to know if you want to know
what the details are you can certainly run this program maybe add even more print statements to
it, so that you can see what is going on.

(Refer Slide Time: 11:54)

Alright so, that really concludes this lecture. And what did we do in this lecture? So we studied
binary search, and we wrote the code for it, and we also observed, and we also analyzed as to
why it is going to be faster than linear search.

798
And similarly we wrote the code for merge sort, and we analyzed that it has to be much faster
than the selection sort code that we wrote earlier in the course. Both of these algorithms have a
similar idea. Which is that we take our original problem, the problem that is given to us and we
divide it into two parts, and in the case of binary search we only work on one of those parts, we
somehow know and that is, what the sorting gives us that we do not need to work on one part at
all.

In the case of mergesort we have to work on both parts, but in any case we are looking at a big
problem as being decomposed into smaller problems. And this idea of viewing and solving
problems in this manner is often called divide and conquer, so what you have seen are examples
of divide and conquer.

And, recursion works nicely to divide and conquer but recursion can also work quite nicely in
other cases. So in any case we now have seen two examples of recursions with arrays and you
can certainly note that both of these are very nice applications, and very nice algorithms, and
very useful algorithms. So we will stop over here but I will, as always urge you to look at the
problems on at the end of this chapter. Thank you.

799
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 19 Part – 1
Structures
Definition and instantiation

Hello and welcome to the NPTEL course on an introduction to programming through C++. I am
Abhiram Ranade and in today’s lecture sequence I am going to be talking about structures. So,
let us take a look at where we are in the course.

(Refer Slide Time: 0:32)

So, you have really learned enough to write essentially any program, so you have learned basic
control statements, you have learned functions, you have learned arrays and in this lecture, we
are going to learn language features that will make writing programs more convenient, safer and
modular. These terms may not mean anything to you right now, but they will become clearer as
we proceed.

800
(Refer Slide Time: 1:04)

So, let me begin with a difficulty. So, if you are writing a large program then it will have lots of
variables. And just managing all the variables is often a bit tiring. It is like you have lots of
papers strewn over the table and you do not know how many papers you have, which is what you
called, which variable, all such things. And on a table we can bring some neatness by putting
related papers into files.

So, that way we have groups and we know what we can, we can sort of roughly know what is in
which group and that helps us figure out what all we have. So, an interesting question is could
we do something like that with variables? And that, in fact, is the solution that structures gives us
and that is the main topic of this lecture.

801
(Refer Slide Time: 2:06)

So, here are the high level ideas. Most entities we deal with in programming have lots of
attributes. If our program is about simulating movement of stars, then each star has a position,
velocity, mass. If our program is about managing books in a library, then each book has an
author, library number, who has burrowed it, of course, the title, and the key idea in structures is
to collect together all information about an entity into a group or you might even think of it as a
super variable and this super variable is called a structure.

(Refer Slide Time: 2:56)

802
So, here is the outline for this lecture. So, we are going to start by talking about structures. So,
we will talk about the basic facilities that C++ provides to define structures, and by the way the
structures are inherited from the C language. We will also talk about operations that can be
performed on structures, and also lots of examples.

(Refer Slide Time: 3:30)

So, a very high level overview, a structure is nothing but a collection of variables and the term
member is also used. The members of a structure are the variables in the collection. So, a
structure can be thought of as a super variable and it denotes all the memory used for all the
members. Each structure has a name. The name refers to the super variable or in other words the
name refers to the region of memory in which all the members are present. So, it refers to an
entire collection. Each structure also has a type and that type defines what variables there will be
in the collection.

803
(Refer Slide Time: 4:14)

So, let us talk about structure types first. You can define a structure type for each type of entity
that you want to represent on the computer. And these types are what might be called
programmer defined types. For example, to represent books, you can define a Book structure
type. When you define a structure type, you must say what variables each structure of that type
will contain. So, continuing the example, if you define a structure or structure type to represent
books, you may wish to have variables to store the name of the book, its price and other
attributes.

(Refer Slide Time: 4:58)

804
So, here is how you define a structure type. The general form is the keyword struct followed by
the name of the structure type that you are trying, that you are defining. Then there is the, it
consists of several variables or members. So, for each member you first have to specify the type,
the type of that member and then you have to give it a name and that is it. So, it ends with a
brace and usually braces do not have semicolons as we have seen them so far, but here there is a
semicolon, and here is an example of a specific structure type that we might define consistent
with this general form.

So, here is a type for storing data about books. So, we are going to call that structure type Book
capital B and then it will have members, 1 member is a title which is a character array. So,
members can be arrays or members can be just plain variables, and then there is another member
which is price and it is of type double. You could have more, but let us say we just have these 2.
So, as I said earlier a, a structure type is user defined data type and it is really similar to int, char,
double which are the primitive data types and the structure type and member names can be any
identifiers.

(Refer Slide Time: 6:38)

So, how do you create a structure of a type that you have defined earlier? So, we just defined a
structure type book. So, if you want to create a structure of that type, we just simply write Book
p, q. So, this creates two structures p, q of type Book. Each created structure has all members
defined in the structure type definition. So, at this point we have actually allocated memory.

805
When we defined a structure type we did not allocate memory, we just said that look here is sort
of a format using which you can create structures and structures actually cause variables to be
created and memory to be allocated.

Now, member x of structure y can be accessed by writing ‘y.x’. So, since we have a structure p
and on the last slide we said that structure type book has members title and price. We can get to
the price member of p by writing p.price and this statement is storing 399 into that member.
Now, we can print it if you wish.

So, if you write cout<<p.title or cout<<p.price, whatever the contents of these members or these
member variables are, will be printed. So, c a so p dot title is presumably the name of the book
represented by the structure p and so that will get printed. Of course, we will have to assign it
first and so once it is assigned we can print it out in this manner.

(Refer Slide Time: 8:29)

Alright, so what have you discussed? We have discussed how to create structure types and then
we discussed creating variables and instances of an already created structure type. Next, we are
going to discuss operations on structures, but let us take a quick break.

806
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 19 Part 2 – Structures (Operations on Structures)

(Refer Slide Time: 0:19)

Welcome back, in the previous segment we discussed how to create structure types and also
create variables or structures or instances of an already created structure type. In this segment
we are going to see what kinds of operations we can perform on structures. So the first
operation, the first thing we can do with structures is to initialize them during creation itself.

(Refer Slide Time: 0:50)

So let me just remind you this is our structure type Book, it contains numbers, title and price
and I can create an instance or I can create a structure of this type and I can initialize it. So
the initialization as usual happens through braces and the first element in the braces initializes

807
the first member which is title and so b.title would be set to the string “On Education”. Then
the second member in the braces initializes the second element in the braces I should perhaps
say, initializes the second member of the structure type book which is price. So this initializes
b.price to 399.

So again let me remind you that “On Education” is a character string and it is stored with a
terminating null as usual. And you might have lots of members in a particular structure type,
so you have to give as many as many values in braces and having the appropriate type. You
can make structures unmodifiable by adding the keyword const. So for example you may
define a structure variable c with title member being “The Outsider” and the price being 250
but here you are saying that c cannot be modified. Either of the two members of c cannot be
changed as your program executes.

(Refer Slide Time: 2:37)

Now one structure can contain another. So for example we might have a structure Point
which contains say the coordinates of the point and now if I want to define the structure disk
it would be natural to have the center being defined as a point. So the first member here is a
point which is a type, so all that we really need is a proper type and so point center is
perfectly fine. And then the second member is of type double and we are going to call it
radius.

So we can create a structure d or an instance of type Disk by writing Disk d. So I can write
d.radius because after all radius is a member of d and I can say d.radius to be 10. But d has a
member center which in turn has a member x, so I can write d.center.x equals 15. Okay and

808
of course I can write d.center.y as well to whatever y coordinate I think the center ought to
have. I can assign one structure to another, okay.

(Refer Slide Time: 3:55)

So basically all members of the right hand side get copied into the corresponding members of
the left hand side, so the name of the structure stands for the entire collection unlike array
names.

So array names stand for the address where the array has been allocated memory, structure
are not like that, the structure name stands for the entire collection. And as I said earlier, a
structure is a variable or you might actually think of it as a super variable because it contains
you can also think of the members being the variables which are contained in this bigger
variable. So as an example we have a book b with title “On Education” and price 399 and say
we have a book c, so now we can write c=b. This will copy both the members and so if I print
c.price the price member of c which is which has been copied over from b is 399 and so 399
will get printed.

809
(Refer Slide Time: 5:17)

Structures can be used with functions and they can be passed to functions by value. So when
you pass it by value it sort of like assignment, all the members are copied to the parameter uh
parameter structure and of course the usual thing is that the types must match. So, even in an
assignment and even in passing the types must match. Structures can also be passed by
reference and this means exactly the same thing as in case of variables. So in the calling, in
the called program, the parameter name refers to the same variable which was passed from
the calling program, the calling function. And you can return structures as well, so what does
that mean? So all the data members of the structure that you want to return are copied back to
a temporary structure in the call, in the calling program, and then you can do whatever you
want with that temporary structure. Basically this temporary structure is going to be in place
of the call, so call should be thought of as returning the result and that is where the temporary
structure is going to be.

810
(Refer Slide Time: 6:41)

So we will see examples, so first an example of passing by value. So here is a structure Point
the one we saw earlier, it has members x and y both double. Now here is a function called the
midpoint, it takes as arguments a and b which are both points.

And it thus it creates a new point mp and returns that, so we will see exactly what happens
and then there is a main program and the main (main) program is going to call this function
midpoint. So the first call the red call okay, suppose we start executing main and come to the
red call, so what happens? So the arguments p and q are copied to the parameters a and b. So
this is the call and these arguments p, q are copied to these parameters a and b and now the
code of midpoint starts executing.

So the first step is that a local structure mp of type Point is created and this is created in the
activation frame of this function midpoint. Its x and y variables are set suitably and if they are
set to the mean of the x and y variables of x and y coordinates of points a and b and then this
mp is returned. So this happens as follows: so a temporary structure of type point is created
and that structure sort of stands in for this call, okay? And the elements of or the members of
mp are copied into that temporary structure, so you can think of this entire structure is copied
into that entire structure, okay?

And subsequently what will happen? Main program will start executing again and this will be
assigned to r. So mp is copied into the temporary structure and the temporary structure is
copied into the structure r and then in this we can print r.x, that is perfectly acceptable and
here is another call, okay, so here we are calling midpoint but we are directly taking its x

811
coordinate. We are not putting it into any local variable and taking, taking the coordinate,
taking the member, we can do this, we can just we can just put .x and this will (this will) just
mean whatever this call returns take its x member, okay?

(Refer Slide Time: 9:54)

We can pass by reference as well and in this case the code is really the same except that we
have these two &s which indicate that is the a and b are passed by reference, okay? So in the
execution of midpoint(p, q) the parameters a, b will refer to variables p and q okay, nothing
will be copied over. Now there is no coping of p, q and this will save execution time if the
structures being passed are large and indeed if you are passing large structures it is good idea
to pass them by reference. The rest of the execution is as before. And normally if I have a
reference parameter as I have that because I want to modify it and therefore it is expected that
reference parameters should be variables.

So these so whatever is being called over here should be variables because only then can I
modify them, modify these reference parameters in the code. However this const says that
this code promises not to modify these things, these parameters.

And therefore with this const. you can pass constant points as arguments to midpoint as well.
So constant structures can be passed as arguments. So in fact, I can write midpoint of the
midpoint of p and q and q. So this will sort of get me a point which is a quarter of the
distance away towards q between p and q, okay. So I can do that as well, I can nest these calls
also.

812
(Refer Slide Time: 11:55)

Next I can have arrays of structures if I wish, so for example I can write Disk d and this just
defines variables d[0] to d[9] each of which is a disk. Similarly I can have a variable lib
maybe short for library which is an array of 100 books, so again this defines variables lib[0]
through lib[99] each of which is a structure of type Book, okay?

So now these (these) variables are just like ordinary disk variables and so I can take the
center x and all the usual stuff. And this also is sort of usual variable, so I can take its
member but the member happens to be an array, so I can write I can index into it and so this
is going to print the third character of the fifth book in the array library or I guess I should
have called it lib because this is how we created it. So it is not really, read this as lib in both
the cases.

813
(Refer Slide Time: 13:01)

Alright, so what have we discussed? We have discussed number of operations on structures,


initialization, nesting and by that I mean have a member b another structure and we have
discussed passing and returning structures from functions, we have also discussed creating
arrays for functions. In the next segment we will have a detailed example involving structures
but let us take a quick break.

814
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 19 Part 3
Structures
An example program

Welcome back. In the previous segment we discussed various operations on structures.

(Refer Slide Time: 0:18)

Now, we are going to put together all these things into a somewhat longish example.

815
(Refer Slide Time: 0:29)

So, here is the problem that we are going to solve. So, given n discs in the plane determine if
they intersect? You may remember that we have written code for this earlier. Now, with structs,
we are going to write the same code or code for the same job, but you will see that in some way
that a code will be nicer. So, let us start with the basic struct that we need. So this is a struct disk
and instead of having point, I could have had points as well, I could have just put in center x
center y and radius as its 3 members.

816
(Refer Slide Time: 1:10)

So, let me get to the main program. So, we are going to have five discs just for simplicity and so
I have put in constant int n to denote the number of discs. And now I am just going to create just
a number of array of disks. And so by the way note that in earlier case what we had to do in the
main program was to create not just a single array but an array to store the coordinate another
array to store the Y coordinate and another array to store the radius.

So, that makes the program verbose and furthermore, it does not really tell you that something is
being done about discs, unless you write a comment, but here very compactly you understand
that, yes, that we are doing something about discs. The first operation that we are going to
perform is to read data. You will note that in the program that we wrote earlier, we put the code
for reading right here, but now the code is elsewhere.

But here in the main program itself, if you know what that code is supposed to be doing is
reading data and reading and in particular this looks like we are reading the various attributes of
the discs. So, again this makes for better readability. Then we have another function which says
check all pairs. So, you can tell easily that look we are going to do something with all pairs and
the result is going to be printed.

817
So that is it. Main program is quite short and sweet and it has steps which have been given names
and these steps are functions and we are passing data to the functions but the data is not, it does
not look like a lot of data. I mean, there are not many names, there are not many parameters,
arguments that we are passing. We are just clearly passing the main argument which is the disc
the number of elements in it.

So there is a certain kind of compactness or neatness to this entire program. So, without structs,
so you would have to you have lots of arrays being passed. So, that would just look a bit more
cluttered. And in some sense, in this program, we are encouraging, thinking at a high level. So,
here when we write read data we are saying, “Oh, somehow it will be read.”

I do not want to think about how exactly that is going to happen, but I know that it is going to
happen and similarly, check all pairs. How is it going to happen? It is given somewhere else but
this is what I really want to happen. So, this sort of tells you what is going at a higher level and
does not force you to read all the details and then figure out. So, let us go to this function. First of
all, reading the data.

(Refer Slide Time: 4:25)

Reading the data is fairly natural. You go over all the elements in the array and read data into it.

818
(Refer Slide Time: 4:30)

Then we are going to check intersections. So, check all pairs or maybe I could have called it
check all intersections that might have been even nicer name. Anyway, so there are n discs which
are passed as arguments and we go over all pairs and we discussed this last time, when we solved
this problem earlier. That we have to have 2 indices, i and j, and i should go from 0 to n-2 really,
and therefore, we have written i less than n-1. And j should go from i+1 to n-1, and for each such
pair we need to check whether those pairs intersect? If they interest we return true. If the loops
execute without finding an intersection, then the controls will reach this point over here and at
that point we know that no intersection was found and so we came in return false. Now, this
function contains really just one kind of an idea. So, it says, “Look, I want to check intersection
between every pair.” So, check between every pair is what is happening over here. How exactly
the checking for a single pair happens that is described in intersect function.

So, this comes over here and notice that the intersect function only talks about 2 discs. It does not
have to know about the entire array. So, the point is that when we write each function, our
viewpoint is somehow limited, and that helps us think about our job, think about whatever code
is doing a little bit better. So, here our rule was that we are going to look at the distance between
the centers, and so this this whole thing is the square of the distance between the two centers.

819
And this should be smaller than the square of the sum of the radii. So, that is what this check that
is the check that is happening over here and the result is being returned.

(Refer Slide Time: 7:05)

So, let us do a quick demo of this.

(Refer Slide Time: 7:12)

So, here is my here is my program: the disk structure type, the intersect function, check all pairs
function, read data. Now, I have also added over here a show discs functions. So, at the end it is

820
going to show us the disc on our cameras. So, this place we will know whether our intersection
answers is correct or not.

(Refer Slide Time: 7:36)

Following this we have the main program. So, really what we had on the slide plus this
additional show function, so in the main program as well we are going to print the answer
whether there is an intersection or not and then we are going to show whether the disc are
intersecting or not. Let me just shift a little bit so that you can see this character.

821
(Refer Slide Time: 8:02)

822
So let us compile this and we're going to run it and we're going to run it by redirecting the file.
So, .dat1 is one file. So, the answer is 1 and here is the plot. So, here are the circles so clearly
there is intersection and therefore the answer was 1.

823
(Refer Slide Time: 8:46)

So, let me do one more. So we do it for 2 and this time there is no intersection and in fact the
answer is 0.

824
(Refer Slide Time: 8:58)

So what have we discussed in this segment? So we discussed a detailed example and here are
some important points that you should observe. So, by using structures, our functions could be
written with fewer arguments and this makes for better readability, less clutter and, of course,
less possibility of errors as well. We will not forget giving a function or we will not exchange
two arguments. So, such errors are sort of very-very easily prevented.

Our overall program can be now more easily written as a bunch of small functions. If we had lots
of arguments to be supplied, we sort have said, “Oh my God, I am tired of suppling all these
arguments”, and so you might have tried not to write small functions. But writing small functions
is a good idea because in a small function you can just one idea, and therefore, you can
understand that function and make sure that it is correct a lot more easily.

Then we also said that because we break things up into functions, each function has its own
limited use. So, for example, the main program has a very high-level view, the other functions
may have views at their own levels. So, in the next segment we are going to talk about pointers
with structures and we will also conclude this entire lecture series.

825
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of computer science and Engineering,
Indian Information Technology Bombay
Lecture 19 Part 4
Structures
Pointers and lecture conclusion

Welcome back.

(Refer Slide Time: 0:29)

In the last segment we did a somewhat detailed example of how structures could be used and
how they might presumably increase the readability of the overall programs. Now, in this
segment we are going to talk about how pointers can be used in conjunction with structures and
we will also have a conclusion for this entire lecture sequence. So, we have seen pointers earlier
and pointers to structures are created in a natural manner.

826
(Refer Slide Time: 0:59)

So, we have in this statement we are defining a disc. So, this is a disc, a variable of type disc and
we are also defining a pointer to a structure or variable of type disc. So, this pointer is dptr. And I
will just remind you what this is. So, this is a disc. So, I guess we have had two kinds of disc.
Now, but this is a disc in which we have the first member was a point and here we are saying that
the x coordinate is 2, the y coordinate of that center is 3 and then the radius is 4.

Now, we can do the normal pointer operations on structure pointers as well. So, for example, I
can write dptr equal to the address of this disc type variable d1. So, that is what you normally do
and then I can take, I can dereference this dptr as well. So, if I get dereferenced dptr, what do I
get? I get d1 itself. But then I can take its radius member and I can say, “Look I want the radius
to be 5 rather than the 4 that it currently is.”

So, that is what this statement is going to do. Now, this idiom, *x. comes up quite frequently, and
therefore, C++ gives a different way of writing it. So, here is another operator, the arrow
operator, which is made up of the characters minus and greater than, you should read it as arrow.
So, *x.y can be written as x->y. So, in x->y, this x should be a pointer and y should be a
member.

827
So, I could have written this statement as this. So, I could have written dptr->radius equals 5, not
dptr.radius. If I want to write dptr.radius, then dptr had better be a disc type variable. But dptr is
not a disc type variable. It is a pointer double disc type variable, and therefore, I should use this
arrow which dereferences first as well.

(Refer Slide Time: 3:46)

Now, pointers can be structured members as well. So, I can have struct disc2 which has double
radius and which has point, but this time my member is not a point, but a point* or it is a pointer
to a point. So, f.centerptr equals to address of P. So, this is a pointer and into it I am storing the
address of this point. Now, I can, I want to print the x coordinate of the center of this disc d. So
how do I get that?

So, I get to d.centerptr which gives me a pointer to the point which is the center and since, this is
a pointer, and I want the x variable, or the x member of it I write arrow x. Then I can have disc2
f. So, F is another disc 2 and maybe I can set it center ptr also to the same point. So, essentially,
these, I am making these to be concentric disc, but there is a subtle point over here. If I change
the center of this then the center of this also changes. So, you should do this only if you intend
that. And yes, this might be a possible motivation for using pointers, so that we can have discs
that are sharing their centers. And we can do similar things. We can set f.centerptr->x equals 15,
that where set the coordinate for the disc d as well. This will also print out 15.

828
(Refer Slide Time: 6:09)

Now, with pointers especially in this current context, we might want to say that a particular
pointer is not pointing to anything at all. For that there is a keyword ‘NULL’ which is reserved.
So, it can be assigned to any pointer to indicate the pointer does not contain does not point to
anything meaningful. We have remarked long ago that a pointer to discs cannot be assigned to a
pointer to points, but null is kind of universal pointer. So you can assign, you can store null into
any kind of pointer. Essentially, you can, say that this particular pointer does not point to
anything at all and you can check whether the pointer points to thing by writing ptr==NULL.

829
(Refer Slide Time: 6:46)

Here is an example where we have pointers to the structure of the same type. So we have a struct
employee but inside it is an employee pointer. So, boss is a pointer to another employee. This is
allowed. This looks like it is referring to itself. In some sense it is, but what the purpose of
writing this at least in this limited context is we need to know how much how much space to
reserve for this point ptr or this member boss.

But all ptrs essentially have the same amount of space and therefore, this is okay. This, of course,
says that subsequently if you use boss it is expected to point variable of type employee. Here is
how you might create employees. So, this is says e1 is president, so the title is President and
there is no boss. So, presumably we might be writing this for somebody who was the head of the
institution. So that person does not have a boss. So its boss is pointing to the null.

There might be an MD in that institution, a Managing Director and the managing director's boss
is the president. So, here we can supply the address of the president and so address of e1 is
supplied over here. Similarly, e3, maybe the executive director, has as boss the president, so here
we are supplying the address of that president. Now, we can do this. So, we can say e2.boss, so
we get to this address of e1 over here and if you want to print out the title of the person.

830
So, to get to the title, the title is a member of e1, but we have an address of e1, and therefore, we
should put an arrow here. So, this will print president. Now, if we write e3.boss we will get to e1.
We will get a pointer to e1. If we take its boss member, an arrow to boss, then we will get null.
So, if we then print it out, then take the title, then we are making a mistake because null is not
pointing to anything, so we cannot take a title of it, and therefore, this is going to cause an error.
So at execution time, the program will say that there is something wrong.

(Refer Slide Time: 9:47)

So what did we discuss in this lecture? So we talked about structures and we said that structures
enable us to group together variables of different types. Now, I should note that arrays also group
together variables, but in arrays the variables are of the same type, whereas in structures they can
be of different types. They may be of the same type but they can be of as many different types as
you want.

Structure name behaves like a variable. So, the structured name does not denote the address of
that structure, but it denotes the content of the structure. So, if you pass it or if you copy it the
content gets copied. Again this is something different from the way array names behave. And
then, why we got onto this, we did all this because by grouping things together, we can reduce
the clutter in our argument lists and we can organize our data better.

831
And because our clutter is reduced we are more inclined possibly to write smaller functions and
these functions can be written as different level. So, as we saw in the example, the main function
was written at a very high level. So, whereas the called functions, the other function sort of dealt
with the internals of the disc, whereas the main function just said, “Oh, here are do these things
with a disc without really worrying about what is going on inside.”

So, let me conclude this lecture then by saying that, structures are a way by which you can
improve the readability of your program, because they help you to group all the attributes
associated with an entity into a single structure or a single super variable. And as always I will
suggest that, please, look at look at the problems at the end of this chapter. Of course, the next
chapter, the next lecture will also continue with chapter 17. So, maybe you can wait until the
next lecture to look at the problems at the end of chapter 17. Thank you.

832
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 20
Part-1 Introduction to Member Functions
Hello and welcome to the NPTEL course on an introduction to programming through C++ I
am Abhiram Ranade and in this lecture I will continue to talk about structures. So, some
reflections on what we have seen so far.

(Refer Slide Time 00:36)

So, we proposed that all attributes of each entity in our program should be grouped into a
structure and we said that the benefits for this are that it would reduce the clutter overall it
will make it easy to pass the entity to a function, we can pass it as a single argument rather
than all the different variables which are associated and because we have fewer arguments,
we will be more likely to write lots of functions, and also each function will have its concern
very limited. And therefore understanding what is going on in the function and reasoning
about it in general will be easier to do.

833
(Refer Slide Time: 01:24)

Now here is an observation about how such entities are processed. So typically, there may be
many attributes that an entity might have but they are accessed in only a few different ways.
So I am going to take two examples, one is a vector from physics and another is the queue
that we had in taxi dispatch problem that we saw earlier.

So in both these cases the vector and the queue will have many attributes or many members,
but you will note that usually we do to read or update the individual members in isolation. A
natural operation requires us to simultaneously access or update several attributes, and in a
very specific manner. So what does it mean? So it means really, that we should support this
kind of access and update rather than the update involving individual members.

(Refer Slide Time: 02:56)

834
So let me show these actually these examples little in more detail. So, vector from physics so
in physics vectors are used to represent lots of things velocities, positions, displacements,
electric fields and say if it is a vector in three dimensions, then it can be indicated by its
components in the x,y,z directions. So maybe we might have a vector type V3 and it contains
members x, y, and z.

There could be other representation as well, I mean there could be the polar representation for
example or the cylindrical coordinate representation. So, here is a key observation so for this
representation you will rarely read just the x component or rarely update just the y
component. What you typically do is, will involve something with will involve all three
coordinates so maybe we will add two vectors together or maybe we will scale up a vector.

So both these operations will involve changing all the coordinates and the change will happen
in the very specific manner.

(Refer Slide Time: 04:05)

The taxi dispatch problem we saw earlier, and it is discussed in chapter 14 of the book. So
briefly we have customers arriving and have to be assigned to waiting taxis, and important
part of that solution was a queue, and into this queue we put IDs of the waiting taxies or
rather the IDs of the waiting drivers and the main part of the queue was an array and these
elements where the one in which we store the IDs, and then there was a variable nwaiting
indicating how many drivers were waiting and variable front which indicated the position of
the first waiting driver.

835
And again, we can make the observation that the queue was accessed using operations insert
remove and initially we had to set nwaiting=front=0. We did not arbitrarily examine the
elements of the array or change n waiting or front in isolation. So whenever we make the
change there was some high level operations that we had in mind and over code was
implementing that high level operation.

(Refer Slide Time: 05:38)

So the insight from all of this is that first of all we should put the all the attributes of an entity
into a structure but in addition, we should provide functions with which to access the
attributes. And these member functions these functions are customarily member functions or
the functionality that we want for accessing is provided by something called member
functions and these member functions are the main topic of this lecture.

So to put it differently we should avoid accessing attributes directly, why is that, well very
likely this indicates that we are doing an operation that is not been clearly thought through
and therefore may be it contains errors. So, clearly something real or even abstract, but sort of
something that we clearly know, something that we clearly understand like a queue or a
vector has its own logic and that logic has to be incorporated into functions and we are going
to describe this notion of member functions which is going to be most useful for
incorporating such logic. So we think about and catalogue the right ways of accessing an
entity.

836
(Refer Slide Time: 07:09)

So here is the outline of this lecture, we are going to have a bit more discussion on the vectors
from physics then we will introduce this notion of member functions and I should mention
here that member functions were not present in C, were an extension to what we inherited
from C and the extension is first proposed and implemented in C++. So, this is kind of a more
modern feature if you will. After discussing member functions, we will talk about taxi
dispatch and see how that as well can be written using member functions. Alright, so what
did we discussed in this part of the lecture.

(Refer Slide Time: 08:08)

So we said that it is not enough to just define a struct to hold entities. Usually we will also
want functions which work on the structs in C++ we can make the functions a part of the

837
struct definition itself and such functions are called member functions. In some ways,
member functions are similar to control panels found on the front of appliances. So, you are
expected to operate an appliance through the buttons or other controls that have been
specifically provided. You are not expected to innovate or you are not expected to do tricky
things when you operate an appliance say for example you are not expected to open the back
and change some capacitors or change some wirings.

So if you want to change the channel on a television there is a very very clear way to do that
and analogously, the thought is that member functions indicate to you what is sort of the clear
proper way of doing things and in some sense you do not want users to go looking into the
data members themselves and changing the data members because they might be making
mistakes in doing that. So next, we are going to develop this idea and for that we are going to
look at the vectors from physics but, let us take a quick break.

838
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 20 Part 2
Structures Part 2
Vectors from Physics

Welcome back.

(Refer Slide Time: 0:34)

In the previous segment, we motivated the need for member functions. In this segment, we are
going to talk about vectors from physics and then later on, see how they how they can be
implemented using member functions and the operations on the vectors using member functions.
So, we have already talked about this.

839
(Refer Slide Time: 0:44)

So, say you are writing a program involving velocities and accelerations of particles, which
move in 3 dimensional space. Then you would find it natural to represent the vectors using a
structure with members x, y, z. So, V3 is the structure type so for 3 dimensional vectors, and its
members are x, y and z, which are all doubles. And, of course, other representations are also
possible.

(Refer Slide Time: 1:21)

840
So, how do you use this struct V3? Well, there could be several operations that you might want
perform. So, for example, you might take 2 vectors and add them up together. So, a function, an
ordinary function which does this, would look something like this. So, you have this function
name. And this function is going to return an object of type V3 or structure of type V3 and it is
going to take arguments which are also of type V3 and we are taking arguments by reference.

So, first it is going to create internally, a V3 object called v and this is going to be our result. So,
what is the result going to look like, well its x component is going to be the sum of the x
components of these two objects similarly, the y, similarly the z. Then you could have a scaling
operation which takes vector and a scale factor, and simply multiplies the scale factor that each
of the members and so the resulting vector is going to be returned.

As you remember, this operation is going to return this vector that means the values will get
copied in some suitable place in that calling program. Here is another possible operation that you
may want with vectors which is a length operation. So, the length operation simply takes a single
vector and it returns the square root of the sum of the individual members. So these might be
some operations that you might want to perform on your structure type on objects of your
structure type V3.

(Refer Slide Time: 3:29)

841
Well here is an example of use of vectors in which these operations can come in quite handy.
And this is so called motion under uniform acceleration. So, we have a particle which has initial
velocity u and uniform acceleration a. Then its displacement at time t, ‘s’ is given as u times t
plus at square by 2 and this is applicable even if u, a and s are vectors and t is a scaler, if it is a
time. To find the total distance covered or the total displacement rather we must take the length
of the vector s.

So this might be whatever program looks like. So, we have V3, we have 3 vectors of type V3 u, a
and s - velocity, acceleration and displacement. And first we read values into u and a. Next, we
could we could calculate this for single value of t but just for fun we will calculate it for multiple
values of t. t ranging from say 0 through 9. So, what will this how we will do it? Well so s is
going to be sum of these two quantities and what are these two quantities?

Well they are u scale by t and then a scale by t square upon by 2. So, what is going on here? a is
a vector, scale of a and t square by 2 is also a vector. That vector and scale of u times t are being
added up and the result is this sum, is this displacement s and this displacement is also a vector.
So, this looks like an ordinary assignment, but really it is it is more complicated than that, when
you when you look at in the ordinary assignment you are tempted to think of it as sort of basic
data types.

Whereas over here, 3 components are being assigned in parallel, or 3 components are being
passed to this function and this function is returning 3 components, so is this. So, then we print
out as a function of t, the displacement that has happened and that is it. So, that is the program.
As you can see we could have return this program by accessing each component of u, s and t, but
rather than that we chose to use these functions sum, scale and length. And the reason for that is
that they reflect better what operation we are actually performing. And furthermore, once you are
somebody writes the operations sum, scale and length and tests them and make sure that they are
right, then you can be more confident that your code is actually correct.

842
(Refer Slide Time: 6:48)

So, let us do a quick demo. So, first we have the structure type, then the sum, then the scale,
length and then we have the main program. It is really what we what we saw on the slides. So, let
us just run it, compile it and run it.

843
(Refer Slide Time: 07:03)

844
So, now we are supposed to type in the velocities and the accelerations. So just so that we can
see what is going on. Let me type the initial velocity to be 0 and let me type the acceleration to
be say 1. So this is a plot of what happens to the particle as a function of time. So by making
these things simple, you should be able to check that these are in fact the correct answers. So,
what is going on over here is, I guess, you can think of it as a particle which is initially at rest is
moving may be falling down to gravity or something like that. Now we could ask, can we do the
same thing with member functions? And this is how it looks like.

845
(Refer Slide Time: 8:23)

So, here we have a member function, which calculates the length and that member function is
being called over here. This red text is the call of that member function. So, length is a member
function. You can see that it is inside the structure definition. And a member function f of a
structure type x should be invoked on a structure s of this type x by writing s.f(arguments),
which is exactly what has happened over here.

So, V is a structure of type of V3 and we are invoking this function on v by writing v. length.
There are no arguments specified over here. So, no arguments are given here as well. Now, this s
or this v is called the receiver of the call. So, there is another analogy here as well that this part is
sometimes even called a message being sent. A message is being sent to this object and that
object responds, so that is that is another metaphor that is used.

But anyway we are going to call this thing before the dot as the receiver of that call. So, in
v.length, v is the receiver, and it is a function call. So, all function calls it executes by creating an
activation frame. And the references to the members of the body of the definition of the function
refer to the corresponding members of the receivers. So see this you have x.x, y.y, z.z. What are
these x, y, z? Well they are these, but as far as these calls are concerned they are members of the
receiver. So this x.x, when this call is being made will actually refer to v.x, this is refer to v.y,
this is refer to v.z. So, then v.length executes x, y, z refer to v.x, v.y, v.z. So, as a result of this

846
v.length is going to return one square plus two square plus three square plus two square again. It
is square root so 1 plus 4 plus 9 square root of that is 3.

Now, the receiver itself is also an argument otherwise how would you know what does x mean.
So, this receiver is an argument and it is it is kind of a hidden argument. Well it is not really
hidden. It is actually upfront, it is it is really at the front. So, it is a kind of a special argument.
But it is not there in the argument list, in the parameter list. Alright, but it is an argument
nevertheless. And it is an argument which is passed by reference.

So in this code, if you change x then the x member of v is going to get changed. So, it is this v is
being passed by reference that is why this happens. If v is v is passed by value, then if you
change x that would not be that would not happen. But indeed, the receiver is passed by
reference. So, we can write the other functions as member functions and here is the complete
definition.

(Refer Slide Time: 12:15)

So, this is our struct V3, the members then this is a first member function which we just saw.
This is the sum operation written as a member function, so sum of V3. Well V3 in what, we need
two arguments to make this sum. Now, that sum, the first argument is the receiver itself. So,
coming over here, so we are doing ut.sum of at/2, so ut is one V3 which is being added to at by 2

847
which is another V3, so in this case this v is going to be at/2 and ut is going to be the receiver for
this.

Alright, so now what how does this functions work. We are supposed to add up the 2 vectors and
pass the resulting vector. So we are going to create the result that over here. V3 of v is going to
be our result vector. Now, the x member of this should be the sum of this ut x and at/2 x. So this
is ut x and this is at by 2 x; similarly y, similarly z. And then we return this vector so that is how
this sum works.

Scale is similar, for the scale so we have u.scale(t). So, u is the receiver and t is the argument. So
t is, the value of t is placed in f, so again what we are we calculating, we are supposed to
calculate the result which is V3 vector, which is the scale version of the receiver. So, to
implement that this is the x member of the receiver, we scale it up by f and put it in the x
member of our result V3. And so we construct all V3, the 3 vx, vy, vz and then we return v.

How does it look like in this function? Well we wanted to calculate u times t so that it is scaling
so we partial result we put over here. Then we wanted to calculate at square so that is a times
scaling by t square by 2. So a.scale of t square by 2 and then we have to add up these two things.
So, that is what is happening over here. Finally, we have to take the sum of the length of that
sum and so that is happening over here.

And I should say that we do not necessarily need to have so many variables if we do not want.
What is happening over here is we are going to scale and then the result is going to be summed
with the scale version of this. And that we can take length, we can apply the length member
function to this entire result. And we are going to, we will then get the length. So, here we can
think of this as one long complicated expression, instead of that we have broken up that
expression into 3 separate expressions which are of course related.

848
(Refer Slide Time: 15:40)

So, what we have discussed? So we discussed the syntax of member functions. We have said that
member function is physically placed inside the struct definition. And we said that the call to a
member function looks like receiver.function_name followed by the arguments. The member
function executes like an ordinary function with the receiver being an additional argument and
the syntax makes the receiver look very different and indeed it is very different. It has a special
relationship.

There is nominal special relationship in that the receiver is being definitely passed by reference
but in addition to that somehow if I write say v.something, then I know this is something which
is happening and it has some special meaning in the context of v. Usually. Or it tells me look this
the code for this function will be found wherever v is itself defined.

We also said that the receiver is implicitly passed by reference and so the call can actually be
modified by the members in the receiver. And this syntax is reasonable but you might ask well
we really need it? We have used the usual function called syntax, so that is that is not quite clear
yet, but it will become clear quite soon. So we will take a quick break over here.

849
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 20 Part- 3
Structures Part 2
Taxi Dispatch
Welcome back.

(Refer Slide Time: 0:26)

In the last segment we discussed member functions. And in this segment, we will take the
discussion further and see it in the context of the taxi dispatch problem.

(Refer Slide Time: 0:21)

850
So, let me remind you what the taxi dispatch problem was. So, customers arrive and have to
be assigned to earliest waiting taxi. And, we now are going to implement the functionality
which we implemented earlier using member functions.

(Refer Slide Time: 0:53)

So first of all, a structure to represent the queue, okay. So, let us say N is the maximum
number of waiting taxis and waiting is the variable which we are going to need to keep track
of the number of taxis currently waiting. Front is the index of the earliest taxi in the array that
we are going to keep. And the array elements front through front plus and waiting mod N
hold the IDs of the waiting taxis.

So remember that in chapter 14, we discussed this and there we said that this is a circular
queue that is why that mod N operation happens. N is the length of that queue, maximum
number. of waiting taxes possible. And the queue is involved in two operations, inserting
taxis and removing taxis, so these become natural member functions. And you will see that it
is useful to have a member function to initialize the queue as well. So, here is what the queue
might look like. So we have constant at N=100, so we need to have some maximum length or
the length of the queue and so that is 100. Then we have array elements, which are going to
store which are going to store the driver IDs of length m and then we are also going to have
variables members which are n waiting and front. Then these are our three member functions.
So, that is that is sort of the overall high level scheme of what we are going to do in this taxi
dispatch problem.

851
So, let us just let me just show you what each of these functions is going to look like. So, let
us start with initialize. So what do we want in initialization? If you remember when we
created the queue, we are we said that n waiting and front should become 0 and that is kind of
a bare minimum that we want the queue that we create should, I mean it should make sense.
So n waiting and front should make sense and at the beginning that is how they make sense.
So, that is what we are going to do in this definition. So, insert is going to contain the code of
what is needed, what is needed to happen when you insert an additional element into the
queue and remove is going to contain the code which is needed for removing elements from
the queue.

(Refer Slide Time: 3:31)

So, what does our main program look like? So, we create a queue, the struct, and then we
initialize it or there should be parentheses there, so that is a typo, we need to have parenthesis
and a semicolon over here. And then there is a loop, so we read in the command which the
operator gives and if it is d then we are going to get the driver details and we are going to try
and insert it into the array into the queue.

If it is a c for a customer, then again, we are going to remove; we are going to remove the
driver. So, we are going to take out the driver from the queue and this is going to be a
reference argument, so this will actually modify this driver. And, of course, in either case, in
this case, if there is no driver waiting, then we should print this message.

In this case, if there is no space to put in the new driver we are also going to put this message.
And if that driver removal is successful then we are going to say print a message saying

852
‘Assigning’ this driver. That is basically the main program, so the member function
initialized. So, this is actually fairly simple as I just described.

(Refer Slide Time: 5:02)

It is going to simply set n waiting to 0 and front also to 0. So, we were doing this at the
beginning in the old program but now notice that it has gone into a member function.

(Refer Slide Time: 5:17)

So, in particular, if you look at this the internals of queue are not really visible and that is a
good thing, in the sense that this code is a high-level code. The internals are being
manipulated but they are being manipulated in these calls in the member function calls. So,
this is the kind of separation of concerns that has come about because of all of this. So in

853
particular, the member functions modify the members of queue and the user which is this
main program in this case is just going to call the appropriate member functions.

And the user where the main program is not really aware even of what happens inside this
queue. If you remember we ourselves had two implementations of the queue and this main
program would work with either implementation, provided the functions themselves were
changed. But this program would not have to change, if the signature of the member
functions does not change.

(Refer Slide Time: 6:23)

The member function insert is again not hard to write. So, we are inserting a driver v and we
are going to check, if the queue has space. And if so we are going to insert it at the front and
we had a fairly extensive discussion of where, we had a fairly extensive discussion of where
the back of the queue is. So, it is a disposition, so that is where we insert. And then the
increment and weighting and we return true, because this is successful. If there are too many
people waiting, then the insertion is not successful and so we return false.

So member functions remove is somewhat similar, so we check whether the queue contains
some values, otherwise we return false. Then the value to be removed should come from the
front of the queue. So we take the value from the front, and we increment front but of course
this increment must be this circular increment that is, if we are already at the last element of
the queue, then we should go to go back to the zeroth element okay. And of course any
waiting should decrease okay.

(Refer Slide Time: 7:48)

854
So so as you can see we can, in fact, easily write taxi dispatch in terms of member functions.
And one point to note and I am repeating it, but it is important which is that in this entire
program we are not really looking at the details of the queue. So our concerns have been
nicely separated, the member functions worry about the details of the queue and the user
program just calls the write functions. So, this exercise is about adding one more operation so
you should certainly attempt it.

(Refer Slide Time: 8:30)

855
So, the member functions only contain the logic of how to manage the queue. And we had
defined invariants about nwaiting front and things like that. And these apply only to the
member functions, the main program is not concerned with those invariants. The main
program only contains the logic of dealing with the taxis and the customers. So this is the so-
called separation of concerns.

And in some sense the new program is simpler as compared to what we had earlier, where
these concerns were mixed up. So if you can separate out concerns it is always a good idea.
So, that really concludes this lecture and here are some concluding remarks.

(Refer Slide Time: 9:19)

So, structure should be used to collect together the attributes of an entity and generally
represent an entity. So if there is an important entity in your program then you should have a

856
structure which is representing that entity. If that entity is made up of parts, then your
structure should contain the parts and the parts themselves may be structures, that is fine. But
usually it is good to have this kind of a correspondence.

Member function should be written to represent valid operations and actions of the entities.
And the invariants which we define for the entity should be satisfied by our member
functions. Now, later on, we will see that we can make this whole philosophy a little bit
stricter. In the sense that so far we have been recommending that accesses to entities should
go through member functions but later on we will be able to force this view. We would be
able to say or we would be able to make the compiler declare an error if the user tries to, he
tries to access an entity in some other ways. So you may or may not want to do that, but you
should note that if if you sort of design structures or such objects which are strict, then you
can you can be sure that look that, I am not doing the wrong thing even by mistake. I am
always am always acting according to the rule book and therefore I could not be making a
mistake.

And, of course, you should be paranoid about making mistakes because a program is going to
be run in so many ways and so many times and you cannot afford to make a mistake in even
one of those times. And therefore, anything that reduces mistakes is a good thing. So, that
concludes chapter 17 of the book and I definitely will encourage you to solve problems at the
end of that chapter and we will stop this lecture. Thank you.

857
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 21 Part- 1
Classes
Introduction
(Refer Slide Time: 0:26)

Hello and welcome to the NPTEL course on An introduction to programming through C++. I
am Abhiram Ranade and today’s lecture is on classes and the reading material for this is
chapter 18 of the textbook.

(Refer Slide Time: 0:33)

858
So, here are the main recommendations from the previous lectures. First, use a struct to hold
information related related to each entity entity that your program deals with. Then define
member functions corresponding to actions or operations associated with the entity.

(Refer Slide Time: 0:52)

The main theme of this chapter is to take this idea further in the following sense. So, the goal
is to build something like a software component around a structure. Now, software
components are useful for building large software systems just as hardware components are
useful for building large hardware systems. And a software component must be convenient to
use and also safe exactly in the sense that hardware components are convenient and safe. So,
for example, they should software component should help prevent programming errors.

(Refer Slide Time: 1:42)

859
So, we have been talking about this theme for some time now. So, let us just clarify this a
little bit more. So things that you buy from the market are packaged and made safe to use.
Fridge, television, are some of these things. So, for example, there is no danger of getting an
electrical shock. A control panel is provided on the device. A user does not have to change
the capacitor values somewhere to change the channels on a television.

The analogous idea for software is that the make the functionality associated with a struct
available to the user only through member functions. So, this is kind of analogous of the
control panel and do not allow the user to directly access the data members inside a struct,
just as a user is not allowed to touch the circuitry inside a television.

And in some sense, the user has no business looking inside right that is the attitude that is that
that is the view that is taken. Or the user does not want to know what is going on inside just
to keep keep his or her headache low. And I mean keep separation of concerns. The user has
lots of things other things to worry about.

So another idea is that if you build a better fridge, you often keep the control panel the same
as the previous model. The user does not need to relearn how to use the new fridge. If you
build a better version of the struct, but if you keep the member functions signatures the same,
then the program that uses the struct does not have to change. So these are the kinds of things
that member functions and this kind of discipline will allow us to accomplish.

(Refer Slide Time: 4:01)

So, the modern version of a struct can behave like a packaged component and the designer of
the struct provides the member functions. Actually the designer of the struct can do lots of

860
things. So, for example, if I have an ordinary variable, lots of things sort of there are lots of
standard operations that can be performed on variables. To begin with, and we have to create
that variable so there is the creation of the object. Then I may want to assign, I may want to
pass the object to a function and we want to pass the struct or object or whatever, back from a
function I want to return it as a result.

And we know that when control leaves a scope, the variables which have been created inside
in the activation frame have to be destroyed. So, the modern version of a struct allows you to
customize these operations however you want. And that gives the designer a lot of freedom
and the freedom can be used to do quite some imaginative things.

Now, in this course, we are not going to talk about all these things at least not immediately.
We are going to talk about just the creation. In todays lecture we are going to say, how the
designer can decides what happens during creation? And the idea is that once structs are
designed in this manner using them becomes convenient and less error-prone.

So, we have been, we have been talking about all these things for some time now. But in
some sense, they are going to come to fruition in this lecture. And structs which are endowed
with such features are also called objects. So, have been using the term objects but the
technical meaning is an object is something is a struct or it is a variable created from a struct
but which can have all such features.

(Refer Slide Time: 6:13)

Alright, so here is an outline of this lecture I am going to talk about something called
constructors. I am going to talk about operator overloading, I am going to talk about access

861
control, then I am going to talk about classes, and then I am going to talk about some special
classes for graphics and input and output. So, what have we discussed so far in this segment?

(Refer Slide Time: 6:40)

We have said that you like to build safe and convenient software components, safe means less
likelihood of errors. Basically, this means think through how the component is going to be
used and provide a set of corresponding member functions. And we will see that we can even
disallow direct access to members and the idea behind this is that usually such access is likely
to be error-prone.

We want our objects to be convenient in the following sense that they make it easy to think
about parts of the program. So, member functions should provide a very clear interface and
the users of the components should not worry about how the functionality is implemented.
So, they do not, the component should be designed so that they do not need to look inside.
So, there should be very very nicely designed control panels so to say. And I should say that
these are guidelines and this is how we would like software to redesign. But sometimes it
does not work that way and that is okay, once in a while, provided you have good reasons.
Alright, so next we will discuss constructors but before that let us take a short break.

862
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 21 Part- 1
Classes
Constructors

Welcome back!

(Refer Slide Time: 0:23)

In the previous segment we talked about software components. In this segment we are going to
talk about constructors.

863
(Refer Slide Time: 0:31)

So, as motivation for this, let us examine the Queue struct in taxi dispatch. So, this is the
definition of the queue, the queue struct and if you remember, there were these, there was an
array of elements storing the waiting drivers IDs, then a few variables, then an initialize member
function and insert and remove member functions. The main program looks something like this.
So, we started off by declaring, by defining the queue creating the queue and that we called
queue.initialize(). And then there was a fairly long, there was a loop which I have not, not put
over here I want to look at these 2 statements.

There is a simple problem over here, which is that a programmer may forget to call initialize, he
will forget. What do you do? It turns out that the designer can ensure that nwaiting and queue
front will become 0 which is what, which was the job of initialize if you remember, even if the
programmer forgets to write this. How that happens, we are going to see in a minute. But that is
the, that is the idea that somehow when we create the queue, we will execute something
automatically, which will cause nwaiting and front to become 0.

864
(Refer Slide Time: 2:09)

So this, this special code that we execute at the time of the construction of an object is called the
Constructor Code. So, basically the constructor is called, whenever an instance of a struct or a
variable or a variable of a struct type is created. Now, in inside the body of the structure
definition, in the structure type definition, a constructor has the same name as the struct and it
does not have a return type. So, we will see that. So for a struct queue these were the members,
and here is the constructor. So, queue there could be parameters, but this particular constructor
does not have a parameter.

And then we are going to give the code that is to be executed. That is it, ok. So, this is what the
constructor is and in main the moment I define queue, I define q as an object of type, structure
type queue, this code is automatically going to be called. So, so the variables will be created and
then this code will be called. So, the code inside the constructor is expected to perform
initialization of the members, but of course it is any code, so you can make into whatever you
want. But that is why, but its purpose really is, it was intended, the notion of constructor was
created so as to enable initializations. So it is really the designer who is keeping track and saying
that, “Oh! Look, when you create you need to initialize, and therefore, I will give you a way of
making that happen automatically.” And then the user just writes this and the initialization
happens. So the constructor is called automatically.

865
(Refer Slide Time: 4:34)

So, in general, we can have constructors in any struct. So, here is a struct x which is in defined
and here is the constructor, so this is the body of the constructor. And in main I can have, I am
declaring little x to be an object of type capital x and I am supplying these arguments and this
will cause this constructor to be called. So, the constructor can take arguments and the creation
of the object x in main can be thought of as happening in 2 steps.

First, the memory is allocated for x, in the activation frame of main and then the constructor is
called on x with the given arguments. So this code executes, but with respect to these arguments.
And, and if you have members referenced over here they are considered to be the members of the
constructed structure. You can have many constructors provided they have different signatures.
And we are going to see example of this as well.

866
(Refer Slide Time: 5:43)

So here is an example of a constructor for V3, so this first constructor does not take any
arguments and it just sets all the members to 0. This constructor takes 3 arguments, constructor
takes a single argument and it sets all the members to that single argument. Are these useful?
Well if they are not useful you can define your own, but I am showing this just to show you what
the possibilities are.

So, how does the main program work? Well the main program works when defining V1 here and
argument has been given, so the constructor which takes a single argument, so since the single
argument is given, the constructor taking the single argument is called, so this is the constructor
is takes a single argument, so thus, it means that v1 dot x, v1 dot y, v1 dot z are set to the value 5,
set to value a which in this case is 5.

When defining v2, no arguments have been given, we note that we are not putting parenthesis
either. So, this is kind of a non- uniformity but that is what it is, we are not putting parenthesis.
So, we are defining, we are just giving the name of the variable which is being defined, and since,
no parenthesis are given, no arguments are given, we look in the definition of v3 and see if there
is a constructor without arguments so this is the one. So, this constructor will get called v2.x,
v2.y, v2.z will be set to 0. So, that is how constructors works, so these constructors work.

867
(Refer Slide Time: 8:05)

So, now you might have wondered we have been creating all these structures without even
knowing about constructors, so what is going on then? Well it turns out that C++ defines a
constructor for which, which takes no arguments and does nothing, if and only if you do not
define a constructor. So in the earliest examples we did not define any constructor, but you could
think of this way that C++ supplied a constructor which is really doing nothing. So you could say
that there is always a constructor either something provided by C++ or something that you
provide. Now, there is a technical term which is very commonly used which is the notion of a
default constructor. A constructor that does not take arguments and this constructor might be
defined by you or by C++ is called the default constructor. If you define an array of struct, each
element is initialized using the default constructor. So, if you want to construct an array of, of a
certain kind of struct, then you had better have a default constructor.

So, now look at this line, if you define a constructor, then C++ does not define the constructor.
So, if you define a 2 argument constructor, then C++ will not even define a 0 argument
constructor. But if you want an array of struct, then that is not a satisfactory state. So if you, if
you define the 2 argument constructor and you want to define arrays then you had better also
define a 0 argument constructor and it could do nothing but that is fine, that is what C++ would
define on its own anyway.

(Refer Slide Time: 9:42)

868
One more remark, so if a member itself is a struct, then its constructor is called first and even this
is the default constructor, however that constructor is used. So, for example, struct point double x,
y, I have struct disk point center, so when constructing disk center will be constructed according
to the constructer of point.

(Refer Slide Time: 10:14)

So, what have we discussed in this segment? So we have said that the constructor can be defined
so that variables get initialized in the, initialized the moment they are created automatically.

869
There can be many constructors with different signatures. Next, we are going talk about
something called operator overloading, but before that we will take a quick break.

870
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 21 Part-3
Classes
Operator Overloading

(Refer Slide Time: 00:18)

Welcome back. In the previous segment we talked about constructors. In this segment we are
going to talk about operator overloading.

(Refer Slide Time: 00:30)

871
In mathematics, arithmetic operators are used with numbers, but they are also used with other
objects such as vectors and the same operators in some sense mean different things in different
places, but they are somehow related and therefore we somehow prefer to use the same symbol.
Now, something like this can also be done in C++ and it is desirable to the extent that it helps
your thinking.

So if, the program that you write is consistent with the way you think about, about the objects in
your program then that is a good thing and C++ allows you to do that. How it is C++ do it? Well
consider an operator @, so @ could be plus, @ could be multiply anything.

So, the operation associated is x @ y, so at appears in the middle and so at is an infix operator.
So, how does C++ look at such an operation? Well C++ treats this as x.operator@ with argument
y. So, operator @ must be a member function in the structure type x, structure type of x. So, if it
is a member function then that member function is executed.

So, if the member function operator@ is defined, then that is called to execute x @ y, it is as
simple as that. So, you can define for example, operator + and that code will be execute if you
write x + y, so we will see an example of this right away.

(Refer Slide Time: 02:38)

So, see we want to do arithmetic on v3 objects. So, this is our main, so we have v3 objects p and
q and they have been called with these constructors. So, we will see those constructors as well in
a minute. But let us say we have initialized those objects p and q somehow or the other. Then we

872
have couple of uninitialized v3 objects and now we can write r=p+q. And the natural
interpretation of this might be that look you add the vectors component wise and we can make
that natural interpretation hold in our implementation, and that is exactly what we are going to
see. So, notice that as we said earlier this just means r=p.operator+(q). So, we are going to define
the operator plus member function. Then we can write something like s=r*10.

So, so far v3, for v3 star does not have any particular meaning r is of type v3 and there is nothing
so far we have said as to what it means to multiply a vector by a scalar. But we can simply define
r.operator*, this expression would be effectively implemented automatically by C++ it will be
interpreted as this operation and C++ will just perform this operation.

So, how does this whole thing work? So, struct v3, if you remember has these 3 parts x, y, z
there are the 3 members x, y, z and let me just get this constructor out of the way. So, this is a
constructor taking 3 arguments and setting x, y, z to those 3 arguments. So, this is kind of the
most natural constructor you might want, I want to set my vector, I want to initialize my vector
to some arbitrary 3 quantities.

Now, comes another constructor because we want to write this as well, so for this, this
constructor will not work. So, this constructor is going to do nothing, so the members x, y, z will
not be initialized in any particular manner.

Next we are going to write the member function operator+. So, the definition of this member
function is like defining, is like the definition of any other member functions. So, this v3 is the
type of the value being returned and this is the argument. And this is effectively going to be
adding 2 vectors. So, how are those 2 vectors going to come? Well 1 is going to be the receiver
so we write, we wrote p+q that was translated implicitly by C++ to this.

So, p is going to be the receiver and that is going to be added to q. So, in this, the receiver is
always there and the second the right hand side operand of the plus is going to be this b. So for
this expression which got translated to this p is going to be the receiver, q is going to be the right
hand, right hand side operand or the b value over here.

So, what happens? So in this, what am I supposed to do? I am supposed to return as a v3 object
having x co-ordinate equal to the sum of the x co-ordinates of the receiver and the right hand

873
object. So, x+b.x is exactly that, y+b.y is the desired y coordinate and z+b.z is the desired z
coordinate. So, we are calling a constructor over here and that constructor is constructing a v3
object with these members.

So, these are exactly the numbers that we wanted for component wise addition or member wise
addition and that is exactly what these member function have accomplished. What about this? So,
we should write a member function r.operator* and this would be the factor argument, so it is
going to look something like this. So v3 will take a, it appears to take a single argument is
operator star but that is not true there is always a receiver and the receiver is, since this is inside a
struct v3 the receiver is of type v3.

So, this is an implementation of v3 times number, so f is that number. And what is going to
happen over here? You should be able to write this now, you are going to return an object whose
numbers are x*f, y*f and z*f and you want to return a v3 object so we just called the v3
constructor with these arguments, so that is it. So, this allows us to do arithmetic on v3 objects.
Now, using this v3 arithmetic we can do something which looks quite nice.

(Refer Slide Time: 08:18)

So, suppose we have v3 objects u, a and s remember our ut plus half at square example. And let
us say t is a double value, now our formula was ut plus half at squared. So, we have essentially
written that formula but you can see that the formula is going to do what we want, why is that?
So, u times t we have defined, u times t is going to be u.operator*(t), so we have defined how

874
this is going to happen. This is going to multiply every member, every component of u by t, so it
is going to do exactly, exactly the right thing. What about this a times t? that is again scaling, so
this if it is calculated first will give me a vector which has been acceleration which has been
scaled by t or acceleration which is multiplied by t. But again when I do this it will be again a v3
though the product multiplied by t, again the v3 multiplied by 0.5.

So, this is going to produce exactly the half at square term that we want. So, now this is going to
be a v3 object, this is going to be a v3 object and there is a plus over here, but we define the plus
operator as well and therefore, this is going to produce the final sum that we wanted and if we
put s equals this then we can get s.x, s.y, s.z which is going to be half at square for t equals 10
and these values of u and a.

(Refer Slide Time: 10:01)

875
876
Let us do a demo of this, so this is our file, kinematics.cpp. So, inside this we have put in
whatever we wanted. So, this constructor and I guess I have, I have ignored putting the simple
constructor over here but I guess it is not needed over here but we could have put that in as well.
So, this is the definition of operator+ so the plus operator, this the definition of times operator
and you can see that I have exactly the code that we want.

So, let us look at this and let us calculate what answers are we expecting. So, t is 10, so ut we
should expect in the x co-ordinate 10 over here and then half at square, so half of a in the x co-
ordinate is going to be 2 and t square is 100 so this is going to contribute a 200 plus 10, so 210.
So, similarly you can do the other things but lets just check whether this will indeed produce s.x
to be 200, so 210. So, let us execute this and run it. Yes, 210 it is the x, x coordinate.

877
(Refer Slide Time: 11:30)

So, here are some exercises, so overload the multiplication to define the dot product of 2 vectors.
As you might remember this is also something that is needed in physics a lot. Now, we already
have overloaded the multiplication but that was a multiplication between a v3 object and a
number.

This is going to be v3 object and another v3 object and that is perfectly fine that can sit next to
our old definitions because the signatures are different and so when you write it in your code
C++ will know exactly which of those functions to use because it will look at the signatures and
it will look at how many arguments, what kinds of arguments you have specified.

878
(Refer Slide Time: 12:19)

So, what have we discussed? So, we have said that expressions involving vectors can be made to
look very much like what you studied in physics. The exact formulae you can almost see in your
code. Other operators can also be overloaded, including unary operators and this is discussed at
length in the book. Although for this course you will not really worry so much about all such
detail overloading. So, if you understand plus and times that is quite enough for this course and
may be the few other operators which we will specifically point out a little bit later.

Now, overloading operators seems very cute but it is also a little bit strange, I mean so in
principle you could take the plus operator and make it do multiplication. So, that could be
amusing but in practice it is a terrible idea because you are fooling people and that is the last
thing that you want to do when you are cooperating, when you are trying to co-operatively solve
the problem.

So, you have to be careful with this kind of overloading. You should use overloading when it
really, when the operators are really consistent with the intuition that you have or intuition that in
general people have, otherwise you will just end up confusing the reader of your program and
believe me you will also confuse yourself. But if the intuition is consistent then you should
overload because one of the idea in modern programming is that, your programs should look like
the language should be like the language you used in dealing with that domain.

879
So, if while doing the physics you think of multiplying vectors by scalars then if you can make
that happen in programming it will also be a good thing, it will increase the readability of your
code and generally make things more appealing. So, I just want to point out that we saw 3 ways
of writing s equal to ut plus half at square, using ordinary functions for sum and product, using
member functions and operator overloading. And I guess you probably agree with me that
operator overloaded looked very very natural. The next topic is going to be access control and
classes but before that let us take a short break.

880
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No 21 Part 4.
Classes
Access control.
(Refer Slide Time: 00:19)

Welcome back. In the last segment we discussed operator overloading. In this segment we are
going to discuss access control and the notion of classes.

(Refer Slide Time: 00:29)

881
So it is possible to restrict access to members or member functions of a struct. So there is a way
by which we can declare a member to be public which means that there is no restriction. We can
declare members to be private which means that they can be accessed only inside the definition
of the struct and the same thing for member functions.

So the typical strategy when we are designing these software components is to declare all data
members to be private so that code which is outside of the definition that the structure definition
cannot look at the data members and some subset of the functions should be public. So that is
sort of like the control panel. So whatever we want the external users to do, we are going to
make them public. So here is a simple example.

(Refer Slide Time: 01:52)

882
We have this struct Queue and what we are saying over here is these are private. So to say that to
declare these to be private, we just have to put private colon before. So this is the so called
access specifier and then the rest of these are public or the constructor and the two member
functions are public. So we have put this access specifier public colon before it that is it.

So if you have such a Queue then from your main program you would not be able to say
Queue.elements. The compiler will say that look you do not so this is a private member or under
for you cannot access it. So you would be forced to use just these member functions.

So, public and private are called access specifiers and they are written with that colon afterwards
and the idea is simple and access specifier applies to all members defined following it, members
and member functions until another specifier is given. So in the previous case, elements nwaiting
and front are private. As we said and Queue the constructor insert and remove are public. So
these appear after the private access specifier, these appear after the public access specifier. So
basically, you can decide how the struct works. I should say with all these using these access
specifiers and also operators. I mean if you want an operator to be accessible, then you should
make it public. So operator plus or operator star should also be made public if you want external
code to be able to access that.

So basically as a designer of a struct, you can exercise great control over how the struct gets used
and this might you might think of this as sort of creating barriers for yourself. So in a sense that

883
is true, but as I discussed some time ago, you want to be able to claim that look my code is not
touching the members even by mistake. And however, why am I so sure of it? Because the
members are private and therefore the data members are private and therefore I know that if
somewhere I try to access a data member then the compiler will complain. So that is a good
reason for making things keeping things public and private with a well thought out strategy.

(Refer Slide Time: 05:06)

So this brings us to a term classes, a class which you might have heard quite a bit and especially
in the context of languages like C++ or Java, and also other modern languages, so what is a
class? A class in C++ is really essentially the same as a struct, except for how the defaults work.
In a struct, everything is public by default. But of course, you can change it, you can put the
access control access control the specifiers. And in a class if you define something as a class then
everything is private.

So we will write a Queue class here so if I write this Queue, and I have said nothing over here, I
have not said private but because this is a class if no specifier has been given then that is treated
as private. So that is why these things would be private. And since there is a public specifier,
these things would be public that is it. So that is really the difference between structs and classes
and classes are a newer term in the sense that classes are associated with all this philosophy
about how to write code.

884
About making member functions, and making things which are public and private. But it really is
the same thing as a class which has been endowed with these member functions. So because C++
has the legacy of C and C has the struct which looks very much like a class, the designers of C++
said that look yes, they are more or less the same but we will keep this minor difference because
in C, everything is public and therefore the term struct which is coming from C also has that idea
that everything is public except if you change it explicitly.

(Refer Slide Time: 07:50)

Alright, so what have we discussed? We have discussed access control and this allows you to
hide members and member functions from users if you wish and this is packaging, this is like
packaging hardware components. So you do not want the people to see the wiring inside. It is not
safe, you may get a shock or something like that or in the case of software, those are parts of the
implementation and you are and you may not know enough to handle those parts. Then we said
that classes and structs are essentially the same except for the defaults. Next, we are going to talk
about classes for graphics and input output, but before that, let us take a short break.

885
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No 21 Part 5
Classes
Classes for graphics and input output
(Refer Slide Time: 00:18)

Welcome back, in the previous segment we talked about access control. In this segment, we are
going to talk about some classes that you have really been using and well, maybe some which are
slightly new but which you will want to use.

886
(Refer Slide Time: 00:35)

So, graphics classes you may have guessed that our graphics primitives such as Line, Rectangle,
Circle are actually classes. So when we create lines we are really just creating, creating instances
of that class or these are structs and we are creating structs.

And when we write something like Line l(0, 0, 55, 70), this really is a constructor call. So in our
graphics library, there is a class called Line or a struct called Line and there is a constructor
which takes four arguments and this is really a constructor call and that returns a line object, or a
line struct. So the constructor in this case is going to initialize an area of memory to hold

887
information about object, so which is what normal constructors do, they initialize the members.
But, as we said earlier the constructors can contain arbitrary code as well. So in this case the
constructor code is actually also going to draw the objects, object on the screen.

So, important point that the line creation commands are really constructor calls to a class called
Line and similarly for circles, rectangles, text. Now in the graphics classes there are data
members which keep track of things, like where is the graphics object? What is the size? So
what is the size? What is the color and these members are private and therefore you do not get to
see them.

How do you change the color? You have been given a call, you have been given a command of
something but as you can see now this is just a member function. So you have been given
member functions. You have been given that control panel which enables you to change colors.
So you do not have to directly go in and change colors. Those are the colors. There is some
information kept about the colors, but that is private information. And you do not want to know
that because that information is kind of complicated. So instead of that it is better to have this
have the commands which are convenient for you to see. And also graphics operations such as
move and rotate are also member functions and how does your program get all of this? Well, the
header file simplecpp fetches or includes all the class definitions when you include that file in
your program.

888
(Refer Slide Time: 04:01)

Now like graphics classes, there also are input output classes, which you have been using, so cin
cout are objects of class istream and ostream respectively and they are defined in the file
iostream. If you remember we had a command, cin.getline of some buffer some buffer name care
buffer name and maybe the length of the char buffer name. So now you can see by the syntax
that this is a member function. So you have been using member functions already in graphics as
well as in io.

889
Now you may say that oh iostream. I did not explicitly include but we have said we have
discussed this earlier and we have told you that look that got included because you included
simplecpp and << and >> are actually operators and they have been defined for the objects by
using things like operator>>. So that is what it is, fstream is another class like istream and that is
used for file io.

So you can create an object of class ifstream and associate it with a file on your computer. So
once you do that, you can read from that file, pretty much like you read from c in and you can
create an object of class and you can create an object of class of stream which can be used for
writing files. You know exactly a similar manner and end will see an example next but for this
you have to include the header file fstream. So if you include that header file then you get to use
if have ifstream and ofstream.

(Refer Slide Time: 06:21)

So here is an example of file io. So this is our program. So as you can see it is including fstream.
It is also including simple CPP because of all the usual things that we have been talking about.
So namespaces, a namespace std and iostream and things like that. So what is new? So here is a
definition, so we are defining an object in file and this is a constructor for it. Its type is ifstream.
So we are defining an ifstream object.

890
So what does this definition really do? So it says, it really says the following, it says that in my
program the name in file is going to be there, so that is the ifstream, but while constructing it and
associating it with the file f1.txt, which is going to be present in my directory. So that is what this
line does. It is creating, it is a constructor call. So it is constructing a variable called infile and its
type is ifstream. But the constructor is linking a file on your computer to this name inside your
program. Similarly ofstream is a structure type and you are creating a variable or an object name
outfile and type ofstream and the constructor is associating the file name f2.txt with this out file.

Now f2.txt is expected to be created when the program executes, it is an output file, a file. So it
need not be there early on. And here is the main program, so inside the main program what are
we doing? We are we have a variable v of type int and we are reading an integer from infile. So
this operator works like before for cin so if I had said cin I would have extracted it would have
extracted an integer from cin now it simply extracts an integer from infile.

So from this file in particular. And this would have sent the value of v to cout had had this been
cout but now it is just going to send the value of v to outfile. That is it. So this is how you can
read files and write files and there are some additional details that you might want to know, like
maybe how do I append to a file and things like that. So that is discussed in the book. But we are
not going to discuss it in this lecture. So anyway, so what does this program do?

So this program is going to read 10 numbers from infile and create a new file f2.txt and put those
numbers inside that file. So this is of course trivial processing of files, but now you get the idea.
So you should be able to write programs which take data from files and which put data into files
not only take data from the keyboard and put data onto the screen.

891
(Refer Slide Time: 10:06)

So what have we discussed? We have discussed graphics classes, we have discussed input output
classes and some of these things you have already been using but now, you know that the
commands that you were using involved classes and constructors and member functions. Next, I
am going to make some general remarks and then I will conclude this lecture, but before that, let
us take a quick break.

892
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 21 Part- 6
Classes
General Remarks

Welcome back. In the previous segment we discussed graphics classes, and input/output classes.
In this segment I will make some general remarks and conclude this sequence of segments.

(Refer Slide Time: 0:29)

So, I will first do a review of terminology, then I will talk about predefined member functions, I
will talk about disabling certain operations, and then I will talk about class declarations and class
header files.

893
(Refer Slide Time: 0:44)

So, the terms object, structure variable, instance of a class, these are synonyms, and all of them
denote a region of memory, and that is the region of memory which contains the data associated
with that object, or structure variable, or the class instance. Now, the term structure can mean a
structure type, as well as a structure variable and which one it is will be clear from the context.

This is really not that confusing, because this kind of usage is present in day to day life. For
example, when we talk about a rose, you might mean a type of flower or we might mean, this
particular flower in my hand. So, our use of the term structure is similar, to this kind of usage.
Then the term object oriented programming also gets used a lot.

Object oriented programming is a methodology for a program design. This methodology


suggests that real life entities should be modelled using structures and classes. So, basically if
your program is about, certain real life entities, this methodology says that you should make
structures or classes corresponding to those real life objects. And, if you are going to operate
upon these real-life entities, then you should make member functions. You should not directly
access the data members. The data members should be hidden. The idea is that, data members
can not be accessed without any discipline; you may just set the values of some data members.
Instead of that if you use a function, then you can only do a certain fixed set of things, so by

894
providing an interface using functions, the designer says that look, this is how you should be
using it and this is and if you use it in this way then your program is going to be correct.

Now object oriented programming has many other features, so, for example, there is a notion of
polymorphism, or there is a notion of inheritance. These are outside the scope of this course but
they are discussed in the book.

(Refer Slide Time: 3:20)

Now in C++ many member functions are already defined for you. So if you do not define any
member functions, C++ still has some member functions defined. For example, C++ does have a
constructor defined for every class. The assignment operator is also likewise defined, and
something called a copy constructor is defined, and something called a destructor is also defined.
You can define any of these and we will see a little bit more detail, and when you do the
definitions, your definitions will override the predefined member function definitions. So, I will
talk about some details now, but really for a complete description you will need to read the book.

895
(Refer Slide Time: 4:16)

So, predefined constructors are always there, if you do not define a constructor. So this
constructor takes no arguments. So, what does it do? Well it does nothing, so if the data members
are fundamental types, it really does nothing. So, in fact, whenever you are defining a struct
earlier and you are just saying struct P, then this predefined constructor was being called to
construct that object P.

If you define any constructor, with arguments without arguments, then your constructors are
going to get used, and the constructor, the predefined constructor is not going to be used. C++ is
basically saying that look you are taking in your own hands, how an object should be
constructed. So my predefined constructors will not, will not be used. I want to make a rather
wider note, as we are discussing constructors.

So, if you have nested structures, so say you have a rectangle structure, a struct, and inside that
there is a point struct. So in that case, so the constructors work in the following manner. So, first
the point objects inside the rectangle will be constructed using the constructors for the point, and
only after the data members are constructed will the constructor for the outer object get called.

896
(Refer Slide Time: 5:56)

When we talked about assignments for struct, and really you should think of that as being an
assignment operator that C++ predefined for you. This predefined assignment operator simply
does member by member copy. So, this is this is what you have been used before we began this
discussion of member functions. When we talked about structs, well you can assign one struck to
another struct, and that was just doing member by member copy.

You can override this, by writing your own assignment operator. Just as we define the plus
operator, you can define the operator equal to. Why is this necessary? Well here is one example,
if you copy, if you make an assignment to a graphics object. You want the data to be copied, plus
the changes, because of the assignment need to also be shown on the screen. So, your assignment
operator can, in fact, make the changes to the screen just as you are doing the assignment. And
we will see more examples of this next week.

897
(Refer Slide Time: 7:15)

A copy constructor is something that is used when you pass a structure to a function. So, when
you pass a structure to a function by value, we have discussed that a copy needs to be made.
Now this is done by a function called the copy constructor. So this copy constructor gets called
to make that copy. C++ provides a predefined copy constructor. So, what does the predefined
copy constructor do? Well it does a member by member copy.

So the new object that is created in the activation frame, of the called function will be a copy,
will be a member by member copy. You can override this, and again for graphics. You may need
not only to make a copy, but you may need to change something on the screen. So, if you move
the object subsequently. You will want this copy to move. So some additional things might need
to be done in addition to just copying the data members. So this can be done, so this is why we
have this thing called a copy constructor. And next week we will see more examples for the need
of the copy constructor.

898
(Refer Slide Time: 8:34)

A destructor sounds like really really dangerous term, but it is needed for the following case. So,
when an object goes out of scope or is deleted by the delete operation, C++ actually calls a
destructor member function. The predefined destructor does nothing. So, basically, there is the
area of the object and nothing really happens, well actually that is not quite true. The destructors
of the nested objects will also get called. So, that is what the predefined destructor does. Just like
the predefined constructor calls the constructor of the nested objects, the predefined destructor
would also call the destructor of the nested objects.

But, you can override. So, instead of doing nothing, you can do you can get something to be
done. So, for example, if a graphics object is going out of scope, then you do not want to see it
on the screen. So if you are designing the graph the graphics system, then you will put in the
destructor the code to remove the object from the screen. And there are other cases, as well
where destructors need to do something interesting, and we are going to see examples of that
next week.

899
(Refer Slide Time: 10:01)

Now, this whole framework of member functions is quite interesting, in that it allows you to
disable certain operations. Basically, the idea is the following if you make certain member
functions private, then those member functions cannot be executed from outside of the class
definition. So basically, for practical purposes you are saying that look you are not allowed to do
this operation.

So, suppose you make the copy constructor private, then it cannot be called from outside which
means that as a designer you are saying look, I do not want you to pass this object by a value to
any function. You may want to do this; you may want to say that look I do not want a copy to be
made of this object. But it can be passed by reference, so that is allowed. But a copy cannot be
made. Similarly, you can make the assignment operator private.

In that case if you write something like a=b; you will be producing a compile time error, again
you are really telling the user of that class please do not please do not make copies of this, I do
not want you to make copies of this. So, we could have taken this approach, when we design the
graphics objects. We could have said that you cannot make copies of the graphic objects.

So, that makes some sense, because after all when you make a copy you need to do some
additional work and we might have said that look we have already done that additional work by

900
allowing you to create a new graphics object. That would have been a reasonable design, but I
guess allowing for copies and doing that extra work is perhaps convenient to the user and
therefore we did that. But C++ gives you the option of saying do not make a copy, so basically
these these access control operators and member functions together give the designer great
amount of fine control.

(Refer Slide Time: 12:11)

Now, I want to say a little bit about organizing files with classes. So typically if you have a
program and if you have files in it the content will be something like this. So there will be
structure definitions, there are functions; there will be the main program. The general principle is
still the same; names must be defined before they are used. And, just as we said that functions
can be defined, can be declared, without defining. I guess I should say the general principle is
that names must be declared before they are used.

So, just as we said that ordinary functions can be declared without being defined, you can have
member functions be declared without defining. And these declarations can also be put in header
files. So, all this is reasonably consistent, reasonably similar to the way we talked about function
header files for functions. And I am not going to discuss this in more detail, but it is discussed in
good detail within the book.

901
(Refer Slide Time: 13:26)

Now, I want to conclude this lecture sequence, this sequence of segments. I want to conclude this
lecture and the point that I want to make, sort of the major high level point is that the notion of
packaged software components is important, just as you have, you can have hardware
components the idea over here is that you can have software components which are nicely
packaged. And which are expected to be used in a certain manner and not in some other
manners.

So, those, the way it is going to be used, is clearly indicated by the designer. And later lectures
will contain more examples. Making some member functions public, is like providing an
interface, sort of like a control panel. So, that is what the designer is telling you, “Please use this
control panel or please use this set of member functions do not try to use the object in other
ways.”

So, basically, things are put behind this control panel and so the designer is saying well you do
not need to worry about what goes on inside. So, I am telling you what these buttons are going to
do, or I am going to tell I am going to tell you what these member functions are going to do, and
I have tested my program and I have guaranteed that they do exactly what I am telling you.

And these ideas are really very similar to what we discussed in connection with ordinary
functions. So, what we said there was the following, we said that the specification of the function

902
must be clearly written down and the specification of the function is really analogous to the
interface, which must be written down as well and explained.

So, if you designed a class then for the benefit of the user, you should clearly explain what the
member functions are doing. You do not have to explain to the user, how the implementation
happens. But you should tell what are they really doing. So, for example, you can say, that move
on a graphic subject will cause the object to be moved. How exactly that move gets implemented
is not is not to be defined or is not to be discussed in this context.

Then the user should not worry about, how the function does its work, that is what we said and
here, the idea is that the data members should be hidden and, in fact, the user should not concern,
himself or herself with, how the implementation of the class happens. So, that is it that is the end
of this lecture. As usual, please look at the exercises at the end of this chapter. Thank you.

903
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-22 Part-01
Representing variable length entities
Introduction

Hello, and welcome to the NPTEL course on an introduction to programming through C++.

(Refer Slide Time: 0:31)

I am Abhiram Ranade and this lecture is about representing variable-length entities. And the
reading for it is chapter 21 of the textbook. So, let me begin with the programming problem.

(Refer Slide Time: 00:43)

904
So, we would like to design a scheme to store the names of the students in your class. Now
there is a natural solution to this use a two-dimensional array like we talked very recently
store ith name in ith row. Now, what will the row size have to be? So, the row size will have
to be as large as the length of the longest name. And therefore, it seems that most rows will
be mostly empty. And therefore, we are using the memory quite inefficiently. So, you might
wonder. Is there is a better scheme?

And this is not the only problem that we are looking at today. Indirectly, there are also other
problems which are very similar. So, for example, for some reason, I might want to store a
whole bunch of polygons in my program. And say the polygons have varying number of
sides. So, again the provision that I might have to make might be for the largest polygon
whereas I might end up having a lot of small polygons. So, again I will end up wasting a lot
of space.

(Refer Slide Time: 02:05)

So, the C++ standard library which is discussed in chapter 22 of the book and which we will
take up later on contains very safe and convenient classes for this. And they will be sufficient
to store names, polygons and other such entities and you should use them wherever possible.
But in this lecture or in this chapter of the book, we are going to talk about how to build the
classes like those in chapter 22. So, essentially we are going to understand what is the
mechanism behind these classes? So, sort of what is the magic on which these classes run?

905
(Refer Slide Time: 2:46)

So, here is the outline for today’s lecture. So, I am going to talk about something called the
heap memory. Which is something that you have not seen so far. And there will be a
discussion of the primitives for allocation and deallocation of memory from this heap
memory. Then we will talk about how do you manage this heap memory and we will do a
detailed example. And in this example, we will talk about a class for representing text strings
and this will be useful in storing the names of students, the problem with which we started
this lecture.

(Refer Slide Time: 3:26)

So, let me begin with what you already know. So, you already know the activation frame
memory. So, how do we define variables, well so far the idea has been that the programmer

906
will give the variable definitions in the text of the main program, or of some function as well.
And the memory for these variables will be allocated when control reaches the variable
definition statements.

And the memory will be allocated in the activation frame of the current function. And it will
also be deallocated, well it will be deallocated when the control exits the block containing the
definition. So, it could be exiting the function, it could be a ‘for statement’ whose control
variables might be getting deallocated. But yes the variable will be deallocated as well and
there is a very clear point where the variable is going to get deallocated. Now, variables
which are created and destroyed in this way are called automatic variables.

Automatic because the memory allocation and deallocation sort of happens automatically,
well, I mean you could say that the user is saying, user is defining the variable and therefore,
it is getting created, yes. But at least the deallocation is the sort of. I mean it is indicated by
the end of the block. But anyway so because the user is not explicitly asking for memory, at
least the user is not explicitly giving up memory these things are called automatic variables.

(Refer Slide Time: 05:31)

In addition to the activation frames, we also have this so called heap memory. So, this is a
completely separate reserved region of memory. Completely different from the activation
frames and in this memory, it is possible to explicitly request, say, give me some memory for
a certain variable and that memory will be given from the heap and we will be saying that this
variable has been allocated to the variable on the heap, whatever.

907
And when there is no more use for the allocated memory the program or maybe the
programmer must explicitly return the memory to the heap. So, the program there must be a
statement in the program which will say okay now I do not need this memory take it back,
put it back and maybe give it to me later if I ask for it again. So, after the memory is returned
it can be used to satisfy other memory allocation requests that might come up with the future.

Now, as you can see, there are explicit statements which say that give me this memory or
there will be an explicit statement which says, “No! No! Take this back.” And so, therefore,
this memory is not automatic in any sense. And even the deallocation is explicit, it does not
happens just because of block is exited by the control.

(Refer Slide Time: 7:01)

All right, what had we discussed so far? Well, we have defined the problem being how to
efficiently use memory for storing entities with varying sizes. And we had said the solution
will be provided using heap memory, which is separate from the activation frame memory.
And next we are going to talk about how to use the heap memory but we will take a quick
break.

908
An Introduction to Programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-22 Part-02
Representing variable length entities
Heap memory basics

(Refer Slide Time: 00:20)

Welcome back. In the last segment we started off by defining a problem that we wanted to solve
which is how to efficiently use memory for storing entities with varying sizes. And we said that
there is something called heap memory, which can be used to implement solutions for such
problems. In this segment we are going to use this heap memory, we are going to see how to use
this heap memory.

909
(Refer Slide Time: 00:47)

So, let us take an example, we want to store a book object on the heap, so here is our book
object, so it is a class book, char title and there is price, maybe I should call it struct because I am
using the internals the members directly, so perhaps I should called it struct but anyway. So, I
can declare a bptr to be a pointer to a book object.

So, right now bptr is not does not contain a value, I am just defining that variable. Now, here I
am assigning a value to bptr and this is a new statement, so this says bptr equal to new book, new
is actually an operator and this operator asks for heap memory. The syntax in general is going to
be new followed by the name of a type. And what this causes is that memory for storing one
variable of type T is allocated on the heap, is reserved on the heap and the statement new T or
new book returns the address of the allocated memory. So, the address of that allocated memory
comes back to the program and then that address gets stored in bptr.

So, bptr now has a pointer or bptr contains the address of some location in the heap memory
which has been given in response to this request. So, now, we can use that location so we can
write bptr->price because bptr is a pointer, so we go to that variable and we look at the price
member from it. And in this way we can keep using the memory as much as we want, we can
change the price, we can change the title, we can do whatever with it.

At some point, we will discover or we will decide that look I do not need this memory any
longer. So, in that case, we should return the memory back, we should tell the heap or the heap

910
manager so to say, that look I was using this memory but now I do not need it so take it back and
maybe give it to me later if I ask for it again. So, that is done by this command delete bptr, that
returns that memory back. New and delete are reserved words and they are also operators. Well a
lot happens behind the scenes for new and delete.

(Refer Slide Time: 03:41)

So, there is some bookkeeping which keeps track of which part of the heap currently in use. And
as a result of this bookkeeping you are guaranteed that in response to a new request you will get
memory that is not currently allocated to another request. Of course, if the heap is full then you
will run out of memory and your program will abort. But if it is not full then you will get that
memory.

And the same region of memory can be allocated to two requests but only if the first request
releases it using the delete before the second request is made. So, at the same time, the same
memory cannot be in use due to two requests. So, here is an example showing how the heap
memory functions and how it is different from standard activation frame memory.

911
(Refer Slide Time: 04:38)

So, in this program let us look at main, so main starts off with creating a variable q which is a
pointer to int, which is of type int star and q is being assigned the result of calling g. So, g is
called and noticed that the g is actually returning a pointer to int, int *g. So, int * is the return
type and g is returning a pointer to int.

So, what happens inside g? Well first a local variable or p is created of type int *, so this is in the
activation frame of g, then we execute our new statement p equals new int, so what does this do?
Well it places an address in the heap so it causes a location in the heap to be allocated and that
address is placed in p. So, p is now pointing to some location in the heap memory which has
been given for it. Then we say *p=5, so what does this do? Well *p takes you to the location in
heap memory and you place 5 over there. So, 5 is stored in the location in the heap memory
which was given to us and now we are returning p. So, what does return p mean?

Well whatever the value of p is returned, but what is the value of p? So, the value of p is the heap
memory address, so this heap memory address is returned. And this goes and takes the place
effectively of this call and it sits in this q, so that address goes and sits in q. And now when we
print *q, what is happening? So, q at this point contains an address in the heap memory which
was allocated over here. So, *q is, q is pointing to that same address but into which we had
stored a 5 over here. . And therefore if you print *q it will print 5. So, at this point we have

912
discovered that we do not need q any longer or we have decided that we do not need q any longer
and therefore we are going to delete q.

So, notice that there is something unusual going on from the point of you of what you have
known so far which is that some memory got allocated over here and it stayed across this
function call boundary and then it was used in the main program and then it was deleted in the
main program. So, this is clearly very very different from the way the memory allocation
happens on the activation frames.

(Refer Slide Time: 07:43)

You can allocate arrays on the heap and so again let us say cptr is a pointer to characters. Now, I
can say cptr equals new char 10. So, this will give me an array of length 10, an array of char.
And now I can start accessing the array as usual because after all the name of the array is an
address, address of the starting and cptr also is an address, address of the starting point of that
array, so I can get the usual variable cptr[0], cptr[9]. So, the array elements I can just access in
this manner.

After I am done with the heap I can write delete[]cptr, so this causes the allocated array to be
deleted. So, note that it is not just plain delete but it is delete[]. Alright so now we have pretty
much, we are pretty much in control of the situation so our problem was storing many names and
now we are able to do so. So, let us see how.

913
(Refer Slide Time: 09:05)

So, let us say we want to store 100 names and so I am going to define an array of pointers,
pointers to char. So, I have an array of pointers and initially I have not put anything in it. So, let
me draw it pictorially, so this is my array names and let us say this is 0th element, first element
all the way till the ninety ninth element. So, what happens next? So, I am going to go over all the
elements of this array and I am going to have an iteration corresponding to all the elements of
array and in the iteration, I am going to read in something into the buffer, I am going to read in
the names into the buffer.

914
(Refer Slide Time: 10:08)

Then I am going to calculate the length, so say on the side over here I have this buffer into which
I read in something and as usual there will be a null after that. And now I am going to call a
function “length” which is supposed to return the number of characters till the null. So, in this
case it should return 3.

So, this function we have discussed earlier or we have discussed something like this earlier and
this function is also discussed in the book, but it is a very simple function so you should be able
to write it very very easily. So, it just returns how many characters there are until the null. And L
is set equal to that length plus 1.

915
So, what is the idea here? So, we want to move, we want to allocate an array of just the right
size, so L is going to be just the right size, because in that array we want to store the name that
we just read but we want to append a null character to it. So, the plus 1 is so that we can append
the null.

(Refer Slide Time: 11:28)

And now we are going to allocate space. So, names[i] so in general let us start form 0 so this is a
pointer. So, this is of type char *, so it is going to be pointer to a character. So, we are going to
do in this statement over here, we are going to do names[i] or say names of 0 in this zeroth
iteration equal to new char L. So, there is some heap somewhere over here and from that heap I

916
am going to get an allocation of an array of say in this case if L is 4 because there are 3
characters plus one then I am going to get an allocation of size 4 and the address of this is going
to be put in over here.

So, typically we do this, draw this by making an arrow saying that whatever is here is pointing to
this. So, it really says that contained over here is the address of this location, so we have just
allocated space for storing this in the heap and we have a pointer to that from our names array.

Now, we simply are going to copy, so we are going to copy from the buffer, so this is our buffer,
so from this we copy into this. So, whatever these three letters were followed by a null is going
to get copied over here. So, this is our buffer and this is names[0][0], names[0][1], names[0][2],
names[0][3].

So, what is happened over here is that we read a name, we allocated space for it plus 1 so that we
want to pad in the null and then we copied that into the name into the newly allocated space and
this we are going to do for all the 100 names that we want to work with. So, that is it, so that is
the program. And so I guess it is a good idea to see what the final result is going to look like.

(Refer Slide Time: 13:36)

So, this names array, so this is going to be present in the activation frame. So, if this is the main
program then this array is going to present in the activation frame of the main program. And this
however is present in the heap memory and similarly from here another array there will be a

917
pointer to another array maybe this time the name is long. From here there will be another
pointer to another array and so on.

So, from each element of this names array, there will be a pointers to arrays in the heap memory.
So all of this part is stored in the heap memory. Now, in this case I have not shown you the
deletion but of course you can write a loop and again once you are done, you can delete, delete
all the variables and give back the memory to the heap.

(Refer Slide Time: 14:43)

918
So, this is the solution that you were asking for and we have just about used the memory that we
needed, we used one null character extra for each name. So, that is very minimal. And what is in
the activation frame of main and what is on the heap we already discussed that.

So, in the heap memory all the arrays storing the names are there and in the activation frame the
array names itself which is, which contains the pointers is in the activation frame.

(Refer Slide Time: 15:22)

Alright, so what have we discussed in this segment? So, in this segment we talked about how to
use the heap memory. In particular, we have talked about new and delete operators. And then we
talked about a solution to our the problem with which we started the lecture and we showed that
using new and delete, we can in fact store all the names in reasonably small amount of space and
then we can get to those names quiet easily as well.

Now, it turns out that while this solution is acceptable, it is actually quiet tricky to use the new
and delete operators and so we need to really evolve something more than just these two
operators, we need to have some scheme, some policy for using new and delete and there are
some difficulties in it, some pitfalls. And in the next lecture we are going to talk about these
pitfalls but before that let us take a short break.

919
An Introduction to Programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 22 Part-3
Representing variable length entities
Pitfalls of using heap memory
Welcome back. In the last segment we discussed the basic primitives for dealing with the
heap memory and we use them to solve a particular problem. Now, we are going to discuss
the issues in using the heap memory and what kinds of pitfalls there are. So, on the face of it,
it seems, and I guess it is true that the allocation and deallocation is syntactically quite
simple.

(Refer Slide Time: 00:44)

There are sort of simple commands which allow you to allocate and deallocate. Experience
however shows that managing heap memory is tricky and lots of errors are made in the
management of heap memory. So, these range from some very obvious ones to less obvious
ones say for example, you may forget to deallocate or delete memory. What does that do?

So, you allocate a lot of memory, you do not delete it and then if you yourself want more
memory then there is nothing left in the heap, so although you have some memory which you
are not using and which have not realized that you are not using since you did not return it to
the heap, the heap is unable to give you memory. So, that is sort of a basic problem, so as
soon as you are done with the memory that you need it you should return it back so that you
can get it later on when you actually wanted.

920
Another problem is the so called Dangling reference problem. This happens if you refer to
memory that has been deallocated. So, you got some memory, you are using it, you returned
it and you are still referring to it.

So, because you returned it, it might have been given to some other request and therefore you
might be destroying the data which or it might be reading data which was not really data that
you thought was present in that location and you can also do something called a Memory
Leak, which is that you destroy the only pointer to the memory allocated on the heap before it
is deallocated, before it is explicitly deallocated. So, we will talk about all these three in some
details.

(Refer Slide Time: 02:47)

So, let us take an example, suppose I have int *iptr. So, iptr is a variable which contains
which is expected to contain pointers to integers. So, I make it point to a new integer, I make
it point to a space allocated on the heap. I store 5 into that space then I delete that. Then I
write some code which could be a long piece of code but let say it does not involve iptr and
after that I again store 10 into that address by dereferencing iptr.

Now, this is not correct, so you did have iptr did have a memory location which was given
from the heap but now so it was given here but you returned it over here and you did not
acquire it again and place it into iptr. So, therefore the location that you are pointing to is not
really what you think it is, it is not your location and so you should really not be using it.

921
So, this reference iptr points to memory that has been written and it should not be used so
therefore it is called the dangling reference and it is wrong to dereference a dangling
reference as has happened over here.

(Refer Slide Time: 04:23)

So, let us talk about memory leaks. So, again we have this iptr which is a variable for storing
addresses of integers, so we acquire memory and get its pointer into, get its address into iptr
and immediately we acquire more memory and get that address also into iptr. Now, clearly
this is wrong. So, the memory allocated in statement 1, its address was stored say let us call it
A was stored in iptr but in statement 2, this A got overwritten.

So, now the memory allocated address A cannot be used by the program because we do not
have any address, we do not have its address. On the other hand, we did not delete that
memory before destroying the address and so the heap allocation functions, the heap manager
thinks that that address has been given to us. So, now that piece of memory is has become
useless because it does not, we cannot use it and the heap manager cannot use it. So, such
memory is set to have leaked out of our system and obviously you do not want such leaks.

922
(Refer Slide Time: 05:49)

Here is another way a leak can happen. So, I have a block inside which I have a variable
declared iptr. It is again of type int *. So, again I allocate an integer and get its address into
iptr but say the block ends exactly at this point. What happens now? So, when the control
exits from the block all the variables which you were declared in the block are destroyed.

So, after the control executes this and comes out, there is no iptr, so that means the contents
of the iptr are gone. So, I had written down the address on some piece of paper and the paper
is no longer there so I do not know that address, that is exactly what has happened. So, iptr is
a destroyed and so nobody can use the memory allocated in statement 1, so we cannot use it
because we do not know the address and the heap manager thinks that it is given to us so
therefore the heap manager cannot used it either. So, the memory at address A has become
unusable.

923
(Refer Slide Time: 07:14)

So, here is simple strategy for preventing memory leaks. So, what is the strategy? So,
suppose a certain pointer variable ptr is the only variable that contains the address of a
variable allocated on the heap. So, clearly we must not store anything into ptr and destroy its
contents. Because that could exactly be a memory leak.

If ptr is about to go out of scope, say because control exits a block in which ptr is defined we
must execute delete ptr. So, these are two rules that we have to keep in mind. So, if we keep
in mind these two rules then we will be sure that there are no memory leaks.

(Refer Slide Time: 08:11)

924
Likewise, there is a simple strategy for preventing dangling references. So, here is sort of
reason why we get dangling references. We saw one but this is out of more general thing. So,
let us say there are two or more pointers, say just say two for example and let us say they are
aptr and bptr which point to the same variable on the heap and we execute delete aptr and we
do not realize that bptr is also pointing to that same memory and therefore we should not be
dereferencing bptr either.

So, but suppose we do dereference bptr and we get to that memory then that is a dangling
reference which we have dereferenced and of course we could have a dereferenced aptr itself
so both are not good.

So, what should we do? A simple way to avoid this is to ensure that at all times, each variable
in the heap will be pointed to only by one ptr. So, there is this case is not going to arise that I
deleted the memory using this pointer but I did not realized that some other pointer was also
pointing into the same memory but of course, if I deleted the memory using this particular
pointer I should also make sure that I do not use this particular pointer and dereference it
subsequently.

That is relatively easier to implement of course you can forget but at least that seems easier
than saying, ‘oh there could be some 5 pointers to the same location on the heap’ and do I
really know which those 5 pointers are? So that is little bit tricky. So, to avoid that situation
we are going to say that at any time each variable on the heap will be pointed only by one
pointer and this is not the only possible strategy, more complicated and more efficient and in
some ways better strategies are possible, but this a fairly good reasonable strategy.

925
(Refer Slide Time: 10:32)

So, what have we discussed? So we have talked about memory leaks and dangling pointers.
And we said that to avoid this we should ensure that each variable allocated on the heap is
pointed to by exactly one pointer at any time. If aptr points to a heap variable then before
executing aptr equal to something changing its value we execute delete aptr, if aptr points to a
heap variable and if control is about to exit the block in which aptr is defined then we execute
delete aptr as well.

So, this is the strategy and this strategy requires us to remember things but fortunately we can
automate it so, that we do not really have to remember all of these things. So, at some point
we have to remember and we have to put them into codes such that code will be
automatically executed and how that happens, we will talk about in the next segment but
before that we will take a quick brake.

926
An Introduction to Programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-22 Part-04
Representing variable length entities
Automating memory management

(Refer Slide Time: 00:21)

Welcome back. In the previous segment we discussed a strategy for preventing memory leaks
and dangling pointers. In this segment we are going to see how this strategy can be automated.
So, we are going to do this by actually implementing the automation process. So, towards that
we are going to define a class called String, which will be a class for representing character
strings.

927
(Refer Slide Time: 00:47)

What we want to do is, we want to be able to store character strings of arbitrary length into
objects of this class and we should be able to pass strings to function, we should be able to
concatenate them, we should be able to copy them and we should be able to index to get the
individual characters of the string. And all this we should be able to do without worrying about
allocating memory, memory leaks, dangling references and things like that.

(Refer Slide Time: 01:16)

All right, so what exactly are we wanting and what freedom do we have? So, let me sketch that.
So, let me begin with a sample program, so here is a sample program. So, in this we are

928
assuming that this string class has already been implemented and so we are saying that look we
want to create instances of that String class and then we want to assign values to that String
class. Then here we want to index into this a. So, we want the first element, so if a is pqr, then
this is the zeroth character, this is the first character, so they should print q.

Then there is a block over here, so because there is a block I can define another b inside. So, this
b should be set equal to a+a. So, it should be set equal to a+a and what is a+a? Well a plus a we
would like it if it means the concatenation of the left operant and the right operant. In this case
these two a’s are the same operants. So, it should be concatenation of this, so at the end of this,
this b should be pqrpqr.

Then we should be able to print this b. So, there should be a member function print and then
afterwards after we exit from this block, we should be able pass our object to a function. So, this
is an argument to the function and if this is a pass, if this is a call by value then this value should
get copied to the parameter of this function f. Alright so now this is our program.

So, let us see, how C++ executes it. So, how does C++ view the various statements and what is
sort of that the normal way of executing something like this. So, first this string a, b. So, the way
the string a, b works is that C++ cause the constructers on a and b. So, we should be writing the
constructers and therefore we should be able to do whatever we want when the statement
executes. So, this is relatively simple.

Now, the next statement is a=b=”pqr”. So, how do you interpret this? Well these are operators
equals to are operators, so this operation equal to, if there are several this is right justified. So,
first this operation happens, so the way that happens is that this becomes the receiver. There is an
operator equal to function and that is called with this. So that is what this is and then the result of
this has to be assigned to this a, and so a is acted upon the operator equal to, but with the result of
all of these things.

So, C++ will do this. C++ is going to allow us the flexibility of defining these functions
operator=. So, the operator= functions should make copies, may be allocate memory. Whatever
is needed can be done inside those operator equal to functions. And we have to do that and we
have to also make sure that while doing that there are no memory leaks and there are no dangling
references.

929
So, proceeding along in this program we have this a[1] if you remember we said that a[1] is also
an operator expression. The operator b in this square bracket, so this C++ reads as a operated
upon by the member function operator square brackets with the argument being 1. So, again
whatever we want to happen as far as evaluation of this a square bracket 1 is concerned we
should put in a operator square bracket.

Then there is a+a the new part there is of course the assignment but that is leave it alone for the
minute, this is the new part and a plus a is again as far as C++ is concerned a dot operator a with
argument being a. So, this a is the receiver, this a is the argument.

So, if we want this whole thing to produce concatenation then we have to define this operator
plus member function suitably. Then b dot print is there but b dot print is fairly standard we just
have to have a member function, so this should not be too difficult, we just want to print it. But
now there is this exit we are exiting the block.

So, at this point we want b to be destroyed. So, as we have said earlier that all the variables
which are created inside a block will be destroyed at the end of the block. For this C++ also has a
special member function that special member function is called the destructor and that is written
by the symbol “~”. So, ~b is the call that is made and that call is the destructor call.

So, again if you want something to happen over here then that can be put in the destructor call
and let us take a quick look at this would we want something to happen over here? Well here b
has been assigned a value. So, presumably we allocated some memory. So, when we exit that
memory should get deleted and that deletion we are going to put, the core for the deletion, we are
going to put in the destructor of b.

So, any memory that was associated, any heap memory that was associated with b should be
deallocated when the destructor gets called. If we do not do that and if we just destroy the
variable b then we will have a memory leak.

Finally, we come to this call f(a). So, f(a) is let us say it is a call by value in which case this a has
to be copied over to the parameter of the function f. So, a is passed as argument and copy of a
has to be made. And this copying C++ does using something called a copy constructor. Well that
parameter is being constructed and it is being assigned a value the parameter is a variable of the

930
same type as a. And so that parameter is being constructed and its constructed with a copy of a
and therefore this kind of this is called a copy constructor.

(Refer Slide Time: 09:03)

So, we will see this in a minute. Alright so the overall plan is as follows we will define the
constructor, assignment operator, square bracket operator, plus operator, destructor, print
function, copy constructor to do their own work which is say the indexing operator must get the
appropriate character. But while doing all of these things, or say the plus operator should
concatenate the strings. But while doing these things if some memory management is needed
those corresponding functions should do that memory management as well. And thereby we
should be preventing memory leaks and dangling references. So, that is the plan.

931
(Refer Slide Time: 09:54)

Here is one more basic idea that we will need in order to do this implementation. So, we will
store the string itself. The string that is going to go and sit inside this assign to this variable that
string itself will be stored on the heap while we maintain a pointer ptr to it inside our class.

So, the idea is that if we store pqr in b, what we are going to do is inside the object b, we will
have a pointer to the heap and pqr itself will get stored on the heap and whenever we store
strings, we will terminate them with the null character. And this is always done so that we do not
have to keep the length of the strings around, the sentinel null will be enough.

932
(Refer Slide Time: 10:57)

So, our object that we design for a string class is going to contain one member ptr and this is
going to be pointing to the heap if there is something in this. If there is nothing in this, then this
will be set to null. Null is also zero but never mind that, we are always going to use null so that
we know that we are talking about pointers.

And this capital null means the pointer really is invalid. So, to avoid dangling references and
memory leaks, we will ensure that each ptr will point to a distinct char array on the heap. Before
we store into ptr, we will delete the variable it points to. And when any ptr is about to go out of

933
scope, we will delete the memory that it points to. So, other designs also possible, one of them is
given in Appendix G of the book. But we will just discuss this simple design.

(Refer Slide Time: 12:00)

So, here is the definition of the class string. So, it contains this ptr and it is a pointer to char and
then it has these public methods or public member functions. So, there is a constructor may be
more than one constructor. So, the very basic constructor is going to just set the ptr to be null that
just says that if I just write string a as I had written earlier, string a semicolon then the ptr
member of a will be null indicating that a is empty.

Then we wanted a print function, we wanted to be able to say print, a.print, so that we can
immediately define. So, all we have to do is, we have to print the characters that ptr points to. So,
let us be a little bit fancy and let us check if ptr is not null in which case we just print everything
starting from ptr till the null character.

Otherwise we will print out a message “NULL”. So, there could be, you could have done other
things, you could have put out full sentence whatever it is. So this is we have defined one
constructor and we have defined one very simple member function but there are lots of other
things to be define. So, that is what we will do next.

934
(Refer Slide Time: 13:42)

Alright, so what we have we discussed, we said that we wish to design a string class which
supports assignment, concatenation, indexing and all of that. And then we took some decisions
regarding how to design it. So, we said that there will be only one data member in the class
which is a pointer. The pointer will point to the heap memory, to the position in the heap
memory where the actual string will be stored and that string will be stored there null terminated.

We will write all the other member functions, lots of other member functions that are required
say constructors, we will overload the assignment operator, the square bracket operator and all
such things to accomplish the required operations and also the required memory allocation and
deallocation. So, in the next segment we are going to talk about the implementation but before
that we will take a short break.

935
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 22 Part – 5
Representing variable length entities
Implementing a class with automated memory management 1

Welcome back.

(Refer Slide Time: 0:25)

In the last segment we made a high level plan for designing our string class. Now, we are going to
jump into the implementation of it.

(Refer Slide Time: 0:27)

936
So, let us start off of it. A=pqr. So this is an assignment statement. We want the character string pqr
to be stored in our string variable a. How should that happen? Clearly, as we said a.ptr should be
pointing to this string pqr. And our rule was that a.ptr should point to things on the heap. Now,
since, we said that we cannot immediately just directly set a.ptr to “pqr”, after all we know pqr we
know that pqr is a cons char ptr. So, we cannot just write a.ptr equal to what that pointer is because
we decided beforehand that the member ptr will point only to the heat.

Why are we doing that? Well, if we know that is only going to point to the heap memory then we
can delete it. If we do not know that, if there is a possibility that sometimes maybe it points to the
heap the memory, sometimes it points to activation frame. Then we cannot delete it. And therefore,
in order to be able to delete it confidently, whatever data it points to should always be on the heap.
And therefore, we must first copy the character string constant to the heap.

All right! So, that is the first consideration that we must copy pqr to the heap because it in general it
may not be on the heap. But then there is also another consideration, a.ptr, we want the set to point
to this pqr but it is already pointing to some variable in the heap. That is what our convention is,
well unless it is null but in general, it could be pointing to some variable on the heap. So what do
we do?

We are making a.ptr point to something else so this variable that it points to is going to be useless
and therefore, we should be deleting it. Why is that? Because we are guaranteed that no other
pointer points to that variable. So, therefore, we can just delete, delete a.ptr.

(Refer Slide Time: 3:01)

937
So that is all there is to it. So, the way the implementation works a=”pqr”, for a=”pqr” we should do
what I just said, but the way to do it is that, this statement, for this statement C++ makes a call to
a.operator=. To operator equal to with a being the receiver and pqr being the argument and so
whatever I just said has to be put inside this function. So, we have to overload this function. So,
what are the types of argument?

What is the type of the argument to this member function operator=? Well, so this is a character
string constant. And we know that this is represented by a variable of type const char * and whose
address is the starting address of this array. So, the member function operator= will have a
parameter constant char * so we can just, so this call will be a valid call, then what value should it
return? So, this is a little tricky.

Now, a=”pqr” wants us to assign pqr into a. But if you remember we can chain assignments, so
what does that mean? We can write something like b=a=”pqr”. So, if this assignment operator is a
part of this expression then this assignment operator is supposed to produce a value. And that value
should be returned by the member function operator=. So what is the value that it is that this is
supposed to produce? Well it is supposed to produce a reference to this a itself. So, from which we
can pick up the value. So, the return value should be the left hand side. So, it should be this a itself
and the return type must be a reference to string because a has type strings, so we should be
returning a reference to that string.

938
(Refer Slide Time: 5:31)

So, here is the code. So, we have, we are defining a member function operator=, in the string. This
will go into the String class and it will take, so it will be operating on, it will be operating on a
string, a string will be the receiver and it will be receiving an argument a character string constant.
So, some a variable of type const char * and let us call that variable RHS. So, first of all we said
that, if we are implementing this so we are changing a.ptr.

So, a is the receiver, we are changing a dot ptr, so whatever a dot ptr is pointing to should, should
be deleted but since is the receiver then this is just ptr. Remember that if a member appears here
without any qualification then it is just the pointer member of that receiver. So, we are going to
delete that ptr. So, effectively what has happened now is, that we were assigning, we were
executing this statement.

939
The memory that a was pointing to, a.ptr was pointing to has now been returned back to the heap.
Now, we said that we have to make a copy of this pqr on the heap. So, how do we do that? Well, we
are going to allocate an array of size length of this rhs, so for pqr it will be just three plus, one byte
to store this, the null character. So, how do we do that? So in section 15.1.4 we had this length
function, which we talked, which you mentioned earlier.

And we just call that, so length of rhs will tell us how long rhs is, we add 1 to that and we allocate
an array on the heap. So, new does that and its address is put into pqr. So, this is the array that has
been allocated. We have not yet moved the data into it. So, this whatever that string constant rhs is,
it only its length has been used up. The data actually has not been used up. So the next step is to
actually do the call.

So, again we had this scopy function which is very simple, which actually just copies every element
of this into this until we reach the null and the null is also copied. So, there is a simple loop but any
you can get that function from this section. And finally we are going to return this receiver itself, so
remember a=pqr got translated into a.operator=(“pqr”). So, this is the receiver and we want to
return the receiver. And here is how we return the receiver. So, this is a special word in C++.

(Refer Slide Time: 8:57)

So, let me just explain that to you. So, this is a C++ keyword and inside a member function, this is a
pointer to the receiver. So, star this would mean the receiver itself.

940
(Refer Slide Time: 9:14)

So, here that is exactly what we want. We want to return the receiver itself. Why are we not
returning a pointer? Because this says that we want to return a reference. This says we want to
return a reference, and the references, references are to variables, so here we should not be having
pointers but we should be having references, so then reference can be picked up. So, we should
write star this over here.

(Refer Slide Time: 9:40)

So, this is a key word and this would mean the receiver itself, and the value of an assignment var
equal to expression is var, so the assignment must return var as a result and hence, the return value
is *this.

941
(Refer Slide Time: 9:54)

So, that was assigning a character string constant to one of our string variable. But we would also
like to be able to assign one of our string variables to another of our string variables. So, we want to
allow code such that, a=b, a=”pqr” and b=a. Alright? So, how do we do this? So, the statement b
equal to a is going to call, is going to be looked upon by C++ as the statement. So, it is the object b
and we are making a member function call on it, so b is the receiver and argument is a.

So, this is another assignment and it is very similar to the assignment that we made earlier, except
that now the argument is not char *, but it is a string variable. And if you want to get the actual
string that we want copied, we have to go through its pointer, so we will do that. We want a
member function operator, which takes string as an argument. We already have a member function
which takes char const char * as an argument but we can have another. So, we can overload, we can
have more functions so long as the signatures are different.

942
(Refer Slide Time: 11:27)

So, this time we have string reference returning, being returned, name of the member of function is
operator equal to in the class string and the argument this time is not const char * but const string
&rhs, so I could have had rhs over here but I do not really want unless is recopy and therefore, I am
going to just get a reference to it. So, we have to be a little careful in all of this. And in principle,
our programmer is allowed to write something a=a. So, a=a is really nonsense, but it is not
disallowed and therefore, we had better deal with it.

So, the best way to deal with things like this is just make a special case, so what we are going to say
is, if this if the receiver is the same, if the address of the receiver is the same as the address of the
right hand side, then that means we are in this situation. So, in that case we have nothing to do but
we can just return this object itself. And, of course, reference to that gets returned, but we are
returning this object.

943
So, suppose, for now rest of the code that the receiver is different from this right hand side, so we
are in a situation not like this, but we are in a situation like whatever a=b, where a and b are
different strings. In that case, as argued earlier we are going to change ptr and if ptr points to
something and ptr will be pointing to something, we have to release that memory, so for that we
have to issue delete ptr and delete ptr is fine even if ptr is null by the way. So, that is not an issue.
But if ptr is not NULL then we have to return that memory back to the heap and that is what this
statement is going to end up doing then, as before we are going to make a copy of the string in the
rhs on the heap. So for this, as before we will allocate length which is rhs.ptr, length(rhs.ptr)+1, that
1 is again to store that null ptr. And this is done quite easily by a very similar statement as before,
length of rhs.ptr+1. So, that much memory we are going to allocate on the heap. And we are going
to copy, we are going to copy the memory that rhs wants to the string that rhs is, rhs contains is
being now copied to the receiver as well. So, ptr which is the receivers pointer the address that it
points to, will now contain, whatever is contained in rhs.ptr.

So, for this we again use the scopy function, so it just essentially transfers characters from, copies
characters from here to here at corresponding displacements and finally, again as before we are
going to return this, the variable that this point stores. That is it.

(Refer Slide Time: 15:08)

So, what have we discussed? We have discussed how to implement assignment operator, so I
should by suitably defining member function operator= and we define two member functions,
operator=. One which takes as argument const char star and another which takes as argument
another string object. In the next segment we will be talking about the implementation of the other
operators but before that we will take a quick break.

944
An Introduction to Programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-22 Part-06
Representing variable length entities
Implementing a class with automated memory management 2

Welcome back! In the last segment we saw implementations of two assignment operators for our class
string. In this segment, we are going to look at implementation of other operators. So, first the Square
bracket or the Indexing operator.

(Refer Slide Time: 00:37)

945
So, if we wish to access the individual characters of the stored character string, we need to define this.
So, as we know if what has been written in the program is a[1], this is read by C++ as a.operator[],
operator square bracket operating on 1.

So, this operator must be overloaded and that overloading is quite simple. So, the receiver has a certain
string and we want character 1 from it and where is the string of the receiver? It is at a.ptr, so we just
have to get character one from a.ptr, that is that is about it. So, we do not have to write a in this because
the receiver is implicit. So, this is going to be the receiver's ptr and we are going to take a displacement
of i from it.

So, that is about it, and notice that we are returning a reference. So, we are returning a reference
because that way, we can change the character as well. So, we would be able to write something like,
suppose we have a and a is pqr then we can write a[0]=a[1]. So, this a of 0 will also be translated or
will also be interpreted by this operator. So, this will return reference to a[0] , so a[0] is a variable and
it will be a reference so it will mean that variable itself, it will not mean the value. So, that variable
itself will appear here so to say and therefore we can store into it.

So, that is why we are returning a reference rather than a value. So, if we do this, then if we have this
defined and if we write this and we are allowed to write this, then this will cause a to become pqr.

(Refer Slide Time: 03:05)

Now, there is an interesting operator Concatenation so for which we are going to overload our plus. So,
we would like a+b to mean the Concatenation of a and b. So, you must create a new string first of all
on the heap and store the Concatenation into it.

946
(Refer Slide Time: 03:12)

So, how does that work? So, we are going to return a string this time, so the result is going to be a
string and our operator plus is going to be overloaded. So again, let me just remind you, a+b becomes
a.operator+(b), so therefore we need to redefine or we need to overload this function operator plus. So,
first we will create this string which is which is going to eventually contain the result and into that
string we are going to store the result but this string has its own pointer and that pointer must point to
the heap and how many elements, how long an array does it need on the heap.

This array must contain the string from a as well as the string from b or looking at it here it should
contain the string from the receiver as well as the string from the right hand side. So, the space needed
must be the length of the string pointed to by ptr, as well as the length of the string pointed to by the

947
rhs.ptr and a 1 so that we can append the null character to it. So, we have allocated the space needed by
writing this new thing and now we just have to copy.

So, this s copy that we had earlier is going to copy whatever is in the receiver into this result, the result
area that we have created. This is created on the heap ofcourse and then we have to copy the rhs string
as well so the same scopy is going to be used but we have to tell scopy that, look I do not want it
copied from the very beginning as what this would be doing, but we want to copy it from index
length(ptr). So, we want to copy from res.ptr index length of the ptr, length of the string that we just
copied. We are going to call s copy but this time we are going to give three arguments.

So, this is the destination , this is the source , what we want copied and this is the displacement in the
destination from where the copying has to begin and you can write this but this function is also given in
the book in that same chapter 15. and finally res will be returned.

(Refer Slide Time: 06:04)

So, the result of this will effectively be replacing this expression, so there will be a temporary which
will be replacing this and you can do whatever you want. So, you might have c=a+b so that then the
temporary will be assigned to c but this evaluation will result in a temporary which contains the
Concatenation, so that is it. So, that is the Concatenation operator.

948
(Refer Slide Time: 06:39)

Now, we need the destructor as well and we talked about it but let us just do this again. So, suppose we
have this code which we had in the program that we have written. So, at this point string b is created
and at this point string b goes out of scope. So, when string b goes out of scope, C++ is automatically
going to call the destructor ~String , so I should really say the destructor in the string class , so that will
get called and it will be called on the receiver so it will be ~b actually the call will look like ~b.

So, what do we want to happening over here. So, by the way there is a default destructor and the
default destructor does nothing and we are going to change it. So, we should delete b.ptr to prevent
memory leaks, so how do we do this? So, our class is going to contain this , the our destructor is going
to have delete ptr inside it, that is about it. So, this is what will happen if b goes out of the scope over
here then it is as good as calling ~b and this is the call that is going to happen.

So, this is the body of the call and b is going to be the receiver and so ptr, the ptr of b is going to be
deleted. So, whatever memory b was pointing to will get deleted exactly as we wanted and as I said
earlier this works even if ptr is null and in this case the delete does nothing.

We also need to write the copy constructor. So, remember that in our program we were calling some
function f with a string object a as the argument. So, how does C++ handle it?

949
(Refer Slide Time: 08:50)

The copy constructor is called by C++ to copy a string object to the parameters. So, this string object is
copied to the parameter in f and that copy is a is little bit of special copy, it is not just like an ordinary
assignment it is a little bit more special than that and we will see in what way it is special and therefore
C++ has a notion of a copy constructor. So, the copy constructor looks like this.

So, it is a constructor, and therefore there is no return type and it is constructing, so here we are going
to use it to construct that parameter in f and so it is going to take one argument which is the object from
which we are supposed to make the copy. So, in this case argument is going to be a and rhs is really
going to be a when this code gets executed and the receiver will be the variable which is the
corresponding parameter in f.

So, what happens? Well, ptr which is the receiver's ptr is going to be assigned, is going to be made to
point to the string that rhs contains. So, first it must allocate some memory and that is what we are
doing over here and its length should be adequate for getting a copy of this. So, rhs.ptr length plus 1 for
the sentinel null. After that we are going to make a copy, the actual copy and that is about it.

Notice that we did not delete ptr as we deleted in the case of the other assignment operations because
this ptr is the ptr of the parameter of f which is of type string , so that is why we are copying this
argument to that parameter , but this parameter is just been constructed as we speak and therefore it is
not pointing to anything at all, so we do not have to delete ptr. And likewise there is nothing to be
returned because this is a constructor and so in the assignment we were returning something, so the
code looked a little bit more complex but here there is no chaining that might be needed and therefore it

950
is just going to be copying from copying from this a to the parameter inside f and just this is necessary.
So, this is the core code of the assignment statement but before that we had to delete ptr in the
assignment statement and then we have to return the object this object itself but both of these things are
not necessary as far as this constructor is concerned. So, this is the code which is used to copy an
argument to a parameter but C++ uses the same code to copy the result back from the called function to
the calling function and that same copy constructor is used and this code will work for that purpose as
well.

(Refer Slide Time: 12:22)

So, what have we discussed in this segment? so we have given the definitions of all member functions
needed to perform assignment, passing and returning from functions, concatenation etc for our string
objects. And these pieces of code should be inserted into the definition of the string. So, next we will
use this class to solve the problem of storing names and we will have concluding remarks for our entire
lecture. But before that we will take a short break.

951
An Introduction to Programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 22 Part-7
Representing variable length entities
Using the implemented class and conclusion

Welcome back. In the last segment we gave the definitions the complete definition of our string
class.

(Refer Slide Time: 00:25)

Now, we are going to use that first to solve the problem with which we started this lecture.

(Refer Slide Time: 00:34)

952
So, the problem was how to store many names of varying sizes. So, here is the program, so we are
going to read 100 names and store them. So, for that we are going to allocate an array of stings .So,
it should be instructive to just see what this actually does. So, in the main programme this is going
to create an array of string objects.

(Refer Slide Time: 01:03)

But let me remind you that a string object is really very simple, it just contains a single PTR, so this
that PTR. So, we have 100 PTRs really because each object just contains one PTR. So, 100 words
will be allocated in the activation frame. And this PTRs will be null by the way, at the beginning.

(Refer Slide Time: 01:45)

Then to do the reading of the names we are going to use this buffer of 80 characters. This is just
meant to be a large enough number and now we are going to read each of the 100 names. So, in this

953
loop iteration we are going to that. So, this time let us say we use the safe alternative but this will
also allow us to get in the spaces.

So, this will cause the name to be read from the keyboard new line terminated into our char array
buffer and of course inside the buffer it will be stored with a null termination and then we are just
going to assign names[i]=buffer that is it.

(Refer Slide Time: 02:34)

So, if you remember how is this going to work, names[i]=buffer. So, this is going to be viewed by
C++ as names[i].operator=(buffer). And if you remember we defined this operator equal to a minute
ago and operator equal to which takes a char array as argument. We defined that a minute ago and
so what that will do is it will allocate some space on the heap and it will start pointing this pointer to
this and it will copy whatever was in the buffer into the space.

(Refer Slide Time: 03:33)

954
So, in this code we are not mentioning things like how many characters did we read into buffer but
all that will happen as a result of this assignment, so that is it, that is the code. Now, you can use this
names array however you want, you can do whatever you want with the names inside that array.

So, again just want to point out that we have solved the problem that we started of this lecture with
the number of bytes used for names[i] will be equal to 1 plus the number of characters and
incidentally this was exactly the solution we got even in the solution that we got very early on in the
lecture, we had the same situation in the activation frame, we had an array of pointers.

(Refer Slide Time: 04:22)

Even here we effectively have an array of pointers although we called it an array of string objects,
the string objects themselves are containing only one member which is a pointer and that pointer
points to something on the heap on the names which are stored on the heap. But the beauty is that
over here in this solution, we are not talking about heap at all. We are not talking about how many
characters we are transferring, how much we are allocating and anything like that.

955
(Refer Slide Time: 04:45)

So, all this is implemented automatically. And we are not mentioning memory allocation. And we
do not have to worry about memory leaks, we do not have to worry about dangling pointers, our
implementation of string class takes care of all of these things.

(Refer Slide Time: 05:11)

956
So, I am now going to give a quick demo which uses our string class. In this program we did not
use the concatenation feature but in this demo we will be doing so, so let us take a look at that. So,
this is words, so here I have copied the length and scopy functions and then over here our string
class starts. The string class is here with the member functions.

(Refer Slide Time: 05:46)

957
So, all the operators, everything is there and this is the destructor which we also wanted.

(Refer Slide Time: 05:59)

958
So, what is our problem? So, the problem that we are going to look at is sort of a fun problem,
nothing useful by any means but just a fun problem. So, what is the problem? So, I will tell you
what are we going to do. So, this program is going to read in a number from the user first and then it
is going to print out something, so that is about what it is going to do.

So what is it going to print out? So it is going to read in a number which it expects to be a two digit
number. Actually it expects the number to be between 20 and 99, so if you type a number between
20 and 99 say you type 37 then this program will print out 37. So, it just writes the number in words
and it does this only for a two digit number but it illustrates the kinds of things that we have been
doing over here.

So, what happens here? So, first we have an array of strings by the way once we define strings then
the C++ machinery will allow us to define arrays of strings, that is no problem. So, we will have an
array of strings, one array called units and another array called tens. So, in units we are going to put
1,2,3,4,5,6,7,8,9. We could put a 0 over here as well but we really do not want to because you will
see why we are not putting a 0 and in tens again we are not putting a 0 but we are putting 10, 20 all
the way till 90.

So, what is this doing over here. So, you give me a number then I am going to extract the tens digit
from it, so that is simply z divided by 10 and then I am going to use that to index into the tens array.
So, suppose the number I type was 37 then the tens digit or 37 divided by 10 is going to be 3. So, I
am going to index into this and now that will get me my thirty. So, remember that I am supposed to
print 37, so I have now been able to get thirty from this. Then I want a dash, so dash is another
string called dash which I have assign to this character dash.

959
So, I am going to add it or I am going to concatenate these two strings together but I also want the
unit’s place, so to get the unit’s place, I just have to do z mod 10 so for 37 this would be 7. So, units
of 7 would be this, so I would get 7. So, from this I would get thirty, from this I would get dash and
from this would get 7. So, I would get thirty dash 7 concatenated which I am going to print and
since print is not putting an end line, I am going to put an end line myself. So, that is all varies to
the program.

It is kind of a trivial program but it does illustrate some ideas one of the ideas is that you can use an
array of characters to do some interesting things because you can index into that array but most
importantly I am doing this because I want to show you that here we are able to concatenate the
objects which we are storing in our string class.

(Refer Slide Time: 09:45)

So, let us compile this and run it and let us run it. So, let us see we write 37, so we do get 37. Let us
do one more, say 85 and we will get 85. But let us do something improper.

960
So, let us say we type 5. So, let us see what we got, so we got the 5 alright but that 0 in tens place
did not come as it should not have come but we did get that dash because that dash is there, so
maybe we should write we should modify our code so that dash also does not appear and of course
you really should make some special cases, you should put in some if statements to check whether
the numbers are 11,12,13,14 all the all the teens basically and for all the teens and ten itself and
11,12 there should be a special case and those cases should also be handled. .

So, anyway, so that is what this program does and as you can see it uses the capital string class that
we just created

(Refer Slide Time: 11:09)

And we are really at the end of the lecture, so I just want to make a few concluding remarks. So, our
class string performs memory allocation and deallocation behind the scenes and it happens
automatically in the sense that the user is not really aware of what is going on. Now, string variables
appear as simple as char variables.

So, when you use char variables you do not really need to worry about where are these stored or
you could think of them as being stored in the activation frame and if you want you can think of the
string variables also has been stored in the activation frame That will not really cause any major
problems. The only difference is that the string variables can contain character strings of arbitrary
length rather than chars, individual chars.

So, in the next lecture we are going to see a class from the standard library called string where s is
not capitalized and we will see that it is a richer version of our string class but the point of
discussing this capital string was to see how such classes can be implemented.

961
So, the basic idea is that these classes that we are going to see that appear in the standard library and
some of which we are going to see soon use memory allocation and deallocation from the heap and
as an example we have studied this, we have designed and studied this String class and there are
other classes in the standard library which we will discuss and one of them will directly enable you
to store polygons, variable sized polygons as was mentioned at the beginning of the lecture. So, that
concludes this lecture, thank you.

962
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-23 Part-01
The Standard Library
Class string

(Refer Slide Time: 0:18)

Hello and welcome to the NPTEL course on ‘An Introduction to programming on C++’. I am
Abhiram Ranade and today’s lecture is on standard library of C++, this is discussed in Chapter
number 22 of the text.

963
(Refer Slide Time: 0:38)

So, the standard library comes with every C++ distribution and it contains many functions and
classes that you are likely to need in day to day programming. These classes have been
optimized and debugged thoroughly. So, if you use them, they will be reliable and you may be
able to write programs with every little work. So, definitely use them if the need arises.
Definitely do not invent your own classes, but learn these classes and use them.

(Refer Slide Time: 1:10)

So, here is what we are going to do in this lecture. So, I am going to talk about the string class. In
the last lecture we talked about a class, which we ourselves designed and which we called String.

964
So this is going to be string but with everything lower case. In some sense this class is
implemented in a manner similar to our String class and in fact all the classes that I am going to
talk about, will have implementations which will need the heap memory.

Okay, so we will deallocate and allocate heap memory but yet all of those things will happen
behind the scenes and to that extent the implementations will be similar to capital String class
implementations which we had had. But, of course, these classes are going to be something
different and there will be differences as well and, in this course, as well we are not going to talk
about exactly how these classes are implemented but just to get a sense that how they might be
implemented.

Okay, we have discussed the capital String class, so we will have some understanding, all of this
will not seem like too much magic to you. So, we will talk about string class, we’ll talk about a
class called a vector class. And we will talk about classes a map, and unordered map and then we
will conclude. So, the string class from the library, okay.

(Refer Slide Time: 2:46)

So, this is a much more powerful version of the string class we developed in chapter 21. There
more constructors, concatenation using + and you can directly print out or read into the strings.
You do not have to go through, go through null terminated arrays or anything like that. And there
are operations for extracting substrings or finding one string inside another.

965
(Refer Slide Time: 3:15)

So, we are going to see some examples. This is not going to be a comprehensive discussion of
the string class, for that I will recommend that you look at the online documentation. So, to use
this class you need to include the header file string. So, here is how you might use it. So, I might
create a string and while creating I might initialize it to this string constant “abcdab”. Now, I can
write string w and in parenthesis I can write a string from which you are going to copy that
string.

So, this is another constructor, but this copies directly. So, that v is directly copied, so I could
have written this to string w=v as well, but this is another style of writing initial values. I can
write string x=v+w, so that it is just concatenation and the concatenation is put into string x. I
can index and index operations can be on both sides, so in this particular case v2 is changing to
v3 so we had abcdab before so that will now become abddab.

Here is an interesting operation, we are doing cout<<v.substring there should be a semicolon


over here, but anyway, so that the substring 2 means the substring of v starting at 2. So, this is v,
so this 012, 012 but remember we just changed this c to d. So, the substring of v starting at 2 will
be ddab. So, v, substring (1.3) says that I want a substring which starts at 1 but whose length is 3.
So, substring of v which starts at 1, so v is now this, so 0 1, so it starts at b but its length is 3, so
this will be bdd.

966
So, for this part we will be end up printing bdd, okay. Then we can find, we can look for strings
inside a given string. So, for example, I can write v.find, so this is for v and we are finding ab
inside it. So, where does ab appears, it appears at 0, so this will return 0. But suppose I execute v
from position 1.

So, this says find ab but execute it from position 1. So, this is our current v, I am not going to
start from here, I am going to start from here. So, in this case, in this case my occurrence is going
to be at 01234, so this should be at occurrence 4. So, this will end up printing 0 and 4 because i
will be set to 0 j will be set to 4.

(Refer Slide Time: 6:39)

So the find function needs an explanation, because if the find member function does not find the
argument in the receiver, then it returns a constant string::npos. So which is not a valid index. So,
what you can do, you can check whether the returned index equals string::npos. So that we know
that the string is not present.

967
(Refer Slide Time: 7:10)

So, going back over here, if we were looking for say x y, then I would have been set to
string::npos, okay. So npos probably is some negative value, for example, so which cannot be the
position of any occurrence, so that is how you can actually check that whether the string appears
or not appears.

(Refer Slide Time: 7:35)

Okay, so, a string object can be passed by value, in which case it is copied, or by reference. So, if
you are passing strings to a function, this is how you can do both. But, of course, usual rules,

968
usual rules apply. String objects can also be compared and for this, the lexicographical order
about which we talked about some time ago is used, the dictionary order. So, just to clarify
abcdef appears earlier in the dictionary, so this will be deemed smaller than this.

(Refer Slide Time: 8:15)

So here is an exercise for you. Write a function which counts the number of occurrences of one
string inside another. So, you know, in our old string when there are two occurrences so your
function should compute, you should print out both the occurrences. So, you will have to use the
find command and slightly in slightly imaginative manner.

969
(Refer Slide Time: 8:38)

Okay, Alright so what have we discussed, we have discussed some features of the string class
which is a powerful safe way for handling text data. So, you really should try to use the string
class as much as possible and avoid null terminated char arrays, because those are error-prone
and also cumbersome. In the next segment, we are going to talk about a class called vector class,
but before we do that let us take a short break.

970
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-23 Part-02
The Standard Library
Class vector

Welcome back!

(Refer Slide Time: 0:19)

In the previous segment we discussed this string class.

(Refer Slide Time: 0:25)

In this segment we will be discussing the vector class. So, the class vector is, should be thought
of as a friendlier and a more versatile version of arrays. To use it you have to include the header
file vector. You can make vectors of any type by supplying the type as an argument to the
template and we will see this in a minute. So, like arrays indexing is possible. But, there are more
things, you can extend the length and you can also insert in the middle of the arrays.

And the implementation of the vector class is sort of like the string class, in the sense that it will
also allocate memory and memory from the heap. Okay. So there will be member classes but
they will do the memory management and all that will happen automatically like the way it
happened for the string, to the string class that we developed. But, of course, the functionality of

971
the vector class is different, so there will be differences also, but this whole idea of having the
memory management happen behind the scenes is, of course, exactly like that.

(Refer Slide Time: 1:40)

So, I am going to discuss the string and the vector class also just by taking examples and again
this is not going to illustrate every feature. To do that, you should look at documentation on the
web. So, I can create a vector of integers by specifying int inside the angle braces or this is what
is called the template argument. So, if I write vector<int> v1, I get an object called v1, but it is
an empty vector.

So there are no elements yet but whenever elements come in, they will be of type int or you are
expected to put in elements of type int. So, here is a vector of strings, you can have vector of
anything, any type. So, here is a vector of strings and this time the name has an argument. So,
this really is a constructor. So, if you have a one argument constructor, it creates, automatically
creates a ten element vector of strings. The strings are initially empty, there is nothing. It is a 10
element vector of strings. Now, this has a more interesting constructor. First of all it is a vector
of shorts. So, V3 is going to be a vector of shorts. It is going to have 10 elements, but if you have
this additional argument, this additional argument says that the values of all the elements will be
300. So, v3 will store 10 copies of 300 once one per element .

I can write an assignment and I can, I can copy vectors directly just by specifying the entire
name. So, to that extent vectors are like structures and, of course, you know that vectors are
classes, so they are indeed, they are indeed structures. But they also have parts which are on the
heap, so typically the data is all on the heap. They can do indexing so v3 is this thing we defined
over here.

This vector that we defined over here and I can said the 6th element to be 34 and I can also look
at any element inside that, whatever I want. Here is a more interesting operation. I can push back
an element so this going to append 22 to v3. So, originally v3 had length 10 and it contained 10
300’s, but now it is going to contain an extra element so it going to have elements 0 through 9
plus the 10th element.

972
And that 10th element is going to be 22. Or maybe this will require some memory allocation,
unless you allocated a large amount of memory to begin with. But potentially this will require
memory allocation and that will happen behind the scenes. You do not really need to even know
about that.

I can find the size of a vector or I can also use length here if I wish. This will just print out the
current length or current size and in this case 11 will get printed out. I can change the length.
This says change the length to 9, so originally we had 0 length, so this is going to make the
length to 9 .

This is going to change the length of v2. Remember v2 was a vector of length 10. All the
elements were empty so this is going to have a length of 15. The new values will be initialized.
They will be initialized to a string consisting of 2 stars. So there are lots of, there is a rich range
of functions, member functions and constructors so you can do lots of things with very small
command.

(Refer Slide Time: 5:43)

Yeah, as I said you should look at online documentation to get the whole range of commands or
operations that are available. Now, push_back is an interesting operation because often you have
to guess the length of an array and you have to guess it and you have to allocate an array, but
with the push back, you can just keep adding elements into your vector. So the guess work is
gone. Yes push back will require increasing space after increasing the space the copying will also
happen. So, it is going to be little more expensive than just assigning a value to any element.
However, it is done very cleverly. So, it is done cleverly in the sense that suppose you exhaust
the current allocation of space and you add a, you push back one more element, so what is done
is a much larger space is given to you, not just that extra element. So that space is allocated and
you copy your current vector into this new space.

But because you get large space whenever you ask for it, your copying and reallocation
operations do not happen that frequently. And there is a way to do it just right, so that really the
effort you spend in reallocation over the entire course of the program turns out to be really quite
negligible. So, effectively push back and indexing can be thought of as a cheap operations. So,
this is one of the things which is really great with vectors that you can keep pushing back and it

973
is a cheap operation, so do not really worry about it. On the other hand, inserting elements in the
middle of vector is possible but is an expensive operation.

And you should really not do this too commonly. I mean if you are doing this too commonly,
you had better have really good reason so do not insert casually in the middle. Vectors can be
passed to functions by value, or by reference and if you pass by value, things get copied. So, if
you make a modification in the call function, then the vector in your calling function does not get
modified but, of course, if you have passed it by reference, then the modification will be
happening in your calling copy as well.

Now a nice thing about vector is that when you pass a vector either by reference or by value, you
do not have to pass the length. So this just reduces the clutter. So your functions looks, you
function calls look more compact. So, I would definitely advice you that now that you know
about vectors, just start using them. Do not use arrays. Because they are just more elegant, more
compact, more elegant, they can do lot more things.

(Refer Slide Time: 8:54)

I want to make a technical remark about vectors. So there is a member function size which
returns the size. Now, the size is returned as a type size_t. Size_t is just an alias for a certain kind
of unsigned integer type. And it is a type which is meant to, it is a type or it is a type of variable,
which is meant specially for storage array indices. Now, therefore, when you go through array
elements or rather vector elements, you should use size type for the index variable. Because if
you have a code like this, okay, here you are comparing the index with v.size. If you had
declared this i to be int, then you would be comparing an integer with an unsigned integer. Now,
this comparison is something that C++ finds a little bit error prone, because unsigned integers
have that wider range and C++ compiler writers worry that look, “Are you sure you want to do
this comparison”, that kind of thing. And therefore, instead of declaring this control variable to
of int, if you declare it of size_t you will not get that warning about this comparison between an
unsigned int and an int. So, yeah, so this is tricky as was discussed in 6.8 and therefore, the
compiler puts a warning but you do not want, when you compile you do not want any warnings.

974
You do not want any clutter and therefore, it is a good idea to just use a size_t over here rather
than an int. If you use int, it is not a big deal but it will just have clutter when you compile. Now,
the vector class can also be used to build multi-dimensional vectors, but really I have to say
multi-dimensional arrays if you will. Here is how you do it.

(Refer Slide Time: 11:18)

So you say vector<vector<int>>. Okay that is what this variable vv is. And note by the way that I
need to put a space over here. Okay. If you put these << consecutively then C++ will interpret as
the output redirection operator. Okay, so what does this nominally say? It says, nominally says
that each element of vv will itself be a vector of integer, right? Because after all what you put
over here is supposed to tell you the type of the elements of this vector. So, each element here
will be a vector of integer.

So, that means to get to the integer itself you must apply 2 integers, so v[0] will get me to a
vector of integers. If I add another index I will get to the actual integer. So, we really have a 2
dimensional over here. So, here, for example, is a definition of something which looks
complicated but which can be easily understood. So, I have a vectors of integers, that is called
v1. So, this 5 tells me how many elements this vector has. Whatever follows is supposed to tell
me the initial value of this element, okay but this element is itself is a vector of ints. So the initial
value of vector if ints is going to be a vector of int of size 10 and each element having a value 23.
So what have we done? Okay. So, v1 has 5 elements, each of which is a vector of ints and each
has length 10 having initial value 23. So what do we get at the end of this?

We are going to get a 5 by 10 array okay all elements 23. So, quite cool. Notice that this syntax
is not really new. I already introduced this syntax, but I am just using it in a somewhat elaborate
manner. Now, if I define a vector like this, I can get how many rows and columns in it, are in it
by just asking the size of vv1. So, the size of vv1 is 5, and if I go to the 0th element then it is
going to be something like this and its size will be 10. So, I am using this to store a matrix, and if
I want to get the size, the number of rows and the number of columns, I can just do something
like this.

(Refer Slide Time: 14:26)

975
So by using vector of vectors, I can create a 5 by 5 identity matrix and here is how I am going to
do it. So first of all, let us see what this does. Okay, so I am going to have a vector of vector
double and I am going to call it m. It is going to have 5 elements, each of which is a vector of
doubles of length 5, but all elements 0.

So at this point, already I will have a 5 by 5 matrix, but in this matrix every element will be 0.
That is not quite what I want. So, but I can access the individual elements. So, what I do is, I am
just going to go over the diagonal and for that I am going through i is equal to 0 to 4 and this will
give the diagonal, so 00 11 22 33 all of these will be set to 1. So, now, I will have a 5 identity
matrix.

(Refer Slide Time: 15:18)

So here is an exercise, 2 simple exercises which I will definitely encourage you to do.

976
(Refer Slide Time: 15:25)

Alright, what have we discussed in this segment? So we have discussed – vectors which are
more powerful version of arrays. Here is a point that you should note – vectors are essentially as
fast as arrays, if you only use indexing and push_back operations. If you insert in the middle then
things get slowed down, but with just these 2 operations then practically arrays. Passing vectors
to functions is more convenient because you do not have to specify the length.

You can get by doing v.size. Then vectors can be used to build nice multi-dimensional arrays.
Okay. So in particular you should be able to write matrix multiplication operations or all kinds of
matrix operations which are all matrix sizes. This is the end of this segment and in the next
segment I am going to talk about sorting vectors and arrays but let me take a quick break.

977
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-23 Part-03
The Standard Library
Sorting vectors and arrays

(Refer Slide Time: 0:19)

Welcome back. In the last segment we talk about vectors. In this segment we are going to talk
about sorting. So, first how to sort a vector.

978
(Refer Slide Time: 0:29)

So, C++ provides a built-in facility to sort vectors and also arrays. And for this you need to
include the header file algorithm. So once you do that suppose you have a vector V of 10
elements. Suppose, somehow you have put values into this vector, then you have to sort, if you
want to sort you just do this, you write sort(V.begin(), V.end()), that is it. Alright!

So, I have not told you why V.begin() and V.end() are, think of this right now as mantras, but I
am going to tell you what they mean shortly. This will sort V in non-decreasing order and begin
and end are, what are called “iterators”, so iterators are kind of pointers, but they are abstract
pointers and we are going to discuss them later.

979
(Refer Slide Time: 1:32)

Sorting an array is quit similar, but not entirely. So again we need the header file algorithm. So
suppose we have an array of 100 elements and somehow we initialized it, put values into it, and
if I want to sort it, I just have a write sort(A, A+100) or here whatever the length it should appear
over here that is it, then it is sorted.

(Refer Slide Time: 2:00)

The sorting order can be decided. You do not have to always sort in non-decreasing order and, in
fact, you can sort anything on which the less than operator is defined. So, for example, you can

980
sort strings. You have also create object or creates structs in which you write the less than
operator. Once you write the less than operator you ready to sort.

This means, for example, I might have a struct which stores marks of various students and I can
now choose to sort those structs say either by the physics marks or either chemistry marks
whatever whatever I want, may be by the total marks, I just have to define the less than operator
consistent with the order that I want.

And you do not even have to define the less than operator. In the sorting, in the sorting command
itself you can specify the sorting order by giving a lambda expression. I am not going to talk
about this in this lecture, but it is discuss quit extensively in the book and it is not hard and I will
definitely encourage you to read it because there will be some exercises related to it.

(Refer Slide Time: 3:30)

So, what have we discuss in this segment? So, standard library contains algorithms to sort
vectors an arrays. For this you need to include header file algorithm and it can sort any type of
objects provided less than operator is defined on those objects, or you supply a comparison
operation as a part of the call. This concludes this segment and in the next segment I am going to
discuss the classes map and unordered map, but let us take a quick break before that.

981
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-23 Part-03
The Standard Library
Classes map and unordered map

(Refer Slide Time: 0:18)

Welcome back. In the previous segment, we discussed sorting.

(Refer Slide Time: 0:26)

982
In this segment, I am going to talk about maps and unordered maps, so these are also template
classes and will see details. So, let me describe them starting with vectors. So, a vector or an
array, gives us an element when we supply an index. The index must be an integer and it must
come from a small range. But sometimes we may want to use indices which are not integers, but
maybe strings. So, for example: Given the name of the country, we might want to use the name
of the country as an index and we would like back its population, or maybe we want back its
capital.

Now, this is exactly what maps or unordered maps can do and these can be obtained by using
header files map and unordered map. Unordered maps are faster but have some poor features. So
we are going to talk about one feature that they have less, but they have some other features also.
But if you do not need those features you should really use unordered map because they are
faster and the reason for these names will become clear soon.

Well, the reason for the name map should be clear because the map is really in this example
mapping the name of a country to the population or it is mapping the name of the country to a
capital, so it is like a mathematical map. A mathematical maps elements of one set to elements of
another set, so that is what this is doing. Unordered map will become clear a little bit later.

(Refer Slide Time: 2:19)

So, let us talk about maps, so what is the general form and take some examples. So, if I want to

983
define a map, here is what I write, I write the keyword map, then I write in braces the two
template arguments, the index type and the value type and then I give the map name. So, as an
example, I can write map<string,double> population. This is going to be useful for doing the
thing that we just say given a country, let us get its population. So, here the indices will have
type string, so, for example, I can have country names and elements will have type double so that
could be population if I want. And if it is going to be a map there is a technical requirement that
this index type must satisfy. So, well I might as well mention it later that the index type must be
comparable using the less-than operator and how that actually comes in, we will discuss later.
But how do we use this, how do we use a map.

(Refer Slide Time: 3:30)

So we have a map from strings to doubles and we our map is called population. So, here is what I
can do, I can say population index India is 1.37. So, this actually creates an entry in the map, it
looks like an array access statement. But it is a lot more interesting, it is creating an entry and
then the index does not have to be an integer in a small range. But it can be anything, well it can
be string as we have specified over here and it is storing 1.37 in that element of the population.

So, map entry or map element has been created now. I can create more and more, and I can print
out what is stored in the map. So, if I write cout<<population[“China”], this will print out 1.42. I
can update the entries as well. So suppose, I just realized that this was an old entry and the new
population is slightly larger, then I can put this new population. 1.37 will go away and it will be

984
replaced by 1.38.

(Refer Slide Time: 4:58)

Now, you would like to know whether our map contains say a certain country. So, I would like
to check if a certain index is defined. So, say we are doing lookup, a population lookup service,
so somebody types the country and now, I want to know whether I have the population with me.
So for that, I am going to write population.count, so count is a member function on population on
those specific maps it takes a country as an argument and it says look is there an element with
this country as the index whatever you type done.

So, for example, if we had placed the population of India, China and US and suppose you typed
in Sri Lanka then this population count what turn out to be 0. Otherwise, it will be 1. And by the
way, there is a multi-map as well, which allows you to put several entries and that is why this
can be a general number, but with maps, it has to be either 0 or 1. So, if this entry has been
defined then we can say print out the population and if this entry is not defined, we can say the
population is not known. So, this is a very short population lookup service that you can put up.

985
(Refer Slide Time: 6:13)

So, as you might expect a lot is going on behind the scenes and there is actually a very
interesting idea and that idea is discussed in chapter 24. It is a bit of an advanced idea, so we are
not going to consider it in this chapter. If you wish to say, that look I have stored a lot of data in
the map and I want to print it out. I want to print out all the countries and their population that I
know. So you can do that and that will need to use of iterators which we are going to discuss
next. The discussion so far also applies to unordered map, so everything that I had said over here
just replace map by unordered map and it will work.

986
(Refer Slide Time: 7:02)

Alright, so what have we discussed? We said that maps are like arrays, but the index need not be
an integer in a limited range. A map M and this applies to an unordered map as well can be
thought of as a pair, so you are storing these pairs, the index and the value pairs. And the way to
add a pair is this, so you say M[index]=value. This adds, this pair into the map.

And you can check if a pair is present by writing M.count we saw this and whether checking
with it is greater than 0 or not and you can get the value by writing M[index]. Unordered maps
have similar functionality. And this is the end of this segment. In the next segment, I am going to
talk about iterators and we will conclude this entire lecture sequence.
Thank You!

987
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 23 Part – 5
The standard library
Iterators

Welcome back.

(Refer Slide Time: 0:18)

In the previous segment we talked about maps and unordered maps. In this segment we are going
to talk about iterators. And we will also conclude this lecture sequence.

988
(Refer Slide Time: 0:31)

Let me remind you that a map is a set of pairs of the form index and value. Okay, and so for
example the population map is this as we define is the sequence. I guess the numbers were
slightly different but anyway this could be a population map. Now, it turns out that C++ stores
these pairs as a struct. So, each pair is a struct in some structure, in some, yeah, in some
container as it is called. And the struct has members first and second.

And first holds the index and second holds the value. So, using iterators you can access all the
elements or all these pairs in the map one after another, do what whatever you want with them.
So, an iterator from map going from, say index, type index to type value, is an object of type
map<index,value>::iterator. So, this iterator also has a type and this type is this complicated
looking thing.

All right, so iterators can be created and they can be set to point the first, point to the first
element in the map. So, I said earlier that an iterator is like a pointer. So, in that sense when I
create an iterator. I can set it to the first element in the map. And then the dereferencing operator,
the star operator is defined and you can use it to get then element that this iterator is actually
pointing to.

And then the plus operator is also defined and that allows you to go to the next, the next element
in the map. So the analogy here is I guess to indices in arrays. So, if you do plus plus to an index

989
you get to the next element of the array. So similarly with here if you do plus plus to an iterator
you get to the next element of the map.

(Refer Slide Time: 3:03)

Okay, so let us do this by as an example. So, our population map, so let us say I store 1.37 as the
population of India and now let me create an iterator. So, mi is a variable that I create but of type
iterator. It does not have any, it is not assigned any value yet. So, I have to put a value into it. So,
I can write mi equal to population.begin(). So, now population.begin() is what might be called a
constant iterator. It is like writing mi equal to zero. So this iterator points in a metaphorical sense
to the first element or the beginning element in this map.

So, this is a constant operator and it points the first element of population. Well, in this case the
first, there is only element so it will point to this element itself. So, if I write cout<<mi->first. So,
remember that we have to think of this is a pointer. So, we are first dereferencing it and we are
getting to the member first of the dereferenced object. So, of course, that can be written as by the
arrow or the minus greater than operator or the arrow operator. And this will print out India and
this will print out 1.37.

990
(Refer Slide Time: 4:34)

But you can do more with this. So, again I have our population map, but let us say we put in all
over three countries into it. Now, I have a for loop. And the control variable for the for loop is
our iterator and it has been initialized to population dot begin. Next, we are supposed to supply
the termination condition for the loop. And this is another constant iterator. So, we are going to
do this until so long as this does not equal the end.

So, you can think of this as an iterator which is just outside the valid iterator ranges. So, again if
you go back to the array this is kind of the length of the array. So, you do not want, you do not
want your index to become as large as the length. So, that is what this is doing. And you are
going to increment that iterator. So, at the end of the loop you are going to increment the iterator
so you go on to the next element of the iterator.

So, to start with mi points to the first iterator and then you check whether your iterator is
pointing to a valid element. If so, you execute the body and at the end of the body you advanced
the iterator. So may be inside the body we are just going to print things out, so whatever the
iterators pointing to the first element or the country we will print and then we will put colon and
will print the second value, that is it.

991
So, what should this do. Well, you would think that they should print out the countries and their
population and that is indeed what happens. But there is something nice, further nice that
happens. So this iterator, this in this case it will print the countries and populations in the
alphabetical order. Or the lexicographic order. And I said earlier that maps require a technical,
there is a technical condition which is that the less than operator should be defined on the index
types and the index types are strings.

And the less than operator on the strings is the lexicographic order. And therefore, when you
advance using the iterator the elements are accessed or visited in the lexicographic order. And so
things will get printed in lexicographic order. This happens for maps but not for unordered maps.
As the name says unordered maps have no order. So, you will get the elements in some order but
there may be nothing interesting as far as that order is concerned. That order is something that
the implementation decides, it may not even be the element that you inserted first; it will be, it
could be some arbitrary order. Again there will be reasons for why it is at ordered but the reasons
are not interesting from our point, right now.

(Refer Slide Time: 7:52)

Yeah, so we said that there was a technical requirement and the less than operation. And when
we stepped through the map using an iterator we visit the pairs in increasing order. And the less
than operator need not be defined but the printing will not happen in it in any interesting order.

992
(Refer Slide Time: 8:10)

So we will do a demo of this just to see what happens with ordered and unordered maps.

(Refer Slide Time: 8:19)

993
994
995
So, let me get out of the presentation and, so let me open this file. So, here is our map. Oh, by the
way I can initialize it in this manner as well. So, what does this mean. This is the, this is a pair
that I want to put in. This is another pair that I want to put in. This is another pair that I want to
put in. But the order over here is not the order in which the pairs actually go in. This is I can just
put it in the order that I remember to pretend.

But C++ will store them in the right order. So, if you need the order it will be there. Now, what I
am going to do over here is, I am going to do that going through all the elements but I am going
to do this for, so I am going to do it twice. I am going to do this first for a map, and then later I
am going to this same thing for an unordered map. So, for this map I am going to print out all
these things. So, exactly the same thing, it is the same, it is the same loop going through all the
elements in order. And here, well, I guess I should put this cout statement before I, after I define
the map but does not really matter. I am putting in the same elements and I am going through, I
am going through the same kind of loop. But this loop is for an unordered map. So, the iterator is
for an unordered map.

And my original map is an unordered map. So, let us see what happens. So see what happened.
So, for the map the contents were printed in alphabetical order or lexicographic order. For an
unordered map, they seem to have been printed in some strange way, who knows what way they
have been printed. But any way, so the look ups and indexing will work exactly the same for
both.

996
(Refer Slide Time: 10:50)

All right, so let us get back to our presentation. Yeah, so I want to talk about a few shortcuts
which are of somewhat recent origin. So, instead of writing that whole complicated type
expression, map::iterator, all of that, I can just put an auto over here. And then I can just say
mi=population.begin(). So, this is an interesting statement because I am not actually giving the
type, I am telling C++ that look I am assigning this to this. And so now you infer the type, so
C++ knows that this has type all that map<….>::iterator. So, therefore, it will itself decide that
this should be that type. So, saves us a lot of typing. The rest of the code is the same. But there is
even more dramatic improvement possible. Another C++11 feature. So, this is what it is called a
range for loop. So, here I am not even really using an iterator explicitly. I am saying after you
iterate you will, so tell me, go directly to the objects that I am iterating through. So, do not even
get me the pointers. Tell me what they are pointing to. So, cNp is really, are really the pairs the
country, the country in population pairs which are stored in this iterator. So, this says that for all
possible pairs, do whatever is in the body. And again since, this is a map not an unordered map,
we will go over these pairs in increasing order of the index. So, I can just write over here
cNp.first. By the way, this is not arrow because cNp is the pair itself. Not a pointer to the pair
and here again cNp.second, that is it. So, this really makes it much nicer to deal with maps
because all that, all those huge iterator references are not there at all.

(Refer Slide Time: 13:25)

997
So, iterators can work with vectors and arrays. So, far that please see the book. Iterators can be
used to find and delete elements from maps and vectors. Declaring an iterator is verbose, because
the type is usually long. So, as we just saw you can specify the type as auto and C++ will infer
the type. And occasionally it might be useful to define to use a typedef statement.

This is also defined in the book. So, in fact, instead of writing say something like vector of
vectors, vector of vector of end. I can call it a matrix. So, wherever I want to type vector of
vector of end I just need to see matrix. So, typedef statement allows me to do just that, again for
the syntax of it, please look at the book.

998
(Refer Slide Time: 14:23)

All right! So, that brings us to the end of this lecture. So, I just want to make a few conclusions.
So, standard, a few remarks, the standard library contains some classes which we discussed but it
also contains some other classes. So, there is a queue class. There is a priority queue class which
is discussed in the book in Chapter 27 and several other classes. And even the classes that we
have discussed have a lot more features. For that, see the online documentation on the web. The
standard library classes use heap memory. However, this happens behind the scenes and you
really do not even need to know about it. And that is the beauty of it. It is reducing your thought,
your thought overhead. You can think of these as just as abstract mathematical objects. So, a
map there is a mathematical object called the map. So, the C++ object called the map is very-
very similar to the mathematical object called the map. So, it is a nicer way of thinking about
things rather than saying that oh there is memory allocation happening. There is, it is happening
but you do not have to think about it. These classes are extremely useful. So, definitely, get lots
of practice with them. And solve the problems at the end of the chapter and we conclude this
lecture over here. Thank you very much.

999
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture-24 Part-01
Data structure based programming
Introduction
Hello! Welcome to the NPTEL course on an introduction to programming through C++. I am
Abhiram Ranade and today's lecture is about data structure based programming.

(Refer Slide Time: 0:30)

So, let me begin by saying that simple programs are about atomic objects. And by atomic
objects I just mean numbers or characters. So, for example, we wrote programs to calculate
the sign of a number or the gcd of two numbers, so these are what I have called simple
programs. More Complex programs and perhaps most programs are about objects which are
collections or sets or sequences of objects.

So, there will be sets of students we are dealing with in our program, or maybe some set of
disc in the plane, some set of taxi drivers, but we are no longer just talking about one or two
objects. We are talking about lots of objects and they even might have some relationships
amongst them. Now, of course, these programs can be written without the standard library
which we learnt about in the last lecture.

And typically we will represent sets using arrays. With the standard library, we have a much
bigger choice, so we will represent sets using vectors, strings, maps and these are just more
convenient ways of representing sets. And when we say data structure based programming,

1000
what I mean over here is programming which involves things like theses vectors, maps, and
so on.

(Refer Slide Time: 2:00)

Ok, so when we talk about sets, there are different variations possible. So, for example; the
elements of the set might be a pair. So, for example; you might be storing pairs of the form,
name and roll number of that student. So, this is very nicely represented using a map data
structure or a map class in the standard library. SL in this lecture is going to mean standard
library.

Another possibility is that not only do you have a set of objects or set of entities but they may
be ordered. So you may think to yourself that this is the first entity or this is the first object,
this is the second object, this is the third object and so on. In such case, the standard library
vector class would be extremely useful. On the other hand, in the relationship is not first,
second, third but just that this comes before this. This in turn, comes before this other one and
so on. So, there is just an ordering relationship in which case the standard library class called
ordered set actually it is just called set but by without any prefix to it, it means implicitly
ordered set. That class will be very useful or that data structure will be very useful and we are
going to see this very soon.

1001
(Refer Slide Time: 3:39)

So, in this lecture we are going to study some additional data structures or additional classes
from the standard library and these are going to be the set and something called a pair. Then,
we are going to see how the data structures are implemented. This is going to be just about a
remark because going into details would be quite complicated.

Then we will see how these data structures can be composed, because the real power is
obtained when you can compose these data structures. Then we will see a simple primitive
called typedef, but all of these we will see in the subsequent segments, so we will take a
quick break here.

1002
An Introduction to programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 24 Part- 2
Data structure based programming
Set and pair classes

(Refer Slide Time: 00:19)

In the last segment we saw an introduction to this lecture sequence. In this segment, we are going
to study the set and the pair classes or data structures from the standard library.

1003
(Refer Slide Time: 00:31)

So, I am going to introduce the set class through an example, through a program. So, first of all,
when we write a program we will need the usual things like include simple CPP but if we want
to use the set class we should also have #include<set>. Then we will have the main program and
in the main program I can define a set as shown here. So this is saying that I want a set of
integers. I want a variable called students which is going to be representing, which is going to be
containing a set of integers. And I am not restricted to a set of integers. I might want a set of
strings for example. So, here I am thinking of representing the students using their roll numbers.
If I wanted to represent them using their names then a set of strings would be the right, the right
class for me to create, the right variable for me to create. Now, let me just go ahead with the
program, so this program is going to read a bunch of student roll numbers.

So, a loop which goes while true there is no exit at the top, but what we are going to do is, we are
going to read in the roll number. So the variable roll number is going to be read from the
keyboard and we are going to have this convention that if the roll number that that is read in, is
smaller than 0, then that is going to be a signal that all the roll numbers have been typed in. So in
that case we are going to break. Otherwise what we typed in is a valid roll number and we just
want to insert it into our student set. So that is accomplished by the statement, students.insert(roll
number). So into a set what we have seen here is that you can insert something and since this is a
set of integers, you can insert an integer. Now we have inserted all the roll numbers into our set

1004
called students. What can you do with this next? So here I am going to read in 1 more roll
number. So let me call it S. So I write into S from the keyboard.

Now, I can check whether this roll number is present in my student set. How do I do this? So for
this we have this function, where this member function called count. So students that,
students.count(S) is going to return the number of times S appears in the set students. So, if S
was typed, then this would evaluate to 1. So, if S is not present, then this would appear 0 times.
So you really should of count, as taking the value 1 or 0 but yeah so that is it. This is the set and
so really no element can appear more than once here.

Then we are going to do something interesting. We are going to print out all the elements of the
set and this is really very similar to what we did for maps. So, over there we iterated, so we
iterated over this set and now this r is going to be each element of this set. So, we are going over
all the elements in the set students and we are going to refer to each element using this variable r.
So, I can iterate over sets. So that is one of the operations that I can do in with a set and given
that operation what can I do with r? Well each element is a roll number and I can print out that
roll number directly.

Now, there is some interesting point over here. So this set implicitly is an ordered set. So, when I
go over the set elements, when I iterate over the set elements, I am going to encounter the
elements in increasing order. So, this less than order should be defined on this data type and
indeed less than is defined on this data type and, in fact, I am going to get in increasing order. If I
had had a set of strings, then I would have got them in lexicographic order.

So this is this is something nice. So I will now be able to print all the set elements but they will
be in increasing order or lexicographic order whatever is consistent with the less than order
which must be defined on this data type. So that is it, so that is it for this program and in
addition, the set class or the set data structure has many other operations defined. For example,
you can remove an element after inserting it into a set and this is done by the member function
erase but that is not the only function. There are other functions also available and there are
various online documentations. So just do a search on the net and you will get all the other
operations which are available. So we are not going to, we are not going to rely on all those
operations. I mean this is just a this is just a very simple minded introduction to this class and so

1005
for understanding, for answering, the questions in the exams as well as answering the question in
the quiz, whatever we have discussed over here is going to be adequate.

Let me just point that there is something also called unordered set. So in this, there is no order, so
if I if I am going to iterate over them, I will get the elements in some order which you cannot
really make any sense of. So there are numbers, may be the numbers will come out increasing
but may be they will not. They will come in some random order. But this set turns out to be
faster. It is a little tricky and I am not going to talk more about it and some of the features that we
have talked are mentioned over here like this iteration order is not available if you, if you create
the set of, if you create an unordered set.

(Refer Slide Time: 07:11)

1006
1007
So, I am just going to give you a demonstration of sets. So, let us go to that. So you can see this
is the same program which we had seen earlier on the slides. So, let me compile it. So, I have
compiled it. Now, I am going to run it and now as I run it, the first thing if you remember I have
to insert students into that set and I have to end by printing, by giving in some negative quantity.
So, maybe I will put 59 as the first roll number. This is the first student that enters.

So, let me just move this so that it is clearly visible. Then may be 45 enters then may be 66
enters, 23 enters and then may be that is the end and so I will give minus 1. So at this point the
program knows that all the students that were supposed to enter have been have entered. Now,
what was the student doing? What was the program doing? Well the program is now expecting
me to type in a roll number and it is going to tell me whether that roll number is present in that
set or not.

So, let us say I typed 66. So, what, let us see what happens? So, when I typed 66, the first thing it
type if you remember is whether or not, what is the count of 66 in this in this set? So, in fact, the
count of 66 is 1 because 66 is present over here. And after that, it printed all the roll numbers in
the set in increasing order. So, this is the increasing order over here 23, 45, 59, 66. We did not
type them in that order but it prints them out in increasing order.

1008
(Refer slide Time: 09:13)

Alright, so let us go back to the slides and let us move on to pairs. The general form of how you
declare a pair is this. So you say pair, that you name a type and another type and then you name
the variable, give the name of the variable that you are trying to create. So, what does this do,
well it creates a struct and it, the struct only has 2 elements. The first element which is actually
called the the data member is called first, has to have type t1 and the second has to have type t2.

So, you can think of this as being a struct which is pre-defined for you. If you just you do not
have to actually say struct and then give members and all of that. This struct is sort of pre-
defined because of this statement over here. So, here is an example, I might say pair<int, string>
p1, p2; So, this creates 2 variables p1 and p2 of type pair of int string. So p1 has an int part and
the string part and p2 also has an int part and the string part and, in fact, to get to the int part of
either I have to use the member first or I so I have to say p1.first or p1.second to get to the string
part.

Now, there is a nice feature. I have this constructer also available. So again this is all pre defined.
So here I am I have to type the initial value of the integer that I want to create, the initial value of
the string that I want to create. So what would this do, this would create a struct p1 whose first
part is 50 and second part is 50 but in words. Alternately, I can do this as well. I can initialize
p2.first=60 and I can initialize p2.second=60 as well. So the string part would be set to this 60
and finally there is an a very interesting convenience provided. I can compare pairs.

1009
So, I can write something like p1<p2. So, what does this do, this is going to be less than if the
first part of p1 is less that the first part of p2. If they are both equal, then it is going to go to the
second part. So, what do you think is going to happen in this case? So, over here the first part of
p1 is 50 and the first part of p2 is 60. So, this comparison is going to come out true. So, this will
cause a 1 to be printed or to be printed. So, yeah, so the comparison happens according to to the
lexicographic sorting order.

(Refer Slide Time: 12:09)

Alright, so what have we discussed in this segment. So, we have discussed the standard library
class set and in addition to the operations that I showed you, there are many other operations
available. It also allows iterators and we also discussed or rather we just mentioned the standard
library class unordered set. Then we discussed the standard library class pair. Now, pair is
something that has meant to be used for quick programming, rather than having to take the
trouble of creating a struct.

So, defining a struct then using it, you can just sort of create the struct on the fly. Yeah, so that is
what pair is going to be for. And by the way pairs are used in maps. So, if you remember a map
itself has 2 parts, a keytype, a key part and the value part. So actually maps are indeed sequences,
ordered sequences of key type value type. So order according to key type and, in fact, you have
seen this when we printed the contents of maps in the last lecture.

1010
Remember lecture in which we had a map from names of countries to their populations, well so
there we got things we wrote things country name, we wrote things like variable.first and that
first was the country name and variable.second and that second was the population. So pairs are
actually used and are parts of maps. C++ also allows you to define a similar class called tuple, oh
by the way here is one quick use that you might put pairs to. If you want to return 2 objects, then
you can just return it as a pair and you can receive it as a pair in your calling program as well. So
rather than having to define a proper struct this is sort of a quick way doing things and, of course,
the fact that pairs are lexicographically ordered is also very helpful. The standard library also has
other interesting classes, something called priority queue is quite interesting but we are not going
to look at those in in this in this course. In the next segment we are going to talk a little bit about
how these data structures are going to be implemented, but before that let us take a break.

1011
An Introduction to programming Through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 24 Part- 3
Data structure based programming
Implementation of standard library data structures

Welcome back.

(Refer Slide Time: 0:22)

In the previous segment we discussed the Standard Library Class Set and Pair and also
briefly talked about unordered sets. In this segment, we are going to discuss a little bit
about how data structures are implemented. So, all these things sound like magic, but, of
course, there is some code which is running behind them so I, want to tell you about that
code.

1012
(Refer Slide Time: 0:44)

So, in the first class that I am going to discuss is the Vector Class. Now, the Vector class
is implemented in a manner similar to the String Class I, should I guess capitalize this
because by the String that I have, that I mean over here, I mean the string that we
discussed in our lecture, not the Standard Library Class String.

If you remember, so we discussed a data structure or a class for storing character strings
and we ended up writing things like constructors, assignment operators, copy constructor,
destructor and also concatenation operators. So, the Vector Class has been implemented
by someone in a similar manner. So, what is the difficulty, what is what is sort of the key
difficulty in implementing a Vector Class, what is the key question we need to answer?

Well, if we are doing a push back operation and if the current array that has been
allocated to hold the elements of the vector gets exhausted, what I mean by that is,
currently you have 100 elements allocated and you push back one more element, so now
you have 101 elements which are stored in your vector. What do you do? Well clearly if
you remember what we did in the string case, what you will have to do is you will have to
allocate a new Array. Then you copy the content of this array into that new array and then
you delete the current array.

1013
(Refer Slide Time: 2:27)

So, if I may draw a picture, this is your current array or array, this is the array pointer and
this is pointing to this array. So if I do a push back I really want to store that element
somewhere over here. But this area is not given to me, so what do I do, I ask for a bigger
array, I may just ask for an additional element and I may just ask for just a little bit more,
but it turns out it is good to ask for a much larger array.

So then I copy this part to this part, so I get whatever I had earlier into this array, and then
I insert whatever I want to push back I store that element that I want to push back into
this element over here. And then I set my array pointer to point to this new array and I
delete this array. I give this array back to my storage allocator because I do not need it
any longer. So, this is something I want to do, so that is sort of natural thing and that is, in
fact, exactly what happens.

1014
(Refer Slide Time: 3:52)

But there is an interesting question that I have not answered which is how big an array do
I allocate.

(Refer Slide Time: 4:01)

Now, turns out that it is a good idea to double the size. So, why is that, if I double the
size. then subsequently if you do more push backs, you will not immediately have to

1015
allocate and copy and things like that. So you will be saving on your copying cost and
additional allocation cost.

You will be wasting a little bit about little bit of memory but how much memory are you
wasting. Well you are wasting exactly as much memory potentially as you have elements,
so you are wasting a little bit of memory, but the time you save because of not having to
copy too frequently is a lot more important.

(Refer Slide Time: 4:47)

And it turns out that it is possible to prove in fact, that if you sort of do this doubling idea
then the copying time is not too large. In fact, you can then think of vectors as being as
efficient as arrays. So, when you have an array, you do not have to do any copying, right.
The memory is given to you once and for all. Here, you do have to do some copying once
in a while you have to do allocate ask for new memory.

But what this is saying is that if you have this doubling strategy then you can ignore those
costs. Let me acknowledge that I (have) I have not explained exactly why this happens. It
can be explained as I said you can actually prove rigorously what I am saying but that is
not a part of this course. You may see it in some other courses say a course on data
structures. But it is worth knowing that vectors really are practically as efficient as arrays.

1016
(Refer Slide Time: 6:07)

Let me next, say a few words about implementation of ordered sets. First of all, let me
acknowledge that this implementation is very tricky. We have not even begun to think
about how ordered sets can be implemented in this course. The Ideas are quite-quite
clever and we have not seen them. Having said that, let me just give you a hint. What
happens when you store an ordered set?

Well, of course, there is some memory allocation that happens but at the end you get the
effect that all your set elements are effectively stored in some sorted order. So they are
not actually, they are not actually in sorted order, but for practical purposes they are in
sorted order. Again this is intriguing and I am sorry to intrigue you but well may be this
is this should be an inspiration for you to take the data structures course. Anyway, what
happens is that effectively the elements get stored in a sorted order.

And why is sorted order important, well that you know the answer to. So if I want to
decide whether an element is present, what can I do? Well I can do binary search so this
binary search like idea also works and we have discussed binary search long ago and we
have seen that binary search is actually very fast, you do not have to look at all the
elements of the sets.

1017
You only look at log of the size of the set that many elements. So the time proportion, the
time required to determine the current element is present is proportional to the log of the
number of elements. So this happens very fast and that is another reason for you to be
using a set, the set class. Because it is actually a very it actually has very fast operations.

And let me just mention over here, that maps which you studied, which we studied in the
last lecture are also implemented in the similar manner. So, again, if I want to store
something into a map, if I write A of something equal to something, then that happens in
time proportional to log or if I want to get the value stored in the map again that happens
in time proportional to the log of the number of pairs stored in the map.

Now, again one very-very cryptic remark I should make and that is that unordered sets
and unordered maps are even cleverer and they actually work even faster. I am not going
to say anything about it, you will need to take course on data structures if you want to
understand why unordered sets and unordered maps are faster and what is the clever idea
behind them.

(Refer Slide Time: 9:15)

I want to make one more comment again this relates to the efficiency of these classes or
data structures. So, basically a point that I want to make, is that if I am defining a class
involving strings, it is usually going to be more complex or more time consuming than a

1018
class involving ints. So, why is this, well if I want to compare, if I want to do any
operation on ints, our computers are very capable of operating on ints or in general on
numbers. So, all these operations take one-two cycles on most computers. So they
involve one two machine level instructions if you remember them. On the other hand, if I
am comparing two strings say they are of size ‘n’ then potentially I will have to compare
all characters, all the elements of the string and could take as large as ‘n’ operations. So,
that is the basic issue that if I have things which are built up using strings, then strings are
long obviously. And therefore, the time taken to do something with strings is usually
longer than the time taken to do something with integers. So, in other words what I am
saying is that if you are counting, if you are looking at the time for operations on sets or
maps or vectors of stings, that is usually going to be bigger than the time for operations
on sets or maps or vectors of ints and therefore, it raises the question can we minimize the
operations on strings.

So, if you are writing production quality programs, this will be an important question you
will want to minimize the operations that you perform on strings. This is a point that I
want to raise right now just to alert you to it, but in this course, in this course we are not
going to worry about this point. So, in this course we are going to ignore this issue but
this is just a point that I want to want you to keep at the back of your mind and again you
can think about it when you do the data structures course you will see why this is the
case.

1019
(Refer Slide Time: 11:41)

Alright, so what did we discuss in this segment? Well, we discussed implementation of


vector and set and we said that maps are implemented like sets and the beauty of maps is
that for insertions as well as for search, for determining whether something is present in
the map, logarithmic time is needed. Next I am going to talk a little bit about how to
compose these data structures together. So, how do you build sets of vectors? When do
you build sets of vectors or vectors of maps or maps of strings and so on? But again,
before that let us take a quick break.

1020
An Introduction to Programming through C++
Professor Abhiram G Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 24: Part - 4
Data structure based programming
Composing data structures

Welcome back.

(Refer Slide Time: 0:19)

In the previous segment we discussed implementation of the classes, vector and set. And also a
little bit about maps. In this segment, I am going to talk about how you use these classes or data
structures in programming. And in particular, in programming, you will need to compose them
together. And how do we do that.

1021
(Refer Slide Time: 0:39)

So, let me take an example, suppose I am writing a program in which I want to keep track of
friends of different people, and let us say for each person I want to make a list of his or her
friends in the order oldest to youngest. And then maybe I (may) I might want to do some
processing on those lists. So, what Data Structure do we use? Well, first of all, what is it that I
require this data structures for all people, lots of people. So, let me begin by asking what is it that
I want for a single individual?

So, for a single individual I want list of friends in oldest to youngest order. So, naturally, what I
can use is a vector of strings. So the string will hold the name of the friend and I have a vector,
so I can have, I can put lots of names in it. And I can put the name in the order oldest to
youngest. So, this is for one individual. So, if I want it for all what do I want? Well, I should
build a map, so for every person whose name is here I want this data structure. So, I should have
map.

And let me call that map the friends map. So just to clarify this let me give an example of how
we are going to use this map. So, I might say, for example, friends[Amitabh] dot and this will get
me all the friends of Amitabh, and on that I am pushing back Dharmendra. So, right, if this is the
very first statement then initially this will give me a vector which is empty and into that will be

1022
added Dharmendra. I can do that again, so again what does this do? This gives me, this first part
give me all the friends of Amitabh. So what are the friends of Amitabh?

Well ‘friends’ is a map, so friends of Amitabh, gets me this element. It gets me a vector of
Strings and onto that I am pushing back another string which is what I should do so I am pushing
back Vinod. So, what does friends[Amitabh] contain right now? Well, it contains Dharmendra
followed by Vinod. I could write one more command,
friends[Dharmendra].push_back(Amitabh), for example. So then friends will contain a pair for
Amitabh and one pair for Dharmendra. And I can put friends of different people inside this
friends map.

And the second element, this map is going to take name and it is going to return a list or a vector
of friends names. And to get to that, how do I get to that? Well a vector is going to be indexed by
numbers. So, for example, if I can I can now write something like this. Friends[Amitabh][0]. So,
give me the zeroth friend of Amitabh. Select again, let us look at what it means, so friends of
Amitabh is going to give me a vector. And since this is a vector it is legal to take the zeroth
indexed element of it and what is this zeroth index element?

Well the push back happened in this order and therefore, I am going to get the zeroth index
element which is Dharmendra, so Dharmendra is going to get printed as a result of this. So, this
is one example of composing data structure. So, what have we composed? Well we have
composed map and of course there is string and we have vector. So we have made a complicated
looking data structure, but if you look at it closely it is actually not that complicated. Because
vector of strings is a list of strings or it is a list of my friends.

And then for every person, I am storing such a list. So the trick is you read it inside out. Or I
guess you can read it outside in as well. So you can say that look for every string something is
being stored over here and what it is.

1023
(Refer Slide Time: 5:10)

Let me take another example, so again this is about keeping track of friends. But, now I want to
determine if A and B are friends. So, I want to determine if Dharmendra and Amitabh are friends
or Jeetendra and Dharmendra are friends and things like that. So, I want to have a data structure
which can quickly answer queries like this. So, what should I use? Well let me give you the
answer. So, here it turns out that is useful to use this a map from string to a set of strings.

So, again I am going to call it friends. So, let me read this, so the first thing is going to be the
name of the person whose friends I am thinking of. And then this set is going to contain the set
of all the friends. So, how do I use this? So, earlier I pushed back Dharmendra, now I am going
to insert. Why insert? Because friends[Amitabh] gets me a set of strings not a vector strings. And
into to a set you insert you do not push back.

So, again I am going to insert Vinod as before and now I can query. So, here is how I am going
to query. So, I am going to ask give me friends of Amitabh and what does it give me? It gives me
a set of friends. And inside that count how many times Jeetendra appears. So, if it appears, if this
appears once, then that means yes Jeetendra is a friend. If this appears, if this returns a zero then
it means Jeetendra is not a friend.

1024
So, what is going to happen now? Well into the set we inserted Dharmendra and we inserted
Vinod and therefore, Jeetendra is not there and therefore, this is going to printout a zero because
we have not made Jitendra a friend. But if you insert even now,
friends[Amitabh].insert(“Jeetendra”) and then call this again, then you will see that the count has
become one. And by the way these are sets. So, if you reinsert it is not going to change anything.
The sets as you know from your study of mathematics, a set cannot contain the same element
more than once.

So, C++ actually does have something called a multiset, which does contain, which allows you
to store several copies of the same element into the set. So as I said, look at the online
documentation if you feel you need to learn what a multiset is. But we are not going to look at
this interesting class in this course because already we are doing a lot. Now, I just want to point
out that this kind of a query to quickly decide whether Jeetendra is a friend of Amitabh would
not be easy with vectors. You have to write a little bit more code.

So what code would we write? So we would say look at that vector, compare Jeetendra to every
element in that vector. That kind of code we would have to write. But here since it is a set and on
the set we have this count operation, we can get the answer in exactly in in just very small
amount of code over here. What is the important point that is coming out of this example, the
data we are storing is really the same. We are storing information about who is the friend of who,
but depending upon what data structure we use certain kinds of queries are easier to answer.

So, here what is easy to answer? Whether or not two people are friends is easy to answer. What
is not easy to answer? Well this data structure you cannot tell who is an, who is the oldest friend.
On the other hand if you had vectors and if you insert friends in order of how long you have
known them, then you could quickly tell who is the oldest friend. Just look at the zeroth friend in
that vector. So again this is a very important point, you should know how to compose data
structures. But just because you are storing the same information, it does not mean that exactly
one kind of data structure is the right data structure. It really depends upon what you want to do
with that information.

1025
(Refer Slide Time: 10:08)

I want to do one more example, so let us say we want to create a fare table. We want to represent
bus fares between cities. So once we have the table, we could ask questions like, what is the fare
between city A and city B. Assuming of course is stored it in our table in the first place. So if
there is a bus, bus connection from city A to city B, and somebody gives us a query, tell me the
fare from A to B, we should be able to look at our table and answer this very quickly. How do
we do this? Well, let us sort of try to build it bottom up or inside out sort to say.

So, let us ask what do we need to remember for each city, what do we need to remember? Well
we need to remember what cities can be reached directly from that city and what fares are there
for each of those journeys. So this is what we want to remember for the first city, second city,
third city whatever it is. For Mumbai, Pune, Nagpur, Kolhapur whatever cities you are talking
about we need to you remember this information.

Well what is this information? So, for every city that can be reached, we want to keep track of
the respective fare. So this is really just a map from city to fare payable. So, what kind of map is
it going to be? So again let us say the reachable city is represented by strings. So, it is going to be
a map from strings to fare, fare could be double. So, it could be a map from strings to double. So
this is just for one city. And what else do we, what do we really want? We want this for all cities.
So if you want it for all cities, what should we do?

1026
Well we want this is going to be inside something and what is that outer thing? Well we want to
map from a city to a map. So, for Mumbai I want a map of all cities reachable and what fares are
payable. So it is a map from a city name to such a map. So here is what it is going to look like.
So map from a string to a map from a string to a double. So, this is really this part and this map,
the city over here is this part. So, I have to supply a city, I have to supply another city and out
will come the double or I can store into this.

So, for example, once I declare this I can write a statement like this. So fare from Mumbai to
Pune is 500 rupees. That is what this statement is saying. But you should really understand what
this is doing. So this is saying there is a variable or there is data structure called fare. What is
that? It is a map. So, I can give you and index which is not here to be a number, it could be a it as
it is a string as it is mentioned over here. So, if I give you Mumbai what do I get? I get a map and
what is that map? That map is going to tell me, what is the price to go from Mumbai to various
cities? So, for every city that is reachable from Mumbai I am going to get the name of the city
and the fare. But once I have that map, if I supply where I want to go, I can store into it the fare
or if I say print this out, I will get the fare get printed.

(Refer Slide Time: 14:04)

Alright, so what did we discuss? So, we discussed that sometimes we need to compose data
structures. The exact choice of data structures depends on what information we want to store.

1027
But also on what operations we need to perform on that information. And then we also said
something about how do you do this composition. So we said that the way we do this
composition is look at a small part of the entire picture and build it up from there.

So, what do we need to for one individual? What do we need to do for a single city? Therefore,
what do we need to do for all individuals or the all cities together? So, next I am going to talk
about something called typedef and then I am going to conclude this lecture sequence. But before
that let me take a quick break.

1028
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 24 Part – 5
Data structure based programming
Typedef and lecture conclusion

Hello and welcome back.

(Refer Slide Time: 0:25)

In the previous segment we talked about how we can compose maps, and vectors and strings
together to build interesting data structures. In this segment, I am going to talk about
somewhat technical, somewhat syntactic called the typedef statement. And then I am going to
conclude this sequence of segments.

1029
(Refer Slide Time: 0:45)

So, typedef, so let me first observe that type names can be become very long, and
cumbersome to write. So, for example, we have already seen that that fare table that we
constructed had this type. So, we have to write it when we define that variable, but now
suppose I want to pass that variable to a function, then even there we will have to type this as
the type of that argument. So, you may think that look typing this again and again is very
cumbersome and also it does not really tell me what this is all about.

So, basically the typedef statement allows short forms to be defined and the idea is this, so I
am, I write typedef, then I want I write the type for which I want to create a short form and
then this is the short form. So, for this, I could have write some, I could have written
something like this. I would say typedef and this is the type, this very type mentioned over
here and for that I am going to create the name called fare table type. So this is the type and
this is the name that has been created this is synonym for this long type name.

And how do I use it? Well, exactly as you think, I can the write faretabl type, fare table so
this creates a variable named fare table of this type. Actually, in the last example, I called it
fare, but since, it really is a fare table maybe I thought I should use this full name. So, just to
complete, I could write faretable[Mumbai][Pune] equal to 500 or cout fare table Mumbai,
Pune. So that concludes discussion about typedef.

1030
(Refer Slide Time: 2:48)

So, let me now make some concluding remarks about this sequence of segments. So, let me
ask the question to you. Do we need data structures such as vectors, strings, maps, sets or
could we live without them? Well we can leave without them. So, they are not strictly
needed, in fact, the language like C does not have these data structures. And what is done
there? Well, the programmer has to really use the arrays and write code to implement
insertion, finding, etc.

Or some other kinds of constructs that the programmers himself or herself has to create. So,
these data structures or these classes are strictly not necessary. But are the useful? You bet!
They are amazing! They make it very easy to write code. So, the designers of these data
structures have guessed and they have guessed very well, what kinds of things people want to
do? And they have put the things into these data structures.

And further more these data structures are template classes. So, you can instantiate them with
any type, so you can create the vector of ints, you can create a vector of doubles, you can
create a vector of circles, you can create a vector of vectors. As you just saw so all of these
things are possible. So, whatever type data structure you want that will get created. And it
will reduce chance of errors.

So, because all these data structure has been created by expert programmers, and they have
been tested, not just by those programmers, but because they have been released to the entire
world, the entire world has tested these data structures for you. So, they are unlikely, it is
unlikely that there is any error in them and they are so compact that using them is also very
convenient and unlikely to produce errors.

1031
And, of course, they make programmes small. So whatever your logic is you can see it often
in a glance. That look this is what I am doing? Instead of having to go over several pages of
code. So, it makes for improved program readability as well. So, definitely use them! Alright
so that is the name message of programme and that is the end of this lecture. Thank you.

1032
An Introduction to Programming through C++
Professor Abhiram G Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 25: Part - 1
Medium size programs
The new marks display program

Hello, and welcome to the NPTEL course on an introduction to programming through C++. I
am Abhiram Ranade and in this lecture, I am going to talk about medium-sized programs.

(Refer Slide Time: 0:39)

So here is the goal of this lecture and the next. So, we are going to develop some medium-
sized programs. So, this will require us to put together the different things that we have
learned and in the process we will also get some ideas about how, medium-sized codes
should be organized. And along with that, we will also see different kinds of computer
applications.

1033
(Refer Slide Time: 1:03)

The first medium-size program that we are going to talk about will build upon the marks
display sequence of programs we have talked about. So this is going to be an enhanced
version of it. So, in this case the program is expected to read data from two files. The first file
which I am going to call RNFile, contains lines, each having the following: So, first on each
line there is the Roll Number, and then there is the Name of the Student with the given roll
number. And for simplicity, we are going to assume that the name does not contain any
spaces, but in real life we would have to handle names with spaces as well. But, we are not
going to bring that in right now. Then, there is another file called the RSMFile, and this
contains lines and each of these lines will begin with a Roll Number, then there will be a
Subject Code and again in that subject code will not contain spaces, that is our assumption.
And following that, there will be a number which will denote the marks obtained by the
student whose Roll Number is given on that line in the subject, whose code is given on the
line. Okay so this is the data that our program will read. You will note that I have chosen the
names RNFile and RSMFile with some purpose. So RNFile is called RNFile because it has
two fields: Roll Number and Name and so the first letters of these are R and N. So we call all
that data as residing in the RNFile and similarly, Roll Number, Subject, Marks whose first
letters are R, S and M. So, that data will constitute the RSNFile. Now, our program must read
these two files, and load up the data that's in these files and after that the program is expected
to respond to commands from the keyboard.

(Refer Slide Time: 3:19)

1034
Okay, so, what are these commands: Well, the commands are the following until and the
commands have to be executed until the user types a command to shut down the program.
Okay so, until the user types the command which requires shut down, the program will have
to execute all the other commands that the user types. So, one command could be that look,
tell me the marks obtained by this given student in this given subject.

Okay, so, the student may specify the roll number or maybe the student will specify the name
but we want the marks of the given subject to be printed out. Then, we might want the rank of
a given student to be printed. Okay, now what is the rank? Well, for the rank, we are going to
calculate average marks obtained by the student in all the subjects that the student has taken.
So, the student who has the highest average marks will have a rank 1, and the student who
has the second highest average marks will have rank 2 and so on.

1035
(Refer Slide Time: 4:29)

So, let me make a few remarks, so first of all it is clear that this is harder than the marks
display programs we have studied earlier. However, by no means this is the hardest possible
version. If you look at what might be needed in real life, things are a lot more complicated.
Okay, so for example, you may have students from many years, okay, so they may have two
students from different years may have the same name or for that matter two students but the
same year might have the same name. And, of course, we already said, that student’s names
may have spaces inside them. Then there could be subjects of different types, so for example
there could be compulsory subjects, there could be elective subjects. And we may ask, give
me the rank in the compulsory subjects or give me a rank and the elective subjects okay. And
yeah so there could be more complex queries and if we are doing this in a program that is a
deployed, then how fast do we respond is going to be important. So, if this is a part of an
information system so a student comes up or a teacher comes up or whoever comes up to
your terminal and types in the command, that person expects to get the response reasonably
fast if at all possible. And therefore, speed is going to be important, if the program is
deployed for actual use. So we are not going to be looking at all of these issues. But we will
maybe touch upon some little bit. And this is a really important issue will which we will
definitely not touch upon. The data may be too large to fit in the main memory of your
computer. So, if you have a huge university with lots of students, over lots of years, lots of
subjects then the data can be large. And the data may not fit in the memory. And then you
would have to worry about, if the command requires data from a certain portion of the disk,
how you get it. Okay but, these these are issues that we are not going to deal with.

1036
Before we go on to our program, and our program is simple as compared to what might be
needed in real life, though it is complicated more complicated than what we have seen so far.
So I just want to point out that, there are many choices in how we might implement our
program that we have set ourselves up for. So, there could be a very simple algorithm and
this might be based on how you would naively solve the problem manually.

Okay so, we will try and mimic what you might do if you had these files say as notebooks
and somebody came came to you and asked the questions. But, of course, even here there is
an issue, if you are clever then you may solve the problem in one way and if you are not so
clever you may solve the problem in another way. So we will look at some simple ideas first.

Then, once we understand what exactly we need to do, we can try to be clever. And then, we
will think about and we will talk a little bit about how we can speed up the program using
say, sorting and binary search, which we have already studied. And we have already seen that
binary search can be much faster than going through data in the linear fashion. And then, we
will talk about faster and elegant methods which are based on maps.

(Refer Slide Time: 8:06)

So, here is an outline of this lecture, so we will begin by designing a format for the
commands. We have discussed what kinds of commands we might need. But now, we will
specifically design what exactly is the user is required to type in order to issue a certain
command. So, after that, we will look at a program based on somewhat naive manual

1037
algorithm. We will look at its code and then we will discuss possible improvements. And
then we will design more sophisticated programs, will also look at code.

(Refer Slide Time: 8:52)

Okay, so that brings us to the end of this segment. So, let me just review what we have
discussed, so we have discussed the “New Mark's Display Problem” and next we are going to
talk about the program inspired by a manual algorithm. But before that we will take a quick
break.

1038
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture No. 25 Part – 2
Medium Size Prgrams
Manual Algorithm for new marks display

Welcome back.

(Refer Slide Time: 0:21)

In the last segment we defined the new Marks display problem. In this segment, we are going to
come up with a program inspired by manual algorithms.

1039
(Refer Slide Time: 0:32)

So, first let us define how the user will communicate with our program. How will the user issue
commands. So, we can try something simple. So, let us say we will use single word codes for
each of our commands. And then the codes are followed by the arguments for the command. So,
for example, we might have a command which looks like M roll number subject code and what
this means is – Tell me the marks obtained by the student with the given roll number in the given
subject or instead of the roll number the user may type in the name.

1040
So, for example, the user may type in something like this so the user may type in M followed by
roll number followed by subject code or M followed by name followed by the subject code. And
likewise, we might have a command R followed by roll number. It says give me the rank for the
student with the given roll number or R followed by name which says give me the rank for the
student with the given name. And you could have a command just a single letter Q, which says
quit or exit the program.

(Refer Slide Time: 2:04)

So, now, let us talk about how you might design the algorithm to respond to such queries. And as
we have said several times in the course, let us start by thinking about how we might solve this
problem manually. So, after we do that, we should consider what is the equivalent of the manual
steps on a computer. And that will allow us to write the code. While doing this, we will also
continuously keep in mind that we want the program to be easy to understand. And this is
something that becomes quite important when you write large or even medium sized programs
like the one we are going to write.

Usually this strategy of designing a program by thinking about how you solve the problem
manually gives us a reasonable solution but we will try to improve upon what we get as well. So,
specifically will ask well can we improve the execution speed. And we would also keep in mind

1041
that we also want the understandability of the program to be good. And so, we will think about
that as well.

(Refer Slide Time: 3:26)

So, let us think about solving the problem manually first. So, suppose the data is given to us in
two notebooks instead of two files. And what appears in the notebook is saying the first
notebook is lines of this form, so roll number followed by name. In the second file we are
expecting to see roll number followed by subject code followed by Marks. So it will contain

1042
lines of this far. So these were the lines which are appearing in files but instead of this let us say
they appear in notebooks so that we can think of a manual algorithm.

So, what is the simplest possible solution? Well suppose we want to translate from the name to
the roll number. We should go through the first notebook to find the roll number. If you have
given the name. So, that is simple enough. And then if we are given the marks query, that is M
followed by roll number or name followed by the subject code. Well you have to go through the
second notebook, which contains lines of this form and we should look for the roll number and
the subject being present in the same line. And then we should just report the marks. The rank
query, well, we have to find the average of the average marks for each student. What I mean by
this is for every student we want to find an average over all the subjects in which the student has
marks. So, if a student has say 90 marks in physics, and 80 marks in mathematics, then there will
be two lines in the second notebook corresponding to that student. So, we have to find those two
lines, and we have to take the average which in this case is going to be 90 plus 80 or 85. So that
is going to be the first step. For every student we must look at the subjects he or she has taken,
and find the average marks obtained by that student. So, this is going to be a somewhat involved
task. Then we will have a table so to say, of the average marks obtained by every student. And
then in this table we have to figure out how many students have higher average than the one
whose rank we want to know. So, that will tell us exactly the rank.

1043
(Refer Slide Time: 6:22)

So those were the manual steps. How do we translate the manual steps into computer steps? So,
what does it mean to say go through the notebooks? Well, nominally it would mean read through
the file, but usually on a computer, our idea is, we read the file just once. We do not read it
repeatedly because reading files is often too slow. So, what we do is we read the files and then
we put the data into some array or something like that in our computer.

So, we will read the data from the file into an array or informally, we can think of table
associated with the array and say we designate an array RNTAB to hold all the data from the file
RNFILE. If you remember RNFILE file was holding roll number and name data. So we will
have an array RNTAB which will have, which will consist, which will be an array of structures.
And the first member in the structure will hold the roll number. And the second member will
hold the name.

Then we also have an RSM file, which contains lines of the form roll number subject marks. So,
we will designate an array let us call it RSMTAB. TAB for table R S M for Roll Number subject
marks. And this will be an array of structures, each structure containing three data members - roll
number, subject and marks. And the subsequent actions that we perform, refer to arrays rather
than the files.

1044
(Refer Slide Time: 8:17)

So, let us think about writing the code, since, we have a fairly clear understanding of what we are
going to do manually. So, now when we write the code, we have to keep some broad principles
in mind. And we have talked about these principles earlier. So basically, we would like to
represent important entities using structures. So, the tables that we define should really be put
into structures. So I mean, something slightly different than what I said earlier. What I said
earlier was that each entry in the table or each element of the array of the array will be a
structure. Now, I am saying that the entire array should in addition be put in a bigger struct. So,
that is sort of the general idea that we are going to put important entities inside a struct, because
the struct kind of encapsulates that entity, and we can put member functions now more easily.
So, we can associate member functions with that with that entire entity. So, RNTAB and
RSNTAB are going to be important entities. So, although they contain inside them other
structures, we will put the whole thing also inside a structure of an appropriate type. So, we will
see this. And we will use functions or member functions to represent important actions. And the
main program should indicate high level program structure. So, what I mean by that is the main
program should contain function calls which, say, cause a query a Marks query to be processed
or another function call to process say the rank query, but the main program should not should
not contain details. So, the details should be implemented in function calls or member function
calls associated with the structures which are holding our important entities.

1045
(Refer Slide Time: 10:56)

So, let us look at the main program first. So, the main program should create the major entities,
in our case the major entities are the table, so these should get created by the main program.
Then the main program should execute. The main loop and the main loop should receive
commands from the users. And the main loop should execute the commands by invoking the
services offered by the major entities. So, when I say invoking services, I mean just a function
call. The main program should not contain details, the details should be in the member function
or the function calls.

The main program should not be too long and should not contain too much detail. So, I said that
the main program should create the tables, but the creation should really happen in the
constructor associated with the entities. So, the details of how the tables, or how the major
entities are constructed should also be hidden, and the main program should really contain the
high level aspect. Why is this? Well, if we put the details in the main program then the high level
organization will not become obvious. We do want to write down the details, of course. But we
also want to indicate what the high level organization is. And therefore, we should have the main
program sort of spell out the higher level organization and from the main program, if you want to
know the details about something, then you can you just have to follow up that function call or
member function call and the details and then the body of the member function call or the
function can we tell you how exactly that function is going to be implemented. So, next we are

1046
going to view the code of mean to see how the main program is going to be written to follow
these principles.

(Refer Slide Time: 13:18)

So, here is our marks, our marks program, Mark display program and here is our main program.
So, the way we are going to organize the main program is that it is going to receive the names of
the files as command line arguments. So, the first, so the zeroth command line argument will be
simply ./a.out. Then the first command line argument following that will be the name of the
rnfile. So, argv is the first command line argument, and then the second command line argument
argv2. So, argv1 when is the first command line argument argv2 is the second command line
argument. And the second command line argument will give the name of the rsmfile. Now, as we
have said earlier, to read the files themselves, we have two associate streams in the files. So, we
are going to do that. And this is how it is done.

So we are going to define ifstreams, we are going to define int ifstream called rnfile. And this
rnfile is going to be an ifstream and the actual file will be in this argv1, what the user types in
when the program is invoked as the first argument, the one after the zeroth argument and rsmfile
is going to be the stream which will be used inside the program. And this rsmfile will get data
from argv2 which is the second name, the second file name which is typed in by the user. So, the
user will type the ./a.out followed by the first finally and then the second file name. Then we said
so, then we said that the main program should create the major entities. So, the major entities are

1047
RNTAB and RSNTAB. And RNTAB, if you remember, is the table which contains information
about roll numbers and associated names. And for that, we need rnfile. So, the way we initialize
this is by calling the constructor for RNTAB. And we pass the file rnfile to it. So the details of
this we will see soon. But notice that over here we are simply calling the constructor and we are
supplying to the constructor whatever information is needed in order for that entity to be
constructed. So, the information needed is the stream associated with that file. So, inside that
RNTAB constructor the data will be read from the stream and the table will be created.

Similarly, the second important entity is this RSMTAB, the roll number subject marks tab and
for this we need the RSMFILE. So, again we are calling the constructor. And to that constructor
we are passing the stream which is associated with the actual file that the user has typed in on the
command line. So, that was the first thing we said that the main program should do. And then the
main program should have a loop. So, let us see what this loop is doing. So the loop runs
indefinitely until an appropriate command is typed. So, let us see that. So, we have a string
variable command and we will read into that variable. So what do we read? Well, we are going
to read first the command code or other command codes where m, q and r. But if you remember,
the user can also type in control D to indicate end of the standard input. And so what this is
saying is that after this reading have you found that cin has ended or was the command Q. So, if
the command was Q or if the cin had ended, then we should just break out and that is how the
loop is going to be terminated and we come out of the loop and then the program itself
terminated. Otherwise we check if the command is an M. So, if the command is an M, then we
know that it is a Marks query. So, if it is a Marks query then we are supposed to get in a roll
number and a subject name. So, this is how we get that.

Now here, we are simply reading in whatever the user types into the variables roll or name and
subject So, if you remember, our Marks command could be marks followed by name or the roll
number followed by subject. So, we are just reading in one word into name and an expert into the
subject and here we are making a compromise. We are simplifying our problem a little bit. So,
we are saying here that name, if the user types a name it consists of a single word. Otherwise
what we will need to do is we need to do something else. We will need to read in the entire line.
And we will need to extract the name and a subject from it. So, this is something that can be
easily done. But as it is, our program is reasonably complicated as we will see. And therefore, we

1048
are going to skip this business about reading in names which contain spaces. So, I will leave it as
an exercise for you to modify this and I will also present the solution for it. So you will
eventually get the code for doing this as well. But just to keep today's discussion simple, we will
assume that the name or the roll number that is given to us is just one word. So, we get the name,
so we get the roll number or name into a single string. We get the subject. So this is where we do
it. So, from that from the keyboard and then we will use of our table RNTAB and we will look
up in it to get the roll number if this was a name.

So, we are going to send whatever it is the roll, roll number or the name to our roll number name
table and then we will get a roll number for it. So, this roll or name could either be a roll number
or name in which case. So, if it is a roll number then lookup has to do nothing, it just returns it
back if it is a name then this lookup will have to return back the corresponding roll number. And
then, we are going to invoke the lookup function this time in RSMTAB which will give us the
student with the specified roll number in the specified subject and that we are directly going to
print out.

So, that is how this Marks query will get processed. If the command was a rank query, then the
processing is very similar except that there is no subject code needed. So, we are just going to get
the roll number or name following the R and again, we are making this compromise assumption
that it is going to be a single word. And then we are going to pass that roll number or name and
get the roll number. As we said if it if already roll number then we will stay with it. And then we
will find the rank for of this given roll number and then we will print it out. If the first word
typed in by the user is neither Q nor M nor R, then we are going to print out a message saying
that you typed in an invalid command. And we will continue the loop but will give the
indication, given an indication to the user saying that look you printed out you typed in it invalid
command.

(Refer Slide Time: 22:34)

1049
So, let us get back to our presentation. So, we have looked at the code of main. Next comes the
major entity that we created - RNTAB.

1050
(Refer Slide Time: 22:45)

So, as we say it contains vectors of pairs: roll number and name. So, each element is itself going
to be a struct. And we are going to create this directly from rnfile. And the construction code is
in the constructor, not in the main program. The main function of this table is to return the roll
number given the name. And this is performed by the member function lookup. So, what does
function lookup do? Well, it returns the roll number if the argument is a valid name. So for this,
we are just going to look through all the names which are stored in this vector, and its return and
it is going to return a roll number if the argument is a valid roll number. This is slightly tricky in
the sense that the name could either be a roll number or a name and so we are going to have a
parameter R or N to indicate this, this this possibility. So, let us now look at the code for this
entity the struct RNTAB.

1051
(Refer Slide Time: 24:05)

So this is our structure RNTAB. So, what does it contain? So, it is a vector of structures, and the
vector itself internally is going to be called a tab. So, RNTAB is the name of, is the name of the
structure which contains this whole thing. And in the main program, rntab will be the name of
the actual object. But inside this will use tab to indicate the actual table which contains the roll
number name pairs. So, what is the rn structure, well, it is just simply is a roll number name pair.
And first we have the construction code over here.

So, what happens over here? We are simply going to read from this stream rnfile which has been
passed to the constructor. And we are going to read into an rn type object, small rn so we will
read in the roll number and will read in the name and we discussed this earlier, we are going to
assume over here that the names a single word for simplicity and the multi word name aspect we
will worry about a little bit, we will worry about in the exercise. And let me just point out right
now, the multi word names you will have to use getline rather than the input the input redirection
operator.

So, we are going to get the roll number and if the file ended we then break. We have done the
whole thing otherwise we get the name and then the name and the roll number are stored in this
structure rn, we just push back this structure at the end of a vector. So, we keep reading lines and

1052
we construct these rn objects and we keep pushing them on our vector we is tab. So, that is how
we initialize or we construct this table.

(Refer Slide Time: 26:18)

Then there is the lookup part. So, how does the lookup part work? So, it is sent a roll number or a
name, and we are going to go through the entire table, or the entire vector and we are going to
check is the name equal to the roll number, if it is then we return this, the corresponding roll
number. If the roll number is itself supplied, then we just return. So, now, in this we are going
through the entire table. When we go through the entire table, if we do not return anything then
that means this r or n is not found either as the roll number or as the name. So, in that case we are
going to return the empty string. Alright, so that is what this RNTAB is and we have seen how it
is implemented. So, we will take a quick break here before we look at the major data structure
which is RSMTAB.

1053
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 25: Part 3
Medium Size Programs
RSMTAB and rest of the program

Welcome back!

(Refer Slide Time: 0:28)

In the last segments, we have been talking about the manual program the program
inspired by the manual algorithm and we have already discussed the main program and
the RNTAB, the table which gives us the translation from the name to the roll number.

1054
(Refer Slide Time: 0:47)

In this segment, we will talk about the RSMTAB, the table which contains information
about the marks obtained by students with the given roll number in the given subject. So
this is the second major entity in our program after the RNTAB. So, this is a vector, and it
stores triples which consists of roll number, subject and marks. The first function that this
table or this entity or this struct is going to perform is that it will return the marks given
the roll number and the subject.

The implementation is going to happen in the member function lookup. So, I used the
same name lookup here, you should not be confused with the lookup in RNTAB. Here the
lookup is we are looking of the marks; given the roll number and the subject. Over there,
we were looking up the roll number given the name. Alright, so the logic of this is fairly
straight forward.

We are going to scan through the vector and we are going to look for entry in the vector
where the roll number is in the entry is the same as the roll number in the command and
the subject in the entry is also the same as the subject in the command and if we have a
match, then we just report the marks. The second function is returning the rank given the
roll number. Now this is a little bit more complicated because at first we need to calculate
the rank. The rank is not immediately available to us.

1055
So, the implementation is done by a member function called findRank. So the way we
calculate the rank is we first calculate the average marks for all roll numbers. Again what
do I mean by this? So, a particular roll number or a student with a particular roll number
will have taken several subjects potentially. So, we are going to look at the marks
obtained by that student or by that roll number in all those subjects and we are going to
take the average of all of those.

So that is the first step. So, for doing that for calculating the average, we have to first
calculate the total number of marks, we have to find out how many subjects there are,
how many subjects this particular student has taken, and then we just divide the total
marks by the number of subjects. We have to do this for all students because only then
we will be able to compare the students. So we need an array to hold this and our
principle is that all significant entities must be structs. So, we will create another table, let
us call it RTNATAB where R denotes roll number, T denotes total marks, N is the number
of subjects and A is the average. So, we are going to use the table to calculate the average
marks for a given roll number and how does this happen? In the step 1 we will calculate
T and N. So, this is done by the member function insert. So, we will see this member
function insert. So, it will go over RSMTAB and it will look at triples of this kind and for
every roll number, subject, mark triple, it will go to RTNATAB for that corresponding
roll number and it will add the marks into this total. And we do not really need to know
the name of the subject now, we just need to know how many subjects the student is
taking.

So, since, we just added the marks for one subjects into T will increment N the number of
subjects by 1. So this way, you will keep accumulating the total marks and the total
number of subjects taken by the students as we scan through RSMTAB. Then in the
second step, we are going to calculate the average for each roll number. So, we are going
to update this A field. So, A is the average field where A is the average. So that is what we
are going to update and that update is simple. So, we already know the total marks
obtained by the student from step 1 and we already know the number of subjects taken by
the students, so we just try to take the ratio T by N. So, T by N will be stored in A and
then we have this RTNATAB, which contains the average marks for a given roll number

1056
and now we have to find the rank.

How do we do this? Well, we look at our students and will simply count how many other
students there are whose average is higher and the average is already been calculated. So,
for this, we again we just have to scan through this RTNATAB once. So, we will see the
details in a minute. So, now we are going to view the structure RSMTAB and we will see,
how the details of how these functions are being performed, so first we will look at this
lookup and then we will look at findRank.

(Refer Slide Time: 7:09)

So, we are going to look at this RSMTAB. So, let us look at the RSMTAB. So this is our
structure RSMTAB. As I said, it is performing two functions, and the first function is the
lookup function and the second function is the findRank function. The lookup function
requires a roll number and the subject and the idea is actually fairly straight forwarded
what you might guess.

We are going to go, we are going to go through all the entries in this RSMTAB. So, the
all the entries in the RSMTAB. So let us look at this structure RSMTAB so what does it
contain? It contains a vector of struct RSM and the vector we are going to call tab or table
in this in this code. So, let us look at what this vector the vector elements are.

(Refer Slide Time: 8:06)

1057
So, the vector elements are RSM and they are simply the triples. So, the file contains
triples and this vector just contains those triples; roll number, subject and marks. So, how
is the file, how is the table initialized, well, here is the constructor. So, the main program
passes along the streams corresponding to the file and we are just going to read in the
data into the table. So, as before we are going to read into and into a structure and then
we are going to push back that structure on to our table so that takes care of how we
initialize the table.

Next, we are going to look it up and we are going to look at the function which does the
lookup and this function is expecting a roll number to be passed and a subject name. So,
basically, this function, this lookup function is going to tell us how many marks a student
with a given roll number got in a given subject. And the code is fairly straight forwarded
as you might guess; we are going to go over all the entries of this table. If we find a
matching entry, that is if you find the roll number in the entry matches the roll numbers
supplied and the subject in the entry matches the subjects supplied, then we just return the
corresponding marks. Now, these corresponding marks were stored as double and we are
actually going to convert it to string and for that there is a utility function which is
present in the string class and we just use that.

Now why are we not returning a double but why are we returning a string? Well, what if
we do not find the roll number and the subject? Then, we need to return something and

1058
nicest thing to return would be a message not found. So, therefore, we have chosen the
type of this lookup function to be string and so here we are returning the marks by first
converting to the string and if the entry, appropriate entry is not found, then we will
return the string not found so that is the lookup which is fairly easy.

The more complicated thing is the rank find, is the findRank function, findRank member
function. So, here we are given the roll number and we want to find the rank of the
student having this roll number. As we said earlier, we need an additional local data
structure called RTNATAB, so this RTNATAB is going to contain all the data associated
with all the students.

So. it will contain the, it is the structure that we are going to use to calculate the average
and the way this works is we are going to insert we are going to go over the file and we
are going to insert the information about students and roll numbers and marks so let us
look at this RTNATAB.

(Refer Slide Time: 11:28)

1059
So, RTNATAB is as we said earlier, a data structure itself consisting of structures of a
certain type. So, let us look at that. So, it contains structures of the type RTNA so it
contains roll number, a total number of subjects and average. So, how does it get built
up? Well, initially it starts of empty and now we have provided an insert member
function, so what does the insert member function do?

It takes the roll number and the marks obtained by the student, and it says and usually we
will just call it with the marks obtained in one subject, but occasionally, we want to call it
without marks obtained in any subject, so we just want to say that look this roll number
exists and do something about it, so make an entry corresponding to that roll number.

So, that is why we are going to have, we are going to have two arguments over here and
the argument is going to be double with marks equal to 0 and the number of subjects
equal to 0. We will finish discussing this lookup function.

1060
(Refer Slide Time: 13:03)

Now we are going to discuss the findRank member function. So, let me remind you the
findRank member function is going to figure out the rank of the given roll number. So,
for that, it has to calculate the average marks obtained by all students and then see where
this roll number is in that list of marks, so to do that, we will need a local data structure
called RTNATAB, so let us first look at this RTNATAB and then we will see how we are
going to use it.

(Refer Slide Time: 13:44)

So, the struct RTNATAB contains a vector of structs RTNA, so as we have discussed this

1061
earlier, RTNA is simply a quadruple, so it contains roll number, total, number of subjects
seen so far and the average, so the purpose of this is to find out for each roll number,
what is the total number of marks, how many subjects there are and then once we have
built up these two fields, we can just calculate the average by dividing this by this, so
here are the constructors for it. So, there are two constructors, so we can create either a
dummy this is the default constructor and this will construct an RTNA for a given roll
number, so the roll number field, the roll number member will be given a certain roll
number, but at this point we are just starting of this record in our structure that we are
going to keep and therefore, the total and the number of subjects will all be set to zero.

So, let us come to this RTNATAB, so we started off with an, we started off with an empty
RTNATAB and then we have two insertions possible into it. So, this insertion just inserts
the roll number, so if you are just inserting a roll number, this is what we need to do
before we insert any marks. So at that point, we are going to push back the roll number
and the empty data structure onto that roll number. So, basically rtnavec will contain just
the roll number and the other fields will be 0 and then there is the other insert function.

(Refer Slide Time: 15:35)

So, in this case we are going to not, we are going to insert the marks for the roll number,
so how does that work? Well, we are going to go through this table, this rtnavec and in
that rtnavec, we are going to check whether the roll number appears, so if the roll number

1062
appears, then we want to know at what position it appears. So, we have discovered this i,
so we break over here and if we do not break, if we go to the end then i will be equal to
rtnavec size. So, if it is rtnavec size as we check over here then we know that this roll
number is not present in the vector. So, we insert it into the vector. So for this, we push
back this RTNA of roll number. So, this is exactly what we did over here. And now we
have i pointing to the index where that roll number appears in rtnavec, either it appear, it
was already there or it appeared because we pushed it at the last position. So, once we
know that we simply have to add the marks to the total which is being accumulated there
and we have to increment N subjects, the number of subjects have to be incremented, so
that finishes this function of insertion, so let us see how this function gets used in our
findRank function.

(Refer Slide Time: 17:20)

1063
So here is the findRank function. So, what are we going to do? Well at position 0 or at the
very beginning, we make an entry for the roll number whose rank we want to determine,
because we are going to quickly need the average marks for this roll number and so we,
so let us just place it at position 0. So, I have written it first so I really mean zeroth
because we are counting from 0 over here, so we inserted it at roll number 0.

Then we went through our table, our RSM table tab refers to that RSM table and we took
the roll numbers from it and so we looked at the size of our RSM table. So, remember all
this is in the context of our RSMTAB, so let me just position it properly so that you can
see what this tab refers to. So, this tab is referring to this RSMTAB, so if you remember
RSMTAB consists of roll number, subject code and marks. So, we are going to go
through all the entries. So tab[i].roll number is the roll number of i th entry. We are not
concerned with the subject name but we are concerned with the marks. So, the ith entry
tells us that roll number tab[i].roll number has got tab[i].marks in some subjects and
since, we want to know what is the total number of marks that this roll number has got,
we are going to insert this into RTNATAB. So, this way we end up inserting all the marks
got by all the roll numbers into this RTNATAB and RTNATAB at this point will include
for every roll number what is the total number of marks and what is the total number of
subjects taken by that roll number. So we are just about ready to calculate the average and
what we do is we will do it directly. We will just call RTNATAB of getRankOf0().

1064
(Refer Slide Time: 19:45)

So let us go back and see that, so getRankOf0() is going to start off with that roll number,
so that we well, we have not said what the roll number is but the roll number in the zeroth
position. Now, in the zeroth position did we insert any subjects, well, we may or may not
have, so we are going to have to check, so if the n subjects is 0, then in going through this
like entire RSMTAB, we did not find the given roll number, so we are immediately going
to return not found.

Otherwise, first we are going to calculate the average, so here is the average being
calculated. So, for all the elements in the table we are just going to set rtnavec[i].average
equals the total divided by the number of subjects. So, at this point, when we come to this
point of the code rtnavec contains the average marks obtained by every student and now
all the remains is to compare the marks of the zeroth entry, the entry the roll number that
we are interested in which we cleverly stored in the zeroth position. So we are going to
we are going to get that entry and we are going to compare the marks of that entry with
all other entries, so we are going to go over the entire table starting at i equal to 1 and if
we, wherever we find that the marks of some other roll numbers are larger than the marks
of our roll number, then we are going to increment rank by 1.

And we started off with rank equal to 1, so that at the end of it whenever we find the
higher average marks, our rank will be incremented eventually we will get the

1065
appropriate rank and again we are going to convert it into string and return it back
because we potentially also want to return not found over here.

(Refer Slide Time: 22:16)

Alright, so that completes the description of this RSMTAB and internally it used this
RTNATAB as well.

1066
(Refer Slide Time: 22:42)

So, let us return back to the presentation.

(Refer Slide Time: 22:50)

So, there are number of points to note in what we have seen. In some sense, the algorithm
or the logic is quite simple or routine. I mean there are lots of things to do, but what we
are doing is not particularly clever. We are calculating averages, we are finding out how
many averages are bigger than the average of the roll number of our interest, so a lot of
things to be done, but the logic itself is fairly straight forwarded.

1067
The key issue is how do we organize this so that the code looks easy to understand, so the
issues has always are keep the main program at high level, details should go into
functions and member functions and we have to make structures for major entities. So the
major entity from the point of view of the main program was RNTAB and also RSMTAB
but while processing RSMTAB, while calculating the average marks, we had to create
another entity called RTNATAB.

So this was, this again we made, for this again we made a structure and we have to try
and give good names for variables and at the end of it, I have to say that this is an art and
not science and you may not like every step that I have taken; you may say that, “Oh, I
think I can write this step better”, and I will invite you to do that and this is an art in the
sense that what you like, I may not like. But the point is you still have to appreciate these
points, that you have to appreciate that code has to be understandable and at least
according to your sense of what is easy or what is easy to understand or what is elegant
you should be developing the code and you should be developing this sense of what is
easy and what is easy to understand and it is of course, possible that your sense of what is
easy might be better than my sense of what is easy and I will definitely invite you to
improve the code that has been given and make it more easy to understand and that is
certainly an ongoing process.

(Refer Slide Time: 25:41)

1068
Alright, so what have we discussed in all of this? We have discussed a simple, somewhat
naive solution. It is simple and naive in the sense that it is sort of repeats computation and
we have seen how the code for this can be organized. Next, we are going to see some
sophisticated solutions. So we will take a break.

1069
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering,
Indian Institute of Technology Bombay India
Lecture 25, Part 4
Medium size programs
Sophisticated solutions to marks display
Welcome back, in the previous segment we discussed a simple solution based on manual
algorithms for our marks display problem, next we are going to turn to somewhat more
sophisticated solutions.

(Refer Slide Time: 00:32)

So to motivate those let us consider the drawbacks of the previous solution, so both queries are
going to be too slow if the number of students, number of subjects is very huge, say if you are
going to do this for your entire university, then you will notice that the previous solutions will be
quite slow. The marks queries slow because we go through the entire RSMTAB on every query
so we want to look for the marks of a given student, but we go through the all the marks of all
the students.

Now, if we sort RSMTAB by roll number and subject we can use binary search to find the
marks. We know this idea and if we implement these ideas then we will be able to speed this up.
The rank query, we calculate averages on every query. So, if I want the rank for a certain roll
number, we calculate the average marks obtained by all ranks. If we then need to find the rank of

1070
some other roll number we again go through the entire process. So the natural question is why do
not we do this once at the very beginning and then just store those things. In fact, once we have
calculated the averages calculating the ranks itself is just one additional step, and again why
should we repeat why do not we do that at the very beginning, it will save quite a bit of time
while processing the queries themselves so that is another thing we should really be doing.

(Refer Slide Time: 02:22)

Now, there is another approach besides sorting and binary search which will work. So, sorting
and binary search will work, but we want to suggest one more approach and this approach is
going to be based on maps. Maps effectively produce the effect of sorting, and accessing maps
happens really by a process like binary search, in fact sometimes it is even faster than binary
search. But let us say it is sort of as good as binary search, so effectively what happens is that if
we use maps, we are going to get speed as well as coding simplicity.

1071
(Refer Slide Time: 03:03)

So, let us first look at the marks query so let me remind you what the query was, the query was
M followed by roll number followed by subject code and of course you could have given the
name, but let us that is a minor matter, so let us just focus on M followed roll number followed
by subject code. Given a roll number and a subject we want to return the marks. Now, if there
was just one subject what would you do? Well, since we know about maps we could just use the
map from roll numbers to marks.

What can we do for multiple subjects? Well we can use the map so the index will be a roll
number and the value that the map produces for us could be something like all marks of the
students. So, subject wise marks of the students, so the value that is produced is not one mark but
all marks. So, may be it produces a vector, so what do we do with all these marks? How do we
go from all these marks to the marks in a particular subject?

Well a natural idea will be to use another map because what are these subject-wise maps
anyway? So they are telling us that say in mathematics the marks are so many for this given roll
number, for this fixed roll number, in physics the marks are so many, in English the marks are so
many. So, this is again a map, so the output of this map which where the index is roll number
should naturally be another map. So, effectively what we are going to do is we are going to use a
2 level map.

1072
(Refer Slide Time: 6:02)

So, let us see how this works. So the level 1 map, let us call it marks and marks[roll number], the
value produced by this map is itself a map. And what is this, it is a map which gives marks of
any subject given a roll number, so given a roll number means the index for this map that is
returned by this map is the roll number. So the overall map is as follows, so the 2 level map is
also going to be called marks but if we just supply 1 index to it, it is going to give us a map and
if we supply the 2nd index, which is the subject, then it will give us the marks for the given
subject for the given roll number.

So, how will we declare something like this? So the declaration is the 1st index type, the 1st index
was a roll number so whatever type we are going to have for the roll number we are going to
place over here and the 1st the while the overall thing is a map which takes a roll number and
produces a value but the value is itself a map. But what is this value? It is a map from a subject
type to a marks type. So we are going to have 2 indices, the 2nd index is going to be a subject
index and the value that that returns is going to be a marks type.

Now, in our case, roll number type and subject type are both string and marks type is double and
so the actual declaration is this. So, map<string, map<string, double> > and if you remember we
have to put a space over here because if we do not then the C++ will interpret it as the input
redirection operator, we do not want that to happen so this is the type declaration for our map. It

1073
really similar to vector of vector of T and as just as this is a matrix or this accessed using 2
indices, this is also accessed using 2 indices.

(Refer Slide Time: 07:50)

So, what is the solution for this query or the entire thing actually, let us start with the entire thing
first. So, the main program you will see is going to be unchanged and in the sense we should
expect this, because the changes are at a low level, at a high level the queries format remains the
same and our main entities our main tables are going to remain the same. But the internals of the
table are going to be different. And well we are going to change the name of RNTAB to NRTAB
for some reason which will become clear in minute but this is only a cosmetic name change. The
program really is unchanged and there are again only these 2 tables. And while we have not
designated any member functions as public or private, but if we were to and I guess once we are
done we should designate some functions as public and private. So, the public member functions
will remain the same. So, what are the public member functions for RNTAB? So there was
lookup here and for NRTAB there was lookup and findrank, so those will remain the same. But
the private member functions that we had, they will be different and even the data member were
be different and the entire logic of these 2 tables is going to be different because now they are
going to be using maps.

(Refer Slide Time: 9:21)

1074
So, how does RNTAB or what we are going to call NRTAB work? So it will not hold a map
instead of a vector. Now maps have a direction from index to value and we want this table to
give us a roll number, given a name. So the index is a name and a value is a roll number. And
therefore, we are going to call it NRTAB, to say that it goes from name to roll number, so that is
the only reason why you are changing a name.

So, NRTAB is a better name, and for some reason which will become clear a little bit later we
are going to keep the reverse map also. But that is not going to be the main map, so in fact, we
will call it the reverse map so to know what is reverse and what is forward it is important to give
NRTAB as the name for the entire thing. So, we will see the details soon, in fact, immediately,
because now we are going to look at unchanged main program and our main first major entity
NRTAB.

1075
(Refer Slide Time: 10:36)

So, this is our 2nd marks display program and I have called it marks 3, sort of marks 2 would
have used binary search and sorting but we have skipped that and we have gone to directly
version 3. So, let me show you the main program first, the main program really has remained the
same except for this name. The name is NRTAB rather RNTAB. So, now let us look at this
entity NRTAB.

So here is out entity NRTAB. So as I said it is going to contain a table which is a map now, and
it is a map from string to string but it is a map from name to roll number. And we will also keep

1076
a reverse map and we will call it REVTAB, and it will give the name given the roll number. So
how do we construct NRTAB? so the data is going to be taken from rnfile which was a stream
corresponding to the file opened on 3d in the main program? And we are going to go through this
file or go through this stream, and as before we are going to read the pairs rno and names so we
need to read the roll number into rno and if we find that the file has ended, then we break
otherwise we read the name and we store in the table, the roll number corresponding to the name.
So, now this is a map and so we can just store it in this manner. And by the way even here we are
assuming that the names are single words. So, as indicated earlier, you can do a little bit more
work to deal with the case where the names are longer and contain spaces. In the reverse tab, we
are going to store the roll number as the index and the name as the value. And now what does
lookup look like? Well, as before we are going to supply it an argument which would either be a
roll number or a name. So, we are going to check - does this appear as an index in the forward
table? And for that we just have to ask tab of count of this greater than 0. If it is then we know
that it is appearing as an index in the forward table so that is it is a name. So, in that case we are
going to return tab of this index otherwise we are going to check does it appear as the index in
the reverse table. The reverse table has roll numbers as indices, so if this does appear we are still
going to return that itself, but why we are doing this, well we want to know whether this is a
valid roll number. So if it is a valid roll number, then we will return itself. If it is not a valid
name or not a valid roll number then we are going to return the empty string. So, this return
protocol is exactly like the protocol like we had in the previous implementation as well. Now, I
want to make a comment over here, this reverse table we are not using in any sensible way. We
are not really indexing into it we are just checking whether the given string appears as a proper
index or we are checking whether is given string is a member of the indices in the set of indices
in this table.

Now for this we could have used the set data structure from the standard library, and that is the
similarity restriction but I use the reverse map since you have not really learnt about it, you could
keep this implementation or we could learn the set data structure and in fact, now that you are
coming to the end of the course you could get into the habit of looking up new things when you
hear about them.

1077
So, this is something you could try out. In any case, I have told you how NRTAB is organized,
and you can see that it is actually simpler because the whole searching business is now gone.
And the map data structure and the map standard library structure takes care of all of that. So, let
us go back to the presentation.

(Refer Slide Time: 15:56)

So, now let us look at RSMTAB, so RSMTAB is going to hold 2 structures. So there is going to
be a TAB, which is going to be the 2 level map which we talked about earlier into which the
content of RSMFILE is read. But then as we discussed, we are going to precompute all the ranks
to begin with. So, this is going to be stored again in a map, so its index is going to be the roll
number and we are going to create this when we create the entire RSMTAB.

So, we are calling it the RSMTAB, but internally it also contains a table for the ranks. So, how
RSMFILE is read is probably quite obvious by now. It is pretty much like how the RNFILE was
read to create RNTAB or NRTAB, we will similarly read RSMFILE and create this first tab.
How do we create the rank? So, that is a little bit more interesting. So first we have to calculate
the average marks for each student. So we have our tab, and we want to add up the marks in
tab[roll number], tab[roll number] if you remember, is going to give you another map it is going
to give you a sub map. So what is that sub map, the sub map is going to be a map from subjects
to marks. So the sub map gives us all the subjects at this particular roll number has taken and we

1078
are just going to add up those marks and divided by the number of subjects. So this is how the
sub map structure is actually coming in quite useful. And then we are going to store the roll
number and the average marks which that we got over here into a vector called roll number
average, so this is going to be a 2nd an additional data structure that we will need, but this is
going to be a very temporary data structure as we will see. So, we will not put it up as a major
thing over here, so we are going to store the roll number and average pairs into this vector. Then
we are going to sort the vector by average marks and when this happens we will have the entries
arranged in decreasing order of average marks and so then we can go over these entries pick up
the roll numbers as they appear and those are the rank holders. So the earliest roll number is rank
1, then the next is rank 2 and so on. So, at the end of this step, roll number average will now
contain roll numbers in order of ranks and so we can just enter them into the map called rank. So
that is how all this is going to work. So, let us now take a look at the code of RSMTAB. And I
want to tell you beforehand that it is going to contain the library class pair. So this pair is going
to be used, this is what is going to be stored in this vector roll number average. So let me just
introduce this pair class a little bit. So what is the pair class, so the pair class contains 2 elements
after all it’s a pair and it is really like a 2 element struct. So, it is a 2 element struct that you do
not have to, you can sort of define as you go along. But there are some important things that are
already defined for pair, for example you can compare 2 pairs without actually yourself defining
a comparison operator, if you have defined a struct, then you would have to define the
comparison operator but if it is a pair a comparison operator is implicitly defined.

So, how does it work? If you are comparing 2 pairs, then you first compare their x values then
you compare their y values. And if you find that the x value of one is smaller than the other, then
you declare that to be smaller. Only if they are equal, only if the x values are equal you move on
to y. So here is another class and as I said this is a new class, I am going to show you the class
and I am going to explain enough about the class but you should not get scared of seeing new
things at this point.

So, as I said you are pretty close to the end of the course and at this point you should have the
confidence to be able to lookup documentation. So, see the online documentation on pairs to
know more about them. So let us know go and look at the code for RSMTAB. So let me just
make this a little bit bigger. So, as I said this RSMTAB.

1079
(Refer Slide Time: 21:44)

This is the structure RSMTAB, our 2nd major entity and we said that it contains this 2 level maps
called TAB which will be index by, the 1st index being be the roll number, the 2nd being the
subject and then this our rank map. So this given roll number will return the rank. So, the
construction of RSMTAB is fairly straight forward. I am not going to go through it, but let me
just look at how the ranks are going to be created.

So for that we have a member function called setup ranks, so this member function will use a
local variable which is a vector and this will contain the pairs, the elements of this vector will be
pairs, and they will consist of a double and a string. The 1st element of the pair is supposed to
hold the average marks when they are calculated, and the second element of the pair is going to
hold the roll number. So, how do we setup the ranks? First, we are going to over the entire
RSMTAB, so RSM is going to be an entry in this table. So, essentially we are going over each
student, so remember that the first index of this is the roll number. So, what we are picking out
over here is an element of it so which means for a fixed roll number, we are going to get the
entry. So, we are going to set total to be 0 and we are going to calculate what the total marks are,
corresponding to every entry in this. So, the roll number is going to be obtained by taking the
first element member of this pair. RSM itself is a pair just like these other pairs. So, the 1st
element is this RSM.first so that is the role number and we are going to push on to this average
rank, this part is going to be the average, and this part is going to be the rank and this loop is

1080
going to be about calculating the average. So, how do we calculate the average? well we are
going to set total to 0 and then we are going to go over sm, which is the 2nd part of this RSM.

(Refer Slide Time: 24:47)

So, I think I should draw picture over here. So, TAB was consisting of pairs, so the pairs we
have called RSM so there are several such pairs. And this itself consists of pairs, because it is a 2
level map. So these are sm’s. So RSM consist of pairs, so what does our TAB look like? So TAB
or rather I should say our tab look like, so tab you remember takes 1 index which is the roll
number and the other index which is the subject.

1081
And therefore, if I look at RSM which is an entry of TAB what does it look like, well this tab is a
bunch of pairs, so what are the pairs in it? so each RSM looks like a roll number and then it looks
like a map itself. So, this is the 1st and this is the 2nd entry in this pair. So over here, when we
fetch an element of this tab, what we are getting is a pair like this. So we have got the roll
number, so what we are doing in this loop is we will be calculating the average for a given roll
number. And then we are going to determine the average for it and we are going to push it
against the roll number. So our average rank vector will get the average over here and the rank
over here, so as you can see that is the last step in this 1st procedure. So, in the 1st procedure, at
this point, we have only calculated the averages and they are pushed on this vector. So how are
they pushed well this part is the roll number and this part is the average and this part is being
determined over here. So, let us see how it is determined, so RSM is all this. So, RSM.second is
going to be this map, so what is this map, so this is a map from subject to marks. So it is pairs of
this kind. So what is happening in this loop is that we are picking up each such pairs, so sm is
going to be a pair subject and mark, so sm is this so total, we are going to create a total for this
given roll number, and we are going to add sm.second to it. So rsm.second is the mark, so this
we are going to add to total, so at this point after we have executed this entire loop, what do we
have. Well we have the total marks obtained by a given student in this variable total. So if we
want the average, we are going to divide total by RSM.second.size. So what is RSM.second?
RSM.second is this entire thing so it is subject marks subject marks subject marks for a given
student. So, how many such entries are there, so the number of such entries are the number of
subjects. So in fact this quantity is simply is precisely the number of subjects so we will indeed
get the average marks over here. And this is the roll number, so at this point this vector average
rank will contain the average marks and the roll number.

(Refer Slide Time: 29:44)

1082
Next we are going to sort this vector; we are going to sort the average mark vector. So if we had
just said the usual things sort average rank begin to end then we would have got the sorting in
increasing order, we want it decreasing, so we pass it the function greater, the greater is
equivalent to the operator greater than. So, greater than if we pass the greater than operator over
here then we are going to get sorting in decreasing order. Otherwise by default, if we do not say
anything, the less than operator get passed over here and therefore we get the usual sorting but
we want the other sorting and since we want decreasing order, we pass the greater than operator
and I said earlier that all such operators are already defined on pairs. And they are defined in sort
of lexicographic order that is the 1st sort on this field and then they sort on this field. So if this
field is different then they sort on this field. But what is this field, this is the average and so at the
end of it this vector will be sorted on the average. So it is sorted on the average, so all I have to
do, is to go through this vector, so we are going to examine every element of this vector and if I
come to an entry of this vector, will the Ith entry of this vector has 2 parts. 1st part is going to be
the average marks, and the 2nd part is going to be the rank associated with that average marks.
But I do not care about the average marks I care about the roll number and since this roll number
averageRank[i].second appears at position I in this vector I know that its rank must be I, if I
count ranks starting at 0 but I want to count starting at I plus at1 and therefore its rank I am going
to set to be equal to us I plus 1. So, what now I get is that I have built up my rank table as well
over here in my RSMTAB I had this rank map, and I have built it up as well.

1083
So, that is what we need to know about this RSMTAB and our find rank function is now
extremely simple. The calculation was already done, and so if the roll number appears in this as
an index in this array we just return there and we just already calculated. Otherwise we return
minus 1. I guess would have even here given that use of protocol of returning the string and we
could have said not found.

1084
(Refer Slide Time: 33:11)

But that is an improvement that you certainly should make to this code. So let us return to our
presentation. So as you can see the code is actually smaller than the previous implementations
and that is because the library codes are not only faster but it are also a lot more compact. The
member functions for maps do a lot of interesting work, they effectively do something like
sorting and it is easier to understand actually because in some sense maps are intuitive I mean the
notion of mapping an index to value this is quite easy to understand.

So, if you are having a difficulty with maps that is ok, in some sense, maps are a bit of an
optional part of this whole course. But I think many people will understand maps, and if you do I
think you should see how powerful they are and you should start using them when you code.
And by the way, in this entire thing I have used maps but I could have used unordered maps as
well. So, unordered maps will also be perfectly fine for all of this. And I should again point out
that the main program has not changed, so in some sense this means that our decomposition of
our logic into high level and low level seems like a good decomposition.

1085
(Refer Slide Time: 34:47)

So let me make some concluding remarks, so the main concern in this entire lecture was how to
organize code so as to put everything in its right place. Why should everything be in its right
place, well it is like why everything in the room should be in its right place because if it is in its
right place, we know where we should be searching, we know where we kept it, we know where
we will find it that kind of thing.

Then we should make functions small to improve readability, we should make code self
documenting, well of course we can write comments, but we have not discussed that but better
than that is to write the code in a very obvious manner. So give the names of the functions, give
the names of variables nicely so that the logic is very obvious. In addition to that, we considered
some additional principles. So we set something like represent important entities using
structures. When we said that if there is an important action, then you should have a named
function doing it, or a named member function doing it because then it is giving importance to
that piece of code and giving it a name which helps in readability and we also said that the main
program should indicate high level program structure, and the detail should get implemented in
function calls.

So, that concludes this lecture and you are invited to go over the code and you are invited to
make the code even more readable. And certainly you really should develop a taste and you do

1086
not have to take my taste, but you should develop a taste and you should have a notion of what is
the right way to write this piece of logic, and you should try to develop a consistent style so that
at least you yourself will be able to find your code and hopefully it will be easier for other people
also to understand your code and find things in it very easily. So we will conclude with that and
Thank you.

1087
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Science and Engineering
Indian Institute of Technology Bombay
Lecture No 26 Part - 1
A Graphical Editor and Solver for Circuits

Hello and welcome to the NPTEL course on an Introduction to Programming through C++. I am
Abhiram Ranade. Today we are going to continue our discussion of medium size programs and
we are going to write a program which will be a graphical editor and solver for the circuits.

(Refer Slide Time: 00:37)

So, I should point out I should observe that computers are often used for designing various
objects, circuits, mechanical objects, chemical plants, and lots of other things. CAD or Computer
Aided Design systems, employ graphical user interfaces which are often abbreviated as GUI.
And you have already seen this in our IDE, a there are buttons and you have clicked buttons to
tell the computer what you want to happen, or you may also have menus. So, our goal for today
is to figure out how these things are actually implemented. And we will be doing a very
preliminary a baby computer aided design program using which will have a graphical user
interface. And, it will design and solve very simple circuits. But it will contain the germ of many
ideas and you will be or you should be extended to do more complicated things, even things
which might be professionally useful. So, let me just talk a little bit about the circuits that we are
considering.

1088
(Refer Slide Time: 2:05)

So, circuit is made of components connected to each other at nodes. Here, is an example. So, in
this example, these black disks, so by that I mean these things, this one, this one, this one are
called nodes or we will call these nodes. And, components are current sources or resistors. So,
for example this is a resistor, this is another resistor, this is what is called a current source. So,
you can have many many other kinds of components, but as we said this is a baby program and
we are only going to consider these 2 components. Each component is connected between 2
nodes, as you can see voltage sources, current sources are connected. So, between these two
nodes we have a resistor and also a current source and between these two nodes we have this
resistor and so on.

And, when we say solving a circuit, what we mean is determining the voltages at the different
nodes. So, because current is flowing through these components, it will produce voltages or
potentials at, at the nodes. And it will and of course there is a question of how much current is
flowing through each of this resistors, or other components that may be there in the circuit. So,
when we say let us solve this circuit, we mean figure out what are the current and voltages in it.

1089
(Refer Slide Time: 03:42)

So, our program is going to be quite simple, very simplistic in fact, and it will perform the job
that I have described but it will lack many features. The appearance will be functionally
adequate, but it will not be elegant or beautiful. It will not draw for example the circuit the way
you just saw it, it will be a little bit more schematic, and again the point is to get started and the
main ideas will be there and you will be able to build upon them if you wish.

Yeah, so you can start with what we present and improve upon it. And, our goal is to illustrate
the basics issues. And, I also want to mention that this is going to be another example of medium
size programs. So, as we write it you will get another example of how medium size programs
have to be organised. So, here is what we are going to do. I am immediately going to start off
with demo of our program.

1090
(Refer Slide Time: 04:50)

So, so I have written the program and I will show it to you and then we will see, I will lead you
towards its design. Yeah, so in the demo we will actually use the program to design a very
simple circuit. And we will use the program to solve the circuit that we designed. Then we will
talk about the design of the program. So, the program will consist of a main loop, and then it will
have some data structures and we will discuss how the functionality is divided between the data
structures and the main program. And as I said, the organization will follow certain the general
principles that we have been talking about as far as designing medium size programs is
concerned.

1091
(Refer Slide Time: 05:43)

So what have we discussed so far? So we have said that CAD or Computer aided design is an
important application of computers. Computer based design programs often use graphical user
interfaces because these are very convenient, you see what you are doing and pictorially seeing
something is very convenient and it tells you exactly what is going on in a very nice way. We are
going to design a baby CAD program which will be useful for designing and solving resistive
circuits in particular circuits which contain resistors and current sources. And next, I am going to
show you a demo of the program but before that let us take a quick break.

1092
Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology, Bombay
Lecture 26 Part 2 – A graphical editor and solver for circuits

(Refer Slide Time: 0:23)

Welcome back. In the previous segment we talked about computer aided design in general
and graphical user interfaces. And what we want to do in this lecture which is designing a
computer aided design program for solving, for designing and solving resistive circuits. So
we will begin this segment with a demo of the program. So the program is in the file
circuit.cpp which I will show you but I will, we will discuss the program a little bit more in
detail later on. What I want you to observe when we run this program is that there are buttons

1093
in it and then these buttons enable you to add nodes, conductances, current sources. And then
the buttons also allow you to solve. And I would like you to observe the solved output.

So, I am going to talk about conductances over here. So conductance, the conductance of an
element is the inverse of its resistance. So, these are just these are just two terms used to
denote the parameter of a circuit component. So, it makes more sense to talk in terms of the
conductance rather than the resistance and that is why we will be using that term. So, let us
do the demo.

(Refer Slide Time: 1:51)

1094
So, this is our program. I am not going to show you show it to you in great detail right now.
But let us compile it and let us run it. Let me bring it a little bit towards the centre. All right.
So, this is the main canvas created by the program. And you can see these four rectangles
which are buttons they are called buttons because if I click on them then some action will
happen. And each button typically has a label. So here the labels are node, conductance,
source, solve and quit and then labels are there just to tell you what the function of the button
is. So this button called node allows us to create nodes in this which will be parts of our
circuit.

So, let us start with that. So, I am going to click on node and now I am allowed to click on the
canvas and then that will create a node. So, for example this has created a node which has
been numbered 0. I want more nodes. So, I will click once more. Now I get node 1. I will
click one more time and I will get Node 2. So, I am going to have a very simple circuit just
three nodes and three components. So, I do not need any more nodes. So now I want to add
conductances.

So, I click on conductance and now I am expected to click on two nodes which have been
created earlier. So, I will click on this node and I will click on this node. And as a result we
will have a conductance inserted between these two nodes and furthermore you can see here
that I am expected to type in the value of the conductance. So, let us say I type in 5 as the
value. So you can see that that value has appeared over here. Now in the circuit diagram I
showed you. There was a very specific standard symbol of resistance drawn over here.

1095
So, we can do that, we can do that. But just to keep this program simple, and because I want
to illustrate the main ideas rather than the details, I have kept this quiet simple. Anyway, so
what has happened is that we have been able to insert a conductance between these two
nodes. I want one more conductance and let us say I put down a conductance again, so I click
conductance and now I can click two nodes again. So, I click this node and I click this node,
so another conductance has been entered and I have I am asked to give its value again. So, let
us say I will give you the value again as 5.

So, you can see that 5 has appeared over here. Now I want to put in a source. After all, unless
we have a source no current will flow. So, let us put down a source over here and let us say I
am going to make the source push current from vertex 2 to vertex 1. So, I will click here first.
Then I will click here. And now I am going to, I have to type in the source strength. So let us
say my source strength is 5 or this is going to force 5 amperes of current through the circuit.
And by the way the conductance values were mhos, or 1 over ohms, if you like.

So, what has happened now is that this current source has been placed over here. Its value is
5. And as you can see the direction has been pointed out. So, the direction is going from 2 to
1. And you may recognize this as our turtle. So, I put down the turtle over here. But I really
should put down something more consistent with the voltage source, like a current source
picture like the one we saw earlier. But again, I wanted to illustrate the main ideas and this
was sort of the easiest way of doing things. So we will see this, how exactly this has been
done but what I have done is that I have imprinted the turtle so as to give the direction of the
flow of the current.

So, now say we ask this to be solved. So, if we solve this, so I have to click on this. So, if I
click on this, what happens is I get the potentials at the various nodes, I guess I clicked it
twice and therefore I got the potentials two times. But anyway, so what has happened? So,
this says that node 0 has 1v potential, 2 has 0v. And 1 has potential 2, ok. So I think that these
values are inverse but they are actually resistances. And so I am pushing, so I am pushing a
current of 5 amperes through this. Sorry, they are mhos and so if I push a current through 5
amperes so let us just calculate what happens.

1096
(Refer Slide Time: 7:42)

So I have a 5 ampere current source and it flows through 1 over 5 ohms resistance. And over
here also 1 over 5 ohms resistance. So, what does this do? So, the total resistance is 2 over 5
ohms. And so the current equal to voltage upon the resistance. And so we have 5 equals the
voltage upon resistance. And so, the resistance and the resistance is 2 upon 5. So, the total
voltage drop is 2 upon 5 times 5 or equal to 2 volts.

(Refer Slide Time: 8:42)

So, what has happened over here? The total drop from here to here is 2 volts as we calculated.
And as you can see the potential at 1 is 2 and the potential at 2 is 0. So indeed there is a total
drop of 2 volts going from here to here. And furthermore the potential in the middle is exactly
half and that is to be expected because we have half the resistance over here and half the

1097
resistance over here as well. So, our program has worked, it has solved the circuit, it has
allowed us to design the circuit and solve it and it has solved it as per our expectation. So at
this point we can quit the program, for that we press the quit button. So, now I can go back to
our presentation.

(Refer Slide Time: 9:32)

So, let us continue. So, what are the main ingredients of the program? Well, the immediate
ingredient to hit you is the onscreen buttons. And we observed that there is a label and that
label is meant to indicate the functionality. And this means of course, that in our program we
need code to decide whether the user clicked inside a button. So, if the user clicked inside the
button, we need to take certain action depending upon which button the user clicked. Then
there were these circuit elements, nodes. So, these appear as circles on the canvas. And we

1098
also put down their number inside the node itself. And again, we had to click the buttons,
click the nodes when we were inserting components.

So, again we need code to decide whether a click is inside a node or where is it. And nodes
will also appear in the mathematical representation of the circuit. So after all, we just do not
want to do a drawing. We want to solve the circuit. So, what is going to happen? Well. A
drawing will get made, but as the drawing is made, we will be building up a representation of
the circuit itself. So, collecting all its data and putting it into a nice convenient data structure.

So nodes will appear in that data structure as well. And exactly how they appear, I will talk
about in a minute. Then there are two major circuit elements, resistors or conductances and
current sources. Again they should appear suitably on the screen. And for now, in our baby
program we are not going to have any occasion to click them. But in general, we may want to
have, make them clickable. So, if we do that then we would need to have code to check
whether clicks are lying inside these components as well. And these components will of
course appear in the mathematical representation. So, let me say a little bit about how our
program seems to be required to be organized based on what we just said. Well, as you saw it
had a main loop. In the loop the program was waiting for the user to click. And based on
what was clicked, the subsequent actions were different. So, if I clicked the node button, then
clearly the program did something so that subsequently a node was created. So, presumably,
it called a function and that function was the one which was responsible to enable the user to
create nodes. And similarly, if you create if you clicked conductance, then a function would
have to be called in order for the user to be able to create conductances. Then we needed to
do some management of the canvas. So, what do I mean by that? Well, we need to draw the
circuit elements. I also, I already said that we need to be able to decide whether the clicks are
inside the circuit elements. So we need to decide what is clicked. And then there is the
mathematical representation. So, the mathematical representation is what is needed for
solving the circuit. So, this is sort of what we can say based on observing the program that we
just ran.

1099
(Refer Slide Time: 13:37)

So, let me talk about the main program. So the main program will create the main entities.
So, these are the buttons, and it will create a data structure that manages the screen. And it
will create a data structure that keeps track of the mathematical representation of the circuit.
And indeed, it will go into a loop. So, inside the loop it will call appropriate functionality
depending upon what button the user is clicking. So now we are going to take a look at the
main program.

(Refer Slide Time: 14:13)

So, here is the main program. So as you saw, as we discussed it sort of creates the main
things. So, what are the main things? Well, first of all, obviously it has to create the canvas.
And then it has to create these buttons which you saw. And then it has to create the

1100
mathematical representation and a data structure which manages the drawing on the canvas.
As this data structure, ok. So, in the process of managing the canvas, we also have to modify
the math representation. And therefore, we will pass it a pointer to the math representation as
well, so that once it modifies the content on the screen it will also add relevant information to
our math representation.

Then there is the main loop. So the main loop has the program waiting for a click. And at this
point a click is expected only in one of these buttons. So, if you click button node then you
are going to ask your canvas content data structure to get a node added. Similarly, if you click
in b2 which is this button, the user is telling the program that look, I want a conductance
added and therefore this function will be called. Similarly, a source addition function will be
called. And if you click this b4 button then you want things solved. You want the circuit to be
solved.

Well, if you want the circuit to be solved, then you may directly we may directly call the
solve member function in the math representation. And finally, if button b5 is called, which is
the quit button then we want to break and after breaking the entire program will terminate. So
what has, so some remarks about this main program. As you can see, the main program is at a
very high level. So, it is creating buttons. How exactly the buttons are created? So, R is a
rectangle being drawn, some text being put inside it. That is not discussed at this level. So the
constructor is called and we will see the constructor in a minute. But the constructor is going
to handle the job. Yes, the constructor needs to be passed some values and those values are
being passed and we will see what exactly those values mean. And then again, so the main
program is creating all these entities. And again, as I said, the creation is the actual creation is
in the constructor which are in the definitions of the entities. So, at this level we are staying
quite high. We are staying at a high level, and we are just setting things up and the details we
are not worrying about and similarly over here. Exactly what happens? What needs to happen
in order to add a conductance, that is not discussed over here. That is a part of this member
function. So, let us get back to the presentation.

1101
(Refer Slide Time: 17:53)

So, next we are going to discuss the class button. So, this has to appear as a rectangle with
text inside it. And we are going to take the following approach. So the rectangle and text
could be made graphic, graphics objects. So we could have, we could create graphics object
of type rectangle and of type text. But in this program that is not needed because once we
create that rectangle we are not going to have any occasion to move it around. Similarly, the
text is not going to change. If that were changing, then it would make sense to create these as
graphic objects.

So, to keep the functionality simple we are simply going to imprint. So, we are simply going
to imprint the rectangle and the text on the canvas. So, we will see this in a minute and then
we will have a member function in which will say whether a click point is inside the
rectangle. So, that is how we will get to know whether a button has been clicked. So, let us
now view the class button from our program.

1102
(Refer Slide Time: 19:08)

So, this was our main program. And as you can see the main program is creating each button
and it is passing some numbers and then the button is going to be called with the member
function in. So, in is going to be passed what value the click returns. So, let us see how all
this is going to work.

(Refer Slide Time: 19:34)

So, this is our class for representing buttons. So, it has data members x, y, w and h. And these
data members are going to keep track of the centre of the button. So, that is the x y will be the
centre of the button. And w will be the width, h will be the height. Now here is the
constructor which is going to be called with the title that should appear and then the x, y, w
and h are passed as parameters. So these parameters are stored into the data members and

1103
then we create the rectangle. As you might remember, to create the rectangle, we need to
specify the centre coordinates and the width and the height. And then we need to, and we said
we are going to imprint it. So, by the way this is also a constructor call in case you have not
realized it. So, I do not have to construct an object by writing rectangle-space-name-space-
parameter, name and then parameters. I can write it as rectangle of the parameter list. And
this will give me a constructed object right here. But it does not have a name, but I do not
want the name. I just want to imprint it, so I can just dot imprint over in this matter. And
similarly, the text is also going to be created and imprinted. Then the member function in is
quite simple.

So, we are getting the click value returned by a click. And as you remember, we have to get
the most significant 16 bits or divide by 65536 to get the x value of the click position and
take the remainder modulo 65536 to get the y value of the click position. And now, if we
want to know whether this click is inside, well, for the click to be inside we need it to be the
case that the distance the x distance from the clicked position to the centre. The x coordinate
of the centre has to be smaller than w. And the y distance between the centre and the click
position should also be smaller than the height.

So if both these conditions are satisfied and only if both these conditions are satisfied, then
we know that the click is inside the rectangle and therefore we check this condition and return
the result. So, if this condition is true, we return true; if this condition is false, we return false
which is exactly what we wanted. So, this is how the button class works. So, again the
important point is that the functional details are inside the class, and not in the main program.
So this way in the main program we can think at a high level. So let us go back to our
presentation.

1104
(Refer Slide Time: 22:41)

So, this is what we saw. And now let us take a look at the class CanvasContent. So, the
CanvasContent class manages the canvas drawing and input other drawing an input for all
components other than the button, buttons. So buttons, we have buttons are special because
buttons have this control like function. So, we have kept them separately but the other circuit
components, how they appear on the screen and what needs to be drawn will be managed by
this class.

So, what operations will it perform? Well, it will have a member function addNode which
will be called in response to click on the node button. So, we already saw that in the main
program. And so the main program waits for the user to click, sorry. So this function is going

1105
to wait for the user to click. And then after the user clicks, it is going to imprint a circle at the
click point and not only just the circle but it is also going to put in the node number. So if you
remember our execution of the program, this is exactly what happened.

And it is going to keep track of the circle position in this node class. Why? Because later on,
we may want to know whether a click is inside a node. And we also need to add this node
into the mathematical representation. So, these are the functions that our addNode member
function needs to perform in response to the user saying that I want a node and clicking on
the canvas to get that node. Then there are other member functions: addSource and
addConductance and these also act in response to button clicks. So, here the wait, the
program waits for users to select 2 nodes. And this is handled by a member function
SelectNode.

And the program gets the conductance and current values from the keyboard and it imprints
appropriate representation on the screen. So, once the data is obtained, once the canvas has
been painted with the right representation, we have to add these components into the object
MathRep as well. So, let us take a look at this CanvasContent object.

(Refer Slide Time: 25:32)

1106
So here is our CanvasContent object. So, what does it keep track of? Well, it has to keep
track of what nodes are present on the screen. So therefore, it needs this pointer to nodes. And
it also needs to know about the math representation. So it is going to have a member mrp
which is going to be a pointer to the math representation. Here is the constructor class, the
constructor, sorry here is the constructor. The constructor is just going to be passed with a
pointer to the math representation and that pointer is going to be stored over here.

So, let us take a look at addNode. So addNode is going to ask the user to click. And once the
user clicks, we are going to create a new node at that click position. So, we will see the node
class in a second, but the constructor of the node will expect a click value to be passed. And,
it has to decide what its id is. So, we will pass Nptr.size because currently we have had nodes
going from 0 to Nptr.size-1. So, Nptr stores pointers to all the nodes created. So, the next
node will indeed be created at this position. So, at this index using this index and so that is
what we passed, and then we add this created node, sorry, we add a node to our math
representation as well. So let us take a quick look at the node class.

1107
(Refer Slide Time: 27:26)

So, the node class is over here. It receives at the constructor, for the constructor it receives a
click value and the index. It calculates where the click actually happened and then it creates a
circle and imprints at that position. So r is some 20 that we fixed and it imprints the text. So,
the text is just the index. So if you remember, inside the node we had the node number
printed. So, this is what does it.

(Refer Slide Time: 27:57)

Then the select node, so let us first look at addConductance. So, addConductance is another
member function inside our CanvasContent. And this is going to be called when the user
clicks the conductance button. And this is the function which is responsible in helping the
user to add a conductance, how does it do it? It calls the select node function twice.

1108
So, let us see now what the select node function does. So here is the select node function. So,
each call of select node waits for the user to click. And then it checks whether the click is
inside a node. If it is inside a node, it will return the node index. So i[1] is expected to be the
index of the click node, i[2] is expected to be the index of the second click node. And this is
just testing whether the click was inside a node actually. If it is inside the node, now we are
going to actually do the processing. That means the user has selected the two nodes between
which the conductance has to be added. So, what do we do here?

So, here we are going to have to draw the line connecting those two nodes. So we get the x
coordinate and the y coordinate of the first click position, x coordinate and y coordinate of
the second click position and then we actually draw this line. And then on our shell window
in our shell window we type out the message, give the conductance value. And so then the
conductance value is received. So, then we can print, we can imprint the text at the centre of
that line of that edge with the value G.

(Refer Slide Time: 30:01)

1109
So, as you if you might remember if the user added a conductance between say this vertex
and this vertex, then the conductance value was imprinted over here. So, this is what is done
in this text statement. And then we want to add this conductance into our math representation
as well and that is what is being called over here. The source addition is very similar.

(Refer Slide Time: 30:24)

So let me just quickly observe that again we are going to select node and then we are going to
draw the line, we are going to get the Source Strength and we are going to add the source into
our math representation. We are going to put down the magnitude of the source and then we
put the turtle. So, the turtle is going to be created, when a turtle is created it is always created
at the centre of the screen. We wanted to come to the centre of that line, the line that we just
drawn. So this is the centre of that line that we just drew, and here is a command. Here is I
guess some undocumented command on the turtle.

1110
And this command says make the turtle face the second end point. And then we make it move
forward. So if so what this is going to do is that if this is the conductance and if this is the
conductance value, the turtle will first come to this point, the centre and then it will move in
the direction of the second end point and it will come over here and it will get imprinted. So,
the purpose of all of this is to imprint but also imprint a little bit away from the source
strength value. That is it, so that is what happens in the conductance our conductance code.

(Refer Slide Time: 31:59)

So, let us get back, so we just saw this and a few remarks: all objects on the screen are
imprinted because we do not need to move them and but we do need to keep track of their
positions and extents to check if the user clicks on them. If we wanted the user to adjust a
drawing, then we would need to create and move around graphics objects. And if you want to
dragging, which is really the nicer way of doing things, you can do it in simplecpp and that is
described in chapter 20.

So, it will need a little bit more work but we really could do very nice pictures. We could
draw a circuit diagram exactly like the one that I showed you at the very beginning. But it
will need more work.

1111
(Refer Slide Time: 32:44)

All right, so what have we discussed in this segment? We said, we discussed the organization
of the main program, we discussed the CanvasContent class which manages the graphics and
it draws components on the canvas and adds them to the MathRep. And next, we are going to
talk about how we represent the circuit mathematically, and how the class MathRep is going
to be designed but before that we will take a quick break.

1112
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 26 Part 3 - A graphical editor and solver for circuits - Mathematical
representation of the circuit

(Refer Slide Time: 0:22)

Welcome back. In the previous segment, we discussed the organization of the main program
and the classes which are related to the canvas and the graphics. Now, we are going to talk
about how the circuit is represented inside the computer.

(Refer Slide Time: 0:35)

So, this is done in a class called MathRep. So, it keeps track of the data related to the circuit.
So, the data consists of: the manner in which the components are connected, the conductance
values and the current source values or what is sometimes referred to as current source

1113
strengths. Then the main member function in this is the function Solve which solves the
circuit built up until then.

(Refer Slide Time: 1:07)

So, let me talk about the representation bit more precisely and this is discussed in section 23.4
of the book. So, suppose we have an n node circuit, then it will be represented using an n by n
matrix and we are going to call this matrix A. In addition to that, we will also have a n by 1
vector b. So, these will keep evolving as our circuit gets built and then when we want the
circuit to be solved, we will perform mathematical operations on this matrix and vector and
we will see all of that soon. So, this matrix, A is going to be used to represent the connections
and the circuit values in the following manner:

1114
So, whatever conductance there is between node i and node j, we are going to make an entry
of that value in the matrix, in the matrix element A[i][j] so, just to make sure that this is
understood. So, let us say this is node i and let us say this is node j in our circuit and suppose,
connecting these two we have we put some conductance C so, then we want simultaneously
in the representation to have A[i][j] = -C. So, this will keep track of what the conductance is
and of course it is symmetrical so, we will also have A[j][i] = -C and it is 0 if no conductance
is specified.

So if there is no edge then this vector would be 0 because no edge is equivalent to 0


conductance. Conductance is indicative of how much current can flow and if there is no edge,
no current can flow and therefore it is natural to say that the conductance is 0. A[i][i] is going
to be the sum of the conductances connected to node i. So let me again give an example. So,
this is some i j, this is some k, this is some l and let us say this conductance is C, this is some
D, this is some E, then A[i][i] we want to be equal to C+D+E.

So, note that given the circuit, we can figure out what these values are and given these values,
we can figure out what the circuit is. So to that extent, this is a representation of this circuit.
Of course, we are not completely done yet, we have not said how voltage sources are
represented. So, voltage sources are represented in the following manner, so, we not only
have this matrix, but we also have that vector B.

If you have a current source which say starts off at some vertex w and enters i and it has some
strength J. So then B[i] should be the sum of all such current values which are forced to enter.
So we will see this in a minute and of course, if there are some currents leaving, then that is
as good as negative entry. So over here, we are subtracting the some of the strengths leaving
i, alright so, how does the circuit get built incrementally? Well, what happens when a new
node is added? So let me draw a picture over here, a new picture.

1115
(Refer Slide Time: 5:44)

So here is some circuit that we have created and now we create a new node. Well, this new
node does not have any connections at all. So what do you think will be present in its row and
in its column? So, if we add so, effectively if we add a new node, we are going to have an
extra column and an extra row added and since the node is not connected to anything at all,
we have to make that initial row and column become 0. So again, let me remind you, how did
we add a new node? Well, suppose this circuit already had nodes 0 through n minus 1, then
when we created a new node, we created a new node n. So, this is now going to correspond to
increasing the number of rows and the number of columns. And so the nth row will
correspond to the new node and that has to be made 0. What about b[n]? So, if you remember
or I guess you do not have to remember, b[n] is supposed to contain the sum of currents and
currents leaving and entering through sources, but right now there are no sources connected.

1116
So, as a result 0 gets added to the column vector b. So, originally our column vector look like
this, so say b[0] through b[n-1] and we are going to add a b[n] to it and the value for this we
are going to make it to as 0 because there is no current source connected to this.

(Refer Slide Time: 7:28)

So, now what happens if conductance C is added between nodes? So, let us go back to this
picture. So suppose a conductance C is added, then what happens over here? Suppose let us
say we are just adding this, but if we add this A[i][j] should be -C. So as a result we are going
to subtract C from A[i][j], remember A[i][j] was originally 0 so both of these were originally
0, so we are going to subtract C from them and we have to, the C has to appear over here and
so to A[i][i], there might have been other entries but we now add C as well.

1117
So that is how adding a conductance gets reflected in our data structure and if I add going
from node i to node j, so let us say this is node i and this is node j. So, I can even draw it over
here. So let me do it that way. So suppose I add a current source, connect going from i to j
over here so, its strength is J. Well, what should happen? So b[i] should have the current
sources entering i, but this is current leaving i. So as a result, I should subtract, subtract j from
b[i], so which is exactly what I am doing. And this j is entering node j and therefore I am
adding capital J to b[j]. So, this is how exactly that circuit gets built up.

(Refer Slide Time: 9:17)

So, let us look at our code and look at the member functions, addNode, addSource,
addConductance. So these are operations in MathRep, so addNode first. So we have to push
back an entire 0 row, we have to append a new 0 row. So, this is what happens, this is what
makes that happen. Notice that the vector class makes it very easy to append and append

1118
rows since this is a vector of vectors. So, A is the vector of vectors, see over here and
therefore this will just append an entire row and then we have to add 0 column. So now what
we do is we are just going to look at every row and we are going to append a 0 to it, that is it.

So this is loop over every row of that vector and we are appending a 0 and finally we want to
append a 0 to our b as well and so that is what this does. What about addSource? So if I am
adding a source, you remember that if a source of value V is added then going from i to j,
then value has to be subtracted and to j the value has to be added. So this is what happens,
what we need to do.

(Refer Slide Time: 10:38)

And if I want to add a conductance, then to A[i][i], the value has to be added, see this, and
also to A[j][j] because the conductance is connected to and the treatment is symmetrical. And

1119
from A[i][j], the value has to be subtracted and also from A[j][i], so that is what
addConductance does. So, quite simple. Alright, so let us get back to our presentation.

(Refer Slide Time: 11:12)

So, now we will talk about how to solve the circuit. So solving the circuit first of all requires
us to find the voltages at the nodes. So we do not know those voltages and let us say we
represent the voltage at node i by x[i]. So, x is going to be a vector and i is going to be the ith
index in it, the value at index i in it. But right now, this is unknown to us. So now, I want to
tell you a little bit about how circuits work. So let me start on that, so this is our vertex i and
this is our vertex j and let us say that going from here to here, there is conductance G[i][j].
Now, what do we know about the current going from here to here? So it turns out that this
current from i to j is equal to the conductance of that times the voltage of i the voltage drop or
the voltage at i minus the voltage at j. So, this is the current going from i to j, now we do not

1120
know this, we only know well, yeah, so everything here is an unknown. So we do not know
the current, we do not know the voltages but what we have done is we have established a
relationship between the voltages at these points and the current over here. So, this is just
what is called Kirchhoff's Voltage Law as you might have perhaps studied in physics.

So now I can ask, what is the total current leaving i? So there might be other edges. So how
do I calculate this? Well, I just take the sum over, let me do it in a different color just to keep
track of it. So I am going to take the sum over all the j, all the conductance is connected to i.
So, if I just take the sum, that gives me the total current leaving.

(Refer Slide Time: 14:16)

Now, I can factor this out and that factoring is important. So let me write it down a little bit
carefully or I guess I can explain it on the screen, so what is happening over here? Well, there
is this x[i] term. This x[i] term is common to all the terms in the series. So I am going to pull
it out and what is the coefficient of the x[i] term? Well, it is going to be the sum of the
conductances G[i][j]. So that is what I have written over here, some of the conductances
leaving i or these G[i][j], and then I am left with this remaining term, so G[i][j]-x[i][j], and
that I just pulled that minus sign out over here, so that is a total current leaving i through the
conductances.

Now, this if you remember, the sum of the conductances leaving i was just A[i][i] and
therefore this is x[i] times A[i][i] and G[i][j] the negative effect, is in fact A[i][j] so, this is
what the entire value is. And in fact this is nothing but the ith component of the product of the
matrix A and x. So, we do not know x yet, but what we have done, is we have established a
relationship between the total current leaving i through the conductances and this matrix A

1121
and this unknown vector x. So, it is ith component of the product is indeed the current leaving
i through the conductances and this must equal, I am sorry I should have said equal over here,
this must equal the total current entering i through the conductances.

(Refer Slide Time: 16:27)

So, here is my, here is my vertex i and I am talking about current leaving through
conductances but there is current entering through current sources as well. So, what is the
current entering through sorry, through the current sources as well. So, what is the current
entering through the current sources? Well, the way we define b it is exactly b[i]. So what
does this tell us? This tells us that this must be equal to this, so the ith component of the
product Ax must equal the ith component of b, but this is true for all ith components and
therefore in fact this entire matrix product must exactly equal b.

1122
So, sorry we should be, so we have to solve Ax=b because we know that Ax must equal b and
now x is the only unknown, this vector of unknowns is there, but we can get that if we solve
this matrix equation. So, this is a simultaneous equation which we have to solve.

Now, there is a slight hitch over here. This system has n equations and n unknowns,
remember n is the number of nodes in our circuit. Unfortunately, these equations are not
independent. But we will get a solution if we set any unknown to 0. So after we set an
unknown to 0, we will get a solution and the details of that I am not going to talk about right
now but they are discussed in this section. So, that is what we are going to do. We are going
to set x[n-1] to 0 and this will effectively allow us to drop the last column as well.

So, we will get a system which has n-1 equations and n-1 unknowns and these equations will
all be independent that is they will contain distinct information and then we can solve it. By
the way, if you are so, many of you probably know electrical circuits a little bit and if we
have voltages in our electrical circuit, then voltages are all relative. So, I can fix any voltage
to be 0 and that is exactly what we are doing over here. But it relates to equations not being
independent and that is discussed in this section. So, please read that.

So, anyway so, I have told you why this product Ax must equal b and I have told you that we
are going to set one of the values x[n-1] to 0 and then we just have to solve for the remaining
unknowns. So, we have a smaller system, well slightly smaller system which we have to
solve.

1123
(Refer Slide Time: 19:29)

So, now how do we solve this system of equations? So, this is discussed in Section 15.2.1 and
I am going to discuss it very briefly. So, we are going to solve Ax=b and we are only going to
look at the first n minus 1 unknowns and first n minus 1 equations. So, in fact let us forget
that we even had that n minus 1. So, basically the idea is that we are going to use equation i
to eliminate x[i] from other equations. So, let me just write that down, show that to you. So
our equations are a11x1 + a12x2 + a13x3 and so on equal to b 1, then a21x1 + a22x2 + a23x3
and so on equals b 2 and in general, ak1x1 + ak2 x2 and somewhere here I will get akk xk
and so on equals b k.

Now, what this is saying is that I am going to use this equation to eliminate x1 from
everyone, from every other equation over here. So how do I do that? So, in general if I have

1124
say ai1x1 + ai2x2 and aiixi = b i, then this equation is going to be used to eliminate this ith
unknown, so this is going to eliminate the ith unknown. How do I do it? Well, so let me write
down what the equations, these equations are.

(Refer Slide Time: 21:55)

So I am going to have a11x1+a12x2 and so on and say the typical term will be a1ixi and so
on equals b1, then a21x1+a22x2 and so on and the term over here will be a2ixi all the way
equals b2. And maybe the jth terms is going to be, the jth equation is going to be something
like aj1x1+aj2x2 ajixi=bj and let us say the ith equation is a i1x1+ai2x2 and here I am going
to get a aiixi=bi. So, what our idea over here is saying is that we are going to use this
equation to eliminate xi from all these other equations, so how do we do that? Well, if I want
to get rid of this term over here in this jth equation, what do I need to do? I am going to

1125
multiply, I am going to multiply this by A[j][i]/A[i][i], so this entire row is going to be
multiplied by A[j][i]/A[i][i]. So what do I get over here?

So, over here I will get A[j][i]x[i], if I now subtract this resulting row, which has A[j][i]x[i]
from the this, I will get a 0 over here, so that is how I have eliminated this. So that is what I
am going to do. So I am going to do this for this row, this row, this row and also all the rows
underneath it. And now in this, I am going to divide by A[i][i], so in general we need to
worry about whether A[i][i] is going to be non-zero. But the way we have defined A[i][i], we
will always be guaranteed that it will be non-zero and so we do not have to worry about it.

So another way of saying this is that we do not need to pivot in case you have seen this, heard
this term pivot. So what does this do?

(Refer Slide Time: 24:55)

1126
So at the end of it, once we do the elimination, our matrix A is going to look like some non-
zero entries over here along the diagonal and everything else is 0 and b has changed suitably,
but b may have whatever entries over here zeros and non-zeroes, in general non-zeroes. So,
we have a diagonal matrix, but now if we, in fact make this 1 then this will exactly be the
solution of Ax, sorry I should have x over here equal to so, if this is made 1 then this will
exactly be the solution.

So, in other words if I divide this entry by this entry, I will get the solution for x[i] so, this is
the ith row. So, that is in fact what we are going to do. So, x[i] is b[i]/A[i][i]. So, that is what
is involved in solving the circuit.

So, at this point we will have found x[i] which are the voltages and so the program can print
the voltage at all the nodes and once we know the voltages we can also of course find the
currents because we already said that they can be, they are related as per this over here. But
we are not going to do that, that is just a detail that you can take care of and you could also
say that ‘Look, I do not want the current printed on or the voltage printed on my shell
window, but I want it printed in the circuit, in the canvas itself, and that also could be done
but again that is a detail that you can take care of.

1127
(Refer Slide Time: 26:44)

All right. So we will take a quick look at this member function Solve. So, what does Solve
do? So, I have described it to you already, so we are going to use the ith row to eliminate x[i]
from every jth row. So, long as of course i is not equal to j so, it is going to calculate this
multiplier and then it is just going to subtract that row and that is that subtraction process, that
is all. And then finally it is going to print out b[i]/A[i][i] as the final voltage values. And
remember that the last, so we had thrown out 1 unknown, and we had set that to 0, so that had
index A.size()-1 and that value was 0. So we are going to print that out as well, so that is it.
So that is what the Solver looks like.

1128
(Refer Slide Time: 27:49)

So, we have this already and so what have we discussed? So we have discussed how circuits
are represented as a system of equations and we said that we are going to set 1 unknown to 0
and that gives us independent equations. Then we discussed how the system can be solved.
So we will take a quick break over here and then we will discuss extensions and we will
conclude this lecture sequence. Thank you.

1129
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Science and Engineering
Indian Institute of Technology Bombay
Lecture No 26
A Graphical Editor and Solver for Circuits
Part - 4
Extensions and Concluding Remarks

(Refer Slide Time: 0:22)

Welcome back, in the previous segment, we discussed the math representation of the circuits that
were designed and we also discussed how we solve those circuits.

1130
(Refer Slide Time: 0:42)

Now we are going to talk about what kinds of extensions might be possible. So there are some
obvious things that could be done and we could improve the appearance, so we should really be
putting standard symbols of resistance and current sources. And maybe we should not really be
using the shell window at all, everything should happen on the canvas. So the final value is
should be shown on the canvas and in fact the user should be asked type directly to the canvas as
well. So and if the user places a node but then later on does not like the position, may be it
becomes too cluttered or something like that, then the user should allow to drag the components
to adjust this visual appearance. So this can be done and it can and it is the primitives you need
for it, I will discuss in chapter 20 in the book.

1131
(Refer Slide Time: 1:43)

And here is something that you might have seen happens with nice CAD programs, so for
example, if I have say vertex node 0 and node 1 here. And suppose I click on node 0. Then a
good program will change the color of this node to indicate that, oh! you just clicked on it. So
that way visually there is a queue given to you which, which tells you where you are and that,
that makes it easy, easier to use the program. That is not hard, it is the matter of detail and you
can do it even now and I certainly suggest that this is one of the extensions you should try out.
So basically if I, if I am selecting this node in order to add a conductance, I am first going to
click on it, then I am going to click on this and the color should change but the color should go

1132
back to the original colors, once this entire operation has been, has been finished. So this is, this
is a good exercise for you.

(Refer Slide Time: 2:48)

Other functionality could also be added. So If several components are connected across same
pair of nodes, then we need draw them far apart. Right now we are drawing them on straight line
but may be if a second component gets put, we need put it in to curve or maybe we need put on
line like that or maybe we need let the user decide what this ought to be. But whatever it is, that
is something that needs some work and it needs some worrying about geometry thing like that.

1133
(Refer Slide Time: 3:23)

Then right now our code is modify A, b in MatRep directly while we are solving. So probably
the right thing to do is make a copy it and then modify the copy of it and keep the values of A
and B consistent with what we said when we defined A and B. In particular, A[i][i] should equal
the some of the conductance leaving i and we should maintain A and B to be that. So and we
could allow some other components for examples capacitors, but in capacitors the solution is
time dependent so a capacitor gets charged and as result the value is different at different times.
So what we might have to do is we might have to show waveforms, so you could say for solve
and then may be you could click on that component and that should pop up a window in which
you can see the voltage waveform or may be not I do not really mean the window but just a
rectangle should be there on the side, inside which that voltage waveform should be shown. And,
a very important part of professional programs is that the gracefully tolerate errors.

So if I am expecting to click on two different nodes in order to insert a conductance, our program
as it stands probably do something wrong, if I just happen to click on the same node twice. So
what should happen is, somehow the program should indicate to me that oh you had made a
mistake and please correct it. So similarly for typing also, if I say type non numerical value and
numerical value is expected, the program should check that and tell me.

1134
(Refer Slide Time: 5:44)

So we have finished the discussion of this graphics editor and solver and what are the
conclusions? Graphical user interfaces are very convenient and they are actually not too hard to
develop. So our code is interesting and some comments are worth making about it. So our code
is separating the various concerns quite well, so what do I mean by this, well class MatRep keeps
track mathematical representation, the class CanvasContent manages the visual appearance, what
happens on screen and on canvas and the main program has sought of the overall control.

So if I want to think about complex system and you can get systems which much more complex
than our editor, I do want this kind of separation of concerns. So I want overall control to be in
one place. The canvas management to be in another place and the math representation to be in
another place because if everything cluttered together, reader will get confused. So in fact in our
program that seems have been managed quite nicely. The way it has been managed is because
we have hierarchy of objects. So the MatRep should contain the matrix and the vector. Matrix
and vector should not be the part of main program, so the, so those are low level details and the
main program is meant to explain or is to meant to talk about how the overall control, how
overall control flows inside our program and so this would be, the matrix and vector would be a
fairly low level detail which you just confuse the issues if you put that matrix and the vector
inside our main program. Canvas content contains Nodes and if you want, you can also put in the
edge data structure. Right now we do not have any Edge data structures. Because visually we
create an edge and it is imprinted on the screen subsequently there is no question of modifying it.

1135
But as we said in extension you may need to, you may want to modify the edge value so say and
might say look I entered a 5 for this conductance ant but no no I really want change it 6, so in
which case, we will need some visual representation of our edge as well and that, for example,
should go into the canvas content, just as we had node array there, you should have an edge array
over there. And one more principal is you have a hierarchy of objects and from one member of
hierarchy you really should not reach out into the sub objects in another hierarchy because then
that becomes confusing.

So main program knows about CanvasContent and MathRep, so main program should invoke
member functions in CanvasContent and MathRep. The main program should not should not,
directly excess the members in the data members in canvas content and further more say for
example, the CanvasContent had this member called node PTR and that contained elements of
the form node and it would be wrong for, for the main program to directly access the members of
this node PTR. So what should happen is, that there should be a member function at the level of
CanvasContent, which math, which which our main program is allowed to excess but not the
details inside canvas content.

(Refer Slide Time: 10:06)

1136
So again, I should perhaps explain this pictorially. So you have main program, you have
CanvasContent, you have MathRep. And inside it, there is something, inside it there is something
and inside that there is something. So main has specific set of member functions that, that the
designer of CC should expose so main should call this member function. It should not reach out
and touch things inside CC and certainly not touch things which are deep inside CC. Because
then that, then what your program is trying to do becomes very very unclear so keep things
simple. Keep things at this level which is, that there are member functions, this program is
allowing other to access and you should really only access things through those member
functions. And I will strongly urge you to try out to extending this program in at least one way.
So please do that. So for example, I said that if I click on a node, its color should change to
indicate to me that I click on that. So that is relatively easy extension and I would definitely
suggest that you try it out and it will be fun and I thing you will see that it makes the program
easier to use. So that is end of this lecture. Thank you.

1137
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 27 Part 1: Cosmological simulation - Introduction and First order Euler
method

Hello and welcome to the NPTEL course on An Introduction to Programming through C++, I
am Abhiram Ranade and in this lecture sequence I am going to talk about Cosmological
Simulation and the reading for this is Chapter 19 of the book. So let me begin by saying a few
very, very broad things.

(Refer Slide Time: 0:42)

So, you could say that the goal of science is to understand phenomena so that we can predict
the future, predicting the future is sort of a major test of science and what this means? Well,
given the state of a system today, we need to say what will happen to it tomorrow. In
contrast, the goal of engineering is to decide how should we interact with the system so that
we get the state we want. And these questions are actually interesting in every field, pretty
much every field. So in cosmology, the questions would be, how did the universe start? And
what happens tomorrow? In meteorology, the question is, what will the weather be like
tomorrow? And even in something like biology, these questions are very important. And for
example, these questions effectively are asking, well, how does an organism grow and even
how can we make it grow well? The goal for today is to write a program that can predict the
position of stars after some time, given the position and velocities today. So, this is the
central question of cosmology and we are going to look into it. But the methods we use in
principle are applicable to almost every other problem, so what is cosmological simulation?

1138
(Refer Slide Time: 2:19)

Well, we are given positions, velocities and masses of some n stars and we will use ri, vi for
the positions and velocities of the ith star and m survive for the weight that the mass of the ith
star and since the positions and velocities are functions of time, we may put 0 after ri and vi
and I should point out that ri and vi are vectors. So, they have three coordinates each. What
do we want? Well, we want the positions and velocities at some time t which we will specify.
So we want to know how our universe has evolved and we also want a movie of this
evolution. Exactly what happens to the stars?

Well, of course, this requires us to know some physics and the main thing it requires is how
one force, one star exerts force on another star. So the force on stari due to starj has
magnitude G*mi*mj/|(rj-ri)|^2, here G is a constant and let me explain what that ri - rj means.
So, I said ri and rj are vectors so, let me draw a picture of the vectors.

1139
So let this be any origin and let us say this is ri and let us say this is rj so, our mass m i is over
here and our mass m j is over here and we really want this distance. So, rj - ri, so this is rj
going in this direction - ri is really this vector. So this vector is rj - ri and what is being done
in the slide is that we are taking the magnitude of this. So magnitude of rj - ri so, we are
dropping the direction and we are squaring it. So, this is the famous inverse square law, that
the force varies as the product of the masses and inversely as the square of the distance
between them and what is the direction of the force?

So the direction of the force is from star i to star j, so it is an attractive force so, the force on
star i due to star j is attractive so that the star i is going to be attracted towards mj. All right.
So, we can write this as the unit vector in this direction. So, the direction can be indicated by
the unit vector from star i to star j and alternatively, the unit vector may be written as this
which is the vector divided by, so it is rj - ri, which is the vector itself in the direction i to j
divided by magnitude of rj - ri. So, this would be the unit vector because we are dividing by
its magnitude.

So now we can substitute this quantity into this, so to say to get a vector, so, what happens?
So the force due to star j on star i as a vector is G*mi*mj*(rj-ri)/(rj-ri)^3 so, what has
changed? So, this was the magnitude to it, we are multiplying by the unit vector. So, now this
becomes a vector quantity and its magnitude is still going to be this. So, we now have the
force due to start i, due to star j on star i as this vector.

Now, in doing this cosmological simulation, we want the total force on star i due to all other
stars. So, this is simply obtained by adding up this quantity for all j which are not equal to i.
And in fact, we are most interested in the acceleration so, that will be this divided by the mass
of i. So, it is the same expression except that the mass of i has been divided out. So, this is
what we need to know in order to calculate the forces and the acceleration and in addition of
course, we need to know Newton's laws, Newton's laws of motion or we need to know basic
kinematics. Basic kinematic says that if there is a certain velocity, then that velocity is the
derivative or the velocity is the rate of change of the position and the acceleration is the
derivative or the rate of change of the velocity.

1140
(Refer Slide Time: 8:06)

Alright, so here is an outline of this lecture sequence. So I am going to start by discussing the
basic method or the first order method as it is also called. Then I will talk about an algorithm
for cosmological simulation using the basic method, then I will talk about a more accurate
second order method and an algorithm based on that. After that I will show you the code for
the second order algorithm and a demo and then I will conclude. So, what is the basic
method? And this basic method is due to Euler.

(Refer Slide Time: 8:46)

So, the input to the basic method is the value of a state variable at time t. It could be position,
it could be velocity, it could be temperature, the method really is applicable to pretty much
anything not just cosmology. So, and we want to know what the value is at time t’>t. So, the

1141
main idea is to approximate it, approximate the whole process using the derivative. So, what
does that mean?

So, it means that if f is the variable you want to estimate and you are given this value f(t) so,
we said that the value of at time t was given to you. So, f(t) is given to you and you want to
know the value of time t’ but let us say for a minute that we want to know the value at some
t+delta. Then the value at time t+delta can be written as f(t)+f’(t)*delta, the derivative times
the time difference.

(Refer Slide Time: 10:07)

So, maybe I should draw a picture over here. So, say time is going in this direction and I am
plotting the variable in this direction. So, suppose the curve of that f, the plot of f versus time
look something like this. And so let us say this is t and let us say this is t + delta so, we do not

1142
know this point, but we want to know this, this is the point that we want to know, this is the
point that we do know. So what the method is saying is that at this point you can approximate
the curve by the tangent, so this is the tangent. And then you are going to multiply the tangent
by this. So this is delta and notice that the slope of the tangent, so f’(t) is the slope of tangent
at time t and a slope is nothing but this distance h divided by delta. So, all that is saying is
that h is equal to f’(t)*delta. So, this h is f’(t)*delta. So, what is this entire thing? This entire
thing is this distance and that is f(t) so, f(t) + f’(t)*delta, that is what we have written over
here. So, it just, this is just a simple thing which comes about by approximating the curve by
a tangent at that same point and another way to think about it is that we have already talked
about the Taylor series expansion. So, this is just the Taylor series expansion to one term or
in addition, the increase is expressed in using one more term. So, yeah, so this is called the
first order estimate and it is called so because delta appears with power 1. Now, this
expression turns out to be reasonably accurate for small delta and delta is often called a step
size. So, what do we do if we want to go all the way till time t’? Well, we divide this interval
into steps of small size delta, that step size and then take as many steps as needed to go from t
to t + t’, so how many steps will be needed? Well, we want to cover the distance t’ - t, so that
many divided by delta, that many steps are needed.

So, we repeat this t’ - t upon delta times. So that we will first get f(t) + delta then f(t) + 2
delta, f(t) + 3 delta and so on substituting, substituting t + delta in place of t over here and
keep going in that manner. So this is the basic first order method and it requires us to know
the derivatives at all points and I should also say that this applies to scalar or vector state
variable. So f could be a scalar, f could be a vector. So, what if f is a vector? Well, then we
are taking the derivative of each of the three components separately.

1143
(Refer Slide Time: 14:07)

Alright, so how do we use this for our cosmology problem? Well, let us say that f denotes ri, f
is ri or the position of star i, then what is f’? Well, f’ is the derivative of the position so it is
the velocity, so it is v i, so of course these are functions of time but I have not put time here
right now just to keep my notation simple. And let us say for simplicity that t is 0, so then
what does this equation look like? Well, so instead of f we are putting in ri, the position of
star i and t is 0, so this is just delta and then this f is just this ri and t is 0 and this is vis-a-vis,
because we say that f’ is vis-a-vis and the delta is there.

So what have you said that if you want to know the position at time delta and given you know
the position at times 0, then to the position at time 0 you just have to add the velocity times
the whatever time interval that is going to elapse and this is going to be the velocity at the
beginning of the interval. But the point is that the interval is small enough we can say that
this is the velocity for the entire thing. So, this is an approximation, that is why we have put
in this approximation, approximate equal to sign over here. But if the interval is small, then
this is not bad, this will be essentially constant during that interval. So, that is it, that is what
this expression that we had on the last slide means as far as the position is concerned. And it
is reasonable for small delta as we just said, because in a small time interval we can sort of
assume that look, the velocity will not change all that much.

Now, the velocity actually changes so we also have to apply to the velocity. So we are now
going to ask, what if this f were to be representing the velocity? Well, then what does f’
represent? So we said earlier that the derivative of the velocity is the acceleration, so this is
nothing but the acceleration, so what does that get us? Well, it says that v’(delta) or the

1144
velocity at time delta is the original velocity. So it is the original velocity + whatever
acceleration that might have accumulated in that time difference delta. So again, it is a kind
of a reasonable thing and now let us use what we know about acceleration. Well, we
mentioned earlier that the acceleration on of star i due to every other star is proportional to
the mass of the stars times the distance between them upon the square of the distance and of
course, the cube of the distance. Well, so this is a vector quantity and this is a scalar quantity.
So it really is mass upon square of distance in the direction in this direction and in our earlier
expressions these zeroes were not there, so time was not mentioned but here we are, we want
to apply this to time 0. So, we actually know this, let me point out that we actually know this
quantity, why? Because we are given the positions at times 0.

So therefore, we know the accelerations at times 0, we are also given the velocity at time 0,
so therefore we can calculate this as well. So, we know the velocity at time 0 so we can
calculate this, we know the velocity at time 0 and we know the acceleration at time 0 because
the acceleration is this which depends only on the positions and we know the positions.

So, basically what has happened is that given the position and the velocity at time 0, we are
able to determine the position and the velocity at time delta for all i, so for all the stars. So
basically, we can predict what happens to our system after delta time units and of course,
delta has to be a small number in order for this prediction to be reasonably accurate. But once
we can do it for a small number, we can just keep on repeating it and then we will get, we can
get to whatever time we want. So, here we got we went from 0 to delta, but then we can start
with this and apply these two updates and then we will get to t equals 2*delta and 3*delta and
so on.

1145
(Refer Slide Time: 19:25)

So, the first order algorithm is quite simple, but I am going to state it nevertheless, you
probably many of you probably have understood what exactly we are doing here. So, the first
step, we are going to read the simulation duration step size and the number of stars into the
variables T, delta and n. Then, for each star, we are going to read its initial position and
velocity and mass into these variables, so these are arrays actually, arrays or vectors but let us
say arrays because we also have the physics factor right now. So, the ith element of the arrays
will get the initial position of the velocity and the initial position and the velocity and of
course the mass is not changing but the mass of the ith star will be put in the ith element of
the vector m.

And then we have to go from, let us say the time 0 to some target time T, so that is what this
the simulation duration is, so from 0, the current time, to the target time T. So we have to take
steps s going from 1 to T/delta. So we have to take T/delta steps. So what happens in each
step? So basically, we are going to do what we said on the last slide. So here what I have
done is I have calculated the acceleration of star i due to all the other stars and this is at the
current time. So I have put down instead of the subscript j I have put down index j because
the mass of the jth star is now in m of j and similarly r of j - r of i to get the difference
between the vector difference, the vector distance between the jth star and the ith star and this
is of course, the cube of the magnitude of the distance.

So this we are going to calculate with whatever values we have in ri rj so, these are at times 0,
so this is just the acceleration at acceleration of star i at time 0 because in the first iteration,
these are values at time 0 and in general, you will see that they are going to be at time (s–

1146
1)*times delta. So s in the first round is going to be 1 and so this is indeed going to be in the
first iteration, it is going to be the acceleration at time 0.

Then we are going to apply the position update rule, so the position update rule was that we
take the current position, add to it the current velocity times delta and we will get the new
position at time delta ahead of whatever time we started. So this is going to give us position
at s delta because at the very beginning over here, we knew the quantity r for all stars at time
0 or in general at time s - 1 times delta. So when we do this update, we will know the quantity
at time s delta and this is the velocity update. So the velocity update says, take the
acceleration at time s - 1 delta or 0 delta in the first 0 in the first iteration and multiply it by
delta and add it to the velocity at 0, so this is actually 0 or s - 1, s - 1 times delta. So, this is
exactly what I have written down in the previous slide, but we have put it in a loop and we
have sort of put it in terms of variables rather than formulae.

So that is it, that is the entire algorithm. So at the end of this, we will have ri and vi contain
the velocities and the positions and velocities of the ith star and at time T, because we would
have taken the right number of steps over here. Now, the performance of this is actually not
that great and let me just give you a clue to this. So even if I take two bodies, let us say the
Sun and the Earth, so what this ends up doing is that the earth will very quickly spiral out
from the star, from the sun.

(Refer Slide Time: 24:11)

So this is the sun, see this is supposed to be the orbit of the earth and if the earth is
somewhere over here, in the first step it will go a little bit outside, then it will go further
outside and by the time it comes over here, it will have gone out substantially and within two,

1147
three turns it would go out very far and this would not work at all. Or let me put it another
way, if I want this to work, I would have to take that, I would have to take that step size so
small that it would take an excruciating amount of time to make the simulation go through
any reasonable amount of time period. So that step size would have to be really small and if
the step size delta is very small, then that really means that the number of steps I have to take
is going to be huge.

(Refer Slide Time: 25:19)

So we are going to fix that though, but let me just remind you what we have discussed. Well,
we discussed the basic cosmological simulation problem and we discussed the first order
method due to Euler and next we are going to talk about a second order method but before
that we will take a quick break.

1148
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture 27 Part-2 - Cosmological Simulation - Second-order Euler method

(Refer Slide Time: 0:19)

Welcome back. In the previous segment, we discussed the basic cosmological simulation
problem and we discussed the first-order Euler method forit. In this segment we will talk
about a second-order method which is going to be lot more accurate.

(Refer Slide Time: 0:34)

So the idea is simple. Instead of using two terms of the Taylor series we are going to use
three terms. So f(t + delta), f is the variable we want to estimate at time t + delta we are given

1149
the value at time t, so f(t) + delta is f(t) + f’(t)*delta and in the previous method we had
stopped at this point.

But here we are going add one more term, so + f’’(t)*delta^2/2. So this is still approximately
equal to because as we know the Taylor series just keeps going and we are not taking all the
terms of the series. We are just taking powers, second powers of delta. And therefore, by the
way it is called second-order method. Now this can be written in a different manner, so let us
look at this part just this part. So I have so this is what I have written down over here and I
am going to rewrite it by taking delta common because delta is there in both.

So this I brought out this delta so here I just get f’(t) and here I get f’’(t)*delta/2. Now if you
look at this you may observe that this is actually a quantity which can be written differently.
So in what way? Well I can write it this way. Why is that? So this is just a first order
approximation of this. How? Well, if I want to know the value of variable at t + something, if
I want to know the value of the variable at t + something, how do I get it? Well, I write it as
the value of the variable at t, then plus the derivative of this plus this something in the
multiplication.

So indeed in this parenthesis what I have is the first-order approximation of this, we are going
in other way of course that we are saying. So we are going to substitute this for this over here.
So instead of this we are going to get this term. So here is the alternate statement of the
second-order method. So we have same thing f(t) + delta is equal to the first term does not
change but this second term looks like this because this taken first-order approximation is
exactly what this is.

This alternate statement is nice in many ways. Why? First of all, there are only two terms, so
that is good. Second, the second derivative has gone away so it is a simpler thing and that
almost looks like the first-order method. The only difference is that in the second term we
had, we had t over here f’(t)*delta. So here we have t + delta/2, so that is the only difference
but this is still essentially the same expression and therefore in terms of error, this is going to
be as good but because it is simpler we are going to use this in our algorithm. So we will use
this form but before we get to that, I want to look at what is geometrically just as to just so
that you get a betterintuition of what is going on over here.

(Refer Slide Time: 4:35)

1150
So, again, let me draw a picture, so this is time and say let us say this is t and let us say this is
t + delta and on this axis we have f. So let say so I am plotting the curve let say something
like this, okay? So this is the plot of f, now what does the first order approximation say? The
first-order approximation. The first-order approximation says that the increment that you are
going to get is going to be the distance, so this distance is delta so the time difference which
is delta times the slope and what is the slope? The slope of the tangent, so the slope of the
tangent is going to be something like this.

So this whole thing is going to be f’(t)*delta because this f’ is nothing but the slope of the
tangent, all right. So what is the second-order term, the second-order method say? The
second-order method is saying that look, do not take the slope at time t sorry, do not take the
slope at time t but take it at time t + delta/2.

1151
So take it somewhere over here. So take it somewhere over here and now the slope looks
something like this, okay. So I want to multiply this slope by this delta and then add that up.
So to do that, I am just going to make it appear somewhere over here, so this slope I have just
dragged it down, now I am going to multiply it by the delta and what has now happened is
that the product is going to get me this.

So this is this slope multiplied by this delta, this whole thing is this slope see that the slope is
going really sharp. So now it turns out that taking the slope in the middle is a good idea. In
this picture also you can see that what I am getting to over here is much closer to the actual
curve than this is. And there is, there is a different way of there is a different reason different
way of thinking about it and that is that…

(Refer Slide Time: 7:23)

To go from here to here, if I take the so when I multiply this distance by the slope I am sort of
assuming that the slope is going to be the same inside this entire interval. So if the slope was
really the same in the entire interval then it would be just a straight line. In that case
multiplying it would give me the exact answer.

But the slope is not the same, so should I take the slope at the beginning, should I take the
slope at the end or should I take slope in the middle? Well, the slope in the middle is likely to
be closer to the average slope and therefore we should be taking the slope in the middle. So
that is really the intuition behind this formula. It comes out from the Taylor series but the
intuition is this.

1152
That I want the slope I want to multiply delta by the slope but I should pick a value which is
sort of close to all the values in this interval. So this is t, this is t + delta. I should pick a value
of the slope which is close to all the values. So what are the values? Well, the slope starts like
this then it goes like this and it finally comes like this. So the slope in the middle which is
this, is kind of like this, kind of like this, it is closer to both and therefore we get less error. So
we just did this, we got the geometric interpretation and this is just to informally see why this
method should be doing better.

(Refer Slide Time: 8:59)

All right, so let us now try to apply this in the context of cosmological simulation. So we will
do exactly like how we proceeded before. So let say f is ri, so this f is ri and ri as we know is
the position of star i. So what is f’? Well, f’ is the derivative of position which is the velocity.
Again, we are going to let t be 0. So what does this give us? So this tells us that the position
at time delta is the initial position plus the velocity at the middle of the interval times delta.
Now this may be another way to see why this new method is better.

Because what we are saying over here is that we are multiplying delta by the velocity in the
middle. So we are saying yes, the velocity might be changing and we are hoping that the
velocity in the middle is a better representative of the velocities in the entire interval.
Intuitively the velocity gets lots of time to change from our selected velocity if we select at
the middle but if we select it if we select it at the beginning. If we select it in the middle, then
the initial velocity or the final velocity is not too far in time from the middle.

1153
And therefore, the middle is a better representative, so that is as far as the position is
concerned. So if we know the position at time 0 and we know the velocity at time delta by 2
then we can calculate the position at time delta. Next let say let see what happens if f is the
velocity, so then f’ is the acceleration and again let us take time equal to 0, sorry this time we
are going to take time equal to delta by 2, you will see why, Okay.

So what becomes of this? So t is delta/2, so we are going to get delta/2 + delta. This is going
to be vi of delta by 2, remember we are substituting vi for f and t and delta/2 for t. And f’ is
acceleration and t is delta/2 so this whole thing becomes delta*delta.

So this tells us how we could calculate the velocity at time delta/2 + delta and for that we
need to know the velocity at time delta by 2 and then the acceleration at time delta. Do you
know the acceleration at time delta? Well, as it happens we do, so this is the velocity term,
this is the for the acceleration what I am going to get. Well, for the acceleration we already
know that it depends only on the position oh, I think I need a delta over here, so there is a
delta over here which I have which I need to add.

So this acceleration term is this term and this is the acceleration at time delta. Do you know
this term? Well, we do if we know ri of delta and by the way when I say we can calculate ri, I
mean we can do it for all stars. So we can know it for rj and everything as well, all right. So
yeah, there is a delta term over here.

Basically what where, what has this led us to? So this says that if we know ri(0) and vi of
delta then we can calculate ri of delta and vi of delta + delta by 2, okay let us just check
again. So can we calculate ri of delta? Well, here is ri of delta, well we have ri + 0, yes we
said if we know ri(0), do we know vi of delta by 2? Yes, if we, we said if we know
vi(delta/2). So yes, if we know these two things, we will be able to calculate ri of delta. Will
we be able to calculate vi of delta + delta/2?

Well, vi of delta + delta by 2 we are going to update as vi(delta/2). Do we know this? Well,
yes we said if we know vi(delta/2), do we know these things? Well, all ri(delta) we have
calculated in this step over here. So therefore, we know these terms as well and therefore we
can calculate this. So what does this mean, what have we exactly accomplished? So I am
going to draw a timeline over here.

(Refer Slide Time: 13:45)

1154
Okay, so this is 0, then this is delta then this is 2 delta, then this is 3 delta and so on. So at this
point we know ri and at this middle point we know vi. And what that tells us that knowing
these two things knowing this and this, we can calculate this and this but now we can apply
the same argument or let me let me write it down properly. We can calculate ri for this point
and vi for this point. Now I can apply the same argument to these two terms the same
calculation. So I will be able to calculate the ri over here and the vi over here and I can keep
going. So it is like the previous thing but ri and vi values are not at the same time, at the same
time instant.

Okay, so they are at these staggered time instants. In fact what is going on is that the ri values
are calculated at integral multiples of delta, odd multiples of delta/2. So these are the ri
calculations and these are the vi calculations. So you can fancifully think of the ri values sort
of jumping across the vi values and in fact this method is also called the Leapfrog method or
it is also called the Midpoint method.

But anyway so this is how the updates were. We calculate these two first, from these two we
can calculate these two, from these two we can calculate these two and so on. So that is
exactly our algorithm. What I am going to write down now is just this in a little bit more like
code first of all.

(Refer Slide Time: 16:09)

1155
We can repeat the steps to get things for 2 delta and 2 delta + delta/2 and so on. Well, there is
a little bit of problem though. So we said if we know these two things, but do we know these
two things? Well, we do not, what was given to us were the positions and the velocities at
time 0. So we know vi at this time and ri at this time, so our input specification said that we
are given the positions and the velocity at time 0, we were not given this. So can we get this?
Well, by now you should able to guess this, can we get this? Well, given the velocity over
here we can always get this if we know the acceleration because that is we can do this by a
first-order Euler expression, we have update. So to go from here to here we will use a first-
order update but note that happens only once. So before we get the whole process started, we
are going to do this first-order update to get the velocity at this point. So what is the
expression needed over here? So we are going to have vi equals the original vi + acceleration
times delta, so that is the first-order update. So that is what we are going to use here.

1156
So we were given these two things, from that we got the velocity over here and ri already we
have and now we are going to use the method on this slide to get these, these, these and how
are we getting these? So this is a second-order update. This is also a second-order update, so
all of these are second-order updates. So we do one first-order update at the very beginning
and subsequently we only do second-order updates. All right, so that is what the code or the
algorithm is going to have.

(Refer Slide Time: 18:11)

So as before we will read simulation duration, step size, number of stars into T, delta, n. Then
we will read the initial position, velocity, mass into those arrays and then this is going to be
the first-order update that we talked about, so calculating vi at this position. So at time delta/2
and you can see that that is why we are multiplying by time delta/2 and the values over here

1157
are at time 0. So these are values at time 0 and from that we are now getting vi at time
delta/2.

And now we are just going to do this t/delta times and at the beginning of the loop ri will hold
position at time (s – 1)*delta, vi will hold velocities at time s - half delta. So we are
effectively at this point in our execution. So at this point we have advanced to this point, so ri
is going to be over here, we have not got to the red values. So at this point ri is holding the
positions at 0 and vi is going to be holding the positions at half.

But s is 1 over here, so this is 1 - half, so that is exactly the right thing. So exactly as we said,
we will calculate the updated values of the position and that will get us the position at this
time. So from this we got to this time. And then we will use the acceleration calculated earlier
to go from this point to this point, so that will take us to acceleration sorry it should be no,
yeah. So this is really the acceleration at s*delta not earlier. We are going to calculate the
acceleration at this point. So we calculated the acceleration at this point and this acceleration
we are going to add, so that will bring us to this point.

So as a result our velocity will be available at this point which is s + half, s + half times delta.
That is it, that is the entire algorithm. So as we said earlier, the first-order update is used only
in this step and over here and over here we are using second-order updates. So as a result the
overall accuracy is high. This does turn out to be a good algorithm, all right.

1158
(Refer Slide Time: 20:56)

So what have we discussed in this segment? So we have discussed the second-order method
and we have discussed sort of the details of the entire algorithm based on the second-order
method. In the next segment I will show you the program but we will take a short break.

1159
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Computer Science and Engineering
Indian Institute of Technology Bombay
Lecture No. 27
Cosmological Simulation
Part 3
The Program

Welcome back, in the last segment we discussed the second-order method for the
cosmological problem and also an algorithm based on it. So before the program let us make a
few remarks. So as always, in order to write the program we should first try and enumerate
the important entities.

(Refer Slide Time: 0:36)

Now in this program, this program is all about positions, velocities, accelerations and these
are not entirely simple quantities. So they are actually 3 dimensional vectors and since they
are important entities we should use a class for them and luckily we did develop such a class
which was our V3 class which we developed some time earlier. So that is exactly what we
will use. So instead of, instead of thinking of it as an array of 3 elements or something like
that we will use our V3 class. And if you remember our V3 class was developed so that we
can add 2 vectors together by writing plus or if we could multiply a vector by a scalar just by
writing star. So that will come in very handy and that will make our code very easy to
understand and everywhere we will not have to write down loop looping over the 3
components.

1160
We can just say U plus V if we want to add vectors U and vectors vector V. Then there were
the other the major entities from a different point of view I guess are the stars. Well the Stars
possess the position, velocities and acceleration but the stars are important entities. So clearly
we should have a struct. Now we could create a struct for the entire galaxy as well, so that
struct would just contain the array of stars. But here we have chosen not to do this we will
discuss this a little bit later when you have seen the entire program. But what we have said so
far, is that the entity is sort of the physical entities are the stars and inside the stars will have
V3 entities which will represent the positions, velocities and accelerations of the stars. What
are the important actions that the program needs to take? Well first of all of course the
program has to read in data then it has to calculate the force due to stars on each other. So this
will involve all stars, then it has to update the position.

So what do we need in order to update the position? Well we should change the velocity of
sorry change the position of each star individually and for that we need the velocity of that
star. So this is a bit of a local operation if we know the velocities of the stars. And similarly
we have to update the velocities, so this is also a local operation because if we know the
accelerations then the new velocity of a star depends on its old velocity and its acceleration.
But these will be important actions that we are going to perform and yeah and we want to
show all this on our canvas. So we should actually move things around as well, so that is
another important action. So this suggests that suggests what what functions we should have.
Because we said at some point that if something is an important action, then we should make
it into a function or a member function.

So we will almost do that some of these if something happens to be really tiny then maybe we
will just write it directly rather than making it into a function. But yes, in general if
something is important we should sort of make it have a name in our program and the way to
do that is by making it a function or a member function and then of course there is the main
program, if you have to see what happens in the main program? Well the main program sets
everything up and it also loops over the time steps. So in that sense the main program is kind
of a controller a kind of a choreographer if you will. So it sort of it sort of sends messages to
everyone saying, oh now we do the next step of the iteration now, now that it is over, do the
next step and next step and so on. So that is what our program is going to be, basically it is
going to follow this outline.

1161
(Refer Slide Time: 5:16)

So we, so now I am going to show you the program I am not going to so, so I am going to
show you the program and I will begin with the main program. I will talk about the function
which reads the data then the function that calculates the forces. I will show you the star
class, the class V3 and while doing this, I would like you to observe that really the whole
thing corresponds to the algorithm that we have discussed. So let me get out of this.

(Refer Slide Time: 5:48)

So here is our main program, so we begin by creating the canvas on which everything is
going to be shown. And then we read in the duration of the simulation, the step size, and the
number of stars and then we have a function which will read in the star related information.

1162
(Refer Slide Time: 6:14)

So this is the function, so it does not do a whole lot of thing. It will read in the values, the
mass X, Y and Z, the positions and the velocities. So these are the initial things that it is
going to read and we are going to have a star array, so this is it is going to be read into this
star array and we are going to initialize each element of that star array using these using these
values. So these 3 values we are going to convert into a position vector by calling this
constructor if you remember this is the constructor for V3. So this is giving the position
vector, this is giving the velocity vector and this is the mass. So it is going to in it, it is going
to initialize each star.

1163
(Refer Slide Time: 7:10)

So let us quickly take a look at that because there is something in some thing that happens in
addition over there. So here is that initialization. So M, V3 r1, V3 v1 so these are the
positions and velocities. So they are going to be put inside the corresponding members. So V
and r are the velocity and position of this star, so these are these are the data members and
mass is also there so M is going to go into mass. But we want everything to be seen on the
screen as well so in this construct this is not a constructor this is kind of a reset like things so
it is the initialization thing. So in this initialization we will actually make this circle appear on
our screen by resetting it and where should it go, well it should go at position x and y where x
and y are the positions of the star. So the way we have done it is that we have used we are we
are pretending that our stars are moving in sort of this pixel space. So after all this is only for

1164
a demonstration and so we are not doing any kind of a change of coordinates over here, so
this is all pixel space.

So pixel coordinate x coordinate we get, pixel y-coordinate we get and over there we are
going to show the star. So that star is going to appear as a circle and we are going to make
that circle be red and filled. And we will have a pen for it which will go down and it will go
down because we want the orbit to be seen as the circle as the star moves. So yeah so this is
initializing the data part as well as initializing what happens on the screen.

(Refer Slide Time: 9:08)

So we read the data that is that is over here and next we are going to calculate the forces. So
how do we calculate the forces? Well for that we need the information about all stars and that

1165
is we pass it the array stars and we also need to calculate the result in some array called
forces so that is what is going to happen over here. So in in the array forces we will calculate
the forces. So how does that happen?

(Refer Slide Time: 9:41)

So it is as you might expect, so we are going to go through every pair of stars and we are
going to calculate the mutual force. So how is the mutual force calculated? Well we have this
function this member function on a star object. So what this is saying is that tell me the force
due to star, due to star i on star j. So and tell it to me as a vector or rather tell me the force on
star i due to star j. And that force we are going to add to the total force on i and we know that
by symmetry, or by a Newton's third law exactly the equal force will be exerted on star j and
so we are going to subtract from it and notice that these are vectors remember that these are
vectors and this is also a vector and the result of this calculation is also a vector.

So this calculation will produce vectors we are we have overloaded the plus and minus
operators we will see that and you already saw that in an earlier lecture. So that we can just
directly add the incremental contribution due to star j on star i and on star star i do to star j.
So this is the incremental contribution and exactly where does Newton's law of gravitation
come in? Well let me show you so this is where it comes in.

1166
(Refer Slide Time: 11:12)

So this r is the distance but distance expressed as a the distance expressed as a vector. So this
is rj. So the other minus ri if you look at our formula and that is the vector distance and that
is, so our formula says it is the vector distance times the gravitational constant which we are
taking as one here and times the mass times, the two masses divided by the power of the
distance to the cube because we already have a distance term over here in the vector in the
vector part. So this is again exactly like what we had in the slides. So we have calculated the
net force.

(Refer Slide Time: 12:06)

1167
So going back to the main program, so once we have the net force why did we calculate the
net force? Well if you remember, we need to have the velocities at time step delta by 2. So if
you remember when we started things of we wanted the positions at time step 0 and velocities
at time step delta/2. So we got that by a first-order update, so what was that first-order
update? Well we are going to take the original velocity of each star and to that we are going
to add acceleration times delta/2. But here we have forces, so in this member function will
convert the forces into accelerations and add them.

(Refer Slide Time: 13:02)

So let us see that, so there is this velocity step that I am going to show you. So V step says
that you had an original velocity to it you are going to add the force divided by mass which is
the acceleration and whatever time displacement you want. How much how by how much
ever you want to advance.

1168
(Refer Slide Time: 13:27)

So in this particular call we are advancing everything by delta by 2 because we started of


with all the data at 0 and we wanted the velocities to have been calculated for delta by 2. So
this gives us at the end of this we will have velocities at t equal to 0.5 delta and positions will
be at T equal to 0 because that is what we started of and we have not modified the positions.

(Refer Slide Time: 13:53)

Then there is the main loop, so how long does the loop run? Well exactly as before it goes
from 0 to t/delta and in the increment of delta. So here we are going to calculate, we are
going to update the position. So this is this update is what we are calling as rStep and this

1169
time we are going to advance the position by the full delta. So therefore the argument that we
give to this is delta, so let us see this rStep.

(Refer Slide Time: 14:26)

So we are passing the duration and that duration is going to be multiplied by V well what is
V? So V is just the velocity, velocity of this star. So remember the velocities are kept along
with the Stars so see this as apart of the star the velocities are kept there itself.

(Refer Slide Time: 14:41)

So in the vStep this velocity that is there with the star we are taking and we are getting the
acceleration and that is got by F divided by mass and then we are multiplying it by the

1170
duration. In this case, delta was passed, so this is just saying a times delta. V equal to V plus a
times delta that is what this is.

(Refer Slide Time: 15:20)

So we have come to this point, we have updated the positions the positions and we have
updated the velocities and yeah so before we have update the velocities we need to of course
calculated the forces. So it is it is exactly the same force calculation function and we updated
the velocities and then this iteration has to happen as many times as needed. So if you want to
advance time by T it has to happen T/delta times. So that is it, so at the end of it we are just
putting a get click over here just, so that though at the end the display does not vanish right
away.

1171
(Refer Slide Time: 16:07)

So the vector class is pretty much like what we had before except that we have added a minus
because we had you have to subtract two vectors, so therefore we have added this. And we
have so ignore this line this line is not really needed. This is somewhat complicated this is
these this is described in the book and this is a way to allow the class to be printed but do not
worry about it I should I should really remove this line, so that is the vector class.

(Refer Slide Time: 16:41)

1172
1173
1174
And so now you can see that we have the vector class we have the star class and we have
these two functions and we have the main program, so let us compile it. And we are supposed
to type in all the data about the Stars. So let me show you two pieces of data that I have so
one piece is the model of a Sun and the earth. So let me type that out first, so what has
happened over here is that I am asking time to go up to 30,000 and my step size is 10 so this
is the mass these three things are the initial position and these three things are the velocities.
So one is 400 one has mass 400 times the other, so really you can think of this as the Sun and
this as the earth if you like. So let me run this and I want to take this as my input, so I will
just redirect, redirect this file as standard input and let us see what happens.

(Refer Slide Time: 17:58)

1175
So that is the Sun and this is the earth which is rotating around it and you will see that it
traces pretty much the same but the same orbit. It does not really diverge, so despite
numerical (calculus) errors in numerical calculations and things like that this is pretty good.
So yeah I could have put in more planets in fact in the demo that I had showed that on the
very first day of class you have this exact this exact program was used. And over there I had
many planets orbiting the Sun. So you can go back and look at that demo as well. But here
today I want to show you something else which is quite interesting, so let me show you the
data first.

So here here I have 30,000 steps again the 10 being the step size and there being three bodies.
So they are all of mass 100, so there all equal and these are the coordinates and velocities.
Now that the positions and the velocities have been calculated very cleverly. So this is what

1176
some astronomers did, this is the this has been taken from the internet okay, so these
positions and velocities have been taken from the internet and these were calculated by some
astronomers and the interesting thing about these positions and velocities are that you will see
that the attractive force is such that the bodies will describe a very strange looking orbit. So
let us see that,

(Refer Slide Time: 19:52)

So I am going to give it this 3 body data. So this is what this is what the Stars do as they are
moving under gravitational force is it not strange that they should that first of all 3 bodies
should trace such an orbit they are sort of following each other. But you can see that they are
actually that they may be doing this because of gravitation. Because just think about say this
at this point this thing which is in the middle is being dragged by the two others and therefore

1177
they are staying staying in this. So this is a curiosity but it goes to show that our code is
actually correct. This is behavior that should be expected for these initial velocities and
positions and masses.

(Refer Slide Time: 20:56)

What did we discuss in the last segment? Well we discussed a program based on the second
order method and in the next we are going to conclude but we will take a break before that.

1178
An Introduction to Programming through C++
Professor Abhiram G. Ranade
Department of Science and Engineering
Indian Institute of Technology Bombay
Lecture No 27
Cosmological Simulation
Part - 4
Concluding Remarks

(Refer Slide Time: 0:19)

Welcome back, in the previous segment, we saw a program based on the Second-Order Method
and we also saw a demo of it. In this segment, we are going to conclude this lecture.

1179
(Refer Slide Time: 0:39)

The main thing that we saw in this is a way of evolving the state of a system and we began by
looking at the basic Euler method. In some sense, the basic Euler method is a precursor to all
Scientific and Engineering calculations. So the idea that I can, I can find the state at the next step
by taking the derivative is a very fundamental very important idea. And then the Second-Order
Method and the other methods that people use today which are more sophisticated are sort of are
developments on this basic insight.

So the insight is that somehow knowing what happens at time t, we can use derivative like
information to predict what happens at t+delta. And this, this is sort of at, at the base, you can
say that this is at the base of everything that goes on almost. Yeah, so we showed you a code
based on the Second-Order Method. Now, this is better than the First-Order Method, but
professional astronomers use the Fourth-Order Method. So effectively that means keeping 4
terms from the Taylor series. And the reason for that is that with a Fourth-Order Method, you
can take bigger time steps. So while the calculation of a single time step becomes more
complicated the savings that result because you have to take fewer time steps are much more.
Now, let me comment a little bit on the program structure for this program. And let us see, let me
first observe that our main program does work at a high-level and the details are hidden in
functions and member functions. So this is what we wanted and we have accomplished it to a
certain extent. Now, the force involves all stars, and so it is a function taking stars the array stars
as an argument. And the velocity and the position updates are local to each star, and so the

1180
updates are member functions. So in some sense, once you decide where you are going to place
the data, then the positions of the functions may also often be naturally indicated.

(Refer Slide Time: 3:37)

Now I should point out that designing a program is an, is an art, not a perfect science. So there
can be other ways of writing the same program. So, let me, let me indicate what the other designs
might have been and of course, these are only a few of the other possibilities. So one possibility
is that perhaps we could have put the entire stars array into a struct we could which we could
fancifully call Galaxy. Because after all, that entire collection also is an important entity. And if
we had done that, , the force calculation would become a member function inside our struct
Galaxy. And we have not done this right now, but this would definitely be a thing worth doing if
we had many entities like galaxies. So if we had if we had several kinds of arrays, then instead of
exposing all those arrays in the main program, it would have been better to keep it to only have a
struct, a container for each array and let the main program see the container. And the details of
what is inside will be hidden in member functions of that container. And in fact, in some of our
earlier programs, we have done that. Then the second alternative design that might be possible is
based on an idea which is, which has been described as a model-view controller design. So what
does this mean? So this says that the system that you are simulating or evolving over time
contains a mathematical model, a contains a mathematical description which indicates how the
system actually changes.

1181
And then there is some code, or some data needed to show all that is how the system is changing
on your screen and that is the view part. And then there is the controller, the controller is the one
which commands the model to change and it commands the view to show whatever is needed to
be shown on the screen. You should have these 3 parts nicely separated. And I should comment
that we have not quite done it. Let us see what we have done? So, we do have a model part, the
stars and the calculations and updates involving them sort of constitute our model. And what is
our view? The view is showing the animation. So our view code and our model code are mixed
up, and I guess purists would frown on it. But the point over here is that the animation, the
showing the animation is really tiny. So every time we update a star, that update changes the star
to change its position. And the and the change in in the view is not very complicated. And,
therefore, we have just put that view update as a part of our model update. But if you have a very
complicated model and a complicated view that you need to generate, then certainly writing the
code for the view in one class and writing the code for the model in another class would be a
good idea. And the controller in this case is our main program itself. So in some sense this this
model view controller organization, even if it is not there, you can see how it could be there in
our main program, in in our program.

Yeah, so as I said in our case, the view part is very minimal, so we have put it inside the star
class itself. The star class does the work of the model as well as the view. Yeah, for more
complex views, it would be desirable to have a separate view class or function, which would go
over the model and generate whatever is to be shown. So that concludes our discussion of this
cosmological simulation. It is discussed at the book in chapter 19, and there are some problems
after the chapter as well. So I will invite you to solve the problems. And as I said simulation is a
very important part, taking, taking the system and evolving it is an is a very important part of the
whole range of computations that people perform and what we have tried to do over here is give
you a glimpse of it. So that is it and that is the end of this lecture. Thank you.

1182
THIS BOOK IS NOT FOR
SALE NOR COMMERCIAL USE
PH : (044) 2257 5905/08 nptel.ac.in swayam.gov.in

You might also like