6 de octubre de 2016

Lectura de datos.

Lectura de datos.
   El Ejemplo 2.3 muestra un sencillo programa que lee desde la entrada estándar dos números enteros decimales (los operandos), y los suma. Este ejemplo también se describirá línea a línea.

   Las líneas 1-7 deberían resultar ahora  familiares, en base a la explicación de un primer programa en C. Por otro lado, la línea 8 presenta un nuevo elemento: la declaración de variables.

   La declaración de variables en C puede hacerse al iniciar un bloque ({ ... }) y tiene la siguiente estructura general:

          {
                tipo_de_dato lista de variables;
                             .
                             .
                             .
          }

donde tipo_de_dato es alguno de los tipos de datos de C, y la lista de variables es una lista de identificadores separada por comas. En base a lo anterior, la línea 8 está declarando tres variables de tipo entero a través de la palabra reservada int.

   Una palabra reservada es una palabra (token) que no puede ser utilizada como identificador y que es propia del lenguaje, lo cual quiere decir que ninguna variable o función (ningún identificador) por ejemplo, puede llamarse “int”.

   Por otro lado, un identificador es una secuencia de caracteres sin espacios que inicia con una letra. Los identificadores sirven para dar nombre a las variables que se declaran y que serán utilizadas dentro de un programa.

   En C existen diferentes tipos de datos: int, float y char son tres de ellos. La idea de tipo de dato se refiere a una categoría de datos pertenecientes a un dominio pero, desde el punto de vista del lenguaje de programación C ¿qué es un tipo de dato?

   Lo que una computadora almacena en su memoria principal no es otra cosa que una secuencia de bits; pues bien, esa misma secuencia de bits tiene diferentes interpretaciones, y la interpretación específica está en función del tipo de dato al que se refiera.

   Considere la siguiente secuencia de bits: 1 1 0 1 0 1 0 1. Suponga que dicho byte representa, como número, al entero decimal 213. Si esta misma secuencia de bits, se interpreta ahora como carácter (char) por ejemplo, podría representar a la hermosa letra 'R' (no es que así sea, es sólo una suposición), mientras que interpretada como un número con punto decimal (float) podría representar al 69.5.

   En resumen, un tipo de dato es la manera en que una computadora interpreta un patrón de bits.

   Continuando con el ejemplo que iniciamos, la línea 10 debería resultar familiar. A este tipo de sentencias se les conoce en el argot computacional como prompt, es decir, un mensaje de solicitud de datos.

   La línea 11 es nueva y muestra uno de los usos de la función scanf. La función scanf se compone básicamente de dos partes:

  1. El (los) especificador(es) de formato indicados entre comillas.
  2. Una lista de variables separadas por comas en donde se almacenarán los valores procesados (leídos) de la entrada estándar.

   El especificador de formato%d”, le indica a la función scanf que leerá un entero decimal, mientras que la expresión “&operando1”, especifica la variable en la que se almacenará el valor leído de la entrada estándar: operando1.

   Debe observarse que el nombre de la variable ha sido antecedido por el símbolo “&”, la justificación de ello se comprenderá mejor cuando se trate el tema de Apuntadores; por ahora, basta con que no olvide anteceder con dicho símbolo el nombre de la variable en la que se desee almacenar el valor procesado, ya que su omisión no es detectada por el compilador como un error, debido a que no es una violación a la gramática del lenguaje C.

   Las líneas 12 y 13 son análogas a las líneas 10 y 11 respectivamente. Asegúrese de comprender la similitud. Por otro lado, la línea 14 presenta la expresión:

suma = operando1 + operando2;

   Dicha expresión le indica a C que realice la operación aritmética de adición sobre los valores almacenados en operando1 y operando2, y que el resultado se asigne (almacene) en la variable suma.

   La tabla siguiente muestra los operadores aritméticos en C:

