Arrays
Exercises
Question 8.1
We discussed using the expression sizeof(a) / sizeof(a[0]) to calculate the number of elements in an array. The expression sizeof(a) / sizeof(t), where t is the type of a's elements, would also work, but it's considered an inferior technique. Why?
- Answer
Using sizeof(a) / sizeof(a[0]) is used to get the total number of elements in the array. It does not consider the type into account when determing the length of the array, which makes it portable as well. But using sizeof(a) / sizeof(t), where t is the type of a's element is inferior as the code reader has to find the type of t in the code, and find the declaration of a to verify if the type of the two variables match, which makes readability more difficult.
Question 8.2
The Q&A section shows how to use a letter as an array subscript. Describe how to use a digit (in character form) as a subscript.
- Answer
We can do so using the following code fragment:
int number_count[10];
number_count[ch - '0'] = 10;
This considers that ch is a character variable, and given that ch lies in the range '0' to '9', which has the ASCII range of 48 (for '0') to 57 (for '9'), we can use it as an array subscript.
Question 8.3
Write a declaration of an array named weekend containing seven bool values. Include an initializer that makes the first and last values true; all other values should be false.
- Program
#include <stdio.h>
#include <stdbool.h>
int main (void) {
bool weekend[7] = {true, false, false, false, false, false, true};
for (int i = 0; i < ((int) (sizeof(weekend) / sizeof(weekend[0]))); i++) {
printf("index %d of array weekend has bool value (1 for true, 0 for false) %d\n", i, weekend[i]);
Question 8.4
(C99) Repeat Exercise 3, but this time use a designated initializer. Make the initializer as short as possible.
- Program
#include <stdio.h>
#include <stdbool.h>
int main (void) {
bool weekend[7] = {[0] = true, [6] = true};
for (int i = 0; i < ((int) (sizeof(weekend) / sizeof(weekend[0]))); i++) {
printf("index %d of array weekend has bool value (1 for true, 0 for false) %d\n", i, weekend[i]);
Question 8.5
The Fibonacci numbers are 0,1,1,2,3,5,8,13, ..., where each number is the sum of the two preceding numbers. Write a program fragment that declares an array named fib_numbers of length 40 and fills the array with the first 40 Fibonacci numbers. Hint: Fill in the first two numbers individually, then use a loop to compute the remaining numbers.
- Program
#include <stdio.h>
int main (void) {
int fib_numbers[40] = {[1] = 1};
for (int i = 0; i < ((int) (sizeof(fib_numbers) / sizeof(fib_numbers[0]))); i++) {
printf("Fibonacci number %d ", i+1);
if (i == 0 || i == 1) {
Question 8.6
Calculators, watches, and other electronic devices often rely on seven-segment displays for numerical output. To form a digit, such devices "turn on" some of the seven segments while leaving others "off":
_ _ _ _ _ _ _ _
| | | _| _| |_| |_ |_ | |_| |_|
|_| | |_ _| | _| |_| | |_| _|
Suppose that we want to set up an array that remembers which segments should be "on" for each digit. Let's number the segments as follows:
Here's what the array might look like, with each row representing one digit:
const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0}, ...};
I've given you the first row of the initializer; fill in the rest.
- Program
#include <stdio.h>
int main (void) {
const int segments[10][7] = {{1, 1, 1, 1, 1, 1, 0},
{0, 1, 1, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, 0, 0, 1},
{0, 1, 1, 0, 0, 1, 1},
Question 8.7
Using the shortcuts described in Section 8.2, shrink the initializer for the segments array (Exercise 6) as much as you can.
- Program
#include <stdio.h>
int main (void) {
const int segments[10][7] = {{1, 1, 1, 1, 1, 1},
{[1] = 1, [2] = 1},
{1, 1, 0, 1, 1, 0, 1},
{1, 1, 1, 1, [6] = 1},
{0, 1, 1, [5] = 1, 1},
Question 8.8
Write a declaration for a two-dimensional array named temperature_readings that stores one month of hourly temperature readings. (For simplicity, assume that a month has 30 days.) The rows of the array should represent days of the month; the columns should represent hours of the day.
- Program
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define OUTER_SIZE (int) (sizeof(temperature_readings) / sizeof(temperature_readings[0]))
#define INNER_SIZE (int) (sizeof(temperature_readings[0]) / sizeof(temperature_readings[0][0]))
int main (void) {
Question 8.9
Using the array of Exercise 8. write a program fragment that computes the average temperature for a month (averaged over all days of the month and all hours of the day).
- Program
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define OUTER_SIZE (int) (sizeof(temperature_readings) / sizeof(temperature_readings[0]))
#define INNER_SIZE (int) (sizeof(temperature_readings[0]) / sizeof(temperature_readings[0][0]))
int main (void) {
Question 8.10
Write a declaration for an 8 x 8 char array named chess_board. Include an initializer that puts the following data into the array (one character per array element):
r n b q k b n r
p p p p p p p p
. . . .
. . . .
. . . .
. . . .
P P P P P P P P
R N B Q K B N R
- Program
#include <stdio.h>
#define OUTER_SIZE (int) (sizeof(chess_board) / sizeof(chess_board[0]))
#define INNER_SIZE (int) (sizeof(chess_board[0]) / sizeof(chess_board[0][0]))
int main (void) {
char chess_board[8][8] = {{'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'},
{'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'},
Question 8.11
Write a program fragment that declares an 8 x 8 char array named checker_board and then uses a loop to store the following data into the array (one character per array element):
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
B R B R B R B R
R B R B R B R B
Hint: The element in row i, column j, should be the letter B if i + j is an even number.
- Program
#include <stdio.h>
#define OUTER_SIZE (int) (sizeof(checker_board) / sizeof(checker_board[0]))
#define INNER_SIZE (int) (sizeof(checker_board[0]) / sizeof(checker_board[0][0]))
int main (void) {
char checker_board[8][8];
Programming Projects
Project 8.1
Modify the repdigit.c program of Section 8.1 so that it shows which digits (if any) were repeated:
Enter a number: 939577
Repeated digit(s): 7 9
- Program
#include <stdio.h>
#include <stdbool.h>
int main (void) {
int digit;
long n;
bool digit_seen[10] = {false};
bool repeated_digits[10] = {false};
Project 8.2
Modify the repdigit.c program of Section 8.1 so that it prints a table showing how many times each digit appears in the number:
Enter a number: 41271092
Digit:Occurrences: | 01 | 12 | 22 | 30 | 41 | 50 | 60 | 71 | 80 | 91 |
- Program
#include <stdio.h>
#include <stdbool.h>
int main (void) {
int digit;
long n;
int digit_count[10] = {0};
Project 8.3
Modify the repdigit.c program of Section 8.1 so that the user can enter more than one number to be tested for repeated digits. The program should terminate when the user enters a number that's less than or equal to 0.
- Program
#include <stdio.h>
int main (void) {
long n, temp;
int digit;
int digit_count[10] = {0};
for (;;) {
Project 8.4
Modify the reverse.c program of Section 8.1 to use the expression (int) (sizeof(a) /sizeof(a[0])) (or a macro with this value) for the array length.
- Program
#include <stdio.h>
#define N 10
#define SIZE (int) (sizeof(num) / sizeof(num[0]))
int main (void) {
int num[N] = {0};
Project 8.5
Modify the interest.c program of Section 8.1 so that it compounds interest monthly instead of annually. The form of the output shouldn't change: the balance should still be shown at annual intervals.
- Program
#include <stdio.h>
#include <strings.h>
#define NUM_RATES (int) (sizeof(amount_after_interest) / sizeof(amount_after_interest[0]))
int main (void) {
int interest_rate;
int number_of_years;
Project 8.6
The prototypical Internet newbie is a fellow named B1FF, who has a unique way of writing messages. Here's a typical B1FF communiqué.
H3Y DUD3, C 15 R1LLY COOL!!!!!!!!!!
Write a "B1FF filter" that reads a message entered by the user and translates it into B1FF- speak:
Enter message: Hey dude, C is rilly cool
In B1FF-speak: H3Y DUD3, C 15 RILLY CO0L!!!!!!!!!!
Your program should convert the message to upper-case letters, substitute digits for certain letters(A→4, B→8, E→3, I→1, O→0, S→5), and then append 10 or so exclamation marks.
Hint: Store the original message in an array of characters, then go back through the array, translating and printing characters one by one.
- Program
#include <stdio.h>
#include <ctype.h>
#define MSG_LENGTH 100
int main (void) {
int i = 0, j = 0;
char ch;
Project 8.7
Write a program that reads a 5 x 5 array of integers and then prints the row sums and the column sums:
Enter row 1: 8 3 9 0 10
Enter row 2: 3 5 17 1 1
Enter row 3: 2 8 6 23 1
Enter row 4: 15 7 3 2 9
Enter row 5: 6 14 2 6 0
Row totals: 30 27 40 36 28
Column totals: 34 37 37 32 21
- Program
#include <stdio.h>
#define COL_SIZE 5
#define ROW_SIZE 5
int main (void) {
int arr_mat[ROW_SIZE][COL_SIZE] = {0};
int row_total[ROW_SIZE] = {0};
Project 8.8
Modify Programming Project 7 so that it prompts for five quiz grades for each of five students, then computes the total score and average score for each student, and the average score, high score, and low score for each quiz.
- Program
#include <stdio.h>
#define QUIZ_SIZE 5
#define STUDENT_SIZE 5
int main (void) {
int arr_mat[STUDENT_SIZE][QUIZ_SIZE] = {0};
int student_total[STUDENT_SIZE] = {0};
Project 8.9
Write a program that generates a "random walk" across a 10 x 10 array. The array will contain characters (all ' . ' initially). The program must randomly "walk" from element to element, always going up, down, left, or right by one element. The elements visited by the program will be labeled with the letters A through Z, in the order visited. Here's an example of the desired output:
A . . . . . . . . .
B C D . . . . . . .
. F E . . . . . . .
H G . . . . . . . .
I . . . . . . . . .
J . . . . . . . Z .
K . . R S T U V Y .
L M P Q . . . W X .
. N O . . . . . . .
. . . . . . . . . .
Hint: Use the srand and rand functions (see deal.c) to generate random numbers. After generating a number, look at its remainder when divided by 4. There are four possible values for the remainder — 0, 1, 2, and 3 — indicating the direction of the next move. Before performing a move, check that (a) it won't go outside the array, and (b) it doesn't take us to an element that already has a letter assigned. If either condition is violated, try moving in another direction. If all four directions are blocked, the program must terminate. Here's an example of premature termination:
A B G H I . . . . .
. C F . J K . . . .
. D E . M L . . . .
. . . . N O . . . .
. . W X Y P Q . . .
. . V U T S R . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Y is blocked on all four sides, so there's no place to put Z.
- Program
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#define ROW_SIZE 10
#define COL_SIZE 10
int main (void) {
Project 8.10
Modify Programming Project 8 from Chapter 5 so that the departure times are stored in an array and the arrival times are stored in a second array. (The times are integers, representing the number of minutes since midnight.) The program will use a loop to search the array of departure times for the one closest to the time entered by the user.
- Program
#include <stdio.h>
int main (void) {
// store the departure time
int departure_time[8] = {8*60, 9*60+43, 11*60+19, 12*60+47, 14*60, 3*60+45, 19*60, 21*60+45};
// store the arrival time
int arrival_time[8] = {10*60+16, 11*60+52, 13*60+31, 15*60, 16*60+8, 17*60+55, 21*60+20, 23*60+58};
Project 8.11
Modify Programming Project 4 from Chapter 7 so that the program labels its output:
Enter phone number: 1-800-CQL-LECT
In numeric form: 1-800-265-5328
The program will need to store the phone number (either in its original form or in its numeric form) in an array of characters until it can be printed. You may assume that the phone number is no more than 15 characters long.
- Program
#include <stdio.h>
#include <ctype.h>
#define NUM_LENGTH 15
int main (void) {
// store the original number entered by the user
char original_number[NUM_LENGTH];
Project 8.12
Modify Programming Project 5 from Chapter 7 so that the SCRABBLE values of the letters are stored in an array. The array will have 26 elements, corresponding to the 26 letters of the alphabet. For example, element 0 of the array will store 1 (because the SCRABBLE value of the letter A is 1). element 1 of the array will store 3 (because the SCRABBLE value of the letter B is 3), and so forth. As each character of the input word is read, the program will use the array to determine the SCRABBLE value of that character. Use an array initializer to set up the array.
- Program
#include <stdio.h>
#include <ctype.h>
int main (void) {
// store the scrabble value of each alphabet
int scrabble_value[26] = {1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10};
char ch;
int scrabble_total = 0;
Project 8.13
Modify Programming Project 11 from Chapter 7 so that the program labels its output:
Enter a first and last name: Lloyd Fosdick
You entered the name: Fosdick, L.
The program will need to store the last name (but not the first name) in an array of characters until it can be printed. You may assume that the last name is no more than 20 characters long.
- Program
#include <stdio.h>
#define LAST_NAME_SIZE 20
int main (void) {
char ch;
char first_initial;
char last_name[LAST_NAME_SIZE];
Project 8.14
Write a program that reverses the words in a sentence:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you can't swallow a cage can you?
Hint: Use a loop to read the characters one by one and store them in a one-dimensional char array. Have the loop stop at a period, question mark, or exclamation point (the "terminating character"), which is saved in a separate char variable. Then use a second loop to search backward through the array for the beginning of the last word. Print the last word, then search backward for the next-to-last word. Repeat until the beginning of the array is reached. Finally, print the terminating character.
- Program
#include <stdio.h>
#define SENTENCE_SIZE 50
int main (void) {
char original_sentence[SENTENCE_SIZE];
char terminating_char;
char ch;
Project 8.15
One of the oldest known encryption techniques is the Caesar cipher, attributed to Julius Caesar. It involves replacing each letter in a message with another letter that is a fixed number of positions later in the alphabet. (If the replacement would go past the letter Z, the cipher "wraps around" to the beginning of the alphabet. For example, if each letter is replaced by the letter two positions after it. then Y would be replaced by A. and Z would be replaced by B.) Write a program that encrypts a message using a Caesar cipher. The user will enter the message to be encrypted and the shift amount (the number of positions by which letters should be shifted):
Enter message to be encrypted: Go ahead, make my day.
Enter shift amount (1-25): 3
Encrypted message: Jr dkhdg, pdnh pb gdb.
Notice that the program can decrypt a message if the user enters 26 minus the original key:
Enter message to be encrypted: Jr dkhdg, pdnh pb gdb.
Enter shift amount (1-25) : 23
Encrypted message: Go ahead, make my day.
You may assume that the message does not exceed 80 characters. Characters other than letters should be left unchanged. Lower-case letters remain lower-case when encrypted, and upper-case letters remain upper-case. Hint: To handle the wrap-around problem, use the expression ((ch - 'A') + n) % 26 + 'A' to calculate the encrypted version of an upper-case letter, where ch stores the letter and n stores the shift amount. (You'll need a similar expression for lower-case letters.)
- Program
#include <stdio.h>
#define MSG_LENGTH 80
int main (void) {
char ch;
char original_message[MSG_LENGTH];
char encrypted_message[MSG_LENGTH];
Project 8.16
Write a program that tests whether two words are anagrams (permutations of the same letters):
Enter first word: smartest
Enter second word: mattress
The words are anagrams.
Enter first word: dumbest
Enter second word: stumble
The words are not anagrams.
Write a loop that reads the first word, character by character, using an array of 26 integers to keep track of how many times each letter has been seen. (For example, after the word smelliest has been read, the array should contain the values 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 2 2 0 0 0 0 0 0, reflecting the fact that smartest contains one a, one e, one m, one r, two s's and two t's.) Use another loop to read the second word, except this time decrementing the corresponding array element as each letter is read. Both loops should ignore any characters that aren't letters, and both should treat upper-case letters in the same way as lower-case letters. After the second word has been read, use a third loop to check whether all the elements in the array are zero. If so. the words are anagrams. Hint: You may wish to use functions from <ctype.h>, such as isalpha and tolower.
- Program
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main (void) {
char ch;
int letter_count_track[26] = {0};
Project 8.17
Write a program that prints an n x n magic square (a square arrangement of the numbers 1, 2, ...., n2 in which the sums of the rows, columns, and diagonals are all the same). The user will specify the value of n:
This program creates a magic square of a specified size.
The size must be an odd number between 1 and 99.
Enter size of magic square: 5
172341011 | 24561218 | 17131925 | 81420212 | 15162239 |
Store the magic square in a two-dimensional array. Start by placing the number 1 in the middle of row 0. Place each of the remaining numbers 2, 3, .... n2 by moving up one row and over one column. Any attempt to go outside the bounds of the array should "wrap around" to the opposite side of the array. For example, instead of storing the next number in row - 1, we would store it in row n - 1(the last row). Instead of storing the next number in column n, we would store it in column 0. If a particular array element is already occupied, put the number directly below the previously stored number. If your compiler supports variable-length arrays, declare the array to have n rows and n columns. If not, declare the array to have 99 rows and 99 columns.
- Program
#include <stdio.h>
#include <stdbool.h>
int main (void) {
int square_size;
int current_row = 0;
int current_col = 0;