0% found this document useful (0 votes)
14 views59 pages

04 Loops, Arrays, and Pointers

Uploaded by

chayanin.ai
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)
14 views59 pages

04 Loops, Arrays, and Pointers

Uploaded by

chayanin.ai
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/ 59

Loops, Arrays, and Pointers

03603111 Programming Fundamentals I

Department of Computer Engineering, Faculty of Engineering at Sriracha


Course outline and schedule
• W1 Introduction • W9 Structures and dynamic arrays
• W2 Data and I/O • W10 Linked structures
• W3 Conditionals • W11 Data representations and
• W4 Loops, arrays, and pointers bitwise operations
(today!) • W12 Low-level programming
• W5 Functions • W13 Multi-file projects and
• W6 Nested loops and 2D arrays header files
• W7 Lab exam #1 • W14 Course review and closing
• W8 Searching and sorting • W15 Lab exam #2
2
Overview

• Conditional loops
• Counter-controlled loops
• break and continue

• Arrays and strings


• Memory addresses and pointers
• Reading strings

3
Previous lesson recaps
4
To succeed in this course…

Write a lot of code


Make a lot of mistakes

5
if statement – do it or skip it

• What you’ve seen in the previous example is Condition


False
the if statement True

Statement(s)
Syntax: if (condition) statement

• The condition is a Boolean expression

6
Comparison and logical operators
Operator Description • Comparison operators yield 1 for true and 0
== Equal to for false
!= Not equal to
Greater than
>
• We use logical operators to combine “logical
Greater than or
>= clauses” Operator Description
equal to
< Less than ! Negation (NOT)
Less than or && AND
<=
equal to || OR

7
Other important points

• Short-circuit evaluation
• Computation cost savings
• Preventing unwanted execution
• Be careful with equality == and assignment = operators
• Never directly compare floating-points for equality
• Defensive programming where possible – always guard against
potential invalid/malicious inputs

8
Type conversion
• When operands’ types are different, one of the operand will automatically be
promoted to the larger/wider type (if possible)
• Roughly, byte à short à int à long à float à double
• Conversion from a large int to float, or a large long to float or double is
potentially lossy

• Narrowing conversion requires explicit casting


• For example, from long to int or from double to long
• 15 / (int)5.5 yields 3 of int type

• Conversion between signed and unsigned where the source value is out of
the target type range is lossy 9
Blocks are treated as single statements
• You’ve seen an example of blocks (or compound statements, enclosed in {
… }) in the previous example

if (choice < 0 || choice > 9) {


printf("Invalid choice (%d)\n", choice);
return -1;
}

• Use blocks when more than one statement are being executed together
• Without using blocks, the return statement will always be executed
if (choice < 0 || choice > 9)
printf("Invalid choice (%d)\n", choice);
return -1; 10
if … else statement – do this or do that

Syntax:
if (condition) statement1 else statement2 Condition
False

True
int n = 123;
Statement(s)1 Statement(s)2
if (n % 2 == 0)
printf("%d is even.\n", n);
else
printf("%d is odd.\n", n);

~> 123 is odd.


11
Multiway selection – the if … else if … else pattern
float score = 75;
float grade; score >= True grade = 4.0
80.0

if (score >= 80.0) False


grade = 4.0; score >= True grade = 3.0
else if (score >= 70.0) 70.0

grade = 3.0; False


else if (score >= 60.0) score >= True grade = 2.0
grade = 2.0; 60.0
else if (score >= 50.0)
grade = 1.0; … …
else
grade = 0.0;
12
Multiway selection – switch … case
• Without break, execution falls through after
printf("It's "); the first matched case
switch (heat_level) { • In this example, case 5 is an empty case –
case 5: case 4: when matched, it falls through to case 4,
printf("insanely, "); and all other cases after that
case 3:
printf("overwhelmingly, ");
case 2: Results
printf("unbearably, "); // When heat_level == 5
It's insanely, overwhelmingly, unbearably,
case 1: incredibly, and extremely hot today.

printf("incredibly, "); // When heat_level == 1


It's incredibly, and extremely hot today.
default:
printf("and extremely hot today.\n");
}
13
User-defined labels with enum
enum { RED, GREEN, YELLOW };
• Enumeration or enum creates labels – integer
int light = RED; constants with names
switch (light) {
• Labels RED, GREEN, and YELLOW are
case RED:
printf("Stop!\n"); assigned integer values starting from 0
break; • Code is more readable – RED, GREEN, YELLOW
case GREEN: instead of 0, 1, 2
printf("Go!\n"); • Declaration of enum in this example is simplified
break; – more elaborated declaration is possible
case YELLOW:
printf("Slow down!\n");
break;
}
14
Conditional expressions
• Let’s say we want to compute an • This x < 0.0 ? -x : x is called
absolute of a floating-point number conditional expression, using the
(without using fabs()) “ternary” (3-operand) conditional
operator cond ? a : b
• We can do it this way: • If cond is true, the expression yields
if (x < 0.0)
a, otherwise it yields b
y = -x;
else
• When there are two actions to
y = x;
choose from, use if … else
• When there are two values to
• But it’s more concise this way: choose from, use conditional
y = x < 0.0 ? -x : x; expressions
15
Bottom line – choosing the right conditionals
switch (decision_type) {
case DO_OR_SKIP:
printf("Use if without else");
break;
case DO_THIS_OR_DO_THAT:
printf("Use if ... else");
break;
case CHOOSE_BETWEEN_TWO_VALUES:
printf("Use cond ? a : b");
break;
case CHOOSE_AMONG_MANY_ACTIONS:
if (condition_type == INTEGER_TYPE) // including char and enum
printf("Use switch ... case");
else
printf("Use if ... else if ... else pattern");
break;
default:
printf("Do you really need conditionals?");
}
16
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

17
Let’s continue with the lesson
18
Let’s start with problems again
• Many problems require us to do things repeatedly
• What is the value of 10! (factorial of 10)?
• If we sum up integers from 1 to N, what are the largest N such that the sum is
less than 1,000?

• 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


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
while loop – check first, then act

• The first is while loop


• Syntax: while (condition) statement

Condition True Statement(s)


• The while loop repeatedly executes
statement until condition is false False

• The condition is checked first – if it’s false


from the beginning, statement will not be
executed (no loop happening)
21
Printing N stars Result:
How many stars do you want? 5
#include <stdio.h> *****

int main() // Re-run


{ How many stars do you want? 0
int n;

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


scanf("%d", &n);
More concise version
while (n > 0) {
while (n-- > 0)
printf("*");
n--; printf("*");
} printf("\n");
printf("\n");

return 0;
}
22
Problem: sum of a series
• If we sum up integers from 1 to N, what is the largest N such that the
sum is less than 50?
• Understanding the problem
• What is the expected output?
• What are the inputs?
• What is the condition?
• Thinking about loops:
• What should each iteration do?
• What is the terminating condition?
23
Sum of a series
#include <stdio.h>
Result:
int main() N that sums up to 45 = 9
{
int target = 50;
int n = 1, sum = 0;
More concise version
while (sum + n < target) {
while (sum + n < target)
sum += n;
sum += n++;
n++;
}

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

return 0;
}
24
do … while loop – act first, then check

• Next is do … while loop


• Syntax: do statement while (condition);

Statement(s)

• The do … while loop repeatedly executes


statement until condition is false Condition
True

• The statement is executed first, then the False


condition is checked – at least one iteration
is guaranteed
25
Problem: input validation

• Keep reading the user input until the input is within the range 1-100

• This is part of defensive programming practice – we assume that the


user always makes mistakes

26
Input validation
#include <stdio.h> Result:
Enter your guess (1-100): 0
int main() Enter your guess (1-100): 101
{ Enter your guess (1-100): 100
int guess; You guessed 100.

do {
printf("Enter your guess (1-100): ");
scanf("%d", &guess);
} while (guess < 1 || guess > 100);

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

return 0;
}
27
Can we use while loop for that?
#include <stdio.h>

int main()
{
int guess;

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


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;
}
28
Counter-controlled loops

• Many iterative problems inherently call for a counter


• What is the value of 10! (factorial of 10)?
• Given N, print N stars

• As we’ve seen in the N stars example, conditional loops can also be


used as counter-controlled loops

29
Factorial of 10
#include <stdio.h>

int main()
{
int n = 10;
int fact = 1;

int i = 1; Result:
while (i <= n) {
fact *= i; 10! = 3628800
i++;
}

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

return 0;
}
30
From while loop to for loop

• This pattern is used often (as demonstrated in the previous example)


initialize;
while (condition) {
statement(s);
step;
}

• C provides a more concise loop statement for the pattern


• Syntax: for (initialize; condition; step) statement
31
Factorial of 10 (for loop version)
#include <stdio.h>

int main()
{
int n = 10;
int fact = 1; Compared with
int i = 1;
for (int i = 1; i <= n; i++) while (i <= n) {
fact *= i; fact *= i;
i++;
printf("%d! = %d\n", n, fact); }

return 0;
}
32
Scope of the initialized variable
• The for loop here: • If we move the declaration out:

for (int i = 1; i <= n; i++) int i;


fact *= i; for (i = 1; i <= n; i++)
printf("%d\n", i); fact *= i;
printf("%d\n", i);

• There is a compilation error –


