You’re in the right place if you want to expand your programming skills into the realms of C and C++ while picking up some useful programming techniques at the same time. You’ll also learn basic UNIX skills and get experience with a number of widely-used development tools.
Catalog Description: This course covers intermediate to advanced programming in both C and C++. The focus of the course is on programming techniques and development tools. Students are expected to learn syntax and basic language features independently. Coursework involves significant programming projects in both languages.
Prerequisite(s): 600.107: Introduction to Programming in Java. (For some assignments, 600.226: Data Structures is also useful.)
Policies: Please read the general course policies and take them to heart. The following course-specific policies are also in effect. Additional policies may be posted at a later date.
There is no required text. However, the following two books are highly recommended if you want to really learn C and C++ well. Neither covers exactly what we’ll do in the course, and both cover things we’ll never even mention, but they are excellent books in any case.
Homework assignments are designed for you to practice certain skills and techniques, they are not formally graded. If you want feedback on your solutions, please ask in office hours.
Programming projects are designed to evaluate how good of a software developer you are. They are formally graded. Please check the individual projects for due dates and the structure your solutions should have. See our Piazza site for detailed submission instructions.
This is not a schedule. It’s a “log” of what we did, roughly, in each lecture. Don’t expect it to turn into a schedule, it won’t.
man, etc.), a first C program, compiling and running C programs, exit status to terminal/shell.
manto look up C library functions, compiler warnings and how to get more of them, using
maketo build a simple C program, using
Makefileto set compiler options, a few more shell commands (
file, etc.), basic types (
charand why we should look at it as a “small integer”,
stdbool.hand some C history to go with it,
unsignedand why it’s often dangerous to use), a first introduction to strings (using
char xbut we need more to cover them deeply), basic control (
do, and even the dreaded
goto), the standard I/O streams and what they are good for (
stderr), a first useful C program:
cat.c, I/O redirection and pipelines in the shell.
make(targets and dependencies, rebuild if newer, “fake” targets like
test, etc.), using
tar) to create archives for project submission, intro to testing, basic shell scripting to automate testing, the
diffcommand, intro to arrays (no bounds checking!), global variables (initialized to 0) versus local variables (not initialized), more details on strings (including the terminating zero byte), the
strcatfunctions, associated memory management challenges.
valgrindto detect memory access errors (works on compiled code, slows down the program, should use
-gfor best results, read
valgrindmessages carefully, finds more than just out-of-bounds issues), notes on testing with and without
valgrind, strings again (fixed size arrays, cannot “grow” as in Java, the
NULterminator), example of missing
NULleading to memory errors, string functions
strcatagain, difference between
*sstrings (read-only data!), the
NULL, command line arguments (
argv, two ways of declaring
argv, hint about
getoptfunction for flags/options), writing a simple
grepclone (the hard way, no
fgetsallowed, discussion of buffer sizes and powers of two), intro to structs, nesting structs for hierarchical data.
voidparameter lists versus empty parameter lists, passing parameters (values), local variables, the strange case of array parameters (pointers, more on Thursday), a brief tutorial on the
gdbdebugger (see links on Piazza, I followed that tutorial pretty closely), streams and files, the
fclosefunctions to open and close files, “What thou fopen()st, thou shalst fclose()!”, the
fputcfunctions, brief detour about
perrorfunction, file positions/offsets and the
fseekfunctions (also brief mention of
%pto print pointers, visualizing pointers, pointers to pointers (to pointers…), why the pointer declaration syntax is tricky (see style guide as well), arrays and pointers, “In most contexts, the name of an array converts to a pointer to the first slot of the array.”, the
sizeofexception, why functions receiving array parameters can modify those arrays, pointer arithmetic (pointer + int -> pointer, pointer - pointer -> int, scaling in terms of
sizeofthe element type), what
a[i]really means (including why
i[a]works just as well).
strcpy, array-style versus pointer-style, historical context for pointer-style, “Write clean code, not tricky code!”, unit testing our string functions, using the library’s
strcpyas test oracles (known correct!), using
assertto write unit tests (including the drawback that one failed test case stops the test driver), dynamic memory allocation,
free(no garbage collector), using
valgrindto find memory leaks, error messages from the standard library (double free for instance), the
callocfunction, historical context, avoiding extra work by picking
calloccorrectly, idea of linked lists, the
revprogram to reverse a file character-by-character.
revprogram, abstraction: the idea of a stack data structure, the
rev.cwith a stack abstraction (much cleaner
main), reusable abstractions: moving the stack out of
revitself, independent compilation in C, object files vs. executable programs, the job of the linker, extracting the stack code from
stack.c, adjusting the
Makefilefor independent compilation, some sad truths about the linker (language independent, doesn’t grok C, just uses names to “link” things), introducing a
stack.hheader file to describe the stack’s interface,
stack.cto ensure consistency (compiler can now check what the linker cannot), unit testing the stack “by itself” using
kvs.hinterface from Homework 5, implementing and testing the interface, the trickyness of C memory management (what if
strdupkeys and values), the
constqualifier (read-only variables, application to pointers).
staticto “hide” global definitions (of functions and variables) from the linker, comparison to
privatein Java, simplify code when possible, example of
free(NULL)being valid so guarding
ifcan be removed, more refactoring in
kvs.c, examples in
kvs_replace_valueresulting in cleaner
kvs_insertcode), difference between using
assertto check preconditions and “programming errors” versus checking “documented errors” with error codes and return values, introduction to coverage analysis (line coverage, branch coverage, path coverage), what does 100% line coverage mean for testing, the
--coveragecompiler/linker option, the
kvs.c, using coverage reports to find missing test cases, heuristic for loops, “One, two, three, good enough for me!”, advice for Project 2, how to approach the simplest possible solution, how to extend it step-by-step into a conforming solution.
fancy_putsexample, passing function pointers,
integrateexample to compute the definite integral of a real function, how
sdbm_applyworks in Project 2, using
addr2lineto help debug
glibcmemory corruption errors (don’t forget
-gfor debugging symbols!), the stack reconsidered, implementing the interface using “growing” arrays, lazy initialization, trouble with
stack.hnot defining a
freefor the stack, the stack reconsidered again, generalizing to multiple stacks, use “incomplete”
struct stackas a “handle” in
stack.h, “complete” the struct in
privatein Java or C++!).
geeqie, hint about
pnmtoplainpnmin Ubuntu, two-dimensional arrays, detailed discussion (and experiments!) regarding passing two-dimensional arrays to functions, the why behind the restriction that only the first dimension can have “open ended” index range, why
double **matrixdoesn’t work with statically allocated two-dimensional arrays, using an Iliffe vector to make
matrix[i][j]work (also the
argvconnection), using a one-dimensional array instead and manually computing offsets as
fakematrix[i * columns + j](as required for Project 3), brief disgression into
freeknows how much it’s freeing, discussion of the
image.hinterface from Project 3, disgression into memory access patterns and performance implications (mentioned caches, you can find out more in 600.229: Computer Systems Fundamentals).
*(*(m + i) + j)even for “squarely” allocated matrices, details about the
(*)type that shows up, the sweet C99 extension for passing multi-dimensional arrays, review of
const intfor constants, introduction to
enumtypes as a useful alternative, brief excursion into C silently converting between
enumtypes, introduction to basic
#definemacros and their pitfalls, one “useful” macro to compute the number of slots in an array (works only if the type is still visibly an array!) and why we cannot write that as a function, a brief excursion on
unionand what it does, started on bitwise operations on unsigned integers.
struct sdbm_dbaffect many of the functions that operate on it (they all must be changed consistently), started to work on generalizing it to dynamically allocate the
struct entryarray, posted a version that also “grows” the array after class.
statickeyword for local variables, discussion of “scope” and “lifetime” of variables, the
constkeyword again, making pointer and pointee
constas it were, using
typedefto introduce new names for existing types, uses for
typedefboth good (function pointers) and (usually) bad (
struct, basic types), more on bitwise operations, especially shifting left and right using the
>>operators, example of encoding/decoding complex information in (parts of) unsigned integers, brief mention of “bitfields” as something to look up, brief discussion of using
void *and explicit “size” parameters to implement “generic” abstractions, brief discussion of
bsearchfrom the standard library, hint regarding “casting” in C, something we were able to stay away from throughout the entire course.