                Captulo 1: Introduccin General.
                ********************************

Comencemos con una introduccin rpida al C. Nuestra intencin es 
mostrar sus elementos esenciales utilizando programas reales, pero sin
perdernos en los detalles, reglas formales o excepciones. De momento
no trataremos de ser completos, ni siquiera precisos (exceptuando la 
coreccin de los ejemplos).
Queremos que llegues lo ms rpidamente posible al punto en que puedas 
escribir programas tiles. Para ello nos centraremos en los puntos 
bsicos: variables y constantes, aritmtica, flujo de control, 
funciones y rudimentos de entrada-slida. Hemos eliminado 
intencionalmente de este captulo las caractersticas de C que no son 
indispensables para escribir buenos programas. Esto incluye 
apuntadores, estructuras, la mayor parte del rico conjunto de 
operadores de C, varias sentencias de control de flujo y muchos otros
detalles.

Por supuesto, este enfoque tiene sus inconvenientes. EL ms notable es
que la descripcin completa de una caracterstica particular del 
lenguaje no se encuentra en un solo lugar, por lo que sta introduccin
puede inducir a confusin debido a su brevedad. Por otro lado, por no
utilizar toda la potencia de C, los ejemplos no son tan concisos ni
elegantescomo podran ser. Hemos tratado de aminorar en lo posible 
estos defectos, advirtiendo su existencia al lector.

En cualquier caso, los programadores expertos debern ser capaces de
adaptar el material de este captulo a sus propias necesidades. Los 
principiantes debern ampliarlos por s mismos, escribiendo programas 
cortos del mismo tipo de los aqu expuestos. Ambos grupos pueden 
utilizar este captulo como un amrco de referencia en el cual encajar 
las descripciones detalladas que comienzan en el Captulo 2.

1.1 Comencemos
**************

La nica forma de aprender un nuevo lenguaje de programacin es 
escribir programas en l. El primer programa en escribir es el 
mismo en todos los lenguajes. Imprime las palabras:

Hello, world

Este es el principal escollo. Para sobrepasarlo es necesario tener el
texto del programa en algn lad sitio, compilarlo con xito, cargarlo,
ejecutarlo y averiguar dnde se requiere situar los resultados. una vez
superados estos detalles mecnicos, el resto es relativamente fcil.

En C, el programa para escribir "Hello, wordl" es:

main()
{
	printf("Hello world\n");
}

La forma de ejecutar el programa depende del sistema concreto que se 
este utilizando. He aqu un ejemplo especfico: en el sistema operativo
UNIX se debe crear el programa fuente en un archivo suyo nombre acabe 
en ".c", como hello.c, y compilarlo con el comando

cc hello.c

Si no se ha cometido ningn error(por ejemplo, omitir un carcter o
cualquier otra equivocacin), la compilacin se realizar sin emitir
mensajes de error, generando un archivo ejecutable llamado a.out. Su 
ejecucuin con el comando (orden)

a.out

producir como salida

Hello, world

En otros sistemas las reglas sern diferentes. Consulta a alguien que 
conozca bien el suyo.

Ejercicio 1-1

Ejecuta este programa en tu sistema. Experimenta y elimina algunas 
partes para ver qu mensajes de error se producen.

Ahora algunas explicaciones sobre el programa. Un programa C, 
cualquiera que sea su tamao, consta de una o ms 'funciones' que 
especifcan las operaciones de clculo que han de realizarse. Las 
funciones de C son similares a las funciones y subrutinas de un 
programa FORTRAN o a los procedimientos  de PL/1, Pascal, ect. En 
nuestro ejemplo, 'main' es una de esas funciones. Normalmente, puedes
dar a las funciones cualquier nombre que sea de tu agrado, pero main 
es un nombre especial (el programa comienza a ejecutarse al principio
de main). Esto significa que todos los programas deben tener una 
funcim main en alg sitio. casi siempre main har uso de otras 
funciones para efectuar su trabajo. Algunas estarn en el mismo 
programa y otras en bibliotecas de funciones escritas previamente. 

