C & C++/디딤돌 C언어

Part 13. 제어문 II (반복문, 별출력)

언휴 2024. 1. 9. 09:28

 

C언어 - 반복문, 별출력
00:20 반복문
01:14 [실습] while문 1에서 100까지 합계 구하기
02:30 [실습] do while문 1에서 100까지 합계 구하기
03:11 [실습] do while문 음수 입력 전까지 합계 구하기
04:34 [실습] for문 1에서 100까지 합계 구하기
05:43 별출력
05:51 [실습] 별출력 - 속이 빈 정사각형 출력

 41. 반복문 (while, do while, for)

반복문은 특정 조건이 참일 동안 반복해서 구문을 수행하는 구문이예요.
C언어에서는 세 가지 종류의 반복문을 제공합니다.

while(조건 표현식) 반복 수행 구문;
do 반복 수행 구문 while(조건 표현식);
for(초기 수행문; 조건 표현문; 조건 변화 구문) 반복 수행 구문;

반복문에서도 조건문처럼 반복해서 수행할 구문이 하나 이상일 때 블록을 지정해서 사용해요.  

while(조건 표현식) 반복 수행 구문;

◈ while문을 이용하여 1부터 100까지 합계를 구하는 예

#include <stdio.h>
int main()
{
    int sum = 0; //합계를 위한 변수 선언
    int lcnt=0;   //반복문 루프 카운터 변수 선언
    lcnt = 1; //lcnt를 1로 대입
    while(lcnt<=100) //루프 카운터가 100보다 작다면
    {
        sum += lcnt; //sum에 현재 sum과 lcnt 더한 값을 대입
        lcnt++; //lcnt 증가
    }
    printf(“1부터 100까지 합은 %d입니다.\n”,sum);
    return 0;
}


◈ 실행 결과
1부터 100까지 합은 5050입니다.

do 반복 수행 구문; while(조건 표현식);

while문은 조건 표현식을 먼저 표현하고 반복 수행할 구문을 작성했어요.
 처음부터 조건 표현식의 결과가 거짓이면 한 번도 수행하지 않을 수 있죠.

반면 do while문은 반복 수행할 구문을 먼저 작성하고 조건 표현식을 작성해요.
do while문은 반복 수행 구문을 최소한 한 번은 수행해요.

최종 사용자로부터 반복해서 정수를 입력 받고 음수를 입력하면 반복문을 마치고 합계를 출력하는 코드를 생각해봐요.
이 때 최종 사용자에게 입력 받는 부분은 최소한 한 번은 수행해야겠죠.
while문을 이용해서 구현할 수도 있지만 do while문을 이용해서 구현할 수도 있어요.

◈ do while 문을 사용하는 예

#include <stdio.h>
int main()
{
    int sum = 0; //합계를 위한 변수 선언
    int num = 0;
    do
    {
        sum += num; //sum에 현재 sum과 lcnt 더한 값을 대입
        printf(“정수를 입력하세요. [음수 입력하면 종료]\n”);
        scanf_s(“%d”, &num);  
    }while(num>=0); //입력한 정수(num)가 0보다 크거나 같다면
    printf(“입력한 수의 합은 %d 입니다.\n”, sum);
    return 0;
}
for(초기 수행문; 조건 표현문; 조건 변화 구문) 반복 수행 구문

for문은 다른 반복문과 다르게 초기에 한 번 수행하는 초기 수행문과 조건 변화 구문을 표현하는 부분이 있어요.
대부분의 반복하는 작업은 초기화 작업과 조건을 변화시키는 구문이 필요할 때가 많아요.
이러한 이유로 for문을 사용하면 효과적으로 반복 작업을 표현할 수 있어요.  

for 문을 사용할 때 주의할 점은 조건 변화 구문을 실행한 후에 반복 수행 구문을 실행하는 것이 아니라는 것이예요.
반복 수행 구문을 실행한 후에 조건 변화 구문을 실행하는 것을 잊지 마세요.

또한 for 문에 조건 표현은 구문으로 작성하는 것이라 표현식이 없는 널 구문(구문의 내용없이 ;만 표현한 구문) 을 사용할 수 있고 널 구문은 참으로 판별해요.

◈ for 문을 이용하여 1부터 100까지의 합을 계산하는 예

