0% found this document useful (0 votes)
5 views36 pages

Ppi Handout 03

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views36 pages

Ppi Handout 03

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

Prozedurale Programmierung

für Informatiker (PPI)

Institute for Autonomous Cyber-Physical Systems

Prof. Dr.-Ing. Bernd-Christian Renner


with Dr.-Ing. Peter Oppermann and Wiebke Frenkel
Control Flow: Branching and Repeating
3
Making Decisions

right

left
Angle-Right Learning Goals
 Check inputs
 Execute conditional code
 Repeat code
 Understand different repetition concepts

1
Award Challenge

Angle-Right Stealing Sugar from the Kitchen


Cebra loves sugar; however, there are a few noisy traps in the kitchen to notify
the parents. Help Cebra to calculate the chances of getting sugar.

Write a program that simulates the following environment N times,


record the number s of successes, calculate the success
probability.
 The way to the kitchen has F fields (2 ≤ F ≤ 10, 000).
 Cebra starts on the first field, the sugar is on the last field.
 Every T’th field is a trap (0 < T < F); except first and last field.
 It is dark and Cebra cannot see the traps.
 Cebra randomly jumps 1 to 6 fields forward.
 There is no sugar in the attempt, if Cebra jumps on a trap.
2
Award Breaking it Down
FILE-CODE handson_sugar-draft.c
read N 1 #include <stdio.h>
2 #include <stdlib.h>
count 3 #include <time.h>
success 4
no yes 5 int main(void)
error N valid? 6 {
7 srand(time(NULL));
no 8
sugar? jump 9 unsigned N;
yes
10 printf(”Enter N: ”);
read F 11 scanf(”%u”, &N);
no 12 // TODO check N
13
14 unsigned F;
yes
15 printf(”Enter F: ”);
no trap?
error F valid? 16 scanf(”%u”, &F);
17 // TODO check F
18
yes 19 unsigned T;
20 printf(”Enter T: ”);
first field 21 scanf(”%u”, &T);
read T
22 // TODO check T
no
23
24 unsigned sugars = 0;
yes yes 25 // TODO repeat N times
no repeated print
error T valid? 26 // TODO go for sugar
N times? probability 27
28 printf(”%.3f\n”, (double)sugars / N);
29 return 0;
30 }
3
Control Flow: Branching and Repeating
3 1
Branching
Simple Branching

PENCIL-ALT Definition: Conditional Statement


Used to control the execution of another statement.

Syntax
if (condition) { statements_true } else { statements_false }

 The condition is evaluated


if it is true then statements_true are executed


otherwise, statements_false are executed




 The else part is optional


 Curly braces are required, if more than one statement follows an if or else
 For readability, write each statement on a new line and use indentation
 Indentation is style (readability, but no syntactical impact)
4
Comparison Operators

Conditions are realized through comparisons

Operator Meaning Operands Example


== equal variables, numbers x == y
!= not equal variables, numbers x != 2
> greater variables, numbers x > y
< smaller variables, numbers x < 1.0
>= greater or equal variables, numbers x >= y
<= less or equal variables, numbers x <= 100

Comparison operators yield a boolean result


false equivalent to zero
true equivalent to unequal zero
5
Simple Branching Example

FILE-CODE ex_branching.c
1 #include <stdio.h>
2
3
4 int main(void)
5 {
6 int n;
7
8 printf(”Please enter a number: \n”);
9 scanf(”%d”, &n);
10
11 if (n > 0) {
12 printf(”The number %d is positive\n”, n);
13 } else {
14 printf(”The number %d is *not* positive\n”, n);
15 }
16
17 return 0;
18 }

6
Complex Branching I

 An if statement can be used inside other if/else statements


 Be aware of the meaning
 Challenge: Design complex branching to be efficient and readable!

Nested Branching: Sequential Branching:


1 if (condition_1) { 1 if (condition_1) {
2 statements_1_true 2 statements_1_true
3 } else { 3 } else if (condition_2) {
4 if (condition_2) { 4 statements_2_true // and statements_1_false
5 statements_2_true // and statements_1_false 5 ...
6 } else { 6 } else {
7 statements_false 7 statements_false
8 } 8 }
9 }

7
Boolean Operators

Operator Meaning Operands Example


&& logic AND boolean v > 0 && v < 10
|| logic OR boolean v < 0 || v > 5
! negation boolean !(v < 0)

