[코딩도장] Unit 32 ~ 33
1. goto 사용하기
1. goto 와 레이블 사용하기
goto 는 중간의 코드를 무시하고
원하는 부분으로 건너뛸 수 있는 제어문이다
goto 를 적절히 사용하면 코드를 좀 더 간결하게 할 수 있고
에러처리에 매우 유용하기 때문에 리눅스 커널에서도 자주 사용된다
if (num1 == 1) // num1이 1이면
goto ONE; // 레이블 ONE으로 즉시 이동
else if (num1 == 2) // num1이 2이면
goto TWO; // 레이블 TWO로 즉시 이동
else // 1도 아니고 2도 아니면
goto EXIT; // 레이블 EXIT로 즉시 이동
goto에 레이블을 지정하면 중간의 코드는 건너뛰고 바로 레이블로 이동한다
1을 입력하면 레이블 ONE 으로 이동하고
2를 입력하면 레이블 TWO 로 바로 이동한다
ONE: // 레이블 ONE
printf("1입니다.\n");
goto EXIT; // 레이블 EXIT로 즉시 이동
TWO: // 레이블 TWO
printf("2입니다.\n");
goto EXIT; // 레이블 EXIT로 즉시 이동
EXIT: // 레이블 EXIT
return 0;
위와 같이 레이블을 지정한뒤 실행할 코드를 작성한다
레이블 ONE 으로 이동했다면 아래에 있는 TWO , EXIT 까지 실행되기 때문에
EXIT 으로 바로 이동해 다음 코드가 실행되는 것을 막는다
예시와 같은 코드를 스파게티 코드라고 한다
코드가 간결해서 읽기 쉽지만 코드의 양이 많아지면 읽기가 너무 어려워진다
위의 코드를 if else 로 표현하면
if (num1 == 1) // num1이 1이면
printf("1입니다.\n");
else if (num1 == 2) // num1이 2이면
printf("2입니다.\n");
코드가 매우 간결해진다
이런 경우에는 goto를 사용하지 않는 것이 좋다
goto는 중첩 루프문을 빠져나오는데 효과적이다
break 을 사용하면 현재 루프만 빠져나오기 때문에 추가적인 코드가 더 필요하다
하지만 goto 를 이용하면 간단하게 빠져나올 수 있다
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (num1 == 20) // num1이 20이라면
goto EXIT; // 레이블 EXIT로 즉시 이동
num1++;
}
}
EXIT: // 레이블 EXIT
printf("%d\n", num1); // 20
goto 를 이용하면 중첩 루프문 마다 break 을 사용할 필요가 없어진다
예시는 for 문이지만 while, do while 문도 goto 로 빠져나올 수 있다
goto 는 에러상황에 실행해야 하는 중복코드를 하나로 모을 수 있다
if (gender == 2) // 여자라면
{
printf("안녕히계세요.\n"); // 중복 코드
printf("문을 닫는다.\n"); // 중복 코드
return 0; // 프로그램 종료
}
if (age < 30) // 30세 미만이라면
{
printf("안녕히계세요.\n"); // 중복 코드
printf("문을 닫는다.\n"); // 중복 코드
return 0; // 프로그램 종료
}
if (isOwner == 0) // 전월세라면
{
printf("안녕히계세요.\n"); // 중복 코드
printf("문을 닫는다.\n"); // 중복 코드
return 0; // 프로그램 종료
}
위의 코드는 에러마다 인사를 하고 문을 닫는코드가 중복된다
goto를 이용하면
if (gender == 2)
goto EXIT; // 에러가 발생했으므로 EXIT로 이동
if (age < 30)
goto EXIT; // 에러가 발생했으므로 EXIT로 이동
if (isOwner == 0)
goto EXIT; // 에러가 발생했으므로 EXIT로 이동
EXIT:
printf("안녕히계세요.\n"); // 에러 처리 코드를
printf("문을 닫는다.\n"); // 한 번만 사용함
조건이 맞지 않아 에러가 발생할 때마다 goto 로 EXIT 으로 이동해 코드를 실행하게 된다
2. FizzBuzz
1. FizzBuzz
FizzBuzz 는 간단한 프로그래밍 문제이다
- 1에서 100까지 출력
- 3의 배수는 Fizz 출력
- 5의 배수는 Buzz 출력
- 3과 5의 공배수는 FizzBuzz 출력
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
printf("FizzBuzz\n");
continue;
}
if (i % 3 == 0) {
printf("Fizz\n");
continue;
}
if (i % 5 == 0) {
printf("Buzz\n");
continue;
}
printf("%d\n", i);
}
return 0;
}
FizzBuzz 문제를 풀 때 주의할 점은
3과 5의 공배수를 FizzBuzz 로 구현하는 것이다
조건의 순서대로 if 문을 이용해서 구현하면
3의 배수는 Fizz
5의 배수는 Buzz
3과 5의 공배수는 FizzBuzz
하지만 3과 5의 공배수가 나오면
3의 배수인지 먼저 확인하기 때문에
Fizz가 출력되게 된다
따라서 3과 5의 공배수를 FizzBuzz 로 출력하기 위해서는
3과 5의 공배수를 출력하는 조건을
제일 위에 작성해야 한다
코드를 매우 단축해서도 작성할 수 있다
int main()
{
for (int i = 0; ++i <= 100;) // 조건식 안에서 변화식을 함께 작성
printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);
// 삼항 연산자를 세 번 사용하여 printf 안에서 처리
return 0;
}
3. 심사문제
32.6 중첩 루프 빠져나오기
다음 소스 코드를 완성하여 200과 300이 각 줄에 출력되게 만드세요.
정답에는 밑줄 친 부분에 들어갈 코드만 작성해야 합니다.
#include <stdio.h>
int main()
{
int num1 = 0;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (num1 == 10)
goto _____
num1++;
}
}
EXIT1:
printf("100\n");
EXIT2:
printf("200\n");
EXIT3:
printf("300\n");
return 0;
}
정답
EXIT2;
EXIT2 로 이동하면 아래의 EXIT3 까지 출력하기 때문에
200과 300이 출력되게 된다
33.8 5와 11의 배수, 공배수 처리하기
표준 입력으로 정수 두 개가 입력됩니다(첫 번째 입력 값의 범위는 1~1000, 두 번째 입력 값의 범위는 10~1000이며 첫 번째 입력 값은 두 번째 입력 값보다 항상 작습니다). 첫 번째 정수부터 두 번째 정수까지 숫자를 출력하면서 5의 배수일 때는 "Fizz", 11의 배수일 때는 "Buzz", 5와 11의 공배수일 때는 "FizzBuzz"를 출력하는 프로그램을 만드세요(scanf 함수 호출 전에 문자열을 출력하면 안 됩니다).
정답에는 C 언어 컴파일러에서 정상적으로 컴파일되는 전체 코드를 입력해야 합니다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int num1, num2;
scanf("%d %d", &num1, &num2);
for (int i = num1; i <= num2; i++) {
if (i % 5 == 0 && i % 11 == 0) {
printf("FizzBuzz\n");
continue;
}
if (i % 5 == 0) {
printf("Fizz\n");
continue;
}
if (i % 11 == 0) {
printf("Buzz\n");
continue;
}
printf("%d\n", i);
}
return 0;
}
'Coding > C' 카테고리의 다른 글
[C언어] 배열, 배열 포인터 사용하기 - 코딩도장 (0) | 2024.01.07 |
---|---|
[C언어] 포인터, 메모리 사용하기 - 코딩도장 (0) | 2023.12.20 |
[C언어] 반복문(for, while, do while) - 코딩도장 (0) | 2023.12.17 |
[C언어] switch 분기문 - 코딩도장 (0) | 2023.12.13 |
[C언어] 비트 연산자 - 코딩도장 (0) | 2023.12.13 |