Lab. de Programacion 53 Mat. de ayuda 21042020
Laboratorio de Programacion 5 3
Prof. Naldo Gomez
MATERIAL PARCIAL DE AYUDA
Hola chicos, espero estén bien. El motivo de
este documento es poner a su alcance una breve recopilación de datos para que
vallan leyendo y asi ir comprendiendo las actividades.
En primera instancia les dejo unos links de
unos videos cortos y muy claros.
Luego de los links tienen dos temas importantes
a ir trabajando, tipos de datos y estructuras.
Links:
TIPOS DE DATOS FUNDAMENTALES. VARIABLES
El C++, como cualquier otro lenguaje de
programación, tiene posibilidad de trabajar con datos de distinta naturaleza:
texto formado por caracteres alfanuméricos, números enteros, números reales con
parte entera y parte fraccionaria, etc. Además, algunos de estos tipos de datos
admiten distintos números de cifras (rango y/o precisión), posibilidad de ser
sólo positivos o de ser positivos y negativos, etc. En este apartado se verán
los tipos fundamentales de datos admitidos por el C++. Más adelante se verá que
hay otros tipos de datos, derivados de los fundamentales.
Datos enteros char signed char unsigned
char signed short int signed int signed
long int unsigned short int unsigned int
unsigned long int Datos reales float double long double La palabra char hace
referencia a que se trata de un carácter (una letra mayúscula o minúscula, un
dígito, un carácter especial, ...). La palabra int indica que se trata de un
número entero, mientras que float se refiere a un número real (también llamado
de punto o coma flotante). Los números enteros pueden ser positivos o negativos
(signed), o bien esencialmente no negativos (unsigned); los caracteres tienen
un tratamiento muy similar a los enteros y admiten estos mismos cualificadores.
En los datos enteros, las palabras short y long hacen referencia al número de
cifras o rango de dichos números. En los datos reales las palabras double y
long apuntan en esta misma dirección, aunque con un significado ligeramente
diferente, como más adelante se verá. Esta nomenclatura puede simplificarse:
las palabras signed e int son las opciones por defecto para los números enteros
y pueden omitirse.
Datos enteros Char signed char unsigned
char Short int long unsigned short unsigned unsigned long Datos
reales Float double long double A continuación se va a explicar cómo puede ser
y cómo se almacena en C++ un dato de cada tipo fundamental. Recuérdese que en C++ es necesario declarar
todas las variables que se vayan a utilizar. Una variable no declarada produce
un mensaje de error en la compilación. Cuando una variable es declarada se le
reserva memoria de acuerdo con el tipo incluido en la declaración. Es posible
inicializar –dar un valor inicial– las variables en el momento de la
declaración; ya se verá que en ciertas ocasiones el compilador da un valor
inicial por defecto, mientras que en otros casos no se realiza esta
inicialización y la memoria asociada con la variable correspondiente contiene basura
informática (combinaciones sin sentido de unos y ceros, resultado de
operaciones anteriores con esa zona de la memoria, para otros fines).
2.1. Caracteres (tipo char)
Las variables carácter (tipo char) contienen
un único carácter y se almacenan en un byte de memoria (8 bits). En un bit se
pueden almacenar dos valores (0 y 1); con dos bits se pueden almacenar 22 = 4
valores (00, 01, 10, 11 en binario; 0, 1, 2, 3 en decimal). Con 8 bits se
podrán almacenar 28 = 256 valores diferentes (normalmente entre 0 y 255; con
ciertos compiladores entre 128 y 127). La declaración de variables tipo
carácter puede tener la forma: char nombre; char nombre1, nombre2, nombre3; Se
puede declarar más de una variable de un tipo determinado en una sola
sentencia. Se puede también inicializar la variable en la declaración. Por
ejemplo, para definir la variable carácter letra y asignarle el valor a, se
puede escribir: char letra = 'a'; A partir de ese momento queda definida la
variable letra con el valor correspondiente a la letra a. Recuérdese que el
valor 'a' utilizado para inicializar la variable letra es una constante carácter.
En realidad, letra se guarda en un solo byte como un número entero, el
correspondiente a la letra a en el código ASCII.
Volviendo al ejemplo de la variable letra, su
contenido puede ser variado cuando se desee por medio de una sentencia que le
asigne otro valor, por ejemplo: letra = 'z'; También puede utilizarse una
variable char para dar valor a otra variable de tipo char: caracter =
letra; /* Ahora caracter es igual a 'z'
*/ Como una variable tipo char es un número entero pequeño (entre 0 y 255), se
puede utilizar el contenido de una variable char de la misma forma que se
utiliza un entero, por lo que están permitidas operaciones como:
letra = letra + 1; letra_min = letra_may + ('a'
- 'A'); En el primer ejemplo, si el contenido de letra era una a, al
incrementarse en una unidad pasa a contener una b. El segundo ejemplo es
interesante: puesto que la diferencia numérica entre las letras minúsculas y
mayúsculas es siempre la misma (según el código ASCII), la segunda sentencia
pasa una letra mayúscula a la correspondiente letra minúscula sumándole dicha
diferencia numérica. Recuérdese para concluir que las variables tipo char son y
se almacenan como números enteros pequeños. Ya se verá más adelante que se
pueden escribir como caracteres o como números según que formato de conversión
se utilice en la llamada a la función de escritura. También se puede reservar 1
byte de memoria mediante variables tipo bool. Aunque realmente no sean un tipo
de variable, C++ permite declarlarlas porque se les da un uso muy específico.
En una variable tipo bool se almacena un único valor en ese byte de memoria.
Este valor puede ser 0 ó 1, donde el 0 corresponde a la sentencia false y el
uno corresponde a la sentencia true. Estas variables no se utilizan para
almacenar datos, sino para controlar el flujo de ejecución, es decir, para
dirigir las bifurcaciones y los bucles. Una variable bool se declara e
inicializa de la siguiente manera:
bool opc = 0;
//false=0
bool opt; opt = true; //true=1
2.2. Números enteros (tipo int)
De ordinario una variable tipo int se almacena
en 4 bytes (32 bits).
Con 32 bits se pueden almacenar 232 =
4294967296 números enteros diferentes: de 0 al 4294967296 para variables sin
signo, y de -2147483648 al 2147483647 para variables que pueden ser positivas y
negativas, que es la opción por defecto. Este es el rango de las variables tipo
int. Una variable entera (tipo int) se declara, o se declara y se inicializa en
la forma: unsigned int numero; int nota = 10; En este caso numero podrá estar
entre 0 y 4294967296, mientras que nota deberá estar comprendida entre
-2147483648 y 2147483647. Cuando a una variable int se le asigna en tiempo de
ejecución un valor que queda fuera del rango permitido (situación de overflow o
valor excesivo), se produce un error en el resultado de consecuencias tanto más
imprevisibles cuanto que de ordinario el programa no avisa al usuario de dicha
circunstancia.
2.3. Números enteros (tipo long)
Aunque lo habitual es que una variable tipo
int ocupe 4 bytes, en algunos compiladores no se le asignan más que 2. Para
evitar este problema se puede anteponer la palabra long, que asegura que la
variable alcance esos 4 bytes. De esta manera el rango de la variable será el
correspondiente al tipo int habitual.
2.4. Números enteros (tipo short)
Existe la posibilidad de utilizar enteros con
un rango menor si se especifica como tipo short en su declaración: short int
numero_pequeño; o, ya que la palabra clave int puede omitirse en este caso,
short numero_pequeño; El rango de un entero short puede variar según el
computador o el compilador que se utilice, pero de ordinario se utilizan 2
bytes (16 bits) para almacenarlos, por lo que se pueden representar 216 =
65.536 números enteros diferentes. Si se utilizan números con signo, podrán
representarse números entre –32.768 y 32.767. También se pueden declarar
enteros short que sean siempre positivos con la palabra unsigned: unsigned
short numero_positivo_mayor; En algunos computadores una variable int ocupa 2
bytes (coincidiendo con short) y en otros 4 bytes (coincidiendo con long). Lo
que se garantiza es que el rango de int no es menor que el de short ni mayor
que el de long.
2.5. Números reales (tipo float)
En muchas aplicaciones hacen falta variables
reales, capaces de representar magnitudes que contengan una parte entera y una
parte fraccionaria. Estas variables se llaman también de punto flotante. De
ordinario, en base 10 y con notación científica, estas variables se representan
por medio de la mantisa, que es un número mayor o igual que 0.1 y menor que
1.0, y un exponente que representa la potencia de 10 por la que hay que
multiplicar la mantisa para obtener el número considerado. Por ejemplo, π se
representa como 0.3141592654 · 101. Tanto la mantisa como el exponente pueden
ser positivos y negativos. Los computadores trabajan en base 2. Por eso un
número de tipo float se almacena en 4 bytes (32 bits), utilizando 24 bits para
la mantisa (1 para el signo y 23 para el valor) y 8 bits para el exponente (1
para el signo y 7 para el valor). Es interesante ver qué clase de números de
punto flotante pueden representarse de esta forma. En este caso hay que
distinguir el rango de la precisión. La precisión hace referencia al número de
cifras con las que se representa la mantisa: con 23 bits el número más grande
que se puede representar es, 223 =
8.388.608 lo cual quiere decir que se pueden representar todos los números
decimales de 6 cifras y la mayor parte –aunque no todos– de los de 7 cifras
(por ejemplo, el número 9.213.456 no se puede representar con 23 bits). Por eso
se dice que las variables tipo float tienen entre 6 y 7 cifras decimales
equivalentes de precisión. Respecto al exponente de dos por el que hay que
multiplicar la mantisa en base 2, con 7 bits el número más grande que se puede
representar es 128. El rango vendrá definido por la potencia, 2128 = 3.4028 · 1038 lo cual indica el
número más grande representable de esta forma. El número más pequeño en valor
absoluto será del orden de 2-127 =
5.8775 · 10-39
Las variables tipo float se declaran de la
forma: float numero_real; Las variables tipo float pueden ser inicializadas en
el momento de la declaración, de forma análoga a las variables tipo int.
2.6. Números reales (tipo double)
Las variables tipo float tienen un rango y
–sobre todo– una precisión muy limitada, insuficiente para la mayor parte de
los cálculos técnicos y científicos. Este problema se soluciona con el tipo
double, que utiliza 8 bytes (64 bits) para almacenar una variable. Se utilizan
53 bits para la mantisa (1 para el signo y 52 para el valor) y 11 para el
exponente (1 para el signo y 10 para el valor). La precisión es en este
caso, 252 = 4.503.599.627.370.496 lo
cual representa entre 15 y 16 cifras decimales equivalentes. Con respecto al
rango, con un exponente de 10 bits el número más grande que se puede
representar será del orden de 2 elevado a 2 elevado a 10 (que es 1024): 21024 = 1.7976 · 10308 Las variables tipo
double se declaran de forma análoga a las anteriores: double real_grande; Por
último, existe la posibilidad de declarar una variable como long double, aunque
el C++ no garantiza un rango y una precisión mayores que las de double. Eso
depende del compilador y del tipo de computador. Estas variables se declaran en
la forma: long double real_pero_que_muy_grande; cuyo rango y precisión no está
normalizado.
5. CONTROL DEL FLUJO
DE EJECUCIÓN
En principio, las
sentencias de un programa en C++ se ejecutan secuencialmente, esto es,
cada una a continuación de la anterior empezando por la primera y acabando por
la última. El lenguaje C++ dispone de varias sentencias para modificar este
flujo secuencial de la ejecución. Las más utilizadas se agrupan en dos
familias: las bifurcaciones, que permiten elegir entre dos o más
opciones según ciertas condiciones, y los bucles, que permiten
ejecutar repetidamente un conjunto de instrucciones tantas veces como se desee,
cambiando o actualizando ciertos valores.
5.1. Bifurcaciones
5.1.1. OPERADOR
CONDICIONAL
El operador
condicional es un operador con tres operandos (ternario) que tiene la siguiente
forma general:
expresion_1 ? expresion_2 : expresion_3;
Explicación: Se evalúa expresion_1.
Si el resultado de dicha evaluación es true (!=0), se ejecuta
expresion_2; si el resultado es
false (=0), se ejecuta expresion_3.
5.1.2. SENTENCIA
IF
Esta sentencia de
control permite ejecutar o no una sentencia según se cumpla o no una
determinada condición. Esta sentencia tiene la siguiente forma general:
if (expresion)
sentencia
Explicación: Se evalúa expresion.
Si el resultado es true (!=0), se ejecuta sentencia; si el
resultado es false (=0), se salta sentencia y se prosigue
en la línea siguiente. Hay que recordar que sentencia puede ser una
sentencia simple o compuesta.
5.1.3. SENTENCIA
IF ... ELSE
Esta sentencia
permite realizar una bifurcación, ejecutando una parte u otra del
programa según se cumpla o no una cierta condición. La forma general es la
siguiente:
if (expresion)
sentencia_1
else
sentencia_2
Explicación: Se evalúa expresion.
Si el resultado es true (!=0), se ejecuta sentencia_1 y se
prosigue en la línea siguiente a sentencia_2; si el resultado es false
(=0), se salta sentencia_1, se ejecuta sentencia_2 y se
prosigue en la línea siguiente. Hay que indicar aquí también que sentencia_1
y sentencia_2 pueden ser sentencias simples o compuestas.
5.1.4. SENTENCIA
IF ... ELSE MÚLTIPLE
Esta sentencia
permite realizar una ramificación múltiple, ejecutando una entre varias
partes del programa según se cumpla una entre n condiciones.
La forma general es
la siguiente:
if (expresion_1)
sentencia_1
else if (expresion_2)
sentencia_2
else if (expresion_3)
sentencia_3
else if (...)
...
[else
sentencia_n]
Explicación: Se evalúa expresion_1.
Si el resultado es true, se ejecuta sentencia_1. Si el resultado
es false, se salta sentencia_1 y se evalúa expresion_2.
Si el resultado es true se ejecuta sentencia_2, mientras
que si es false se evalúa expresion_3 y así sucesivamente.
Si ninguna de las expresiones o condiciones es true se ejecuta expresion_n
que es la opción por defecto (puede ser la sentencia vacía, y en ese caso
puede eliminarse junto con la palabra else). Todas las sentencias pueden
ser simples o compuestas.
5.1.5. SENTENCIA
SWITCH
La sentencia que se
va a describir a continuación desarrolla una función similar a la de la
sentencia if ... else con múltiples ramificaciones, aunque como
se puede ver presenta también importantes diferencias. La forma general de la
sentencia switch es la siguiente:
switch (expresion) {
case expresion_cte_1:
sentencia_1
case expresion_cte_2:
sentencia_2
...
case expresion_cte_n:
sentencia_n
[default:
sentencia]
}
Explicación: Se evalúa expresion
y se considera el resultado de dicha evaluación. Si dicho resultado
coincide con el valor constante expresion_cte_1, se ejecuta sentencia_1
seguida de sentencia_2, sentencia_3, ..., sentencia.
Si el resultado coincide con el valor constante expresion_cte_2, se
ejecuta sentencia_2 seguida de sentencia_3, ..., sentencia.
En general, se ejecutan todas aquellas sentencias que están a continuación de
la expresion_cte cuyo valor coincide con el resultado calculado al
principio. Si ninguna expresion_cte coincide se ejecuta la sentencia que
está a continuación de default. Si se desea ejecutar únicamente una sentencia_i
(y
no todo un conjunto
de ellas), basta poner una sentencia break a continuación (en algunos
casos puede utilizarse la sentencia return o la función exit()).
El efecto de la sentencia break es dar por terminada la ejecución de la
sentencia switch. Existe también la posibilidad de ejecutar la misma sentencia_i
para varios valores del resultado de expresion, poniendo varios case
expresion_cte seguidos.
El siguiente ejemplo
ilustra las posibilidades citadas:
int opc;
cout <<"Introduzca la opcion deseada:
";
cin>>opc;
switch (opc){
case 1 : cout << "caso 1\n" ;
break;
case 2 : cout << "caso 2\n" ;
break;
case 3 : cout << "caso 3\n" ;
break;
case 4 : cout << "caso 4\n" ;
break;
default : cout << "caso por
defecto";
}
5.1.6. SENTENCIAS
IF ANIDADAS
Una sentencia if
puede incluir otros if dentro de la parte correspondiente
a su sentencia, A estas sentencias se les llama sentencias
anidadas (una dentro de otra), por ejemplo,
if (a >= b)
if (b != 0.0)
c = a/b;
En ocasiones pueden
aparecer dificultades de interpretación con sentencias if...else anidadas,
como en el caso siguiente:
if (a >= b)
if (b != 0.0)
c = a/b;
else
c = 0.0;
En principio se
podría plantear la duda de a cuál de los dos if corresponde la
parte else del programa. Los espacios en blanco –las indentaciones
de las líneas– parecen indicar que la sentencia que sigue a else corresponde
al segundo de los if, y así es en realidad, pues la regla es que el
else pertenece al if más cercano. Sin embargo, no
se olvide que el compilador de C++ no considera los espacios en blanco (aunque
sea muy conveniente introducirlos para hacer más claro y legible el programa),
y que si se quisiera que el else perteneciera al primero de los if
no bastaría cambiar los espacios en blanco, sino que habría que
utilizar llaves, en la forma:
if (a >= b) {
if (b != 0.0)
c = a/b;
}
else
c = 0.0;
Recuérdese que todas
las sentencias if e if...else, equivalen a una
única sentencia por la
posición que ocupan
en el programa.
5.2. Bucles
Además de bifurcaciones,
en el lenguaje C++ existen también varias sentencias que permiten repetir una
serie de veces la ejecución de unas líneas de código. Esta repetición se
realiza, bien un número determinado de veces, bien hasta que se cumpla una
determinada condición de tipo lógico o aritmético. De modo genérico, a estas
sentencias se les denomina bucles. Las tres construcciones del
lenguaje C++ para realizar bucles son el while, el for y
el do...while.
5.2.1. SENTENCIA
WHILE
Esta sentencia
permite ejecutar repetidamente, mientras se cumpla una determinada condición,
una sentencia o bloque de sentencias. La forma general es como sigue:
while (expresion_de_control)
sentencia
Explicación: Se evalúa expresion_de_control
y si el resultado es false se salta sentencia y se prosigue
la ejecución. Si el resultado es true se ejecuta sentencia y
se vuelve a evaluar expresion_de_control (evidentemente alguna variable
de las que intervienen en expresion_de_control habrá tenido que ser
modificada, pues si no el bucle continuaría indefinidamente). La
ejecución de sentencia prosigue hasta que expresion_de_control se
hace false, en cuyo caso la ejecución continúa en la línea
siguiente. En otras palabras, sentencia se ejecuta repetidamente
mientras expresion_de_control sea true, y se deja de
ejecutar cuando
expresion_de_control
se
hace false. Obsérvese que en este caso el control para
decidir si se sale o no del bucle está antes de sentencia, por lo
que es posible que sentencia no se llegue a ejecutar ni una sola vez.
5.2.2. SENTENCIA
FOR
For es quizás el tipo de
bucle mas versátil y utilizado del lenguaje C++. Su forma general es la siguiente:
for (inicializacion; expresion_de_control;
actualizacion)
sentencia;
Explicación: Posiblemente la
forma más sencilla de explicar la sentencia for sea utilizando la
construcción while que sería equivalente. Dicha construcción es
la siguiente:
inicializacion;
while (expresion_de_control) {
sentencia;
actualizacion;
}
donde sentencia puede
ser una única sentencia terminada con (;), otra sentencia de control ocupando
varias líneas (if, while, for, ...),
o una sentencia compuesta. Antes de iniciarse el bucle se ejecuta inicializacion,
que es una o más sentencias que asignan valores iniciales a ciertas variables o
contadores. A continuación se evalúa expresion_de_control y si es false
se prosigue en la sentencia siguiente a la construcción for;
si es true se ejecutan sentencia y actualizacion, y
se
vuelve a evaluar expresion_de_control.
El proceso prosigue hasta que expresion_de_control sea false.
La parte de actualizacion sirve para actualizar variables o incrementar
contadores. Un ejemplo típico puede ser el producto escalar de dos vectores a
y b de dimensión n:
for (pe =0.0, i=0; i<n; i++){ /*i empieza en 0,
porque los
vectores empiezan a contar desde
la posición cero*/
pe += a[i]*b[i];
}
Primeramente se
inicializa la variable pe a cero y la variable i a 0; el ciclo se
repetirá mientras que i sea menor que n, y al final de cada ciclo el
valor de i se incrementará en una unidad. En total, el bucle se repetirá
n veces. La ventaja de la construcción for sobre la
construcción while equivalente está en que en la cabecera de la
construcción for se tiene toda la información sobre como se
inicializan, controlan y actualizan las variables del bucle. Obsérvese que la inicialización
consta de dos sentencias separadas por el operador (,).
5.2.3. SENTENCIA
DO ... WHILE
Esta sentencia
funciona de modo análogo a while, con la diferencia de que la
evaluación de expresion_de_control se realiza al final del bucle,
después de haber ejecutado al menos una vez las sentencias entre llaves; éstas
se vuelven a ejecutar mientras expresion_de_control sea true.
La forma general de esta sentencia es:
do
sentencia;
while(expresion_de_control);
donde sentencia puede
ser una única sentencia o un bloque, y en la que debe observarse que hay que
poner (;) a continuación del paréntesis que encierra a expresion_de_control,
entre otros motivos para que esa línea se distinga de una sentencia while
ordinaria.
Comentarios
Publicar un comentario