Summary
This lesson opens the fifth unit of the course, devoted to functions. It explains what the unit is for: to teach how to decompose a problem into named parts, each with an interface and a contract, and how to solve certain problems by reducing them to a smaller instance of themselves, by recursion; it presents its four lessons and the thread that joins them; it recalls what the unit takes for granted, above all the loops of unit 4 and their invariants; it formulates the problem the unit solves, that of a program that repeats the same copied computation and that, because of a slip in the copy, answers wrongly without the compiler saying anything; it anticipates the contract (the precondition and the postcondition) as the form in which the unit will specify each part; 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 algorithms of unit 4 (the trace of a loop, its invariant and its variant) and review them if necessary.
- Anticipate, with an example, the idea of a contract: what a part of the program demands of whoever uses it and what it guarantees in return.
- 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 five questions check what the unit takes for granted: the trace of a loop, its invariant, the precondition of a specification, the copying of a value in an initialization and the search, within a program of unit 4, for a computation with its own inputs and outputs. The next five touch, in the order of the lessons, on the central ideas of the unit: the call stack, the passing of an argument, the separation between computation and presentation, the recursive definition of the factorial and the execution of a function that calls itself. 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 does
int n{305}; int c{1}; while (n >= 10) { n = n / 10; ++c; } std::println("{}", c);write?It counts the iterations and forgets thatcstarts at 1.It makes one iteration too many: with the conditionn >= 10is already false.It confuses the counter with the value ofnafter the first iteration.Question 2From earlier unitsIn the loop
int total{0}; int k{1}; while (k <= n) { total += k; ++k; }, with , what relation holds each time the condition is evaluated?It holds in the middle of the iteration, after adding and before incrementing, but not when the condition is evaluated.It holds only at the end: it is the postcondition, not the invariant.It is the condition of the loop, and it is false precisely on exit; an invariant holds then too.It holds at the start, with the empty sum and ; and if it holds before an iteration, it holds after it, because the iteration adds and then increments it. On exit, , and the invariant gives the sum from 1 to . The lesson Recursion justifies its functions with the same reasoning by induction.Review: Designing correct loops
Question 3From earlier unitsThe specification of division says: “given integers and , obtain and with and ”. What is its precondition?
It confuses the precondition with the postcondition: that is what the result satisfies, not what is demanded of the data.It is a condition on the output, not on the input.With there is no with : the problem has no solution, and the precondition excludes it.The precondition is what is demanded of the data for the problem to have a solution; the postcondition, what the result satisfies. The unit turns this pair into the contract of each function: the precondition binds the caller, and the postcondition, the function.Question 4From earlier unitsAfter
int a{3}; int b{a}; b = 7;, what is the value ofa?It believes thatbandaremain joined forever; the initialization copies the value, not the cell.It confuses the copy with an uninitialized variable:areceived 3 and nothing changed it.The initializationint b{a}copies into the cell ofbthe value thatahad; afterwards, the two cells are independent. The lesson Parameters and scope shows that a parameter is initialized in the same way, with a copy of the argument, and teaches the other possibility: a second name for the same cell.Review: Variables and memory
Question 5From earlier unitsThe program of lesson 4.4 that writes the primes less than 100 has a loop that runs through the candidates and, inside it, another that tries their divisors. Which part is a computation with its own inputs and outputs, one that would be worth naming?
It confuses the input and the output of the whole program with those of an inner computation.It is a statement, not a computation with a meaning of its own: it has no input and no result that anyone would want to use.It confuses a datum with a task: the variable stores the result of the computation, but it is not the computation.The inner loop depends on nothing but the candidate, and its result is a yes or a no. Giving it a name lets the outer loop be read as its specification: “for each candidate, if it is prime, write it”. The lesson Designing with functions rewrites that program in this way.Review: Numerical algorithms
Question 6A program starts in
main;maincalls a functiong, andgcalls another functionh. Whilehis running, which calls are in progress?It believes that the caller disappears on calling; instead, it waits in order to continue where it stopped.It believes thatgended on callingh; it will end whenhreturns control to it.It is an honest answer: lesson 5.1 explains it with a figure of the stack.Question 7With the function
int f(int x) { x = x + 1; return x; }, what doesint a{3}; int b{f(a)}; std::println("{} {}", a, b);write?It believes that the function modifies the argument; by default, it receives a copy.It believes that the change toxdoes not reach even the returned value.It believes that a parameter cannot be modified; it can, unless it is declaredconst.The parameterxis a variable offthat is initialized with a copy of the argument: the function changes the copy and returns 4, andakeeps its 3. It is pass by value, the default mode of C++.Review: Parameters and scope
Question 8A program reads a date and must write its day of the week. Which decomposition separates the computation from the presentation?
It mixes two tasks: what is computed can be neither reused nor compared with an expected value.It separates the tasks, but it connects them through a hidden effect: whoever reads the call does not see where the datum comes from.It is an honest answer: lesson 5.3 teaches how to decide which functions to write.In this way the computation is tested with numbers, without looking at the screen, and it can serve another program that writes the result in another way. Lesson 5.3 calls this criterion “one function, one task”.Review: Designing with functions
Question 9Which of the following definitions defines for every natural number ?
Without a base case, the definition never stops: would refer to , and so on without end.It defines correctly for , but it leaves undefined, although it equals 1.It defines in terms of itself: the definition is circular and does not reduce the problem.Question 10With
int f(int n) { if (n == 0) { return 0; } return n + f(n - 1); }, what doesstd::println("{}", f(3));write?It believes that a single call is executed, or it confuses the argument with the result.It believes that thereturn 0of the base case is the result of the whole chain; it is only that of the last call.The name of the function is known from its header onwards, and it can be used in its own body.f(3)waits forf(2), which waits forf(1), which waits forf(0); the latter returns 0, and on the way back 1, 2 and 3 are added. The function computes , the same sum as the loop of the second question.Review: Recursion
Loading the content…
Completed
Sign in to save your progress