1 of 44

Loops

03603111 Programming Fundamentals I

Department of Computer Engineering, Faculty of Engineering at Sriracha

2 of 44

Course outline and schedule

  • L01 Introduction
  • L02 Data and I/O
  • L03 Conditionals
  • L04 Loops (today!)
  • L05 Arrays, strings, and pointers
  • L06 Functions and abstraction
  • Lab exam #1
  • L07 Nested loops, file I/O, and dynamic arrays
  • L08 Sorting
  • L09 Searching
  • L10 Structures
  • L11 Linked data structures
  • L12 Unions and tagged structures
  • Lab exam #2

2

3 of 44

Overview

  • The while loop
  • Loop invariants
  • Loop interruption: break and continue
  • The do … while loop

3

4 of 44

Previous lesson recaps

4

5 of 44

if statement – do it or skip it

  • What you’ve seen in the previous example is the if statement

Syntax: if (condition) statement

  • The condition is a Boolean expression

5

Statement(s)

Condition

True

False

6 of 44

if … else statement – do this or do that

Syntax:

if (condition) statement1 else statement2

int n = 123;

if (n % 2 == 0)

printf("%d is even.\n", n);

else

printf("%d is odd.\n", n);

~> 123 is odd.

6

Statement(s)1

Condition

Statement(s)2

True

False

7 of 44

Comparison and logical operators

  • Boolean expressions compare values or expressions using comparison operators
  • Comparison operators
    • Comparison operators yield 1 for true and 0 for false
    • Note the low precedence of these operators, compared to arithmetic operators

  • Multiple conditions can be combined using logical operators
  • Logical operators
    • We use them to combine “logical clauses”
    • && has higher precedence than ||, and ! has the highest precedence

7

Operator

Description

==

Equal to

!=

Not equal to

>

Greater than

>=

Greater than or equal to

<

Less than

<=

Less than or equal to

Operator

Description

!

Negation (NOT)

&&

AND

||

OR

8 of 44

Multiway selection – the if … else if … else pattern

#include <stdio.h>

int main()

{

char c;

printf("Enter a character: ");

scanf(" %c", &c); // note the space before %c

if (c >= 'A' && c <= 'Z') {

printf("'%c' is a capital letter.\n", c);

} else if (c >= 'a' && c <= 'z') {

printf("'%c' is a small letter.\n", c);

} else {

printf("'%c' is not a letter.\n");

}

}

8

Enter a character: x

'x' is a small letter.

// Re-run

Enter a character: A

'A' is a capital letter.

// Re-run

Enter a character: 9

'9' is not a letter.

Results

9 of 44

General cautions and guidelines

  • Never use = (assignment) where == (equality) should be used

  • Never compare floating-points for equality
    • Check if the value is within tolerance (e.g., 0.0001f) rather than being exactly equal (fabs() is helpful here)

  • When there are two actions to choose from, use if … else

  • When there are two values to choose from, use conditional expressions (cond ? a : b)

9

10 of 44

The U-SWACT Problem Solving Framework

  1. ͏UNDERSTAND the problem
    • What is the task really asking?
    • What are the inputs and expected outputs?
    • Are there any constraints (e.g., size, time, types, value ranges)?
  2. Make up SAMPLE INPUTS
    • Try normal and edge cases
    • Include small, negative, or boundary values
  3. ͏WORK OUT solutions manually
    • For each sample input, figure out the correct output by hand
    • Explain your reasoning in plain language
    • Look for patterns or repeated steps
    • If stuck, simplify the problem or solve a related problem first
  1. Write the ALGORITHM
    • Write down the steps from input to output
    • Break it into sub-problems if needed
    • Sketch out any loops or conditions
  2. Translate into CODE
    • Start small – implement one step at a time
    • Test frequently as you build
    • Use print or a debugger to trace values
    • If it doesn’t work, go back to your algorithm or manual steps
  3. ͏TEST the code
    • Try all your sample inputs from Step 2
    • Add more: normal, edge, and invalid inputs
    • Ask: “Does this cover all cases I can think of?”