1st Operand 2nd Operand AND OR Negation


x y x && y x || y !x
true true true true false
Truth table:
true false false true false
false true false true true
false false false false true

8
Complex Branching II

 Conditions may be constructed from any logic expression


 Compound conditions are generally evaluated from left to right
 Mind the precedence of logic operators
use parentheses, if in doubt or to improve readability
 If outcome of compound condition is determined, remaining conditions are
skipped

AND-composition OR-composition
1 if (condition_1 && condition_2) { 1 if (condition_1 || condition_2) {
2 statements_1_and_2_true 2 statements_1_or_2_true
3 } else { 3 } else {
4 statements_1_or_2_false 4 statements_1_and_2_false
5 } 5 }

A hideous example
1 if (x == 0 && ++y > 3) { // evaluation of ++y depends on value of x!
2 ...
3 }

9
Dos and Don’ts

 Use negation ( ! operator) only with logic expressions


Compare numbers to zero: v == 0, not !v
 Don’t use implicit comparisons with zero
Compare numbers to inequality with zero: v != 0, not v
 Always use braces
 Use else if instead of another if whenever appropriate
for faster execution, better readability, lower chances of semantic errors
 Don’t use assignments (including ++ / -- in conditions)
there are exceptions
 Check your ranges in comparisons
 Don’t compare floating-point values (for equality)
they are approximations, so use a threshold (error margin)

10
Dos and Don’ts: Examples

FILE-CODE ex_branching-bad.c
1 #include <stdio.h>
2
3 int main(void)
4 {
5 short s = -1;
6 int n = 0;
7 double d = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1;

SKULL-CROSSBONES
8
9 if (n) { /* obfuscating what is checked */ }
10 if (!n) { /* applying a logic operator to an int */ }
11 if (n < 0)
12 n *= -1;
13 /* adding something down here with indentation will lead to unintended behavior */
14 if (n++ < 0) {
15 /* obfuscating what happens */
16 }
17 if (s < 35000) {
18 /* always true */
19 }
20 if (d == 0.9) {
21 /* are these the same? */
22 printf(”d is 0.9”);
23 }
24
25 return 0;
26 }

11
Quiz 3.1

1 int x = 13;
TERMINAL
Consider the shown C source code. 2
3
char c = ’a’;
bool b = false;

Which of the statements given below is


4
5 if (x > 10 && ++c < ’B’ || b) {

true?
6 statements_1
7 } else {
8 if (c++ > ’b’ && (b = x == 13)) {
9 statements_2
10 } else if (b) {
This is really bad code! 11 statements_3
12 }
13 }

A statements_1 are executed B statements_2 are executed

None of the statements_i (i = 1, 2, 3) are


C statements_3 are executed D executed
12
A Shortcut for Branching in Special Situations

Syntax
condition ? expression_true : expression_false

 Ternary operator: If condition evaluates to true, expression_true is evaluated;


otherwise expression_false is evaluated
 The ternary operator should not be used to mimic any other if/else construct
as it makes your code less readable
Counterexample:
1 bool b;
Use cases: 2
3
...
// the good
1 int x; 4 if (b) {
2 ... 5 printf(”run: pass”);
3 // variant A: if ... else 6 } else {
4 if (x > 0) { 7 printf(”run: fail”);
5 abs = x; 8 }
6 } else { 9
7 abs = -x; 10 // the bad (formatting doesn’t make it any better)
8 } 11 b ? printf(”run: pass”) : printf(”run: fail”);
9 12
10 // variant B: ?: 13 // and the beauty
11 int abs = x > 0 ? x : -x; 14 printf(”run: %s”, b ? ”pass” : ”fail”);

12
Deciding between Discrete Alternatives

PENCIL-ALT Definition: Switch Statement


A switch statement is a more elegant conditional statement for discrete decisions.

 The variable var is matched against the given cases


(values value_i) in the given order
must be of integer type Syntax

 The statements statements_i of the first matched case switch (var) {


case value_1:
value_i are executed up to statements_1
break;
the next break statement or case value_2:


statements_2
the end of the switch block break;


...
 Omitting a break statement causes a fall-through default:
statements_else
i.e., successive execution of statements regardless of the case value }

 The optional default case is executed, if there is no


other match
13
Example

FILE-CODE ex_switch.c
1 #include <stdio.h>
2
3 #define CHOICE_DE 1
4 #define CHOICE_DE_STR ”DE”
5 #define CHOICE_EN 2
6 #define CHOICE_EN_STR ”EN”
7
8 int main(void)
9 {
10 int lang;
11 printf(”Choose your language (%d:%s, %d:%s)! ”, CHOICE_DE, CHOICE_DE_STR, CHOICE_EN, CHOICE_EN_STR);
12 scanf(”%d”, &lang);
13
14 switch (lang) {
15 case CHOICE_DE:
16 printf(”You chose %s\n”, CHOICE_DE_STR);
17 break; // see what happens, if you omit this and choose CHOICE_DE
18 case CHOICE_EN:
19 printf(”You chose %s\n”, CHOICE_EN_STR);
20 break;
21 default:
22 printf(”Invalid choice!\n”);
23 }
24
25 return 0;
26 }

14
GLASSES Remarks and Spoiler

FILE-CODE ex_noswitch.c
1 #include <stdio.h>
2
 switch statements are frequently 3
4
enum { CHOICE_DE, CHOICE_EN, CHOICE_NUM };
const char * const CHOICE_STR[] = { ”DE”, ”EN” };

used with constants or enumerated 5


6

data types
7 int main(void)
8 {
we’ll talk about that later 9
10
unsigned lang;
printf(”Choose your language!\n”);

The example on the previous slide is a


11 for (unsigned i = 0; i < CHOICE_NUM; i++) {
 12 printf(” %u: %s\n”, i, CHOICE_STR[i]);
13 }
pretty bad implementation 14 scanf(”%u”, &lang);
15
but we don’t know any better yet 16 if (lang < CHOICE_NUM) {
17 printf(”You chose %s\n”, CHOICE_STR[lang]);
 In particular, it can be solved more 18
19
} else{
printf(”Invalid choice!\n”);
elegantly and extendably 20
21
}

22 return 0;
23 }

15
Award Preparing for the Kitchen
FILE-CODE handson_sugar-input.c
5 #define F_MIN 2
6 #define F_MAX 10000
7
8 int main(void)
9 {
10 srand(time(NULL));
11
12 unsigned N;
13 printf(”Number of runs (N, N>0)? ”);
14
15
scanf(”%u”, &N);
if (N <= 0) {
Check-Circle Read input
Validate input
16 printf(”error”);
17 return 0; Check-Circle
18 }
19
20 unsigned F;
Times-Circle Repeat N times
21 printf(”Number of fields (F, %u<=F<=%u)? ”, F_MIN, F_MAX);
22 scanf(”%u”, &F); Times-Circle Try to get the sugar
23 if (F < F_MIN || F > F_MAX) {
24
25
printf(”error”);
return 0;
Check-Circle Write high-quality software
26 }
27
28 unsigned T;
29 printf(”Trap distance (T, 0<T<F)? ”);
30 scanf(”%u”, &T);
31 if (T < 1 || T >= F) {
32 printf(”error”);
33 return 0;
34 }
16
Control Flow: Branching and Repeating
3 2
Repetitions
Repetition Statements

PENCIL-ALT Definition: Repetition Statement


A repetition statement allows the controlled repeated execution of statements.

 Repetition statements
while-statement


do-while-statement


for-statement


 In principle, one kind would suffice


 Each kind has typical use cases

17
while Loop

PENCIL-ALT Definition: While Statement


A while-statement is used to control the repeated execution of statements; as long as the loop
condition holds, the statements are repeatedly executed.

Syntax
while (condition) {
statements
}

 statements are executed until condition turns false


 condition is evaluated before entering and after each complete cycle of the loop
loop may not be entered at all


statements are always executed as a whole




 Unless the statements inside the loop can be interrupted, condition must
become false due to a statement inside the loop

18
while Loop – Use Cases

FILE-CODE ex_while-loop.c
1 #include <stdio.h>
2
3 int main(void)
4 {
Typical use cases 5
6
unsigned x;
unsigned digits = 0;

Unknown number of loop


7 printf(”Enter a positive number!”);
 8 scanf(”%u”, &x);

iterations
9
10 while (x > 0) {
11 x /= 10;
 Guarded (first) loop execution 12
13 }
digits++;

14
15 printf(”The number has %u decimal digits.\n”, digits);
16
17 return 0;
18 }

19
do-while Loop

PENCIL-ALT Definition: Do-While Statement


A do-while-statement is used to control the repeated execution of statements; the statements are
repeated as long as the loop condition holds.

Syntax
do {
statements
} while (condition);

 statements are executed at least once and repeated until condition turns false
→ loop is always entered at least once

20
do-while Loop – Use Cases

FILE-CODE ex_do-while-loop.c
1 #include <stdio.h>
2
3 #define NUMBER_MIN 10
Typical use cases 4 #define NUMBER_MAX 20
5
 Unknown number of loop iterations 6
7
int main(void)
{
8 unsigned x;
 At least one execution 9 do {
10 printf(”Enter a number from [%u, %u]: ”,
 Best to use with short loop bodies to 11
12
NUMBER_MIN, NUMBER_MAX);
scanf(”%u”, &x);

make the loop condition more visible 13


14
} while (! (x >= NUMBER_MIN && x <= NUMBER_MAX));

15 printf(”You entered %u.\n”, x);


16
17 return 0;
18 }

21
for Loop

PENCIL-ALT Definition: For Statement


A for-statement is a more compact while-statement for countable or alike repetitions.

Syntax
for (initialization; condition; stepping) {
statements
}

Equivalent while-statement
1 initialization
2 while (condition) {
3 statements
4 stepping
5 }

22
for Loop – Use Cases

FILE-CODE ex_for-loop.c
Typical use cases 1 #include <stdio.h>
2
 Known number of executions 3
4
int main(void)
{
(counted) 5
6
unsigned n;
unsigned sum = 0;

Iterations over a data set


7 printf(”Enter n to calculate the sum from 1 to n! ”);
 8 scanf(”%u”, &n);
what we mean are arrays, which we will 9
10 for (unsigned i = 1; i <= n; i++) {
talk about later 11 sum += i;
12 }
 Stepping independent of loop 13
14 printf(”The sum from 1 to %u is %u.\n”, n, sum);

content (fixed pattern)


15
16 return 0;
17 }

Remark: Variables declared in the initialization part of a for-statement only exist inside
the (entire) for loop

23
Breaking a Loop

 A loop can be aborted at FILE-CODE ex_break.c


arbitrary places using the 1 #include <stdio.h>

break-statement
2 #include <stdbool.h>
3
4 int main(void)
 Statements inside the loop 5
6
{
bool isPrime = true;
following the break statement 7
8
unsigned int x;

or not executed 9
10
printf(”Enter a positive number: ”);
scanf(”%u”, &x);
11
 The program continues behind 12
13
for (unsigned d = 2; d*d <= x; d++) {
if (x % d == 0) {
the loop 14
15
isPrime = false;
break;
 Used to handle special 16
17 }
}

situations or to improve 18
19 printf(”%u is %s.\n”, x, isPrime ? ”prime” : ”not prime”);

readability
20
21 return 0;
e.g., avoid additional or long if 22 }

statements (blocks)

24
Shortcutting a Loop

 The continue statement is used to bring 1 #include <stdio.h>


FILE-CODE ex_continue.c

the program control to the beginning of 2


3
#include <stdbool.h>

the loop 4
5
#define N 100

6 int main(void)
 Statements of the loop following the 7 {
8 unsigned int div;
continue statement are skipped 9
10 printf(”Enter a positive number: ”);
 Program continues at top of the loop 11
12
scanf(”%u”, &div);

13 printf(”Numbers <%u divisable by %u:”, N, div);


do-while unconditionally 14
15
for (unsigned n = 1; n < N; n++) {
if (n % div != 0) {
while with the condition 16
17 }
continue;

for with the stepping, followed 18


19 // you’d typically have more beef here
by the condition 20
21
// than a single statement
printf(” %u”, n);
22 }
 Used to prevent certain, long or nested 23
24
printf(”\n”);

if blocks inside a loop 25 return 0;


26 }

25
Infinite Loops

 There are cases, when loops


never end


e.g., on an embedded device that has no OS


are only left from somewhere within


for improved readability; however, there may be more elegant solutions

FILE-CODE ex_inf-loop.c
1 #include <stdio.h>
2 #include <stdbool.h>
3
4 int main(void)
5 {
6 while (true) { // also frequently: while (1)
7 int x;
8 printf(”Enter a number to compute the square for (0 to exit): ”);
9 scanf(”%d”, &x);
10 if (x == 0) {
11 break;
12 }
13 printf(”(%d)^2 = %u\n”, x, (unsigned)(x*x));
14 }
15
16 return 0;
17 }

26
Dos and Don’ts

 Use the most suitable loop type


 Abide by the rules for branching regarding the loop condition
 Use break and continue sparingly
 Do not change the stepping variable inside a for-loop
 Make sure that your loops terminate
be careful about integer overflows, don’t use floating-point values for stepping
 Repetition statements may be nested
in any combination and to any depth
 ...

27
Award Trying to Get Some Sugar

FILE-CODE handson_sugar-loops.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <time.h>
4
5 #define F_MIN 2
6 #define F_MAX 10000
7

Read input
8 #define JUMP_MAX 6
Check-Circle
··· Check-Circle Validate input
38 unsigned sugars = 0;
39 for (unsigned n = 0; n < N; n++) { Check-Circle Repeat N times
40 unsigned field = 1;
41
42
while (field < F && (field == 1 || field % T != 0)) {
field += 1 + (rand() % JUMP_MAX);
Check-Circle Try to get the sugar
43 }
44 if (field >= F) { Check-Circle Write high-quality software
45 sugars++;
46 }
47 }
48
49 printf(”success probability: %.3f\n”, (double)sugars / N);
50
51 return 0;
52 }

