Assignment #3

Introductory C Programming

UW Experimental College


Assignment #3

Handouts:

Assignment #3
Answers to Assignment #2
Class Notes, Chapter 4
Class Notes, Chapter 5

Reading Assignment:

Class Notes, Chapter 3, Secs. 3.3-3.5
Class Notes, Chapter 4, Secs. 4.1-4.1.1, 4.3
Class Notes, Chapter 5, Secs. 5.1-5.3
(optional) Class Notes, Secs. 3.6, 4.1.2-4.2, 4.4, 5.4

Review Questions:

  1. How many elements does the array
    	int a[5];
    
    contain? Which is the first element? The last?
  2. What's wrong with this scrap of code?
    	int a[5];
    	for(i = 1; i <= 5; i = i + 1)
    		a[i] = 0;
    
  3. How might you rewrite the dice-rolling program (from the notes, chapter 4, p. 2) without arrays?
  4. What is the difference between a defining instance and an external declaration?
  5. What are the four important parts of a function? Which three does a caller need to know?


Tutorial Section

  1. Here is another nested-loop example, similar to exercise 4 of assignment 1, and to tutorial 3 of assignment 2. This one prints an addition table for sums from 1+1 to 10+10.
    /* print an addition table for 1+1 up to 10+10 */
    
    #include <stdio.h>
    
    int main()
    {
    	int i, j;
    	/* print header line: */
    	printf("  ");
    	for(j = 1; j <= 10; j = j + 1)
    		printf(" %3d", j);
    	printf("\n");
    	/* print table: */
    	for(i = 1; i <= 10; i = i + 1)
    		{
    		printf("%2d", i);
    		for(j = 1; j <= 10; j = j + 1)
    			printf(" %3d", i + j);
    		printf("\n");
    		}
    	return 0;
    }
    
    The first j loop prints the top, header row of the table. (The initial printf(" "); is to make it line up with the rows beneath, which will all begin with a value of i.) Then, the i loop prints the rest of the table, one row per value of i. For each value of i, we print that value (on the left edge of the table), and then print the sums resulting from adding that value of i to ten different values of j (using a second, inner loop on j).

    Make a simple modification to the program to print a multiplication table, or a subtraction table.
  2. Here is yet another nested-loop example. It is very similar to the one above, except that rather than printing the sum i+j, it determines whether the sum is even or odd, using the expression (i+j) % 2 . The % operator, remember, gives the remainder when dividing, and an even number gives a remainder of 0 when dividing by 2. Depending on whether the sum is even or odd, the program prints an asterisk or a space. Type in and run the program, and look at the pattern that results.
    #include <stdio.h>
    
    int main()
    {
    	int i, j;
    	for(i = 1; i <= 10; i = i + 1)
    		{
    		for(j = 1; j <= 10; j = j + 1)
    			{
    			if((i + j) % 2 == 0)
    				printf("* ");
    			else	printf("  ");
    			}
    		printf("\n");
    		}
    	return 0;
    }
    
    (Why are there parentheses around i + j in the expression (i + j) % 2 ? What if they were left out?)

    Modify the program to print a pattern of . and # characters, or X's and O's. If you wish, experiment by taking the remainder when dividing by 3 or 4, instead. Since the remainder when dividing by 3 can be 0, 1, or 2, you could use a cascaded if/else statement to print one of three characters for each sum (or one of four if taking the remainder when dividing by 4).
  3. Later in this assignment (exercise 3), you're asked to create a simple function to compute the squares of numbers. Sometimes, rather than writing a function which will compute a value each time it's called, it's useful to build an array containing all the values we might need. Here is a program which declares an array, then fills it with the squares of the numbers from 1 to 10:
    #include <stdio.h>
    
    int main()
    {
    	int i;
    	int squares[11];	/* [0..10]; [0] ignored */
    	/* fill array: */
    	for(i = 1; i <= 10; i = i + 1)
    		squares[i] = i * i;
    	/* print table: */
    	printf("n\tsquare\n");
    	for(i = 1; i <= 10; i = i + 1)
    		printf("%d\t%d\n", i, squares[i]);
    	return 0;
    }
    
    There's one slight trick in the declaration of the squares array. Remember that arrays in C are based at 0. So if we wanted an array to hold the squares of 10 numbers, and if we declared it as int squares[10]; the array's 10 elements would range from squares[0] to squares[9]. This program wants to use elements from squares[1] to squares[10], so it simply declares the array as having size 11, and wastes the 0th element.

    The program also uses the tab character, \t, in its printouts, to make the columns line up.

    Modify the program so that it also declares and fills in a cubes array containing the cubes (third powers) of the numbers 1-10, and prints them out in a third column.
  4. We're going to write a simple (very simple!) graphics program. We'll write a function printsquare which prints a square (made out of asterisks) of a certain size. Then we'll use our favorite for-i-equals-1-to-10 loop to call the function 10 times, printing squares of size 1 to 10.
    #include <stdio.h>
    
    int printsquare(int);
    
    int main()
    {
    	int i;
    	for(i = 1; i <= 10; i = i + 1)
    		{
    		printsquare(i);
    		printf("\n");
    		}
    	return 0;
    }
    
    int printsquare(int n)
    {
    	int i, j;
    	for(i = 0; i < n; i = i + 1)
    		{
    		for(j = 0; j < n; j = j + 1)
    			printf("*");
    		printf("\n");
    		}
    	return 0;
    }
    
    Type the program in and run it. Then see if you can modify it to print ``open'' squares, like this:
    ****
    *  *
    *  *
    ****
    
    instead of filled squares. You'll have to print the box in three parts: first the top row, then a number of ``* *'' rows, and finally the bottom row. There's obviously no way to print ``open'' boxes of size 1 or 2, so don't worry about those cases. (That is, you can change the loop in the top-level main function to for(i = 3; i <= 10; i = i + 1) .)


