Capítulo 3
Programación en lenguajes de alto nivel
1)Concepto de Algoritmo
2)Lenguajes y paradigmas de programación.
3)Características de la Programación Estructurada
4)Concepto de Programa de alto nivel
5)Variables y constantes
6)Tipos simples de datos
7)Fases en la realización de un programa
7.1 Análisis del problema.
7.2 Diseño del algoritmo.
7.3 Programación del algoritmo
Algoritmo
Definición de Algoritmo:
Es un proceso mecánico en lógica y matemáticas. Donde mecánico
significa:
Se expresa mediante el conjunto de instrucciones bien
definidas.
Terminará en un número finito de pasos
Es efectivo, es decir, aborda un problema con tareas
realizables (no necesita por ejemplo, disponer de memoria
infinita)
No necesita de introspección ni inteligencia para llevarse a
acabo
Algoritmo del MCD de Euclides:
A y B dos números naturales
Repetir
Si A < B entonces intercambiar los valores de A y B
A = A-B
Hasta que A=0
En B se encuentra el MCD de los dos números originales
Traza
Consiste en darle unos valores de entrada concretos al algoritmo
y ver qué valores van adquiriendo las variables fundamentales
del algoritmo:
A
B
Valores de entrada: 4 22
(Entrada (Input) del algoritmo)
Intercambio 22
4
Resto 18
4
Resto 14
4
Resto 10
4
Resto 6
4
Resto 2 4
Intercambio 2 4
Resto 4
2
Resto 2
2
Lenguajes de alto y bajo nivel
Paradigmas Alto Nivel / Bajo Nivel
Lenguaje de alto nivel: Trabaja con
instrucciones en lenguaje natural.
Lenguaje de bajo nivel: Trabaja con las
instrucciones del microprocesador.
Programa 1 (lenguaje de bajo Programa 2 (lenguaje de alto
nivel): nivel C++)
MOV 90A8H [0003H] int resultado;
MOV 549FH [0008H] int contador;
MOV AX 90A8H resultado = 3;
contador =8;
LAZO: JZ FINAL while(contador != 0){
ADD AX 90A8H resultado = resultado + 3;
DEC 549FH contador = contador -1;
JMP LAZO }
FINAL: MOV 90A8H AX cout << “El resultado es: “ <<
resultado << endl;
Programación de Alto Nivel:
Programación estructurada
● Es un modelo de programación basado en tres
conceptos:
– Aḿbito de las variables. Las variables sólo
pueden ser accedidas por el subprograma (Módulo)
en el cual están definidas. (Lo veremos en el
tema 5)
– Pocas instrucciones de control: Solo hay dos
tipos de instrucciones de control: Condicionales
e Iterativas (Lo veremos en este tema)
– Uso del diseño Top-down en la elaboración de los
programas. (Lo aprenderemos a lo largo del curso)
Análisis del problema
Metodología Top-Down
Se descompone el problema original en subproblemas
más pequeños y (en teoría) más sencillos.
Se vuelve a descomponer en problemas más
sencillos hasta que los problemas sean
directamente traducibles a un algoritmo
Se codifican los subprogramas y se combinan entre
sí para solucionar el problema original
Problema
Original
SubProblem SubProblem SubProblem
a a a
1 2 3
SupProblem SubProblem SubProblem
a a 1-2 a
1-1 1-3
Hipótesis: La solución de los problemas sencillos, combinados,
da lugar a la solución del problema complejo original
Ventajas diseño top-down
*Favorece un estilo de programación Modular (se verá
en el capítulo 5)
Buena organización del código
Rápida detección de errores
Reutilización del código
*Hay ENCAPSULAMIENTO de los datos y de los subprogramas
(Módulos)
- Una sentencia no puede pertenecer a dos
subprogramas
- La información se pasa entre subprogramas (los
subprogramas NO ACCEDEN a los datos de otros
subprogramas)
Favorece el proceso de división del trabajo
Estructura general de un programa
en C++ Librería:
●
Directivas de preprocesador Conjunto de
#include <iostream> programas ya
● Declaraciones globales (constantes, funciones,…) escritos que C++
const float PI = 3.14159; proporciona al
● Instrucción de ámbito de las variables
programador.
using namespace std; -Matemáticas
● Función Principal:
-Entrada /
int main() salida
{
Secuencia de declaraciones e instrucciones y llamadas a subprogramas
return(0);
}
● Especificación de cada uno de los subprogramas utilizados
float función1 ()
{
Secuencia de declaraciones e instrucciones
return (<valor>);
}
● ...
Estructura de un programa en C++
#include <iostream> //cabecera. ESTO ES UN COMENTARIO
using namespace std;
int main(){ //declaración de la función principal
//Parte de declaración de variables
int numero;
int i;
//Parte de cuerpo de instrucciones
cout << “indica el numero de comienzo” << endl;
cin >> numero;
for(i=1; i < 10 ; i++){
numero = numero *i;
cout << numero << endl;
}
//Instrucción de retorno de valor
return(0);//instrucción final de retorno
}
Componentes de un programa:
Variables y constantes
● Constante: Valor numérico que se define una única
vez en el programa y no cambia nunca su valor.
Sirve para definir constantes numéricas como
– const float PI = 3.14159;
– const float ratio_cambio = 0.8766;
● Variables: Dato que almacena un valor de un tipo de dato
específico. Puede variar a lo largo del programa.
int numero;
float valor;
char letra;
bool es_verdadero;
Datos en C++: simples y
compuestos
TIPOS
SIMPLES COMPUESTOS
ENTERO PUNTO FLOT. CARACTER BOOLEANO PUNTERO
HOMOGENEOS HETEROGENEOS
VECTORES CADENAS DE REGISTROS
CARACTERES
LINEALES MATRICES n-
DIMENSIONALES
Los tipos de datos simples los proporciona el lenguaje de
programación. Los tipos de datos compuestos son agregados de los
simples
Elementos esenciales de un Programa:
Sentencias
● Las Sentencias, son cada una de las instrucciones básicas de un programa. Hay 4 tipos:
– Declaración: Sirve para definir los datos. Ejemplo: float p;
– Asignación: Carga un valor en una variable. El símbolo '=' la divide en dos partes:
la variable receptora del valor en la parte izquierda
la expresión o valor en la parte derecha. Cualquier variable en la parte
derecha representa su valor. Ej. p = (q*q) – (3.5 / q);
-De control de flujo: Establecen el orden de de jecución del resto de sentencias.
-De entrada/salida: Sirven para introducir datos y sacar datos y mensajes al usuario (Teclado/Pantalla)
Ejemplos:
int x; //declaración
float y; //declaración
x = 3; //asignación
y = 7;//asignación
x = 2 + (y*5) – x; //El valor de x es 34 tras realizarse la asignación. Nota el uso de x en ambas partes
If (x != 0) //Sentencia de control de flujo
x = x + x; //Asignación correcta
Más sobre Sentencias (asignación)
Una asignación especial es la primera vez que una
variable recibe un valor. Esta primera
asignación se llama inicialización de la variable y el
lenguaje C++ permite realizarla en el momento de la
declaración de la variable:
float numero = 5.45 ;
En la operación de asignación se distinguen la parte izquierda (L) de
la asignación que es la que recibe el valor, y la parte derecha (R)
que es la que proporciona el valor. En la parte L, la variable se
comporta como espacio de memoria receptor de un valor. En
cambio en la parte R la variable se comporta como el valor que
contiene. Esta distinción hace posible asignaciones como esta:
int x ;
x = 5;
(parte L) (parte R)
x = x + 9; /*obsérvese el uso de x en L y
R de la asignación*/
Sentencias de entrada y salida
● Sentencias de entrada de datos
La entrada de datos estándar es el teclado del
computador. La sentencia C++ para ella es
cin >> <nombre variable>;
Ejemplo: int x;
char letra;
cin >> x; // carga una variable de tipo entero con
el valor tecleado
cin >> letra; //cara una variable de tipo char con
una letra tecleada
Sentencias de entrada y salida
● Sentencia de salida
La salida estandar es la pantalla. La instrucción de C++ para
la salida de datos es: cout << <nombre de variable> << endl;
Ej. int x=65;
char letra = ‘A’;
cout << x << “ “ << letra << endl;
Sacaría por pantalla: 65 A
//dejaría el cursor en esta línea
Como se ve, las salidas se pueden encadenar para formar salidas más complejas:
cout << “El numero: “ << x << “se asocia con la letra “ << letra << endl;
sacaría por pantalla: El número 65 se asocia con la letra A
Atributos de los datos
●
Nombres: Es una etiqueta que identifica al dato. No empiezan
por {0,1,2,3,4,5,6,7,8,9,_?,¿,!,%,#}
No contienen blancos.
Se diferencian mayúsculas de minúsculas
int 1234ya; (Nombre de variable incorrecto)
float ¿solucion?; (Nombre incorrecto)
char letra vocal; (Nombre incorrecto)
Convenio: Los nombres de las constantes se escriben en
mayúscula
●
Tipo (de dato): es la especificación del conjunto de valores
permitidos para ese dato (numero de bytes que ocupa) y el
conjunto de operaciones permitidas con ese dato.
-El conjunto de valores permitido lo determina el número de
bytes que cada compilador asigna para almacenar a un dato
de un tipo concreto.
-La operación definida sobre un tipo da como resultado un dato
del mismo tipo. Así está prohibido realizar una operación “Raíz
cuadrada” sobre un dato de tipo entero, ya que no es una
operación propia de este tipo.
Atributos de los datos
Ámbito. Es la región del código de un programa
sobre la cual un dato está definido. Los datos
cuyo ámbito sea todo el código de un programa se
denominan datos globales. Su declaración se
realiza en la cabecera del programa. Los datos con
una región de validez menor, se denominan datos
locales a esa región. El ámbito de una variable
local es el código del subprograma (función o
procedimiento) donde está definida y su
declaración como variable está en la cabecera del
código correspondiente al subprograma. El ámbito
de un dato implementa la idea de encapsulación de
los datos dentro de los módulos. Las variables
locales a esos módulos están encapsuladas en ellos
y no son accesibles por los restantes
procedimientos o funciones del programa.
Dirección. Es la dirección del primer byte que
forma la celda de memoria preparada para contener
Tipos de datos simples (C++)
Tipo Entero (int en C++)
Representación: Dependiendo del compilador usa 2 bytes , 4 bytes
o más. Si usa dos bytes el intervalo de representación es [-
32768, 32767].
Si usa 4 bytes el intervalo de representación es [-2147483648,
2147483647]
Operaciones Aritméticas (por orden de prioridad):
- {operación unaria de cambio de signo}
* / % {multip. división entera y operador módulo
Nota: El operador módulo devuelve el
resto de la división entera.}
+ - {suma, resta}
Operaciones Relacionales o lógicas
! negación {!FALSE es igual a TRUE}
> >= < <=
== != {igual o distinto de}
Regla: Dentro del mismo grupo, tendrá mayor prioridad la
operación que aparezca más a la izquierda en la expresión.
Por ejemplo:
- 3 + 5 + 6 / 4 <= 4 * 8.5 / 2
da como resultado TRUE y corresponde a la agrupación de
operaciones siguiente: ( (-3)+5+(6 / 4) ) <= ((4*8.5) / 2 )
Tipos de datos simples (C++)
Precedencia de operaciones:
Cuando no hay paréntesis, las expresiones se evalúan usando u
orden de precedencia establecido por el lenguaje C++:
Mayor
++, - - (operaciones incremento/decremento) precedenc
- (operación unaria de signo negativo) ia
*/% (multiplicación, división y módulo)
+- (suma , resta)
< <= > >= (operadores relacionales)
== != (operadores relacionales)
&& (AND lógico)
|| (OR lógico) Menor
precedenc
ia
Tipos de datos simples (C++)
Modificadores del tipo int
short int [-32768, 32767]
unsigned int [0, 65536]
long int [-2147483648, 2147483647] (si el int es de 2 bytes)
Unsigned long int [0, 4294967296]
Errores más comunes en la utilización del tipo entero:
Uso de variables sin inicializar su valor
#include <iostream>
main(){
int x,y,z; {declaración}
z = x+y; {ERROR!.No sabemos el valor de x e y}
cout <<“El resultado es” << z; {se imprimira un
valor que desconocido}
return(0);
}
Tipos de datos simples (C++)
Desbordamiento. Ocurre cuando excedemos la cifra máxima o
mínima de almacenamiento.
#include <iostream>
main(){
int x,y,z; {imaginemos que está
representado por 2 bytes ((+/-)32768)}
x=30000;
y=32000;
z= x+y; {Se produce un desbordamiento al
salirse de rango el resultado de la suma}
return(1);
}
Tipos de datos simples (C++)
Tipo punto flotante (float en C++)
Operaciones:
Aritméticas: Las mismas que los enteros salvo '%' (operador
módulo). La librería matemática permite el uso de funciones
matemáticas.
Lógicas: Está permitidas las comparaciones del tipo < <= > >=
No están bien definidas las operaciones == y != debido a la
precisión finita.
Rango:
float [10 ^ -38 10 ^38] (4 bytes)
Con el modificador double [10 ^-4932 10 ^4932] (8 bytes)
Problemas con el tipo coma flotante:
Precisión Finita. Como sabemos, el conjunto matemático de los
números reales es no numerable, esto quiere decir que entre dos
números reales tan próximo uno a otro como queramos, siempre
existe otro entre los dos. Es por eso que en nuestro intervalo de
representación de los reales, no vamos a poder representar
cualquier número real
Tipos de datos simples (C++)
Distribución no homogénea de la precisión.
Como una consecuencia de la precisión finita, se da el
hecho de que la precisión es diferente dependiendo de la
zona de la recta real en que situemos nuestros cálculos.
El hecho es evidente: si estamos en las proximidades del 0
podemos utilizar todos los números de la mantisa para
representar a dicho número. En cambio si estamos en las
proximidades de los números extremos representables (i.e.
3.4 Exp 38), las cifras de la mantisa representarán
realmente decenas, centenas, millares,…pero no cifras
decimales, con lo que podremos expresar los números con
menor precisión.
Acumulación del error de precisión.
Si bien se producen errores de redondeo cuando nos faltan
cifras para apreciar un valor real, todavía se produce un
error más grave cuando estos errores de redondeo se van
acumulando en los cálculos, es decir cuando empleamos un
valor que hemos redondeado por falta de precisión para
realizar nuevos cálculos.
Tipos de datos simples (C++)
Errores típicos del manejo de coma flotante:
Aparte de los problemas enumerados arriba producidos
por la precisión finita, también podemos encontrar los
mismos que ocurren con los enteros.
Un error típico además del manejo de coma flotante es
usar las operaciones lógicas ( ==, !=) (igual que,
distinto de) con estos números. Debido a la precisión
finita es posible que dos números difieran sólo en sus
dígitos más bajos, que pueden ser despreciables a
efectos de lo que estamos comparando, y sin embargo el
programa los tomará como diferentes. Por ejemplo
0.9990 Exp –5 y 0.8999 exp –5 los tomará como
diferentes, cuando lo son en su décima cifra.
Tipos de datos simples (C++)
Caracteres (char en C++)
Representación: En el estándar ASCII 1 byte (256
caracteres)
Tipos de datos simples (C++)
Operaciones con el tipo char: >, >=, <, <=, ==, !=
Tipo booleano o lógico (bool en C++)
Representación: Formalmente 1 bit, en la práctica 1 byte
Valores
{true (se representa como cualquier entero diferente de 0) ,
false (se representa como 0)}
Operaciones: Las tres operaciones básicas del álgebra de Boole son : AND,
OR, NOT cuyas tablas de valor ya se definieron en el capítulo 1. Con ellas se
pueden implementar otras como NAND, NOR , XOR.
Las operaciones NAND y NOR tienen especial interés en electrónica.
La operación XOR viene definida por la siguiente tabla de verdad:
XOR
0 1
0 0 1
1 1 0
Tipos de datos simples (C++)
Tipo puntero
Una variable de este tipo consiste en un conjunto de bytes (4 o´
6) en los que se almacena una dirección a una celda de memoria.
Normalmente decimos que un puntero “apunta” a un dato, ya que al
contener la dirección de la memoria del 1er byte de ese dato, lo
tenemos localizado en la memoria. El tipo de dato al que puede
“señalar” un puntero, es cualquiera de los tipos simples que hemos
visto y los definidos por el programador que veremos en el capítulo
siguiente.
Operaciones. Hay dos básicas:
-la operación dirección. Dada una variable de un tipo cualquiera,
(incluído el tipo puntero), obtiene la dirección en memoria del
primer byte de esa variable. Se usa básicamente para asignar a un
puntero un valor. En C++ esta operación se nombra con el carácter
‘&’ de tal manera que &<nombre variable> representa la dirección de
comienzo de dicha variable en la memoria.
Tipos de datos simples (puntero)
La operación indirección. Es la inversa a la
anterior. Dado una dirección de una variable, accede
al dato almacenado en esa dirección. En C++ se nombre
con el carácter ‘*’ con lo que hay que será el
contexto del uso el que nos la diferencie de la
operación producto de dos números.
int *p; {puntero a un dato de tipo entero}
float *p; {puntero a un tipo de dato coma flotante}
char **p {puntero que guarda la dirección de memoria
donde se encuentra como dato la dirección de memoria de un
dato }
Algunas operaciones usuales son:
char c = ‘a’; int num=5;
char *p; int *p;
p= &c; {p apunta a c} int g;
cout << *p << endl; p= & num;
*p = ‘b’; {cambia c por ‘b’} g = 9 * (*p);
Conversión de tipos
En el lenguaje C++, las conversiones implícitas de tipo (también llamadas
coerciones) son realizadas por el compilador en tiempo de compilación en los
dos casos siguientes:
-En las expresiones:
Como regla general las variables en una expresión se transforman al tipo que
mayor espacio de memora requiere siguiendo estas sencillas condiciones:
Si algún operador es de tipo double, todas las variables se convierten a
éste.
Sino, Si algún operador es de tipo float, todas las variables se convierten a
éste.
Sino, Si algún operador es de tipo long, todas las variables se convierten a
éste.
Sino, Si algún operador es de tipo int, todas las variables se convierten a
éste.
Sino, las variables de tipo short y char son mantenidas.
- En las asignaciones.
El resultado de la derecha de la asignación es transformado al de la
izquierda. Si esta transformación sigue alguna de las reglas del apartado
anterior, no hay problemas. En cambio:
Si la asignación es (int)(short) o (int)(char) NO se pierde información.
Si es (char) ← (int) o (int)(long) se pierde información (hay
desbordamiento)
Si es (int) (float) o (int) (double) o (long) (float) o (long)
(double) se produce un truncamiento a su parte entera.
Conversión de tipos
Ejemplos:
int x=7;
float y=3.0;
float resultado;
resultado= x / y; //dará 3.5
Conversion explícita
En C++ se pueden realizar conversiones explícitas indicando
entre paréntesis, delante de una variable, el tipo al cual
queremos transformarla:
float y;
cout <<“introduce un numero real”;
scanf(“%f”, &y);
y = y – (int)y; /*conversión explícita*/
cout << “ su parte decimal es: ” << y;
En bibliografía anglosajona la conversión explícita se llama
“casting”.
Actividad en clase
● Escribe un programa en C++ que sume dos números que se
piden por la entrada estándar y saque su resultado por
la salida estandar
● Una planta embotelladora empaqueta cajas de refrescos
con 5 refrescos cada una. Escribe un programa que pida
cuántos refrescos hay que empaquetar y devuelva cuántas
cajas se crearán y cuántas botellas quedarán sueltas.
● Escribe un programa que pida por entrada estandar una
cantidad de dias en punto flotante (ej. 5.35 dias) y
devuelva el número de dias (5), el número de horas (8
horas) y el número de minutos (24). Usa conversión
explícita de tipos para truncar las cantidades en punto
flotante