#include <stdio.h>
int main()
{
    int sum = 0; //합계를 위한 변수 선언
    int lcnt=0;   //반복문 루프 카운터 변수 선언

    for(lcnt = 1; lcnt<=100 ; lcnt++ ) //1로 초기화; lcnt가 100보다 작다면; lcnt 1 증가
    {
        sum += lcnt; //sum에 현재 sum과 lcnt 더한 값을 대입
    }
    printf(“1부터 100까지 합은 %d입니다.\n”,sum);
    return 0;
}

이러한 제어문의 문법은 머리로 이해하는 것은 크게 어렵지 않아요.
하지만 반복문으로 문제를 해결하는 코드를 작성하는 것은 단순히 문법을 익힌다고 되는 것은 아니예요.
다양한 문제를 해결하는 과정에서 경험적 노하우를 키워야 프로그램에서 제어문을 사용할 수 있어요.

프로그래밍 언어 학습 후에 자료구조와 알고리즘을 익혀 다양한 문제를 해결방법을 익히고 경험을 쌓길 바래요.

이 책에서는 다양한 자료구조와 알고리즘을 소개하고 않아요.
여러분은 자료구조와 알고리즘 등의 학습으로 효과적인 문제 해결 능력을 키우세요.

 ◈ 기본 연습 
1. 두 수를 입력받은 후 작은 수~큰 수 사이의 모든 수의 합을 구하는 프로그램을 작성하시오.

더보기
//두 수를 입력받은 후 작은 수~큰 수 사이의 모든 수의 합을 구하는 프로그램
#include <stdio.h>
int main(void)
{
    int a, b;
    int sum;
    printf("두 개의 정수 입력:");
    scanf_s("%d%d", &a, &b);
    if (a > b)//a가 b보다 크면
    {
        //두 수를 교환
        int temp = a;
        a = b;
        b = temp;
    }
 
    printf("%d ~ %d =", a, b);
    for (sum = 0; a <= b; a++)
    {
        sum += a;
    }
    printf("%d\n", sum);
    
 
    return 0;
}


2. 1부터 100 사이에 있는 모든 6의 배수를 출력하는 프로그램을 작성하시오.

더보기
//1부터 100 사이에 있는 모든 6의 배수를 출력하는 프로그램
#include <stdio.h>
int main(void)
{
    int n;
    for (n = 1; n <= 100; n++)
    {
        if (n % 6 == 0)//6으로 나누어서 나머지가 없으면
        {
            printf("%d ", n);
        }
    }
    printf("\n");
 
    return 0;
}


3. 한 자리의 정수를 입력받아 입력받은 수의 단을 출력하는 프로그램을 작성하시오.
예:
한 자리의 정수를 입력하시오.
7
7*1 = 7   7*2 = 14   7*3 = 21
7*4 = 28 7*5 = 35   7*6 = 42
7*7 = 49 7*8 = 56   7*9 = 63

더보기
//3. 한 자리의 정수를 입력받아 입력받은 수의 단을 출력하는 프로그램
//예:
//한 자리의 정수를 입력하시오.
//7
//7 * 1 = 7   7 * 2 = 14   7 * 3 = 21
//7 * 4 = 28 7 * 5 = 35   7 * 6 = 42
//7 * 7 = 49 7 * 8 = 56   7 * 9 = 63
#include <stdio.h>
int main(void)
{
    int n;
    int i;
    printf("한 자리의 정수를 입력하세요.\n");
    scanf_s("%d", &n);
    if ((n <= 0) || (n> = 10))
    {
        printf("잘못 입력하였습니다.");
    }
    else
    {
        for (i = 1; i <= 9; i++)
        {
            printf("%d*%d= %2d ", n, i, n*i);
            if (i % 3 == 0)
            {
                putchar('\n');
            }
        }
    }
    return 0;
}



4. 다음을 반복하는 프로그램을 작성하시오.
“I: 추가 D: 삭제 S:검색 L:전체 출력 E:종료”를 화면에 출력
하나의 문자를 입력받음
입력받은 문자가 ‘i’ 혹은 ‘I’일 때는 추가, ‘d’ 혹은 ‘D’일 때는 삭제 , ‘s’ 혹은 ‘S’일 때는 검색, ‘l’, ‘L’일 때는 전체 출력이라고 화면에 출력

(단, E를 누르면 프로그램을 종료)

