Los tipos de datos fundamentales y sus variantes son esenciales, pero más bien primitivos. C y C++ incorporan herramientas que permiten construir tipos de datos más sofisticados a partir de los tipos de datos fundamentales. Como se verá, el más importante de éstos es struct, que es el fundamento para las class en C++. Sin embargo, la manera más simple de crear tipos más sofisticados es simplemente poner un alias a un nombre mediante typedef.
Esta palabra reservada promete más de lo que da: typedef sugiere «definición de tipo» cuando «alias» habría sido probablemente una descripción más acertada, ya que eso es lo que hace realmente. La sintaxis es:
typedef descripción-de-tipo-existente nombre-alias
La gente a menudo utiliza typedef cuando los tipos de datos se vuelven un poco complicados, simplemente para evitar escribir más de lo necesario. A continuación, una forma común de utilizar typedef:
typedef unsigned long ulong;
Ahora si pone ulong, el compilador sabe que se está refiriendo a unsigned long. Puede pensar que esto se puede lograr fácilmente utilizando sustitución en el preprocesador, pero hay situaciones en las cuales el compilador debe estar advertido de que está tratando un nombre como si fuese un tipo, y por eso typedef es esencial. Un caso en el que typedef resulta útil es con los tipos puntero. Como se ha mencionado anteriormente, si escribe:
int* x, y;
Esto genera en realidad un int* que es x, y un int (no un int*) que es y. Es decir, el * se asocia a la derecha, no a la izquierda. Pero, si utiliza un typedef:
typedef int* IntPtr; IntPtr x, y;
Entonces ambos, x e y son del tipo int*.
Se puede argumentar que es más explícito y por consiguiente más legible evitar typedefs para los tipos primitivos, y de hecho los programas se vuelven rápidamente difíciles de leer cuando se utilizan muchos typedefs. De todos modos, los typedefs se vuelven especialmente importantes en C cuando se utilizan con struct.