In previous episodes we have discussed the notion of control structures. They are special instructions, making it possible to repeat processing or to execute processing according to a number of conditions. Today, we will expand on this idea with another way to repeat processing : the conditional loops. If, in a program, we wish to repeat a number of processing and that the number of repetitions is known à priori, that is, before entering the loop, it is possible to use a "for loop". However, there are situations where we wish to repeat processing as long as a given condition is true but we do not know how many times it will be necessary to repeat the processing until the condition becomes false. In such a case we have to use other types of repetition instructions : The conditional loops. Their execution depends on the fulfillment of a condition. In C++ they appear as loops "do while" or "while". For illustrations purposes, let us reuse our example tasked with the computation of some grades' average. A priori, we do not know how many grades will be entered to calculate their average. We begin by by asking it from the user. The number of grades will thus be entered via keyboard interaction. Then, if this number is positive, we will use an iteration "for" and input all the grades. At every iteration, a grade will be typed on the keyboard and added to the sum of all grades. Once all the grades have been entered, we will obviously exit the iteration and continue with the execution of the rest of the program At this point, we will calculate the average and print it. We can surmise that is not very natural to let the user input a number of grades equal to 0. Thus, we wonder how to compel the user into typing a number of grades strictly greater than 0. Concretely, we wish to repeat these instructions until the user inputs a number of grades strictly positive. We do not know how many times we will have to repeat these instructions, for we cannot forsee a priori when the user will indeed input a number strictly positive. Thus, we will have tu use a special control structure. What we are looking for, here, is the so-called "do while" loop. The "do while" loop is written this way : the keyword "do" followed by a pair of braces and the keyword "while" which means to repeat as long as this condition is true. Concretely, we will repeat these instruction inside the body, that is the instructions in the braces as long as the condition is true. Let us now examine step by step the execution flow of our little example with the "do while" loop. We presuppose that a variable "nombre_de_notes" has been previously declared and is ready to contain the number of grades entered by the user. Once we reach this instruction, nothing prevents us from entering the loop's body. At this point, we wil ask the user to input the number of grades. The number of grades is entered via keyboard interation. Now this line will be executed, evaluating the loop continuation condition. Let us suppose that the user types, as the number of grades, the value 0. In this case, the evaluation of the condition will return "true" which means that the number of grades doesn't fulfill our criteria. Since the condition is true, we will enter a new cycle. Once again, we will thus execute the loop's body. This time, let us suppose that the user inputs, as number of grades, the value -1. During the evaluation of the continuation condition, this condition will once again return true, for, of course, -1 is less or equal to 0. At this point, we will once again, enter a new cycle. We begin our third iteration and, again, we will ask the user to input the number of grades and read it via keyboard interaction. Let us suppose, that this time, the crestfallen user ends up understanding what we're expecting and inputs number of grades strictly positive, for example, 6. At this time, during the evaluation of the loop continuation condition, the evaluation will return false since 6 is strictly greater than 0. Thus, we exit the "do while" loop and resume the execution right after the semicolon concluding the "do while" instruction. Now let us formally examine the syntax of a "do while" instruction in C++. The keywords "do while" frame the so-called "do while body", which rests in braces. Following the "while" is the loop continuation condition. The semantic is as follows: the processing within the body are repeated as long as the condition is "true". Once again : we repeat the processing as long as the condition is "true". Not unlike the instruction of a conditional branching, the "do while" loop continuation condition can be relatively complex, resorting to logical operators. For example, we can formulate such a condition : let's repeat the processing as long as x is equal to y plus z and that z is greater than 10 or t is less than 25. Thus we can imagine pretty sophisticated continuation conditions, especially resorting to logical operators. It is also worth noting that the parentheses around the condition are absolutely mandatory in C++. Just as it is with the"if", the condition will be written in a pair of parentheses. An important observation regarding the "do while" loop is that its body will systematically be executed at least once. Indeed, if we recall our step by step example of a "do while" loop, we see that at this point, nothing prevents us from entering the body, thus we will execute the block at least once. However, this block will only be executed once if, after the first iteration, the evaluation of the condition returns "false". In this case, we will simply resume the execution after the loop. But in the meantime, the block of instructions will have been executed once. This is very important and stands among the "do while" loop's specificities. Another observation : if the condition doesn't ever become false, then the processing will be repeated indefinitely. Consequently, one must be careful in the condition's formulation in order to prevent an infinite loop. Indeed, infinite loops are generally not the expected result, at least not for beginners. Those were the core ideas regarding the "do while" loop. Before we can put behind us the topic of the "do while" syntax, please heed this last warning : this semicolon here, at the end of the "do while" instruction, which is rather easy to forget. Now, there are situations where we wish to test the loop's condition prior to the execution of the body. In such as case, we will resort to another variant of conditional loops : the "while" instruction. Its syntax is as follows : the keyword "while" immediately followed by the condition, in parentheses. Then comes the loop's body in braces. The "while" loop is rather similar to the "do while" loop : we will repeat the processing as long as the condition returns true. The main difference is that, in the "while" loop, the condition is tested before we enter the loop. Thus, if the condition is false from the get-go, we will immediately jump to the next instruction after the "while", meaning that the block will not be executed a single time. As we've seen before, it is not the case with the "do while" loop where the block will always be executed at least once. Here are two basic examples, illustrating the fundamental difference between "while" and "do while". We have here two very similar loops, with identical continuation conditions. In both cases, the continuation condition relies on a variable i, intialized to 100. Let us start by examining what happens during the execution of the "do while" loop. When we reach the execution of the "do while", nothing prevents us from entering the loop's body. At this point, we will print the message "bonjour". Now we reach the point of the "do while" loop where the continuation condition is evaluated. Since i contains 100, the condition will of course return "false". Thus we exit the loop and continue the execution with the possible instructions after the "do while". In the meantime, the message "bonjour" has been displayed on the terminal. Now on to the "while" loop. Upon this line's execution, we will right away test the condition which will, as before, since both conditions are identical, be evaluated as false. This means that we won't ever enter the loop's body and instead continue the execution right after the "while". Thus, the loop has not printed anything. Here, we found ourselves in a situation where two very similar loops : one "do while" and one "while" do not lead to the same result. This is due to the time where the continuation condition is evaluated. Among the classic mistakes among beginners using the "while" and "do while" loops is one possibly leading to very puzzling results. This mistake relates to our famous semicolon. This semicolon marks the end of the "do while" instruction and is placed right after the condition. Now, if we were to add a semicolon after the "while" condition, our program would behave strangely and, most importantly, incorrectly. Let us see what would happen if we added this semicolon. This instruction would be interpreted as if it were a "while" loop with, as body, an empty instruction. Therefore, there is nothing within the loop impacting i. So, if i contained something less than 10, for example 1, this loop would cycle indefinitely since there is no way to make i reach a value greater than 10, which would render the condition false. As a matter of fact, this ++i, which we probably wished to be inside the body, will never be reached if i started containing less than 10. Indeed, this plus plus i instruction will be considered as being outside the "while" loop. Now you know three ways to repeat instructions in a program : the "for loop" which we have discussed in a previous episode and what we have just seen, namely the conditional loops which can take two forms, either "while" or "do while". Now, we will discuss how to choose which form to use. The choice depends on rather simple criteria. If the number of repetitions is known a priori, we will want to choose the "for" type iteration. Imagine for example that you wish to calculate the average of all students attending this course. We know a priori how many students follow this course. Thus, in order to calculate the sum of the grades and the average, we will gladly use a "for loop" since the number of iterations is known a priori. However, if the number of iterations is not known a priori, we will pick a conditional loop, either "while" or "do while". Now how do we choose between "while" and "do while" ? Simply, we will ask ourselves if we need to execute at least once the loop's body. If we want the body to be executed at least once, which is the case, if we're interracting with the user, for example, if we ask a value from the user and demand this value to be between two values, we need the user to input the value at least once before we can test if it fulfills the condition. In this situation, we will rather resort to a "do while" loop. Otheriwse, we will naturally use a "while" loop, that is, a loop where the condition evaluation will occur before entering the loop's body. Now, let us enrich our little example from before. It is a typical situation where a "do while" loop is required since we need the user to input the number of grades at least once before we can test if this number is within the desired interval. Thus we resorted to a "do while" loop. Now we wish to upgrade this program a little so that the user will be informed upon entering, for example, a negative number, of the program's expectations. So we wish to complete the here program so that a relevant message will be displayed when the user enters a negative or null grade. How should we proceed ? Obviously, this message will appear every time the number does not fulfill the desired condition. Thus, it will probably be placed within the loop's body : we will repeat this instruction every time the user inputs something incorrect. We could imagine such a solution : enriching the loop's body with one more test. After having read the entered value, we will test if the typed number is less or equal to 0. In this case, we will display a message to warn the user. Please note, that this is indeed part of the loop's body since we wish to repeat this process every time an unsatisfactory number is entered. As you can see in this example, the condition testing if the number of grades is less or equal to 0 appears now twice : Once in the "if" and another as the loop continuation condition. It would have been smart to store the result of this evaluation in a variable so that we do not need to evaluate it again. For example, we can introduce a boolean variable "saisie_invalide" initialized to "false". (TN: saisie_invalide means invalid_entry ) We will update this variable here, in the loop's body at every iteration, storing the result of the condition evaluation, that is "number of grades less or equal to 0". Thus, "saisie_invalide" will contain either "true" or "false" This will allow us to write the condition in a unified way, replacing this by "if (saisie_invalide)" and we'll resume the processing as before. We will repeat the processing "while" the the variable "saisie_invalide" contains true. This here is good practice. In a program, we always wish to avoid situations where we express the same thing multiple times in independant ways, in several places. It is like the copy-paste. So, let us return to our little example regarding the input of grades by a user. Let us examine different ways to formulate the condition in order to tend to different needs. Until now, we compelled the user to type a number of grades greater than 0. Let us imagine, that we wish to restrict the number of grades to 10. The question we are asking is: how do we formulate the condition with this new goal in mind ? In order to formulate the continuation condition, let us start by expressing it in plain words. Now, the number of entered grades will be incorrect in two cases : either this number will be less or equal to 0, which contradicts this expectation, or the user will input a number greater than 10, which contradicts this. That means we will loop as long as we find ourselves in either one of these situations. In both cases, the number of grades, is incorrect. It now becomes obvious that we will have to resort to the logical connective "OR". Namely, we repeat the processing as long as either situation is encountered. In C++, this will be translated by such a code. We repeat the processing as long as the entered number of grades is less or equal to 0 OR that the number of grades is greater than 10. Let us move on to another example. We wish to write a short program which purpose is to make the user guess a number. To simplify, let us imagine that the number to guess is always 5. The idea is to code a "do while" loop asking a number from the user and comparing it with the secret number. We will exit the loop only once the number has been guessed. We're wondering how to formulate the condition so that we exit the loop once the user has guessed the correct number. As before, we will start by formulating the condition in plain words. We know that the loop is to be repeated as long as the user has not guessed the secret number. What does it concretely mean ? They have not guessed correctly as long as the typed number is different from the secret number, which is 5. How do we formulate this condition in C++ ? Simply through this line : we repeat the process as long as the entered number is different from the secret number. We notice that the formulation in C++ is not too far from the formulation in plain words. Let us now enrich this example where the user is tasked with guessing a number. We wish to give the user only a limited number of trials. The poor fellow will not be allowed to guess indefinitely. Thus we will resort to a trial counter, that is, a variable we introduce here. This trial counter will be incremented at every loop iteration. Now, we wish that, after three trials, the game will be over unless the user has guessed correctly. Now we're wondering how to formulate this condition. Once again, let us start by formulating this condition in plain words. We will repeat the loop as long as the user has not guessed the correct number and as long as the user still has trials left. It is clear that both conditions must be fulfilled together. We will keep iterating only if both conditions are fulfilled. Now, let us try to formulate this somehow closer to C++. The first condition is that the entered number is different from the secret number. The second condition is that the number of trials is less than 3. Both these conditions must be verified together. In C++, this translates into this line of code. The first condition is that entered number is different from the secret number, which translates into what is written here. The second condition is that the number of trials must be less than 3, which translates into what is written. We have here the logical connective "AND" which guarantees. that both conditions must be fulfilled simultaneously. Again, we see, that the C++ formulation is not too different from the formulation in plain words. The user can now exit the loop in two different ways. He can exit the loop because he has guessed correctly, in which case, this part of the condition becomes false or because he has run out of trials. Now, let us suppose that we wish to let the user know why, concretely, he exits the loop. Since we wish to inform the user of the reason why he exits the loop, we need to enrich the program. Once we have exited the loop, we will test for which condition we have exited. Did we exit the loop because of the failure of this condition, namely, because the user has guessed correctly. Or did we exit the loop due to the failure of this second condition, namely, because we ran out of trials. Thus, we will run the test here. If the entered number is equal to the secret number, it means we exited the loop because of this condition's failure and we can inform the user that he has guessed correctly. Otherwise, it means that the user has burnt all his trials and we can inform his that he has lost the game. We can also print the secret numer to let him know what we were expecting from him. However, we must avoid logical fallacies in the test formulation. Let us imagine that, trying to the see if the correct number has been guessed, we test if the limited number of trials has been reached. In this case, the situation where the user has guessed the correct number exactly on his third trial will be interpeted as a failure while it was actually a success. Thus, one must remain careful regarding the logic in test formulations when we aim to realize such processing. The correct way here was the one presented in the first solution, namely formulating the condition not in relation to the number of trials but in relation to wether or not the correct number has been guessed. This way, we avoid the aforementioned trap.