본문 바로가기
혼공단 12기(혼공C)

[혼공C] 3주차 선택문, 반복문

by 눈 떠 보니 공대생 2024. 7. 20.

주차 진도 기본 숙제 추가 숙제
3주차(7.15~7.21) Chapter 5~6 혼공 용어 노트에 용어 추가 등 노트 활용하고 공유하기 p151 크리스마스 소개팅 예문 if문 손코딩 인증 또는 실행화면 캡처하기

<기본 숙제: 혼공 용어 노트에 용어 추가 등 노트 활용하고 공유하기 >

 

<추가 숙제: p151 크리스마스 소개팅 예문 실행화면 캡처하기 >

[코드]

#include <stdio.h>

int main() {

	char c, love;

	printf("크리스마스가 지났습니까?(Y/N) : ");
	scanf("%c", &c);

	if (c == 'N') {
		printf("연인이 있습니까?(Y/N) : ");
		scanf(" %c", &love);

		if (love == 'N') {
			printf("소개팅을 주선해 주겠습니다.\n");
		}
		else if (love == 'Y') {
			printf("즐거운 크리스마스 되세요~\n");
		}
		else {
			return 0;
		}
	}	

	return 0;
}

+) 2개 이상의 scanf()를 사용할 때, input을 제대로 받지 못하는 경우가 종종 있다. 이럴 때에는 '%' 앞에 스페이스 등을 입력하면 정상적으로 입력을 받을 수 있다.

[실행 결과]


Chapter 3. 변수와 데이터 입력

1. 변수

1) 변수 선언 방법

<자료형> <변수명> <;> e.g.) int a;

변수 선언하면 메모리에 저장 공간 생김 → default value: garbage value

→  initialization 필요; “=” (대입 연산자: 오른쪽 값을 왼쪽 값에 할당) 사용

** 변수 선언과 대입 규칙

규칙 1. {} 안에 변수 선언, 선언 위치부터 블록 끝까지 사용

규칙 2. 변수의 자료형 동일 -> 동시에 둘 이상의 변수 선언 e.g.) int b, c;

규칙 3. 대입 연산자: 연산자 왼쪽 변수에, 오른쪽의 값 할당 e.g.) <변수> = <상수, 변수, 수식>

규칙 4. 변수가 대입 연산자 왼쪽 -> 저장 공간(l-value), 연산자의 오른쪽 -> (r-value)

 

Chapter 5. 선택문

1. if

제어문 선택문 if, switch ~ case
반복문 while, for, do ~ while
분기문 break, continue, goto, return

1) if문의 기본 형식

if(조건식){실행문;}: 조건식을 만족하면 실행문 실행, 그렇지 않으면 실행하지 않고 지나감

** 읽기 쉬운 코드를 위한 규칙

1. if중괄호 사용, 들여쓰기 → 실행문 명확히 구분

2. 실행문은 반드시 중괄호 안에 작성

, 실행문이 1문장인 경우 중괄호 생략 가능

2) if ~ else: 둘 중 하나 반드시 선택하는 경우

if(조건식){실행문1;}else{실행문2;}

** if ~ else문의 규칙

1. else: 조건 X

2. 실행문은 반드시 중괄호 안에 작성

, 실행문이 1문장인 경우 중괄호 생략 가능

3. if 2번보다 if ~ else문 한 번 사용하는 게 좋은 경우도 있음

3) if ~ else if ~ else: 3개 이상의 실행문에서 반드시 하나를 선택하는 경우

**규칙

1. 각 조건에 따른 실행문 2개 이상 → 반드시 중괄호로 묶기

2. 조건식 차례로 검사 → 이전 조건의 결과 반영

2. if문 활용과 switch ~ case

1) if문 중첩

(1) if문 중첩 사용 이유

① 선행 조건 → 불필요한 조건 검사 X

② 실행 효율 향상

<1부터 하나씩 검사>

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int a;
	scanf("%d", &a);

	if (a == 1) {
		printf("일");
	}
	else if (a == 2) {
		printf("이");
	}
	else if (a == 3) {
		printf("삼");
	}
	else if (a == 4) {
		printf("사");
	}
	else if (a == 5) {
		printf("오");
	}
	else
	{
		printf("육");
	}
}

<분할 정복(divide and conquer) 기법: 실행 시간 감소>

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
	int a;
	scanf("%d", &a);

	if (a <= 3) {
		if (a == 1) {
			printf("일");
		}
		else if (a == 2) {
			printf("이");
		}
		else {
			printf("삼");
		}
	}
	else {
		if (a == 4) {
			printf("사");
		}
		else if (a == 5) {
			printf("오");
		}
		else {
			printf("육");
		}
	}
}

2) else 결합 문제: 중첩 if문에서 뒤따르는 else의 위치가 모호해져 발생하는 문제

3) switch ~ case

switch (조건식){

           case 상수식1:

                      실행문1;

                      break;

           case 상수식2:

                      실행문2;

                      break;

           default:

                      실행문3;

                      break;

}

** 규칙

1. 조건식: 정수식 정수형 상수 또는 변수, 수식의 결과값이 정수

2. 기본적으로 case break 포함(switch문 빠져나오는데 이용)

e.g.

#include <stdio.h>

int main() {
	int rank = 2, m = 0;

	switch (rank) { // 조건식 확인 → rank 값 2
		case 1:
			m = 300;
			break;
		case 2: // case 2로 이동
			m = 200; // break 이전까지 실행
			break; // break에 의해 블록 탈출
		case 3:
			m = 100;
			break;
		default:
			m = 10;
			break;
	}

	printf("m : %d\n", m); // m : 200

	return 0;
}

조건식과 일치하는 case의 상수가 없으면 default로 건너뛴다.

