Laboratory Training 3
C++ Statements
1 Training Tasks
Operations and statements should be used to complete all tasks. All statements should be plcaed into main() function's
        body.
1.1 Programmatic Implementation of Branching Algorithm
Develop a program that implements an algorithm for solving quadratic equation. The program should include checking all possible variants of the source data. In particular, the discriminant should be checked, and it should be checked whether the equation is quadratic. If the equation degenerates into a linear one, it is necessary to provide for finding the root of this linear equation, or to establish the presence of infinite count of solutions (absence of solutions).
Examples of source data and results:
| Source Data | Output | 
|---|---|
| 1 1 -2 | x1 = -2 | 
| 1 1 2 | No roots | 
| 2 2 -4 | x1 = -2 | 
| 0 1 2 | x = -2 | 
| 0 0 10 | No roots | 
| 0 0 0 | Infinite count of roots | 
1.2 Programmatic Implementation of Looping Algorithm
Develop a program in which the user enters the values of x, n, and k. The program implements an algorithm for calculating the following expression:
In the given sum, the common element can be written as i/(x + 2i), but it omits one element when i = k. Provide a check of possible errors.
Examples of source data and results:
| Source Data | Output | 
|---|---|
| x = 1  |  1.20635  | 
| x = 1  | 1.60635 | 
| x = -2 |  Error  | 
1.3 Calculating Product
Write a program that reads x and n and calculates y:
Examples of source data and results:
| Source Data | Output | 
|---|---|
| x = 1  |  -720  | 
| x = 0.5  | 46899.3 | 
1.4 Calculating Sum
Write a program that reads  eps (a small number that is the accuracy of calculations) and calculates y:
The loop terminates if new summand is less than eps.
Examples of source data and results:
| Source Data | Output | 
|---|---|
| 0.1 | 0.875 | 
| 0.00001 | 0.999985 | 
| 0.0000001 | 1 | 
1.5 Individual Assignment
You should develop a program that calculates values of a function in a given range. The program should implement an algorithm developed in carrying out assignment 1.3 of the first lab.
2 Instructions
2.1 Null Statement
Previously, the classification of statements was given, and the syntax and techniques of working with description statements and expressions statements were considered.
A null statement (empty statement) is just the semicolon and nothing else. A null statement is used when the statement is needed syntactically, but no action is required.
2.2 Compound Statement
A compound statement is a sequence of statements enclosed in braces {}. A compound statement
        is also called a block. The block does not end with a semicolon. Syntactically, the block can be considered
        as a single statement. For example:
        {
    temp = a;
    a = b;
    b = temp;
}
      
      Compound statements are usually placed in those places of the program where the syntax allows the only statement, but the algorithm requires several actions.
