Bucles condicionales en C

CBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderás cómo implementar bucles condicionales en la programación en C. Comenzarás por entender los fundamentos de los bucles while, luego explorarás el uso de las directivas break y continue para controlar la ejecución del bucle. Además, aprenderás cómo filtrar elementos de un array utilizando declaraciones condicionales y optimizar la eficiencia del bucle con diversas directivas. Al final de este laboratorio, tendrás una sólida comprensión de los bucles condicionales y sus aplicaciones prácticas en la programación en C.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 97%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Comprender los bucles while

En este paso, aprenderás los fundamentos de los bucles while en la programación en C. Los bucles while son estructuras de control poderosas que te permiten repetir un bloque de código mientras una condición específica siga siendo verdadera.

Vamos a crear un programa simple en C para demostrar la sintaxis básica de un bucle while. Abre el editor de VSCode y crea un nuevo archivo llamado while_loop_example.c en el directorio ~/project.

cd ~/project
touch while_loop_example.c
#include <stdio.h>

int main() {
    int count = 1;

    while (count <= 5) {
        printf("Current count: %d\n", count);
        count++;
    }

    return 0;
}

Desglosemos el código:

  • int count = 1; inicializa una variable contador
  • while (count <= 5) crea un bucle que continúa mientras count sea menor o igual a 5
  • printf() muestra el valor actual de count
  • count++ incrementa el contador en cada iteración

Compila y ejecuta el programa:

gcc while_loop_example.c -o while_loop_example
./while_loop_example

Ejemplo de salida:

Current count: 1
Current count: 2
Current count: 3
Current count: 4
Current count: 5

Aquí hay otro ejemplo que demuestra un bucle while con entrada del usuario:

#include <stdio.h>

int main() {
    int number;

    printf("Enter numbers (enter 0 to stop):\n");

    number = 1;  // Initialize to non-zero value
    while (number!= 0) {
        printf("Enter a number: ");
        scanf("%d", &number);

        if (number!= 0) {
            printf("You entered: %d\n", number);
        }
    }

    printf("Loop ended. Goodbye!\n");

    return 0;
}

Este ejemplo muestra cómo se pueden utilizar los bucles while para entrada interactiva, continuando hasta que se cumpla una condición específica (ingresar 0).

Aplicar la directiva break en bucles while

En este paso, aprenderás sobre la directiva break en la programación en C, que te permite salir de un bucle prematuramente cuando se cumple una condición específica. La declaración break proporciona una forma de terminar inmediatamente el bucle actual y continuar la ejecución con la siguiente declaración después del bucle.

Vamos a crear un nuevo archivo llamado break_loop_example.c en el directorio ~/project para demostrar el uso de break:

cd ~/project
touch break_loop_example.c
#include <stdio.h>

int main() {
    int number;

    printf("Enter numbers to find the first multiple of 10:\n");

    while (1) {  // Infinite loop
        printf("Enter a number: ");
        scanf("%d", &number);

        if (number % 10 == 0) {
            printf("Found a multiple of 10: %d\n", number);
            break;  // Exit the loop when a multiple of 10 is found
        }

        printf("Not a multiple of 10. Try again.\n");
    }

    printf("Loop terminated after finding a multiple of 10.\n");

    return 0;
}

Desglosemos el código:

  • while (1) crea un bucle infinito que continuará hasta que se encuentre una declaración break
  • Cuando el usuario ingresa un número divisible por 10, la declaración break sale inmediatamente del bucle
  • Si el número no es divisible por 10, el bucle continúa solicitando entrada

Aquí hay otro ejemplo que demuestra break en un escenario más complejo:

#include <stdio.h>

int main() {
    int sum = 0;
    int count = 0;
    int input;

    printf("Enter numbers (enter a negative number to stop):\n");

    while (1) {
        printf("Enter a number: ");
        scanf("%d", &input);

        if (input < 0) {
            break;  // Exit the loop if a negative number is entered
        }

        sum += input;
        count++;
    }

    if (count > 0) {
        printf("Average of entered numbers: %.2f\n", (float)sum / count);
    } else {
        printf("No numbers were entered.\n");
    }

    return 0;
}

Este ejemplo muestra cómo se puede usar break para:

  • Detener la recopilación de entrada cuando se cumple una condición específica
  • Calcular el promedio de los números ingresados
  • Proporcionar flexibilidad en la terminación del bucle

Compila y ejecuta los programas para ver cómo funciona la directiva break:

gcc break_loop_example.c -o break_loop_example
./break_loop_example

Utilizar la directiva continue en bucles while

En este paso, aprenderás sobre la directiva continue en la programación en C, que te permite saltar la iteración actual de un bucle y pasar a la siguiente iteración. La declaración continue proporciona una forma de ejecutar o saltar selectivamente partes de un bucle basadas en condiciones específicas.

