본문 바로가기
Programming/컴퓨터프로그래밍및실습

[컴프실] 제7장: 반복문

by Lizardee 2023. 7. 11.
반복 구조

: 어떤 조건이 만족될 때까지 루프를 도는 구조

 

 

반복문의 종류
  • while 루프
  • for 루프

 

 

while 문

: 주어진 조건이 만족되는 동안 문장들을 반복 실행한다.

//while문
#include <stdio.h>

int main(void)
{
	int i = 0; //초기화
	
	while (i < 5) { //반복 조건
		printf("Hello World!\n"); 
		i++; //반복 내용
	}
	return 0;
}

 

//while문을 이용한 구구단 출력 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int n = 0;
	int i = 1;

	printf("출력하고 싶은 단을 입력하세요: ");
	scanf("%d", &n);

	while (i <= 9) {
		printf("%d*i = %d\n", n, n * i);
		i++;
	}
	
	return 0;
}

 

//while문을 이용한 제곱값 출력 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int n=0;
	
	printf("===================\n");
	printf("n n의 제곱");
	printf("===================\n");

	while (n <= 10) {
		printf("%d %d\n", n, n * n);
		n++;
	}

	return 0;
}

 

//1부터 n까지의 합 계산하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int n; //입력받는 정수
	int i = 1; //i는 1로 초기화

	printf("정수를 입력하시오: ");
	scanf("%d", &n);

	int sum = 0; //초기화
	while (i <= n) {
		sum += i; //sum == sum + i
		i++;
	}

	printf("1부터 %d까지의 합은 %d입니다.\n", n, sum);

	return 0;
}

 

//n 이하의 짝수 합을 구하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int n;
	printf("정수를 입력하시오: ");
	scanf("%d", &n);

	int sum = 0;
	int i = 1;

	while (i <= n) {
		if (i % 2 == 0) {
			sum += i;
		}
		i++;
	}
	printf("1부터 %d까지의 짝수합은 %d입니다.\n", n, sum);

	return 0;
}

 

//합계 출력하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int n;
	int i = 0;
	int sum = 0;
	while (i < 5) {
		printf("값을 입력하시오: ");
		scanf("%d", &n);
		sum += n;
		i++; //i++는 맨 마지막에
	}
	printf("합계는 %d입니다.\n", sum);
	return 0;
}

 

//참과 거짓
#include <stdio.h>

int main(void)
{
	int i = 3;
	while (i) { // i < 0
		printf("%d은 참입니다.\n", i);
		i--;
	}
	printf("%d은 거짓입니다.\n", i);
	
	return 0;
}

 

//팩토리얼 계산하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int n;
	printf("정수를 입력하시오: ");
	scanf("%d", &n);

	int i = 1;
	int Fac = 1;

	while (i <= n) {
		Fac *= i;
		i++; //i++;
	}

	printf("%d!은 %d입니다.\n", n, Fac);

	return 0;
}

 

 

센티널(보초값의 이용)
  • 센티널: 입력되는 데이터의 끝을 알리는 특수한 값
//성적의 평균을 계산하는 문제
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int score = 0;
	printf("종료하려면 음수를 입력하시오.\n");
	int i = 0; //0으로 초기화
	int sum = 0;
	while (score >=0 ) {
		printf("성적을 입력하시오: ");
		scanf("%d", &score);
		sum += score;
		i++;
	}
	sum = sum - score; //마지막 데이터를 제거한다.
	printf("성적의 평균은 %f입니다.\n", (double)sum / (i-1));

	return 0;
}

 

Lab: 최대공약수 찾기
//최대 공약수 찾기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
	int a, b;
	int r;
	printf("두 개의 정수를 입력하시오(큰수, 작은수): ");
	scanf("%d%d", &a, &b);

	while (a != 0) {
		r = a % b;
		a = b;
		b = r;
	}
	printf("최대 공약수는 %d입니다.\n", a);

	return 0;
}
  • 유클리드 알고리즘

주어진 코드는 유클리드 호제법(Euclidean algorithm)을 사용하여 두 수의 최대 공약수(Greatest Common Divisor, GCD)를 찾는 알고리즘입니다. 아래는 해당 부분의 알고리즘에 대한 자세한 설명입니다:

  1. while 루프를 사용하여 a가 0이 아닐 때까지 반복합니다. 초기에 a와 b는 사용자로부터 입력받은 두 수입니다.
  2. 루프 내에서 a를 b로 나눈 나머지를 구합니다. 이를 r에 저장합니다. (r = a % b)
  3. 다음으로 a에는 b의 값을 대입합니다. 이렇게 하면 a에는 이전 단계에서 구한 나머지인 r이 저장됩니다. (a = b)
  4. b에는 r의 값을 대입합니다. 이렇게 하면 b에는 이전 단계에서의 a를 b로 나눈 나머지인 r이 저장됩니다. (b = r)
  5. 이후 다시 루프의 처음으로 돌아가고, a가 0이 아닌 경우 위 과정을 반복합니다.
  6. a가 0이 되면 루프를 빠져나와서 a에는 최대 공약수가 저장됩니다. 이는 b가 0이 되는 시점에서의 a의 값과 동일합니다.
  7. 최대 공약수인 a를 출력합니다.