더보기
//다음을 반복하는 프로그램
//하나의 문자를 입력받아 ‘i’ 혹은 ‘I’일 때는 추가, ‘d’ 혹은 ‘D’일 때는 삭제,
//‘s’ 혹은 ‘S’일 때는 검색, ‘l’, ‘L’일 때는 전체 출력이라고 화면에 출력
//단, E를 누르면 프로그램 종료
#include <stdio.h>
int main(void)
{
    char key='\0';
    while (key!='E')
    {
        printf("I:추가 D:삭제 S:검색 L:전체 출력\n");
        printf("메뉴 선택:");
        scanf_s(" %c", &key, 1); //엔터를 스킵하기 위해 앞에 공백을 포함
        switch (key)
        {
        case 'i': case 'I': printf("추가\n"); break;
        case 'd': case 'D': printf("삭제\n"); break;
        case 's': case 'S': printf("검색\n"); break;
        case 'l': case 'L': printf("전체 출력\n"); break;
        case 'E': break;
        default: printf("잘못 선택하셨네요.\n");  break;
        }
        
    }
    return 0;
}

5. 두 개의 양의 정수를 입력받아 공약수의 합을 계산하는 프로그램을작성하시오.

더보기
//두 개의 정수를 입력받아 공약수의 합을 계산
#include <stdio.h>
int main(void)
{
    int a, b;
    int n;
    int sum=0;
    printf("두 개의 정수 입력:");
    scanf_s("%d%d", &a, &b);
 
    if (a > b)//a가 b보다 크면
    {
        //두 수를 교환
        int temp = a;
        a = b;
        b = temp;
    }
    printf("%d와 %d의 공약수:",a,b);
    for (n = 1; n <= a; n++)
    {
        if ((a%n == 0) && (b%n == 0))//n이 a와 b의 약수일 때
        {
            sum += n;
            printf("%d ", n);
        }
    }
    
    printf("\n%d와 %d의 공약수의 합:%d\n",a,b, sum);
 
    return 0;
}



6. 두 개의 양의 정수를 입력받아 공배수를 작은 순서부터 차례대로 10개를 출력하는 프로그램을 작성하시오.

더보기
//두 개의 정수를 입력받아 공약수 10개를 차례대로 출력
#include <stdio.h>
int main(void)
{
    int a, b;
    int n;
    int count = 0;
    printf("두 개의 정수 입력:");
    scanf_s("%d%d", &a, &b);
 
    if (a > b)//a가 b보다 크면
    {
        //두 수를 교환
        int temp = a;
        a = b;
        b = a;
    }
    printf("%d와 %d의 공약수를 차례대로 (최대)10개 출력\n", a, b);
    for (n = 1; (n <= a)&&(count<10); n++)
    {
        if ((a%n == 0) && (b%n == 0))//n이 a와 b의 약수일 때
        {
            count++;
            printf("%d ", n);
        }
    }
    printf("\n");
    
 
    return 0;
}



7. ‘a’문자에서 ‘z’문자 사이의 모든 문자와 아스키 코드 값을 출력하는 프로그램을 작성하시오.

더보기
//소문자의 아스키 코드값을 출력
#include <stdio.h>
int main(void)
{
    char ch;
    for (ch = 'a'; ch <= 'z'; ch++)
    {
        printf("%c:%d\n", ch, ch);
        
    }
    return 0;
}

42. 제어문 연습 – 별출력

제어문의 문법을 보면 어렵지 않아요.
그런데 실제 프로그래밍에서 사용하려면 논리를 전개해는 것이 어려워요.
다양한 문제를 해결하면서 조금씩 숙련시킬 수 있어요.

간단한 제어문 연습을 해 봐요.

먼저 속이 빈 정사각형을 출력하는 것을 해 봐요.

C언어 - 별출력 - 사각형
C언어 - 별출력 - 사각형

최종 사용자가 정수를 입력하면 입력한 정수에 맞게 속이 빈 정사각형을 출력하는 거예요.
물론 화면의 X좌표의 폭과 Y좌표의 폭이 서로 달라 정사각형처럼 보이지는 않아요.

논리를 먼저 생각하세요.
정수를 입력받는 것이 제일 먼제 해야 할 일겠죠.

scanf_s("%d",&n);//입력

그리고 입력한 정수만큼 정사각형을 출력해야 되겠죠.

따라서 입력한 정수만큼 반복 수행하는 구문이 필요하겠네요.

