Está en la página 1de 12

TEL-102 Seminario de

Programación

Estructuras de control

Wladimir Ormazábal (wladimir.ormazabal@usm.cl)

In [2]: #include <iostream>


using namespace std;

Previos
No solo son necesarios los tipos de datos, variables y operaciones para que
podamos codificar los algoritmos con los que trabajamos, también necesitamos
poder manejar el flujo en la ejecución del código por parte de la máquina.

Las Estrcuturas de control permite manejar el flujo mediante al ejecución


mediante la evalaución de expresiones interpretadas como valores booleanos
( true o false ).

Recuerde que se interpeta como true todo valor numérico ≠ de


0

Otros puntos relevantes a tener en consideración:

• Se pueden tener estructuras de control que controlan la ejecución de una o


más sentencias o no en base a una condición (selección).

• Se pueden tener estructuras de control que repiten una o más sentencias


hasta que se alcance (o mientrás se cumpla) cierta condición.

• A diferencia de Python, el ámbito correspondiente a la estructura de control


se indica mediante el uso de {} y no mediante la identación (aunque es
altamente recomendada para facilidad de lectura y ruteo)

Caso 1: Selección
Uno de los escenarios más recurrentes es el seleccionar la ejecución de una o
más sentencias en base a la evaluación de una condición.

if - else if - else
Muy similar a la lógica ya conocida desde Python:

if <condición>:
...
elif <condición 2>:
...
else:
...

En C++ se escribe como:

if(condición){
...
}else if(condicion 2){
...
}else{
...
}

Notar que else if y else son opcionales (puede estar uno o


ambos). Se ejecuta hasta la primera condición que se cumple, sino
se cumple ninguna se ejecuta la sentencia dentro de else . Las
condiciones a evaluar son expresiones.

In [4]: int x = 10;

if(x > 0){


cout << "Mayor que 0" << endl;
} else if(x > 5){
cout << "Mayor que 5" << endl;
} else{
cout << "No se que paso" << endl;
}

Mayor que 0
Las expresiones pueden incluir operaciones, que se realizan y evalúan
dependiendo de la naturaleza de la operación y de las reglas de precedencia:

In [5]: int x = 0;

if(x++ > 0){


cout << x <<" es mayor que 0!" << endl;
}else{
cout << x << " es menor o igual a 0" << endl;
}

1 es menor o igual a 0
In [6]: int y = 0;

if(++y > 0){


cout << y << " es mayor que 0!" << endl;
}else{
cout << y << " es menor o igual a 0" << endl;
}

1 es mayor que 0!
Otro elemento relevante a tener en consideración es dada la naturaleza
"booleana" de las expresiones que son evaluadas: solo se evaluarán hasta que
sea necesario (corto circuito)

In [7]: int x = 0;

if(1 == 1 || ++x){
cout << "1 siempre es igual a 1" << endl;
}
cout << "x = " << x << endl;

1 siempre es igual a 1
x = 0

In [8]: int x = 0;

if(1 == 1 && ++x){


cout << "1 siempre es igual a 1" << endl;
}
cout << "x = " << x << endl;

1 siempre es igual a 1
x = 1
También se respeta el orden de precedencia al momento de ejecución de
asignaciones dentro de la expresión a evaluar:

In [9]: int x = 0;

if(1 == 1 || (x = 1 + 1)){
cout << "1 siempre es igual a 1" << endl;
}
cout << "x = " << x << endl;

1 siempre es igual a 1
x = 0

In [10]: int x = 0;

if(1 == 1 && (x = 1 + 1)){


cout << "1 siempre es igual a 1" << endl;
}
cout << "x = " << x << endl;

1 siempre es igual a 1
x = 2
Hay que tener especial cuidado cuando se está utilizando asignaciones de
expresiones que involucran a una misma variable

In [11]: int x = 0;

if(x > 0 && ++x > 0){


cout << "Se cumplio la condición" << endl;
}
cout << "x = " << x << endl;

x = 0

In [12]: int x = 0;

if(x > 0 || x++ > 0){


cout << "Se cumplio la condición" << endl;
}
cout << "x = " << x << endl;