28
Award Trying to Get Some Sugar Gracefully

FILE-CODE handson_sugar.c
5 #define F_MIN 2
6 #define F_MAX 10000
7
8 #define JUMP_MAX 6 Check-Circle Read input
9
10
11
int main(void)
{ Check-Circle Validate input
12 //srand(time(NULL));
13 srand(0); // remove randomness to compare results Check-Circle Repeat N times
14
15
16
unsigned N;
do { Check-Circle Try to get the sugar
17 printf(”Number of runs (N, N>0)? ”);
18
19
scanf(”%u”, &N);
} while (N <= 0);
Check-Circle Write high-quality software
20
21 unsigned F;

Note: This is different from the


22 do {
23 printf(”Number of fields (F, %u<=F<=%u)? ”, F_MIN, F_MAX);

flow chart, but it is a more


24 scanf(”%u”, &F);
25 } while (F < F_MIN || F > F_MAX);

interactive implementation.
26
27 unsigned T;
28 do {
29 printf(”Trap distance (T, 0<T<F)? ”);
30 scanf(”%u”, &T);

29
Award Trying to Get Some Sugar Differently

FILE-CODE handson_sugar-alternative-1.c FILE-CODE handson_sugar-alternative-2.c


34 unsigned sugars = 0; 33 unsigned sugars = 0;
35 34
36 for (unsigned n = 0; n < N; n++) { // repeat N times 35 for (unsigned n = 0; n < N; n++) { // repeat N times
37 unsigned fld = 1; 36 unsigned fld = 1;
38 while (true) { 37 do {
39 // trap every T’th field (T, 2T, ...) 38 // 1st jump is ”free” (no sugar, no trap)
40 if (fld > 1 && fld < F && fld % T == 0) { 39 fld += 1 + (rand() % JUMP_MAX);
41 break; // abort 40 // check whether we made it and got trapped
42 } 41 } while (fld < F && fld % T != 0);
43 // reached sugar w/o hitting a trap 42
44 if (fld >= F) { // reached goal 43 // (only) if we made it to the end, there’s sugar
45 sugars++; 44 if (fld >= F) {
46 break; // done 45 sugars++;
47 } 46 }
48 // no sugar, no trap -> jump 47 }
49 fld += 1 + (rand() % JUMP_MAX); 48
50 } 49 printf(”%.3f\n”, (double)sugars / N);
51 // NOTE: optimizations (see ”...-alternative-2.c”) 50
52 // - F >= 2 and fld == 1 is no trap -> move jump up 51 return 0;
53 // - no trap on last field, swap checks to remove 52 }
54 // fld != F check
55 // - avoid scattered loop exits (depends on taste)
56 }
57
58 printf(”%.3f\n”, (double)sugars / N);
59
60 return 0;
61 }

30
Prozedurale Programmierung
für Informatiker (PPI)

Institute for Autonomous Cyber-Physical Systems

Prof. Dr.-Ing. Bernd-Christian Renner


with Dr.-Ing. Peter Oppermann and Wiebke Frenkel

You might also like