C 언어 조건 루프

CBeginner
지금 연습하기

소개

이 랩에서는 C 프로그래밍에서 조건부 루프를 구현하는 방법을 배우게 됩니다. 먼저 while 루프의 기본 사항을 이해하고, break 및 continue 지시어를 사용하여 루프 실행을 제어하는 방법을 살펴봅니다. 또한, 조건문을 사용하여 배열 요소를 필터링하고 다양한 지시어를 통해 루프 효율성을 최적화하는 방법을 배우게 됩니다. 이 랩을 마치면 조건부 루프와 C 프로그래밍에서의 실용적인 응용 프로그램에 대한 탄탄한 이해를 갖게 될 것입니다.

While 루프 이해하기

이 단계에서는 C 프로그래밍에서 while 루프의 기본 사항을 배우게 됩니다. while 루프는 특정 조건이 참인 동안 코드 블록을 반복할 수 있게 해주는 강력한 제어 구조입니다.

while 루프의 기본 구문을 보여주는 간단한 C 프로그램을 만들어 보겠습니다. VSCode 편집기를 열고 ~/project 디렉토리에 while_loop_example.c라는 새 파일을 만듭니다.

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;
}

코드를 분석해 보겠습니다.

  • int count = 1;은 카운터 변수를 초기화합니다.
  • while (count <= 5)는 count가 5 이하인 동안 계속되는 루프를 생성합니다.
  • printf()는 count의 현재 값을 표시합니다.
  • count++는 각 반복에서 카운터를 증가시킵니다.

프로그램을 컴파일하고 실행합니다.

gcc while_loop_example.c -o while_loop_example
./while_loop_example

예시 출력:

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

다음은 사용자 입력을 사용하는 while 루프를 보여주는 또 다른 예시입니다.

#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;
}

이 예시는 while 루프가 특정 조건 (0 입력) 이 충족될 때까지 계속되는 대화형 입력에 어떻게 사용될 수 있는지를 보여줍니다.

While 루프에서 Break 지시어 적용하기

이 단계에서는 C 프로그래밍에서 특정 조건이 충족될 때 루프를 조기에 종료할 수 있게 해주는 break 지시어에 대해 배우게 됩니다. break 문은 현재 루프를 즉시 종료하고 루프 다음의 다음 문으로 실행을 계속하는 방법을 제공합니다.

break의 사용법을 보여주기 위해 ~/project 디렉토리에 break_loop_example.c라는 새 파일을 만들어 보겠습니다.

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;
}

코드를 분석해 보겠습니다.

  • while (1)은 break 문이 나타날 때까지 계속되는 무한 루프를 생성합니다.
  • 사용자가 10 의 배수를 입력하면 break 문이 즉시 루프를 종료합니다.
  • 숫자가 10 의 배수가 아니면 루프는 입력을 계속 요청합니다.

다음은 break를 더 복잡한 시나리오에서 보여주는 또 다른 예시입니다.

#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;
}

이 예시는 break를 사용하여 다음을 수행하는 방법을 보여줍니다.

  • 특정 조건이 충족되면 입력 수집을 중지합니다.
  • 입력된 숫자의 평균을 계산합니다.
  • 루프 종료 시 유연성을 제공합니다.

break 지시어가 어떻게 작동하는지 확인하려면 프로그램을 컴파일하고 실행하십시오.

gcc break_loop_example.c -o break_loop_example
./break_loop_example

While 루프에서 Continue 지시어 활용하기

이 단계에서는 C 프로그래밍에서 continue 지시어에 대해 배우게 됩니다. continue 지시어는 루프의 현재 반복을 건너뛰고 다음 반복으로 이동할 수 있게 해줍니다. continue 문은 특정 조건에 따라 루프의 일부를 선택적으로 실행하거나 건너뛰는 방법을 제공합니다.

continue의 사용법을 보여주기 위해 ~/project 디렉토리에 continue_loop_example.c라는 새 파일을 만들어 보겠습니다.

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;
}

