03. Tipos básicos de datos
Objetivos
- Saber qué se entiende por objeto y cómo se declara.
- Entender qué es un tipo básico o elemental de datos.
- Conocer qué clases de valores puede guardar cada tipo de datos.
- Entender el concepto de variables y constantes.
- Conocer las operaciones disponibles para cada tipo de datos.
- Aprender qué es una expresión y cómo se evalúa.
Introducción
Los algoritmos y programas requieren manipular información. Habitualmente, a partir de unos datos de entrada, devuelve unos datos de salida.
Toda esta información se guarda en los objetos, los cuales en memoria quedarán codificados en códigos binarios (secuencias de ceros y unos), tanto si se trata de una letra como de un número. Los tipos de datos nos permiten asignar el tipo de estos objetos, lo que define qué longitud tienen en memoria en bytes (1 byte = 8 bits, donde un bit es un 0 o un 1) y cómo los interpretamos, así como qué valores pueden guardar y las operaciones que podemos hacer con ellos.
En esta unidad se introducen los tipos básicos o elementales, que nos permitirán definir objetos simples. Más adelante, veremos cómo construir nuevos tipos más complejos a partir de estos.
1. Tipos elementales y objetos
Hay que guardar la información que manipula un programa en la memoria del ordenador. En los inicios de la programación, cuando se programaba en lenguaje máquina, para acceder y manipular la información correctamente era necesario conocer la dirección de la memoria donde estaba guardado cada dato y el número de bytes necesarios para representarla. Había que hacer todas las operaciones contando bytes y conociendo las direcciones, lo que complicaba mucho la programación.
Para facilitar la programación, apareció el concepto de variable. Una variable es un nombre simbólico que hace referencia a una información concreta guardada en memoria. Ahora bien, no se debe pensar en una variable únicamente como una dirección de memoria ya que tiene más información asociada. De hecho, una variable consta, como mínimo, de los siguientes atributos o características:
- Nombre o identificador: identifica la variable.
- Tipo: indica qué valores se pueden guardar dentro de la variable y determina el espacio en memoria necesario para hacerlo.
- Valor almacenado de la variable en un momento concreto.
- Dirección: indica la dirección de memoria donde está almacenada la variable.
- Visibilidad: indica en qué partes del programa o algoritmo se puede utilizar la variable.
Ahora puede parecer complejo hablar de todos estos atributos, pero como se irá viendo, son conceptos fundamentales con los que se trabaja constantemente.
Hay algunos casos en que interesa que el valor de la variable no se pueda modificar nunca durante la ejecución del programa. Los lenguajes de programación permiten identificar de una manera especial estos objetos que no queremos modificar. Se llaman constantes. Así, una constante es una variable que no se puede modificar. Tiene los mismos atributos que una variable, excepto que solo tiene un valor posible.
Veamos con más detalle los atributos o características de las variables.
- Nombre o identificador de una variable. Una variable puede tener cualquier nombre simbólico que queramos darle. Es recomendable que el nombre ayude a entender el tipo de información que guarda. Por ejemplo, si queremos guardar el saldo de una cuenta bancaria, podríamos llamar a la variable saldo y si queremos guardar el coste de un bien, podemos llamarla coste. Hay que tener en cuenta que, en ambos ejemplos, el valor que guardará la variable será un número real, pero el nombre ayuda a entender el significado del contenido de la variable dentro del programa.
- Tipo de datos de una variable. El tipo de datos describe el conjunto de posibles valores que puede tomar una variable y, por tanto, también el conjunto de operaciones que se pueden realizar con ella. Veremos que hay tipos elementales de datos y también tipos más complejos que se tratarán más adelante.
- Valor de una variable. El valor guardado de una variable es el valor concreto que tiene en un momento dado de la ejecución del programa. El valor irá cambiando según las operaciones que se hagan con ella y siempre deberá ser un valor dentro del rango de valores válidos según el tipo definido por la variable.
- Dirección de memoria de una variable. La dirección de memoria es un entero que indica en qué posición de la memoria está guardado el valor de la variable. Internamente, durante la ejecución, la dirección se utiliza para saber dónde guardar y dónde encontrar el valor de la variable en cada momento. En lenguaje algorítmico no se puede trabajar con la dirección directamente, pero en el lenguaje C sí que se puede, como se verá más adelante.
- Visibilidad de la variable. Un algoritmo está formado por diferentes partes, como se estudiará en una próxima unidad. Las variables solo serán visibles en determinadas partes del algoritmo según dónde estén definidas. Por ejemplo, en un bloque, cada vecino puede ver y cambiar los muebles de su casa, pero no puede ver ni cambiar los de los demás vecinos. En cambio, los muebles de la entrada al edificio son compartidos y visibles para todos los vecinos. Con las variables pasa lo mismo.
1.1. Tipos Elementales
1.1.1. Tipo entero
El tipo entero es uno de los más utilizados a la hora de programar. Ahora bien, hay que tener en cuenta que el tipo entero en informática no es idéntico al concepto matemático del tipo entero. Desde el punto de vista matemático, el número de enteros es infinito, pero la memoria del ordenador no lo es y, por tanto, el rango de valores que se puede asignar a una variable de tipo entero está entre dos valores concretos, un entero mínimo MININTEGER y un entero máximo MAXINTEGER. Estos valores límite dependerán del ordenador que se utilice.
En síntesis:
Identificador | integer |
---|---|
Rango de valores | desde MININTEGER hasta MAXINTEGER |
Operadores internos | - (cambio de signo), + , - , * , div, mod |
Operadores externos | =, ≠, <, >, ≤, ≥ |
Ejemplos | 3, -123, 9876, 0 |
Nota 1: recordad que 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.
Ejemplos:
8 * 4 = 32, el resultado de multiplicar dos enteros es otro entero.
56 + 20 = 76, el resultado de la suma de dos enteros retorna otro entero.
En cambio:
8 > 45 = falso, el resultado es de tipo booleano (tipo que se estudiará a continuación).
Nota 2: de los operadores indicados, los menos conocidos son div y mod que precisamente en programación se utilizan bastante. Recordemos que cuando hacemos una división tenemos lo siguiente:
dividendo = cociente * divisor + resto
El operador div retorna el cociente de la división de dos enteros. El resultado es también un entero. Por ejemplo:
45 div 3 = 15
45 div 2 = 22
30 div 7 = 4
El operador mod retorna el resto de la división entera. Por ejemplo:
45 mod 2 = 1
30 mod 7 = 2
345 mod 10 = 5
Nota 3: fijaos que 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.2 Tipo real
En programación interesa también poder representar valores numéricos que no sean enteros, sino que tengan decimales.
El tipo llamado real es el utilizado para estos valores, pero hay que tener en cuenta que, tal como ocurre con los enteros, los reales que se pueden representar no son infinitos, sino que hay un real mínimo, MINREAL, y un real máximo, MAXREAL. Estos valores límite dependen del ordenador con el que trabajamos. Además, no todos los reales son representables. Recordemos que, desde el punto de vista matemático, entre dos reales, por ejemplo 1.0 y 2.0, hay también un número infinito de posibles valores reales. En programación el número de reales que se pueden representar dependen de la precisión utilizada (número de bytes que se utilizan para representar un real). Esto hace que las operaciones con reales sean delicadas y haya que pensar bien en el orden en que se quieren hacer los cálculos, antes de programarlos.
En síntesis:
Identificador | real |
---|---|
Rango de valores | desde REALMIN hasta REALMAX |
Operadores internos | - (cambio de signo), + , -, * , / |
Operadores externos | =, ≠, <, >, ≤, ≥ |
Ejemplos | 3.0 , -123.56 , 5.0E 8, 49.22E 8, 1.0E5 |
Nota 1: desde un punto de vista informático, los enteros y los reales son dos tipos diferentes y no tienen nada que ver entre ellos, ya que la manera de representarlos internamente es muy diferente. Esto no quiere decir que no se pueda operar entre ellos pero, como veremos más adelante, es necesario convertir los reales a enteros o viceversa antes de para poder operar entre ellos.
Nota 2: ¡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.3 Tipo carácter
Otro tipo de dato muy común es el tipo carácter, que sirve para representar letras, dígitos, símbolos de puntuación y otros símbolos utilizados normalmente en informática.
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. Por lo tanto, se pueden representar hasta 256 caracteres diferentes. En este código, la «á» (a acentuada), por ejemplo, se considera un carácter. En internet, se puede encontrar la lista completa de códigos ASCII.
Precisamente por el hecho de haber un número detrás de cada carácter, se puede definir un orden dentro de los caracteres y, por tanto, realizar operaciones de comparación entre ellos. El código ASCII asegura que las letras están ordenadas alfabéticamente, pero hay que tener en cuenta que las mayúsculas y minúsculas no están las unas a continuación de las otras.
Una variable de tipo carácter solo guarda un único carácter. Más adelante ya se verá cómo se pueden representar cadenas de caracteres para poder guardar palabras o frases completas.
En síntesis:
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’, ‘?’, ‘@’, ‘à’ |
Nota: hay que tener en cuenta que no es lo mismo el número 1 que el carácter '1'. El primer valor se puede asignar a una variable de tipo entero, el segundo, a una variable de tipo carácter.
1.1.4. Tipo booleano
El tipo booleano es el tipo más simple que existe ya que solo admite dos valores: true (cierto) o false (falso). Su nombre procede del álgebra de Boole y toma del álgebra los operadores lógicos and, or y not. Recordemos brevemente cómo funcionan los operadores lógicos. Si a y b son dos expresiones de tipo booleano, el resultado de los operadores es el siguiente:
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 |
En síntesis:
Identificador | boolean |
---|---|
Rango de valores | false, true |
Operadores internos | and, or, not, =, ≠, <, >, ≤, ≥ |
Operadores externos | no hay |
Ejemplos | false, true |
Aparte de los operadores lógicos también se pueden utilizar los operadores de comparación (que llamamos relacionales), tal como se hace en otros tipos. Para poder comparar, sin embargo, hay que saber cuál es el orden de los dos valores booleanos. Por convención, false es menor que true. Por lo tanto:
a | b | a < b | a > b | a = b | a ≤ b | a ≥ b |
---|---|---|---|---|---|---|
true | true | false | false | true | true | true |
true | false | false | true | false | false | true |
false | true | true | false | false | true | false |
false | false | false | false | true | true | true |
El uso del tipo booleano es muy importante en la programación, ya que permite tomar decisiones dentro del programa o algoritmo, es decir, según el resultado de la comparación de determinados valores el programa ejecutará unas instrucciones u otras.
1.2.1. Declaración de constantes
La sintaxis en lenguaje algorítmico para declarar constantes es la siguiente:
const
constName: type = value;
end const
#define constName value
Donde constName es el nombre que damos a la constante, type su tipo y value el valor de la constante. 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.
Por convención, los nombres de las constantes se suelen escribir siempre en mayúsculas. Veamos algunos ejemplos:
const
PI: real = 3.1415926;
MAX_STUDENTS: integer = 50;
IVA: integer = 21;
BLANC_CHAR: char = ' ';
end const
#define MAX_STUDENTS 50
#define IVA 21
#define BLANC_CHAR ' '
La declaración de constantes es muy útil y recomendable para todos los valores fijos que se utilicen en un algoritmo.
1.2.2. Declaración de variables
La sintaxis en lenguaje algorítmico para declarar variables es la siguiente:
var
variableName: type;
end var
Donde variableName es el nombre de la variable y type el tipo. 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 escribir:
var
variableName1, variableName2, varaibleName3: 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. Veamos algunos ejemplos:
var
roomLength: real;
roomWidth: real;
currentNumberStudents: integer;
readChar: char;
end var
float roomWidth;
int currentNumberStudents;
char readChar;
Nota: en las declaraciones de variables y constantes se puede ver una serie de palabras en negrita. Estas palabras 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.
De ahora en adelante, siempre que veamos en un algoritmo palabras en negrita, son palabras clave del lenguaje algorítmico. Si se escribe un algoritmo en papel, se pueden indicar las palabras clave en otro color o bien subrayarlas. De esta manera se podrán distinguir del resto.
2. Tipos enumerativos
El lenguaje algorítmico, así como la mayoría de lenguajes de programación, permite definir nuevos tipos de datos combinando tipos elementales.
Más adelante, veremos de manera generalizada cómo definir estos nuevos tipos, pero hay uno que se utiliza extensamente y que presentamos a continuación. Son los tipos enumerativos.
El tipo enumerativo es un tipo de datos que consiste en definir un conjunto finito de valores, que se enumeran en la propia definición. Este tipo permite agrupar un conjunto de constantes.
La sintaxis para definirlos es la siguiente:
type
typeName = {VALUE1, VALUE2, VALUE3, ... , VALUEN}
end type
Como hemos dicho, VALUE1, VALUE2, ... son constantes. Cada value se representa internamente con un valor numérico creciente empezando por 0.
Por ejemplo, si se quiere trabajar con los días de la semana podemos definir el tipo y las siguientes variables:
type
daysOfTheWeek = {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY}
end type
var
firstDay: daysOfTheWeek;
lastDay: daysOfTheWeek;
end var
daysOfTheWeek firstDay;
daysOfTheWeek lastDay;
Las variables firstDay y lastDay solo podrán tener alguno de los valores definidos en el tipo enumerativo.
2.1. Operaciones con tipos enumerativos
Los únicos operadores que se pueden aplicar a los tipos enumerativos son los operadores relacionales externos ( =, ≠, <, >, ≤, ≥ ). El orden en que se enumeran los valores es el que se utiliza para establecer las relaciones de menor a mayor. Así pues, siguiendo el mismo ejemplo MONDAY < TUESDAY podríamos escribir: firstDay > secondDay.
3. Expresiones
Las expresiones nos permiten hacer cálculos en un lenguaje de programación. Una expresión es una combinación finita de operandos (constantes, variables y funciones) y de operadores (+, - <=, etc.) que sigue unas normas de sintaxis establecidas y que tiene como resultado un valor de alguno de los tipos elementales del lenguaje.
Según el tipo resultante, las expresiones pueden ser aritméticas (resultado numérico) o lógicas (resultado booleano).
Algunos ejemplos de expresiones:
- Expresión aritmética que da como resultado un entero y que solo utiliza constantes:
5 * 90 + 7 *(3 + 9) - Expresión aritmética que da como resultado un real y que utiliza una constante definida (PI) y una variable de tipo real (radius):
2 * PI+ radius - Expresión lógica que da como resultado un booleano y que utiliza constantes:
6 + 9 * 8 > 78
Dentro de una expresión, los operandos no se pueden combinar de cualquier manera. Hace falta disponer de una sintaxis para saber si una expresión está bien escrita, así como unas normas que indiquen como evaluarla.
3.1. Sintaxis de una expresión
Como hemos comentado, los operandos no se pueden combinar de cualquier manera con los operadores. Hay que definir una sintaxis para saber si una expresión está bien escrita. A continuación, se define cómo construir expresiones sintácticamente correctas.
- Un valor es una expresión. Por ejemplo:
5 , 3.1416, ‘a’
- Una variable es una expresión. Por ejemplo:
radius, numberOfStudents,
- Una constante es una expresión. Por ejemplo:
PI, MAX_STDENTS, IVA
- Si E1 y E2 son expresiones y op es un operador binario, E1 op E2 también lo es. Por ejemplo:
5+6, radius * 8 +9, a > b, i < max
- Si E es una expresión, (E) también lo es. Por ejemplo:
(radius * 8 +9)
- Si E es una expresión y op es un operador unario, op E también lo es. Por ejemplo:
-7, -(radius * 8 +9)
- Si E1, E2, ... , son expresiones y f es una función, f(E1,E2,...,En) también lo es. Por ejemplo:
sinus(90), sqr(25)
3.2. Semántica de una expresión
Ahora bien, no todas las expresiones sintácticamente correctas se pueden evaluar. También es necesario que sean semánticamente correctas, es decir, que tengan sentido.
Para que una expresión sea semánticamente correcta no puede relacionar dos expresiones (operandos) de diferentes tipos con un operador binario, ni tampoco puede aplicar un operador unitario a una expresión de un tipo incorrecto.
Por ejemplo, no tiene sentido comparar un carácter, digamos ‘a’, con un entero, digamos 5.
Recordemos una vez más que, desde el punto de vista informático, los enteros y los reales son tipos diferentes y, por lo tanto, semánticamente es incorrecto mezclarlos directamente. Ejemplos de expresiones semánticamente incorrectas:
6 + 8.8 | Porque suma un entero y un real. |
true > 35 | Porque compara un booleano con un entero. |
‘c’ + 34 < ‘b’ | Porque suma un carácter con un entero. |
45 < 56 <90 | Compara primero dos enteros y el resultado que es un booleano se compara con un entero. |
Así pues, al escribir expresiones hay que tener en cuenta tanto los aspectos sintácticos como los semánticos. En un lenguaje de programación, el compilador detectará los errores sintácticos y puede indicar advertencias (warnings) con los errores semánticos.
3.3. Prioridad de los operadores
A la hora de evaluar una expresión (obtener su valor resultante), hay que saber qué operadores evalúan primero y cómo se utilizan los paréntesis, es decir, conocer la prioridad de los operadores.
Primero hay que evaluar siempre las expresiones que están dentro de los paréntesis y después evaluar siempre los operadores con prioridad más alta (siendo 1 la prioridad más alta).
Prioridad | Operadores |
---|---|
1 | (cambio de signo), no |
2 | *, /, div, mod |
3 | + , - |
4 | ≠, >, <, ≤, ≥ |
5 | i |
6 | o |
A igual prioridad, los operadores se operan de izquierda a derecha.
4. Funciones de conversión de tipo
Hemos visto que en programación no es semánticamente correcto operar enteros con reales, lo cual puede parecer que limita los cálculos que se pueden hacer.
Pero a la hora de programar disponemos de funciones de conversión de tipos. Es decir, funciones que, dado un valor de un tipo, lo convierte en otro. 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.
5. Ejemplos
5.1. Ejemplo 03_01: decidir los tipos de datos
Enunciado:
Queremos guardar información de una persona en diferentes objetos. En concreto, nos interesan la edad, el sexo y el promedio mensual de ingresos para los últimos n meses, donde n será una constante del programa con valor 18. Definid la constante n y las variables age, sex y salary que permitan guardar estos datos en lenguaje algorítmico y en lenguaje C. Justificad la decisión del tipo de datos.
Solución:
Lo primero que hay que hacer es decidir los tipos de datos que tenemos. En el caso de n, será un valor numérico positivo, ya que es el número de meses. En el caso de la edad, será un valor entero. En el caso del sexo, tenemos dos posibles valores, hombre y mujer, que podemos representar con un carácter H para hombre y M para mujer. Finalmente, el promedio del sueldo será un valor real, ya que necesitamos al menos 2 decimales (cantidad mínima en euros). Con estas decisiones, la definición en lenguaje algorítmico quedaría de la siguiente manera:
const
N: integer = 18;
end const
var
age: integer;
sex: char;
salary: real;
end var
#define N 18
/* Declaración de variables */
int age;
char sex;
float salary;
Hay que tener en cuenta que, si no hay una especificación muy precisa en los datos, existen otras posibles soluciones. Por ejemplo, el sexo lo podríamos definir también como un tipo enumerado con dos posibles valores (MAN y WOMAN). En este caso, la solución sería:
const
N : integer = 18;
end const
type
tSex = {MAN, WOMAN}
end type
var
age: integer;
sex: tSex;
salary: real;
end var
#define N 18
/* Definición de tipos */
typedef enum { MAN, WOMAN } tSex;
/* Declaración de variables */
int age;
tSex sex;
float salary;
5.2. Ejemplo 03_02: análisis de expresiones
En este ejemplo se muestra un ejercicio para analizar la validez de un conjunto de expresiones a partir de la definición de objetos en lenguaje algorítmico.
Enunciado:
Dadas las definiciones de tipos, constantes y variables siguientes, relacionadlas con las clases de una escuela:
type
tName = {LITTLE, MEDIUM, OLDER} /* posibles nombres de las clases*/
end type
var
class1, class2, class3: integer; /*variables que indican el número de alumnos de cada clase*/
sorted: boolean;
percent, average: real;
name1, name2, name3: tName; /*variables para guardar los nombres de las clases */
end var
Indicad si son correctas o no las instrucciones y expresiones siguientes. En caso de que no lo sean, especificad el motivo o motivos:
a) sorted = class1 > class2 > class3
b) average:= integerToReal(class1 + class2 + class3) / 3.0
c) name1 = LITTLE or OLDER
d) percent:= class1 div class1 + clase2 * 100
Solución:
a) Incorrecta. Ya que todos los operandos tienen la misma prioridad, se evalúan de izquierda a derecha y, por lo tanto, tendremos (sorted = class1), donde se comparan dos variables de tipos distintos.
b) Correcta.
c) Incorrecta. En primer lugar se evalúa (name1 = LITTLE) que es correcta y retornará un booleano, pero después este booleano se evaluaría con el operando o con OLDER y, por lo tanto, tenemos variables de tipos distintos.
d) Incorrecta. Asignación de un entero a un real. A la variable percent, que es de tipo real, se le asigna el resultado de una expresión que es de tipo integer.
5.3. Ejemplo 03_03: evaluación de expresiones
En este ejemplo se muestra la evaluación paso a paso de un conjunto de expresiones en lenguaje algorítmico.
Enunciado:
Dadas las definiciones del ejemplo 2 y teniendo en cuenta los siguientes valores de las variables:
class1 = 50, class2 = 30, class3 = 40, sorted= true, name1= LITTLE, name2 = MEDIUM, name3 = OLDER
Calculad el resultado de las siguientes expresiones:
a) sorted= (class1 > class2 and class3 >(class2 + 10))
b) name1 = LITTLE or sorted and name2 > name3
c) class1 * 5 + class2 * 10 div 2 – class3 div 4 + 5 *2
Solución:
a) Recordemos que hay que evaluar la expresión según la prioridad de los operadores, teniendo en cuenta que a igual prioridad se opera de izquierda a derecha. Aunque no se ha indicado de forma explícita, las variables hay que sustituirlas por su valor para poder evaluar la expresión.
sorted = (class1 > class2 and class3 >(40)) | Evaluamos el contenido de los paréntesis primero y sustituimos la variable sorted por su valor. |
true = (true and class3 >(40)) | Después, las desigualdades. La primera da resultado true ya que el valor de class1 es mayor que la de class2. |
true = (true and false) | La segunda desigualdad da false ya que class3 tiene el valor 40. |
true = (false) | Como true no es igual a false el resultado final es false. |
false |
b)
true or sorted and name2 > name3 | Primero hay que evaluar la desigualdad y sustituir la variable sorted por su valor. |
true or true and false | Después se evalúa el and, que tiene mayor prioridad. |
true or false | Por último se evalúa el or. |
true |
c)
50 * 5 + class2 * 10 div 2 – class3 div 4 + 5 * 2 | Se evalúa la primera multiplicación. |
250 + class2 * 10 div 2 – class3 div 4 + 5 * 2 | Como la multiplicación y el operador div tienen la misma prioridad, la subexpresión class2 * 10 div 2, se debe evaluar de izquierda a derecha, es decir, primero la multiplicación y luego la división entera. |
250 + 300 div 2 – class3 div 4 + 5 * 2 | |
250 + 150 – class3 div 4 + 5 * 2 | Se evalúa la otra división entera. |
250 + 150 – 10 + 5 * 2 | Se evalúa la multiplicación. |
250 + 150 – 10 + 10 | Se evalúan las sumas y las restas. |
400 |
5.4. Ejemplo 03_04: definición de expresiones
En este ejemplo se muestra cómo definir expresiones en lenguaje algorítmico.
Enunciado:
Dadas las definiciones del ejemplo 2, construid expresiones en lenguaje algorítmico que calculen lo que se pide:
a) Expresión que comprueba si hay una clase de nombre LITTLE.
b) Expresión que calcule el número de alumnos que tendría la clase1 si aumentamos la capacidad en un 5%.
c) Expresión que indique si hay alguna clase en la que el número de alumnos supere la media en 15.
Solución:
a)
(name1 = LITTLE) or (name2 = LITTLE) or (name3 = LITTLE)
Para que la expresión represente lo solicitado hace falta comprobar si alguna de las variables name1, name2 o name3 tiene el valor LITTLE. Para ello debemos escribir tres comparaciones, una para cada variable. Es decir, debemos escribir las expresiones:
(name1 = LITTLE), (name2 = LITTLE), (name3 = LITTLE)
Pero, además, estas tres expresiones se deben combinar para obtener el resultado final deseado. Por sí mismas no dan el resultado esperado y además son tres expresiones, no una única. ¿Cómo se deben combinar? Si lo que queremos es que la expresión final sea cierta si al menos una de las expresiones anteriores es cierta, el operador que debemos usar es el operador or.
La expresión final que soluciona el problema será:
(name1 = LITTLE) or (name2 = LITTLE) or (name3 = LITTLE)
b)
La primera solución que podemos pensar para este ejercicio es escribir directamente la expresión class1 *1.05, pero, aunque matemáticamente esto es correcto, en programación no lo es ya que los operadores de la anterior multiplicación son de tipos distintos. La variable class1 está definida de tipo entero, no real. Por lo tanto, hay que convertirla primero en real y escribiremos:
integerToReal(class1) * 1.05
Pero esto nos dará un número de alumnos que no necesariamente será un número entero, por lo tanto, necesitamos convertir de nuevo el resultado a entero. La solución final es:
realToInteger( integerToReal(class1) * 1.05 )
c) Este ejercicio combina las casuísticas de los dos anteriores. Por un lado hay que comparar de manera individual si cada clase tiene o no más alumnos que la media más 15 y luego combinar las tres expresiones para crear una única. Esto daría las tres expresiones siguientes, aplicando los cambios de tipos necesarios:
integerToReal(class1) >= (integerToReal(class1+class2+class3)/3.0) + 15.0
integerToReal(class2) >;= (integerToReal(class1+class2+class3)/3.0) + 15.0
integerToReal(class3) >= (integerToReal(class1+class2+class3)/3.0) + 15.0
Por último, hay que combinarlas con un operador or para obtener la expresión final:
( integerToReal(class1) >;= (integerToReal(class1+class2+class3)/3.0) + 15.0) or
( integerToReal(class2) >= (integerToReal(class1+class2+class3)/3.0) + 15.0) or
( integerToReal(class3) >;= (integerToReal(class1+class2+class3)/3.0) + 15.0)
Nota: para obtener expresiones que hagan estos cálculos y que sean correctas en lenguaje algorítmico, es importante conocer bien el sistema de tipos de este y para qué tipos se puede aplicar cada operador. Es posible que se tengan que utilizar las funciones de conversión de tipos en algunos casos.
Resumen
En esta unidad hemos visto los tipos de datos en lenguaje algorítmico (booleano, carácter, entero y real). También hemos visto cómo crear tipos enumerados. Además, hemos trabajado con la evaluación y construcción de expresiones. Finalmente hemos visto las conversiones de tipos.
En el siguiente vídeo podemos ver un resumen de la definición de expresiones:
En el siguiente vídeo podéis ver un resumen sobre la evaluación de expresiones: