Skip to content
Topos Uranos

Summary

This lesson opens the first unit of the course, devoted to the first steps in programming with C++. It explains what the unit is for: to take someone who has never programmed from a problem stated in everyday language to a program that compiles, runs, reads data and writes results, knowing what each tool did along the way; it presents its six lessons and the thread that joins them, from the algorithm written in English to the classification of errors; it specifies the little that is taken for granted, namely school arithmetic, the habit of following written instructions and the handling of files and folders; it formulates the problem the unit solves, that of turning a calculation one knows how to do by hand into a procedure that a machine carries out without making mistakes and without tiring; and it shows where it leads, in the following units and in the course Programming in C++ II.

Learning objectives

  1. Describe the sequence of contents of the unit and explain what each lesson contributes to the next.
  2. Recognize the prior knowledge the course assumes (operating with integers and decimals, computing a quotient and a remainder, following written instructions, saving a file in a given folder) and review it if necessary.
  3. Explain, with an example, the path the unit teaches to travel: from the statement to the specification, from the specification to the algorithm and from the algorithm to the program that is compiled and run.
  4. 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. Since this is the first unit of the course, there are no questions about previous units; instead, the first three check what the course takes for granted: the quotient and the remainder of an integer division, the order of the steps of a procedure, and the name, the extension and the folder of a file. The next seven touch, in order, on the central ideas of the six lessons of the unit. Whoever has never programmed should not expect to get them right, and it does not matter: 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.

Entry assessment

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.

  1. Question 1From earlier units47 sheets are shared out among 6 people, in equal whole parts, and those that are not enough for a complete round are kept. How many does each person receive and how many are kept?

  2. Question 2From earlier unitsTo send a file attached to an email there are four steps: A, write the recipient’s address; B, press “Send”; C, open a new message; D, attach the file. Which order is the right one?

  3. Question 3From earlier unitsA file is saved in C:\Users\ana\programas\suma.cpp. What is its name, what is its extension and in which folder is it?

  4. Question 4A recipe says: “If the dough is dry, add a spoonful of water and knead; repeat until it is not”. The dough needs exactly three spoonfuls to stop being dry. How many times is it asked whether the dough is dry?

  5. Question 5Which of these instructions can anyone, or a machine, follow in exactly the same way?

  6. Question 6A program compiles without errors or warnings, runs well with many data, and with one in particular stops with the message “division by zero”. At what moment did the error occur?

  7. Question 7Visual Studio Code was installed with its C++ extension, and when g++ --version is requested in the terminal, the terminal answers that it does not recognize g++. What is most likely?

  8. Question 8The compiler writes a message that begins with warning: and, in spite of it, produces the executable. What does it mean?

  9. Question 9Where does the execution of a C++ program begin?

  10. Question 10A program declares int age{};, executes std::cin >> age; to read an age, and the user types abc. What happens?

The contents of the unit

The unit has six lessons, which travel in order along the path from a problem to a working program. Each one assumes the previous one, and the first assumes nothing about the language.

  • From the problem to the algorithm. The course begins without code, because the algorithm comes before the program. The lesson teaches how to specify a problem by its input, its output and the relation between them (the precondition and the postcondition); how to describe an algorithm in numbered steps, without ambiguity; how to trace it by hand with a trace table; how to recognize in it sequence, decision and repetition; and how to justify that a repetition terminates, with a quantity that decreases on every round.
  • Programs, compilers and C++. An algorithm written for a machine is a program, and a C++ program is not run as it is written: the preprocessor, the compiler and the linker turn it into an executable. The lesson goes through those three stages, distinguishes what is discovered when compiling from what only shows up when running, compares the compiled model with the interpreted one and places the standards of the language in time, up to C++23, the one the course uses, and C++26, whose implementation in the compilers is under way.
  • Installing the environment on Windows, macOS and Linux. Three complete guides, one per system, to install a compiler capable of C++23 and the editor Visual Studio Code with its C++ extension, to check that everything works with a test program and to solve the frequent failures: the compiler the terminal does not find, the old version and the standard that was not requested.
  • Compiling, running and configuring. The cycle of editing, saving, compiling, running and reading, from the terminal and from the editor, with the course command. The lesson distinguishes errors, which prevent the executable, from warnings, which point out suspicious code; it turns on the sanitizers (the one for memory errors, AddressSanitizer, and the one for undefined behavior, UndefinedBehaviorSanitizer), which watch the program while it runs; and it explains why an output shows strange symbols instead of accented letters and the ñ.
  • Anatomy of a program. The minimal program, piece by piece: the include directive and the headers, the function main and the exit code, the namespace std, statements, blocks and comments. The lesson teaches how to fix structural errors by reading the compiler’s messages from the first one, and sets out the course’s style guide.
  • Input, output and errors. The program communicates with the outside world: it writes with std::print and std::println, with format specifications for the width and the decimals, and reads with std::cin. The lesson shows what happens when the input does not have the expected form and how the reading is checked, and closes the unit with the classification of errors by their moment: compile errors, link errors, runtime errors and logic errors.

