Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a40c7e0

Browse files
Update tutorial sources for v1.2
1 parent b8b43cb commit a40c7e0

11 files changed

+292
-262
lines changed

‎00-about-this-tutorial.md‎

Lines changed: 21 additions & 18 deletions
Large diffs are not rendered by default.

‎01-string-and-character-literals.md‎

Lines changed: 30 additions & 28 deletions
Large diffs are not rendered by default.

‎02-variables-scopes-and-namespaces.md‎

Lines changed: 46 additions & 33 deletions
Large diffs are not rendered by default.

‎03-conditions-and-operators.md‎

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
## Run-time user input
44

5-
The programs we have seen in the previous two chapters have been a little predictable in how they run as they have a *linear execution path* through the `main()` function. Such simple programs have very little practical use. More complex programs, which alter their *control flow* based on *user input* fall into two types:
5+
The programs we have seen in the previous two chapters have been a little predictable in how they run, as they have a *linear execution path* through the `main()` function. Such simple programs have very little practical use. More complex programs, which alter their *control flow* based on *user input* fall into two types:
66

7-
* *Batch programs* take all of their input at the beginning of their execution, usually from any or all of: program parameters, an environment variable, or an input file.
7+
* *Batch programs* take all of their input at the beginning of their execution, usually from any or all of: program parameters, an environment variable(s), or an input file.
88

99
* *Interactive programs* enact a dialog with the *user* (the computer operator) while the program is executing. This dialog is often two-way as the user is not necessarily expected to know what input is required without being prompted.
1010