x = 1

Caso 1.1: Equivalencia a un valor


Una evaluación que puede ser recurrente, es que se necesite evaluar la
equivalencia a un valor, lo cual se puede implementar facilmente con lo visto.
Por ejemplo, si un valor es "A", "B" o "C"

In [13]: char x = 'B';

if(x == 'A')
cout << "Es A" << endl;
else if(x == 'B')
cout << "Es B" << endl;
else if(x == 'C')
cout << "Es C" << endl;

Es B

switch - case
Es una sentencia que nos permite evaluar la equivalencia de una variable con
algún valor determinado:

switch(variable){
case valor_1:
...
break;
case valor_2:
...
break;
default:
....
}
Por ejemplo, el caso anterior:

In [14]: char x = 'B';

switch(x){
case 'A':
cout << "Es A" << endl;
break;
case 'B':
cout << "Es B" << endl;
break;
case 'C':
cout << "Es C" << endl;
break;
default:
cout << "No corresponde a los valores" << endl;
}

Es B
Es muy importante el uso de break dado que se pueden seguir realizando
todas las instrucciones hasta salir de switch .

In [15]: char x = 'B';

switch(x){
case 'A':
cout << "Es A" << endl;
case 'B':
cout << "Es B" << endl;
case 'C':
cout << "Es C" << endl;
default:
cout << "No corresponde a los valores" << endl;
}

Es B
Es C
No corresponde a los valores

Caso 2: Repeticiones
Otro escenario común es realizar cierta repetición de de instrucciones bajo
alguna condición (mientra se cumpla o hasta que se alcance).

while
Se repite la instrucción en base a alguna condición a evaluar lo que en Python
es:

while condicion:
...
En C++ es:

while(condicion){
...
}
Por ejemplo, hacer una cuenta regresiva hasta llegar a 1:

In [16]: int x = 10;

while(x > 0){


cout << x << "!" << endl;
x--;
}

10!
9!
8!
7!
6!
5!
4!
3!
2!
1!
Notar que si la condición no se cumple no se realiza ninguna iteración

In [17]: int x = 0;

while(x > 0){


cout << x << "!" << endl;
x--;
}
cout << "fin..." <<endl;

fin...
Si quisieramos ejecutar el ciclo al menos una vez, se puede (entro otras cosas)
apoyar de una variable auxiliar que nos garantice aquello:
In [18]: int x = 0; bool aux = true;

while(aux){
cout << "flag..." <<endl;
if (x > 0){
cout << x << "!" << endl;
x--;
}else{
aux = false;
}
}
cout << "fin..." <<endl;

flag...
fin...

do-while
Existe una sentencia que nos garantiza al menos un ciclo (o iteración) antes de
evaluar, la cual se escribe como:

do{
...
}while(condicion)
La evaluación de la condición se hace luego de terminar una iteración, en
cambio en el while se hace al inicio del ciclo.

In [19]: int x = 0;

do{
cout << x << "!" << endl;
}while(x > 0);
cout << "fin..." <<endl;

0!
fin...

In [21]: int x = 10;

do{
cout << x-- << "!" << endl;
}while(x > 0);
cout << "fin..." <<endl;

10!
9!
8!
7!
6!
5!
4!
3!
2!
1!
fin...
Se pueden obtener los mismo resultados con ambas sentencias, pero se
debe ser cuidadoso en cuanto al uso de variables que se están evaluando

In [22]: int x = 0;
do{
cout << x++ << "!" << endl;
}while(x < 0);
cout << "fin..." <<endl;

0!
fin...

In [23]: int x = 0;
while(x < 0){
cout << x++ << "!" << endl;
}
cout << "fin..." <<endl;

fin...

In [24]: int x = 0;
while(x <= 0){
cout << x++ << "!" << endl;
}
cout << "fin..." <<endl;

0!
fin...

for
Otra sentencia para poder iterar. for establece como se inicializa una variable
numérica, la condición mientras la cual se va a realizar las iteraciones y el como
se va actualizando la variable:

