Lecture 6 - Data Structures: Hal Perkins
Lecture 6 - Data Structures: Hal Perkins
Administrivia
Exercises:
- ex5 is out: clean up the code from section yesterday, split into
HW:
- HW1 due very soon; get going NOW if you havent yet
Todays topics:
- implementing data structures in C
- multi-file C programs
- brief intro to the C preprocessor
- the last node in the list contains a NULL pointer (or some
head
element Y
element X
element next
n1
1
element next
n2
NULL
manual_list.c
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
NULL
// crashes if false
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
NULL
// crashes if false
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
NULL
(POL) head
NULL
(POL) e
(POL) n
???
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
NULL
(POL) head
NULL
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
???
???
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
NULL
(POL) head
NULL
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
???
???
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
NULL
(POL) head
NULL
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
???
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
NULL
(POL) head
NULL
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
NULL
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
NULL
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
NULL
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
NULL
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
???
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
element next
NULL
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
???
???
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
???
???
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
???
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
(POL) head
(POL) e
(POL) n
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
(main) list
// crashes if false
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
PushOntoList
push_list.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
a (benign) leak!!
try running with valgrind:
// crashes if false
return n;
}
int main(int argc, char **argv) {
Node *list = NULL;
list = Push(list, 1);
list = Push(list, 2);
return 0;
element next
NULL
element next
}
CSE333 lec 6 C.5 // 06-29-12 // perkins
element
// crashes if false
next
element
next
NULL
return n;
CSE333 lec 6 C.5 // 06-29-12 // perkins
manual_list_void.c
(main) hello
(main) list
element
. \0
next
element
next
! \0
NULL
CSE333 lec 6 C.5 // 06-29-12 // perkins
Multi-file C programs
Lets create a linked list module
- a module is a self-contained piece of an overall program
Modularity
The degree to which
components of a system
can be separated and
recombined
- loose coupling and
main program
separation of concerns
- modules can be
linked
list
hash
table
developed independently
- modules can be re-used
in different projects
C header files
header: a C file whose only purpose is to be #included
- generally a filename with the .h extension
- holds the variables, types, and function prototype declarations
C module conventions
Most C projects adhere to the following rules:
- .h files never contain definitions, only declarations
- .c files never contain prototype declarations for functions that
Csource code
- processes the directives it finds in your code (#something)
Example
cpp_example.h
bash$ cpp -P cpp_example.c out.c
bash$ cat out.c
#define FOO 1
#include "cpp_example.h"
int main(int argc, char **argv)
{
int x = FOO;
// a comment
int y = BAR;
verylong z = FOO + BAR;
return 0;
}
cpp_example.c
CSE333 lec 6 C.5 // 06-29-12 // perkins
#include "ll.h"
ll.c
return 0;
}
example_ll_customer.c
ll.h
CSE333 lec 6 C.5 // 06-29-12 // perkins
Payload: 'yo!'
Payload: 'goodbye'
Payload: 'hello'
bash$ valgrind --leak-check=full ./example_customer
...etc.
Building systems
This doesnt really scale: gcc -Wall -g -o gadget *.c
- Could take hours (think gcc source, linux kernel, etc.)
Directly or indirectly...
Build dependencies
All build tools work from same core idea: capture build
dependencies and recompile only whats needed
ex: Dependency graph for example_ll_customer
example_ll_customer.c
ll.h
example_ll_customer.o
ll.c
ll.o
example_ll_customer
CSE333 lec 6 C.5 // 06-29-12 // perkins
make
Venerable unix tool to automate build tasks
Input is a Makefile with rules describing dependencies:
target: sources
tab char command(s)
Meaning: if any source is newer (file system timestamp)
than target then run command(s)
- Nothing actually requires command(s) to have anything to do
Exercise 1
Extend the linked list program we covered in class:
- add a function that returns the number of elements in a list
- implement a program that builds a list of lists
make sure your linked list code, and customers code that uses it,
contains no memory leaks
CSE333 lec 6 C.5 // 06-29-12 // perkins
Exercise 2
Implement and test a binary search tree
- http://en.wikipedia.org/wiki/Binary_search_tree
- implement it as a C module
bst.c, bst.h
- implement test_bst.c
Exercise 3
Implement a Complex number module
- complex.c, complex.h
- includes a typedef to define a complex number
contains main( )
CSE333 lec 6 C.5 // 06-29-12 // perkins