@@ -18,7 +18,7 @@ As a quick introduction to the stream output object `cout` (an abbreviation of "
1818
cout << "The answer is: " << 42 << '\n'; // println("The answer is: {}", 42);
1919
```
2020

21-
As a complement to `cout`, the stream input object `cin` (an abbreviation of "Character Input") overloads `>>` (the *stream extraction operator*) to allow variables to be set from user input. When a `cin` input expression is reached, the program waits (indefinitely) for the user to type some input and press Enter. The following program outputs a message inviting the user to enter a number, and then prints this number out again on the console. Before `cin` is used, the variable to be used to accept the input into must have already been defined so that the type of the required input can be deduced. Providing an initial value is preferred (empty braces give it a default value) in case the read by `cin` fails due to either invalid input, such as the user typing letters where digits were required, or end-of-input (Ctrl-D or Ctrl-Z):
21+
As a complement to `cout`, the stream input object `cin` (an abbreviation of "Character Input") overloads `>>` (the *stream extraction operator*) to allow variables to be set from user input. When a `cin` input expression is reached, the program waits (indefinitely) for the user to type some input and press Enter. The following program outputs a message inviting the user to enter a number, and then prints this number out again on the console. Before `cin` is used, the variable to be used to accept the input into must have already been defined so that the type of the required input can be deduced. Providing an initial value is preferred (empty braces give it the default value, zero in this case) in case the read by `cin` fails due to either invalid input, such as the user typing letters where digits were required, or end-of-input (Ctrl-D, or Ctrl-Z under Windows):
2222

2323
```cpp
2424
// 03-age1.cpp : get and then display an integer
@@ -83,11 +83,11 @@ Note: Braces for function **definitions**, including `main()`, are always mandat
8383

8484
* Change the program to test for non-zero using the "not equal" operator and a `0`. Does this work in the same way?
8585

86-
* Change the program again to test for zero (as opposed to non-zero), and change the output statements appropriately so the output remains correct.
86+
* Change the program again to test for "equals" zero (as opposed to "not equal"), and change the output statements appropriately so the same logic remains. Is this program better? Consider whether the *happy path* should be satisfied by the first "if" clause (as opposed to "else").
8787

88-
* Now alter the original program to test a floating-point (`double`) variable as being zero or non-zero. Do you consider use of `0.0` as better style?
88+
* Now alter the original program to test a floating-point (`double`) variable as being zero or non-zero. Do you consider use of `0.0` as being better style?
8989

90-
* Delete the braces surrounding the `if` and `else` clauses. Does the code still compile? What happens if you added a second statement line to the `else` clause? Or the `if` clause?
90+
* Delete the braces surrounding the `if` and `else` clauses. Does the code still compile? What happens if you add a second statement line to the `else` clause? Or the `if` clause?
9191

9292
The `if` statement is a binary choice, however some decisions require more than two options. To enable this, `if` statements can be *chained* together. The following program chains a further `if` onto the tail of the first `else` clause. Note that in this special case, using braces for the first `else` clause is **not** recommended as this would indent the code. The combination `else if` (with mandatory space) is unambiguous to readers of your code; a second statement to the first `else` clause (which would necessitate braces) is unlikely to be needed as the (possibly itself chained) `if` which follows counts as a single statement.
9393

@@ -145,7 +145,7 @@ int main() {
145145

146146
**Experiment**
147147

148-
* Change the above program so that the test logic is inverted with the output remaining the same, in other words `alice_age` falling outside the range 6-11 results in a positive condition test. Hint: you will need to use the `or` keyword and change the order of the output statements.
148+
* Change the above program so that the test logic is inverted, while the output remains the same; in other words `alice_age` falling outside the range 6-11 results in a positive condition test. Hint: you will need to use the `or` keyword and change the order of the output statements.
149149

150150
* Now change `and` to `&&` in the original program. Does it still compile and run? Which style do you prefer?
151151

@@ -192,23 +192,23 @@ int main() {
192192
}
193193
```
194194

195-
Notice that "getting" multiple variables from `cin` allows for the input of three values together, optionally separated by whitespace or newlines. This permissiveness can be useful in some cases but doesn't handle erroneous input very well so is often unsuitable to be used in production code (as error recovery involves clearing the error state, possibly losing input in the process). The four `case` statements each check for a valid integer (actually a character literal) stored in `op` and program flow jumps to the one that matches, if any. The `break` statements are necessary and cause control flow to jump to the closing brace of the switch block; if they were not present flow would *fall through* to the next `case` statement, which is rarely desirable. The `default` case statement is optional, and program flow always continues here if none of the `case` statements match, if it is not present the compiler will often produce a warning.
195+
Notice that "getting" multiple variables from `cin` allows for the input of three values together, optionally separated by whitespace or newlines. This permissiveness can be useful in some cases but doesn't handle erroneous input very well so is often unsuitable to be used in production code (as error recovery involves clearing the error state, possibly losing input in the process). The four `case` statements each check for a valid integer (actually a character literal) stored in `op` and program flow jumps to the one that matches, if any. The `break` statements are necessary and cause control flow to jump to the closing brace of the switch block; if they were not present flow would *fall through* to the next `case` statement, which is rarely desirable. The `default` case statement is optional but usually desirable, and program flow always continues here if none of the `case` statements match; if it is not present the compiler will often produce a warning.
196196

197-
Notice also the use of `cerr` to output error messages to the *standard error stream*; by default `cerr` echos to the terminal (the same as for `cout`) but this output can be redirected at run-time to a text file (or a null device). The `if` test for zero divisor should be familiar syntax by now and prevents a possible floating-point exception. In this case, and in the case of an error, the result variable contains the default value zero.
197+
Notice also the use of `cerr` to output error messages to the *standard error stream*; by default `cerr` echoes to the terminal (the same as for `cout`) but this output can be redirected at run-time to a text file (or a null device). The `if` test for zero divisor should be familiar syntax by now and prevents a possible floating-point exception. In this case, and in the case of an error caused by an invalid operator, the result variable`r` contains the default value zero.
198198

199199
**Experiment**
200200

201201
* Change the type of the input and result variables to `double` and make sure the program still compiles and runs correctly.
202202

203203
* Add a `case` clause for the exponentiation operator `'^'` which calls the function `pow(x,y)` (C++ has no built-in exponentiation operator, `^` in code actually means bitwise exclusive-or). Hint: you will need `#include <cmath>` and possibly also `-lm` on the link path.
204204

205-
* Go back to using `int` variables and add the modulo operator `%` to the list of valid operators. You will need to add a suitable `case` clause. Note that this operation gives the remainder from a division, so divide-by-zero needs to be caught here as well.
205+
* Go back to using `int` variables and add the modulo operator `%` to the list of valid operators. You will need to add a suitable `case` clause. Note: this operation gives the remainder from a division, so divide-by-zero needs to be caught here as well.
206206

207-
* Rewrite the case values as plain decimal integers, obtained from a table showing ASCII characteres against their numbers. Then try using hexadecimal values, and then octal values.
207+
* Rewrite the case values as plain decimal integers, obtained from a table showing ASCII characters against their numbers. Then try using hexadecimal values, and then octal values.
208208

209-
* Rewrite the whole switch-case block as multiple if-else-if statements. Test all control-flow paths.
209+
* Rewrite the whole switch-case block as multiple if-else-if... statements. Test all control-flow paths.
210210

211-
The need for `break` statements at the end of each `case` clause has already been mentioned. Occasionally the behavior of program flow falling through to the next case can be useful. More often, multiple `case` matches using the same code is the desired behavior. The following program demonstrates the former of these:
211+
The need for `break` statements at the end of each `case` clause has already been mentioned, however occasionally the behavior of program flow falling through to the next case can be useful. More often, multiple `case` matches using the same code is the desired behavior. The following program demonstrates the former of these:
212212

213213
```cpp
214214
// 03-fallthrough.cpp : demonstrate case clauses without break
@@ -323,9 +323,9 @@ The variable defined in the initializer can optionally be used in the condition
323323

324324
**Experiment**
325325

326-
* Try to use `n` and `m` after the closing brace of the `else` clause.
326+
* Try to use `n` and `m` after the closing brace of the `else` clause. Which, if either, is possible? What does this tell you about the scope of an initializer-defined variable?
327327

328-
* Rewrite this program to use a `switch` statement instead of `if`. Pay close attention to the conditional expression needed. The new program should correctly handle all inputs and produce identical output to the one shown.
328+
* Rewrite this program to use a `switch` statement instead of `if`. The new program should correctly handle all inputs and produce identical output to the one shown. Hint: you may want to use `case` statements which fall through.
329329

330330
## Constexpr if
331331

@@ -383,4 +383,4 @@ The table below is intended to be a complete list, and as such introduces operat
383383
| throw | right to left | exception throw expression | throw expression |
384384
| , | left to right | comma sequencing operator | expression, expression |
385385

386-
*All text and program code &copy;2019-2024 Richard Spencer, all rights reserved.*
386+
*All text and program code &copy;2019-2025 Richard Spencer, all rights reserved.*

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /