Lab: Multi-Dimensional Arrays

Summary: In today's laboratory, we explore issues pertaining to mutli-dimensional arrays.

Contents:

Preparation

a. Create a directory for this lab.

b. Add the standard Makefile to that directory. (Note that the `-Wall` flag will give you warnings for some of the code we provide. You can safely ignore some of the warnings.) Now that you know how to use the debugger, you might want to add -g to `CFLAGS`.

Exercises

Exercise 1: Initializing Multi-Dimensional Arrays

Here is a sample initialization of a one-dimensional array of integers.

```int ant[5] = { 5, 2, 7, 3, 4 };
```

Figure out how to initialize the two-dimensional array `bat` so that the row zero contains 8, 16, 32, and 64; row one contains 5, 7, 9, and 11; and row two contains 0, 1, 2, 3.

```int bat[3][4] = figure-this-out;
```

You can print out your array with

```  printf ("Row 0: %d, %d, %d, %d\n",
bat[0][0], bat[0][1], bat[0][2], bat[0][3]);
printf ("Row 1: %d, %d, %d, %d\n",
bat[1][0], bat[1][1], bat[1][2], bat[1][3]);
printf ("Row 2: %d, %d, %d, %d\n",
bat[2][0], bat[2][1], bat[2][2], bat[2][3]);
```

Exercise 2: Multi-Dimensional Arrays as Single-Dimensional Arrays

Suppose we've declared `bat` as above and `cow` and `i` as follows:

```int *cow;
int i;
```

a. What do you expect the effect of the following code to be?

```  cow = (int *) bat;
for (i = 0; i < 12; i++) {
printf("cow[%d]: %d\n", i, cow[i]);
} // for
```

c. Consider why we might have gotten these results.

Exercise 3: Bounds Violations in Multi-Dimensional Arrays

Consider again the declaration of `bat` above.

a. What values do you expect to get for the following?

```  printf ("bat[0][4] = %d\n", bat[0][4]);
printf ("bat[0][7] = %d\n", bat[0][7]);
printf ("bat[1][7] = %d\n", bat[1][7]);
printf ("bat[2][4] = %d\n", bat[2][4]);
printf ("bat[2][-1] = %d\n", bat[2][-1]);
```

c. Consider why you got those results.

Exercise 4: Printing Cells, Revisited

You may have noted a bit of repetition in the code for the previous problem. As you might expect, that repetition is dangerous, because we might mistype something, as in

```  printf ("bat[2][4] = %d\n", bat[2][5]);
```

How do we avoid that problem? Ideally, we'd use a function. However, functions in C can't treat something as both a string (e.g., `"bat[2][4]"`) and a value (e.g., `bat[2][4]`). Fortunately, macros can.

Consider the following macro

```#define PRINT_INT_CELL(CELL) printf ("%s: %d\n", #CELL, CELL);
```

b. Replace the first call to `printf` with a call to `PRINT_INT_CELL`.

```  PRINT_INT_CELL (bat[0][4]);
```

c. Using `cc -E` (run the prEprocessor), find out what `PRINT_INT_CELL` expands to.

d. Replace all of the calls to `printf` with calls to `PRINT_INT_CELL`. Then compile your program and make sure that it works in the same way.

Exercise 5: Declarations, Revisited

Consider the following code.

```  int rabbit[2][3] = { 1, 2, 3, 4, 5, 6 };
int r, c;

for (r = 0; r < 2; r++)
for (c = 0; c < 3; c++)
printf ("rabbit[%d,%d] = %d\n", r, c, rabbit[r][c]);
```

a. What do you expect to happen when you try to compile this code?

c. What do you expect to happen when you try to run this code?

Exercise 6: Partial Specifications

We have been specifying our two-dimensional arrays by giving both the number of rows and the number of columns. However, K&R suggest that one can elide the number of rows. For example, consider the following example from section 5.9.

```char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };
```

a. Verify that our compiler permits the declaration with neither errors nor warnings.

b. What do you expect the results of the following to be?

```#define PRINT_CHAR_CELL(CELL) printf ("%s = '%c' (%d)\n", #CELL, CELL, CELL);
// ...
PRINT_CHAR_CELL(aname[0][0]);
PRINT_CHAR_CELL(aname[0][1]);
PRINT_CHAR_CELL(aname[0][2]);
PRINT_CHAR_CELL(aname[1][0]);
PRINT_CHAR_CELL(aname[2][0]);
```

d. What do you expect the size of `aname` to be?

f. What do you expect the results of the following to be?

```  PRINT_CHAR_CELL(aname[1][0]);
PRINT_CHAR_CELL(aname[1][1]);
PRINT_CHAR_CELL(aname[1][2]);
PRINT_CHAR_CELL(aname[1][3]);
```

h. What do your results suggest about what has happened in the declaration?

Exercise 7: Three-Dimensional Arrays

Consider the following declaration of a three-dimensional array:

```int chinchilla[2][3][4];
```

a. How many elements does `chinchilla` have?

b. Check your answer with `sizeof`.

c. Can one initialize `chincilla` while declaring it?

e. Where in memory is `chinchilla[i][j][k]` relative to `chinchilla[0][0][0]`?

For Those with Extra Time

Extra 1: Printing Arrays

a. Suppose `a` is a NxM array. Write instructions for printing `a` as a grid. For example, for `rabbit` above, we might print

```  1  2  3
4  5  6
```

Note: You are simply writing code, not a function. (Functions are hard to write for this because you need to specify the size in the parameter.)

b. Rewrite your code to work with `rabbit`.

c. Rewrite your code to work with `bat`.

Extra 2: Printing Arrays, Revisited

Write a function, `printIntMatrix (int rows, int cols, int matrix[rows][cols])`, that prints a matrix as in the previous exercise.

History

Monday, 17 February 2003 [Samuel A. Rebelsky]

Tuesday, 2 November 2010 [Samuel A. Rebelsky]

Tuesday, 12 April 2011 [Samuel A. Rebelsky]

• Updated for CSC 161 2011S.
• Moved printing problem to the extras section.
This document may be found at `http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2011S/Labs/multi-arrays-lab.html`.