Prev Next

A Few Loose Ends

Typedefs

You can give names to types using typedefs. Declaration

  typedef oldT newT;
declares name newT to be a new name for a previously declared type oldT.

Example
  typedef char* charptr;
declares charptr to be a name for type char*.

If you write

  charptr x,y;
both x and y will have type char*. You can get around some difficulties of C/C++ using typedefs. For example, there is no type for true/false data. Instead, a truth value is just an integer, with true being 1 and false being 0. You can write

Example
  typedef char boolean;
defines type boolean to be the same a char.

The preprocessor

When a C or C++ program is compiled, it is first passed through a preprocessor, which makes some modifications to the program. One thing that the preprocessor does is to expand includes. When you write

#include <cstdio>
the preprocessor inserts the contents of file stdio.h in place of the include line. Include lines can have the file name enclosed in <...> or in "...". If you use <...>, the preprocessor looks for the file in the directory that has standard header files. If you use "...", the preprocessor looks for the file in the current directory.

The preprocessor provides a macro facility. If you write

#define NULL 0
for example, each occurrence of NULL will be replaced by 0 by the preprocessor. Note that there is no semicolon. If you write
#define NULL 0;
then each occurrence of "NULL" gets replaced by "0;", which is probably not what you want. #define lines are one line long. The preprocessor is not free-form.

Macros can have parameters. You can write

#define max(x,y) ((x) > (y) ? (x) : (y))
to create a macro for computing the maximum of two values. max(n,0) would be replaced by (n) > (0) ? (n) : (0). You should always put parentheses around arguments in macros, as has been done here, or you can get very strange effects from the textual substitution done by the preprocessor.

Note: Preprocessor directives start with a # in column 1. Don't indent the #.

The preprocessor can also be used to make decisions at compile time. A common kind of decision is to ask whether a symbol is defined. A definition of NULL might look like this.

#ifndef NULL
#define NULL 0
#endif
This says to compile what is between #ifndef NULL and #endif only if NULL is not a defined preprocessor macro. This kind of thing is commonly used in header files (described in the next section) to prevent them from being read more than once by the compiler. A file called myhead.h typically has the form
#ifndef MYHEAD_H
#define MYHEAD_H
...
#endif
The first time the file is read, and MYHEAD_H is defined. Subsequent times, the entire file is skipped.


Prev Next