코드를 분석해 보겠습니다.

  • 프로그램은 사용자에게 10 개의 숫자를 입력하도록 요청합니다.
  • if (number % 2 != 0)은 숫자가 홀수인지 확인합니다.
  • continue는 홀수에 대한 현재 반복의 나머지 부분을 건너뜁니다.
  • 짝수만 합계에 추가되고 계산됩니다.

다음은 더 복잡한 조건에서 continue를 보여주는 또 다른 예시입니다.

#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;
}

이 예시는 continue를 사용하여 다음을 수행하는 방법을 보여줍니다.

  • 특정 값을 건너뜁니다.
  • 조건에 따라 숫자를 선택적으로 처리합니다.
  • 보다 유연한 루프 제어를 제공합니다.

continue 지시어가 어떻게 작동하는지 확인하려면 프로그램을 컴파일하고 실행하십시오.

gcc continue_loop_example.c -o continue_loop_example
./continue_loop_example

조건문을 사용하여 배열 요소 필터링

이 단계에서는 C 프로그래밍에서 조건문과 루프를 사용하여 배열 요소를 필터링하는 방법을 배우게 됩니다. 필터링을 통해 특정 조건을 기반으로 배열에서 특정 요소를 선택할 수 있습니다.

배열 요소 필터링을 보여주기 위해 ~/project 디렉토리에 array_filtering.c라는 새 파일을 만들어 보겠습니다.

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;
}

필터링 프로세스를 분석해 보겠습니다.

  • 입력 저장을 위한 numbers 배열과 필터링된 요소를 저장하기 위한 filtered_even 배열을 만듭니다.
  • 첫 번째 루프는 사용자로부터 10 개의 숫자를 읽습니다.
  • 두 번째 루프는 조건문을 사용하여 짝수를 필터링합니다.
  • if (numbers[i] % 2 == 0)은 숫자가 짝수인지 확인합니다.
  • 일치하는 요소는 filtered_even 배열에 저장됩니다.

다음은 여러 필터링 조건이 있는 더 복잡한 예시입니다.

#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;
}

이 예시는 다음을 보여줍니다.

  • 입력 배열에서 소수를 필터링합니다.
  • 소수성을 확인하기 위한 중첩 루프.
  • 필터링된 요소를 별도의 배열에 저장합니다.

프로그램을 컴파일하고 실행합니다.

gcc array_filtering.c -o array_filtering
./array_filtering

예시 입력 및 출력:

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

지시어를 활용한 루프 효율 최적화

이 단계에서는 다양한 지시어와 전략을 사용하여 C 프로그래밍에서 루프 효율성을 최적화하는 기술을 배우게 됩니다. 루프 성능과 가독성을 향상시키는 다양한 접근 방식을 살펴봅니다.

최적화 기술을 보여주기 위해 ~/project 디렉토리에 loop_optimization.c라는 파일을 만들어 보겠습니다.

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;
}

다음은 여러 최적화 기술을 보여주는 또 다른 예시입니다.

#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;
}

시연된 주요 최적화 기술:

  1. 루프 언롤링 (Loop unrolling) 을 통한 루프 오버헤드 감소
  2. 분기 예측 최소화
  3. 초기화 및 처리 결합
  4. 조건부 합산을 위한 곱셈 사용

최적화 플래그를 사용하여 프로그램을 컴파일하고 실행합니다.

## 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

추가 최적화 팁:

  • -O2 또는 -O3 컴파일러 플래그 사용
  • 루프 내 함수 호출 최소화
  • 적절한 데이터 유형 사용
  • 불필요한 계산 방지
  • 루프 불변 코드 이동 (Loop invariant code motion) 고려

요약

이 랩에서는 C 프로그래밍에서 while 루프의 기본 사항을 배우게 됩니다. 여기에는 루프의 흐름을 제어하기 위해 break 및 continue 지시어를 사용하는 방법이 포함됩니다. 또한 조건문을 사용하여 배열 요소를 필터링하고 다양한 지시어를 사용하여 루프 효율성을 최적화하는 기술도 탐구할 것입니다. 이 랩을 마치면 다양한 프로그래밍 문제를 해결하기 위해 C 에서 조건부 루프를 구현하는 방법에 대한 확실한 이해를 갖게 될 것입니다.