Exercises (pick three or four):

  1. Write code to sum the elements of an array of int. (Write it as a function, if you like.) Use it to sum the array
    	int a[] = {1, 2, 3, 4, 5, 6};
    
    (The answer, of course, should be 21).
  2. Write a loop to call the multbytwo() function (chapter 5, section 5.1, p. 1) on the numbers 1-10. For extra credit, compile your main function and the multbytwo() function as two source files, one function per file.
  3. Write a square() function and use it to print the squares of the numbers 1-10:
    1  1
    2  4
    3  9
    4  16
    ...
    9  81
    10 100
    
  4. Write the function
    	void printnchars(int ch, int n)
    
    which is supposed to print the character ch, n times. (Remember that %c is the printf format to use for printing characters.) For example, the call printnchars('x', 5) would print 5 x's. Use this function to rewrite the triangle-printing program of assignment 1 (exercise 4).
  5. Write a function to compute the factorial of a number, and use it to print the factorials of the numbers 1-7. (Extra credit: print the factorials of the numbers 1-10.)
  6. (Kernighan and Ritchie) Write a function celsius() to convert degrees Fahrenheit to degrees Celsius. (The conversion formula is °C = 5/9 * (°F - 32).) Use it to print a Fahrenheit-to-Centigrade table for -40 to 220 degrees Fahrenheit, in increments of 10 degrees. (Remember that %f is the printf format to use for printing floating-point numbers. Also, remember that the integer expression 5/9 gives 0, so you won't want to use integer division.)
  7. Modify the dice-rolling program (Sec. 4.1) so that it computes the average of all the rolls of the pair of dice. Remember that integer division truncates, so you'll have to declare some of your variables as float or double.

    For extra credit, also compute the standard deviation, which can be expressed as
    sqrt((sum(x*x) - sum(x)*sum(x)/n) / (n - 1))
    (where the notation sum(x) indicates summing all values of x, as usually expressed with the Greek letter sigma; there is not such a sum() function in C!) If you put the line
    	#include <math.h>
    
    at the top of the file, you'll be able to call sqrt().

    (See the note in Assignment #2, Exercise 5, about compiling with the math library under Unix. There are better ways of computing the standard deviation, but the above expression will suffice for our purposes.)
  8. Write either the function
    	randrange(int n)
    
    which returns random integers from 1 to n, or the function
    	int randrange2(int m, int n)
    
    which returns random integers in the range m to n. Use your function to streamline the dice-rolling program a bit.

    The header file <stdlib.h> defines a constant, RAND_MAX, which is the maximum number returned by the rand() function. A better way of reducing the range of the rand() function is like this:
    	rand() / (RAND_MAX / N + 1)
    
    (where N is the range of numbers you want).

    Extra credit: investigate the behavior of randrange(2), both using the ``obvious'' range-reduction technique (the modulus operator %, as shown in the notes) and this improved method. If your library's implementation of rand() is a good one, you won't see a difference. But if you're not so lucky, you may see something very surprising.
  9. Rewrite the dice-rolling program to also print a histogram. For example, if there are 21 rolls of 7, the output line ``7: 21'' should also contain a horizontal row of 21 asterisks. (Use the printnchars function from exercise 4, if you wish.) The output might look like this:
    2: 2    **
    3: 5    *****
    4: 4    ****
    5: 10   **********
    6: 15   ***************
    7: 28   ****************************
    8: 12   ************
    9: 9    *********
    10: 7   *******
    11: 5   *****
    12: 3   ***
    


This page by Steve Summit // Copyright 1995-9 // mail feedback