for(inicialización variable;condicion evaluada;actualización


variable){
....
}

Hacer una cuenta regresiva de 10 hasta 1:

In [25]: for(int i = 10; i > 0; i--){


cout << i <<"!"<<endl;
}

10!
9!
8!
7!
6!
5!
4!
3!
2!
1!
Notar que primero se ve la condición antes de realizar un ciclo

In [26]: for(int i = 10; i < 10; i++){


cout << i <<"!"<<endl;
}
cout << "fin..." <<endl;

fin...
En consecuencia, si la condición no se cumple no se actualiza la variable
(dado que esto se realiza una vez finalizado el ciclo)

In [27]: for(int i = 10; i < 10; --i){


cout << i <<"!"<<endl;
}
cout << "fin..." <<endl;

fin...
La actualización de la variable es una instrucción previa a la evaluación del
ciclo siguiente

In [28]: for(int i = 3; i > 0; i--){


cout << i <<"!"<<endl;
}

3!
2!
1!

In [29]: for(int i = 3; i > 0; --i){


cout << i <<"!"<<endl;
}

3!
2!
1!
La variable se puede definir antes, y mantendrá el valor actualizado por el
cilo for una vez finalizado este

In [30]: int i = 8;
for(i = 3; i > 0; --i){
cout << i <<"!"<<endl;
}
cout <<"Final i: "<< i <<"!"<<endl;

3!
2!
1!
Final i: 0!
Pero si se define una variable dentro del ámbito del ciclo for
(independiente del nombre) su valor solo vivirá dentro del ciclo, siendo
independiente a las variable fuera de esta ámbito.

In [32]: int i = 8;
for(int i = 3; i > 0; --i){
cout << i <<"!"<<endl;
}
cout <<"Final i: "<< i <<"!"<<endl;

3!
2!
1!
Final i: 8!

Otros puntos relevantes:


Rompiendo ciclos
Existen otros importantes que ayudan a trabajar con funciones, por ejemplo el
romper el ciclo en caso de ser necesario. Para ello contamos con:

• break : Termina la iteración desde donde se ha utilizado la sentencia (o el


más cercano).
• continue : Termina el ciclo para pasar al siguiente.
• return : Termina la ejecución de una función (ya lo veremos)
independiente del ciclo donde nos encontremos

In [3]: int x = 3;
while(x > 0){
for(int i=1;i<5;i++){
cout<<"("<< x << "," << i << ")" << ": " << i << " - ";
}
x--;
}

(3,1): 1 - (3,2): 2 - (3,3): 3 - (3,4): 4 - (2,1): 1 - (2,2): 2 -


(2,3): 3 - (2,4): 4 - (1,1): 1 - (1,2): 2 - (1,3): 3 - (1,4): 4 -
Identificando los valores pares, podríamos saltarnos al siguiente ciclo(solo
imprimir las i impares)

In [4]: int x = 3;
while(x > 0){
for(int i=1;i<5;i++){
if(i%2 == 0)
continue;
cout<<"("<< x << "," << i << ")" << ": " << i << " - ";
}
x--;
}
(3,1): 1 - (3,3): 3 - (2,1): 1 - (2,3): 3 - (1,1): 1 - (1,3): 3 -
Terminar el ciclo for al encontrar la primera i impar:

In [5]: int x = 3;
while(x > 0){
for(int i=1;i<5;i++){
if(i%2 == 0)
break;
cout<<"("<< x << "," << i << ")" << ": " << i << " - ";
}
x--;
}

(3,1): 1 - (2,1): 1 - (1,1): 1 -

Valores de entrada
Una forma de obtener valores de entrada es mediante el uso de cin para ello se
debe:

#include <iostream>
using namespace std;

...

cin >> variable_a_almacenar_valor


O en caso de no usar el namespace:

#include <iostream>

...

std::cin >> variable_a_almacenar_valor

In [6]: int x = 0;
cin >> x;

En caso de errores
Se pueden utilizar sentencias try - catch
In [7]: #include <iostream>
#include <string>
using namespace std;

string s = "Hola";

También podría gustarte