Las soluciones a los ejercicios se pueden encontrar en el documento electrónico titulado «The Thinking in C++ Annotated Solution Guide», disponible por poco dinero en www.BruceEckel.com.
En la librería C estándar, la función puts() imprime un array de caracteres a la consola (de modo que puede escribir puts("Hola")). Escriba un programa C que use puts() pero que no incluya <stdio.h> ni declare de ningún otro modo la función. Compile ese programa con su compilador de C. (Algunos compiladores de C++ no son programas distintos de sus compiladores de C; en ese caso puede que necesite averiguar qué opción de línea de comandos fuerza una compilación C.) Ahora compílelo con el compilador C++ y preste atención a la diferencia.
Cree una declaración de struct con un único método, entonces cree una definición para ese método. Cree un objeto de su nuevo tipo de dato, e invoque el método.
Cambie su solución al Ejercicio 2 para que la struct sea declarada en un fichero de cabecera convenientemente «guardado», con la definición en un fichero cpp y el main() en otro.
Cree una struct con un único atributo de tipo entero, y dos funciones globales, cada una de las cuales acepta un puntero a esa struct. La primera función tiene un segundo argumento de tipo entero y asigna al entero de la struct el valor del argumento, la segunda muestra el entero de la struct. Pruebe las funciones.
Repita el Ejercicio 4 pero mueva las funciones de modo que sean métodos de la struct, y pruebe de nuevo.
Cree una clase que (de forma redundante) efectúe la selección de atributos y una llamada a método usando la palabra reservada this (que se refiere a la dirección del objeto actual).
Cree una Stash que mantenga doubles. Rellénela con 25 valores double, después muéstrelos en consola.
Repita el Ejercicio 7 con Stack.
Cree un fichero que contenga una función f() que acepte un argumento entero y lo imprima en consola usando la función printf() de <stdio.h> escribiendo: printf("%d\n", i) donde i es el entero que desea imprimir. Cree un fichero separado que contenga main(), y en este fichero declare f() de modo que acepte un argumento float. Invoque f() desde main(). Intente compilar y enlazar el programa con el compilador C++ y vea qué ocurre. Ahora compile y enlace el programa usando el compilador C, y vea qué ocurre cuando se ejecuta. Explique el comportamiento.
Averigüe cómo generar lenguaje ensamblador con sus compiladores de C y C++. Escriba una función en C y una struct con un único método en C++. Genere la salida en lenguaje ensamblador para cada una de ellas y encuentre los nombres de ambas funciones, de modo que pueda ver qué tipo de «decoración» aplica el compilador a dichos nombres.
Escriba un programa con código de compilación condicional en main(), para que cuando se defina un valor del preprocesador, se muestre un mensaje, pero cuando no se defina, se imprima otro mensaje distinto. Compile este código experimentando con un #define en el programa, después averigüe la forma de indicar al compilador definiciones de preprocesador en la línea de comandos y experimente con ello.
Escriba un programa que use assert() con un argumento que siempre sea falso (cero) y vea qué ocurre cuando lo ejecuta. Ahora compílelo con #define NDEBUG y ejecútelo de nuevo para ver la diferencia.
Cree un tipo abstracto de dato que represente una cinta de vídeo en una tienda de alquiler. Considere todos los datos y operaciones que serían necesarias para que el tipo Video funcione bien dentro del sistema de gestión de la tienda. Incluya un método print() que muestre información sobre el Video.
Cree un objeto Stack que almacene objetos Video del Ejercicio 13. Cree varios objetos Video, guárdelos en la Stack y entonces muéstrelos usando Video::print().
Escriba un programa que muestre todos los tamaños de los tipos de datos fundamentales de su computador usando sizeof.
Modifique Stash para usar vector<char> como estructura de datos subyacente.
Cree dinámicamente espacio de almacenamiento para los siguientes tipos usando new: int, long, un array de 100 char, un array de 100 float. Muestre sus direcciones y libérelos usando delete.
Escriba una función que tome un argumento char*. Usando new, pida alojamiento dinámico para un array de char con un tamaño igual al del array que se pasa a la función. Usando indexación de array, copie los caracteres del argumento al array dinámico (no olvide el terminador nulo) y devuelva el puntero a la copia. En su main(), pruebe la función pasando una cadena estática entre comillas, después tome el resultado y páselo de nuevo a la función. Muestre ambas cadenas y punteros para poder ver que tienen distinta ubicación. Mediante delete libere todo el almacenamiento dinámico.
Muestre un ejemplo de una estructura declarada dentro de otra estructura (una estructura anidada). Declare atributos en ambas structs, y declare y defina métodos en ambas structs. Escriba un main() que pruebe los nuevos tipos.
¿Cómo de grande es una estructura? Escriba un trozo de código que muestre el tamaño de varias estructuras. Cree estructuras que tengan sólo atributos y otras que tengan atributos y métodos. Después cree una estructura que no tenga ningún miembro. Muestre los tamaños de todas ellas. Explique el motivo del tamaño de la estructura que no tiene ningún miembro.
C++ crea automáticamente el equivalente de typedef para structs, tal como ha visto en este capítulo. También lo hace para las enumeraciones y las uniones. Escriba un pequeño programa que lo demuestre.
Cree una Stack que maneje Stashes. Cada Stash mantendrá cinco líneas procedentes de un fichero. Cree las Stash usando new. Lea un fichero en su Stack, después muéstrelo en su forma original extrayéndolo de la Stack.
Modifique el Ejercicio 22 de modo que cree una estructura que encapsule la Stack de Stashes. El usuario sólo debería añadir y pedir líneas a través de sus métodos, pero internamente la estructura usa una Stack(pila) de Stashes.
Cree una struct que mantenga un int y un puntero a otra instancia de la misma struct. Escriba una función que acepte como parámetro la dirección de una de estas struct y un int indicando la longitud de la lista que se desea crear. Esta función creará una cadena completa de estas struct (una lista enlazada), empezando por el argumento (la cabeza de la lista), con cada una apuntando a la siguiente. Cree las nuevas struct usando new, y ponga la posición (qué número de objeto es) en el int. En la última struct de la lista, ponga un valor cero en el puntero para indicar que es el último. Escriba una segunda función que acepte la cabeza de la lista y la recorra hasta el final, mostrando los valores del puntero y del int para cada una.
Repita el ejercicio 24, pero poniendo las funciones dentro de una struct en lugar de usar struct y funciones «crudas».