1 of 39

Arrays, Strings, and Pointers

03603111 Programming Fundamentals I

Department of Computer Engineering, Faculty of Engineering at Sriracha

2 of 39

Course outline and schedule

  • L01 Introduction
  • L02 Data and I/O
  • L03 Conditionals
  • L04 Loops
  • L05 Arrays, strings, and pointers (today!)
  • 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 39

Overview

  • The for loop
  • Arrays
  • Strings
  • Pointers
  • Pointer arithmetic

3

4 of 39

Previous lesson recaps

4

5 of 39

while loop – check first, then act

#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;

}

5

Condition

Statement(s)

False

True

6 of 39

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

6

CODING PATTERN

PATTERN NAME

7 of 39

Simple Loop Invariant

This is a simple 4-step recipe to use loop invariants that works well for problems with a single-value result that can be derived directly from a list of items

  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

However, this is not the only way to use loop invariants, but it’s a simple way to start

7

CODING RECIPE

RECIPE NAME

8 of 39

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)

8

9 of 39

do … while loop – act first, then check

#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;

}

9

Condition

Statement(s)

False

True

10 of 39

The for loop

11 of 39

Convenient counter-controlled style for loop

  • This while loop pattern is used often

initialize;

while (condition) {

statement(s);

step;

}

  • But it’s more concise to use for loop for this pattern

for (initialize; condition; step)

statement

11

1

2

4

3

1

2

4

3

True

False

12 of 39

Factorial of 10 (for loop version)

#include <stdio.h>

int main()

{

int n = 10;

int fact = 1;

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

fact *= i;

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

return 0;

}

12

int i = 1;

while (i <= n) {

fact *= i;

i++;

}

Compared with

13 of 39

Scope of the counter variable

  • The for loop here:

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

fact *= i;

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

  • There is a compilation error – variables declared inside the for loop are not available outside it
  • ͏Scope is the region of code where a variable is accessible
  • In this case, i has a local scope inside the for loop only
  • If we move the declaration out:

int i;

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

fact *= i;

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

  • It will now compile, because the variable is declared outside the for loop
  • Here, the scope of i is outside the loop, so it is now accessible to printf()

13

14 of 39

When to use which?

  • Prefer while for conditional loops in general

  • Prefer for when you want a counter-controlled loop or when you’re working with a list of items

  • Use do … while when either 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

  • These are general guidelines, not rules – use whatever that works best for your specific situations!

14

15 of 39

Arrays

16 of 39

Problem: Counting integers equal or above the average

  • Given a list of n integers, count items whose value is equal to or above average
  • Let’s U-SWACT it together!
    • UNDERSTAND: Take a minute to understand the problem first
      • What are the inputs?
      • What is the expected output?
      • What’s missing here? – we need to know the average before we can count!
    • SAMPLE INPUTS: Create some sample inputs
      • We need a few, but let’s try: 7 5 3 4 2
    • WORK OUT: This is quite simple – try it!
      • Remember to work through the list one at a time

UNDERSTAND

SAMPLE INPUTS

WORK OUT

ALGORITHM

CODE

TEST

17 of 39

Help! We’re stuck!

  • ALGORITHM: So far so good, so we need to find an average then count the elements
    • But how do we go back and count the elements we’ve read?
    • We need something to hold the values of multiple elements!
    • This is what we call an array

  • There are a few things we need to solve first
    • How do we read user inputs into an array?
    • How do we sum an array so we can compute the average?
    • How do we go through and check each element in the array if it’s qualified for a condition?

17

18 of 39

Arrays

  • 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 };

18

Value

5

3

1

2

4

10

7

4

6

11

Index

0

1

2

3

4

5

6

7

8

9

19 of 39

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];

arr[0] = 1;

arr[1] = arr[0] + 2;

arr[arr[0] + 1] = arr[0] + arr[1];

19

Value

1

3

4

Index

0

1

2

20 of 39

Reading user inputs into an array

  • Using Repeat N Times, we perform scanf() for each element

int main()

{

int scores[10];

// Read user inputs into array

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

scanf("%d", &scores[i]); // array elements need &

// Do other stuff ...

}

20

21 of 39

Sum of the array

#include <stdio.h>

int main()

{

int arr[] = { 3, 4, 2, 0, 1 };

int num_elems = 5;

int sum = 0;

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

sum += arr[i];

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

return 0;

}

21

Sum = 10

Result:

22 of 39

Solution: Counting integers equal or above the average

int elems[MAX_ELEMS];

int num_elems;

scanf("%d", &num_elems);

int sum = 0;

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

scanf("%d", &elems[i]);

sum += elems[i];

}

float average = (float)sum / num_elems;

int count = 0;

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

if (elems[i] >= average) {

count++;

}

}

printf("Count of elements above %.2f: %d\n", average, count);

22

5

7 5 3 4 2

Count of elements above 4.20: 2

Result:

Mixing data types require casting, otherwise our answer will be wrong

23 of 39

Example: Finding the maximum

#define MAX_LEN 100

int main()

{

int scores[MAX_LEN]; // pre-allocated size must be large enough

int num_scores;

// Read number of inputs

scanf("%d", &num_scores);

// Read user inputs into array

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

scanf("%d", &scores[i]); // array elements need &

// 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);

}

23

