There is a loop in C language

There are many tasks in which commands are to be repeated until a certain result is achieved. Such a repetition is called a loop in programs. Every form of counting is implemented in the program in a loop. With the zero point calculation according to Regula Falsi, new approximations are always calculated in a loop until the zero point of the function has been found with the specified accuracy. In computer games you can shoot until your last spaceship has been shot down. A loop has the character of repetition, but also always contains a condition under which the loop is exited, or positively formulated: The loop is run through as long as the loop condition applies.

Infinite loop

Pay particular attention to the formulation of the loop condition. It happens not only to beginners that the loop never ends because the loop condition never becomes false. Such a loop is called an endless loop. Another cause of an infinite loop can be that the condition is correctly formulated, but that the programmer forgets to change the data that is queried in the condition within the loop.

Head controlled: while

As long as

The simplest loop is initiated by the keyword. The German translation is >> as long as <<. And that is a good description of how such a loop works. It repeats operations as long as a certain condition is met. We also use such bows in everyday life. As long as the soup is not salty enough, add a teaspoon of salt. And just as the salt content is checked first in this example, the loop first checks the condition and only then executes the instruction.

Analogy to if

The syntax is very similar to a statement. In fact, the only difference is that the loop repeats the statement. If the condition is not met from the outset, the loop behaves exactly like the statement: it does not execute the statement.

The loop begins with the keyword. The condition under which the statement immediately following is executed follows in brackets. Here, too, several instructions can be combined into one instruction block if they are enclosed in curly brackets. Figure {grafwhile} shows the syntax graph.

Graphics only available in the book

Counting for beginners

As a first example, let's teach the computer to count. Think about what you are doing when you count. First, you start with a specific number, typically one. Then the repetition follows, in which you always increase the previous value by one. Since at some point you want to do something other than counting, you will stop repeating at a certain value.

Counting for computers

In the program you use a variable that you preset with the start value. This starting value must be set before the loop, otherwise the variable would be reset to its starting point in every round and the loop would rotate forever. Then the program should enter the loop in which the variable is always increased by one. The loop begins with the keyword. The condition is formulated immediately after this in brackets. As long as this condition applies, the program remains within the loop. If you want to count to ten, you have to check here whether the variable is less than or equal to 10. Directly after the condition, you can specify a statement that is to be repeated in the loop. Since on the one hand you want to increase the variable by one and on the other hand you want to display the current status on the screen, you need two statements that are to be executed in the loop. But this can easily be solved with a block, i.e. curly brackets. The output of the variables and the subsequent increase of the variables are set in the block. #include using namespace std; int main () {i = 1; while (i <= 10) // loop condition {cout << i << endl; // action i ++; // Without this increase it becomes an infinite loop}}

Border issues

It is easy to make mistakes when defining the loop boundaries. If you were to use the less than sign, the program would only count to nine. The reason is that once the contents of the i reaches the value 10, the condition no longer applies and the inside of the loop is no longer entered. You can also create a loop that iterates ten times by starting at 0 and asking if the variable is less than ten. Then the variable would i run from 0 to 9. If you i however, before increasing the output, you get the numbers from 1 to 10. #include using namespace std; int main () {int i = 0; while (i <10) {i ++; cout << i << endl; }}

Test on the head

The loop checks the condition at the head of the loop. This means that the statements in the loop will not be executed at all if the condition before entering the loop is false.

Structogram

You can see the structure diagram of the loop in Figure {whilediagramm}. The query as to whether the loop is to be run through is found at the beginning and >> comprises << the statement or the statement block that is executed within the loop.

Graphic structure diagram of the while loop only available in the book

As a further example, counting is repeated, but this time backwards.

int i = 10; while (i> 0) {i--; } Here is the counter variable i preset with 10. The loop condition checks whether i is greater than 0. That's true, so the loop is entered and the loop body is executed. It just contains the variable i decreased by 1 so that i still contains 9 after the first pass. That is still greater than 0. The loop is iterated through until i by decrementing it becomes 0. At the next check at the head of the loop, the condition is no longer valid and the loop is exited immediately. The listing is missing the output. As a little exercise, you can think about what might be output if you write the output statement before or after decrementing i put in the loop. If you are sure what will happen, give it a try!

Foot-operated: do ... while

