CSC 161 Grinnell College Fall, 2011
 
Imperative Problem Solving and Data Structures
 
 

Laboratory Exercise on Two Dimensional Arrays

Two Dimensional Arrays

Introduction

In C, [one-dimensional] arrays provide a mechanism to access a sequence of data using a single index, such as item[0], item[1], item[2], .... Similarly, C supports the organization of data in a table by specifying a row and a column:

2 dimensional array

As with one-dimensional arrays, two-dimensional arrays can contain data of any type, although each entry in a table must have the same type. Also, the size of a two-dimensional array must be declared when it is first defined:

   int table [5][10];

When using a two-dimensional array as a parameter, the declaration of a procedure header must know the number of columns in the table (so the computer knows when one row stops and the next starts). As with 1-dimensional arrays, a procedure header does not need to specify the number of rows in the table. Thus, if the above table were passed to a printArray procedure, the header of printArray might be given as follows:

   void printArray (int arr[][10])

The sample program 2D-array-with-proc.c shows a 2-dimensional array declared in main and passed to a printArray procedure.

Altogether, two dimensional arrays are a wonderful way to store lots of data which would normally require lots of arrays!

Initial Experiments

  1. Copy the program 2D-array.c and look over the various array declarations.

    1. Which array declarations are invalid? Write a sentence explaining why they are invalid and test to see whether they compile. Once you are sure which are invalid, comment them out of your program.

    2. How many elements does each array hold?

    3. Write loops to display the contents of each array. You should use seperate nested for loops for each array.

    4. Check whether you were correct on how many elements each array holds.

    5. Add another array, array6[][], which has the numbers (0, 1, 2, 3) in the first row, (2, 4, 6, 8) in the second row, and (3, 6, 9, 12) in the third row. Display the array once you have declared and initialized it.

2D Arrays in Songs

  1. Recall the program array-move.c. While this program is nice, we could make it even more concise with two dimensional arrays!

    1. Write an array of motion structures (which store a speed and a time) and perform the motions by looping through the structs.

    2. What would the size of a two dimensional array which stores both the speed and the time of each motion have to be?

    3. Write a two dimensional double array to store all of the motions. Then perform all of the motions with a loop.

    4. Write a few sentences discussing the merits and potential hazards of using the structs method and 2D arrays method.

Transforming Pictures

Pictures are same as two dimensional arrays of Pixels in many ways. One major similarity is that you can iterate through them in much the same way you would iterate through a 2D Pixel array.

  1. Write a function, void colorToGray (Picture * pic), which takes in a Picture * and then converts each pixel to its grayscale value. A grayscale pixel is a pixel where the RGB are all set to 30% of the red value + 59% of the green value + 11% of the blue value (source: wikipedia.org/Grayscale). Your function should then display the Picture. Test this out on a few pictures you take with your robot.

  2. Write a function, void setPictureMax (Picture * pic), which finds what the highest of the RGB of each pixel is and sets that pixel to just that value (e.g. a pixel of RGB (50,135,85) will have a new RGB of (0,255,0)). Your function should then display the Picture. Test this out on a few pictures you take with your robot.

Declarations, Revisited

The following exercise is from Samuel Rebelsky's lab on multi-dimensional arrays: multi-dimensional arrays

  1. 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]);
    1. What do you expect to happen when you try to compile this code inside of a main() method?

    2. Check your answer experimentally.

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

    4. Check your answer experimentally.

  2. Now replace your display loops with the following code:

    for (c = 0; c < 3; c++)
     for (r = 0; r < 2; r++)
      printf ("rabbit[%d,%d] = %d\n", r, c, rabbit[r][c]);
    1. What do you expect to happen when you try to run this code?

    2. Check your answer experimentally.

    What is going on here is that two dimensional arrays are actually stored in memory as single dimensional arrays, laid out row after row. There are some cool things which you can do with this, such as putting a Picture * into a two dimensional Pixel array with a function that treats the Pixel[][] array as a single dimensional Pixel array. You will see this in the next exercise.

Transforming Pixel Arrays

    1. Read over the following code which puts a Picture * into a Pixel[][] array:

      /* Precondition: Pixel * pixArray is a two dimensional array of size
      [rGetPictureHeight (pic)][rGetPictureWidth (pic)] */
      
      void
      picToPixArray (Picture * pic, Pixel * pixArray)
      {
        int i, j;
        int width = rGetPictureWidth (pic);
        int height = rGetPictureHeight (pic);
      
        for (i = 0; i < height; i++)
          for (j = 0; j < width; j++)
            *(pixArray + (i * width) + j) = rGetPicturePixel (pic, j, i);
      } // picToPixArray
    2. Now read over the following code which puts a Pixel[][] array back into a Picture *:

      /* Precondition: Pixel * pixArray is a two dimensional array of size
      [rGetPictureHeight (pic)][rGetPictureWidth (pic)] */
      
      void
      pixArrayToPic (Picture * pic, Pixel *pixArray)
      {
        int i, j;
        int width = rGetPictureWidth (pic);
        int height = rGetPictureHeight (pic);
      
        for (i = 0; i < height; i++)
          for (j = 0; j < width; j++)
            rSetPicturePixel (pic, j, i, *(pixArray + j + i * width));
      } // pixArrayToPic
    3. Test this out on a few pictures taken with the robot. Make sure you dereference picArray when calling these functions.

  1. Use the code to put a Picture * into a two dimensional array and then flip the picture upside down. Then put the array back into the picture and display it. Test this on a few pictures you take with the robot.

For those with extra time

Two dimensional arrays are fine and dandy, but C supports moving up to even higher dimensions of arrays!

  1. Write a function which takes in an array of Pictures taken by the robot and stores them in a three dimensional array of Pixels.

  2. Write a function which takes in a three dimensional array of Pixels and modifies the Pixels in some way.

  3. Write a function which turns a 3D array of Pixels into a single dimensional array of Picture *s. You should then display these pictures.

Reminder: Complete Evaluation Form

When you have finished this lab, be sure to fill out its evaluation form in the "Lab Evaluation" section for CSC 161 on Pioneer Web.