The thread that joins them is that of the program itself. The first lesson conceives it, the second explains what it is turned into, the third installs the tools that turn it, the fourth teaches how to use them and to listen to what they say, the fifth dissects it and the sixth sets it talking with whoever uses it. If this is so, at the end of the unit the student still knows very little C++, but knows how one works with it, and that is what the rest of the course assumes.

What is taken for granted

The course does not assume any previous experience in programming. It does assume, on the other hand, three skills that are worth reviewing now, if the entry assessment showed any doubt.

The first is school arithmetic: operating with integers and with decimals, respecting the order of operations (multiplication and division before addition and subtraction, unless there are parentheses) and, above all, computing the quotient and the remainder of an integer division. This last one is more important than it seems. Dividing 47 sheets among 6 people gives 7 to each one with 5 left over, which is written 47=6⋅7+547 = 6 \cdot 7 + 5, with the remainder 55 less than the divisor 66. C++ has one operator for the quotient and another for the remainder, and a large part of the calculations with integers (converting seconds into hours, separating the digits of a number, deciding whether a number is even) comes down to them. Whoever wants to study it in detail finds it, with its proof, in the course Algebra and Geometry I: Numbers, Functions and Plane Geometry; here it is enough to know how to compute it.

The second is the habit of following written instructions to the letter and of recognizing when an instruction is not enough to know what to do. It is not a matter of knowledge, but of attitude: reading “add salt to taste” and noticing that this instruction depends on whoever carries it out. The first lesson of the unit turns that attitude into a method.

The third is the basic handling of a computer: creating a folder, saving a file in it with a chosen name, recognizing the extension of the name (.cpp, .txt, .exe) and knowing which folder each file is in. It is worth setting the system now to show the extensions, which some systems, such as Windows, hide by default: the source code suma.cpp and the executable suma.exe are very different files, and confusing them is a source of absurd errors. The unit also teaches how to use the terminal, so it is not necessary to know it beforehand; it is enough to be willing to type commands instead of pressing buttons. Installing programs requires, finally, being able to do so on one’s own computer; the installation lesson points to an online alternative for whoever cannot.

English is not assumed. The compiler’s messages are in English, and the course teaches how to read them field by field, so that what matters in them (the file, the line, the kind of defect) is understood without mastering the language. Nor is any mathematics beyond school mathematics assumed: the examples use division, averages, multiplication tables, dates and times.

The problem the unit solves

A calculation one knows how to do by hand is not yet a program. The distance between the two is what the unit teaches to travel, and a simple problem allows measuring it.

ExampleA duration in hours, minutes and seconds

A stopwatch records the duration of each activity as a number of seconds, for example 7384, and one wants to write it in the usual form of hours, minutes and seconds, with the minutes and the seconds always in two digits: 2:03:04. By hand, the calculation is a chain of divisions: 7384=3600⋅2+1847384 = 3600 \cdot 2 + 184, from which come 2 hours and 184 seconds; 184=60⋅3+4184 = 60 \cdot 3 + 4, from which come 3 minutes and 4 seconds. For one duration it takes a minute. For the thousand durations of a log, on the other hand, the calculation by hand is long and error-prone, and the task lends itself to being carried out by a machine.