In some situations the test at the head of the loop is unfavorable. Sometimes you want to perform an action and only at the end will you be able to tell whether the action should be repeated. For example, a child will beg his grandpa for sweets until he doesn't have any more. (Experienced parents will rightly object that the grandpa system does not adhere to the final condition.) In any case, the child will beg first, otherwise it cannot even check the condition. In this case, the test only takes place after the loop body has passed through.

Input check

In programs, a foot-controlled loop becomes a typical application, especially for input checks. Within the loop, the program requests input from the user. Only then is it checked whether the entry is correct. If the input is not satisfactory, the loop is repeated. Another example is the game Minesweeper. The user should click on a field. As long as there is no mine under the field, he may continue to play. You can't tell where the user clicked until the end of the loop. The syntax graph of the loop can be seen in figure {grafdowhile}.

Graphic syntax graph do-while only available in the book

Again, in most cases you will use a block of curly braces because a loop usually consists of several statements.

The structogram differs from that of the loop in that the condition is now at the end.

Graphic structure diagram of the do-while loop only available in the book

The following example counts backwards. Look at the listing and see if it prints the numbers 10, 1 and 0! Check whether your guesses are correct!

#include using namespace std; int main () {int i = 10; do {cout << i << endl; i--; } while (i> 0); }

Counted: for

The two loops shown so far required three elements:
  • An initialization before the start of the loop
  • A condition under which the loop is executed
  • An action that can change the condition
If one of these elements is missing or incorrect, the risk of an infinite loop is high. The loop contains all three elements in your head. In this way, they are grouped together in one place and can be kept under control more easily.

A very typical application for grinding is counting; and this is where the clarity of the loop is particularly evident. The following example counts from 0 to 9.

for (i = 0; i <10; i ++) {cout << i << endl; }

Summarized

First of all, in the brackets that follow the keyword, there is a start instruction that sets the variable i to 0. In the case of loops, this initialization was carried out before the loop. Second, the loop condition can be seen. The third instruction is to increment the counter variable, which is usually at the end of the loop. These three elements are each separated by a semicolon. The loop looks like this:

The graphic syntax graph for for is only available in the book.

The loop is very similar to the loop. It just packs their skills more elegantly and makes the programmer less likely to forget important elements. You could easily represent the above scheme as a loop.

Start instruction; while ( condition) { Loop body; Final instruction; }

Accordingly, the structogram does not differ from that of the while loop. Only the content of the loop header is written to the query area.

The graphic structure diagram of the for loop is only available in the book.

In the structogram, some programmers put the final statement in the field of the command for the start statement and condition.

Multiple statements

If you need several statements in the start or end statement, you cannot just put a block with curly braces in the parentheses. However, it is possible to put several statements in the start or end statement by separating them with a comma. The following example illustrates this: #include using namespace std; int main () {int i, a; for (i = 0, a = 10; i <5; i ++, a--) {cout << i << "-" << a << endl; }}

comma

The reason is that the comma is an expression operator that separates two expressions from each other. The last expression is evaluated. Correspondingly, from the compiler's point of view a Statement consisting of two expressions, which in turn are separated by a comma operator.

Omit instructions

The three elements in the brackets of the loop do not have to be filled. If you don't need a start instruction, just leave it out and just use a semicolon. The final statement can also be omitted. Then the second semicolon is followed by the closing bracket.

Infinite loop

You may occasionally see a special variant of the loop in sample programs. If a programmer deliberately wants to program an infinite loop, he often uses the loop and does not write anything in the brackets except the two semicolons. The empty condition is perceived as true by C ++. C ++ is obviously fundamentally optimistic. Since the loop condition never becomes false, such a loop is never exited. Such infinite loops generally have a different exit than the one via the head condition. This includes, for example, the command described in the next section. for (;;) // runs until the next power failure {...}

Loop jumps: break and continue

Normally the loop condition alone should determine when to exit a loop. This gives the loop a clearly defined exit. The call from enables a special case. It causes an immediate exit from the loop. Typically it is used in the middle of a loop body when a special situation, such as an error, occurs. error = 0; while (a> 0) {... c = 4; if (error == 9) {break; } a ++; ...}

Not a good style

This mechanism is of course tremendously practical. You can react immediately to events that require exiting the loop. However, this construction has two flaws: First, the loop condition behind the no longer shows the conditions under which the loop is ended, and second, the statements in front of and behind the query appear to be on the same level. However, the statement is not executed under the same conditions as.

