29 KiB
PEC 1
Volver a la página principal de "Fundamentos de la Programación"
Índice
- PEC 1
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.
Identificador | Descripción |
---|---|
Tipo | integer |
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.
Identificador | Descripción |
---|---|
Tipo | real |
Rango de valores | desde MIN_REAL hasta MAX_REAL |
Operadores internos | - (cambio de signo), + , - , * , / |
Operadores externos | =, ≠, <, >, ≤, ≥ |
Ejemplos | 3.0 , -123.56 , 5.0E 8, 49.22E 8, 1.0E5 |
¡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 (American Standard Code for Information Interchange), que utiliza un byte para representar cada carácter.
Identificador | char |
---|---|
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.
a | b | a and b | a or b | not a |
---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | false |
false | true | false | true | true |
false | false | false | false | true |
Identificador | Descripción |
---|---|
Tipo | boolean |
Rango de valores | false, true |
Operadores internos | and, or, not, =, ≠, <, >, ≤, ≥ |
Operadores externos | no hay |
Ejemplos | false, true |
1.2.1. Declaración de constantes
Sintaxis:
const
CONST_NAME: type = value;
end const
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:
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:
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:
var
variableName1, variableName2, variableName3: type;
end var
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.
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.
var
variableName: type;
end var
variableName := value;
type variableName;
variableName=value;
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.
type
enumType = (value1, value2, value3, ..., valueN);
end type
typedef enum { VALUE1, VALUE2, VALUE3, ... , VALUEN } typeName;
Ejemplo con los días de la semana:
type
daysOfTheWeek = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
end type
var
firstDay: daysOfTheWeek;
lastDay: daysOfTheWeek;
end var
typedef enum { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
daysOfTheWeek;
daysOfTheWeek firstDay;
daysOfTheWeek lastDay;
1.2.1 Operaciones con tipos enumerativos
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 entero45 < 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 |
---|---|---|
ventas | Sí | Es recomendable escribir en minúsculas. |
_articulo | No | No empieza por un carácter alfabético. |
aux2 | Sí | Poco recomendable. Es mejor usar nombres descriptivos. |
1_articulo | No | No empieza por un carácter alfabético. |
numero articulos | No | Los espacios en blanco no son permitidos. |
numeroArticulos | Sí | Es un nombre descriptivo. |
piezaCamión | No | No se pueden utilizar caracteres especiales ni acentos (la "ñ" se considera un carácter especial) |
const | No | Es |
2.1.1. Tipos elementales en C
2.1.1.1. Tipo booleano
Para poder usar la librería stdbool.h será necesario importarla previamente al inicio de nuestros programas en lenguaje C de la siguiente forma:
#include <stdbool.h>
Característica | Lenguaje algorítmico | Lenguaje C |
---|---|---|
Identificador | boolean | bool |
Rango de valores | true, false | true, false |
Operadores internos | not, and, or, =, ≠, <, ≤, >, ≥ | !, &&, |
2.1.1.2. Tipo carácter
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 |
---|---|---|
Identificador | caracter | char |
Rango de valores | conjunto finito de valores | conjunto finito de valores definidos por el código ASCII |
Operadores externos | =, ≠, <, ≤, >, ≥ | ==, !=, <, <=, >, >= |
Sintaxis de valores | 'a', 'W', '1' | 'a', 'W', '1' |
2.1.1.3. Tipo entero
La siguiente tabla resume las características del tipo entero y su traducción a C.
Característica | Lenguaje algorítmico | Lenguaje C |
---|---|---|
Identificador | integer | int |
Rango de valores | MIN_INTEGER a MAX_INTEGER | -2147483648, 2147483647 |
Operadores internos | - (cambio de signo), +, -, *, div, mod | - (cambio de signo), +, -, *, /, % |
Operadores externos | =, ≠, <, ≤, >, ≥ | ==, !=, <, <=, >, >= |
Sintaxis de valores | 3, 465434, -2134567 | 3, 465434, -2134567 |
El rango de los enteros puede variar según el compilador y el ordenador donde se ejecute el programa.
2.1.1.4. Tipo real
La siguiente tabla resume las características del tipo real y su traducción a C.
Característica | Lenguaje algorítmico | Lenguaje C |
---|---|---|
Identificador | real | float |
Rango de valores | MIN_REAL a MAX_REAL (no todos) | ±3.4E±38 (7 dígitos significativos) |
Operadores internos | - (cambio de signo), +, -, *, / | - (cambio de signo), +, -, *, / |
Operadores externos | =, ≠, <, ≤, >, ≥ | ==, !=, <, <=, >, >= |
Sintaxis de valores | 0.6, 5.0E-8, -49.2E+0.8, 1.0E5, 4.0 | 0.6, 5.0E-8, -49.2E+0.8, 1.0E5, 4.0 |
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:
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
:
#define NOMBRE valor
Para declarar una variable, se usa la sintaxis siguiente:
tipo nombre;
Por ejemplo, para declarar tres variables i, j, k de tipo entero:
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:
typedef enum {valor1, valor2..., valorn} nombre;
2.1.5. Funciones de conversión de tipos
Lenguaje algorítmico | Lenguaje C | Ejemplo |
---|---|---|
realToInteger | (int) | (int) -3.99 |
integerToReal | (float) | (float) 3 |
charToCode | (int) | (int) 'A' |
codeToChar | (char) | (char) 65 |
2.2 Especificación de algoritmos
Sintaxis de C para los comentarios.
/* Pre: precondición */
algoritmo
/* Post: postcondición */
2.3. Estructuras algorítmicas
2.3.1. Estructura general de un programa en lenguaje C
La estructura de un programa en lenguaje C es la siguiente:
/* Programa estructura.c Estructura básica de un programa en C
Jordi Riera, 2018
*/
/* Inclusión de ficheros de cabecera */
#include <stdbool.h>
#include <fichero2>
/* ... */
/* Declaración de constantes en tiempo de compilación */
#define NOMBRE_CONSTANTE1 valor_define1
#define NOMBRE_CONSTANTE2 valor_define2
/* ... */
/* Declaración de tipos */
typedef definicion_de_tipo1 nombre_tipo1;
typedef definicion_de_tipo2 nombre_tipo2;
/* ... */
int main() {
/* Definición de constantes */
const tipo_de_constante1 nombre_constante1 = valor_constante1;
const tipo_de_constante2 nombre_constante2 = valor_constante2;
/* ... */
/* Declaración de variables */
tipo_de_variable1 nombre_variable1;
tipo_de_variable2 nombre_variable2;
/* Cuerpo del programa */
accion1
accion2
/* ... */
}
2.3.2. Acciones elementales: la asignación
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:
Instrucción | Descripción |
---|---|
readChar | Lee un caracter del buffer |
readBoolean | Lee un boolean del buffer |
readInteger | Lee un entero del buffer |
readReal | Lee un real del buffer |
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.
keyboard --> Buffer --> screen
Instrucción | Descripción |
---|---|
writeChar | Escribe un caracter en el buffer |
writeBoolean | Escribe un boolean en el buffer |
writeInteger | Escribe un entero en el buffer |
writeReal | Escribe un real en el buffer |
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:
# include <stdio.h>
Tipo de dato | Especificativo de tipo | Ejemplo de datos |
---|---|---|
Caracter | %c | 'a' |
Booleano | %d | 0 (equivalente de false), 1 (equivalente de true) |
Enumerativo | %u | {VALUE1, VALUE2, ... VALUEN} |
Entero | %d | 34 o -32 |
Real | %f | 3.1415 |
String | %s | "Hello World" |
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:
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 = 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():
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:
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
3.4. Ejemplos
3.4.1. Ejemplo 05_01: entrada
algorithm sum
var
a: integer;
b: integer;
s: integer;
end var
a:= readInteger();
b:= readInteger();
s:= a + b;
end algorithm
# include <stdio.h>
int main() {
int a;
int b;
int s;
scanf("%d", &a);
scanf("%d", &b);
s=a+b;
return 0;
}
3.4.2. Ejemplo 05_02: salida
algorithm sumaSalida
var
a: integer;
b: integer;
end var
a:= 2;
b:= 2;
writeString("La suma de a y b es :");
writeInteger(a + b);
end algorithm
# include <stdio.h>
int main() {
int a=2;
int b=2;
printf("La suma d'a i b és : %d", a + b);
return 0;
}
3.4.3. Ejemplo 05_03: entrada y salida
algorithm sumaEntradaSalida
var
a: integer;
b: integer;
c: integer;
m: real;
end var
a:= readInteger();
b:= readInteger();
c:= readInteger();
m:= integerToReal(a+b+c)/3.0;
writeReal(m);
end algorithm
# include <stdio.h>
int main() {
int a;
int b;
int c;
float m;
scanf("%d", &a);
scanf("%d", &b);
scanf("%d", &c);
m=(a+b+c)/3.0;
printf("%f", m);
return 0;
}