10

UNDERSTAND

SAMPLE INPUTS

WORK OUT

ALGORITHM

CODE

TEST

11 of 44

The while loop

11

12 of 44

Let’s start with problems again

  • Many problems require us to do things repeatedly
    • Compute 10!
    • Find the maximum among all the integers entered by the user
    • Find the largest N such that the sum from 1 to N is still less than 50

  • Some are task-oriented
    • Given N, print N stars
    • Keep reading the user input until the input is within the range 1-100

  • Take a minute to think how a computer can solve these problems
  • Again, remember that we cannot process all the numbers at once
    • Let’s say we do it one at a time, but repeatedly

13 of 44

Conditional loops

  • There are 3 loop (iteration) control structures in C
    • while loop
    • do … while loop
    • for loop

  • All of them are conditional – meaning that they will repeatedly do things until the condition is false

  • We’ll focus only on the while and do … while loops for now

13

14 of 44

while loop – check first, then act

  • The first is while loop
    • Syntax: while (condition) statement

  • The while loop repeatedly executes statement until condition is false
  • The condition is checked first – if it’s false from the beginning, statement will never be executed (no loop happening)

14

Condition

Statement(s)

False

True

15 of 44

Problem: Printing N stars

#include <stdio.h>

int main()

{

int n;

printf("How many stars do you want? ");

scanf("%d", &n);

while (n > 0) {

printf("*");

n -= 1;

}

printf("\n");

return 0;

}

15

How many stars do you want? 5

*****

// Re-run

How many stars do you want? 0

Result:

16 of 44

Introducing the (in)famous ++ and -- operators

++ is the increment operator, and -- is the decrement operator

  • C++ got its name from this operator!
  • Can’t be used with floating-point types

  • Both a++ and ++a by themselves are similar to a += 1
  • When it’s used in an expression or assignment, the difference is important
    • ++a increments a first, then uses the incremented value in the expression
    • a++ uses the current value of a in the expression first, then increments a
  • Given a = 10:
    • b = a++ * 2; // a == 11, b == 20
    • b = ++a * 2; // a == 11, b == 22

16

17 of 44

Problem: Printing N stars using -- operator

Direct substitution

int main()

{

int n;

printf("How many stars … ");

scanf("%d", &n);

while (n > 0) {

printf("*");

n--; // replaces n -= 1;

}

printf("\n");

}

Concise and idiomatic usage

int main()

{

int n;

printf("How many stars … ");

scanf("%d", &n);

// Check and decrease at once

while (n-- > 0) {

printf("*");

}

printf("\n");

}

17

18 of 44

Similar problem: Counting up to N

#include <stdio.h>

int main()

{

int n;

printf("Number to count up to: ");

scanf("%d", &n);

int v = 1;

while (v <= n) {

printf("%d\n", v);

v++;

}

return 0;

}

18

Number to count up to: 5

1

2

3

4

5

Result:

What happens if we try to combine the increment operator (++) with the condition?

19 of 44

Repeat N Times

PROBLEM: Given N, repeat an action N times

SOLUTION: We need a counter variable that counts up from 0 to N-1 (idiomatic) or 1 to N (less common)

Using while:

int i = 0; // counter variable

while (i < n) {

// Perform action ...

i++;

}

However, it is more common to use the for loop, which we will discuss next week

Using for:

for (int i = 0; i < n; i++) {

// Perform action ...

}

�Counter variables are commonly named i, j, or so, but you’re welcome to use a more meaningful name

19

CODING PATTERN

PATTERN NAME

20 of 44

++ and -- can make your head spin

  • Given a = 10 and b = 20, what are the final values of a, b, and c in the following statements?
    • c = a++ + b++;
    • c = 10 + ++a - b--;
    • c = ++a * 2 + ++a * 3;
  • The last example is BAD – the result depends on the order of executing the two ++ operators, which is undefined
  • Never use these operators on the same variable more than once in the same expression (you’d probably never have a reason to do it anyway)

