- [3.4.3. Ejemplo 05\_03: entrada y salida](#343-ejemplo-05_03-entrada-y-salida)
## 1. Tipos de datos
Los **objetos** son entidades que tienen un estado y un comportamiento. Los tipos de datos son la forma de representar los objetos en un programa.
### 1.1. Tipo elementales y objetos
Una **variable** es un nombre simbólico que hace referencia a una información concreta guardada en memoria.
Atributos de una variable:
- **Nombre**: identificador de la variable.
- **Tipo**: tipo de dato que almacena.
- **Valor**: valor que almacena.
- **Dirección**: dirección de memoria donde se almacena.
- **Visibilidad**: ámbito de la variable.
Una **constante** es un valor que no puede ser modificado durante la ejecución del programa.
#### 1.1.1. Tipos elementales
##### 1.1.1.2. Enteros
Los **enteros** son números sin parte decimal. Pueden ser positivos o negativos. Los valores que se pueden asignar a una variable de tipo entero está entre dos valores concretos, un entero mínimo MIN_INTEGER y un entero máximo MAX_INTEGER que dependerán del ordenador que se utilice.
| Rango de valores | desde MIN_INTEGER hasta MAX_INTEGER |
| Operadores internos | - (cambio de signo), + , - , * , div, mod |
| Operadores externos | =, ≠, <, >, ≤, ≥ |
| Ejemplos | 3, -123, 9876, 0 |
Los **operadores internos** son aquellos que hacen que el resultado de operar dos valores de un tipo devuelva un valor del mismo tipo, mientras que los **operadores externos** son aquellos cuyo resultado de la operación es un valor de un tipo diferente.
De los operadores indicados en la tabla, los menos conocidos son div y mod que precisamente en programación se utilizan bastante.
div - devuelve el cociente de la división entera de dos números.
mod - devuelve el resto de la división entera de dos números.
La división (/) no se ha incluido en la lista de operadores ya que no es un operador válido
para el tipo entero.
##### 1.1.1.3. Reales
Los **reales** son números con parte decimal. Pueden ser positivos o negativos. Los valores que se pueden asignar a una variable de tipo real está entre dos valores concretos, un real mínimo MIN_REAL y un real máximo MAX_REAL que dependerán del ordenador que se utilice.
¡cuidado con las divisiones! Antes de dividir hay que comprobar siempre que el divisor sea diferente de 0. Si se divide por 0 durante la ejecución del programa se producirá un error y el programa dejará de funcionar.
##### 1.1.1.4 Carácter
Los **caracteres** son símbolos que se pueden representar en la pantalla. Los valores que se pueden asignar a una variable de tipo carácter están entre dos valores concretos, un carácter mínimo MIN_CHAR y un carácter máximo MAX_CHAR que dependerán del ordenador que se utilice.
Internamente los caracteres están representados por números. A cada carácter le corresponde un número. El conjunto de correspondencias entre caracteres y números se llama código. Hay diferentes códigos, pero el más utilizado y que se ha convertido en estándar es el código [ASCII](https://es.wikipedia.org/wiki/ASCII) (American Standard Code for Information Interchange), que utiliza un byte para representar cada carácter.
| Rango de valores | Conjunto finito de valores que depende del código utilizado por el ordenador |
| Operadores internos | No hay |
| Operadores externos | =, ≠, <, >, ≤, ≥ |
| Ejemplos | 'a', 'A', '?', '@', 'à' |
##### 1.1.1.4 Booleano
El tipo de dato **booleano** es un tipo de dato que puede tener uno de dos valores: verdadero o falso. En algunos lenguajes de programación se representa con 1 y 0, pero en otros se representa con true y false.
Su nombre procede del álgebra de Boole y toma del álgebra los operadores lógicos and, or y not.
El primer carácter del nombre ha de ser siempre alfabético. El resto pueden ser alfabéticos, numéricos o el carácter ‘_’. No puede haber espacios entre los caracteres.
Ejemplos:
```c
const
PI: real = 3.1415926;
MAX_STUDENTS: integer = 50;
IVA: integer = 21;
BLANK_CHAR: char = ' ';
end const
```
#### 1.2.2. Declaración de variables
Sintaxis:
```c
var
var_name: type;
end var
```
Igual que con las constantes, el primer carácter del nombre ha de ser siempre alfabético. El resto pueden ser alfabéticos, numéricos o de carácter ‘_’. No puede haber espacios entre los caracteres.
Si hay diversas variables del mismo tipo, podemos declararlas en la misma línea separándolas por comas:
Por convención, los nombres de las variables se escriben en minúscula y, si el nombre de la variable está formado por dos palabras, la primera letra de las palabras, exceptuando la de la primera palabra, se escribe en mayúscula. [CamelCase](https://es.wikipedia.org/wiki/Camel_case).
```c
var
roomLength: real;
roomWidth: real;
currentNumberStudents: integer;
initialLetter: char;
end var
float roomLength;
float roomWidth;
int currentNumberS
char initialLetter;
```
En las declaraciones de variables y constantes se puede ver una serie de palabras que forman parte de la sintaxis del lenguaje algorítmico y sirven para que el compilador (el intérprete del código escrito) entienda en cada momento qué se quiere hacer. Estas palabras se llaman palabras clave (o reservadas) del lenguaje y no se pueden utilizar como nombres ni de variables ni de constantes. Cada lenguaje de programación tiene sus palabras clave, aunque la mayoría son coincidentes entre los diferentes lenguajes.
#### 1.2.3. Asignación a variables
En notación algorímitca, para asignar un valor a una variable, se utitliza el operador de asignación := que se lee "toma por valor". El operador = es el equivalente en C.
```c
var
variableName: type;
end var
variableName := value;
type variableName;
variableName=value;
```
```c
var
roomLength: real;
roomWidth: real;
currentNumberStudents: integer;
initialLetter: char;
end var
{Inicializamos las variables}
roomLength:=0.0;
roomWidth:=0.0;
currentNumberStudents:=0;
initialLetter:=' ';
float roomLenght;
float roomWidth;
int currentNumberStudents;
char initialLetter;
roomLenght=0.0;
roomWidth=0.0;
currentNumberStudents=0;
initialLetter=' ';
```
### 1.2 Tipos enumerativos
Los **tipos enumerativos** son aquellos que permiten definir un conjunto finito de valores que puede tomar una variable. Los valores que se pueden asignar a una variable de tipo enumerativo están entre los valores que se han definido en la declaración del tipo.
Los únicos operadores que se pueden aplicar a los tipos enumerativos son los operadores relacionales externos ( =, #, <, >, #, # )
### 1.3. Expresiones
Una **expresión** es una combinación de valores, variables, operadores y funciones que se evalúa para obtener un resultado con un valor de alguno de los tipos primitivos del lenguaje..
Dentro de todo el conjunto de expresiones, las que devuelven un resultado numérico se llaman **expresiones aritméticas**. Las que devuelven un resultado booleano se llaman **expresiones lógicas**. Y existen más como las **expresiones de cadena** o las **expresiones de caracteres**.
#### 1.3.1. Semántica de una expresión
La **semántica** de una expresión es el significado que tiene la expresión. En el caso de las expresiones aritméticas, la semántica es el valor numérico que se obtiene al evaluar la expresión. En el caso de las expresiones lógicas, la semántica es el valor booleano que se obtiene al evaluar la expresión.
No todas las expresiones sintácticamente correctas se pueden evaluar. También es necesario que sean semánticamente correctas. Ejemplos:
-`3/0` no se puede evaluar ya que el resultado de dividir un número por 0 no está definido.
-`6 + 8.8` Porque suma un entero y un real.
-`true < 35` Porque compara un booleano y un entero.
-`‘c’ + 34 < ‘b’` Porque suma un caracter y un entero
-`45 < 56 < 90` Compara primero dos enteros y el resultado, que es un booleano, se compara con un entero.
#### 1.3.2. Prioridad de los operadores
La **prioridad de los operadores** es el orden en que se evalúan las operaciones. Los operadores con mayor prioridad se evalúan antes que los de menor prioridad. El contenido de los paréntesis son las primeras. Si dos operadores tienen la misma prioridad, se evalúan de izquierda a derecha. Las prioridades:
| Prioridad | Operadores |
| --------- | ---------------------- |
| 1 | (cambio de signo), not |
| 2 | *, /, div, mod |
| 3 | +,- |
| 4 | =, ≠, >, <, ≤, ≥ |
| 5 | and |
| 6 | or |
### 1.4. Funciones de conversión de tipo
Las **funciones de conversión de tipo** son funciones que permiten convertir un valor de un tipo a otro tipo. Las funciones disponibles en lenguaje algorítmico son:
-`integerToReal`, que convierte un entero en real.
-`realToInteger`, que dado un real retorna su parte entera.
-`codeToChar`, que dado un código ASCII retorna el carácter correspondiente.
-`charToCode`, que dado un carácter retorna su código ASCII.
Ejemplos:
-`realToInteger(789.78) = 789`.
-`codeToChar(65) = ‘A’`.
-`charToCode(‘s’) = 115`.
-`integerToReal(10) = 10.0`.
## 2. Tipos básicos de datos en C
### 2.1 Objetos elementales del lenguaje C
| Nombre o identificador | ¿Es correcto? | Comentario |
En C los caracteres van delimitados por comillas simples como en el lenguaje algorítmico. La tabla siguiente resume las características del tipo carácter y su traducción a C.
| Característica | Lenguaje algorítmico | Lenguaje C |
El lenguaje C permite reales con más dígitos significativos: los tipos double y long double.
#### 2.1.2. Declaración de objetos en C
Para declarar una constante, se utiliza la construcción:
```c
const tipo nombre = valor;
```
A veces es conveniente definir constantes con valor conocido ya durante la compilación. Se puede hacer con la directiva `#define`:
```c
#define NOMBRE valor
```
Para declarar una variable, se usa la sintaxis siguiente:
```c
tipo nombre;
```
Por ejemplo, para declarar tres variables i, j, k de tipo entero:
```c
int i, j, k;
```
#### 2.1.3. Expresiones en C
Las expresiones en lenguaje C siguen las mismas reglas de construcción y evaluación que en el lenguaje algorítmico. En caso de duda, sin embargo, siempre es aconsejable poner un paréntesis de más para indicar claramente la orden de evaluación de la expresión.
#### 2.1.4. Definición de tipos. Tipos enumerados en C
El constructor de tipos enumerados en C sigue la siguiente sintaxis:
La acción de asignación del lenguaje algorítmico, ":=" se traduce en el operador de asignación en lenguaje C, "=".
La distinción entre acción y operador es muy importante, ya que implica que el lenguaje C permite hacer asignaciones en cualquier punto del código donde una expresión sea válida.
Por ejemplo, es un error muy común hacer una asignación, en vez de una comparación en la condición de una sentencia condicional, por usar el operador de asignación "=" en lugar del operador relacional de igualdad "==", lo cual tiene graves repercusiones de cara al buen funcionamiento del programa.
## 3. Funciones de entrada/salida
Cuando pensamos en entrada de datos nos referimos a cualquier tipo de entrada; pueden ser las teclas que se pulsan en un teclado, la posición del ratón o pantalla táctil, un fichero en disco, una dirección de internet, un lector de códigos de barras, una webcam o el micrófono.
Del mismo modo, cuando hablamos de salida nos podemos referir a un amplio abanico de opciones, desde la pantalla del ordenador, un archivo, una impresora o el sistema de control de un robot.
Si no se cambia explícitamente, la entrada estándar (o `stdin` del inglés standard input) es el teclado, y la salida estándar (o `stdout` del inglés standard output) es la pantalla.
### 3.1. Entrada
Cuando se pulsan teclas en un teclado, estas se convierten en su código ASCII y se almacenan como caracteres en lo que se llama un buffer, el cual contiene toda la secuencia de caracteres que han escrito y que ningún programa ha leído todavía.
keyboard --> buffer --> programa
Este buffer es una estructura conocida como FIFO (First In First Out)
Para leer la información de este buffer, tenemos a nuestra disposición un conjunto de instrucciones en lenguaje algorítmico según el tipo de datos que queremos leer:
| readString | Lee una cadena de caracteres del buffer |
### 3.2. Salida
Cuando escribimos en la salida estándar, toda la información queda guardada en forma de caracteres en un buffer, que se va leyendo y mostrando en la pantalla.
| writeString | Escribe una cadena de caracteres en el buffer |
### 3.3. Entrada y salida en C
Con la librería `stdio` (standard input/output) se pueden realizar operaciones de entrada y salida en C. Se debe incluir la librería al inicio del programa:
```c
# include <stdio.h>
```
| Tipo de dato | Especificativo de tipo | Ejemplo de datos |
| Puntero | %p | 0x000000AA; los punteros los trataremos en el módulo "13. Punteros en C". |
#### 3.3.1. Entrada
El método genérico para la entrada de datos es el método `scanf` que permite leer datos de la entrada estándar. La sintaxis es la siguiente:
```c
scanf("formato", &variable);
```
| Método | Traducción a C |
| ----------- | --------------- |
| readChar | scanf("%c", &c) |
| readBoolean | scanf("%d", &b) |
| readInteger | scanf("%d", &i) |
| readReal | scanf("%f", &r) |
| readString | scanf("%s", s) |
Además, con la instrucción `getchar` se puede leer un carácter de la entrada estándar.
```c
c = getchar();
```
Al leer un carácter después de otro tipo de dato en C, el salto de línea del dato anterior puede interferir. Para solucionarlo, se puede usar getchar() para limpiar el búfer antes de scanf():
```c
scanf("%d", &i);
getchar();
scanf("%c", &c);
```
#### 3.3.2. Salida
El método genérico para la salida de datos es el método `printf` que permite escribir datos en la salida estándar. La sintaxis es la siguiente:
```c
printf("formato", variable);
```
| Método | Traducción a C |
| ------------ | ------------------------------ |
| writeChar | printf("%c", c) |
| writeBoolean | printf("%d", b) |
| writeInteger | printf("%d", i) |
| writeReal | printf("%f", r) |
| writeString | printf("cadena de caracteres") |
| writeString | printf("%s", s) |
Adicionalmente, podemos añadir modificaciones a cómo queremos que se muestren los datos. Estos
modificadores se ponen entre el símbolo % y el especificativo de tipo:
```
%[modificadores][ancho][.precisión]especificativo
```
Más info: https://www.tutorialspoint.com/c_standard_library/c_function_printf.htm