variables declared inside for loop • It will now compile, because the
(i in this case) are not available variable is declared outside the
outside it for loop
33
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
Sum of a series with skipping
#include <stdio.h>

int main() Result:


{ N that sums up to 48 = 12
int n = 0, sum = 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 >= 50)
break;
sum += n;
}

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

return 0;
}
35
When to use which?
• while is more commonly used for conditional loops

• Use for when you want counter-controlled loops

• Use do … while when one of the followings holds:


• You need to always have at least one iteration regardless of the condition

• You have an action p that needs to be done on every iteration, and the
condition c depends on the result of action p
• In this case, if you use while, you will need to duplicate p both before the
while clause and within the body of the while, so do … while is a better fit
36
Sequential data structures
Arrays and strings
Arrays
Value 5 3 1 2 4 10 7 4 6 11
Index 0 1 2 3 4 5 6 7 8 9

• Array is a fixed-size collection of elements of the same type


• Each element is accessible via an index
• Declaration and initialization:
// 10-element int array (40 bytes allocated), uninitialized
int xs[10];
// 3-element float array (24 bytes allocated), with initialization
double ys[] = { 1.0, 2.5, 4.5 };
// 5-element unsigned int array (20 bytes), initialized to 1, 2, 3, 0, 0
unsigned zs[5] = { 1, 2, 3 };
38
Operations on arrays

• Array indexes starts from 0 to N-1


• Use an integer expression as a subscript (inside square brackets) to refer
to an element

int arr[3]; Value 1 3 4


Index 0 1 2
arr[0] = 1;
arr[1] = arr[0] + 2;
arr[arr[0] + 1] = arr[0] + arr[1];
39
Sum of the array
#include <stdio.h>

int main()
{
int arr[] = { 3, 4, 2, 0, 1 }; Result:
int num_elems = 5;
Sum = 10
int sum = 0;

for (int i = 0; i < num_elems; i++)


sum += arr[i];

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

return 0;
}
40
Finding the maximum
#include <stdio.h>

#define NUM_SCORES 5
Result:
int main()
{ 5 7 2 9 6
int scores[NUM_SCORES]; Max = 9
// Read user inputs into array
for (int i = 0; i < NUM_SCORES; i++)
scanf("%d", &scores[i]); // array element needs &

// Find maximum score


int max = scores[0];
for (int i = 1; i < NUM_SCORES; i++)
if (scores[i] > max)
max = scores[i];

printf("Max = %d\n", max);

return 0;
}
41
Address Memory Variable
Variables, memory, and addresses
0xBC04 A0
• Variables are stored in memory 0xBC05 86
exp
0xBC06 01
• Memory is a collection of byte-addressable cells
0xBC07 00
0xBC08 42
int exp = 100000; // 0x186A0 0xBC09 65
char name[8] = "Beck"; // 0x42 0x65 0x63 0x6B 0x00 0xBC0A 63
int *ptr = &exp; // 0xBC04 0xBC0B 6B
name
0xBC0C 00
0xBC0D ?
• Pointers are variables that store addresses – they point 0xBC0E ?
to data stored in memory 0xBC0F ?
• Note that actual in-memory ordering of variables is not 0xBC10 04
ptr
0xBC11 BC
guaranteed to be the same as the declaration order
42
Pointers
• Pointer variable declaration: type *name;
int *ptr;
• “Address of” operator (&) is used to get the address of a variable
ptr = &exp;
• Array and string variable names represent their memory addresses – we can
get their addresses directly without using & operator

• “Pointer dereference” operator (*) is used to get the value stored at the
memory address pointed to by the pointer
*ptr = *ptr + 1000;
• It is also used for assigning a value to that memory address
43
Pointers in action Result:
Value at 00000000005FFE80 = 3
int arr[] = { 3, 4, 2, 0, 1 }; Value at 00000000005FFE84 = 4
Value at 00000000005FFE88 = 2
int *ptr = arr; Value at 00000000005FFE8C = 0
Value at 00000000005FFE90 = 1
Address of the pointer = 00000000005FFE78
for (int i = 0; i < 5; i++) {
printf("Value at %p = %d\n", ptr, *ptr);
ptr++;
}
printf("Address of the pointer = %p\n", &ptr);

• Use %p to print the address referred by the pointer


• Pointer moves (++, --) in a step size equal to the size of the referred type (4
bytes for int in this case)
• Pointer is also a variable, and has its own memory address, too!
44
Null-terminated strings

• Strings are sequence of characters, used for representing textual data


• C-style strings are null-terminated char arrays
• Null-terminated means that strings end with the null character ('\0')
which is an integer with value 0

• Not used in most other languages (including C++ which has another
string type)

45
Null-terminated strings
Content 'H' 'e' 'l' 'l' 'o' '!' '\0'