Too frequent use of is indicative of a lack of planning. Instead of carefully formulating a condition and controlling the process with a query, the loop is terminated spontaneously. The following process is equivalent to the previous one, but has the advantage that the process and the end of the loop become clearer.

error = 0; while (error! = 9 && a> 0) {... c = 4; if (error! = 9) {a ++; ...}} Before using to get out of a loop, you should think about whether you can make the flow more elegant. If you still have good reasons to work with, you should at least point out this abnormality with a comment at the top of the loop.

continue

The order falls into a similar category. However, this does not leave the loop, but immediately jumps to the end of the loop. The part of the loop body following the command is therefore not processed. while (a> 0) {... c = 4; if (error == 9) {continue; } a ++; ...} Using is even easier to work around than using. The only advantage over using an query is that it reduces the indentation depth for the statement. But that is precisely the disadvantage at the same time: You cannot tell from the indentation that these commands are only executed if the variable error does not contain the value 9. while (a> 0) {... c = 4; if (error! = 9) {a ++; ...}} The only really useful use of the command is in the statement. Here it is in the nature of things that after a case has been processed, the instruction is left with a jump.

The brutal jump: goto

Label

The instruction can jump to any position within the same function. A so-called label is set as the jump destination. A label consists of a name and a colon. There must be at least one instruction behind each label. if (a == 0) {a ++; goto in between; } b + = 2; if (b> 6) {goto GanzHinten; In between: // here is b> 6 or a == 1 b = 4; } else {c = 2; } At the very back: a ++; The jump to the place Between: shows what nonsense is possible with the statement. Although this jump is not criticized by the compiler, it is difficult to predict what will happen. If you are already using a command, then you should at most use it to exit nested loops and not jump into other blocks.

middle Ages

As you use it more often in your programs, you will notice the same look on your colleagues' faces that you get when you share your schnitzel with a battle ax in the canteen.

In old (really old) programming languages ​​there was only the absolute jump to reach another point in the program. As these programs became very confusing, there was a crusade against the use of the in the 1970s. With queries and loops, modern languages ​​have everything they need to be able to do without the command. A jump makes it difficult to understand the program flow. That's why you should avoid it.

Examples

Loops and queries are a basic part of any program. It will take you some practice to recognize queries and loops in the assignments and to learn how to combine them. To this end, a few examples are considered in this section. The examples are chosen to show how loops and queries are nested within one another. The Nassi-Schneidermann diagrams are used for illustration, but also as design tools.

Prime numbers

Prime numbers are numbers that are only divisible by themselves and 1. There is no formula for calculating the prime numbers, but you have to check for each smaller number whether it can be divided without a remainder.

Outer loop

The program should output all prime numbers between 3 and 100. So there is a big counting loop for all candidates. #include using namespace std; int main () {const int maxprime = 100; // end of calculation int prime number; // Test candidate for (prime number = 3; prime number <= max prime number; prime number ++) // run through all candidates {// check whether the prime number is really a prime number // test output: cout << prime number << ""; } cout << endl; } First a test output was set in the loop. With this, you can see that the prime candidates actually run from 3 to 100. If you are unsure whether parts of the program do what you expect from them, you should incorporate such test aids into your program. You can delete them later. If the amount of expenditure becomes too large for you, simply reduce MaxPrimzahl to 10 for the test phase!

Inner loop

In the next step, each candidate should be checked in the loop. To do this, it is divided by all the numbers between 2 and its own value minus one. If there is no remainder left in this division, the numbers are mutually divisible and the candidate is not a prime number. So you need another loop inside the loop. The divisor is counted up in this loop. It starts at 2 and runs until. #include using namespace std; int main () {const int maxprime = 100; int prime number, divisor; for (prime number = 3; prime number <= max prime number; prime number ++) {// check whether prime number is really a prime number for (divisor = 2; divisor <= prime number-1; divisor ++) {// test output cout << divisor << " "; } cout << endl; } cout << endl; }

Prime test

Now it has to be checked whether Prime number by divisor is divisible. You are already familiar with the% command for the modulo calculation. It returns 0 if there is no remainder left when dividing. So we need to construct a query to check that when splitting Prime number by divisor no rest remains. #include using namespace std; int main () {const int maxprime = 100; int prime number, divisor; for (prime number = 3; prime number <= max prime number; prime number ++) {// check whether prime number is really a prime number for (divisor = 2; divisor using namespace std; int main () {const int maxprime = 100; int prime number, divisor; bool is a prime number; cout << "2"; for (prime number = 3; prime number <= max prime number; prime number ++) {is one prime number = true; // Check whether the prime number is really a prime number for (divisor = 2; divisor Remember status This program fulfills the requirements that we had set. At the beginning there is a Boolean variable named is a prime number Are defined. This variable is set to for each new candidate. As soon as a divider is found, it is set to. After all divisors have been tested, the candidate is issued, if is a prime number still is.

For the sake of completeness, the number 2 is simply output directly at the beginning without any explicit calculation.

optimization

However, this solution is not ideal. The inner loop will run through to the end even if the candidate is already divisible by 2. You can easily turn this off by adding an additional condition to the loop. As before, it is checked whether all divisors have been run through for the candidate, and additionally whether no divisibility has yet been determined. #include using namespace std; int main () {const int maxprime = 100; int prime number, divisor; bool is a prime number; cout << "2"; for (prime number = 3; prime number <= max prime number; prime number ++) {is one prime number = true; // Check whether the prime number is really a prime number for (divisor = 2; istEinePrimzahl && divisor Max prime number bet on 10,000. At the end you can see the structogram of the prime number program in figure {prime number diagram}.

Graphics are only available in the book

Greatest common divisor

The greatest common divisor (GCF) of two numbers is the greatest of the numbers by which both numbers are completely divisible. The greatest common divisor calculation is primarily used to reduce fractions. If the numerator and denominator are divided by the greatest common divisor, the fraction is optimally shortened. The algorithm for computing the greatest common divisor could be based on a prime number computation. To do this, one would split both numbers into their prime factors and multiply all common prime factors. But there is still an easier way. More than 2000 years ago, Euclid already described a very easy to implement procedure for calculating the GCD.

Euclid

We call the two numbers whose GCD is to be found a and b. The idea is based on the knowledge that the GCF is not only a divisor of a and b, but also of b and (a-b), provided that b is greater than a. (I assume that you are not interested in a proof of this finding.) So instead of examining a and b, you can also examine b and (a-b). This means that the larger of the two numbers no longer needs to be examined. With the two new numbers, however, you can proceed in the same way as with a and b. Again, the difference between the two numbers is used instead of the larger number. If you repeat this process until the smaller number becomes 0, the other number must be the GCD.

First the structogram

In this example, the development of the program should begin with the structogram. First, the two candidates are read. A loop then runs as long as the smaller value is greater than 0. A check must be made within the loop to determine which of the two numbers is larger. If necessary, the values ​​are swapped before they are subtracted from one another.

Graphics only available in the book

To deceive

This formalizes the general description of the algorithm and puts it in a structogram. Almost anything can be easily implemented directly in C ++ code. Only the swapping of the variable content needs to be described in more detail before it can be converted into program code. The spontaneous thought would be to write first and then. But that won't work because the variable content of a is overwritten in the first assignment and is therefore lost. An auxiliary variable must therefore be used in which the content of a before it is overwritten. help = a; a = b; b = help; The swap is now added to the structogram. At the same time, the names are approximated to the syntax of C ++.

Graphics only available in the book

Transferred to C ++

It is now an easy exercise to convert this structogram into a corresponding C ++ program. The structured chart can therefore be a help in developing a program, especially when more complex processes are involved. #include using namespace std; int main () {int a, b, help; cin >> a; cin >> b; while (b> 0) {if (b> a) {// Swap a and b help = a; a = b; b = help; } a = a - b; } cout << a << endl; }

Exercises

  • Complete the program VAT.cpp to the effect that the program checks whether the net price is greater than 0 and only then performs the calculation.
  • Add to the program VAT.cpp add an error message to be displayed if the user attempts an incorrect entry.
  • Compound interest: You pay 5000 euros into an account at an interest rate of 5% every year. Create a table with the year on the left and the balance on the right.
  • Number guessing: Let the computer pick a random number between 1 and 1000. The user gives a tip and the computer reports whether the tip was bigger, smaller or correct. This is repeated until the tip has hit the number.