이 알고리즘의 핵심은 두 수를 반복적으로 나누어가며, 나머지를 구하고 이를 이용하여 다음 연산을 수행하는 것입니다. 두 수의 최대 공약수는 나머지가 0이 될 때의 나누는 수(나눗셈의 피제수)로 결정되므로, 이 과정을 반복하면서 최대 공약수를 구할 수 있습니다.

 

Lab: 반감기
// 반감기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
    int halflife; // 반감기를 저장할 변수
    printf("반감기를 입력하시오(년): ");
    scanf("%d", &halflife);

    double initial; // 초기 양
    double current; // 현재 양
    int years = 0; // 경과한 시간(년)

    initial = 100.0; // 초기 양을 100으로 설정
    current = initial; // 현재 양을 초기 양으로 설정

    // 현재 양이 초기 양의 1/10보다 클 때까지 반복
    while (current > initial / 10.0) {
        years += halflife; // 경과한 시간에 반감기를 더함
        current = current / 2.0; // 현재 양을 절반으로 감소시킴
        printf("%d년 후에 남은 양 = %f\n", years, current);
    }

    printf("1/10 이하로 되기까지 걸린 시간 = %d년", years);

    return 0;
}

이 코드는 반감기를 통해 시간이 경과함에 따라 어떤 양이 얼마나 줄어들게 되는지를 계산하는 프로그램입니다. 반감기는 주어진 물질의 양이 절반으로 줄어드는 시간을 의미합니다. 코드의 동작과정은 다음과 같습니다:

  1. 사용자로부터 반감기를 입력받습니다. 반감기는 양의 단위로 표현되는 시간입니다. (예: 년, 일 등)
  2. 초기 양과 현재 양을 저장할 변수를 선언합니다. 초기 양은 100으로 설정하고, 현재 양은 초기 양과 동일하게 설정합니다.
  3. 경과한 시간을 나타내는 변수인 years를 0으로 초기화합니다.
  4. while 루프를 사용하여 현재 양이 초기 양의 1/10보다 클 때까지 반복합니다.
  5. 루프 내에서 경과한 시간에 반감기를 더합니다.
  6. 현재 양을 절반으로 감소시킵니다.
  7. 각 루프 반복에서 현재 양을 출력합니다.
  8. 1/10 이하로 되기까지 걸린 시간을 출력합니다.

반감기 개념은 특정 물질이 어떤 활동이나 붕괴 등을 통해 점차적으로 양이 줄어드는 현상을 설명하기 위해 사용됩니다. 이 코드에서는 초기 양을 100으로 설정하고, 현재 양은 초기 양의 절반으로 계속 감소시킵니다. 반감기마다 현재 양이 절반으로 줄어들게 되며, 현재 양이 초기 양의 1/10보다 작아지면 루프가 종료됩니다. 종료 시점에서의 경과한 시간을 출력하여 1/10 이하로 되기까지 걸린 시간을 알 수 있습니다.

 

Lab: 복리의 무서움
//복리의 무서움
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	double money = 1;
	int i = 1;

	for (i = 1; i < 30; i++) {
		money = money * 2;
		printf("%d일날 현재 금액 = %f\n", i+1, money);
	}

	if (money <= 100000000)
		printf("1억원을 일시불로 받겠습니다.\n");
	else
		printf("복리로 받겠습니다.\n");
	
	return 0;
}

 

 

do...while 문

: 적어도 한번은 반복문장을 실행한다.

//사용자가 0을 입력할 때까지 입력된 숫자들을 더하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int n;
	int sum = 0;

	do { //do
		printf("정수를 입력하시오: ");
		scanf("%d", &n);
		sum += n;
	} while (n != 0); //n!=0일 때

	printf("숫자들의 합 = %d\n", sum);

	return 0;
}

 

//입력을 처리하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int i;

	do {
		printf("1--새로만들기\n");
		printf("2--파일열기\n");
		printf("3--파일닫기\n");
		printf("하나를 선택하시오: ");
		scanf("%d", &i);
		printf("선택된 메뉴 = %d\n\n", i);
	} while (i >= 1 && i <= 3);

	return 0;
}

 

Lab: 숫자 추측 게임
//프로그램이 가지고 있는 정수를 사용자가  알아맞히는 게임
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //난수발생 함수를 위한 헤더파일