The use of blocks is associated with certain rules for formatting the source code. The brace opens on a new line, no code is placed after it in this line. Subsequent statements are allocated on the next line with indentation. For indents, you can use:
- two spaces;
- four spaces;
- tab character.
In these lab examples, four spaces are used for indentation.
After the last statement of the block (before the closing brace), a new line is entered, and the last indentation is canceled. A closing brace is located on a separate line.
Blocks can be nested inside each other. Example:
        {
    a = x;
    b = y;
    {
        temp = a;
        a = b;
        b = temp;
    }
}
      
      The block is also important in determining the scope and lifetime of identifiers. The identifier declared inside the block has scope from the point of definition to the closing brace. For example,
    {
    int  i = 1;
    {
        int  k = i;
    }
    k = 2; // Error! The variable k is not available in the external block 
}
      It is bad idea to create local variables with the same name, especially since some languages (e.g. Java, C#) don't allow it.
Modern coding standards require the placement of blocks in the branches of a conditional statement and in the body of a loop, even if this block is syntactically unnecessary.
2.3 Selection Statements
2.3.1 Condition Statement
Selection statements allow you to perform different actions depending on the conditions that arise during the execution of the program.
The condition statement (if statement) controls conditional branching. The syntax for the if statement
        has two forms:
The first form:
if (expression) statement
The second form:
if (expression) statement1else statement2
In the first form of the syntax, if expression is true (nonzero), statement is
        executed. If expression is 0 (false), statement is ignored. 
In the second form, statement1 is executed if the condition expression returns a value other than 0 (true), statement2      is executed if the result of the condition expression is interpreted as 0 (false). 
A condition expression can be of any integer type (or a type that can be converted to integer).
With both forms, control then passes from the if statement
        to the next statement.
The statements (statement, statement1, statement2) can be a single statements
        ending with a semicolon or a blocks enclosed in braces. For example: 
if (i > 0) y = x * i;else { x = i; y = x + i; }
In this example, the statement y = x * i is executed if i is greater than 0. If i is
        less than or equal to 0, i is assigned to x and x + i  is assigned to y. 
 Note: good coding practice recommends always using a compound statement in if statements
        and loops, even if a single statement executed.
The algorithm for calculating the reciprocal value presented in the first laboratory training can be programmatically implemented using a conditional statement:
#include <iostream>using namespace std;int main() {double x; cin >> x;if (x == 0) { cout << "Error" << endl; }else {double y = 1 / x; cout << y << endl; }return 0; }
As can be seen from the above example, in both branches of the if statement there
        are compound statements in accordance with good coding practice. In addition, the variable y is defined inside the
        block in only one of the branches. This style is considered more correct than defining all variables in advance.
 Very often, beginners make the mistake of using if (x = 0) instead of if (x
        == 0):
int x = 3;if (x = 0) { cout << "zero"; }else { cout << "non-zero"; }
Using such a condition will not cause compiler errors, only a "hint" can appear, but it will lead to unpleasant
        consequences. The block that must be executed if the condition is true, will never
        be executed and control will pass to else. In addition, the value of x will be spoiled. After such "checking",
        it will always be 0.
The following program calculates the result of division:
#include <iostream>using namespace std;int main() {double a, b; cout << "Enter a and b: "; cin >> a >> b;if (b) {double c = a / b; cout << "Quotient is " << c << endl; }else { cout << "Error" << endl; }return 0; }
 As can be seen from the example, instead of checking if (b != 0), it
        is enough to write if (b). This form is typical
        for C and C++, but is forbidden in some other languages, such as Java or C#.
Conditional statements can be nested within each other. For example, It is necessary to enter x and output the following messages "left" if x < 0, "inside" if 0 ≤ x ≤ 1 and "right" if x > 1. The input and checking code can be as follows:
double x; cin >> x;if (x < 0) cout << "left";else if (x <= 1) cout << "inside";else cout << "right";
To avoid confusion in this case, it is also advisable to use braces:
double x; cin >> x;if (x < 0) { cout << "left"; }else {if (x <= 1) { cout << "inside"; }else { cout << "right"; } }
Typical mistakes of beginners are the placement of the condition after else (syntax
        error), as well as the unnecessary checking of a condition that has already been checked:
if (x < 0) { cout << "left"; }else {if (x >= 0 && x <= 1) { cout << "inside"; }else {if (x > 1) { cout << "right"; } } }
You should avoid unnecessary actions in the program.
When working with a conditional statement, errors related to the use of an extra semicolon may occur. Even
        if the variables x and y have been correctly created and initialized, the following code
        will not compile:
if (x > 0); { y = 1; }else { y = 2; }
The error is due to the fact that a semicolon was placed after the checking. In fact, there is
        an empty statement (;) after if (...). This empty stament is executed
        if the statement is equal to true (1). The compound statement is executed in all cases.
        The else keyword in
        this case no longer refers to if, which causes a compilation error. Therefore, do
        not abuse semicolons in the source code.
2.3.2 The switch Statement
The switch statement allows for branching on multiple values of expression.
switch (expression) {/* body */ }
The switch statement body consists of a series of case labels and an optional default label.
        The label consists of the case keyword followed by a constant expression. No two constant expressions
        in case statements can evaluate to the same value. The default label can
        appear only once.
Execution of the switch consists of calculation of the control expression and transition to the group of statements
        marked by a case label which value is equal to the control expression. If there is
        no such label, statements are followed after the default label. During the execution
        of the switch, the statements with the selected label are passed, and then the statements are executed in the normal
        order. In order not to follow the statements that remain in the body of the switch, you must use the break statement.
        For example:
switch (i) {case 1: cout << "equals to 1";break ;case 2: cout << "equals to 2, ";default : cout << "not equals to 1"; }
The results of running previous code are following:
| i | Output | 
|---|---|
| 1 | equals to 1 | 
| 2 | equals to 2, not equals to 1 | 
| another | not equals to 1 | 
The expression after switch keyword must be integer.
The switch statement allows you to create a simple menu. Depending on the user input, the program
        performs different actions. Example:
double x; cout << "Enter x\n"; cin >> x; cout << "1 - Calculation of the reciprocal value\n"; cout << "2 - Calculation of the second power\n"; cout << "3 - Calculation of the third power\n";int k; cout << "Enter the answer\n"; cin >> k;switch (k) {case 1: cout << 1 / x << endl;break ;case 2: cout << x * x << endl;break ;case 3: cout << x * x * x << endl;break ;default : cout << "Wrong choice!" << endl;break ; }
Output of menu items and input of the user's answer can be put into a loop. Cycles will be discussed below.
Labels can be grouped if several values cause the same actions. For example, the user enters the number of the month (from 1 to 12 inclusive) and the program displays the name of the season:
int month; cout << "Enter month: (1..12): "; cin >> month;switch (month) {case 12:case 1:case 2: cout << "Winter\n";break ;case 3:case 4:case 5: cout << "Spring\n";break ;case 6:case 7:case 8: cout << "Summer\n";break ;case 9:case 10:case 11: cout << "Autumn\n";break ;default : cout << "Wrong season!\n"; }
Missing break statement is one of the most common mistakes in using switch.
          Therefore, in some languages (for example, C#) its use of break is mandatory
          and its absence leads to a compilation error.
2.4 Iteration Statements
2.4.1 Overveiw
Cyclic constructions (loops) are very often used in programs. It is very difficult to find a real program that has been created without using explicit loops. But even in the implementation of algorithms without explicit cycles, cyclic structures are implicitly present, since it is not possible to implement data input and output at the standard level without cycles.
Loops are used for calculating sums and products, traversing all elements of arrays or other data structures, implementing iterative calculation algorithms, getting events from various devices with processing of these events, reading data from a file (until the end of the file), working with strings, etc.
Loops in programming languages are usually built from a header (checking a condition, defining a range, preparing or modifying a parameter, etc.) and a body (statements that can be executed multiple times, depending on conditions).
Looping statements are presented in four versions:
- a loop with a precondition: before each step of the loop, a certain condition is checked, if the result is true, the actions defined in the body of the loop are performed;
- a loop with a postcondition: first, the actions defined in the body of the loop are performed, then the condition is checked, and depending on the result of the check, the actions are repeated or the loop is terminated;
- a loop with a parameter: a special variable is initialized, a cycle parameter, the condition for performing actions in the body of the cycle is checked and the value of the parameter is modified;
- a loop built on a range: a range is defined and work is carried out with elements of arrays or other data structures.
A loop built on a range associated with arrays and other collections of items will be covered later.
Syntactically, in all loop forms, the body is a single statement. If several statements must be executed in the body, a compound statement (block) is used. Good coding practice requires the use of a block in all cases.
2.4.2 Loop with a Precondition and Postcondition
The loop with the precondition is built according to the scheme:
while (condition) statement
A while loop causes your program to repeat a statement as long as the starting condition remains true.
The following examples demonstrate usage of loop with a precondition for calculating the simple sum:
The code will be as follows:
int y = 0;int i = 1;while (i <= n) { y += i * i; i++; }
It is very important to change the value of i in the body of the loop, otherwise you can get an endless
        loop. Also, it would be a mistake to place a semicolon after the header: we will get an endless loop, at each
        step of which a null statement is executed:
int y = 0;int i = 1;while (i <= n);// endless loop {// This is no longer the loop body y += i * i; i++; }
2.4.3 Loop with a Postcondition
The loop with the postcondition is built according to the scheme:
do statementwhile (condition);
The statement is executed, and then condition is evaluated. If condition is true, the loop
        is repeated; otherwise, the loop ends. The do...while loop executes the body of the loop before
        its condition is tested and ensures that the body always executes at least one time. A disadvantage of a postconditional
        loop is the ability to execute the body of the loop even when the condition was not met immediately. Sometimes it
        is dangerous.
A previous sum
 can be calculated using a do ... while loop:
int y = 0;int i = 1;do { y += i * i; i++; }while (i <= n);
The disadvantages of the loop with the postcondition present even in this example: if, for example, n      is
        zero, the result must be 0, but the loop with the postcondition produces the result 1. 
Sometimes a loop with a postcondition is used in data input, requiring the user to enter correct data. Example:
double x;do { cout << "Enter a positive value\n"; cin >> x;if (x <= 0) { cout << "Error!\n"; } }while (x <= 0);
The use of such constructions is not always correct and can be applied only if it is determined by the task.
2.4.4 Loop with the parameter
The for statement (loop with the parameter) is built according to the scheme:
for (expression1; expression2; expression3) statement
The for loop implements the following algorithm:
- The expression1specifies the initialization for the loop. There is no restriction on the type ofexpression1.
- The expression2is evaluated before each iteration. If it is equal to zero, the transition to the next statement of the program, located after the body of the loop.
- If expression2istrue(nonzero), looping body (statement) is executed
- The expression3is evaluated. This expression is evaluated after each iteration. The process then begins again with the evaluation ofexpression2.
The for loop is the most compact and reliable for calculating sums and products with
        a fixed number of steps.
The previous examples of calculating the sum:
 can be implemented using a for loop:
int y = 0;for (int i = 1; i <= n; i++) { y += i * i; }
In this example, the variable i (the loop parameter) is created in the loop header. The scope of this variable is limited to the header and body of the loop, and the lifetime is limited to the execution time of the loop steps. This approach is recommended because there is no possibility of using a previously created variable and losing its previous value. In all cases, a new variable is created, even if a variable with the same name was previously created. After the loop ends, the parameter created in the header cannot be used.
Sometimes it is necessary to use the value of the parameter after the end of the loop. Then the parameter must be defined before the cycle. Example:
int y = 0;int i;for (i = 1; i <= n; i++) { y += i * i; } cout << i;// the last value of i which is n + 1 
Unlike loops with a precondition and a postcondition, it is more difficult to accidentally get an endless loop, because the initial value of the parameter is explicitly specified and its change is assumed at each step.
The statement
for ( ; ; );
is the way to produce an infinite loop. It is unlikely that such a code occurred by mistake. But sometimes the error will be an incorrectly defined range of the parameter. Such a cycle will not be endless, because sooner or later the value of the parameter will reach a minimum negative value and become positive:
int i;for (i = 1; i <= n; i--) { y += i * i; } cout << i;// 2147483647 - maximum integer value 
In the header of the loop, the Visual Studio compiler will show an "Ill-defined for-loop" warning.
You should also not put a semicolon after the for loop header:
int y = 0;int i;for (i = 1; i <= n; i++);// error! { y += i * i; }
The loop will not be endless, but the code that was intended as the body of the loop will be executed once for
        i with the value of n + 1.
In general, the for loop is more reliable and effective than loops with a precondition
        and a postcondition.
2.5 Transition Statements
In loops, break terminates execution of the nearest enclosing loop statement. Control passes
        to the statement that follows the terminated statement. A continue statement forces transfer
        of control to the controlling expression of the loop. Any remaining statements in the current iteration are not
        executed. Most often break and continue are used in the following constructions:
if (condition_of_early_end_of_loop)break ;if (condition_of_early_end_of_iteration)continue ;
The goto statement allows you to go to the label. A label is an identifier with a
        colon in front of the statement. Using goto and labels, you can code without blocks and cycles. For example, the
        previous sum can be calculated as follows:
        
    int  y = 0;
    int  i = 1;
label1:
    if  (i > n)
        goto  label2;
    y += i * i;
    i++;
    goto  label1;
label2:
    cout << y;
      
      In this example label1 and label2 are labels.
Such code resembles the style of the FORTRAN language. A program built on such structures is difficult to read and even more difficult to debug. This style is not used in modern programs.
The only case where the use of goto is reasonable
        is the interruption of several nested loops. For example:
int a;// ... double b = 0;for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {if (i + j + a == 0) {goto label; } b += 1 / (i + j + a); } } label:// other statements 
3 Sample Programs
3.1 Character Codes
The character output program shown in the previous lab examples can be modified so that the user types characters
        in a loop. The loop is finished after entering A:
#include <iostream>using namespace std;int main() {char c;do { cin >> c;// Inputs character int i = c;// Converts char to int cout << i << '\n';// Outputs code }while (c != 'A');// until c == 'A' return 0; }
The do-while statement executes a statement repeatedly until the specified termination condition
        (the expression) evaluates to false.
3.2 Nested if Statements
It is necessary write a program that reads x and calculates y:
| x | y | 
|---|---|
| less than -8 | 100 | 
| from -8 to 1 | 200 | 
| greater than 1 | 300 | 
The program will be as follows:
#include <iostream>using namespace std;int main() {double x; cin >> x;double y;if (x < -8) { y = 100; }else {if (x <= 1) { y = 200; }else { y = 300; } } cout << y;return 0; }
3.3 Linear Equation
The condition statement can be used for solving a linear equation:
In Example 3.1 of the first laboratory training, a branching algorithm that solves this task was given. A program that implements this algorithm can be as follows:
#include <iostream>using namespace std;int main() {double a, b; cout << "Enter a and b: "; cin >> a >> b;if (a != 0) {double x = -b / a; cout << "Root is " << x << endl; }else {if (b == 0) { cout << "Infinite count of roots." << endl; }else { cout << "No roots." << endl; } } }
3.4 The switch Statement
It is necessary write a program that reads x and n and calculates y using
        a switch statement:
| n | y | 
|---|---|
| 1 | x | 
| 2 | x2 | 
| 3 | x3 | 
| 4 | 1 / x | 
| other values | 0 | 
#include <iostream>using namespace std;int main() {double x, y;int n; cin >> x >> n;switch (n) {case 1: y = x;break ;case 2: y = x * x;break ;case 3: y = x * x * x;break ;case 4: y = 1 / x;break ;default : y = 0; } cout << y;return 0 }
3.5 The Sum
It is necessary to write a program that reads x and n and calculates y:
The program must write error message if denominator equals zero.
#include <iostream>using namespace std;int main() { setlocale(LC_ALL,"UKRAINIAN");double x, y = 0;int i, n; cout << Input x and n: "; cin >> x >> n;for (i = 1; i <= n; i++) {if (x == i) { cout << "Error!\n";break ; } y += 1/(x - i); }if (i > n)// sum is calculated { cout << "y = " << y << "\n"; }return 0; }
Alternative solution:
#include <iostream>using namespace std;int main() {double x, y = 0;int i, n; cout << "Input x and n: "; cin >> x >> n;for (i = 1; i <= n; i++) {if (x == i) { cout << "Error!\n";return 1; } y += 1/(x - i); } cout << "y = " << y << "\n";return 0; }
3.6 The Product
It is necessary write a program that reads x, k, and n and
        calculates y:
#include <iostream>using namespace std;int main() {double x, y = 1;int i, k, n; cout << "Input x, k, and n: "; cin >> x >> k >> n;for (i = 0; i <= n; i++) {if (i == k) {continue ; } y *= (x + i); } cout << "y = " << y << "\n";return 0; }
Alternative solution:
#include <iostream>using namespace std;int main() {double x, y = 1;int i, k, n; cout << "Input x, k, and n: "; cin >> x >> k >> n;for (i = 0; i <= n; i++) {if (i != k) { y *= (x + i); } } cout << "y = " << y << "\n";return 0; }
3.7 A Product with Alternating Signs
In Example 3.3 of the first laboratory training, the algorithm for calculating a product with alternating signs in multiplicands is given:
A program that implements this algorithm can be as follows:
#include <iostream>using namespace std;int main() {double x;int n; cout << "Enter x, n: "; cin >> x >> n;int k = 1;double p = 1;for (int i = 0; i <= n; i++) { p *= x + i * k; k = -k; } cout << "Product = " << p;return 0; }
3.8 The Exponent
Assume that we want to write a program that reads x and calculates ex:
The loop terminates if new summand is less than 0.00001.
#include<iostream>using namespace std;int main() {double x, y = 0;double z = 1;// Summand int i = 1; cout << "Input x: "; cin >> x;while (z > 0.00001) { y += z; z *= x / i; i++; } cout << "y = " << y << "\n";return 0; }
Alternative solution:
#include <iostream>using namespace std;int main() {double x, y = 0;double z = 1;// Summand cout << "Input x: "; cin >> x;for (int i = 1; z > 0.00001; i++) { y += z; z *= x / i; } cout << "y = " << y << "\n";return 0; }
As can be seen from the example, the condition check in the for loop is not necessarily related to the parameter.
3.9 Nested Loops
In Example 3.4 of the first laboratory training, the algorithm for calculating the sum of products is given:

We'll implement calculations using nested loops. A program can be as follows:
#include <iostream>using namespace std;int main() {int n; cout << "Enter n: "; cin >> n;int sum = 0;for (int i = 1; i < n; i++) {int p = 1;for (int j = 1; j < n; j++) { p *= i + j * j; } sum += p; } cout << "Sum = " << sum; }
3.10 Table of Square Roots
The following program reads interval boundaries and step of argument increasing from keyboard and prints
        in a cycle values of square roots of intermediate values.
        To calculate the square root, we can use the standard sqrt() function, which is declared in the cmath header file.
#include <iostream> #include <cmath>using namespace std;int main() {double from, to, step; cout << "Enter the left border, right border, and step of argument: "; cin >> from >> to >> step;if (from < 0 || to < 0 || from >= to || step <= 0) { cout << "Wrong data\n"; }else {// The main program loop: for (double x = from; x <= to; x += step) { cout << "x = " << x << "\t y = " << sqrt(x) << endl; } }return 0; }
The table of x and y values should be shown after launching program.
4 Exercises
Task 1
Write a program that reads characters and prints their hexadecimal code. Read and output data in a loop.
Task 2
Write a program that reads decimal integers and prints characters with corresponding codes. Read and output data in a loop.
Task 3
Write a program that reads x and calculates y (signum function) using an if statement:
| x | y | 
|---|---|
| less than 0 | -1 | 
| 0 | 0 | 
| greater than 0 | 1 | 
Task 4
Write a program that reads integer n and calculates y using a switch statement:
| n | y | 
|---|---|
| 0 | 2 | 
| 1 | 4 | 
| 2 | 5 | 
| 3 | 3 | 
| 4 | 1 | 
| other values | 0 | 
5 Quiz
- What is a statement?
- Where and why is an empty expression used?
- What is an expression statement?
- What is a compound statement (block) used for?
- Describe the syntax of the the ifstatement.
- What errors can be associated with the use of a conditional statement?
- Describe the syntax of the switchstatement.
- How to use breakstatement withinswitchstatement?
- What is the defaultstatement?
- What is loop header and loop body?
- What is the difference between a loop with a precondition and a loop with a postcondition?
- What is the main disadvantage of the loop with a postcondition?
- What are advantages of the forstatement?
- What is the difference between breakandcontinuestatements?
- How to leave multiple nested loops?
- When is it appropriate use of the gotostatement?
