 So, we will begin our discussions today. We are going to discuss some additional control mechanisms particularly the break and continue statements which do play an important part whenever our iterative structures are rather complex. We will look at another decision making control structure which is a substitute for if then else if in certain circumstances which is called the switch statement. After discussing that we will move over to a very important concept notion of a function or a sub-program or a sub-routine where we organize our instructions for certain tasks as a separate unit or separate code blocks and we will see how such code blocks get executed and how these code blocks can be invoked from within our program. Basically, we will be looking at the notion of functions in C++. We will look at the parameter passing mechanism. There are two mechanisms one is called passing by value the other is called passing by reference. The other part we will discuss later because most of the usage that we will do today and some of the most of the examples that you will use they will pass the parameters by value. We will look at the notion of a separate function declaration and finally I will give you a take home assignment which will be actually put upon the moodle by tomorrow. We will hopefully have some clicker quizzes at the end of the day. So let us look at these two statements. These are standalone statements unlike assignment where there is an expression evaluation or the for if and while statements where there are conditions and statements associated with those conditionals. The break and continue statement are just standalone statement. They do not have any parameter nothing you just say break or you just say continue. The objective is as described here. So whenever you are within an iteration and for some condition you do not want to continue with the iteration anymore. Notice that every iteration will have its controlling condition which will be written at the top either as part of the false statement or as part of the wild statement. And ordinarily you will come out of the iteration only when that condition becomes false as long as it is true you will continue to iterate. However there could be situations when you just want to get out of the iteration if let us say some bad input comes or some very specific condition is made ahead of the normal termination condition then you use the break statement. Continue statement is similar to the break except that break statement permanently gets out of the loop whereas the continue statement actually skips any remaining portion of the loop body and goes to the next iteration. Let me show this diagrammatically here. This is how the normal iteration will look like and depending upon this condition here as long as this condition is true you will continue to execute this part and continue iteration. This is the standard wild statement while condition you keep doing this. The moment this condition becomes false you will get out. The break statement can be written by you within the body of the statements which are to be iteratively executed. So this is the iteration block. Within this block if anywhere you write a break statement this means that the subsequent portion will be skipped the entire iteration body will be skipped and abandoned and you will come out here directly. So that is the meaning of the break. Obviously if you have an unconditional break like that then in the first iteration itself when you come in you will get out. There is no point there. So very obviously the break statement will be used along with some conditional judgment. If some condition is made then you do not want to continue with the iteration you want to get out. So then you can use the break statement. The continue statement is used in a similar fashion but the meaning is slightly different. If instead of the break you were to use a continue statement here both do not make sense simultaneously of course. So if instead of break if you wrote continue then again the remaining portion of the iteration will be skipped and you will come straight to the next iteration. So that is the difference. Break is a permanent abandoning of the iterative block. Continue is abandoning the remaining part of the block in that iteration and then go back again. Next time when you come if the continue is not executed you will complete the entire iteration. So again I will repeat that continue and break statements are not to be used just as standard statements because otherwise they will always be executed and therefore disastrous results will fall. This is as far as the while is concerned. In the for loop also if you use any one of these statements exactly the same thing happens except that when you are using for we have said that the third specification of the for namely the increment of the count will happen at the end of this iteration. So if you use continue statement continue statement will not bypass that increment rather the increment such as i equal to i plus 1 will happen after you come. So basically when you abandon the iteration block because of the break you abandon it permanently and get out because of continue you abandon the remaining part and go to that point from where either you go back to the next iteration or you go and increment the variable in for loop and go back. So this is how for and break statements are used. The break statement is also used in the context of another conditional control which is called the switch and we shall look at the switch statement in a moment. This is essentially another form of conditional if there is a situation where you are required to examine the value of a single expression. The example that I have given is the value of a single variable n and let us say for specific values of n you are required to do either this or that or that or that. That means if n is equal to 1 you are required to execute task 1 n is equal to 2 you are required to execute task 2 etc. Obviously you can implement such a logic using the normal if but you will have to keep writing if then else if if then else if etc etc. And if there is a common action that you have to take for several values of n then you will have to either club them in the if statement or you will have to repeat those conditions again. So instead of using an if then else if else if ladder you could use the switch statement. It is an alternative specification and it is a definitely an elegant specification. It is more readable and shorter. So I will show you an example of using the switch statement. This is the syntax definition of the switch. You start with the keyword switch in bracket you write an expression exactly like if if expression. So if expression do something here switch followed by expression and then you have this switch block. So starting from here up to this end is the switch block very much like that if then else block if block or follow whatever you want to call it a block. Now if the depending upon the value of this it is not like an if statement that you either come in here or you get out in switch you always get into the block and the expression is evaluated for equality with certain value. So it is not a general condition. Is x square greater than y is not the kind of condition that you are right here. This expression must result in a single value. Further that single value must be comparable for equality and therefore invariably that single value must be an integer value. A floating point value cannot be compared for equality because as you know there are approximate representations for values there. So when we say expression it must result in a single integer value or an equivalent integer value that the correct definition is a value which can be compared for equality. And what this switch statement does is based on this value it will go to any one of these so called case statements here. So case value 1, case value 2, case value 3 etcetera etcetera depending upon what is the value of the expression the control will jump directly to that case statement. So for example if the value of the expression is value 2 then it will jump to this state and it will execute whatever is stated here. Unfortunately the switch statement does not take you out after executing that case meaning this control is transferred to case value 2 but then onwards it will continue executing the remaining statements as well. We do not want that ordinarily and therefore we would use the break statement. So the break statement means break out of this block. Break in case of foreign while also says break out of the block here also it says break out of the block. Let us illustrate this with an example. Consider this we want to classify a single digit input integer. Integer value has been given 1, 2, 3, 4, 5, 6, 7, 8, 9. I would like to say for example 1, 3 and 5 are odd numbers 2, 4, 6, 8 are even numbers. We can even classify some as prime numbers. So 3, 5, 7 are prime numbers. Depending upon the way in which we wish to classify the classification depends upon the specific value of the input that we have received. So what we are doing in this program is we are reading the value of an integer and based on the value of that integer we want to take certain actions. Basically print the classification let us say. Here is the program. We will say switch A. So note that this is not a relational expression in a normal if for our wild cells. It is actually an expression which must result in a value that can be compared for equality. So A itself is an expression. Now observe the code that is written next. Case 0, C out, U type 0 and L. So basically it is just announcing that somebody typed a 0. You could take any other actions if you wanted. After this execution the control will continue to execute remaining instructions. You do not want that because you want to take different actions depending upon different values of it. So you use the break state. In case A is 0 you will come here, execute this and break out of the entire switch loop. The switch block starts here. It will end somewhere later as we shall see. Suppose the value is 1, 4, 9. We know that these are perfect squares. So we want to classify these numbers as perfect squares. That means the input that you give is a perfect square. So the value is a perfect square. Notice case 1 column, case 4 column, case 9 column. This means that in any one of these three cases you will come here. So you are specifying three possible values for which you have to execute this statement. Again there is a break. Case 2 means if the value of A is 2 the control will skip all of these and come here directly. Here we are saying 2 is an even number. Again we are using break to get out of any remaining statements to go outside the block of switch. Here is a similar statement here. Case 3, case 5, case 7. That means if A is equal to 3 you will come here. If A is equal to 5 you will come here. If A is equal to 7 you will come here. What is important is to write the column here. The column actually separates out a label in a C program. We are not going to look at labels because they are used only along with a statement called very harmful statement called go to statement. We are not going to use that and we are not going to discuss that. But the column is a similar notion. We shall later on see when we discuss more object oriented concepts then certain memberships of classes etc could be denoted by two colons coming one after another but that we will see later. So as of now the switch statement will switch you to here, here or here depending upon the value of A being any one of these and then I announce A is a prime number. If I have 6 and 8 then I say A is an even number. I am noticing that I am using break every time so after that I get out. Now it is quite possible that somebody who gave the input as A without realizing that the program is attempting to classify only values between 1 and 9 might have by mistake given 27 or could have given 0 or could have given minus 12. After all A is an integer and all possible integer values can be given as input. Since we do not want to handle any one of those there is a default case. That means if the expression A does not have any one of the values which have been very specifically written in terms of our cases then the control will come to default. Default is usually the last item written in a switch statement. If something is not satisfied you come out to default and then in the default we are reminding only single digit numbers are allowed whatever some state. This is of course an artificial example but some real life examples could be that suppose you have written a program some such programs you will be writing as part of your projects team projects that you will do where a large application you are given which does 3 or 4 different things. Consider the academic office application. An academic office application will permit you to register for courses. It will permit teachers to enter grades. It will permit you to locate your registration record. It will permit you to alter courses. It will permit you to look at timetable. For each of these there are different programs that have been written at the back. It is not uncommon in such cases that when you enter that application for the first time and you execute the main program you will be shown a menu. It is a press one for looking at your registration record. Press two to delete courses. Press two to add courses. Press three to locate your timetable. Press four to do something. So when you press one, two or three something has to happen at the back end. That one, two or three is captured as input and effectively a switch statement like logic will be used at the back end to say if input is one invoke this. If input is two do that. If input is three do that. So the usage of the switch is actually quite common in large and complex programs which demand interaction with the users and they give multiple options to the users. So switch and the associated break statement and break and the associated continue statement for iteration exits. These are two important additional features that should be kept in mind when you write your programs. With this we now come to the discussion of an extremely important part of the course which is modularizing our programs. So far we have been writing eight, ten, twenty line programs. But when we write hundred line programs, when we write two thousand line programs, when we write fifty thousand line program, it is very obvious that fifty thousand line single monolithic program is completely unreadable by any human being. So we would like to organize our program into separate modules based on the task which those modules perform. At our level of understanding now we shall introduce this notion of modularization through an important usage which is called the function definition and function invocation. For that we revisit some of the problems that we have seen earlier. This is the problem of finding out root K using Newton-Raphson method. All of you remember this program? We had said that if we meet the accuracy requirement of some threshold, then we can terminate the loop. There was only one question that I wanted to ask because nobody raised it here. This program will execute correctly in your opinion? Is there any serious flaw? K is taken as input. It's root I want to find out. And I start with an initial value of x equal to 1. We have said that we will always reach convergence. The problem is with this expression here. We all assume that this expression is correctly written because mathematically that is what we would write x square minus K to be greater than this or K minus x square to be greater than this. Making sure that the absolute value of the difference between K and x square is what is being compared. However, the way this expression is written, it will be evaluated using C plus plus rules of precedence and associativity and not our knowledge of mathematics. C plus plus rules state that while you have star minus greater than or minus etcetera, etcetera, it is not very clear whether this or operator will not apply itself to 0.0001 or K in which case something very funny could result. Now, even I don't remember the precedence exactly because that's a large table. Do you? Some of you might, but most of you won't. And therefore it is absolutely pertinent to make sure that if whenever you are writing a complex condition, you yourself provide appropriate set of parenthesis to ensure that the precedence that you have in mind is implemented by C plus. Consequently, I would suggest that independent of whether C plus plus compiler correctly translates this as we wish, we should still put this into parenthesis and this into another parenthesis indicating that this is one comparison, this is another comparison and either of the two comparisons yielding true, I should continue. So please keep that in mind whenever you write long expressions, do not assume that your notion of mathematical precedence or arithmetic operator precedence that you are used to is exactly what C plus plus implement. It actually doesn't. Anyway, the point now is this is how we could write let's say finding out the root of a Newton-Raphson method. Notice that here what we are doing is effectively this is the evaluation of f of x upon f dash x. Now this is one example. There could be situations where I have to evaluate a function repeatedly in my program. Here I am evaluating it only once. But suppose I have to evaluate it repeatedly, I will have to keep writing the instruction for calculations again and again and again. This is another alternative using a fixed number of iterations. This does not use a complicated condition, but it just says I will use 10 iterations and at the end of 10th iteration I am fairly certain that I will get an accurate result. You can cross check indeed the Newton-Raphson method for this particular case converges quite rapidly and you would get as good an approximation as you would with the wild state. This is another way of doing things. Look at what I am doing. First look at the previous example. For int i equal to 0, i less than 10, i plus plus. So I am specifying 10 iterations. In each iteration a new value of x is calculated based on the old value exactly using the formula that we worked out. Consequently we are pretty sure that x will approach the correct value and within whatever accuracy I want I would be able to get that. Can I use the FOR statement, but can I instead of saying fixed number of iterations, prescribe as many iterations as are required to meet my condition? The answer is yes. I could for example write my FOR statement in this fashion. So I take the value of k. The initial value is x equal to 1. That is the first specification. This x is not a counter. x is actually a floating point variable, but it is perfectly permitted. The next specification is the condition for continuation of iteration and that is exactly as we had written namely that I till I find my root within the accuracy of function of x between being close to 0.0001 on either side of the x axis I should continue. And after what will I do in my continuation? After I continue I generally increment the value of x. It so happens that within the body of the iteration let us go to the previous slide. Within the body of the iteration I was recomputing x any which way. I can consider this to be an increment of x. Although it is not really x is equal to x plus something that is a complex formula, but value of x is changing. I could then prescribe that change as the third specification of my FOR statement. x is equal to x plus k by x by 2. After all what is required in the FOR statement is that at the end of iteration when you increment you are trying to change the condition which is being evaluated which is ordinarily i less than equal to n or some such thing. But as long as you make that condition change and then on the re-evaluation sometime or the other this condition will become false is perfectly fine. So whatever was in the loop body of while which was changing the condition effectively is now incorporated as the third specification of FOR. And having done that I notice I have nothing else left to do. This is the initial value I have to give. This is the terminal condition. If this is not met I should terminate. Otherwise I should execute the body, increment the count variable and go back and keep on doing this. Instead of incrementing the count variable separately in the FOR specification I say this is the count variable execution and that matches with what exactly I wanted to do within the iteration body any which way. Consequently this is the FOR statement with null block. There is nothing specified to be done in FOR. The FOR loop itself does all the computations and comes out. I just wanted to tell you that this is a perfectly valid C++ program. It will work exactly like the previous white statement does. In fact FOR and while therefore are quite interchangeable. Just as I can implement while kind of control using FOR as you see here I could also implement counting control using while as we had discussed earlier. There I could explicitly start with some initial value of a variable, a count variable as 1 outside the while loop. Within the while condition I would say while I less than equal to n and after whatever block I had to write at the end if I had one more condition explicitly a statement explicitly it says I++ I would have implemented a FOR control. So these two are exchangeable. Also just like in the while statement by enforcing a condition which will always remain true I could enforce a perpetual iteration in finite loop. Similarly in FOR also it is possible to enforce a perpetual loop. This is the explanation of the previous slide that we saw. The use of FOR without a body is possible we said for x is equal to 1 x star x minus k greater than this etcetera x equal to this. So here x is initialized to 1 before the loop then it is incremented to reflect the new x calculated properly and the condition will stop the loop when accuracy is obtained. This is the explanation for the previous slide. However it is possible to write something as simple as this FOR in bracket semicolon, semicolon bracket clause. What this means is I am giving a FOR instruction to the computer I am showing no initialization statement so nothing needs to be done. I am not putting any condition which means this loop is to be executed perpetually and obviously I am not putting any increment condition. Just like the example that we saw earlier we all felt it was artificial example when we said vile 1 why should we say vile 1 or vile 2 for example would have had the same effect. Basically we are enforcing a infinite iteration. In exactly the way we said vile 1 we could also say FOR in bracket semicolon, semicolon bracket clause and this will also enforce an infinite iteration. Ordinarily we cannot imagine why I would require an infinite iteration but it is possible that my logic is so complex that there is no single condition in which I want to exit the iteration. There may be 100 statements within that block and maybe after 20 statements based on one condition I might have to get out. However ordinarily that condition will be satisfied so I want to continue iterating but later on some other condition I might want to get out. Now that I have empowered myself with statements such as break and continue I should be able to do this fine tuning of my exit from the iteration or going straight to the next iteration using any one of those two statements. Consequently you will find that in many professional programs it is not uncommon particularly when you have a very complex logic to specify an infinite iteration either by saying vile 1 or by saying FOR semicolon semicolon and then take care of exiting the iteration appropriately using the break continue statements along with some if condition checking. So this is additionally that what you can do there. Okay we come back now to our main focus of discussion namely the functions in C plus plus. We are now talking about a facility which will compute let us say I have a quadratic fx is equal to x square plus bx plus c ordinarily if I want to evaluate this at some value of x what will I do I will write that formula y is equal to a times x into x plus b times x etcetera. But suppose I have to evaluate this quadratic at one place here another place there third place somewhere else then I will have to repeat the computational specification for this quadratic expression at each of these places. So if I want to execute let us say this particular expression to find out the value of this function at some x equal to 2.3 and x equal to something else 4 then I will have to say y1 is equal to all of this with x equal to 4 somewhere later I will have to say y2 is equal to all of this with x is equal to 2.3. If I have to evaluate it at 5 places I will have to do the Godagiri of writing the expression 5 times. Can I neatly bundle up such computations for a function separately at some place and can I tell c plus plus compiler that look whenever I want to evaluate that quadratic I will give you a value of x take that value to that function execute whatever are the statements required to evaluate that and come back with me come back to me with whatever value has been computed this essentially is then the notion of the function. So we observe that it will be useful if we will write the formula separately at one place and make repeated use of those instructions whenever we require. Essentially let me say that formula is written by me as something called a function quad for quadratic. Then I would like to say y1 is equal to quad a comma b comma c comma 4 whenever I want to evaluate that quadratic for x equal to 4. Later on in my program if I want to evaluate it for x equal to 2.3 I could use such a statement y2 is equal to quad a comma b comma c comma 2.3. We note that quad a comma b comma c comma 4 or quad a comma b comma c comma 2.3 are not natural written statements of c plus plus. C plus plus does not recognize this but c plus plus provides us with a facility by which we could describe such functions. When we said describe such functions it means that we can write all the instructions which are required to evaluate the function value. And what we write in parenthesis are called parameters. So we will supply these parameters whenever we want to use this function. The machine will take it to that instruction block as I mentioned calculate the function value and return back with that value which will be replacing this entire expression. So suppose the computations turn out to be say 7.83 that value will be returned here and I will actually have this as equivalent of y1 is equal to 7.83. Now this facility is called function specification and function invocation. I now take you through the same example that we had used earlier in the Newton Raphson method where we were to evaluate a function and its derivative. We used it last time to calculate the root of a number but in general you could find root of any function. It could be a polynomial for example. As long as that polynomial has one real root at least and as long as you have a decent starting value which is an estimate and if you have a conversion sort of algorithm then using the same method calculating fx, calculating f dash x to represent the approximation by tangent of that curve at some point you would be able to successfully go near other root. However the more complex function you have the more complex will be its derivative and then if you were to do it again and again and again not in this particular example but in some other cases then you will have to repeat those computations by giving instructions again and again. That is why we look at it and say that we observe it would be nice if we had a separate block of instructions to calculate these. A function in C is such a separate block. So a function that we write in C plus plus and we shall see how exactly the function is written. This function will take one or more parameters from us. So imagine function to be a separately sitting entity. For a moment you imagine that Dumbo that we had talked of in the first lecture. Imagine that that fellow has an assistant Dumbo. Who is that function Dumbo? So it is a separate entity completely. Whenever we write a function reference within an expression in our instructions actually that whole set of parameter values will be taken to that gentleman who will do the computations as we prescribe and will return the value that is so computed. So here are some examples. Float my function in bracket float A float B float C float X. What I have written here? Said float value. Value is equal to A star X star X plus B star X plus C return value. Remember this group of statements will not be part of your long program which is implementing a solution. This is a separately identified block of statements which will evaluate only the value of a function. The word function here is not mandatory. Notice the word is my function. So it is a name. I could have chosen abrakha, abrakha, F, whatever work. So what identifies the definition of a function in C plus plus? Well, that the word float and as we shall see the fact that such definition must occur at specific places within your program. You cannot write this anywhere arbitrarily within a program. As a matter of fact, the normal requirement is that any number of functions which you wish to define and which you later want to use in your program, they must be defined at the beginning before the function main is written. In fact, int main is nothing but a function that we write. We do not call it the operating system called same. So let us look at this function definition. Float my function followed by these four parameters. Each parameter has a value which is of a certain type. Notice that ab and c are not read here by input statements. Ab and c are not also assigned any values here. Same thing about x, which is also a parameter. X is neither read in this definition nor it is being calculated. However, we are using all of them in this expression. Our rule is that we cannot use anything in an expression unless we have initialized those values. This is the point that is being made that whenever I write parameters like these, they represent the corresponding receiving place for the values which will be sent to that function whenever that function is called. So you can imagine that in your main program, you will have the equivalent variables abcd or ab1b1c1 or mnop whatever. You will have those variables. Whenever you call that function sitting in a corner, you will be giving these values 3, 4, whatever you are prescribed. You cannot give five values when you have defined only four values as parameters in that function. You cannot give three either. You have to give exactly as many values as are prescribed there. Now just as you have memory locations for those variables in your program, say pqrs, for each one of them when it becomes a parameter, imagine that there is a memory location for the function which is a separate memory location. And you can imagine that a value as if it is being picked out from here or copied from here and is put into that memory location. So that memory location is a separate memory location. Its scope is only within that function. Therefore when I come inside this function ever, I would have come here only because someone called me and whosoever called me would have supplied these values to me. With these values therefore I can proceed to any computations that I want. Since I want to evaluate the value of the quadratic for a given x and for a given values of ab and c, I can execute this statement. This will result in some value. Now that function has calculated this value. But I need that value in my program here. It is precisely because of that I have asked that function to do some computations and given the parameter. Upon completion of the task of calculations that function just as it received parameters in its own memory locations, from its memory location for value, it will pick out the final value and return it to me. And when it returns, I can use that value and continue to do whatever I want to do with it. That return value is returned using a statement return followed by value. Look at the evaluation of the derivative of ax square plus bx plus c. I have written another function here called my derivative. This does not require so many parameters because the derivative does not depend on c at all. It depends upon ab and x. So I have only three parameters. Float a, float b, float x. Again I have a float value. Observe that while these might have been written one after another, that is exactly how they will be written. This value and this value have nothing to do with each other. So another important notion which we will clarify further as we go ahead with discussions is the notion of the scope of a definition. When I define a variable in my program, ordinarily that variable is known in the entire program anywhere. So anywhere in the program if I refer to that variable for input, output, computations, it will go to that memory location, take its value or put that value, whatever. However, this scope is extremely refined in c++. For example, there is a block scope which means that if I declare a variable inside a block, inside a fall block for example, then that variable is known only inside that fall block. It is not known outside it. Suppose outside I have declared a variable by the same name and those two names would they clash? No. When I am outside that block, that name is known by the definition that I have given earlier. When I am inside that block, that is forgotten temporarily. A separate memory location which has been created for another name which I have declared inside that block will now take effect. In exactly the same fashion, whenever I am executing this, the value has a variable location there for this function. Whenever I am executing this, this has another value location somewhere else because these two functions are independent blocks. So we should keep that in mind. This is the syntax definition of the function. The first word tells me what is the type of value that will be written. Remember in C++, any value that you speak of must belong to one of the types where so far seen integer and float and the variations thereof like double and whatever. Later on we shall study care type and some other types that are available. But whatever is the type, I define that type here. Then I give a name. This is my own choice. And then in parenthesis, I write as many parameters as are required for me to correctly evaluate that function value. Could be 1, 2, 3, 4, 5, whatever. Each parameter must have an associated type and this type must match the corresponding type of which value a parameter has been given to that function. They must match exactly. I can give an int parameter for a float parameter in the function definition and vice versa. There is no automatic conversion or any such thing that happens in an expression evaluation. So this is rather stricter. And the return statement of course returns a value. This incidentally need not be a single variable. It can also be an expression. That expression will be computed at that point in time. Whatever is the value, that value will be written. This is something that I would like you to read and imbibe very carefully. This is the, in a nutshell, whatever I have stated about the function, this sort of captures the essence. So imagine that the compiler translates instructions of any function we define separately and keeps these as an independent block. Always whenever you talk about a function or refer to a function in your mind, it is good idea to imagine that my program is here, my computer is here, but my function is somewhere in that corner. So imagine some other computer which is executing that function tightly coupled to my computer, but independent block. Anytime a function is invoked, the given parameters are taken to that function. The execution of my program temporarily suspense. I stopped doing whatever I was doing because a function has been invoked. So I assemble the parameter values, go to that function, execute the instructions in that function, come back with a written value and reshoom whatever I was doing. That is the way the function executes in our model. In the Newton-Raphson method, given a value of x, we calculate the next value using this formula. So that means we have to evaluate fx and evaluate f-x. Suppose the function was this, then whatever two c++ functions we have written, my function and my derivative can be used if these are the functions that we are using in the Newton-Raphson method. So using my function and my derivative, my program will become simply like this. I start with x equal to 1. I am doing let's say 10 iterations, but the computation that I do within each iteration says x is equal to x minus my function in bracket abcx divided by my derivative in bracket abx. Notice a little shortening of the program here. The advantage is not really apparent because you are invoking that function exactly once. So you might as well have written the statement there itself which does the computation of function value, which is what we had done earlier. But what is important is to understand how the function works. I will execute all these instructions normally. So far there is nothing associated with the function. I come to this assignment statement. I keep aside the LHS which is an L value x. I look at the RHS. Beyond the equal to sign, this is the RHS. RHS is a complex expression. I start looking at components of the expression based on the precedence. I come across x minus my function in bracket this, this, this, this. X is non. I have a value. If I say minus w, I would have picked up a value from w. But what I have is called a function reference. The machine understands that this is not something that I can pick a value from somewhere. This is a function reference. Since a reference is encountered at this stage, the machine will abandon executing remaining part of my instruction. We'll hunt out this my function code which is sitting in a corner. Go over to that my function with these parameter values of a, b, c, and x. Whatever those values are at this point in time. It will execute those instructions in my function and come back exactly at this point. Suppose the value turned out was 37.58. All that the machine does now after it comes back is it will replace this entire expression by x minus 37.8 divided by whatever one. So effectively every function reference is replaced by a value which is written from that function. It will proceed further. It will have to evaluate this. Again it will go to another function using these parameters, come back with a return value. And with the returned values and the value of x, it will complete the calculation of this expression. Is this clear? These are invocation rules stated very explicitly. You can read them up. Again what I have explained, I have reiterated it because these concepts are rather important. It is worthwhile to ensure that you have imbibed them completely. So whenever a function reference is seen by the program, generally while evaluating an expression, program execution is suspended. You go over to that corner with the parameter values. The value of the function is calculated by that block which is sitting in that corner. The value is returned to me and I take the return value, substitute it for the function reference and carry on with my task. It is actually conceptually very simple. Now this is what leads to modular programming. Particularly if I have very complex functions defined, each one of which takes maybe 30-40 lines of computation, rather than repeating those 30-40 lines as instructions in my program multiple times, whatever I require to calculate that function value, I would rather prepare a module and keep it aside. Another advantage is that suppose I want to modify this Newton-Raphson method. Instead of a x square plus b x plus c, I want to find out the root of a cube, a cubic, unlike a quadratic. A quadratic may have only non-real roots, but a cubic always has at least one real root. So if I had a cubic, a x cube plus b x square plus c x plus d, and its derivative is 3 a x square plus etc etc etc, if I were to implement all these computations in my program as I was doing earlier, then I will have to go through the program to find out where I was writing, quadratic and its derivative and replace each one of those lines by an appropriate change to the cubic equation. On the other hand, if I have written my program in a modular fashion by defining functions, then my main program for Newton-Raphson method stays as it is. The only thing I do is I change the function definition for the function and the function definition for the derivative and my job is done, my program can run as it. If I can write such functions and use them in my program, can I not use functions which a friend of mine has written? So somebody has written a program to find out inverse of a matrix. Now why should I rewrite that function myself? Why can't I use that code directly? The answer is yes, of course you can do that. We can even compile those functions such as matrix multiplication, matrix inversion, any other complex computations as separate programs and then link them, connect them. It's sort of there somewhere else outside when I compile them and link them, they sit in my corner so that they become visible to me. I can invoke them and they can return values exactly the kind of values that I would return with my program. It is perhaps now that one of the clumsy lines in our program we can understand. You remember we were always wondering why did we say int main and why did we say return zero at the end? This is because what we write and we believe it is a main program that we have written. For the operating system it is actually a function written by somebody else, namely you and I. Just as within my program if I have written a function I can invoke it and it will return me some value. Similarly my entire main program is treated as a function by the operating system. And when I say dot slash a dot out what the operating system is doing is actually it is invoking my function. Visibly it is not sending any parameters. Visibly it will have nothing to do with any value written by you. But technically it is possible to do both and as we shall see later in the course actually whenever you execute a main program some implicit parameters are passed to it by the operating system. We shall see those parameters later. But what is also important to understand is that if I want an operating system to take some action depending upon how much program execution has culminated I can actually use this return value. And that is why whenever you write int main you will generally say return followed by a value. It is always a integer value. The return value is integer value because we have said int main. If I had said float main I must return a floating point value. There is a third option called void. Void. Void means no type. It means nothing. In such cases I will only say return I will not put any expression. This is the meaning of our saying int main and our saying return 0 at the end. And just as for a function that I define both these lines are obligatory. I must say int or float or whatever for the function definition and I must return an appropriate value in exactly the same fashion. Whenever we write a main program and want it to be compiled and executed by C++ we must write int main, void main or something main and we must return a value of the appropriate type otherwise it will not be executed properly. Here is another example. Taking it one step forward and perhaps suggesting why a function definition will be almost mandatory in our case. Consider this. In your school arithmetic you would have solved some problems like this search and indices and so on. So let's say I have an arbitrary formula under root m plus under root n divided by under root m plus n. I want to calculate these values. I have no clue on how to get an under root. But I say I have just written a program to find out the root of any number k. If I can find the root of any number k I can find the root of any number m. I can find the root of any number n. I can also find the root of number m plus n. Now this is slightly more complex. I have a program that program is written in terms of k. It reads the value of k and it finds out an approximate value of under root k and that I print. That is the program that I have. Now I want to write another program where I want to read two values m and n. For m I want to execute this entire thing to calculate root m. For m I want to do the same thing and for m plus n I want to do the same thing. What choices do I have? I write and rewrite and rewrite the same code three times. Once in terms of k, another in terms of m, third in terms of m. The other n beta strategy would be to write that entire Newton-Raphson technique as a function and pass to that function the value m when I want square root m, the value n when I want square root m, etc. And that is exactly what we propose to do. So we write a function called root x. If I have written a function called root x, then in our program we could simply write v is equal to, I will of course have to read m and n and so on. But once I do that, if I say v is equal to root m plus root n divided by root m plus n. Now you can see the power of the function definition and invocation. When this expression is evaluated, first time root n will come. The value of n will be taken as a parameter to that corner. The entire root computations will be done. Obviously there will be a return value which will come and replace this complete reference root m. Same thing with the second time again reference, same thing with the third time reference. This is the function that we would write. After include and using namespace std, I will say float root in bracket float k. Now you look at how my original program of root finding has become compressed. Why? I am not doing any input output here. There is no input, no output. This is a standalone function. Somebody will come with an input value and I have to return an output value. So no input output statement is required. I start with float x equal to 1. Whenever a control comes to this function some value will be sitting inside this because it is a parameter. So k has been initialized. I will do these iterations and at the end of these iterations the value of x that has been found is the value of the root which I have approximated. I simply return x. So it becomes an extremely short square root finding. And then how do I invoke it? Well I have to calculate the value of that formula as I said. So I must read values of m and n. Having read values of m and n, I have to calculate square root of m plus square root of n divided by square root of m plus n. It is simply done by invoking the function like this. Is this clear? So this is a very neat way of organizing our program. This example assumes that CS 101 slot 5 students have given an exam. CS 101 slot 11 students have also given the same exam. And I am just curious which group performs better. So I want to find out the average marks scored by students of slot 5. Average marks scored by students of slot 11. And I want to find out the maximum of these two. That slot group perhaps has performed better. I could of course write a program to calculate both these averages. I could also say that look how to calculate average. How do I have to calculate average? In slot 5 some 200 students will take that exam. In slot 11 some 212 students may take that exam. So once I have to calculate the average of 200 given numbers next time I have to calculate the average of 212 given numbers. And I have to get back these averages and compare them to decide which one is better. Can I not write a function which will calculate the average for a given number of students? So look at how the program is organized. Using namespace std double average int comma int. This is some fancy stuff. Where is the function? We said function must be defined before int. Before int main. So this is what C plus plus permits. If I want to concentrate on my main program and if I have a series of functions which I am going to use and which I am defining it permits me to define these functions later. But at the beginning it requires me to give what is known as a prototype definition. After all what is required for my main program to invoke a function? It should have a name. It should know how many parameters it has to send. It should know what type of parameter values will be sent and it should know what parameter value will be written. This is effectively what is compiled in this prototype definition which is a mandatory thing. So I am saying double average. That means the average is a function. It will return a value of type double. Double is double of float if you recall. What are the parameters to this? In this case I want to give a slot number and I want to give number of students in that slot. So I have two integer parameters. Notice that the names are not prescribed here. It is not required. What C plus plus compiler does is it prepares some kind of a blank coca for this function. It says in this function there are two parameters which are going to come. Each one is integer. So it actually creates two memory locations. It has not given them any name. It creates a third memory location. It will contain the return value of the type double. And it will say later on whenever I get the instructions for doing the computations in this function I will fill up those instructions in that coca. But I know the name of the function. I know how many parameters will come. What type of values they will bring and what type of value they will bring back. With that now I write my main program. The main program says integer n5 comma n11. I am using two arbitrary names to replant number of students in slot 5 and slot 11. I define averages as double. This is something that I would like to urge you to follow. A float variable particularly in 32 bit machines has very limited procedure. And whenever you use it for any serious computational purposes you might be very quick in reaching the limits of floating point representation and get into lots of possible errors which happen due to round off and so on in fractional numbers. It is generally a good idea to use double for floating point values. Machines are very fast so the extra effort required to handle double values is not so much. Memory is quite a bit these days and therefore double is more or less a standard thing. In fact, whenever you write a constant in your program x is equal to 7.5. The 7.5 is actually not translated internally as a floating point constant. Which translated is treated as a double constant. All constants that you write which are a floating point type are internally converted to a double. That is the standard default in C++. Anyway, so having defined these variables I asked for the number of students in slot 5 and I get the value of n5, number of students in slot 11, I get the value of n11. With these two variable values I calculate slot 5 average as average 5, n5. Notice 5 is my first parameter therefore in my mind I have decided that the first parameter will be a slot number. The second parameter will be the number of students in that school. Slot 11 average similarly is this and that once I have computed these all that I need to do is I compare if slot 5 average is greater than slot 11 then I output slot 5 perform better else I output slot 11 perform better. Any program. This is the function. I could have written this function instead of that prototype at the top in which case the prototype would not have been necessary because C++ compiler would have seen directly the complete details here. But if I wish to write this after my main function which is permitted then I must introduce a prototype at the beginning for C++ compiler to anticipate that when it is translating my main program and it encounters a reference to average then it knows exactly what kind of compilation it has to do. So this is the program. Whenever control comes here it will come with two values slot and n. Now the names are given. The slot and n will be utilized inside. As you will see I am not doing any computation with slot. I can't find a square of the slot number that makes sense. But I am using it to give an output. So for example give marks for student number i in slot number so and so. So give this student first student in slot 5, second student in slot 5 etc. Later on when I invoke it with slot 11 same thing will happen here. Notice what I am doing. I am starting with sum equal to 0 and if there are n students this is common n now. Value that comes in here will be n5 in one case and n11 in another case. But I need to write only one set of instructions. And then I calculate the sum as sum of all the marks. What am I returning? I am deliberately not calculating the final result in a separate variable. I could have done that. This is just to show that I can write any expression that I want to do. When I execute this program with the values this is a sample execution. So I compile the program. First I give number of students in slot 5 as 3, number of students in slot 11 as 2. And these are just arbitrary values I have given. Then this is how, now the first two lines come out of the main program. Then I invoke the function. The subsequent input output is happening within the function. So the function reads for student number 1 I give the values as 17.5, student number 213, student number 3, 12.5. The number of students are important because the average sum will have to be divided by the actual students who participated in that exam. And it so happens that the average of slot 5 is better. So I say slot 5 has performed better. This is how you will organize all your functions. And in fact one more question which I will leave it to you to ponder over the weekend because that is what we are going to discuss next. You now understood how functions can be organized functions can be written. However in this particular example suppose there are not 3 and 2 students there are actually 270 and 260 students as we have now. And in general I will not be interested only in the average marks. I would be interested in knowing who are the top ten performers. I would be interested in knowing who are the ten people who have not been able to do well at all so that I can help them more. I would therefore need information about marks of individual students no matter whether they are 200 or 500. In fact I can't compute the grades only by knowing the average. I would like my computer to record marks for each individual student. And I would like to read them. I would like to arrange them in descending or ascending order. I would like to do variety of things. How do I store a large number of numbers and yet be able to identify each individual number and process it in whatever context I want to do. Currently there does not seem to be any mechanism. As a matter of fact when we wanted to find out the maximum of 5 numbers we said we could extend it to find out maximum of 200 numbers by using only one variable. Fine we solved the problem of finding out the maximum but we lost the individual identity of 200 numbers. After they were read and we have compared the maximum and found out if you ask me what was the fifth number I don't know. What was the 75th number in the serial order in which it was given as input I don't know. Okay fine you have found out the maximum. Who is the student who scored this maximum I don't know. That is not very useful. Consequently we now need an extended ability not only to represent individual values in individual variables but collection of values and still be able to refer to them using the neat techniques of iteration to move from first value to second value to third value to fourth value. Otherwise we will go mad writing down 500 variable names, 500 iterations and so on. That is precisely what we are going to discuss in the next week. The notion of arrays or a set of values and how they are to be handled and we will extend this example further.