Control de Flujo

Por Ariel Parra

Condicionales

CPC Γα=Ω5

Tablas de verdad para operadores booleanos

NOT ( ! )

p ¬p
F V
V F

AND ( && )

p q p ∧ q
F F F
F V F
V F F
V V V

OR ( || )

p q p ∨ q
F F F
F V V
V F V
V V V
CPC Γα=Ω5

if

  • if single-line
bool programo, estudio = true;
if(programo) cout << "verdadero";
else
    cout << "falso";
  • if tradicional
if( programo == true ) {
    cout << "Aprendo, ";
}else if (programo != true){
    cout << "Procrastino, ";
}
if ( programo && estudio ) {
    cout << "tendre exito en competencias";
} else if ( programo || estudio ) {
    cout << "quiza tenga exito";
} else {
    cout << "pues no tendre exito";
}
CPC Γα=Ω5

Operador Ternario

El operador ternario en C++ es una forma compacta de escribir una declaración if-else que siempre devuelve un valor, dependiendo de una condición. Primero se escribe la condición booleana, seguida del operador ?, que indica el valor que se devolverá si la condición es verdadera. Después del operador :, se coloca el valor que se devolverá si la condición es falsa.

cout << (programo ? "Aprendo, " : "Procrastino, ");
cout << (programo && estudio ? "tendre exito en competencias" : (programo || estudio ? "quiza tenga exito" : "pues no tendre exito"));
CPC Γα=Ω5

Switch-case

Permite evaluar una expresión y ejecutar diferentes bloques de código de manera eficiente, en este caso a es la expresión evaluada y solamente puede ser numerica (int / long long) o un caracter (char).

switch(a) { 
    case 'A': case '1':
        cout << "solo caracteres 'A' y '1'";
        break;
    case 'a' ... 'z': 
        cout << "letras minusculas"; 
        break; 
    case 0 ... 10:
        cout << "numeros del 0 al 10"; 
        break;
    default:
        cout << "lo demas";
} 
CPC Γα=Ω5

Ciclos

CPC Γα=Ω5

for

  • for tradicional
for (size_t i=0; i < n; ++i) {
    cout << n << " ";
}
  • for single-line
for (size_t i=0; i < n; ++i) cout << n << " ";
  • for de rango
for (int numero : numeros) {
    cout << numero << " ";
}
CPC Γα=Ω5

while

  • while
int i = 0;
while (true) {
    cout << i;
    if (i++ > n) break;
}
  • do-while
int i = 0;
cout<<endl;
do {
    cout << ++i;
} while (i < n);
CPC Γα=Ω5

Progresiones

Progresiones aritméticas

Por ejemplo: 5,8,11,14,...

int a = 5, d = 3, n = 10;
for (int i = 0; i < n; ++i) {
    cout << a + i * d << " ";
}

Progresiones geometricas

Por ejemplo: 5,15,45,135,...

int a = 5, r = 3, n = 10;
for (int i = 0; i < n; ++i) {
   cout << a * pow(r, i) << " ";
}
CPC Γα=Ω5

Progresiones aritméticas

  • Fórmula del término n-ésimo:

   int an = a1 + (n - 1) * d;
  • Fórmula de la suma de los primeros n términos:

    int sn = ( n * (2 * a1 + (n - 1) * d) ) /2;
  • o de manera equivalente:

CPC Γα=Ω5

Progresiones geométricas

  • Fórmula del término n-ésimo:

    int an = a1 * pow(r, n - 1);
  • Fórmula de la suma de los primeros n términos:

Para r != 1:

    int Sn = a1 * (pow(r, n) - 1) / (r - 1);
  • Fórmula de la suma de una progresión geométrica infinita (cuando |r| < 1):

CPC Γα=Ω5

Sumatorias (Σ)

La sumatoria (notación sigma: Σ) se usa para sumar una secuencia de términos.

int n = 10, sum = 0;
for (int i = 1; i <= n; ++i) {
    sum += i;
}
CPC Γα=Ω5

Multiplicatorias (Π)

La multiplicatoria o producto (notación pi: Π) se usa para multiplicar una secuencia de términos.

int n = 5, product = 1;
for (int i = 1; i <= n; ++i) {
    product *= i;
}
CPC Γα=Ω5

Condiciones de salto

  • break: Termina el bucle o la declaración switch y transfiere el control a la declaración inmediatamente siguiente.