for(line=1;line<=n;line++)//line: 1~n
{
    //line에서 해야 할 일
}

맨 위줄과 아래 줄은 같은 일을 수행하고 나머지 줄도 같은 일을 수행하겠네요.

for(line=1;line<=n;line++)//line: 1~n
{
    if((line==1)||(line==n))//line is 1 or n
    {
        //line에서 해야 할 일
    }
    else//거짓
    {
    }
}

그리고 맨 위줄과 맨 아래 줄은 별을 입력한 정수만큼 출력해요.
이 때 출력할 별의 수는 입력한 정수만큼이예요.
따라서 입력한 정수만큼 별을 출력하는 반복문이 필요해요.

for(star=1; star<=n;star++)
{
    putchar('*');
}

나머지 줄은 맨 앞에 별을 출력하고 입력한 정수 -2 만큼의 공백을 출력하고 다시 별을 출력해야겠죠.

물론 줄을 구분하기 위한 개행문자도 출력해야겠죠.

putchar('*');//별1
for(space=2;space<n;space++)//공백 2 ~ n-1 
{
    putchar(' ');
}
putchar('*');//별1

이처럼 해야 할 일이 무엇인지 파악하는 과정이 필요해요.

//속이 빈 정사각형
// 입력
// 5
//출력
// *****       1 별5, 개행
// *      *        2 별1, 공백3, 별1, 개행
// *      *        3 별1, 공백3, 별1, 개행
// *      *        4 별1, 공백3, 별1, 개행
// *****       5 별5, 개행

//line: 1~n
    //line is 1 or n 가 참
        //별 n
    //line is 1 or n 가 거짓
        //별1, 공백(n-2), 별1
    //개행

#include <stdio.h> 
int main(void)
{
    int n;
    int line,space,star;   

    scanf_s("%d",&n);//입력
    for(line=1;line<=n;line++)//line: 1~n
    {
        if((line==1)||(line==n))//line is 1 or n 가 참
        {
            for(star=1; star<=n;star++)
            {
                putchar('*');
            }         
        }
        else//line is 1 or n 가 거짓
        {
            putchar('*');//별1
            for(space=2;space<n;space++)//공백 2 ~ n-1
            {
                putchar(' ');
            }
            putchar('*');//별1            
        }   
        putchar('\n');//개행
    }
    return 0;
}

다음의 기본 연습을 직접 해 보세요.
생각보다 많은 시간이 걸릴 수도 있어요.
바로 개발 도구에 코딩을 하는 것보다 전체적인 논리를 종이게 기술하는 등의 작업을 먼저 해 보세요.
그리고 논리를 파악한 후에 구현하는 것이 비용을 줄일 수도 있어요.

◈ 기본 연습
1. 다음처럼 입력한 정수 높이의 삼각형을 출력하는 프로그램을 작성하시오.

C언어 - 별출력 (삼각형)
C언어 - 별출력 (삼각형)

더보기
//삼각형 출력
//입력
// 5                - n
//출력
//     *             1- 공백 4, 별1, 개행
//    ***           2- 공백 3, 별3, 개행 
//   *****          3- 공백2, 별5, 개행
//  *******        4- 공백1, 별7, 개행 
// *********       5- 공백0, 별9, 개행
 
//공백 = n-line
//별 = 2*line -1
//개행=1
 
#include <stdio.h>
 
int main(void)
{
    int n;
    int line,space,star;
    
    scanf_s("%d",&n);//입력
    for(line=1;line<=n;line++)//n개 라인
    {
        for(space=1;space<=(n-line);space++)//공백 n-line개
        {
            putchar(' ');
        }
        for(star =1; star<=(2*line -1); star++)//별 2*line -1개
        {
            putchar('*');
        }
        putchar('\n');//개행
    }
    return 0;
}

2. 다음처럼 입력한 정수의 높이에 맞게 다이아몬드를 출력하는 프로그램을 작성하시오.

C언어 - 별출력 (다이아몬드)
C언어 - 별출력 (다이아몬드)

더보기
// 다이아몬드 출력
// 입력
// 5                - n
//출력
//     *             1- 공백 4, 별1, 개행
//    ***           2- 공백 3, 별3, 개행 
//   *****         3- 공백2, 별5, 개행
//  *******        4- 공백1, 별7, 개행 
// *********      5- 공백0, 별9, 개행
//  *******        4- 공백1, 별7, 개행 
//   *****         3- 공백2, 별5, 개행
//    ***           2- 공백 3, 별3, 개행
//     *            1- 공백 4, 별1, 개행
 
