CS16, Summer 2012


Goals for this lab

By the time you have completed this lab, you should be able to

Step by Step Instructions

Step 1: Get together with your lab partner, and create a lab06 directory

Choose the first partner wisely (ask us if you don't know the goal). If your assigned partner is more than 5 minutes late, ask the TA to pair you with someone else for this week.

This lab's first pilot should log in, create ~/cs16/lab06/ and make that your current directory.

Step 2: Practice using an array from the ch prompt

Start ch, and simplify the ch prompt if you want:

-bash-4.2$ ch
                Professional edition, version
              (C) Copyright 2001-2009 SoftIntegration, Inc.
/cs/class/cs16/lab06> _prompt = "ch> "

Create an array, a, that can store 10 int values:

ch> int a[10];

Now accomplish each of the following steps in order:

  1. Unlike standard C, ch has filled the array with zeros. Go ahead and verify that both the first and last element do equal zero, by typing a[0] and then a[9] on successive lines.
  2. Another feature of ch that is not like standard C is that a warning will be issued if you try to access an element outside the bounds of the array. Try it now, by typing a[10] and then a[-1], and read the different messages.
  3. Now set the value of the first array element, a[0], to 1. And then verify its new value by typing a[0] again at the prompt.
  4. Use a for loop to set the other nine array elements to successive powers of 2. That is, a[0] already stores 20, and so we want to store 21 in a[1], 22 in a[2], and so on up to a[9]. Declare the loop control variable, i, and type the for loop header exactly as shown here - including the '\' continuation character at the end:
    ch> int i;
    ch> for (i=1; i<10; i++)\
    The next line you type should be indented, because it is "inside" the loop structure. This line must be an assignment statement that sets the value of the current array element, a[i], to twice the value of the preceding element, a[i-1]. Before going on to part e, verify that 29 is now stored in a[9].
    ch>     CENSORED: SETS a[i]
    ch> a[9]
  5. Here we want to print a neat table of these powers of 2, by looping through the array and printing the index and value of each array element on a separate line. Of course you should use a for loop to accomplish this task. The values should line up (i.e., right justified) to match this output display:
    0   1
    1   2
    2   4
    3   8
    4  16
    5  32
    6  64
    7 128
    8 256
    9 512

By the way, see what ch displays when you just type the array name, a, by itself (your result probably will be a different value, but that's not what you should think about):

ch> a

Surprised? The result is a memory address (in hexadecimal). It is the address of the first byte in the array. Keep this concept in mind, and learn more about it in chapter 6: an array name points to a location in memory.

Step 3: Write and test a function to sum elements of an array

Do NOT exit ch (to keep the array from Step 2 in memory), but open emacs or another editor to create a file named isum.chf (a ch "function file"). Type a comment such as /* returns sum of the first n values in x */ and define the function as specified here:

Write a function named isum that takes two arguments - an int array named x, followed by an int named n - and returns an int value that is the sum of the first n elements in x.
Here is what the function's header should be:

int isum(int x[], int n)

Save the file as isum.chf in your lab06 directory. Then test it from the ch prompt. If something doesn't work correctly, fix the problem before going to Step 4. Here are some correct answers to expect:

ch> isum(a, 10)
ch> isum(a, 4)
ch> int b[] = {17, -4, 11, 9};
ch> isum(b, 4)

The first two examples sum all and then just the first four elements of the array from Step 2. The third example demonstrates another way to create an array - a way that automatically sizes it and initializes its elements. The size is determined by the number of values listed between the curly braces, and the elements are initialized with these values in the order they are listed.

Step 4: Write and test a function to find an average value from an array

First: switch roles between pilot and navigator if you did not already do that.

Create a file named avg.chf with your editor (still no need to exit ch). Type an appropriate comment and then function avg as follows:

Write a function named avg that takes two arguments - an int array named x, followed by an int named n - and returns a double value equal to the average (arithmetic mean) of the first n elements in x.
This function can and should be very short, because you should use function isum to calculate the average, as in:
double result = (double)isum(x, n) / n;
Save the file as avg.chf in your lab06 directory. Then test it from the ch prompt. If something doesn't work correctly, fix the problem before going to Step 5. Here are some correct answers to expect:

ch> avg(b, 4)
ch> avg(a, 10)

Step 5: Complete a program to find differences from average in user-entered data

You can exit ch now. Make a copy of this skeleton program in your (first pilot's) ~/cs16/lab06 directory. You can cp a copy from the instructor's account:

-bash-4.2$ cp ~kyledewey/cs16/lab06/diffs.c ~/cs16/lab06/

Study the parts of the program that are complete: (1) after including the standard input-output library, there are prototypes for the two functions you wrote in Steps 3 and 4; (2) a symbolic constant is defined to set a maximum number of input values, because the values will be stored in an array whose size must be specified; (3) main begins by creating the array, a, and four other variables to be used later; (4) the user is prompted to enter data, and these data are read into the array - at the end of this for loop, the value of n is equal to the number of data values entered and stored in the array; and (5) between the two uppercase instructions to you, the values of n and average are printed along with a message that differences will print next.

First, just to be safe, make a new directory named safe, inside your lab06 directory, and copy your two function files into it:

-bash-4.2$ mkdir safe
-bash-4.2$ cp *.chf safe/
-bash-4.2$ ls safe
avg.chf  isum.chf

Stay in the lab06 directory, and accomplish the following steps in this order:

  1. Append your two functions from Steps 3 and 4 to the end of diffs.c. You can use an editor to copy/paste, but you can also use a combination of the Linux cat command and output redirection to get the job done. First observe what happens when you type the following command at the system prompt:
    -bash-4.2$ cat isum.chf avg.chf
    The command's purpose is to concatenate the files listed as arguments and print the result to standard output. So now type that command again, but use the double output redirection arrow, >>, to redirect the output to the end of diff.c:
    -bash-4.2$ cat isum.chf avg.chf >> diffs.c
    Now start your editor to edit diffs.c, and verify that your two functions are appended to the end of it - just once. You might have to add newlines between parts of the file to clean it up. And don't be afraid to start over completely with a new copy of diffs.c if you made mistakes that are difficult to undo, and remember you saved copies of the chf files in directory safe too.
  2. Type your name(s) in the comment at the top.
  3. In the appropriate place, use your avg function to set the value of the variable named average.
  4. In the appropriate place, write a loop to calculate and print the differences between each of the n values and the average value. Match the results shown below (uses "%g" as the format specifier).

Save the file, and exit the editor. You can use ch to test your program, but also make an executable version of it:

-bash-4.2$ make diffs
cc     diffs.c   -o diffs
-bash-4.2$ ./diffs
enter up to 100 integers - end by non-integer:
15 -23 4 38 done
average of 4 values: 8.5
differences from average:

Before proceeding to Step 6, be sure your version works exactly like the instructor's solution. You can run that solution yourself by typing the following at the system prompt:


Step 6: Get credit for the lab

Don't leave early though ... see challenge problems below.

Submit the lab with the turnin program. You MUST have both your name and your partner's name in the file in order to receive credit. Remember that the original pilot needs to do this step, since that is whose account you have been using in Cooper Lab.

Bring up a terminal window and cd into the original pilot's cs16 directory, and cd again into the lab06 directory. Then type the following to turn in just the completed file from Step 5 above:

turnin lab06@cs16 diffs.c

Respond "yes" when the program asks if you want to turn in (be sure to read the list of files you are turning in), and then wait for the message indicating success.

Evaluation and Grading

Each student must accomplish the following to earn full credit for this lab:

Deadline for submission: Wednesday 8/8 (11:59pm)

Optional Extra Challenge

Practice Lab: Two-dimensional arrays

Most quarters, the next lab would be about two-dimensional arrays. This quarter, because of the holiday on May 28, the lab about Pointers will be next. We still think you should practice using two-dimensional arrays though, and so you should work on the practice lab when you have time to do so. Here is the practice lab link.

Adapted by Kyle Dewey from a lab prepared by Michael Costanzo.