Introduccion
C es un lenguaje de programacion de proposito general que ha sido estrechamente asociado con el sistema UNIX en donde fue desarrollado puesto que tanto el sistema como los programas que corren en el estan escritos en lenguaje C. Sin embargo, este lenguaje no esta ligado a ningun sistema operativo ni a ninguna maquina, y aunque se le llama “lenguaje de programacion de sistemas” debido a su utilidad para escribir compiladores y sistemas operativos, se utiliza con igual eficacia para escribir importantes programas en diversas disciplinas.
Muchas de las ideas importantes de C provienen del lenguaje BCPL, desarrollado por Martin Richards. La influencia de BCPL sobre C se continuo indirectamente a traves del lenguaje B, el cual fue escrito por Ken Thompson en 1970 para el primer sistema UNIX de la DEC PDP-7.
BCPL y B son lenguajes “carentes de tipos”. En contraste, C proporciona una variedad de tipos de datos. Los tipos fundamentales son caracteres, enteros y numeros de punto flotante de varios tamanos. Ademas, existe una jerarquia de tipos de datos derivados, creados con apuntadores, arreglos, estructuras y uniones. Las expresiones se forman a partir de operadores y operandos; cualquier expresion, incluyendo una asignacion o una llamada a funcion, puede ser una proposicion. Los apuntadores proporcionan una aritmetica de direcciones independiente de la maquina.
C proporciona las construcciones fundamentales de control de flujo que se requieren en programas bien estructurados: agrupacion de proposiciones, toma de decisiones (if-else), seleccion de un caso entre un conjunto de ellos (switch), iteracion con la condicion de paro en la parte superior (while, for) o en la parte inferior (do), y terminacion prematura de ciclos (break).
Las funciones pueden regresar valores de tipos basicos, estructuras, uniones o apuntadores. Cualquier funcion puede ser llamada recursivamente. Las variables locales son normalmente “automaticas”, o creadas de nuevo con cada invocacion. La definicion de una funcion no puede estar anidada, pero las variables pueden estar declaradas en una modalidad estructurada por bloques. Las funciones de un program a en C pueden existir en archivos fuente separados, que se compilan de manera separada. Las variables pueden ser internas a una funcion, externas pero conocidas solo dentro de un archivo fuente, o visibles al programa completo.
Un paso de preprocesamiento realiza substitucion de macros en el texto del programa, inclusion de otros archivos fuente y compilacion condicional.
C es un lenguaje de relativo “bajo nivel”. Esta caracterizacion no es peyorativa, simplemente significa que C trata con el mismo tipo de objetos que la mayoria de las computadoras, llamense caracteres, numeros y direcciones. Estos pueden ser combinados y cambiados de sitio con los operadores aritmeticos y logicos implantados por maquinas reales.
C no proporciona operaciones para tratar directamente con objetos compuestos, tales como cadenas de caracteres, conjuntos, listas o arreglos. No existen operaciones que manipulen un arreglo o una cadena completa, aunque las estructuras pueden copiarse como una unidad. El lenguaje no define ninguna facilidad para asignacion de almacenamiento que no sea la de definicion estatica y la disciplina de pilas provista por las variables locales de funciones; no emplea heap ni recolector de basura. Finalmente, C en si mismo no proporciona capacidades de entrada/salida; no hay proposiciones READ o WRITE, ni metodos propios de acceso a archivos. Todos esos mecanismos de alto nivel deben ser proporcionados por funciones llamadas explicitamente.
De manera semejante, C solamente ofrece un control de flujo franco, y lineal: condiciones, ciclos, agrupamientos y subprogramas, pero no multiprogramacion, operaciones paralelas, sincronizacion ni co-rutinas.
Aunque la ausencia de alguna de esas capacidades puede parecer como una grave deficiencia (“¿significa que se tiene que llamar a una funcion para comparar dos cadenas de caracteres?”), el mantener al lenguaje de un tamano modesto tiene beneficios reales. Puesto que C es relativamente pequeno, se puede describir en un pequeno espacio y aprenderse con rapidez. Un programador puede razonablemente esperar conocer, entender y utilizar en verdad la totalidad del lenguaje.
Por muchos anos, la definicion de C fue el manual de referencia de la primera edicion de El lenguaje de programacion C. En 1983, el American National Standards Institute (ANSI) establecio un comite para proporcionar una moderna y comprensible definicion de C. La definicion resultante, el estandar ANSI o “ANSI C” , se esperaba fuera aprobada a fines de 1988. La mayoria de las caracteristicas del estandar ya se encuentran soportadas por compiladores modernos.
El estandar esta basado en el manual de referencia original. El lenguaje ha cambiado relativamente poco; uno de los propositos del estandar fue asegurar que la mayoria de los programas existentes pudiesen permanecer validos o, al menos, que los compiladores pudieran producir mensajes de advertencia acerca del nuevo comportamiento.
Para la mayoria de los programadores, el cambio mas importante es una nueva sintaxis para declarar y definir funciones. Una declaracion de funcion ahora puede incluir una descripcion de los argumentos de la funcion; la sintaxis de la definicion cambia para coincidir. Esta informacion extra permite que los compiladores detecten mas facilmente los errores causados por argumentos que no coinciden; de acuerdo con nuestra experiencia, es una adicion muy util al lenguaje.
Existen otros cambios de menor escala en el lenguaje. La asignacion de estructuras y enumeraciones, que ha estado ampliamente disponible, es ahora parte oficial del lenguaje. Los calculos de punto flotante pueden ahora realizarse con precision sencilla. Las propiedades de la aritmetica, especialmente para tipos sin signo, estan esclarecidas. El preprocesador es mas elaborado. La mayor parte de esos cambios solo tendran efectos secundarios para la mayoria de los programadores.
Una segunda contribucion significativa dei estandar es la definicion de una biblioteca que acompane a C. Esta especifica funciones para tener acceso al sistema operativo (por ejemplo, leer de archivos y escribir en ellos), entrada y salida con formato, asignacion de memoria, manipulacion de cadenas y otras actividades semejantes. Una coleccion de encabezadores (headers) estandar proporcionan un acceso uniforme a las declaraciones de funciones y tipos de datos. Los programas que utilizan esta biblioteca para interactuar con un sistema anfitrion estan asegurados de un com portam iento com patible. La m ayor parte de la biblioteca esta estrecham ente modelada con base en la “biblioteca E/S estandar" del sistema UNIX. Esta biblioteca se describio en la primera edicion y ha sido tambien ampliamente utilizada em otros sistemas. De nuevo, la m ayoria de los programadores no notaran mucho el cambio.
Debido a que los tipos de datos y estructuras de control provistas por C son manejadas directamente por la mayoria de las computadoras, la biblioteca de ejecucion (run-time) requerida para implantar programas autocontenidos es pequena. Las funciones de la biblioteca estandar unicamente se llaman en forma explicita, de manera que se pueden evitar cuando no se necesitan. La mayor parte puede escribirse en C, y excepto por detalles ocultos del sistema operativo, ellas mismas son portatiles.
Aunque C coincide con las capacidades de muchas computadoras, es independiente de cualquier arquitectura. Con un poco de cuidado es facil escribir programas portatiles, esto es, programas que puedan correr sin cambios en una variedad de maquinas. El estandar explica los problemas de la transportabilidad, y prescribe un conjunto de constantes que caracterizan a la maquina en la que se ejecuta el programa.
C no es un lenguaje fuertemente tipificado, sino que, al evolucionar, su verificacion de tipos ha sido reforzada. La definicion original de C desaprobo - pero permitio - el intercambio de apuntadores y enteros; esto se ha eliminado y el estandar ahora requiere la adecuada declaracion y la conversion explicita que ya ha sido obligada por los buenos compiladores. La nueva declaracion de funciones es otro paso en esta direccion. Los compiladores advertiran de la mayoria de los errores de tipo, y no hay conversion automatica de tipos de datos incompatibles.
Sin embargo, C mantiene la filosofia basica de que los programadores saben lo Que estan haciendo; solo requiere que establezcan sus intenciones en forma explicita.
Como cualquier otro lenguaje, C tiene sus defectos. Algunos de los operadores tienen la precedencia equivocada; algunos elementos de la sintaxis pueden ser mejores. A pesar de todo, C ha probado ser un lenguaje extremadamente efectivo y expresivo para una amplia variedad de programas de aplicacion.
El libro esta organizado com o sigue. El capitulo 1 es una introduccion orientada a la parte central de C. El proposito es hacer que el lector se inicie tan pronto como le sea posible, puesto que creemos firmemente que la forma de aprender un nuevo lenguaje es escribir program as en el. La introduccion supone un conocimiento practico de los elementos basicos de la programacion; no hay una explicacion de computadoras, de compilacion, ni del significado de una expresion como n = n + 1. Aunque hemos tratado de mostrar tecnicas utiles de programacion en donde fue posible, la intencion del libro no es la de ser un texto de consulta sobre estructuras de datos y algoritmos; cuando nos vimos forzados a hacer una eleccion, nos hemos concentrado en el lenguaje.
En los capitulos del 2 al 6 se discuten varios aspectos de C en mayor detalle y mas formalmente de lo que se hace en el capitulo 1, aunque el enfasis esta aun en los ejemplos de programas completos, mas que en fragmentos aislados. El capitulo 2 trata de los tipos basicos de datos, operaciones y expresiones. El capitulo 3 trata sobre control de flujo: if-else, switch, while, for, etc. En el capitulo 4 se cubren funciones y la estructura de un programa —variables externas, reglas de alcance, archivos fuente multiples y otros aspectos— y tambien abarca al preprocesador. El capitulo 5 discute sobre apuntadores y aritmetica de direcciones.
El capitulo 6 cubre estructuras y uniones.
El capitulo 7 describe la biblioteca estandar, la cual proporciona una interfaz comun con el sistema operativo. Esta biblioteca esta definida por el estandar ANSI y se intenta que se tenga en todas las maquinas que manejan C; asi, los programas que la usen para entrada, salida y otros accesos al sistema operativo se puedan transportar de un sistema a otro sin cambios.
El capitulo 8 describe una interfaz entre los programas en C y el sistema operativo UNIX, concentrandose en entrada/salida, el sistema de archivos y la asignacion de memoria. Aunque algo de este capitulo es especifico de sistemas UNIX, los programadores que usen otros sistemas de todas maneras encontraran aqui material de utilidad, incluyendo alguna comprension acerca de como esta implantada una version de la biblioteca estandar, asi como sugerencias para obtener un codigo portatil.
El apendice A contiene un manual de consulta del lenguaje. El informe oficial de la sintaxis y la semantica de C es en si el estandar ANSI. Ese documento, sin embargo, esta principalmente pensado para quienes escriben compiladores. El manual de consulta de este libro transmite la definicion del lenguaje en una forma mas concisa y sin el mismo estilo legalista. El apendice B es un resumen de la biblioteca estandar, de nuevo mas para usuarios que para implantadores. El apendice C es un breve resumen de los cambios del lenguaje original. Aunque, en caso de duda, el estandar y el compilador en uso quedan como las autoridades finales sobre el lenguaje.
Continuar: Capitulo 1