Skip to content

Handout: Lecture 4 In-Class Exercises

Today is all at the keyboard. Part A is integer arrays; Part B is strings (arrays of char). These are the building blocks for HW1 - Build Your Own String Library, released today - but none of them is an HW1 function. They drill the underlying moves (walking to the '\0', char arithmetic, using a letter as an index) so HW1 is a matter of combining tools you have already used.

Try each one yourself first; we will discuss in class, and the solutions are in a separate document afterward. Compile with warnings on:

clang -Wall -Wextra -std=c17 myprog.c -o myprog

Reminders that will keep you out of trouble today:

  • Array indices run 0 to n - 1. There is no bounds checking - stepping outside that range is undefined behavior.
  • A string is a char array ending in '\0'. Loop until you hit the '\0'; you do not need to know the length up front.
  • A char is a small integer (ASCII): 'A' is 65, 'a' is 97, and they differ by 32. You may use <stdio.h>, but solve the character logic yourself (no <ctype.h>) - that is the HW1 mindset.

Set up

mkdir -p ~/cmsc14300/lec04
cd ~/cmsc14300/lec04

Part A - Integer arrays

Exercise A1 - Largest and smallest

Read (or hard-code) an array of integers and print the largest and smallest value, found in a single pass.

int a[] = {42, 17, 99, 3, 56, 8};
int n = 6;                 /* six values, so n is 6 */

largest:  99
smallest: 3
- Stretch: also report the index at which the largest value occurs.

Exercise A2 - A sum function (and an average)

Write a function that sums an integer array, then one that averages it.

int    sum(int a[], int n);        /* total of the n elements      */
double average(int a[], int n);    /* mean as a real number        */
  • average should reuse sum. Mind the Lecture 3 integer-division trap: to get a real average you must convert to floating point, e.g. (double) sum(a, n) / n.
  • Notice you must pass n in: the function receives only a reference to where the array starts, with no way to recover the count from a itself.
sum:     225
average: 37.50
  • Stretch: split this across stats.c / stats.h / main.c and build it with a Makefile, the way we did in Lecture 2.

Part B - Strings

Exercise B1 - Count uppercase and lowercase

Read a word and count how many characters are uppercase letters and how many are lowercase letters.

  • Read a single word with scanf("%s", word); - it stops at the first space.
  • Walk the string until '\0'. For each character, use the range tests c >= 'A' && c <= 'Z' and c >= 'a' && c <= 'z'.
Enter a word: HelloWorld
uppercase: 2
lowercase: 8
  • Stretch: also count digits (c >= '0' && c <= '9') and "other" characters, and check that the four counts add up to the word length.

Exercise B2 - Redact the letters (modify in place)

Read a word and overwrite every letter with a #, leaving digits and punctuation untouched, then print the result. The point is writing back into the same array - word[i] = '#'; - while you walk it.

  • Test for a letter with the two range checks from B1, joined by ||.
  • This is the in-place transform shape you will reuse all over HW1 (case conversion, the cipher): walk the string, decide per character, and assign back. Here the decision is trivial on purpose so you can focus on the mechanics.
Enter a word: abc123XYZ!
redacted:     ###123###!
  • Test the awkward cases: a word of only punctuation and a word with no letters at all.

Stretch - take it further

These drill three moves HW1 leans on - using a letter as an array index, searching a string, and scanning an array for a maximum - without being HW1 functions themselves.

  1. Letter-frequency histogram. Read a word and count how many times each letter a-z appears, case-insensitively, using an int counts[26] indexed by c - 'a'. Print only the letters that actually occur. The c - 'a' trick that turns a letter into a 0..25 index is exactly the mapping the HW1 cipher uses.
  2. Find a character. Write int index_of(char s[], char target) that returns the index of the first occurrence of target, or -1 if it is not present. A plain walk that returns early - the search shape behind many string routines.
  3. Most common letter. Extend exercise 1: after filling counts, scan those 26 numbers (the way A1 scanned for a maximum) and report which letter appears most often.