C Programming Hints

Introduction

This document is a supplement to the C programming documentation An Introduction to Programming using the C Programming Language (abbreviated ItPutCPL) by Mike Mossinghoff and Rafael de la Llave. ItPutCPL is available on-line in `/usr/local/doc/programming/C-Class'.

This document, C Programming Hints, contains some additional information about programming in C on UNIX machines in the Math Department.

C in Emacs

GNU Emacs has a special mode called c-mode for editing C source files. When you visit a .c or a .h file, Emacs automatically puts you in c-mode. One of the nice features of c-mode is automatic indentation. Type TAB at the beginning of a line to position the point (a.k.a. cursor) at the right indentation for that line. As usual, you can do C-h m to find out more about the current mode.

GNU Emacs also has a function for compiling source files. The Emacs function compile can help you compile C files. If you have errors in your C files, C-x ` will take you to the position in you C files where the first error occured. You'll also see a message describing the error. Subsequent C-x ` commands take you to the next errors. To learn more about compile, type C-h C-f compile.

Emacs can find function definitions. For example, say you are developing a program that consists of several .c files. You remember that you need to change a function called foo(). Where is foo()? Assuming that you have run an indexing program called etags on your program files, all you have to do it to type M-. foo. Emacs will open the file containing the definition of foo(), and Emacs will put the point (a.k.a. cursor) at the beginning of the definition.

Finally GNU Emacs has a mode for debugging programs. M-x gdb starts the GNU debugger gdb in a buffer. For more information on this mode, type C-h C-f gdb. See section Debugging.

See section `Introduction' in Introduction to Gnu Emacs, for more information about the Gnu Emacs editor.

C Compilers

The Math Department UNIX machines have several C compilers:

We recommend that you use gcc. Gcc has lots of features, produces fast executables, and is available on several varieties of computers. Gcc has a UNIX man page and an Emacs info node (C-h i). (See section `Manual Pages' in Introduction to UNIX, for more information about man pages.)

As usual, check the man pages for more information about these compilers.

Debugging

Occasionally -- very, very rarely -- your programs don't behave as you expect. One approach to figuring out what's going on is to insert various printf statements in you code. Then recompile, rerun, repeat. You might have to go throught this process a bunch of time before you isolate the problematic chunk of code.

There's a better way. Use a source-level debugger. Source-level debuggers allow you to step throught the execution of you code. You can examine and change values of variables. You can also call functions and set break points.

Here's a list of the debuggers we have:

We recommend gdb. Gdb is a very flexible debugger, and GNU Emacs has a nice interface for gdb. In GNU Emacs 19 (emacs19), start a gdb session with M-x gdb. Gdb also has in Emacs info node. See section `Emacs Info' in Introduction to Gnu Emacs, for information about Emacs info.

Note that to use a source-level debugger, you must compile your files with the -g compiler flag. This flag tells the compiler to include debugging information in the object files. See the man page for you favorite compiler for more information about compiler flags.

Optimizing

After you've debugged your program, you might want to attempt to make it run faster. In order to improve the running time of your program, it's helpful to know where the program spends most of its time. For example, if 80% of a program's execution time is spent in a function called foo(), then foo() is a good place to look for speed-ups. You can use the program prof to gather execution statistics for programs. Check the man page for prof for more information.

Make

Most non-trivial C programs consist of several .c and .h files. To build a multi-file program, you can compile each file by hand and then link them all together. When you change a file, you'll often need to recompile other files due to dependencies. A UNIX program called make helps to automate this process of building multi-file programs.

The idea is that you write a makefile which contains instructions about how to build your program. After making changes to various files, you simply type make to rebuild your system. If your makefile is written correctly, only the files that have to be recompiled are. See the man page for make for more information.

Choosing the Right Language

Our computers have several programming languages. Some of the more useful ones are Maple, C, Perl, and Lisp. Once you've decided that a computer can help you solve a certain problem, you should consider which tool or language is most appropriate. For example, if you need to invert a matrix of large integers, you should probably use Maple. It would take a good C programmer longer to write an C program do the same thing -- even considering the (short) time it takes one to learn enough Maple to get the job done.

C is a fairly low-level language. Unlike Maple and Lisp, you must allocate and free your own memory. C is also a static language: to change your program's behavior, you must exit, recompile, and restart the program. In Maple and Lisp, you can simply redefine things in the middle of a computation. C also lacks some higher-level features found in other languages. For example, if you want to use really big integers, hash tables, or graphics, you have two choices: You could locate, compile, and learn a package somebody else developed to do what you want, or you could write your own. C's advantages are good control over the hardware and decent portability across platforms.