Memory 48 65 6C 6C 6F 21 00 00 00 00
Index 0 1 2 3 4 5 6 7 8 9

0xA10D
0xA10C
0xA10B

0xA110
0xA111
0xA112
0xA113
0xA114
0xA115
0xA116
0xA10E
0xA10F
Address

char text[10] = "Hello!";

• This example is a string pre-allocated to 10 bytes, using 7 bytes to store


a string of length 6
46
Reading strings with scanf()
• When used with string (%s), scanf() will read characters until a whitespace is
encountered
char str[20];
printf("Enter a word: ");
scanf("%s", str);

• If “hello world” is entered, only “hello” will be read into str


• No need to use &str, the array name (str) already represents its address

• To prevent buffer overflow, width specifier can be used


scanf("%19s", word);
• Note that the width does not include the null character – therefore we specify
1 character less than the array size
47
Problem: counting string length

• Given a string, find the length of the string

• How do we determine a string length?


• By counting characters?
• When will we finish counting?

48
Counting string length
#include <stdio.h> Result:
Enter a word: Hello!
int main() Length of "Hello!" = 6
{
char str[20];

printf("Enter a word: ");


scanf("%19s", str);

int i = 0;
while (str[i] != '\0')
i++;

printf("Length of \"%s\" = %d\n", str, i);

return 0;
}
49
Counting string length (pointer version)
#include <stdio.h>

int main()
{
char str[20];

printf("Enter a word: ");


scanf("%19s", str);
Compared with
int i = 0; int i = 0;
char *p = str; while (str[i] != '\0')
while (*p++ != '\0')
i++;
i++;

printf("Length of \"%s\" = %d\n", str, i);

return 0;
}
50
Problem: copying a string

• Given a source string variable and a destination string variable, copy the
content of the source string to the destination string

• How do we know how much to copy?

51
Copying a string
#include <stdio.h> Result:
int main() Enter a word: Hello!
{ Content of dest = "Hello!"
char src[20];
char dest[20] = "1234567890123456789";

printf("Enter a word: ");


scanf("%19s", src);
Shortened version
int i = 0;
while (src[i] != '\0') { int i = 0;
dest[i] = src[i]; while ((dest[i] = src[i]) != '\0')
i++; i++;
}
dest[i] = '\0'; It tends to become harder to read though
printf("Content of dest = \"%s\"\n", dest);

return 0;
}
52
Copying a string (using for loop)
#include <stdio.h>

int main()
{
char src[20];
char dest[20] = "1234567890123456789";

printf("Enter a word: ");


Compared with
scanf("%19s", src); int i = 0;
while (src[i] != '\0') {
int i; dest[i] = src[i];
for (i = 0; src[i] != '\0'; i++) i++;
dest[i] = src[i]; }
dest[i] = '\0';
dest[i] = '\0';
printf("Content of dest = \"%s\"\n", dest);

return 0;
}
53
Copying a string (pointer version)
#include <stdio.h>

int main()
{
char src[20];
char dest[20] = "1234567890123456789";

printf("Enter a word: ");


Compared with
scanf("%19s", src); int i = 0;
while (src[i] != '\0') {
char *p = src, *q = dest; dest[i] = src[i];
while (*p != '\0') i++;
*p++ = *q++; }
*p = '\0';
dest[i] = '\0';
printf("Content of dest = \"%s\"\n", dest);

return 0;
}
54
Problem: concatenating two strings

• Move to the end of the destination string


• Have you seen a similar problem?
• Reuse the idea from counting string length
• Copy from the source string to the end of the destination string
• Have you seen a similar problem?
• Reuse the idea from copying a string
• It’s like the previous two problems combined

55
Concatenating two strings
char src[20];
char dest[25] = "12345";
Result:
Enter a word: Hello!
printf("Enter a word: "); Content of dest = "12345Hello!"
scanf("%19s", src);

int i = 0, j = 0;

// Move to the end of dest


while (dest[j] != '\0')
j++;

// Copy from src to dest


while (src[i] != '\0')
dest[j++] = src[i++];

dest[j] = '\0';

printf("Content of dest = \"%s\"\n", dest);


56
Concatenating two strings (pointer version)
char src[20];
char dest[25] = "12345";

printf("Enter a word: ");


scanf("%19s", src);

char *p = src, *q = dest;

// Move to the end of dest


while (*q != '\0')
q++;

// Copy from src to dest


while (*p != '\0')
*q++ = *p++;

*q = '\0';

printf("Content of dest = \"%s\"\n", dest);


57
C standard library already handles all these stuff

• We have library functions that do all these in string.h


• strlen(), strcpy(), strcat()

• We’ll talk more about them in the next lesson

58
That’s it for today!

59

You might also like