Vamos a crear un nuevo archivo llamado continue_loop_example.c en el directorio ~/project para demostrar el uso de continue:

cd ~/project
touch continue_loop_example.c
#include <stdio.h>

int main() {
    int number;
    int sum_even = 0;
    int count_even = 0;

    printf("Enter 10 numbers to calculate the sum and count of even numbers:\n");

    int i = 0;
    while (i < 10) {
        printf("Enter number %d: ", i + 1);
        scanf("%d", &number);

        // Skip odd numbers
        if (number % 2!= 0) {
            printf("Skipping odd number: %d\n", number);
            continue;  // Move to the next iteration
        }

        sum_even += number;
        count_even++;

        i++;
    }

    if (count_even > 0) {
        printf("Sum of even numbers: %d\n", sum_even);
        printf("Count of even numbers: %d\n", count_even);
        printf("Average of even numbers: %.2f\n", (float)sum_even / count_even);
    } else {
        printf("No even numbers were entered.\n");
    }

    return 0;
}

Desglosemos el código:

  • El programa pide al usuario que ingrese 10 números
  • if (number % 2!= 0) comprueba si el número es impar
  • continue salta el resto de la iteración actual para números impares
  • Solo se suman y cuentan los números pares

Aquí hay otro ejemplo que demuestra continue con condiciones más complejas:

#include <stdio.h>

int main() {
    int number;
    int positive_count = 0;
    int negative_count = 0;

    printf("Enter numbers (enter 0 to stop):\n");

    while (1) {
        printf("Enter a number: ");
        scanf("%d", &number);

        // Exit the loop if 0 is entered
        if (number == 0) {
            break;
        }

        // Skip zero
        if (number == 0) {
            continue;
        }

        // Count positive and negative numbers
        if (number > 0) {
            positive_count++;
        } else {
            negative_count++;
        }
    }

    printf("Positive numbers count: %d\n", positive_count);
    printf("Negative numbers count: %d\n", negative_count);

    return 0;
}

Este ejemplo muestra cómo se puede usar continue para:

  • Saltar valores específicos
  • Procesar selectivamente números basados en condiciones
  • Proporcionar un control de bucle más flexible

Compila y ejecuta los programas para ver cómo funciona la directiva continue:

gcc continue_loop_example.c -o continue_loop_example
./continue_loop_example

Filtrar elementos de array con sentencias condicionales

En este paso, aprenderás cómo filtrar elementos de un array utilizando declaraciones condicionales y bucles en la programación en C. El filtrado te permite seleccionar elementos específicos de un array basados en ciertas condiciones.

Vamos a crear un nuevo archivo llamado array_filtering.c en el directorio ~/project para demostrar el filtrado de elementos de un array:

cd ~/project
touch array_filtering.c
#include <stdio.h>

#define MAX_SIZE 10

int main() {
    int numbers[MAX_SIZE];
    int filtered_even[MAX_SIZE];
    int filtered_count = 0;

    // Input array elements
    printf("Enter %d numbers:\n", MAX_SIZE);
    for (int i = 0; i < MAX_SIZE; i++) {
        printf("Enter number %d: ", i + 1);
        scanf("%d", &numbers[i]);
    }

    // Filter even numbers
    printf("\nFiltered Even Numbers:\n");
    for (int i = 0; i < MAX_SIZE; i++) {
        if (numbers[i] % 2 == 0) {
            filtered_even[filtered_count] = numbers[i];
            filtered_count++;
            printf("%d ", numbers[i]);
        }
    }

    printf("\n\nTotal even numbers: %d\n", filtered_count);

    return 0;
}

Desglosemos el proceso de filtrado:

  • Creamos dos arrays: numbers para almacenar la entrada y filtered_even para almacenar los elementos filtrados
  • El primer bucle lee 10 números del usuario
  • El segundo bucle utiliza una declaración condicional para filtrar los números pares
  • if (numbers[i] % 2 == 0) comprueba si un número es par
  • Los elementos que coinciden se almacenan en el array filtered_even

Aquí hay un ejemplo más complejo con múltiples condiciones de filtrado:

#include <stdio.h>

#define MAX_SIZE 10

int main() {
    int numbers[MAX_SIZE];
    int prime_numbers[MAX_SIZE];
    int prime_count = 0;

    // Input array elements
    printf("Enter %d numbers:\n", MAX_SIZE);
    for (int i = 0; i < MAX_SIZE; i++) {
        printf("Enter number %d: ", i + 1);
        scanf("%d", &numbers[i]);
    }

    // Filter prime numbers
    printf("\nFiltered Prime Numbers:\n");
    for (int i = 0; i < MAX_SIZE; i++) {
        // Skip numbers less than 2
        if (numbers[i] < 2) continue;

        int is_prime = 1;
        for (int j = 2; j * j <= numbers[i]; j++) {
            if (numbers[i] % j == 0) {
                is_prime = 0;
                break;
            }
        }

        // Add prime numbers to filtered array
        if (is_prime) {
            prime_numbers[prime_count] = numbers[i];
            prime_count++;
            printf("%d ", numbers[i]);
        }
    }

    printf("\n\nTotal prime numbers: %d\n", prime_count);

    return 0;
}