20

INTERESTING BITS

21 of 44

Problem solving recipe: loop invariants

22 of 44

Problem: Sum of the inputs

  • Given an integer n, followed by exactly n integers, find the sum of the n integers
  • Example:

5

1 3 2 -1 7

~> 12

  • We cannot add up all the integers at once – instead we need to go through them one-by-one
  • We need a variable to hold the result as we progress
  • We can use Repeat N Times pattern to read and process the n inputs

22

23 of 44

Solution: Sum of the inputs

#include <stdio.h>

int main() {

int n;

int num;

int sum = 0;

// Read the number of inputs

scanf("%d", &n);

int i = 0;

while (i < n) {

scanf("%d", &num); // read each number

sum += num; // add to the sum

i++;

}

printf("%d\n", sum);

return 0;

}

23

Note the variable sum:

  • At any point, sum remains the sum of the inputs so far
  • Before the loop starts, sum is the sum of zero inputs, which is exactly zero
  • At the end of each iteration, sum is the sum of the inputs read so far
  • When the loop finishes, sum is the sum of all inputs – the final and expected result

24 of 44

Loop invariants

  • In the previous example, the condition that “the variable sum must remain the sum of all inputs so far” is called the loop invariant
    • Invariant means “an unchanging property”

  • A loop invariant is a condition or statement about a loop's variables that is true before the loop starts and remains true after every single iteration

  • Loop invariants are especially useful in problems that deal with directly deriving a single result from a list of items

  • By maintaining the invariant, correct result is guaranteed by the end of the loop

24

25 of 44

A simple 4-step recipe to use loop invariants

  1. Result Variable: Set up a variable that will hold your final result (e.g., max_val, sum, count)
  2. Initialization: Initialize this variable with a base case value that makes your rule true even before the loop starts
    • Example: For summing, start with 0. For finding the max, start with the first item.
  3. Maintenance: Inside the loop, update the variable as you process each new item, ensuring your rule (invariant) is still true at the end of every iteration
    • The Invariant: "My variable holds the correct result for all the items I've seen so far."
  4. Termination: When the loop finishes, the variable will hold the final, correct result

  • This recipe works well for problems with a single-value result that can be derived directly from a list of items
  • However, this is not the only way to use loop invariants, but it’s a simple way to start

25

26 of 44

Problem: Maximum of the inputs

  • Given an integer n, followed by exactly n integers, find the maximum of the n integers

  • Let’s use the simple loop invariant recipe:
    • Result Variable: The result is the maximum, so we name it max_val
      • Let’s pause here: What’s the loop invariant for this problem?
      • Invariant: max_val holds the maximum of all the inputs we’ve seen so far
    • Initialization: Maximum of zero inputs is undefined, so we initialize max_val to the first item as its base case value instead
    • Maintenance: Inside the loop, update max_val such that it always holds the maximum of the inputs seen so far by the end of each iteration
    • Termination: When the loop finishes, max_val should hold the maximum of all the inputs – verify that it does

  • Work it out on the provided blank sheet to go from the recipe to code

26

27 of 44

Blank sheet – work out your solutions here

27

28 of 44

Problem: Factorial of N

  • Given an integer n, 0 ≤ n ≤ 10, compute n!

  • Again, let’s use the simple loop invariant recipe to work it out:
    • What’s the result variable?
    • What’s the invariant?
    • What’s the initial value?
    • How do we maintain the invariant?

  • Work it out on the provided blank sheet

28

29 of 44

Blank sheet – work out your solutions here

29

30 of 44

Solution: Factorial of 10

#include <stdio.h>

int main()

{

int n = 10;

int fact = 1;

int i = 1;

while (i <= n) {

fact *= i;

i++;

}

printf("%d! = %d\n", n, fact);

return 0;

}

30

10! = 3628800

Result:

31 of 44

