CS140 Midterm Exam - October 5, 2004 -- Answers and Grading
Question 1
No real commentary necessary -- just grab
p1.c and
inputfile, and run it:
UNIX> p1 < inputfile
4
3
5
3
72
UNIX>
|
What does it do? If the third word is a number, it prints the number. The only
lines that are not numbers are the "Davis Love III", "# Comment" and "E. Power Biggs"
lines.
Grading
This is 6 points. Six easy points, if you ask me. If you included
extra lines (e.g, zeros or something for the non-numeric lines), you
received half credit.
If you forgot newlines, you lost two points.
Question 2
The point of this question was to make you do a little code reading,
and show that you understand some C basics.
Again, you may run this yourself -- here's p2.c.
UNIX> p2 < inputfile
T Character zero of "Tiger"
i Character one of "Singh"
5 Character 2%1=0 of "5"
2 Character 3%2=1 of "72"
# Character 4%1=0 of "#" (word 4%2=0)
9 Character 5%2=1 of "69"
e Character 6%4=2 of "Cher" (word 6%6=0)
g Character 7%5=2 of "Biggs" (word7%5=2)
UNIX>
|
This program is a little sloppy -- i and j are always the
line number (zero-indexed). You pick the i-th word (modulo the
number of fields), and the j-th character (modulo the string length),
and print it out with a newline.
Grading
This is 6 points -- you start with six, and lose one per incorrect
line (you can't go negative). You lose one if you forgot newlines.
Omitted lines are minus one.
Question 3
The point of this code (p3.c) was to crunch
through some basics of dllists.
You have one dllist. Odd lines are prepended. Even lines are appended.
The first line number is one, not zero.
Therefore, with each successive line, the list is:
Tiger (Prepend)
Tiger Vijay (Append)
Phil Tiger Vijay (Prepend)
Phil Tiger Vijay Davis (Append)
# Phil Tiger Vijay Davis (Prepend)
# Phil Tiger Vijay Davis Sergio (Append)
Cher # Phil Tiger Vijay Davis Sergio (Prepend)
Cher # Phil Tiger Vijay Davis Sergio E. (Append)
And the output is:
UNIX> p3 < inputfile
Cher
#
Phil
Tiger
Vijay
Davis
Sergio
E.
UNIX>
|
Grading
Six points again. You lost a point for reversing the output (zero-indexing
the line number). You lost two points if you stripped out the comment, since
there is no code to do so.
Question 4
This was some stack and queue code.
Odd lines get enqueued on the queue,
and even lines get pushed onto the stack. Lines are zero-indexed. Therefore,
here is the result of each input line:
s = "Tiger" | q = |
i=0 -- Push onto stack |
s = "Tiger" | q = "Vijay" |
i=1 -- Enqueue onto queue |
s = "Phil", "Tiger" | q = "Vijay" |
i=0 -- Push onto stack |
s = "Phil", "Tiger" | q = "Vijay", "Davis" |
i=1 -- Enqueue onto queue |
s = "#", "Phil", "Tiger" | q = "Vijay", "Davis" |
i=0 -- Push onto stack |
s = "#", "Phil", "Tiger" | q = "Vijay", "Davis", "Sergio" |
i=1 -- Enqueue onto queue |
s = "Cher", "#", "Phil", "Tiger" | q = "Vijay", "Davis", "Sergio" |
i=0 -- Push onto stack |
s = "Cher", "#", "Phil", "Tiger" | q = "Vijay", "Davis", "Sergio", "E." |
i=1 -- Enqueue onto queue |
So the output is:
UNIX> p4 < inputfile
Cher
#
Phil
Tiger
Vijay
Davis
Sergio
E.
UNIX>
|
Grading
Six points again.
You lost two points if you stripped out the comment, since
there is no code to do so.
You lost one point if you forgot the newline between the stack
and queue.
Question 5
Given that first line of output, we know the following things:
- The first element of a starts at 0xbffff9b0. a[1]
is stored at location 0xbffff9b4. Each successive element is four
past the previous element.
- ip is stored in 0xbffff9e0. Its value starts at the location
of a[3]: 0xbffff9bc. Then it is incremented by four, so that by
the time it is printed, its value is 0xbffff9c0, which points to a[4].
- ipp is stored in 0xbffff9e4. Its value is 0xbffff9e0. That does
not change when ip is modified.
- After setting ip and ipp, the value of a[3] is set
to 11, and then to 21. Ip is then incremented by four, so that it points
to a[4]. So a[4]'s value is changed to 31, and then to 41.
So, the output of the program is:
UNIX> p5
0xbffff9b0 0xbffff9e0 0xbffff9e4
0 1 2 21 41 5 6 7 8 9
0xbffff9c0
0xbffff9e0
0xbffff9b0
0x1
UNIX>
|
Pictorally, here is the state of the system after executing "ipp = &ip."
This is what you know from the first line of output:
The following pictures will show the next few lines of the program, and
their effect on memory. From that you can generate the output:
Grading
Six points again. Three of these points were trivial -- the values of
ipp, &a[0], and a[1] are unchanged throughout the
program. Two points are allotted for the first line, and one for the
second line. I was not liberal with partial credit.
Question 6
Ok -- a non-trivial program, but it is broken up into straightforward
parts. You do not need to store anything past a line, so no malloc()'s
or strdup()'s are necessary. You simply need to read each line, and
do the following:
- Ignore the line if it is a comment. Note, that should be when
is->text1[0] is '#', not when is->fields[0][0] is '#'.
- Figure out where n is. It should be the first word that
is a number, which you may determine with sscanf().
- Read in the n scores, keeping a running total.
- Print out the average.
- Now print out the name using a for or while loop, printing
out each word until you get to the word that holds n.
The only subletly is whether to handle a zero value of n. I said
that all input files are legal, but is one with a zero value of n
legal? You had to consider the problem, and either handle it in your
code, or specify to me that you didn't consider such files legal.
Here is the answer
(digest.c).
#include < stdio.h >
#include "fields.h"
main()
{
IS is;
double n, score;
double total;
int nfield, i;
is = new_inputstruct(NULL);
while (get_line(is) >= 0) {
/* Check for comments */
if (is->text1[0] != '#') {
/* Find the field that holds n. Note that this loop both does
that and has n set when it is done. */
for (nfield = 0; sscanf(is->fields[nfield], "%lf", &n) == 0; nfield++) ;
/* Now scan in the scores and add them to the total */
total = 0;
for (i = nfield+1; i < is->NF; i++) {
sscanf(is->fields[i], "%lf", &score);
total += score;
}
/* Print out the average. This assumes that n=0 is an illegal value */
printf("%10.4lf", total/n);
/* Finally, print out the name and the newline */
for (i = 0; i < nfield; i++) printf(" %s", is->fields[i]);
printf("\n");
}
}
}
|
Grading
Eight points:
- Dealing correctly with comments: 1 point
- Finding n: 1 point
- Setting n properly: 1 point
- Scanning in the scores: 1 point
- Computing the average properly: 1 point
- Dealing with n equal to zero: 1 point
- Printing out the name: 2 points