5�5 7 2 9 6

Max = 9

Result:

24 of 39

Example: Searching for an element

int elems[] = { 6, 1, 3, 0, 9, 4, 2 };

int target;

int pos = -1;

printf("Enter a number to search: ");

scanf("%d", &target);

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

if (elems[i] == target) {

pos = i;

break;

}

}

if (pos != -1) {

printf("Found %d at position %d\n", target, pos);

} else {

printf("%d not found in the array\n", target);

}

24

Enter a number to search: 9

Found 9 at position 4

// Re-run

Enter a number to search: 5

5 not found in the array

Result:

25 of 39

Memory addresses and pointers

26 of 39

Variables, memory, and addresses

26

Address

Memory

Variable

0xBC04

A0

exp

0xBC05

86

0xBC06

01

0xBC07

00

0xBC08

42

name

0xBC09

65

0xBC0A

63

0xBC0B

6B

0xBC0C

00

0xBC0D

00

0xBC0E

00

0xBC0F

00

0xBC10

04

ptr

0xBC11

BC

  • Variables are stored in memory
  • Memory is a collection of byte-addressable cells

int exp = 100000; // 0x186A0

char name[8] = "Beck"; // 0x42 0x65 0x63 0x6B 0x00

int *ptr = &exp; // 0xBC04

  • ͏Pointers are variables that store addresses – they point to data stored in memory
  • Note that actual in-memory ordering of variables is not guaranteed to be the same as the declaration order

27 of 39

Pointers

  • Pointer variable declaration: type *name;

int *ptr;

  • Address of” operator (&) is used to obtain the address of a variable

ptr = &exp;

  • Array and string variable names already represent their memory addresses by themselves – we can get their addresses directly without using & operator just by referring their names

  • 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

27

28 of 39

Pointers in action

int arr[] = { 3, 4, 2, 0, 1 };

int *ptr = arr;

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!

28

Value at 00000000005FFE80 = 3

Value at 00000000005FFE84 = 4

Value at 00000000005FFE88 = 2

Value at 00000000005FFE8C = 0

Value at 00000000005FFE90 = 1

Address of the pointer = 00000000005FFE78

Result:

29 of 39

Strings

29

30 of 39

Greeting with “strings”

#include <stdio.h>

int main()

{

char name[50];

char surname[50];

int age;

printf("Enter your name: ");

scanf("%s", name);

printf("Enter your surname: ");

scanf("%49s", surname);

printf("Enter your age: ");

scanf("%d", &age);

printf("Hi %s %s, you are %d years old!\n", name, surname, age);

}

30

Enter your name: John

Enter your surname: Doe

Enter your age: 25

Hi John Doe, you are 25 years old!

Result:

C strings are arrays of char

Use %s to read a string (word)

Note that string variables do not have an & in front of them

Also, use %s to print strings

String reading can be length-limited

31 of 39

C uses 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 the value 0

  • Null-terminated strings are not used in most other languages
    • C++ and Java which have a native string type, although C++ also supports null-terminated strings

31

32 of 39

Null-terminated strings

char text[10] = "Hello!";

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

32

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

Address

0xA10B

0xA10C

0xA10D

0xA10E

0xA10F

0xA110

0xA111

0xA112

0xA113

0xA114

0xA115

0xA116

33 of 39

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

33

34 of 39

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?

  • Think again: What is the last character in every string?
    • It’s the null character ('\0’)

  • Can we use the Simple Loop Invariant recipe?
  • Let’s try!
  • Result Variable: We name it count
    • Invariant: count is always the length of the string we’ve seen so far
  • Initialization: Before the loop, we haven’t seen any character yet, so we initialize count to zero
  • Maintenance: At the end of each iteration, we’ve seen one more character, so we count up by one
  • Termination: How (and when) do we terminate?
    • Terminating condition is different from the Repeat N Times pattern!

  • So, how should we end this loop?
  • What’s the terminating condition?

34

35 of 39

Solution: Counting string length

#include <stdio.h>

int main()

{

char str[20];

printf("Enter a word: ");

scanf("%19s", str);

� int count = 0;

while (str[count] != '\0')

count++;

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

return 0;

}

35

Enter a word: Hello!

Length of "Hello!" = 6

Result

36 of 39

Convenient function for string length

  • Getting the length of a string is a very common operation
  • C provides a library function for this operation in string.h
    • The function is strlen(s)
    • You’ll need to #include <string.h> to use it

  • Common usage pattern:

for (int i = 0; i < strlen(s); i++) {

// Do something

}

36

37 of 39

Problem: Find and replace characters

  • Given a string s, a character c we want to look for, and a character d to replace it, find all occurrences of c in s, and replace them with d

  • We now know how to loop from the first character to the last

37

38 of 39

Solution: Find and replace characters

char str[50];

char src;

char dest;

printf("Enter a string: ");

fgets(str, sizeof(str), stdin);

printf("Enter character to replace: ");

scanf(" %c", &src);

printf("Enter replacement character: ");

scanf(" %c", &dest);

int i = 0;

while (str[i] != '\0') {

if (str[i] == src) {

str[i] = dest;

}

i++;

}

printf("Modified string: %s\n", str)

38

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

if (str[i] == src) {

str[i] = dest;

}

}

With for loop

39 of 39

That’s all for today!

39