Summary
This lesson opens the fourth unit of the course, devoted to control flow. It explains what the unit is for: to teach how to govern the order in which the statements of a program are executed, with decisions and with loops, and how to reason about their correctness, that is, how to make sure that every case is handled, that every loop does what it should and that it terminates; it presents its four lessons and the thread that joins them; it recalls what the unit takes for granted, above all the compound conditions of unit 3; it formulates the problem the unit solves, that of a program that computes the greatest common divisor with a fixed number of steps and that, depending on the data, answers wrongly or stops at a division by zero; it anticipates the invariant as the tool with which the unit will justify its loops; and it shows where it leads, in the following units and in the course Programming in C++ II.
Learning objectives
- Describe the sequence of contents of the unit and explain what each lesson contributes to the next.
- Recall the compound conditions of unit 3 (the connectives, short-circuit evaluation and negation by De Morgan’s laws) and review them if necessary.
- Anticipate, with an example, the invariant as a reasoning tool: a relation among the variables that a repetition preserves and that, at the end, gives the result.
- Recognize what one is expected to be able to do at the end of the unit, and distinguish it from what will be learned in the following units.
Entry assessment
Before working through the unit, it is worth measuring the starting point. This assessment is a self-assessment: it is not graded, and its only purpose is to guide your study. The first four questions check what the unit takes for granted: the negation of a compound condition, short-circuit evaluation, the trace of a repetition from lesson 1.1 and the limit of an int. The next seven touch, in the order of the lessons, on the central ideas of the unit, and several of them start from school mathematics: the greatest common divisor, summation notation, the termination of a procedure. No one is obliged to get them right yet, and in some of them “I don’t know yet” is an honest answer: each answer, right or not, explains the point and names the lesson that deals with it. The same skills are measured again at the end, in the synthesis lesson.
Before starting the unit, measure your starting point. It is a short self-assessment: it is not graded and its result is stored only in your browser.
Question 1From earlier unitsWhat is the negation of the condition
1 <= n && n <= 10?It negates each part but keeps the conjunction: it forgets De Morgan. Moreover, no number is at the same time less than 1 and greater than 10, so that condition is always false.It changes the connective correctly but negates the relations wrongly: it excludes too much, the boundaries 1 and 10, which satisfy the original condition.It negates only the first part.By De Morgan, the negation of a conjunction is the disjunction of the negations, and the negation of1 <= nisn < 1, notn <= 1. The unit needs it in every chained decision, because theelsebranch handles exactly the negation of the previous conditions, and in every loop, because on exit the negation of its condition holds.Review: Relations and logic
Question 2From earlier unitsWith
int d{0};andint n{5};, what happens whend != 0 && n / d > 2is evaluated?It ignores short-circuit evaluation: the division is never computed.There is no way for a conjunction with a false operand to be true.The expression is correct; the compiler does not know the value ofdat run time.The first operand is false, and short-circuit evaluation does not evaluate the second: the guard on the left protects the division. The unit turns this guard into explicit decisions and into loop conditions that protect their body.Review: Relations and logic
Question 3From earlier unitsDivision by repeated subtraction from lesson 1.1 starts with and , and repeats “while , subtract from and add 1 to ”. With and , how many times is the body of the repetition executed?
It counts the evaluations of the condition, which are one more than the iterations.It stops the repetition with : it reads as .It confuses the number of iterations with the initial value of .The trace gives : the body is executed four times, and the condition is evaluated five times, because the last evaluation is the one that fails. Lesson 4.2 writes this repetition in C++ and turns the trace into a table.Question 4From earlier unitsWith a 32-bit
int, what does the standard guarantee about the value of46341 * 46341?It ignores the range of the type: that number does not fit in anint.It believes that overflow stops at the edge; the standard promises nothing.The type of the result is decided by the operands, which areint, not by the value of the result.The maximum is . The unit meets this product in a place where no one looks for it: the conditiond * d <= nof a loop that tries divisors, which overflows precisely when is close to the maximum.Question 5A program contains the chain of decisions
if (score >= 50), which writes “Passed”;else if (score >= 90), which writes “Excellent”; andelse, which writes “Failed”. What does it write withscoreequal to 95?It believes that the most demanding condition wins; the first one that holds wins.It believes that all the true branches are executed; in a chain only one is executed.It is an honest answer: lesson 4.1 explains it, and the exit assessment will return to the boundaries of a chain.In a chain, the first branch whose condition is true is executed, and . The “Excellent” branch is never executed: its real case is and , which is empty. Lesson 4.1 teaches how to read the real case of each branch and how to order the conditions.Review: Decisions
Question 6Which of the following expressions denotes the sum ?
It adds times the number , that is, : it confuses the term with the upper limit.It adds : it shifts the limits and loses the last term, the off-by-one error of loops.The upper limit cannot be the index itself: the expression has no meaning.The index runs through the integers from 1 to , and each term is itself. Aforloop that accumulates is the direct translation of this notation: the loop variable is the index, its bounds are those of the summation, and the body adds the term.Review: Loops
Question 7With
int total{0};, what doesstd::println("{}", total);write afterfor (int i{0}; i < 5; ++i) { total += i; }?It believes thatireaches 5: it reads<as<=.It confuses the accumulator with the counter: five is the number of iterations, not the sum.It is an honest answer: lesson 4.2 teaches the form of theforand how to count its iterations.The variableitakes the values 0, 1, 2, 3 and 4, and ; withiequal to 5 the condition fails and the body is not executed. It is the summation of the previous question with the limits 0 and 4.Review: Loops
Question 8In division by repeated subtraction (, ; while , becomes and becomes ), what relation among the variables holds every time the condition is evaluated?
It holds only on exit: while the repetition goes on, the condition ensures the opposite.It holds only at the end; before that, is less than the quotient.It is an honest answer: lesson 4.3 teaches how to find and check this relation, and the exit assessment will ask it again.It holds at the start, because ; and if it holds before an iteration, it holds after it, because . On exit the negation of the condition, , is added, and the two together give the result. A relation like this is called an invariant, and lesson 4.3 turns it into the method for designing loops and justifying them.Review: Designing correct loops
Question 9A procedure starts from an arbitrary integer (positive, zero or negative) and repeats “while , subtract 2 from ”. Does it terminate for every ?
That happens with the condition ; with , the repetition stops as soon as equals 0 or .With a negative the condition is false from the start, and the body is not executed.The conclusion is correct, but the reason is not: being an integer is not enough; the quantity must be natural while the repetition goes on, and it must decrease.The quantity is a natural number while the repetition goes on (the condition ensures it) and decreases strictly: it is a variant, the tool from lesson 1.1 that lesson 4.3 uses in every loop. With “while ” the answer would change: an odd skips zero.Review: Designing correct loops
Question 10What is the greatest common divisor of 84 and 36?
It is a common divisor, but not the greatest.It is a common divisor, but not the greatest: the factor 3, which they also share, is missing.It is the least common multiple, not the greatest common divisor.The common divisors are 1, 2, 3, 4, 6 and 12. The Euclidean algorithm obtains it without searching for divisors: and , so . Lesson 4.4 writes it as a loop and proves why it works.Review: Numerical algorithms
Question 11To decide whether 101 is prime by trying divisors, up to which divisor is it enough to go?
It uses half: it is correct, but five times longer than necessary.It tries all the candidates: it is correct, but it does not take advantage of the fact that divisors come in pairs.It is an honest answer: lesson 4.4 proves it.If 101 had a divisor with , then would also be one, and one of the two would be at most . It is enough to try 2 to 10: none divides 101, which is prime. Lesson 4.4 proves the rule and writes it without roots or products that overflow.Review: Numerical algorithms
Loading the content…
Completed
Sign in to save your progress