Now, a machine cannot receive the explanation above. It receives a text in a programming language, and to write that text one must first have settled three questions that the calculation by hand left implicit. The first is the specification: what goes in (an integer number of seconds, not negative), what comes out (three integers, the hours, the minutes and the seconds) and what relation joins them: if tt is the total, t=3600h+60m+st = 3600 h + 60 m + s, with 0≤m<600 \leq m < 60 and 0≤s<600 \leq s < 60. The second is the algorithm: the precise steps that, for any admissible input, produce that output.

  1. hh takes the value of the quotient of tt by 36003600.
  2. mm takes the value of the quotient by 6060 of the remainder of tt by 36003600.
  3. ss takes the value of the remainder of tt by 6060.
  4. Write hh, a colon, mm with two digits, a colon and ss with two digits.

The third is the writing of the algorithm in C++, in the exact form the language requires, and its translation into an executable with the appropriate tools. The following program does it. It contains many things that have not been explained yet: variables (lesson 2.1), the operators / and %, which give the quotient and the remainder of integer division (lesson 3.1), reading with std::cin and format specifications (lesson 1.6); the specification {:02} of this program, which writes a number in two positions padding with zeros on the left, is a variant of the width that that lesson teaches and that lesson 3.1 will use. For now it is enough to recognize in it the four steps of the algorithm.

C++ program
#include <iostream>#include <print>​int main(){    int total{};  // variables will be explained in lesson 2.1    std::print("Duration in seconds: ");    std::cin >> total;    const int hours{total / 3600};    const int minutes{total % 3600 / 60};    const int seconds{total % 60};    std::println("{} s = {}:{:02}:{:02}", total, hours, minutes, seconds);}
Program input
7384
Output
Duration in seconds: 7384 s = 2:03:04

Lines 9 to 11 are steps 1 to 3, and line 12 is step 4. That the result matches the one computed by hand is no coincidence, but the check every program deserves: to test it first with a datum whose answer is known.

The program solves the problem, but the unit also teaches to distrust it. If the user types abc instead of a number, the reading fails, total is left at zero and the program writes, without any warning sign, that the duration is 0:00:00: a false conclusion with the look of a true one. If the user types a negative duration, the specification does not say what must happen, and the result makes no sense. If total / 360 is written instead of total / 3600, the program compiles, runs and gives a wrong result, and no tool notices. Each of those defects belongs to a different kind of error, which is discovered at a different moment and is looked for in a different way; the last lesson of the unit classifies them. It follows that the problem the unit solves is not only that of writing this program, but that of knowing why it works, with which data it stops working and which tool will warn, or not, of each defect.

Therefore, at the end of the unit the student will be able to write, compile and run programs of this kind: a few input data, a few calculations in sequence and a few results written with formatting. The student will not yet be able to make decisions or repeat instructions in C++ (though in an algorithm written in English, yes), nor to choose with judgment the type of each datum; that is what the following units bring.

Where it leads

The unit is the threshold of the course. What it uses without explaining is explained later, in this order. Unit 2, “Data and types”, explains variables and how they are stored in memory, the limits of integers (and why a correct calculation can overflow), the rounding of numbers with decimals and the conversions between types. Unit 3, “Expressions and operators”, explains the arithmetic of C++, with the quotient and the remainder of negative numbers, the logic of conditions and what the standard leaves undefined in an expression. Unit 4, “Control flow”, brings into C++ the decisions and the repetitions that the first lesson writes in English, and teaches how to justify that a loop is correct and terminates. Unit 5 breaks programs down into functions; unit 6 introduces compound data (arrays, vectors, tables and records), with the searching and sorting algorithms and their cost; unit 7 deals with text, robust input and files; and unit 8, with programs of several files, systematic testing and the debugger.

After the course, Programming in C++ II continues with what this one leaves out on purpose: pointers and dynamic memory, classes with methods, user-defined templates, anonymous functions and exceptions. None of those topics is necessary to solve the problems of this course, and postponing them allows concentrating on what holds in any language: specifying, designing the algorithm, writing it clearly and checking that it is correct. The synthesis lesson of this unit will gather precisely that distinction, between what is proper to C++ and what will be carried over to any other language.