Problem: Sum up until 50

  • Find the largest N such that the sum from 1 to N is still less than 50
    • This problem is similar to sum of inputs, but with a different terminating condition
    • It’s not counting up to N, but to add up to some value less than 50
    • The terminating condition has 50 as its end marker

  • In this problem, it’s not exactly the sum that we want to know – it’s the N that sums up to it
  • Can we use the simple loop invariant recipe to solve it?
    • What’s the result variable?
    • What’s the invariant?

  • Loop invariants sometimes involve more than one variables – such as in this problem – so the simple loop invariant recipe does not apply
  • As you gain more experience with simpler loop problems, this one will also become easier

31

32 of 44

Solution: Sum up until 50

#include <stdio.h>

int main()

{

int target = 50;

int n = 1, sum = 0;

while (sum + n < target) {

sum += n;

n++;

}

printf("N that sums up to %d = %d\n", sum, n - 1);

return 0;

}

32

N that sums up to 45 = 9

Result:

while (sum + n < target)

sum += n++;

More concise version

33 of 44

Interrupting the loop flow

34 of 44

break and continue

  • These statements are used to interrupt the flow of loops

  • break exits from the loop
  • continue skips the remaining statements and starts the next iteration

  • Often used with a conditional statement (if or if … else)

34

35 of 44

Sum of a series with skipping

#include <stdio.h>

int main()

{

int n = 0, sum = 0, last_add = 0;

while (1) { // infinite loop

n++;

// Skip any number divisible by 3

if (n % 3 == 0)

continue;

// Stop once target is reached

if (sum + n >= 35)

break;

sum += n;

last_add = n; // we record last_add because sometimes n is skipped

}

printf("N that sums up to %d = %d\n", sum, last_add);

return 0;

}

35

N that sums up to 27 = 8

Result:

36 of 44

We have just seen an infinite loop

  • A 1 means true, which, in this case, means the condition is always true -- indefinitely

  • We use an infinite loop when:
    • The exit condition can only be checked in the middle of the iteration
    • There are multiple exit conditions
    • The task really needs to be executed indefinitely
      • For examples, game or event-handling loops

36

37 of 44

The do … while loop

38 of 44

do … while loop – act first, then check

  • Next is do … while loop
    • Syntax: do statement while (condition);

  • The do … while loop repeatedly executes statement until condition is false
  • The statement is executed first, then the condition is checked – at least one iteration is guaranteed

38

Condition

Statement(s)

False

True

39 of 44

Problem: Input validation

  • Problem: We want to ask the user to guess a number, but also make sure the input is within the range 1-100
  • Solution: If the user enters a value that is outside the range, keep asking until a valid input is entered

  • This is part of defensive programming practice – we assume that the user always makes mistakes

  • Input validation is very common:
    • Asking the user to confirm (with ‘y’ or ‘n’)
    • Presenting a list of choices and making sure the user enters a valid one

39

40 of 44

Input validation

#include <stdio.h>

int main()

{

int guess;

do {

printf("Enter your guess (1-100): ");

scanf("%d", &guess);

} while (guess < 1 || guess > 100);

printf("You guessed %d.\n", guess);

return 0;

}

40

Enter your guess (1-100): 0

Enter your guess (1-100): 101

Enter your guess (1-100): 100

You guessed 100.

Result:

41 of 44

Can we use while loop for that?

#include <stdio.h>

int main()

{

int guess;

printf("Enter your guess (1-100): ");

scanf("%d", &guess);

while (guess < 1 || guess > 100) {

printf("Enter your guess (1-100): ");

scanf("%d", &guess);

}

printf("You guessed %d.\n", guess);

return 0;

}

41

Code is repeated

42 of 44

When to use which?

  • Use while in most cases for conditional loops

  • Use do … while when one of the followings holds:
    • You need to always have at least one iteration regardless of the condition
    • The value you’re checking requires the loop body to run to get it

  • Input validation is the most common use case for do … while

42

43 of 44

When you’re lost, a reference is here to help…

C reference: https://en.cppreference.com/w/c

Still, I recommend getting a book – your life will be easier that way

43

44 of 44

That’s all for today!

44