Este ejemplo demuestra:

  • Filtrar números primos de un array de entrada
  • Bucles anidados para comprobar la primalidad
  • Almacenar los elementos filtrados en un array separado

Compila y ejecuta los programas:

gcc array_filtering.c -o array_filtering
./array_filtering

Ejemplo de entrada y salida:

Enter 10 numbers:
Enter number 1: 5
Enter number 2: 12
Enter number 3: 7
Enter number 4: 15
...

Filtered Prime Numbers:
5 7

Total prime numbers: 2

Optimizar la eficiencia de bucles con directivas

En este paso, aprenderás técnicas para optimizar la eficiencia de los bucles en la programación en C utilizando diversas directivas y estrategias. Exploraremos diferentes enfoques para mejorar el rendimiento y la legibilidad de los bucles.

Vamos a crear un archivo llamado loop_optimization.c en el directorio ~/project para demostrar técnicas de optimización:

cd ~/project
touch loop_optimization.c
#include <stdio.h>
#include <time.h>

#define ARRAY_SIZE 10000

// Function to calculate sum using traditional loop
int traditional_sum(int arr[], int size) {
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum;
}

// Function to calculate sum using optimized loop
int optimized_sum(int arr[], int size) {
    int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;

    // Loop unrolling technique
    int i;
    for (i = 0; i + 4 < size; i += 4) {
        sum1 += arr[i];
        sum2 += arr[i + 1];
        sum3 += arr[i + 2];
        sum4 += arr[i + 3];
    }

    // Handle remaining elements
    for (; i < size; i++) {
        sum1 += arr[i];
    }

    return sum1 + sum2 + sum3 + sum4;
}

int main() {
    int arr[ARRAY_SIZE];
    clock_t start, end;
    double cpu_time_used;

    // Initialize array
    for (int i = 0; i < ARRAY_SIZE; i++) {
        arr[i] = i + 1;
    }

    // Traditional sum
    start = clock();
    int traditional_result = traditional_sum(arr, ARRAY_SIZE);
    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
    printf("Traditional Sum: %d\n", traditional_result);
    printf("Traditional Loop Time: %f seconds\n", cpu_time_used);

    // Optimized sum
    start = clock();
    int optimized_result = optimized_sum(arr, ARRAY_SIZE);
    end = clock();
    cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
    printf("Optimized Sum: %d\n", optimized_result);
    printf("Optimized Loop Time: %f seconds\n", cpu_time_used);

    return 0;
}

A continuación, otro ejemplo que demuestra múltiples técnicas de optimización:

#include <stdio.h>

#define MAX_SIZE 1000

int main() {
    int numbers[MAX_SIZE];
    int even_sum = 0, odd_sum = 0;

    // Efficient initialization and summation
    for (int i = 0; i < MAX_SIZE; i++) {
        numbers[i] = i + 1;

        // Conditional sum with minimal branching
        even_sum += (numbers[i] % 2 == 0) * numbers[i];
        odd_sum += (numbers[i] % 2!= 0) * numbers[i];
    }

    printf("Sum of Even Numbers: %d\n", even_sum);
    printf("Sum of Odd Numbers: %d\n", odd_sum);

    return 0;
}

Técnicas de optimización clave demostradas:

  1. Desenrollado de bucles (loop unrolling) para reducir la sobrecarga del bucle
  2. Minimización de las predicciones de ramificación
  3. Combinación de inicialización y procesamiento
  4. Uso de multiplicación para la suma condicional

Compila y ejecuta los programas con banderas de optimización:

## Compile with basic optimization
gcc -O2 loop_optimization.c -o loop_optimization
./loop_optimization

## Compile with advanced optimization
gcc -O3 loop_optimization.c -o loop_optimization
./loop_optimization

Consejos adicionales de optimización:

  • Utiliza las banderas del compilador -O2 o -O3
  • Minimiza las llamadas a funciones dentro de los bucles
  • Utiliza tipos de datos adecuados
  • Evita cálculos innecesarios
  • Considera el movimiento de código invariante del bucle

Resumen

En este laboratorio, aprenderás los conceptos básicos de los bucles while en la programación en C, incluyendo cómo utilizar las directivas break y continue para controlar el flujo del bucle. También explorarás técnicas para filtrar elementos de un array utilizando declaraciones condicionales y optimizar la eficiencia de los bucles con diversas directivas. Al final de este laboratorio, tendrás una comprensión sólida de cómo implementar bucles condicionales en C para resolver una variedad de problemas de programación.