CSC 101 Lecture Notes Week 2
Let's Start Programming


Relevant Reading: Chapters 3 and 4




  1. Here's another sample C program.

    1. It's a bit more complicated than the example from last week.

    2. It introduces topics from Chs 2 and 3 of the book.

    3. It's similar in structure and complexity to programming assignment 1.

    4. Here's the spec:
      Compute simple statistics for three real numbers read from standard input.
      The statistics computed are the sum of the numbers, the arithmetic mean, and
      the standard deviation.  Output the results to standard output, in the
      following form:
      
      Sum =
      Mean =
      Standard Deviation =
      

    5. Here's the first version of the program:
      #include <stdio.h>
      #include <math.h>
      
      #define NUM_DATA_POINTS 3               /* Fixed number of data points */
      
      int main () {
      
          double x1, x2, x3;                  /* Input variables */
          double sum;                         /* Computed sum */
          double mean;                        /* Computed mean */
          double std_dev;                     /* Computed standard deviation */
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Compute the sum.
           */
          sum = x1 + x2 + x3;
      
          /*
           * Compute the mean.
           */
          mean = sum / NUM_DATA_POINTS;
      
          /*
           * Compute the standard deviation.
           */
          std_dev = sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / NUM_DATA_POINTS);
      
          /*
           * Output the results.
           */
           printf("Sum = %f\n", sum);
           printf("Mean = %f\n", mean);
           printf("Standard Deviation = %f\n\n", std_dev);
      
          return 0;
      
      }
      

    6. We'll examine this program fully during class, including its stepwise refinement.


  2. How about some testing?

    1. OK, so I've implemented the program (I think).

    2. Let's compile and run it to see.
      gcc -ansi -pedantic -Wall -Werror stats.c
      a.out
      
      Enter three real numbers, separated by spaces: 1 2 3
      Sum = 6.000000
      Mean = 2.000000
      Standard Deviation = 0.816497
      

    3. Hmm, is this correct?

      1. From what I know about standard deviation, I think it's supposed to be 1.0 in this case.

      2. I better go look it up, and then ask the program specifier if what I'm doing is correct.


  3. OK, so the specification wasn't precise enough.

    1. We'll fix it by citing an authoritative reference.

    2. Then we'll fix, i.e., "debug" the program to agree with the spec.

    3. This entails changing the program computation for the standard deviation from this
          std_dev = sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / NUM_DATA_POINTS);
      
      to this
          std_dev = sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / (NUM_DATA_POINTS - 1 ));
      

    4. Here's the updated code, with changes shown in red:
      /****
       *
       * This program computes simple statistics for three real numbers read from
       * standard input.  The statistics computed are the sum of the numbers, the
       * arithmetic mean, and the standard deviation.  The results are output to
       * standard output, in the following form:
       *
       * Sum =
       * Mean =
       * Standard Deviation =
       *
       * The precise formulae for mean and standard deviation are as defined here:
       *
       *    http://www.gcseguide.co.uk/statistics_and_probability.htm
       *
       *
       * Author: Gene Fisher (gfisher@calpoly.edu)
       * Created: 31mar11
       * Last Modified: 4apr11
       *
       */
      
      #include <stdio.h>
      #include <math.h>
      
      #define NUM_DATA_POINTS 3               /* Fixed number of data points */
      
      int main () {
      
          double x1, x2, x3;                  /* Input variables */
          double sum;                         /* Computed sum */
          double mean;                        /* Computed mean */
          double std_dev;                     /* Computed standard deviation */
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Compute the sum.
           */
          sum = x1 + x2 + x3;
      
          /*
           * Compute the mean.
           */
          mean = sum / NUM_DATA_POINTS;
      
          /*
           * Compute the standard deviation.
           */
          std_dev = sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / (NUM_DATA_POINTS - 1 ));
      
          /*
           * Output the results.
           */
           printf("Sum = %f\n", sum);
           printf("Mean = %f\n", mean);
           printf("Standard Deviation = %f\n\n", std_dev);
      
          return 0;
      
      }
      


  4. A Note on precise program specification.

    1. The specification of a program describes what the program is supposed to do.

      1. The preceding example illustrates the importance of precise program specification.

      2. If a specification is imprecise, the program may well not produce the results that the specifier or programmer expects.

    2. In CSC 101, your instructors are the program specifiers.

      1. You will be given program specifications, and it will be your job to implement them properly.

      2. Your instructors will do their best to provide you thorough and precise specs.

      3. However, instructors can certainly make mistakes.

      4. If there's ever anything you don't understand about a program spec, or think is incorrect, don't hesitate to ask.

    3. An important part of a programmer's job is to fully understand a program's specification.

      1. If a programmer has any questions about a spec, he or she should always as the specifier for clarification.

      2. In the real world of software development, program specifiers and implementors should always work as a team, to ensure that a fully correct program gets developed.


  5. OK, let's re-compile the updated program, and run it again.
    gcc -ansi -pedantic -Wall -Werror stats.c
    a.out
    
    Enter three real numbers, separated by spaces: 1 2 3
    Sum = 6.000000
    Mean = 2.000000
    Standard Deviation = 1.000000
    

    1. This looks better.

      1. We'll definitely need to do some more testing before we're completely sure it's correct.

      2. We'll talk plenty more about testing details in upcoming lectures.

    2. For the current lecture, we'll do some program refinement, in particular by adding some functions.


  6. Restructuring the stats program using functions.

    1. A function in a C program is a piece of computation that has the following properties:

      1. It has a mnemonic name, i.e., a name that indicates what the function computes.

      2. It has a zero or more inputs, which are used in its computation.

      3. It has an output, which is the result of its computation.

    2. Here's a very simple function that computes the sum of three numbers, which is part of the stats program we started above:
      /*
       * Return the sum of the given three numbers.
       */
      double compute_sum(double x1, double x2, double x3) {
          return x1 + x2 + x3;
      }
      

    3. We'll dissect this definition fully in class, and chapter 3 of the book provides an in-depth introduction to functions like this.

    4. Here's a refined version of the stats program with three functions, one for each of its statistical computations:
      /****
       *
       * This program computes simple statistics for three real numbers read from
       * standard input.  The statistics computed are the sum of the numbers, the
       * arithmetic mean, and the standard deviation.  The results are output to
       * standard output, in the following form:
       *
       * Sum =
       * Mean =
       * Standard Deviation =
       *
       * The precise formulae for mean and standard deviation are as defined here:
       *
       *    http://www.gcseguide.co.uk/statistics_and_probability.htm
       *
       *
       * Author: Gene Fisher (gfisher@calpoly.edu)
       * Created: 31mar11
       * Last Modified: 3apr11
       *
       */
      
      #include <stdio.h>
      #include <math.h>
      
      #define NUM_DATA_POINTS 3               /* Fixed number of data points */
      
      /*
       * Declare the prototypes for functions used in the program.
       */
      double compute_sum(double x1, double x2, double x3);
      double compute_mean(double x1, double x2, double x3);
      double compute_std_dev(double x1, double x2, double x3);
      
      int main () {
      
          /*
           * Declare the variables used in main.
           */
          double x1, x2, x3;                  /* Input variables */
          double sum;                         /* Computed sum */
          double mean;                        /* Computed mean */
          double std_dev;                     /* Computed standard deviation */
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Compute the sum.
           */
          sum = compute_sum(x1, x2, x3);
      
          /*
           * Compute the mean.
           */
          mean = compute_mean(x1, x2, x3);
      
          /*
           * Compute the standard deviation.
           */
          std_dev = compute_std_dev(x1, x2, x3);
      
          /*
           * Output the results.
           */
           printf("Sum = %f\n", sum);
           printf("Mean = %f\n", mean);
           printf("Standard Deviation = %f\n\n", std_dev);
      
          return 0;
      
      }
      
      /*
       * Return the sum of the given three numbers.
       */
      double compute_sum(double x1, double x2, double x3) {
          return x1 + x2 + x3;
      }
      
      /*
       * Return the arithmetic mean of the given three numbers.
       */
      double compute_mean(double x1, double x2, double x3) {
          return compute_sum(x1, x2, x3) / NUM_DATA_POINTS;
      }
      
      /*
       * Return the standard deviation of the given three numbers.
       */
      double compute_std_dev(double x1, double x2, double x3) {
      
          double mean = compute_mean(x1, x2, x3);
          return sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / (NUM_DATA_POINTS - 1 ));
      }
      


  7. One more program refinement.

    1. One of the advantages of defining program functions is that they can be used wherever their value is needed, without having to store it in a variable.

    2. Here's what this idea looks like in the stats program:
      /****
       *
       * This program computes simple statistics for three real numbers read from
       * standard input.  The statistics computed are the sum of the numbers, the
       * arithmetic mean, and the standard deviation.  The results are printed to
       * standard output, in the following form:
       *
       * Sum =
       * Mean =
       * Standard Deviation =
       *
       * The precise formulae for mean and standard deviation are as defined here:
       *
       *    http://www.gcseguide.co.uk/statistics_and_probability.htm
       *
       *
       * Author: Gene Fisher (gfisher@calpoly.edu)
       * Created: 31mar11
       * Last Modified: 3apr11
       *
       */
      
      #include <stdio.h>
      #include <math.h>
      
      #define NUM_DATA_POINTS 3               /* Fixed number of data points */
      
      /*
       * Declare the prototypes for functions used in the program.
       */
      double compute_sum(double x1, double x2, double x3);
      double compute_mean(double x1, double x2, double x3);
      double compute_std_dev(double x1, double x2, double x3);
      
      int main () {
      
          /*
           * Declare the variables used in main.
           */
          double x1, x2, x3;                  /* Input variables (other vars gone) */
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Compute and output the results (preceding three assignment statements gone).
           */
           printf("Sum = %f\n", compute_sum(x1, x2, x3));
           printf("Mean = %f\n", compute_mean(x1, x2, x3));
           printf("Standard Deviation = %f\n\n", compute_std_dev(x1, x2, x3));
      
          return 0;
      
      }
      
      /*
       * Return the sum of the given three numbers.
       */
      double compute_sum(double x1, double x2, double x3) {
          return x1 + x2 + x3;
      }
      
      /*
       * Return the arithmetic mean of the given three numbers.
       */
      double compute_mean(double x1, double x2, double x3) {
          return compute_sum(x1, x2, x3) / NUM_DATA_POINTS;
      }
      
      /*
       * Return the standard deviation of the given three numbers.
       */
      double compute_std_dev(double x1, double x2, double x3) {
      
          double mean = compute_mean(x1, x2, x3);
          return sqrt((pow(x1 - mean, 2) +
                          pow(x2 - mean, 2) +
                          pow(x3 - mean, 2)) / (NUM_DATA_POINTS - 1 ));
      }
      

    3. What's happened here is that we've eliminated the three program variables sum, mean, and std_dev.

    4. Then the print statements call the functions directly to get the results.

    5. This is not a massive improvement to the program, but it illustrates how functions can be used.


  8. So what's so great about functions?

    1. In this particular example, you may be asking yourself "What's the point of using functions when the program is pretty much as simple without them?"

    2. This question is fair enough, and the best immediate answer is this -- "Very few C programs are as simple as this; we're introducing functions this way to avoid being overwhelmed with details."

    3. As we'll see very soon, using functions in larger C programs is an indispensable part of program design.

    4. Here are a couple quick questions to stimulate your thinking in this area:

      1. Suppose we wanted to write a program that computes statistics on thousands of numbers, not just three?

      2. And suppose we wanted to share our statistical program with other people, so they could use it in the same way that they use programs from the C library?

    5. The answer to both these question involves designing the statistical program using functions.


  9. Introduction to Conditional Statements

    1. We saw a very brief introduction to the C if statement in lecture notes week 1.

    2. It is one of the most fundamental and important aspects of programming.

    3. It allows a decision to be made in a program, and based on the outcome of the decision, the program will do different things.


  10. Extending the specification of the simple stats program.

    1. Add the following to the specification:
      Input numbers must be non-negative.  If a negative number is input, it is
      treated as a 0.  The number of data points remains 3, even if one or more
      negative numbers is input.  For example, with input 1 -2 3, the results are
      
      Sum = 4.000000
      Mean = 1.333333
      Standard Deviation = 1.527525
      

    2. The updated program looks like this:
      /****
       *
       * This program computes simple statistics for three real numbers read from
       * standard input.  The statistics computed are the sum of the numbers, the
       * arithmetic mean, and the standard deviation.  The results are output to
       * standard output, in the following form:
       *
       * Sum =
       * Mean =
       * Standard Deviation =
       *
       * The precise formulae for mean and standard deviation are as defined here:
       *
       *    http://www.gcseguide.co.uk/statistics_and_probability.htm
       *
       * Input numbers must be non-negative.  If a negative number is input, it is
       * treated as a 0.  The number of data points remains 3, even if one or more
       * negative numbers is input.  For example, with inputs
       *
       *     1 -2 3
       *
       * The results are
       *
       * Sum = 4.000000
       * Mean = 1.333333
       * Standard Deviation = 1.527525
       *
       *
       * Author: Gene Fisher (gfisher@calpoly.edu)
       * Created: 31mar11
       * Last Modified: 3apr11
       *
       */
      
      #include <stdio.h>
      #include <math.h>
      
      #define NUM_DATA_POINTS 3               /* Fixed number of data points */
      
      /*
       * Declare the prototypes for functions used in the program.
       */
      double compute_sum(double x1, double x2, double x3);
      double compute_mean(double x1, double x2, double x3);
      double compute_std_dev(double x1, double x2, double x3);
      
      int main () {
      
          /*
           * Declare the variables used in main.
           */
          double x1, x2, x3;                  /* Input variables */
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Consider any negative input to be 0.
           */
          if (x1 < 0) x1 = 0;
          if (x2 < 0) x2 = 0;
          if (x3 < 0) x3 = 0;
      
          /*
           * Compute and output the results.
           */
          printf("Sum = %f\n", compute_sum(x1, x2, x3));
          printf("Mean = %f\n", compute_mean(x1, x2, x3));
          printf("Standard Deviation = %f\n\n", compute_std_dev(x1, x2, x3));
      
          return 0;
      
      }
      
      /*
       * Return the sum of the given three numbers.
       */
      double compute_sum(double x1, double x2, double x3) {
          return x1 + x2 + x3;
      }
      
      /*
       * Return the arithmetic mean of the given three numbers.
       */
      double compute_mean(double x1, double x2, double x3) {
          return compute_sum(x1, x2, x3) / NUM_DATA_POINTS;
      }
      
      /*
       * Return the standard deviation of the given three numbers.
       */
      double compute_std_dev(double x1, double x2, double x3) {
          double mean = compute_mean(x1, x2, x3);
          return sqrt((pow(x1 - mean, 2) +
                       pow(x2 - mean, 2) +
                       pow(x3 - mean, 2)) / (NUM_DATA_POINTS - 1 ));
      }
      

    3. We'll dissect these uses of if in class; chapter 4 of the book provides an in-depth introduction to the subject.


  11. Yet another change to the spec.

    1. In addition to treating negative inputs as zero, we also want to drop them out of the stats computation, by subtracting 1 from the number of data points for each negative input.

    2. The changed part of the revised spec looks like this:
      Input numbers must be non-negative.  If a negative number is input, it is
      treated as 0.  For each negative input, the number of data points is
      decremented by 1.  For example, with inputs 1 -2 3, the results are
      
      Sum = 4.000000
      Mean = 2.000000
      Standard Deviation = 1.000000
      

    3. The updated program looks like this:
      /****
       *
       * This program computes simple statistics for three real numbers read from
       * standard input.  The statistics computed are the sum of the numbers, the
       * arithmetic mean, and the standard deviation.  The results are output to
       * standard output, in the following form:
       *
       * Sum =
       * Mean =
       * Standard Deviation =
       *
       * The precise formulae for mean and standard deviation are as defined here:
       *
       *    http://www.gcseguide.co.uk/statistics_and_probability.htm
       *
       * Input numbers must be non-negative.  If a negative number is input, it is
       * treated as 0.  For each negative input, the number of data points is
       * decremented by 1.  For example, with inputs
       *
       *     1 -2 3
       *
       * The results are
       *
       * Sum = 4.000000
       * Mean = 2.000000
       * Standard Deviation = 1.000000
       *
       *
       * Author: Gene Fisher (gfisher@calpoly.edu)
       * Created: 31mar11
       * Last Modified: 3apr11
       *
       */
      
      #include <stdio.h>
      #include <math.h>
      
      /*
       * Declare the prototypes for functions used in the program.
       */
      double compute_sum(double x1, double x2, double x3);
      double compute_mean(double x1, double x2, double x3, int num_data_points);
      double compute_std_dev(double x1, double x2, double x3, int num_data_points);
      
      int main () {
      
          /*
           * Declare the variables used in main.
           */
          double x1, x2, x3;                  /* Input variables */
          int num_data_points;                /* Number of data points */
      
          /*
           * Initialize the number of data points to 3.
           */
          num_data_points = 3;
      
          /*
           * Prompt the user for the input.
           */
          printf("Enter three real numbers, separated by spaces: ");
      
          /*
           * Input the numbers.
           */
          scanf("%lf%lf%lf", &x1, &x2, &x3);
      
          /*
           * Consider any negative input to be 0, and drop it from stats by
           * decrementing the number of data points for each negative input.
           */
          if (x1 < 0) {
              x1 = 0;
              num_data_points = num_data_points - 1;
          }
          if (x2 < 0) {
              x2 = 0;
              num_data_points = num_data_points - 1;
          }
          if (x3 < 0) {
              x3 = 0;
              num_data_points = num_data_points - 1;
          }
      
          /*
           * Compute and output the results.
           */
          printf("Sum = %f\n", compute_sum(x1, x2, x3));
          printf("Mean = %f\n", compute_mean(x1, x2, x3, num_data_points));
          printf("Standard Deviation = %f\n\n",
              compute_std_dev(x1, x2, x3, num_data_points));
      
          return 0;
      
      }
      
      /*
       * Return the sum of the given three numbers.
       */
      double compute_sum(double x1, double x2, double x3) {
          return x1 + x2 + x3;
      }
      
      /*
       * Return the arithmetic mean of the given three numbers, and the given number
       * of data points.  Question: What happens here if num_data_points = 0?
       */
      double compute_mean(double x1, double x2, double x3, int num_data_points) {
          return compute_sum(x1, x2, x3) / num_data_points;
      }
      
      /*
       * Return the standard deviation of the given three numbers, and the given
       * number of data points.  Question: What happens here if num_data_points = 0?
       */
      double compute_std_dev(double x1, double x2, double x3, int num_data_points) {
      
          double mean = compute_mean(x1, x2, x3, num_data_points);
          return sqrt((pow(x1 - mean, 2) +
                       pow(x2 - mean, 2) +
                       pow(x3 - mean, 2)) / (num_data_points - 1 ));
      }
      


  12. A picture of computer memory in the stats program.

    1. We've discussed the idea of computer memory in previous lectures, and it's introduced in book chapter 1.

    2. To understand a C program, memory is often drawn as boxes, labeled with the names of variables.

    3. For example, the following two lines of a program
      int x;
      x = 10;
      
      can be illustrated like this:

    4. To be precise about the structure of program memory, we need to take note that it's organized into separate pieces, one piece for each function in a program.

      1. Specifically, the variables and parameters in each function are organized into a piece of memory that belongs to that function.

      2. For example, the main function in the first version of the stats program has six variables: x1, x2, x3, sum, mean, std_dev.

      3. For this version of the program, memory looks like this:

      4. This is a picture of memory before the program runs, with all of the memory locations blank, to indicate that no values have been stored in them yet.

      5. After the program runs, with say inputs 1, 2, 3, memory looks like this:

      6. Note that it's OK for us to show the values without the decimal points, since we're illustrating memory here for human understanding, and we can therefore know that the value of 1 is the same as 1.000000.

    5. In the most recent version of the stats program, we eliminated three of the variables in main, added a new variable to main, and added three functions that have their own parameters and variables.

      1. Now the main function has four variables: x1, x2, x3, and num_data_points.

      2. Each function has three parameters, also named x1, x2, x3.

        1. As we discussed in class, the names of the parameters happened to be the same as the names of the main variables, but they're still all separate pieces of memory.

        2. Note also that function parameters are stored in the same kind of memory as variables.

      3. In addition to the three parameters, function compute_std_dev has an additional parameter num_data_points, and a variable named mean.

      4. With all these variables and parameters, a picture of program memory in the stats program looks like this:



    6. You may find pictures like this helpful in understanding how a program works.

    7. We'll use these kind of pictures in the coming weeks, to illustrate exactly what memory looks like before, during, and after functions are executed.

    8. To get started thinking about this, you can fill in above picture of memory at the following points of program execution:

      1. Before the program starts.

      2. After the scanf has executed, but before any of the if statements is executed.

      3. After the if statements have executed, but before any of the functions is called.

      4. After the compute_sum function is called, but before it returns.

      5. After the compute_sum function is called, and it has returned.

      6. After the program is entirely finished.