1. Goals for this week
-
Learn how to write C library code, and how to link it into programs that use it
-
Learn what
.c
and.h
files are -
More practice with strings in C (and using the
readline
library) -
Practice with Dynamic 2-D arrays (Method 2: the programmer friendly but space inefficient, way)
2. Starting Point Code
Start by creating a 11 directory in
your cs31/weeklylabs
subdirectory and copying over some files:
$ cd ~/cs31/weeklylabs
$ mkdir week11
$ cd week11
$ pwd
/home/you/cs31/weeklylabs/week11
$ cp ~newhall/public/cs31/week11/* ./
$ ls
3. Writing a C library
We are going to learn how to write a C library and how to use it in a program.
First, let’s look at some documentation about Libraries in C. We are going to look at the "CREATING AND USING YOUR OWN LIBRARY CODE" part of this. This content is also available in in Section 2.9.6 of the textbook.
Next, lets look at an example C library implementation, starting with the
library interface in mylib.h
, and the implementation in mylib.c
.
Then let’s look at an example program that uses it (prog.c
), and
try compiling and running it.
Phases of Compilation contains some information about the preprocessor and other compilation phases.
4. make and Makefiles
We have been using make
and Makefiles
all semester. When make
is run
it reads the Makefile
to find the rules for compiling or for cleaning up
compiled files.
We are not going to talk about make today, but if you are curious,
here is some documentation about writing makefiles:
Makefiles.
After looking this over, open in vim the Makefile
you copied over with
today’s in-class code and see if you understand what it is doing. I’ve added
some comments to describe some parts of it. Also, fancyMakefile
is another
version of a Makefile
for building the prog
executable. It uses some more
advanced features of make. You could try compiling using it by
running make -f fancyMakefile
, and make clean -f fancyMakefile
.
5. Strings and chars in C
Let’s look at the file str.c
. This code contains some examples of
manipulating strings (and individual chars in a string) in C.
Remember, that in C, a string is an array of char with a special
terminating null character '\0'
that signifies the end of the string.
The array
of chars can be statically or dynamically allocated (by calling malloc
).
One thing to remember is to allocate enough space for the terminating
null character.
This code also shows an eample of using the readline
library to read in a
string entered by the user. There is some documentation about the readline
library here:
The
readline library.
Let’s look at the man page for readline and see what it does, how to call
it, and what it returns:
man readline
The call to readline
returns a string (allocated in heap
space) to the caller containing the contents of the input line. It is the
caller’s responsibility to free this returned string.
Let’s take a look at this code and see what it is doing. Note its uses
the ctype and string library functions. C string library functions assume
that the caller has allocated space for the result string (note the call
to strcpy
).
Some example use of string library functions:
strcmp, strlen, strcpy, strstr, strchr,
Some example use of C library functions for testing char values:
isalnum, isdigit, isspace
Chapter 2.6.3 contains information about string library and C library functions for char values.
Their man pages will also give more information about how to use them.
man strcmp
man isspace
5.1. Try out
-
In another window, compile and run this program to see what it is doing. Note when it is manipulating the individual char in the string (array of chars) and when it is treating it as a string (using
strcpy
,strlen
).
Try running with some different input strings, for example:
hello 1 2 3
hello 1 2 3
!@ hello x%
-
Next, try implementing code to create a substring for the first token in the str string:
-
search for the start of the first token (the first non-space char)
-
continue processing chars until find end of first token (the first space char following sequence of non-spaces)
-
change the char at the end of the first token to '\0'
Make the substr pointer point to the beginning of the first token and try printing it out. One way to set a pointer to point to any bucket in an array is:
ptr = &(array[i]);
Compile and try running with different input strings and see if it works.
-
6. Dynamically allocated 2-D arrays (an array of arrays)
We are going to look at an example of the "Method 2" way of dynamically
allocating a 2D array. This way supports [i][j]
indexing, but it is
less memory efficient than the single malloc
("Method 1") way of allocating
2D arrays.
This method allocates a 2D array as an array of arrays. In the outer array (of row dimension) each element stores the base address of an inner array ( of column dimension) of values in each row of the 2D array. Section 2.5 of the textbook describes this, and includes an figure of what this version of a 2D array looks like in memory.
This type of 2D array is used for the argv
2D array of char
that contains
the command line argument values passed to execvp
(or as a parameter to
main
).
In this method, the programmer makes num_rows + 1
calls to malloc
:
-
one
malloc
to dynamically allocate an array oftype *
that will store the base address of an array to store each row’s values. -
num_rows
mallocs
to dynamically allocate arrays oftype
to store the values in each row of the 2D array. The base address of each is stored in theith
bucket of the outer array.
The variable storing the base address of the outer array is a type **
:
a pointer to a storage location that stores a type *
(which stores the
base address of an array of type
). For example:
int **2d_array;
char **2d_chararr;
-
Let’s look at the example in
twoD_method2.c
. -
Next, try implement the two functions that it calls.
-
Next, try adding code to free its dynamically allocated space.
-
Next, run in valgrind and see if you have any memory access errors:
valgrind ./twoD_method2
7. Handy References
-
-
C arrays, strings and the string library (Chapt 2.5, 2.6)
-
C dynamically allocated 2D-arrays (Chapt 2.5.2 Method 2)
-
Writing C libraries (Chapt 2.9.6)
-
Command line arguments (Chapt 2.9.2)
-
-
C programming
-
C debugging
-
Chapter 3 on gdb and valgrind
-
Unix