for (int i = 1; i <= 10; ++i) {
    if (i == 5) break;
    cout << i << " ";
}
  • continue: Omite la iteración actual de un bucle y continúa con la siguiente iteración.
for (int i = 1; i <= 10; ++i) {
    if (i == 5) continue;
    cout << i << " ";
}
CPC Γα=Ω5
  • return: Sale de una función y devuelve un valor al llamador.
int sumar(int a, int b) {
    return a + b;
}
int resultado = sumar(3, 4);
cout << resultado << endl;
  • goto: Transfiere el control a una declaración etiquetada dentro de la misma función. (Nota: puede crear código ilegible y propenso a errores, pero también puede solucionar problemas con la recursión).
int i = 1;
start:
    if (i > 5) goto end;
    cout << i << " ";
    ++i;
    goto start;
end:
CPC Γα=Ω5

Funciones

CPC Γα=Ω5

Nesting

El nesting ocurre cuando anidamos condicionales dentro de otro. Esto lleva a un código difícil de leer.

inline void foo() {
    if (var) {
        if (qux) {
            if (baz) {
                cout << "Todas las condiciones son verdaderas";
            } else {
                cout << "baz es falso";
            }
        } else {
            cout << "qux es falso";
        }
    } else {
        cout << "var es falso";
    }
}

Existen dos métodos para evitar el nesting y ser un never-nester: inversión y extracción.

CPC Γα=Ω5

1.Inversión

Consiste en manejar los casos negativos primero y usar declaraciones return para salir del flujo de control lo antes posible.

inline void foo() {
    if (!var) {
        cout << "var es falso";
        return;
    }
    if (!qux) {
        cout << "qux es falso";
        return;
    }
    if (!baz) {
        cout << "baz es falso";
        return;
    }
    cout << "Todas las condiciones son verdaderas";
}
CPC Γα=Ω5

2.Extracción

Consiste en dividir el código en funciones más pequeñas y específicas para mejorar la legibilidad.

inline void checkBaz() {
    if (!baz) {
        cout << "baz es falso";
        return;
    } cout << "Todas las condiciones son verdaderas";
}
inline void checkQux() {
    if (!qux) {
        cout << "qux es falso";
        return;
    } checkBaz();
}
inline void foo() {
    if (!var) {
        cout << "var es falso";
        return;
    } checkQux();
}
CPC Γα=Ω5

Branching y Branchless

El término branching se refiere a las condicionales, cuando el programa diverge en dos caminos puede llegar a ser lento en ciertos casos debido a que el CPU intenta adelantarse precagargando una de las funciones posibles. La metodologia branchless evita eso, pero puede volver menos legible la funcion.

inline int menorBranch(int a, int b) {
    if (a < b)  
        return a;
    return b;
}
inline int menorBranchLess(int a, int b) {
    return a * (a < b) + b * (b <= a);
}
CPC Γα=Ω5

Lambda λ

Las lambdas o funciones lambda permiten definir funciones anónimas de forma concisa. Son útiles para crear funciones cortas que se utilizan en el contexto de otra función, como en algoritmos STL.

La sintaxis básica de una lambda es:

[capturas](parámetros) -> tipo_retorno {
    // Cuerpo de la función
};

Un ejemplo:

auto suma = [](int a, int b) -> int { return a + b; };
int res = suma(5, 3);
CPC Γα=Ω5

Problemas

CPC Γα=Ω5

Referencias

CPC Γα=Ω5

a_n es el término n-ésimo. a_1 es el primer término. n es el número del término. d es la diferencia común.

a_n es el término n-ésimo. a_1 es el primer término. n es el número del término. r es la razón común.

i=1: Es el índice de la sumatoria. En el código, es la variable de iteración del bucle for. Donde 1 es el valor inicial. n: Es el valor final del índice i. En el código, corresponde a la condición de paro del bucle i <= n. i: Es el término general que se suma. En el código, es lo que se suma a la variable sum en cada iteración sum += i.

i=1: Es el índice de la sumatoria. En el código, es la variable de iteración del bucle for. Donde 1 es el valor inicial. n: Es el valor final del índice i. En el código, corresponde a la condición de paro del bucle i <= n. i: Es el término general que se multiplica. En el código, es lo que se multiplica por la variable product en cada iteración product *= i.

auto nos ahorra escribir: std::function<int(int, int)> suma = [](int a, int b) -> int { return a + b; };