Arrays
The goal of this lab is to introduce arrays as data structures and as parameters to functions.
An array is used to arrange data in memory. The cubbies just outside the dining hall represent a real-life example of this data structure; the fixed-size boxes are arrayed in a grid. The following steps illustrate the use of arrays within C.
Array Indices
-
Copy the program,
array-scale.cto your account.- Explain what this program does.
-
Near the end of the program, the
indexvariable is set to5. What happens if this index value is set to an inappropriate value? You may want to try reasonably small errors (e.g.,index = 8, orindex = -1) as well as ridiculous indices (e.g.,index = 123456789). Explain the results that you get. - Change the loop in the program so that it counts down, instead of up.
Multiple Arrays
-
Program
array-move.cmakes the Scribbler move at specified speeds for certain times, using one array for speed and a second array for time.-
Explain how this program is similar to and different from
the program
array-scale.cfrom the previous question. -
Try changing the definition of
NUM_MOVES, which tells the number of moves (it is now 8) to different numbers and see what happens.- Try a number smaller than 8.
- Try a number greater than 8.
-
Explain how this program is similar to and different from
the program
A Robot Journey
-
One might describe a journey by the robot as having a series
of steps. For each step,
- the robot moves forward at a specified speed for a certain time
- the robot turns at a given speed for a specified time
As you know, speeds for the Scribbler 2 are numbers between -1.0 and 1.0 (or between 0.0 and 1.0, if the robot only moves forward). Also, speed parameters for either
rTurnRightorrTurnLeftare between -1.0 and 1.0.Set up an appropriate set of four arrays to guide the robot through a journey of at least 10 steps. (The main loop should go through array values, first calling
rForwardand then one of the turn commands.) (See theMyroC.hheader for details of these robot commands.)
Taking Pictures
The following notes outline the steps needed to utilize the Scribbler 2 to take a picture.
-
This is how you declare a Picture:
Picture pic; -
This is how you take and store a Picture:
pic = rTakePicture(); -
This is how you display a
PicturerDisplayPicture (&pic, duration, "Window Title");Where
"Window Title"is the text that will appear in the title bar of the window that displays your picture.You can make an array of
Pictures just like any other variable type. This is becausePictureis a "type" just likecharandint, but it is for storing Scribbler pictures.Note that
rDisplayPicturehas both blocking and non-blocking functionality, which is dependent on the duration. Recall that a blocking call stops the program from continuing, and a non-blocking call allows for the program to keep going. So with a non-blocking call, you could have a photo displayed and have the robot execute new commands.- If duration is positive, then it is a blocking call.
- If duration is negative, then it is a non-blocking call.
- If duration is 0, then non-blocking and non-terminating (you will have to close the window manually).
-
Example program
photographer.cillustrates the difference of how blocking and non-blocking commands work; it will take a picture, turn and show it to you, then repeat this twice more.- First uncomment the first commented out part , then run the program and observe.
-
Next, comment back out
rDisplayPicturepart and uncomment the second part of the code.
- Write a program that tells the Scribbler to take and store 6 photos by turning in a circle, and showing them in reverse order. Taking the pictures and showing them should be done with two separate loops.
Arrays and Functions
Consider the following declaration within a C program:
int notes[8] = {523, 587, 659, 698, 783, 880, 987, 1048};
C uses this declaration in at least two ways:
-
The machine allocates space for
8
intvalues within main memory. -
The identifier
notesis used to reference the location of the first element in main memory.
To clarify, the variable notes identifies the
start of the the array. Thus, notes[0] specifies
the first value in the block of memory, notes[1]
specifies the second value in the block of memory, etc. This
interpretation of the array has two consequences when using
functions.
-
The variable
notesspecifies an address. Array parameters are thus passed by reference, because the address is given. This means that the machine only has to pass the reference to the array—not copy the entire array— when passing arrays to functions. -
The variable
notesspecifies a starting address, but not an ending address or array. Programmers must must keep track of size separately to use an array in processing.
-
Program
max-min.cis a simple C program that computes the maximum, minimum, and average of an array of numbers; and programmax-array.ccomputes the maximum of an array of numbers using a separate function. Copy both of these programs and be sure you know how they work.-
Initialization in
find_maxuses the statementmax = array[0]. Why do you think this is done, rather than settingmaxto a large number (e.g., 1500) and starting the loop index at 0 rather than 1? -
Using
max-array.cas an example, add separate functions,find_minandfind_average, that compute the minimum and the average of the values in an array. -
Write an additional procedure
find_statsthat computes the maximum, minimum, and average values within one function. Since multiple values are to be computed and used by the main program, this function must pass values back using reference parameters. The function declaration should be:void find_stats (const double array[], int array_size, double * p_max, double * p_min, double * p_average)
-
Initialization in
-
In program
max-array.cfrom Step 6, modifyfind_maxso that it adds 3 to each array element after computing the maximum. That is, the loop infind_maxshould be changed to
Explain what happens when the array is printed in the main program and why.for (j = 1; j <array_size; j++) { if (array[j] > max) max = array[j]; array[j] += 3.0; }
Robot Hoedown
-
Write a function,
swings, with the following signature:
This function should have the following properties:void swings (const double speeds[], const double durations[], int array_size)-
array_sizeidentifies the number of elements stored in thespeedsarray and in thedurationsarray. -
For each
speeds[i], durations[i]pair, the Scribbler should turn with the associated speed and duration - If the current index of the command is an even number, it should turn right
- If the current index of the command is an odd number, it should turn left
-
Hint: Consider using the
%operator to determine whether the index is even or odd.
-
-
Copy the following function into your program, and make sure
you understand what it does:
void divide_swings (double times[], int times_length) { for (int i = 0; i < times_length; i++) times[i] /= 3; } // divide_swings-
Predict what will happen if you make the following calls
in your
mainmethod, in this order:swings (speeds, times, num_moves); divide_swings (times, num_moves); sleep (3); swings (speeds, times, num_moves); - Now test it out and explain what happened and why this is possible.
-
Predict what will happen if you make the following calls
in your
