제어문 / 조건문( if, if-esle, if-else if-else, 중첩 if ) / 선택문( switch-case )
▶▶▶ 제 어 문
– Java에서 코드는 위에서부터 아래로 순차적으로 실행됨.
그러나 어떤 코드를 반복해야 될 수도 있고, 어떤 코드는 건너뛰는 등의 순서를 변경해야 되는 일이 발생함.
이 때, 제어문을 사용하면 코드 실행 흐름을 제어할 수 있음.
1. 조건문 / 선택문 — if / switch
2. 반복문 — for / while
3. 보조 제어문 — break / continue
▶▶ 조건문
– 조건식의 결과에 따라 실행할 문장이 달라지는 문(Statement)
1. 단일 if 문
2. if—else 문
3. if—else if—else 문
4. 중첩 if 문
▶ 단일 i f 문
– 가장 단순 조건문
– 조건식 판별 결과가 true일 때, 특정 문장(블록 {})을 추가로 실행함.
문장 1;
if (조건식) {
조건식 판별 결과가
true일 때 실행할
문장 2;
}
문장 3;
• 조건식 판별 결과 true : 문장1 → 조건식(true) → 문장2 → 문장3
• 조건식 판별 결과 false : 문장1 → 조건식(flase) → 문장3
✓ 즉, 조건식의 결과가 true이면 if문실행, 거짓이면 그냥 다음 문장 실행.
EX ) 정수의 절댓값 계산하기
int num = -5; // 문장1
if(num < 0) {
num = -num; // 문장2
System.out.println("음수를 양수로 변환!"); // 문장2
}
System.out.println("num의 절대값 : " + num); // 문장3
→ num = -5의 값을 가지고 있음. 조건식에서 "num이 0보다 작느냐" 라고 물었기 때문에 결과는 true.
→ 결과가 참이므로 문장2를 실행함. 또한, 결과값에 상관없이 문장3은 if문의 블록 밖에 있으므로 무조건 실행함.
✓ 음수를 양수로 변환!
num의 절대값 : 5
EX2 ) 비교연산자, 논리연산자 활용하기
나이(age)를 입력 받아 20대인지 판별 → 나이(age)가 20이상이고 나이(age)가 29이하(30미만) → 논리곱 사용
int age = 35;
if(age>=20 && age<=29) {
System.out.println("당신은 20대 입니다!");
}
if(age<20 || age>=30) {
System.out.println("당신은 20대가 아닙니다!");
}
→ 1번째 if문 — age가 20보다 크거나 같고 29보다 작거나 같다는 모든 조건을 만족해야 (&& 논리곱)
"당신은 20대 입니다!"를 출력함
→ 2번째 if문 — age가 20보다 작거나 또는, 30보다 크거나 같다는 조건 중 하나라도 만족하면 (|| 논리합)
"당신은 20대가 아닙니다!"를 출력함.
✓ age변수 값에 따라 2번째 if문에서 30보다 크거나 같다는 조건이 만족되어 '당신은 20대가 아닙니다!' 출력됨.
▶ i f — else문
– 조건식 판별 결과가 true일 때와 false일 때 서로 다른 블록을 수행함.
– 삼항연산자와 유사한 형태로 수행되나 삼항연산자보다 유연하여 조건식 판별 결과에 따라 실행 가능한 문장이 다양함.
– if문 블록은 조건식 결과가 true일 때 실행하고, else문 블록은 조건식 결과가 false일 때 실행함.
→ 둘 중 하나의 블록만 실행됨.
문장1;
if (조건식) {
문장2 (조건식 결과가 true일 때 실행할 문장들)
} else {
문장3 (조건식 결과가 false일 때 실행할 문장들)
}
문장4 (if문 블록 밖에 위치하므로, if문 다음에 무조건 실행되는 문장들)
✓ 조건식 판별 결과 true : 문장1 → 조건식(true) → 문장2 → 문장4
✓ 조건식 판별 결과 flase : 문장1 → 조건식(false) → 문장3 → 문장4
EX ) 정수의 대한 절대값 계산
int num = -5; // 문장1
if(num < 0) {
System.out.println("음수이므로 양수로 전환!"); // 문장2
num = -num; // 문장2
} else {
System.out.println("양수이므로 변환 생략!"); // 문장3
}
System.out.println("num의 절대값 : " + num); // 문장4
→ num = -5이므로 if문으로 들어가 양수로 전환됨. 따라서 문장2를 실행하고 if문 밖에 있는 문장4를 실행함.
✓ 음수이므로 양수로 전환!
num의 절대값 : 5
EX2 ) 정수 num에 대해 홀수, 짝수(0포함) 판별
if문을 사용하여 홀수일 경우, "num은 홀수!" 출력하고, 아니면(짝수일 경우) "num은 짝수!" 출력하기
일반적으로 프로그래밍에서 홀수 & 짝수를 표현하는 기준은 아래와 같음.
• 홀수 : 정수 num을 2로 나눈 나머지가 1일 경우 (1과 같은 경우)
• 짝수 : 정수 num을 2로 나눈 나머지가 0일 경우 (0과 같은 경우)
int num = 7;
if(num%2 == 1) {
System.out.println(num + " : 홀수!");
} else {
System.out.println(num + " : 짝수!");
}
→ 비교연산자(==) 보다 퍼센트연산자(%)가 우선순위 더 높으므로, 나눗셈 먼저 하고 그 나머지가 1인지를 판별함.
✓ num = 7이므로, if문의 조건 결과 true이기에 '7 : 홀수!' 값이 출력됨.
EX3 ) 비교연산자, 논리연산자 활용하기
20대란? 나이가 20이상이고 29이하(30미만) → 논리곱 사용
int age = 35;
if(age>=20 && age<30){
System.out.println("당신은 20대 입니다!");
} else {
System.out.println("당신은 20대가 아닙니다!");
}
→ 프로그래밍 기준에서 논리곱 & 논리합 사용시, 산술과 다르게 되도록이면 변수를 왼쪽에 둠.
✓ age값이 35이므로, if문의 조건 결과 false이기에 else문의 출력문이 선택되어 '당신은 20대가 아닙니다!'가 출력됨.
▶ if — else if — else문
– 두 가지 이상의 조건식을 사용하여 세 가지 이상의 경우의 수 판별
– 기본 if문으로 첫 번째 조건을 설정하고, else if문으로 두 번째 이후의 조건을 설정함.
– 모든 조건이 만족하지 않을 때 실행할 문장이 있을 경우, 문장의 마지막에 else문을 사용
– if문 비교는 위에서 아래로 차례대로 비교를 수행함.
→ 비교 범위가 좁은 조건식부터 비교를 수행해야 한다!
if (조건식1){
조건식 1의 결과가 true일 때,
실행할 문장들.
} else if (조건식2){
조건식 1의 결과가 false이고,
조건식 2의 결과가 true일 때,
실행할 문장들.
} else if (조건식n){
조건식 1~n-1의 결과가 false이고,
조건식 n의 결과가 true일 때,
실행할 문장들.
} else {
위의 모든 조건식(n까지) 결과가 false일 때
(마지막 else문은 생략 가능)
}
EX1 ) 조건을 걸어, 양수 & 음수 & 0 판별하기
int num = 5;
if(num > 0) { // 양수일 때
System.out.println(num + " = 양수");
}else if(num < 0) { // 음수일 때
System.out.println(num + " = 음수");
}else { // 양수도 음수도 아닐 때
System.out.println(num+ " = 0");
}
→ else if (num==0)으로 써도 되지만,
위의 케이스는 양수, 음수, 0 이렇게 3가지 경우밖에 없기 때문에 else(나머지) 사용함.
✓ num=5이므로, if문 조건을 만족하여 '5 = 양수'가 출력됨.
EX2 ) 홀수, 짝수, 0 판별하기
int num = 0;
if(num%2 == 1) {
System.out.println(num + " = 홀수");
}else if(num%2 == 0) {
System.out.println(num + " = 짝수");
}else if(num == 0) {
System.out.println(num + " = 0");
}
→ 기본문법에 맞게끔 차례대로 홀수, 짝수, 0을 판별하는 조건식을 만들었으나,
이렇게 코드를 짜면 홀수, 짝수의 판별에는 문제가 없지만 0의 판별에는 문제가 생겨, '0 = 짝수'의 결과값이 나옴.
→ if문은 위에서부터 차례대로 조건을 검사하는데,
마지막 else if문의 0은 바로 위의 else if문의 짝수판별식에서 2로 나눈 나머지도 0이므로 여기서 true가 됨.
✓ 결과가 0도 짝수로 나오기 때문에 0을 출력하는 문장은 실행 될 수 없으므로,
홀수 판별식의 위치는 무관하나, 0을 판별하는 문장(0과 같다)은 짝수 판별 문장보다 위에 위치하도록 해야 함.
int num = 0;
if(num%2 == 1) {
System.out.println(num + " = 홀수");
}else if(num == 0) {
System.out.println(num + " = 0");
}else if(num%2 == 0) { // else문 사용 가능
System.out.println(num + " = 짝수");
}
→ 0을 판별하는 조건식보다 아래쪽에서 짝수를 판별해야 함.
✓ num=0이므로, 첫번째 else if문을 만족하여 '0 = 0' 결과값이 출력됨.
EX3 ) 좁은 범위부터 시작하기
int num = 20;
if(num > 5) {
System.out.println("5보다 크다!");
} else if(num > 10) {
System.out.println("10보다 크다!");
}
→ num > 5 조건식 범위 안에 num > 10 조건식이 포함되므로, num > 10 조건식은 실행될 수가 없는 문장.
num이 10보다 커도 이는 무조건 5보다도 크기 때문에, if 문만 실행되어 답은 "5보다 크다"라고만 나옴.
✓ 순서를 바꾸어 10보다 크냐 다음으로 5보다 크냐를 물어봐야 함.
int num = 20;
if(num > 10) {
System.out.println("10보다 크다!");
} else if(num > 5) {
System.out.println("5보다 크다!");
}
→ if ~ else문 작성 시에는 조건식의 범위가 좁은 조건식부터 판별해야 함
✓ num=20이므로, if문의 조건을 만족하여 '10보다 크다!'가 출력됨.
▶ 중첩 if문
– if문(else if 또는 else 포함) 블록 내에서, 또 다시 if문을 사용하여 조건식을 판별하는 것.
if문 블록을 여러번 중첩시킴.
if (조건식1) {
if (조건식2) {
조건식1이 true이고, 조건식2도 true일 때 실행
} else {
조건식1이 true이고, 조건식2가 false일 때 실행
}
}
EX1 ) 점수에 알맞은 학점 출력하기
— 학점 "A" 90~100점, "B" 80~89점, "C" 70~79점, "D" 60~69점, "F" 0~59점
1 ) 입력받은 점수가 0~100 사이일 경우 "점수 입력 완료!" 출력, 아니면 "점수 입력 오류!" 출력하는 큰 틀 만들기 (if문)
2 ) 그 안에서 점수에 따른 학점 출력하기 (중첩 if문)
방법 1 ) 논리곱 사용
int score = 70;
String grade = "";
if(score >= 0 && score <= 100) {
System.out.println("점수 입력 완료!");
if(score >= 90 && score <= 100) {
grade = "A";
} else if(score >= 80 && score <= 89) {
grade = "B";
} else if(score >= 70 && score <= 79) {
grade = "C";
} else if(score >= 60 && score <= 69) {
grade = "D";
} else {
grade = "F";
}
System.out.println(score + "점의 학점 : " + grade);
}else {
System.out.println(score + " : 점수 입력 오류!");
}
→ 모든 조건에서 출력문이 동일하므로, if문에서 출력할 문장을 빼서 마지막에 써 주기 위해 String타입의 변수 생성함.
→ grade라는 변수에 어떤 학점이 올 지 모르니 ""; 값을 비워놓음.
char타입은 ' '작은따옴표가 있고, 어떤 문자든 꼭 들어가 있어야 하므로, null값을 주기에는 String타입이 좋음.
→ scorer값이 70이므로 0~100사이의 값이 조건인 첫번째 if문 만족,
그 중에서 70점 이상 70점 이하이의 값이 조건인 두번째 else if문을 만족하여 grade변수에 "C"값이 저장됨.
✓ '점수 입력 완료!'
'70점의 학점 : C'가 출력됨.
방법 2 ) 좁은 범위부터 시작
int score = 50;
String grade = "";
if(score >= 0 && score <= 100) {
System.out.println("점수 입력 완료!");
if(score >= 90) { // 90 이상일 때 자동으로 100이하가 적용됨
grade = "A";
} else if(score >= 80) { // 위의 조건이 거짓이라면 자동으로 89 이하
grade = "B";
} else if(score >= 70) { // 위의 조건이 거짓이라면 자동으로 79 이하
grade = "C";
} else if(score >= 60) { // 위의 조건이 거짓이라면 자동으로 69 이하
grade = "D";
} else {
// 위의 조건이 모두 거짓이면 자동으로 59이하이고
// 이미 0 ~ 100 사이 점수만 입력 가능하므로 0 이상
grade = "F";
}
System.out.println(score + "점의 학점 : " + grade);
} else {
System.out.println(score + " : 점수 입력 오류!");
}
→ score값이 50이므로 0~100사이의 값이 조건인 첫번째 if문 만족,
그 중에 두번째 if문과 밑의 else if문들의 조건을 만족하지 못하기에, else문으로 넘어가 grade변수에 "F"값이 저장됨.
✓ '점수 입력 완료!'
'50점의 학점 : F'가 출력됨.
EX2 ) 문자 ch에 대한 대소문자 판별 & 변환하기
— ch가 대문자일 때 소문자로 변환, 소문자일 때 대문자로 변환, 대소문자가 아닐 경우 "변환 불가!" 출력
• 대문자란? 'A'(65)이상이고 'Z'(90)이하인 문자
• 소문자란? 'a'(97)이상이고, 'z'(120)이하인 문자
• 소문자 → 대문자로 변환
→ a97 - A65 = 32 → b98 - B66 = 32 ⇒ 소문자와 대문자의 차이는 '32'
char ch = 'b';
if(ch >= 'A' && ch <= 'Z'){ // ch >= 65 && ch <= 90 가능
System.out.println(ch+"는 대문자");
ch += 32;
System.out.println("소문자"+ch+"로 변환 완료!");
}else if(ch >= 'a' && ch <= 'z'){ // ch >= 97 && ch <= 120 가능
System.out.println(ch+"는 소문자");
ch -= 32;
System.out.println("대문자"+ch+"로 변환 완료!");
}else {
System.out.println("변환 불가!");
}
→ ch값이 'b'이므로 else if문을 만족,
첫번째 실행문 출력 후, 변수 ch에 -32가 되어 66(B)의 값이 저장되고, 두번째 실행문이 출력됨.
✓ 'b는 소문자'
'대문자 B로 변환 완료!'
▶▶ 선택문
– 특정 조건에 대해 여러가지 판별을 수행하는 문.
▶ Switch — case문
– if문과 달리 범위에 대한 판별 등이 불가능하며, 값에 대한 동등 비교만 가능함.
– switch문의 조건식에는 연산식 또는 변수, 리터럴 등이 올 수 있으나,
반드시 정수 타입 또는 문자열 타입(또는 eunm 타입 상수)만 사용 가능.
→ 이 중, 정수는 byte, short, char, int만 사용 가능 (long X)
– switch문에서 지정한 조건에 맞는 값을 case문에서 탐색하여 일치하는 값을 갖는 case문의 문장을 실행함.
이 때, case문에는 조건식 결과를 비교할 리터럴 1개만 명시함.
→ 일치하는 case문이 없을 경우, default문을 찾아서 실행함. (else문과 유사하며 생략도 가능)
– case문의 문장 실행 후, break문을 만나면 switch문을 빠져나감.
단, break문이 없을 경우 다음 break문을 만나거나 switch문이 종료될 때까지,
현재 문장의 아래쪽 모든 실행 문장을 실행함.
→ 다른 case문과 default문의 실행문까지 모두 실행
– case문끼리의 순서는 무관함.
switch (조건식) {
case 값1 :
조건 결과 값1과 일하는 경우 실행할 문장들
break; (switch문을 바로 빠져 나감)
case 값2 :
조건 결과 값2과 일하는 경우 실행할 문장들
break;
case 값n :
조건 결과 값n과 일하는 경우 실행할 문장들
break;
default :
case문 중 일치하는 값이 없을 경우 실행할 문장들
}
EX1 ) break문 사용
int num = 2;
switch(num) {
case 1 : System.out.println("num = 1");
case 2 : System.out.println("num = 2");
case 3 : System.out.println("num = 3");
}
→ num의 값이 2이므로, case 2의 문장을 실행하지만, break문이 없어 아래쪽 case 3의 문장도 실행함.
✓ 'num = 2'
'num = 3'
num = 2;
switch(num) {
case 1 : System.out.println("num = 1");
case 2 : System.out.println("num = 2");
case 3 : System.out.println("num = 3");
default : System.out.println("일치하는 case문 없음!");
}
→ break문이 없을 때, case문과 default문 모두 실행 대상에 포함됨.
✓ 'num = 2'
'num = 3'
'일치하는 case문 없음!'
위의 코드들을 break문을 사용하여 조건식에 알맞은 값을 출력하겠음.
int num = 2;
switch(num) {
case 1 :
System.out.println("num = 1");
break;
case 2 :
System.out.println("num = 2");
break;
case 3 :
System.out.println("num = 3");
break;
default :
System.out.println("일치하는 case문 없음!");
}
→ num=2이므로, case2의 출력문을 실행 후, break문을 만나 아래쪽 나머지 문장은 실행하지 않고 switch문을 빠져나감.
default문 아래쪽에 다른 실행문이 없으므로 break문 생략가능. default문에는 굳이 break문 안써도 됨.
✓ 'num = 2'
EX2 ) switch문에 '문자열 데이터' 전달 시
switch("KOREA") { // 변수 값 대신 전달 가능
case "대한민국" : System.out.println("대한민국"); break;
case "KOREA" : System.out.println("KOREA!"); break;
case "한국" : System.out.println("한국!"); break;
default : System.out.println("다른 나라!");
}
→ switch문의 조건식에는 연산식, 변수, 리터럴이 올 수 있으나 반드시 정수타입 & 문자열타입만 올 수 있음.
→ 실행할 코드가 한 줄이라면, 줄바꿈하지 않고 이어서 씀.
→ 조건식이 문자열타입 "KOREA"이므로
case "KOREA"의 값과 일치하기에, 해당 출력문을 출력하고 break문을 만나 switch문을 빠져나감.
✓ 'KOREA!'
EX3 ) 연산식 사용
switch(10 / 2) {} // 10/2는 결과가 정수이므로 사용 가능
switch(10 / 2.0) {} // 10/2.0의 결과는 실수이므로 사용 불가
switch(1+"1") {} // 결합연산자로 정수+문자열 = 문자열이므로 사용 가능
→ switch문에는 연산식이 사용 가능하지만, 연산 결과가 정수, 문자열타입이어야 함.
Q1 ) switch-case문을 사용하여 입력받은 월(month)이 다음과 같을 때, 해당 월의 일수를 출력하시오.
• 1, 3, 5, 7, 8, 10, 12월일 경우 : "한 달은 31일" 출력
• 4, 6, 9, 11월일 경우 : "한 달은 30일" 출력
• 2월일 경우 : "한 달은 28일" 출력
A1 )
int month = 2;
switch(month) {
case 1 : System.out.println(month + "월의 한 달은 31일"); break;
case 3 : System.out.println(month + "월의 한 달은 31일"); break;
case 5 : System.out.println(month + "월의 한 달은 31일"); break;
case 7 : System.out.println(month + "월의 한 달은 31일"); break;
case 8 : System.out.println(month + "월의 한 달은 31일"); break;
case 10 : System.out.println(month + "월의 한 달은 31일"); break;
case 12 : System.out.println(month + "월의 한 달은 31일"); break;
case 4 : System.out.println(month + "월의 한 달은 30일"); break;
case 6 : System.out.println(month + "월의 한 달은 30일"); break;
case 9 : System.out.println(month + "월의 한 달은 30일"); break;
case 11 : System.out.println(month + "월의 한 달은 30일"); break;
case 2 : System.out.println(month + "월의 한 달은 28일");
}
→ 이렇게 코드를 작성해도 틀린건 아니지만, 딱 봤을 때 중복되는 구간이 많음.
좀 더 간단하게 코드를 수정해 보겠음.
int month = 7;
switch(month) {
case 1 :
case 3 :
case 5 :
case 7 :
case 8 :
case 10 :
case 12 : System.out.println(month + "월의 한 달은 31일"); break;
case 4 :
case 6 :
case 9 :
case 11 : System.out.println(month + "월의 한 달은 30일"); break;
case 2 : System.out.println(month + "월의 한 달은 28일");
}
→ 결과값이 1, 3, 5, 7, 8, 10, 12일 때, 원래는 모든 case문에서 "한 달은 31일" 문자열이 출력됐는데
이는 중복이므로, 각 case문에서 모두 출력하지 않고 마지막 case문에서만 출력하고 나머지는 비워두면,
break 문이 없기 때문에 12월까지 내려가서 출력문을 실행함.
→ 결과값이 4, 6, 9, 11일 때 또한 출력문이 중복되므로, 마지막 11월에서만 출력문을 실행하면 됨.
✓ '7월의 한 달은 31일'
Q2 ) switch-case문을 사용하여 점수에 알맞은 학점을 출력하시오.
— 학점 "A" 90~100점, "B" 80~89점, "C" 70~79점, "D" 60~69점, "F" 0~59점
A2 )
점수(score)에 따른 학점 계산을 switch문으로 수행할 경우,
case문에서 값만 지정 가능하여 범위 지정이 불가능하므로 각각의 점수를 모두 지정해야 함.
int score = 88;
switch(score) {
case 100 : System.out.println("A학점!"); break;
case 99 : System.out.println("A학점!"); break;
case 98 : System.out.println("A학점!"); break;
// 생략
case 55 : System.out.println("A학점!"); break;
case 54 : System.out.println("A학점!"); break;
case 53 : System.out.println("A학점!"); break;
// 생략
case 1 : System.out.println("A학점!"); break;
case 0 : System.out.println("A학점!"); break;
}
→ 이런식으로 작성하게 되면, 값에 따른 결과를 위해 총 100줄의 코드를 만들어야 해서 비효율적임.
첫번째 문제에서 봤듯이 switch-case문은 중복하는 문장을 찾아 코드를 간단하게 만들 수 있었음.
중복하는 문장을 찾으려면, 공통점을 먼저 찾아야 함.
일단, 학점을 출력하는 출력문이 각 학점별로 중복이 되고, case의 값 또한 99, 98, 97... 10의 자리가 중복됨.
그렇다면 일의 자리는 버리고 10의 자리값만 남긴다면...10, 9, 8, 7, 6, default로 case값을 정할 수 있음!
연산식을 활용하여 각 학점에 해당하는 점수의 공통점을 추출함.
A학점 : 90점대와 100점( = 10의자리 숫자가 9또는 10)
B학점 : 80점대( = 10의자리 숫자가 8)
C학점 : 70점대( = 10의자리 숫자가 7)
D학점 : 60점대( = 10의자리 숫자가 6)
F학점 : 나머지 점수( = default)
✓ 점수에서 10의 자리 값을 추출하여 switch문에 전달
score = 88;
switch(score/10) {
case 10 :
case 9 : System.out.println("A학점"); break;
case 8 : System.out.println("B학점"); break;
case 7 : System.out.println("C학점"); break;
case 6 : System.out.println("D학점"); break;
default : System.out.println("F학점!!!");
}
→ case 뒤에는 조건식 결과를 비교할 리터럴 1개(값)만 명시할 수 있으므로 변수에 식을 써줌.
⚠️ 문제점 발생⚠️
– 101~109점도 나누기 10을 하면 몫이 10이므로, A학점으로 취급됨.
→ if문을 사용하여 0~100사이일 때만 학점 계산하는 조건 걸기!
int score = 88;
if(score >= 0 && score <= 100) {
switch(score/10) {
case 10 :
case 9 : System.out.println("A학점"); break;
case 8 : System.out.println("B학점"); break;
case 7 : System.out.println("C학점"); break;
case 6 : System.out.println("D학점"); break;
default : System.out.println("F학점!!!");
}
}else {
System.out.println(score + " : 점수 입력 오류!");
}
→ score=88이므로, if문의 0~100점 사이의 조건에 만족하여 switch-case문으로 들어감.
→ switch문의 조건식에 의해 88/10=8이므로, case 8의 값을 찾아가 해당 출력문이 출력됨.
✓ 'B학점'
Comment

확실히 조금씩 어려운 개념들을 마주할수록 문제 풀 때 수도코드가 늘어난다ㅎㅎㅎ
알고리즘이 어떻게 실행되어야 하는지 쉽게 파악할 수 있어서 좋은듯ㅎㅋㅋ
블라블라 열심히 수도코드를 써 놓고, 그걸 코드로 변환해서 답을 맞췄을때의
그
짜릿함
!!!!!!!!!!!!!!!!!!!!!
공부가 너무 재밌다
(아직까지는ㅎ)