int main(void) {
	int guess;
	int n = 0;
	srand((unsigned)time(NULL)); //난수 발생기 시드 설정
	int answer = rand() % 100; 

	do {
		printf("정답을 추측하시오: ");
		scanf("%d", &guess);
		n++;
		if (guess < answer)
			printf("LOW\n");
		else if (guess > answer)
			printf("HIGH\n");
	} while (guess != answer);

	if (guess == answer)
		printf("축하합니다. 시도 횟수 = %d", n);

	return 0;
}

▶ 난수 발생

  • 헤더파일: #include <stdlib.h>
  • 난수 발생기 시드 설정: srand((unsigned)time(NULL));
  • 난수: int answer = rand()%100;

 

 

for 루프

: 정해진 횟수만큼 반복하는 구조

  • 초기식: 변수값 초기화
  • 조건식
  • 증감식: 한 번의 루프 실행이 끝나면 증감식 실행
//Hello World! 5번 출력하기
#include <stdio.h>

int main(void) {
	int i = 0;
	
	for (i = 0; i < 5; i++) {
		printf("Hello World!\n");
	}
	
	return 0;
}

 

//1부터 10까지의 정수를 더하여 합계를 구하는 프로그램
#include <stdio.h>

int main(void) {
	int i = 1;
	int sum = 0;

	for (i = 1; i <= 10; i++) {
		sum += i;
	}

	printf("1부터 10까지의 정수의 합 = %d\n", sum);

	return 0;
}

 

//1부터 사용자가 입력하는 수까지 정수의 세제곱값 구하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int i = 1;
	int n;

	printf("정수를 입력하시오: ");
	scanf("%d", &n);
	printf("=========================\n");
	printf("   i     i의 세제곱\n");
	printf("=========================\n");

	for (i = 1; i <= n; i++) {
		printf("   %d     %d\n", i, i * i * i);
	}

	return 0;
}

 

//화면에 * 글자를 이용하여 네모 그리기
#include <stdio.h>

int main(void) {
	int i = 1;
	
	printf("************\n");
	for (i = 1; i <= 5; i++) {
		printf("*          *\n");
	}
	printf("************\n");

	return 0;
}

 

//팩토리얼 값 계산하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int n;
	int i = 1;
	int Fac = 1; //곱셈은 1로 초기화

	printf("정수를 입력하시오: ");
	scanf("%d", &n);

	for (i = 1; i <= n; i++) {
		Fac *= i;
	}

	printf("%d!은 %d입니다.\n", n, Fac);

	return 0;
}

 

 

중첩 반복문

: 반복문 안에 다른 반복문이 위치

//* 기호를 사각형 모양으로 출력하는 프로그램
#include <stdio.h>

int main(void) {
	int x = 0; //가로
	int y = 0; //세로

	for (y=0;y<5;y++){
		for (x = 0; x < 10; x++)
			printf("*");
		printf("\n");
	}

	return 0;
}

 

//*로 삼각형 출력하기
#include <stdio.h>

int main(void) {
	int a = 0; //가로
	int b = 0; //세로

	for (b = 0; b < 5; b++) {
		for (a = 0; a <= b; a++) //b와 a의 크기 비교
			printf("*");
		printf("\n");
	}

	return 0;
}

 

Lab: 직각삼각형 찾기
/* 직각삼각형 찾기*/
#include <stdio.h>

int main(void) {
	int a = 1;
	int b = 1;
	int c = 1; //가장 긴 변

	for (a = 1; a < 100; a++) {
		for (b = 1; b < 100; b++) {
			for (c = 1; c < 100; c++) {
				if (a * a + b * b == c * c) {
					printf("%d %d %d\n", a, b, c);
				}
			}
		}
	}

	return 0;
}
/* 직각삼각형 찾기*/
//직각삼각형에서 동일한 것 제외하기
#include <stdio.h>

int main(void) {
	int a = 1;
	int b = 1;
	int c = 1; //가장 긴 변

	for (a = 1; a < 100; a++) {
		for (b = a; b < 100; b++) { //b를 a로 초기화
			for (c = b; c < 100; c++) { //c를 b로 초기화
				if (a * a + b * b == c * c) {
					printf("%d %d %d\n", a, b, c);
				}
			}
		}
	}

	return 0;
}

 

 

무한 루프(infinite loop)

: 조건 제어 루프에서 프로그램이 무한히 반복하는 일

  • 조건 제어 루프에서 가끔은 프로그램이 무한히 반복하는 일이 발생한다. 이것은 무한 루프로 알려져 있다. 무한 반복이 발생하면 프로그램은 빠져 나올 수 없기 때문에 문제가 된다.
  • 하지만 가끔은 무한 반복하여야 하는 프로그램에 대해 의도적으로 무한 루프를 사용한다.