Operador      Descripción
                   /             División (cociente)
               %            Módulo (residuo)
                             *             Multiplicación (producto)
             +             Adición (suma)
                  -              Sustracción (resta)

   Los operadores se evalúan siguiendo una precedencia. La precedencia de operadores le indica al compilador cuáles de los operadores en una expresión deben ser evaluados primero. Considere la siguiente expresión:

3 + 5 * 4

   La expresión anterior es evaluada como 23 y no como 32, debido precisamente a que la multiplicación tiene una precedencia mayor sobre la adición, sin importar que la adición sea la operación que aparece primero (más a la izquierda).

   Si lo que se desea es primero realizar la suma y luego el producto, la expresión debe escribirse como:

(3 + 5) * 4

   Los paréntesis modifican la forma en que son evaluadas las expresiones, es decir, modifican la precedencia de cualquier operador y éste es su uso más común, aunque en muchas ocasiones se utilizan sólo por claridad en la forma de representar una expresión sin que modifiquen la precedencia de los operadores involucrados.

   Los operadores aritméticos “/”, “%” y “*” tienen la misma precedencia y es más alta que la de los operadores “+” y “-”. Si en una expresión existen operadores con la misma precedencia, la expresión es evaluada de izquierda a derecha.

   Finalmente, la línea 15 (la línea 17 se explicó a detalle en un primer programa en C ) introduce una novedad respecto al primer ejemplo, ya que muestra el uso de especificadores de formato dentro de la función printf.

   Al igual que en la función scanf, el especificador de formato “%d” le indica a la función printf que en la posición del especificador de formato va a imprimir, en la salida estándar, un entero decimal cuyo valor está almacenado en la variable suma, la cual se encuentra después de la coma. En este sentido, por cada especificador de formato debe existir su correspondiente variable asociada, de tal forma que tanto el número de especificadores de formato como el de variables, debe corresponder.

   Una posible salida de nuestro ejemplo se muestra en la siguiente figura. Asegúrese de comprender la descripción realizada hasta el momento, así como de entender lo que sucede con la ejecución y la salida correspondiente antes de continuar.

Una posible salida del Ejemplo 2.3.

   Considere ahora el Ejemplo 2.4 y compárese con el anterior. Note que todas las líneas son iguales excepto por la línea 15. La línea 15 contiene tres especificadores de formato “%d”. Cada especificador de formato, le indica a la función printf que imprima en orden, el entero decimal correspondiente almacenado en cada una de las variables correspondientes: operando1, operando2 y suma.

   La lógica del programa de este nuevo ejemplo no cambia en nada con respecto de la lógica del ejemplo anterior, sólo se ha cambiado el estilo en la forma de presentar los resultados, la cual es más ad hoc con la intención del programa.

   El segundo ejemplo  muestra la forma de incluir más de un especificador de formato en la función printf, de tal forma que puede observarse que por cada especificador de formato existe su correspondiente variable asociada. Es importante mencionar también que es responsabilidad del programador el asegurar que exista una correspondencia entre el especificador de formato y el tipo de dato de la variable, C no realiza esta verificación.

   Los especificadores de formato para printf tienen la siguiente forma general:

%[-]m.nx

donde % delimita el inicio del especificador de formato y x representa el especificador de formato a utilizar. El guión o signo de menos alinea el campo a la izquierda; si se omite, el campo se alinea a la derecha. Ahora bien, dependiendo del valor de x, los número enteros representados por m y n se interpretan de manera diferente:
  • Usualmente, m es la longitud mínima y n es la longitud máxima del campo (ancho de campo o espacio) que se utilizará para imprimir x.
  • Si x representa el especificador de formato para un número con punto decimal, n es interpretado como la precisión que deberá ser utilizada (número de decimales después del punto).
   Una posible salida para el Ejemplo 2.4 se muestra en la siguiente figura. Pruebe ambos ejemplos con distintos valores y observe sus resultados; repita el procedimiento hasta que se sienta cómodo y entienda por completo el mecanismo de funcionamiento de los programas.

Una posible salida del Ejemplo 2.4.