case, default는 건너뛸 위치를 표시하는 label 역할

** break 생략

필요에 따라 생략 가능

switch문 탈출하지 않고, 다음 구문 실행

switch (rank) { // 조건식 확인 → rank 값 2
		case 1:
			m = 300;
			break;
		case 2: // case 2로 이동
			m = 200; // m = 200 할당
		case 3: // case 3으로 이동
			m = 100; // m = 100 할당
			break; // switch문 탈출
		default:
			m = 10;
			break;
	}

+) switch ~ case 문을 if 문으로 바꿔 보기

<switch ~ case>

switch (rank) {
		case 1:
			m = 300;
			break;
		case 2: 
			m = 200; 
			break;
		case 3:
			m = 100;
			break;
		default:
			m = 10;
			break;
	}

<if문>

if (rank == 1) {
	m = 300;
}
else if (rank == 2) {
	m = 200;
}
else if (rank == 3) {
	m = 100;
}
else {
	m = 10;
}

Chapter 6. 반복문

1. while, for, do ~ while

1) while

while(조건식){

           실행문

}

(1) 조건식이 참인 동안 실행문 반복

(2) 실행문 수행 후 조건식으로 돌아감

(3) 조건문이 거짓이면 while문 빠져나옴

e.g.

#include <stdio.h>

int main() {
	int a = 1;

	while (a < 10) {
		a *= 2;
	}

	printf("%d\n", a); // 16

	return 0;
}
  while 1 2 3 4 5
a < 10 거짓
while문 빠져나옴
a *= 2 1 * 2 2 * 2 4 * 2 8 * 2  
a 2 4 8 16  

2) for

for(초기식; 조건식; 증감식){

           실행문

}

(1) 실행문을 특정 횟수만큼 반복

(2) 초기식: 최초 1회 실행

(3) 조건식: 참이면 실행문 실행

(4) 실행문 반복 후 증감식으로

(5) 증감식 수행 후 조건 검사

e.g.

#include <stdio.h>

int main() {
	int a = 1;

	for (int i = 0; i < 3; i++) {
		a *= 2;
	}

	printf("%d\n", a); // 16

	return 0;
}
  for 1 2 3 4
i 0 1 2 3
i < 3 거짓
a의 값 1 * 2 2 * 2 4 * 2 8 * 2

cf) for문의 ( ) 내에서 선언한 변수(여기서는 i) ( ) 내에서만 사용할 수 있다.

3) do ~ while

do{

           실행문

} while (조건문)

(1) 반복할 문장 수행

(2) 조건 검사

#include <stdio.h>

int main() {
	int a = 1;

	do {
		a *= 2;
	} while (a < 10);
	printf("%d\n", a); // 16

	return 0;
}

a의 값 = 1, 2, 4, 8일 때 실행문 반복

a의 값이 16이 되면 조건(a < 10) 거짓 → 반복 끝냄

2. 반복문 활용

1) 중첩 반복문: 반복문의 실행문이 반복문인 경우

① 별 5개 그리기
② ①을 3번 반복
[중첩 반복문]
① 별 1개 그리기
② ①을 5번 반복
③ ②를 3번 반복
#include <stdio.h>

int main() {
	int i, j;

	for (i = 0; i < 3; i++) {
		for (j = 0; j < 5; j++) {
			printf("*");
		}
		printf("\n");
	}

	return 0;
}

/*
결과
*****
*****
******
*/

※ 주의: 서로 독립적인 제어 변수 사용하기!

#include <stdio.h>

int main() {
	int i;

	for (i = 0; i < 3; i++) {
		for (i = 0; i < 5; i++) {
			printf("*");
		}
		printf("\n");
	}

	return 0;
}

/*
결과
*****
*/

2번째 for1번 실행, 빠져나온 후 i의 값은 5 1번째 for문의 조건 거짓 → 1번째 for문 빠져나옴

  ( ) 내에서 제어 변수를 선언하면, 해당하는 for문만 제어할 있다. , 혼동을 줄이기 위해 변수명을 달리하면 좋다.

#include <stdio.h>

int main() {

	for (int i = 0; i < 3; i++) {
		for (int i = 0; i < 5; i++) {
			printf("*");
		}
		printf("\n");
	}

	return 0;
}

/*
결과
*****
*****
*****
*/

※ 중첩 반복문으로 구구단을 출력하는 프로그램

#include <stdio.h>

int main() {

	for (int i = 1; i < 10; i++) {
		printf("---%d단---\n", i);
		for (int j = 1; j < 10; j++) {
			printf("%d * %d = %d\n", i, j, i*j);
		}
	}

	return 0;
}

/*
결과
---1단---
1 * 1 = 1
…
1 * 9 = 9
…
---9단---
…
9 * 9 = 81
*/

2) break continue 분기문

(1) break: 반복문 내에서, 반복을 즉시 끝냄

(반복문 블록 내에서, 해당하는 블록을 바로 빠져나옴)

#include <stdio.h>

int main() {

	int i;
	int sum = 0;

	for (i = 1; i < 10; i++) {
		sum += i;
		if (sum > 30) break;
	}
	printf("누적한 값 : %d\n", sum);
	printf("마지막으로 더한 값 : %d\n", i);

	return 0;
}

/*
결과
누적한 값 : 36
마지막으로 더한 값 : 8
*/

switch ~ case문 내에서 break switch ~ case 블록만 벗어남

(2) continue: 다음 실행 위치를 반복문 블록 끝으로 함

#include <stdio.h>

int main() {

	int i;
	int sum = 0;

	for (i = 1; i < 100; i++) {
		if ((i % 4) == 0) {
			continue; // i가 4의 배수면 sum += i 문장을 건너뛰고 for문 반복
		}
		sum += i;
	}

	return 0;
}