CSC161 2010F Imperative Problem Solving
[Skip to Body]
Primary:
[Front Door]
[Schedule]
-
[Academic Honesty]
[Instructions]
Current:
[Outline]
[EBoard]
-
[Assignment]
[Lab]
Groupings:
[EBoards]
[Assignments]
[Examples]
[Exams]
[Handouts]
[Labs]
[Outlines]
[Readings]
Related Courses:
[CSC195 2003S (Rebelsky)]
[CSC161 2009F (Coahran)]
[CSC161 2010S (Walker)]
Misc:
[SamR]
[ISO]
[GNU Coding Standards]
Summary:
Prerequisites: Familiarity with C, up through functions.
a. Create a directory for this lab. I'd recommend CSC161/Libraries
.
b. In that directory, create a Makefile
with the following
lines
CFLAGS=-Wall LDFLAGS=-lm
a. Create a file, mylib.c
, that contains one function,
int average(int values[], int count)
, which computes the
average of an array of values.
b. Obviously, one thing you'd like to do is test that code. We might
start with a simple test. Create a file test1.c
, with
the following code:
#include <stdio.h> int main () { int values[] = {1,2,3}; printf ("%d\n", average(values, 3)); return 0; } // main
c. One way to compile the two files together is by using both source files. Write
% cc -o test1 test1.c mylib.c
Note: You'll probably get a warning message because test1.c
does not officially know about average
. That's okay, it's
just a warning.
d. Run the resulting file (./test1
).
e. Remove test1
.
You'll note that our program has two source files: test1.c
contains the main
function and mylib.c
contains
the average
function that gets called by main
.
What happens if we try to use them separately?
a. What do you expect to happen if you compile test1.c
without
including mylib.c
?
b. Try it
make test1
c. What do you expect to happen if you compile mylib.c
without
including test1.c
?
d. Try it
make mylib
It turns out that we're often better off compiling each file separately. That way, if we make a change to one file, we reduce the work required to rebuild our program - we only need to recompile that one file and then join the compiled files together.
a. Create an object
file from mylib.c
with
% make mylib.o
b. Create an object
file from test1.c
with
% make test1.o
c. Link
the two files together with
% cc -o test1 mylib.o test1.o
d. Confirm that the resulting program works as expected.
e. Remove test1
and both .o
files.
The previous exercise gives you a lot of steps to remember. First you
have to make each .o file. Then you have to link them together. (Okay,
maybe it's not that many steps.) How do you remember the steps?
Often, we just tell make
about them.
a. Add the following lines to your Makefile
. (Note that you
must use a tab for the indented line.)
test1: test1.o mylib.o gcc -o test1 test1.o mylib.o
These lines tell make
two different things:
test1
requires test1.o
and mylib.o
test1
, you use the command gcc -o test1 test1.o mylib.o
b. Type
make test1
c. Run test1
.
d. Make an update to test1.c
(e.g., use a different array).
e. Make test1
again. What steps were redone? What steps
were not redone?
Okay, we've been getting a lot of warnings about the compiler not
knowing enough about average
. Let's solve that problem.
a. Create a file mylib.h
with the following line.
int average (int values[], int count);
b. At the top of mylib.c
, add the line
#include "mylib.h"
c. At the top of test1.c
, add the line
#include "mylib.h"
d. Remake your program and verify that the warning has disappeared.
Suppose we made a mistake in the header. What will the effect be?
a. Update mylib.h
so that it suggests that average
has a third parameter.
b. What do you expect to happen when you remake test1
?
c. Check your answer experimentally.
d. What happened? Well ... make
didn't know that a change
to mylib.h
was supposed to require recompilation. So you
need to tell it so. Add the following lines to your Makefile
.
mylib.o: mylib.h test1.o: mylib.h
e. Now, what do you expect to happen when you remake test1
?
f. Check your answer experimentally.
g. We hope that you discovered that the program will not compile with the mismatched errors. So, correct the header in preparation for the next exercise.
One of the reasons we use separate files is that it lets us swap the implementations of different functions.
a. Create the file yourlib.c
with the following lines
#include "mylib.h" int average (int values[], int count) { // The average grade is a B, and a B is an 85. return 85; } // average
b. Add lines to your Makefile
that link yourlib.c
and test1.o
and call the result test1a
.
c. Make test1a
.
d. Run the program.
Note that we are also supposed to be able to share variables between files. Let's try doing so.
a. Add the following to myutil.h
int reset (); int increment (); int counter;
b. Add #include <stdio.h>
to the top of
myutil.c
(unless you already have it there).
c. Add the following to myutil.c
int reset () { counter = 0; } // reset int increment () { ++counter; printf ("Counter is now %d.\n", counter); } // increment
d. Create a new program, test2.c
with the following lines:
#include <stdio.h> #include "myutil.h" int main () { counter = 5; printf ("Counter is now %d.\n", counter); reset (); printf ("Counter is now %d.\n", counter); increment (); printf ("Counter is now %d.\n", counter); counter = 10; increment (); printf ("Counter is now %d.\n", counter); } // main
e. Add lines to your makefile to make test2
from
mylib.c
and test2.c
.
f. What output do you expect when you run the program?
g. Check your answer experimentally.
h. As you may have discovered, what you've done is accidentally create
two versions of the variable counter
, one in
mylib.c
, one in test2.c
. How do we share the
variable? We use the extern
prefix in the declaration
in mylib.h
.
extern int counter;
i. What do you expect to have happen if you make this change?
j. Check your answer experimentally.
k. You've now discovered that you need at least one declaration of
counter
. Add that to mylib.c
.
Write a program that takes a series of numbers on the command line
(no more than twenty) and uses average
to find their
average.
[Skip to Body]
Primary:
[Front Door]
[Schedule]
-
[Academic Honesty]
[Instructions]
Current:
[Outline]
[EBoard]
-
[Assignment]
[Lab]
Groupings:
[EBoards]
[Assignments]
[Examples]
[Exams]
[Handouts]
[Labs]
[Outlines]
[Readings]
Related Courses:
[CSC195 2003S (Rebelsky)]
[CSC161 2009F (Coahran)]
[CSC161 2010S (Walker)]
Misc:
[SamR]
[ISO]
[GNU Coding Standards]
Disclaimer:
I usually create these pages on the fly
, which means that I rarely
proofread them and they may contain bad grammar and incorrect details.
It also means that I tend to update them regularly (see the history for
more details). Feel free to contact me with any suggestions for changes.
This document was generated by
Siteweaver on Tue Oct 5 11:34:23 2010.
The source to the document was last modified on Tue Oct 5 11:34:21 2010.
This document may be found at http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2010F/Labs/libraries-lab.html
.
A PDF version of this document may be found at
http://www.cs.grinnell.edu/~rebelsky/Courses/CSC161/2010F/Labs/libraries-lab.pdf