//line:1~n
    //공백 = n-line
    //별 = 2*line -1
    //개행=1
//line:n-1 ~ 1
    //공백 = n-line
    //별 = 2*line -1
    //개행=1 
#include <stdio.h>
 
int main(void)
{
    int n;
    int line,space,star;
    
    scanf_s("%d",&n);//입력
    for(line=1;line<=n;line++)//line: 1~n
    {
        for(space=1;space<=(n-line);space++)//공백 n-line개
        {
            putchar(' ');
        }
        for(star =1; star<=(2*line -1); star++)//별 2*line -1개
        {
            putchar('*');
        }
        putchar('\n');//개행
    }
    for(line=n-1; line>=1;line--)//line:n-1 ~ 1
    {
        for(space=1;space<=(n-line);space++)//공백 n-line개
        {
            putchar(' ');
        }
        for(star =1; star<=(2*line -1); star++)//별 2*line -1개
        {
            putchar('*');
        }
        putchar('\n');//개행
    }
    return 0;
}

3. 다음처럼 입력한 정수의 높이에 맞게 산봉우리를 출력하는 프로그램을 작성하시오.

C언어 - 별출력 (산)
C언어 - 별출력 (산)

더보기
//산봉우리 출력
//입력
//5                - n
//출력
//                    *                                      1                        공백(9+9),별1, 개행
//                   ***                                    2                        공백(9+8), 별3, 개행
//                  *****                                   3                        공백(9+7),별5, 개행
//                 *******                                 4                         공백(9+6), 별7, 개행
//                *********                                5                         공백(9+5), 별9, 개행
//     *         ***********          *                   6  공백4, 별1, 공백4, 공백4, 별11, 공백4, 공백4, 별1, 개행
//    ***      *************        ***                  7  공백3, 별3, 공백3, 공백3, 별13, 공백3, 공백3, 별3, 개행
//   *****    ***************     *****                8  공백2, 별5, 공백2, 공백2, 별15, 공백2, 공백2, 별5, 개행
//  *******  *****************  *******               9  공백1, 별7, 공백1, 공백1, 별17, 공백1, 공백1, 별7, 개행
// *************************************            10   공백0, 별9, 공백0, 공백0, 별19, 공백0, 공백 0, 별9,개행 
//line:1~2*n
//조건(line<=n)이 참일 때
     //공백= (2*n-1)+(2*n-line) = 4*n -1-line
     //별 = 2*line-1
     //개행
//조건(line<=n)이 거짓일 때
     //공백 = 2*n-line
     //별 = 2*(line-n)-1
     //공백 = 2*(2*n-line)     
     //별 = 2*line-1
     //공백 = 2*(2*n-line)
     //별 = 2*(line-n)-1
     //개행 
#include <stdio.h> 
int main(void)
{
    int n;
    int line,space,star;
    
    scanf_s("%d",&n);//입력
    for(line=1;line<=2*n;line++)//line: 1~2n
    {
        if(line<=n)//line is 1~n
        {
              for(space=1;space<=(4*n - 1 - line);space++)//공백 4*n - 1 - line개
              {
                  putchar(' ');
              }
              for(star =1; star<=(2*line -1); star++)//별 2*line -1개
              {
                  putchar('*');
              }
              putchar('\n');//개행
        }
        else//line is n+1 ~ 2n
        {
              for(space=1;space<=(2*n-line);space++)//공백 2n-line개
              {
                  putchar(' ');
              }
              for(star =1; star<=2*(line-n)-1; star++)//별 2*(line-n)-1개
              {
                  putchar('*');
              }
              for(space=1; space<=(2*(2*n-line));space++)//공백 2*(2*n-line) 개
              {
                  putchar(' ');
              }                  
              for(star =1; star<=(2*line-1); star++)//별 2*line-1개
              {
                  putchar('*');
              }
              for(space=1; space<=(2*(2*n-line));space++)//공백 2*(2*n-line) 개
              {
                  putchar(' ');
              }
              for(star =1; star<=2*(line-n)-1; star++)//별 2*(line-n)-1개
              {
                  putchar('*');
              }
              putchar('\n');//개행
        }
      
    }
    return 0;
}