break 문
  • break문은 반복 루프를 빠져 나오는데 사용된다.
/* 100만원으로 재테크를 시작한 사람이 1년에 30%의 수익을 얻는다면
몇 년 만에 원금의 10배가 되는지 계산하는 프로그램 */
#include <stdio.h>

int main(void) {
	double seedMoney = 1000000; //100만원
	double money = seedMoney; //seedMoney로 초기화
	int year = 0;

	while (1) {
		year++;
		money += money * 0.3;
		if (money >= 10*seedMoney)
			break;
	}

	printf("원금의 10배가 되려면 %d년이 필요합니다.\n", year);

	return 0;
}

 

//제곱근을 구하여 출력하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h> //제곱근 함수를 위한 헤더파일

int main(void) {
	double input;
	double answer = 1; //제곱근

	while (1) {
		printf("실수값을 입력하시오: "); 
		scanf("%lf", &input); //while문 안에 있어야 함!
		answer = sqrt(input);
		if (input < 0.0)
			break; //무한루프 탈출
		printf("%f의 제곱근은 %f입니다.\n", input, answer);
	}

	return 0;
}

 

 

goto문이 필요한 유일한 경우
  • 중첩 루프 안에서 어떤 문제가 발생했을 경우, goto를 이용하면 단번에 외부로 빠져나올 수 있다.
  • break를 사용하면, 하나의 루프만을 벗어날 수 있다.

 

 

continue 문
//0부터 10까지 정수 중에서 3의 배수만 제외하고 출력하는 프로그램
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	int i = 0;
	
	for (i = 0; i <= 10; i++) {
		if (i % 3 == 0)
			continue; //그냥 계속 진행한다.
		printf("%d ", i);
	}

	return 0;
}

 

/* 소문자를 대문자로 변환하는 프로그램*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
    char input;

    printf("소문자를 입력하시오: ");

    while (scanf(" %c", &input) == 1) { //반복적으로 입력받음
        if (input < 'a' || input > 'z') {
            break; // a~z 사이의 소문자가 아닌 경우 종료
        }

        printf("변환된 대문자는 %c입니다.\n", input - 32);
        printf("소문자를 입력하시오: ");
    }

    printf("\n");
}

 

Lab: 파이 구하기

 

Lab: 복리 이자 계산
//복리 이자 계산
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void) {
	double Money;
	double rate;
	int year;

	printf("원금: ");
	scanf("%lf", &Money); //&lf
	printf("이율(%%%) : ");
	scanf("%lf", &rate); //&lf
	printf("기간(년): ");
	scanf("%d", &year);
	printf("=======================\n");
	printf("연도 원리금\n");
	printf("=======================\n");

	int i = 1;
	for (i = 1; i <= year; i++) {
		Money = Money + (rate / 100) * Money;
		printf("%d   %lf", i, Money);
		printf("\n");
	}

	return 0;
}

 

Lab: 자동으로 수학문제 생성하기
//난수 발생
#include <stdio.h>
#include <stdlib.h> //난수 발생 헤더파일

int main(void) {
	srand(time(NULL)); //난수 발생
	int i = 0;
	for (i = 0; i < 10; i++)
		printf("%d\n", rand());
}
//자동으로 수학문제 생성하기
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //난수 발생 헤더파일

int main(void) {
	int n;
	printf("몇 개의 수학문제를 생성하시겠습니까? ");
	scanf("%d", &n);

	srand(time((NULL))); //난수 발생
	int i = 0;
	for (i = 0; i < n; i++) {
		int x = rand();
		int y = rand(); //정답 여부를 판단하기 위해
		printf("%d + %d = ", x, y);
		int answer;
		scanf("%d", &answer);
		if (answer == x + y)
			printf("맞았습니다.\n");
		else
			printf("틀렸습니다.\n");
	}

	return 0;
}

 

Lab: 도박사의 확률
//도박사의 확률
#include <stdio.h>
#include <stdlib.h> //난수 발생 헤더파일

int main(void) {
	int initialMoney = 50;
	int goal = 250;
	int i;
	int wins = 0;

	srand((unsigned)time(NULL)); //난수 발생
	for (i = 0; i < 100; i++) { //도박장에 100번 방문
		int cash = initialMoney;
		while (cash > 0 && cash < goal) {
			if ((double)rand() / RAND_MAX < 0.5) //난수 발생
				cash++; //1달러 증가
			else
				cash--; //돈을 잃음
		}
		if (cash == goal)
			wins++; //100번의 방문 중 1번은 성공
	}

	printf("초기 금액 &50\n");
	printf("목표 금액 &250\n");
	printf("100번 중에서 %d번 성공\n", wins); //wins의 횟수는 매번 다름

	return 0;
}