CS140 Midterm 1 Solutions

Fall 2009

  1. (8 points) Write an anonymous struct for a student's record in a class and use typedef to name it "Student". The struct should contain the following fields:

    1. name: a string of at most 30 characters that contains the student's full name
    2. midterm: an integer denoting the student's score on the midterm
    3. final: an integer denoting the student's score on the final
    4. hw: an array that records the results of 10 homework assignments. The scores on the assignments are all integers.
    5. avg: a floating point number denoting the weighted average of the midterm, final, and homework assignments
    6. sex: a character denoting the sex (male/female) of the student.
    typedef struct {
      char name[31];
      int midterm;
      int final;
      int hw[10];
      double avg;
      char sex;
    } Student;

  2. (4 points) Suppose you have the following two declarations:
          int score;
          char *student_name;
    Based on the typedef that you just wrote:

    1. Declare a variable named new_student, which points to a Student.
      Student *new_student;
    2. Malloc a Student struct and assign the pointer returned by malloc to new_student.
      new_student = (Student *)malloc(sizeof(Student));
    3. Assign the value of score to the midterm field in your newly allocated struct.
      new_student->midterm = score;
    4. Copy the string pointed to by student_name to the name field in your newly allocated struct.
      strcpy(new_student->name, student_name);

  3. (3 points) 0x1d08 + 0x6 = 0x1d0e (I want the hexadecimal result)

  4. (8 points) Suppose I have the following declarations and code:
         int a;
         int *b;
         char day[20];
         char *save_day;
         b = &a;
         *b = 30;
         save_day = day;
         strcpy(save_day, "hello brad");
    Also suppose that the above variables are assigned the following memory addresses:
         a: 0x1000
         b: 0x1004
         day: 0x101c
         save_day: 0x1008
    After the above code executes, what is the value of:

    1. a: 30
    2. b: 0x1000
    3. day: "hello brad"
    4. save_day: 0x101c

  5. (3 points) What is the memory address of the last character in day, assuming that a character occupies one byte of memory.
    memory address = starting memory address of day + (20-1)*sizeof(char)
                   = 0x101c + 19*1
                   = 0x101c + 0x13
                   = 0x102f
    I subtracted 1 from 20 because you start counting from 0, not 1.
  6. (21 points) Consider the following declarations:
           char buffer[100];
           char field[20];
           char *max_field;
           char *license_plate;
           char *state;
           char *count;
           int *scores;
           int area_code;
    Write statements to accomplish the following tasks:

    1. do a safe copy of the string in field to max_field.
      max_field = strdup(field);
    2. if the string in buffer is small enough to copy it to field without overflowing field's array then do so. Do nothing if the field is too big to copy to field.
      if (strlen(buffer) < 20)
        strcpy(field, buffer);
    3. malloc an array of 50 ints and assign the address of the newly created array to scores.
      scores = (int *)malloc(sizeof(int)*50);
    4. use scanf to read an integer into area_code.
      scanf("%d", &area_code);
    5. use scanf to read a string into buffer.
      scanf("%s", buffer);
    6. use scanf to read an integer into scores[3].
      scanf("%d", &scores[3]);
    7. suppose that license_plate points to a string that represents a license plate of the form "state-digits", such as "tennessee-941". Assume that you do not know how many letters precede the dash, nor how many digits are in the number. Write a piece of code to extract the strings representing the letters and the digits from license plate and assign pointers to these two strings to state and count. You may make copies of the strings if you wish, but that is unnecessary. You may modify the string pointed to by license_plate in order to divide it into two strings.
    count = strchr(license_plate, '-');
    *count = '\0';  // replace the '-' with a null character
    state = license_plate;
    count = count + 1;

  7. (9 points) What is the Big-O running time for the following functions?

    1. O(n2): T(n) = 5n2 + 10n * log n + 1000n
    2. O(1): T(n) = 1000000
    3. O(2n): T(n) = 100n3 + 20n2 + 100 + 2n

  8. (3 points) If you had three programs with the above running times, which one would you prefer if you were unsure about your input size but wanted to assume the worst (i.e., that the input sizes could be fairly large). Circle one of the following three letters to denote which program you would choose:
    b: as n gets large, the constant time program will be the fastest. Since we are unsure
       about the size of the input and are assuming the worst, we must assume that the input
       can be fairly large. Hence we prefer the constant time program, even though it has
       the largest constant.

  9. (8 points) Behold the following function:
         int mystery(int a[], int size) {
           int i;
           int sum;
           sum = 0;
           for (i = 0; i < size; i++) {
             sum = sum + a[i];
           return i;
    1. What is an appropriate measure for the input size (i.e., n)? The number of elements in the array, which is given by size.
    2. Write a function that gives a rough estimate for T(n). You do not need to show your work.
      T(n) = 3n + 3
      To see why the running time is what it is, we can rewrite the function as:
           int mystery(int a[], int size) {
             int i;
             int sum;
             sum = 0;
             i = 0;
             while (i < size) {
               sum = sum + a[i];
             return i;
      Now you can see that each iteration of the loop takes 3 instructions. The loop iterates n times, for a total of 3n instructions. The remaining instructions take 1 time unit each, and there are 3 of them. Hence the running time of 3n+3.

  10. (9 points) Consider the following code:
         int main(int argc, char *argv[]) {
           FILE *output_file;
           double sales_price;
    Assume that the above program takes five command line arguments that represent 1) the name of the output file, 2) the month, 3) the day, 4) the year, and 5) the sales_price.

    1. Write a fragment of code to open the output file for writing, test whether or not it was opened, and, if it failed to open, prints an error message that explains why it failed to open.
      output_file = fopen(argv[1], "w");
      if (output_file == NULL) {
    2. Write a statement to convert the last command line argument to a double and assign it to sales_price.
      sales_price = atof(argv[5]);
    3. Write an fprintf statement that writes a string to the output_file in the format:
      mm/dd/20yy $xxxx.xx    (e.g., 5/ 6/2008 $12.39)

      • mm represents the month.
      • dd represents the day
      • yy represents the year
      • xxxx.xx represents the sales price
      • The month, day, and year fields should all be two characters wide, even if the fields are only single digits.
      • The sales price should be left_justified. For example, if sales_price is 12.39, it should be printed as $12.39, not $ 12.39.
      fprintf(output_file, "%2s/%2s/20%2s $%-7.2lf\n", 
                           argv[2], argv[3], argv[4], sales_price);

  11. (9 points) For each of the following scenarios, choose from the following list the data structure that most efficiently and simply achieves the stated goal. Do not justify your answer.

    1. array: You want to read photo files in which the first line gives the number of rows and columns of pixels in the photo, and the remaining lines contain the pixels. You want to do certain operations on the photos, such as negate the pixels or print them out in reverse order

    2. linked list: You want to maintain a set of slides and you want to be able to conveniently and efficiently 1) delete slides, and 2) insert slides before or after another slide.

    3. linked list: You want to model a line of people waiting for tickets to a UT football game. You should be able to efficiently remove people from the front of the line and add people to the end of the line. You do not know the maximum number of people that may be in the line.

  12. (15 points) Write a function named max_word with the following characteristics:

    1. it has one parameter, which is a pointer to a character string that denotes the name of an input file.
    2. it creates an inputstruct for the file
    3. for each line in the file it prints the smallest word in alphabetical order on that line, prefixed with the number of that line.
    4. it releases the inputstruct when the file is fully read
    5. it returns a count of the number of words in the file As an example, given the input:
           how are you
           doing today and how
           do you think 
           you will
           do tomorrow?
      your function should produce the output:
           1: are
           2: and
           3: do
           4: will
           5: do
      and return the value 14.
      int max_word(char *filename) {
        IS input_file;
        int index;
        int i;
        int word_count = 0;
        input_file = new_inputstruct(filename);
        while (get_line(input_file) >= 0) {
          word_count += input_file->NF;  // count the number of words per line
          index = 0;
          // the simplest and most efficient way to keep track of the minimum word on
          // each line is to keep track of its index. We do not need to save a copy
          // of the word, because we do not need to do anything with a word after its
          // line has been processed
          for (i = 1; i < input_file->NF; i++) {
            if (strcmp(input_file->fields[i], input_file->fields[index]) < 0)
      	index = i;
          printf("%d: %s\n", input_file->line, input_file->fields[index]);
        return word_count;