Un mtodo de comunicacin de datos entre funciones es el uso de 
argumentos. Los parntesis que siguen al nombre de la funcin encierran
en la lista de argumentos; main es una funcin sin argumentos, lo que 
se indica mediante ( ). Las llaves {} enmarcan las sentencias o
proposiciones que integran la funcin; son anlogas al DO-END de PL/1
o al begin-end de Algol, Pascal y otros lenguajes.
Una funcin se invoca especificando su nombre, seguido de una lista
de argumentos entre parntesis. No existe instrucin CALL como en 
FORTRAN o PL/1.
Los parntesis deben estar presentes, aunque no haya argumentos.

La lnea que dice

printf("helo, wordl"\n);

realiza una llamada a una funcin llamada printf, con el argumento 
"hello, wordl\n", printf es una funcin de biblioteca que dirige la 
salida hacia la terminal (a no ser que se especifique otro destino).
En este caso imprime la cadena de caracteres que constituye su 
argumento.

Una secuencia de carcteres entre comillas se denomina cadena 
caracteres o constante de caracteres. Por el momento, el nico 
uso que se har de las cadenas ser como argumentos para printf y otras
funciones.

La secuencia \n que aparece en la cadena es la notacin que emplea C 
para indicar el carcter "nueva lnea" que hace avanzar la impresin 
al margen izquierdo de la siguiente lnea. Si se elimina el grupo \n 
(un experimento interesante), la impresin no acabar con un carcter 
de salto de lnea. La nica forma de introducir un carcter nueva lnea
en el argumento de printf es recurrir al gurpo \n.

Si se intenta algo como:

printf("helo, wordl
");

el compilador de C emitir mensajes pocoa mistosos acerca de las 
comillas no encontradas. 

La funcin printf jams efectuar un salto de lnea automticamente. 
Por tanto, se pueden utilizar varias llamadas para construir una lnea
de salida en etapas.

Nuestro primer programa se podra haber escrito tambin as:

main()
{
  printf("hello, ");
  printf("wordl");
  printf("\n");
}


obteniendo una salida idntica.

Observese que \n representa un solo carcter. Una secuencia de escape 
como \n proporciona un mecanismo general y extensible para representar 
carcteres no imprimibles. Entre las posibilidades que ofrece C estn
\t para el tabulador, \b para el retroceso, \" para comillas, \\ para
la diagonal invertida.

Ejercicio 1.2

Experimenta y observa que suscede cuando la cadena utilizada como
argumento para printf contiene \x, donde  x es cualquier carcter
distinto de los anteriormente mencionados.

El programa podra ser as:

main()
  {
  printf("hola\d");
  }

y la salida sera (en el caso del compilador tc20) la siguiente:

holad

1.2 Variables y aritmtica
**************************

El siguiente programa imprime la tabla de conversin de temperaturas
Fahrenheit a centgrados o Celcius utilizando al frmula C=(5/9)(F-32)

  0	-17.5
 20	 -6.5
 40	  4.4
 60   	 15.6
...       ...
260	126.7
280	137.8
300	148.9

Listado:

/*Imprime la tabla Fahrenheit - Celcius 
para f = 0, 20, ..., 300 */

main()
  {
  int lower, upper, step;
  float fahr, celcius;
  
  lower = 0; /* lmite inferior de la tabla de temperaturas */
  upper = 300; /*Lmite superior */
  step = 20; /* tamao del incremento */

  fahr = lower;
  while (farh <= upper)
    {
    celcius = (5.0/9.0) * (fahr  - 32.0);
    printf("%4.0f %6.1f", fahr, celcius);
    fahr = fahr + step;
    }
  )

Los dos primeros renglones:

/*Imprime la tabla Fahrenheit - Celcius 
para f = 0, 20, ..., 300 */

son un comentario que, en este caso, explica brebemnete los que hace el
programa.

El compilador precinde de los carcteres comprendidos entre /* y */;
pueden utilizarse libremente para hacer que un programa sea ms fcil 
de comprender. Los comentarios se usan en cualquier lugar en el que se 
pueda colocar un espacio en blanco o un carcter nueva lnea.

En C se deben declarar todas las variables antes de su utilizacin, 
normalmente al comienzo de la funcin y antes de cualquier proposicin
ejecutable. En caso de olvidar una declaracin, el compilador emitir 
un mensaje de error. Una declaracin consta de un tipo y una lista de 
variables que tienen este tipo como en:

int lower, upper, step;
float fahr, celcius;

El tipo int indica que las variables de la lista son enteros; float 
indica punto flotante, es decir, nmeros que poseen parte fraccionaria.
La precisin, tanto de int como de float, depende de la mquina que se 
est utilizando. En la PDP-11, por ejemplo, un int es un nmero con 
signo que ocupa 16 bits, esto es, est comprendido entre -32768 y 
+32767. Un nmeroen punto flotante es una cantidad que ocupa 32 bits, 
que posee aproximadamente 7 dgitos significativos y cuya magnitud est
comprendida entre 10^-38 y 10^+38.

Aparte de int y float, C ofrece otros tipos de datos bsicos:

char	->	carcter - un solo byte
short	->	entero corto
long	->	entero largo
double	->	punto flotante de doble precisin

Los tamaos de estos objetos tambin dependen de la mquinas. tambin
existen arreglos, estructuras y uniones de estos tipos bsicos, 
apuntadores a ellos y funciones que devuelven los avlores de estos
tipos, todo lo cual se expondr en el momento oportuno.

El programa de conversin de temperaturas comienza con las 
instrucciones:

lower = 0;
upper = 0;
step = 0;
fahr = 0;

que asignan a las variables sus valores iniciales. Las sentencias o 
proposiciones individuales se terminan con punto y coma.

cada lnes de la tabbla se calcula en la misma forma, para lo cual se 
utiliza un ciclo (bucle) que se repite una vez por cada lnea. Este es
el propsito de la sentencia:

while (fahr <= upper);
  {
  ...
  }

Se examina la condicin encerrada entre parntesis. Si es cierta (fahr
es menor o igual que upper), se ejecuta el cuerpo del ciclo (todas las
proposiciones que estn entre las llaves { y } ). A continuacin se 
vuelve a evaluar la condicin y, si es cierta, se ejecuta el cuerpo de 
nuevo. Cuando la condicin se torna falsa (fahr excede el valor de 
upper), finaliza el ciclo y se reanuda la ejecucin de la sentencia que
lo sigue. En este caso no hay ms proposiciones, por lo que el programa
acaba.

El cuerpo de while puede contar de una o ms sentencias encerradas 
entre llaves, como el convertidor de temperaturas, o de una sola
sentencia, como en:

while (i < j)
  i = 2 * i;

En cualquier caso, las sentencias controladas por while se desplazan
hacia la deracha mediante el tabulador, para observar con una sinmple
ojeada cuales son las sentencias incluidas en el ciclo. El sangrado 
acenta la estructura lgica del programa. Aunque C es muy permisivo 
con respecto al posicionamiento de las sentencias, un sangrado adecuado
y el uso de los espacios en blanco son muy importantes para construir
programas fciles de leer. Nosotros recomendamos escribir una sola 
sentencia por lnea y (normalmente) dejar blancos a ambos lados de los
operadores. La posicin de las llaves es menos importante. Hemos 
elegido entre varios estilos utilizados normalmente. Elige el estilo
que creas ms conveniente y no te apartes de l.

La mayor parte del trabajo tiene lugar en el cuerpo del ciclo. la 
temperatura Celcius se calcula y se asigna a celcius mediante la
sentenbcia:

celcius = (5.0 / 9.0) * (fahr - 32.0);

Se utiliza 5.0/9.0 en lugar de la forma ms sencilla 5/9 porque en C,
como en otros muchos lenguajes, la divisin de enteros trunca el
resultado, por lo que se descarta cualquier parte fraccionaria. Por
este motivo, el valor de 5/9 es cero y, por supuesto, lo sern tambin
todas las temperaturas. Un punto decimal en una constante indica que es
de tipo punto flotante. Por lo tanto, 5.0/9.0 es igual a 0.555... que
es valor deseado.

Tambin se escribe 32.0 en lugar de 32 incluso aunque, como farh es de
tipo float, el valor 32 ser convertido automticamente a float (32.0)
antes de efectuar la sustraccin. Por razones de estilo sera sensato
escribir las constantes en punto flotante, con el punto decimal
explcito, aun cuando posean valores enteros; esto resalta la naturaleza
de punto flotante para los lectores humanos y asegura que el compilador
tambin lo vea de la misma forma.

Observese que, tanto la asignacin:

fahr = lower;

como la comprobacin:

while (fahr <= upper)

trabajan como se esperaba: la variable de tipo int es convertida a
float antes de realizar la operacin.

Este ejemplo tambin muestra algo acerca de la forma en que funciona
printf. En realidad, printf es una funcin con formatos de conversin.

Su primer argumento es una cadena de carcteres que imprimir,
indicando cada signo % el lugar en que ha de sustituirse cada uno de
los restantes (Segundo, tercero, ...) argumentos y en que forma ha
de ser impreso. Por ejemplo, en la sentencia

printf("%4.0f %6.1f", fahr, celsius);

la especificacin de conversin %4.0f indica que se ha de imprimir un
nmero en punto flotante que ocupe un espacio de almenos cuatro
carcteres, sin dgitos, despus del punto decimal. %6.1f pide otro 
nmero que ocupar al menos seis posiciones, con un dgito despus
del punto decimal en forma anloga al formato F6.1 de FORTRAN o F(6,1) 
de PL/1. Pueden omitirse partes de una especificacin: %6f indica que
el nmero ocupar al menos 6 carcteres; %.2f requiere dos posiciones
despus del punto decimal, pero sin restringir el nmero total de
carcteres, y %f simplemente dice que se imprimir un nmero en punto
flotante. Printf tambin reconoce %d para enteros decimales, %o para
enteros en sistema Octal, %x para decimal, %s para cadenas de
carcteres y %% para escribir el propio carcter %.
en forma anloga 









1.9 Arreglos de caracteres
**************************

El tipo de arreglo (array) ms comn en C es, probablemente, el de 
caracteres. Para ilustrar el uso de los arreglos de caracteres y las
funciones para manipularlos, escribiremos un programa que lee un
conjunto de lneas e imprime la de mayor longitud. El esquema bsico es
bastante simple:

while (hay ms lneas)
  if (es mayor que la ms hasta el momento)
    guardar la lnea y su longitud
imprimir la lnea ms larga

Este sistema deja claro que el programa se divide naturalmente en
partes. Una obtiene una lnea nueva, otra la examina, otra lo guarda y
el resto controla el proceso.

Ya que las cosas se dividen tan elegantemente, conviene escribirlas en
la misma forma. A partir de este criterio escribamos primero la funcin
getline para extraer la siguiente lnea de la entrada; esto es una 
generalizacin de getchar. Para que la funcin sea til en otros
contextos, intentaremos hacerla lo ms flexive posible. Como mnimo,
getline ha de devolver una indicacin sobre un posible fin de archivo.
El diseo ms utilizado consiste en devolver la longitud de la lnea,
o cero si se encntr el fin de archivo. Cero nunca es una longitud
vlida de lnea, debido a que todas las lneas contiene al menos un
carcter. Incluso las que slo pasan un carcter nueva-lnea tiene
longitud 1.

Cuando se encuentre una lnea mayor que la ms larga encontrada hasta
ese momento, debera guardarse en el algn lugar. Esto sugiere una 
segunda funcin, copy, que traslada la nueva lnea a un lugar seguro.

Finalmente, se nesecita un programa principal para controlar getline y
copy.

El resultado es el siguiente:

#define MAXLINE 1000 /*tamao mximo de la lnea*/

main()
  {
  int len; /*longitud de la lnea actual*/
  int max; /*longitud mxima hasta el momento*/ 
  char line[MAXLINE]; /*linea actual*/ 
  char save[MAXLINE]; /*guarda la lnea ms larga*/
  max = 0;
  }

