시험을 봤지만, 여기 문제에서도 부족한 부분을 채우기 위해서 전체적으로 해설을 내가 작성해보면서 몰랐었던, 놓쳤던 부분들을 찾아 낼 수 있었다.
배운점 1
Switch 조건문에서 int만 사용 되는 줄 알았는데 double 도 사용 된다는 것을 다시 회상 할 수 있었다.
배운점 2
유효성 검사 부분에서 내가 자주 실수하던 논리 연산자에 대해서 다시 한번 정리 할 수 있었다.
배운점 3
Q8에서 나는 저 값을 내림(Math.floor())해야 한다는 것에 몰두해서 생각보다 효율적이지 못한 코드를 작성 한 것 같다.
시험이 끝나자 마자 팀 동료들과 해당 부분에 대해 어떻게 작성 했는지 내용을 공유했다.
이준영
11:13 AM
value - value%100
장지예
11:24 AM
(value/100)*100
김인용
11:26 AM
어짜피 정수였다는걸 이용하지 못했네요. 내림에 대한 생각뿐이었나봐요
(int)(Math.floor((value/100)*100))
나도 value자체가 int type으로 선언 된 것을 인지하고 있었는데, Math클래스 함수를 사용하는데 몰두되어 더 간단한 방법들을 생각 안했다. 사실 동료들 처럼 단순하게 처리 했어도 되는 문제이다. 이미 팀원의 코드 자체가 내 코드에도 부분적으로 포함된 것을 보면 나는 필요없는 형변환으로 시스템에 오히려 무리를 주는 상황이라 생각되었다.
배운점 4
지나고나니 1문제가 틀렸다.
내가 생각하기엔 이 부분의 입력이 잘못되었다. 그래서 맞은거다? 아니다. 오히려 치명적인 실수이다. 모르면 보통 작성을 안하거나 오류가 발생한다. 그럼 다른 사람이나 개발한 나 조차도 쉽게 발견한다. 하지만 이 조건식 괄호 ( 하나가지고 틀린 것 자체가 치명적인 오류를 발생 시킬 수도 있다. 더 복잡해지고 할 수록 이런 부분은 디버깅 과정을 거치더라도 놓치기 쉬워진다. 에러가 발생하는데 어딘지 찾기가 어렵다. 특히 작성을 한 부분이면 사람의 눈으로 체크 할 때 “여긴 멀쩡히 입력 되었는데 왜 실행에서 오류가 나지?” 라고 지나쳐가기 쉬운 치명적인 오해를 불러 올 수 있다. 물론 IDE 자체가 컴파일 오류를 잡아 줄만한 부분이긴 하지만, 프로그래밍은 그렇다 틀리면 틀린 것이다. 우선 더블체크 하지않은 잘못이고, 시험지에 입력해놨다가 Ctrl + C, V를 믿엇던 내가 잘못이다. 나 조차도 믿지말고 내가 눈으로 보고 확인한 것만 믿어야 한다.
Q1. 90점을 넘으면 A등급, 아니라면 B등급을 출력하는 소스코드입니다. 빈칸에 들어갈 알맞은 소스코드는?
public class ConditionalOperation{
public static void main(String[] args){
int score = 85;
char grade;
(빈칸)
System.out.println(score+"점은 "+grade+"등급입니다.");
}
}
//실행결과 : 85점은 B등급 입니다.
JavaScript
복사
1.
(score>90)? score='A' : 'B'; // score에 할당하고있으니 아니다. X
2.
grade=(score>90)? 'A' : 'B'; // (조건)? 일때 true : false 값을 grade에 넣고 있다. O
3.
if (score>90) grade='A'; if else grade='B'; 조건문은 다음과 같이 해야 한다.
if(score>90) {
grade = 'A'
}else{
grade = 'B'
}
Java
복사
이 부분도 정확하지 않다. score가 -값이 들어가도 B로 할당되기 때문에
if(score>90 || score<=100) {
grade = 'A'
}else if(score>80 || score<=90){
grade = 'B'
}else if(
...
}else{
System.out.print("잘못된 값을 입력하셨습니다.)
}
Java
복사
처럼 정확하게 조건들을 구분해야 한다.
Q2. 534자루의 연필을 30명의 학생들에게 똑같은 개수로 나누어줄 때 1인당 몇개를 가질 수 있고, 몇개가 남는지를 구하는 코드입니다. (1), (2)에 들어갈 알맞은 코드가 짝지어진 것은?
int pencils =534;
int students = 30;
int pencilsPerStudent = (1)
int pencilsLeft = (2)
JavaScript
복사
1.
(1) pencils%students (2)pencils%students
2.
(1) pencils/students (2)pencils/students
3.
(1) pencils/students (2)pencils%students
4.
(1) pencils%students (2)pencils/students
이런 문제는 생각하지 말고 실제로 계산 하는 것이 빠르다.
534/30 = 17.8
int 정수형이기 때문에 몫에서 실수 부분이 제외된다. 17개씩 나누어 가질 수 있고,
534%30 = 24
나머지 부분이 30 인원에 모자라기 때문에 남는 부분이다.
Q3. 다음 코드를 실행했을 때 출력 결과는?
int score = 85;
String result = (!(score>90))? "가" : "나";
System.out.println(result);
JavaScript
복사
1.
가
2.
나
논리에 대한 파악이다. 그대로 해석하면
스코어는 85라는 정수가 할당되어있다.
결과는 스코어가 ((90초과일때))가 아닐때기 때문에 90 미만일때라고 봐야 한다.
90 미만일 때 true에 “가”를 false에 “나”를 결과에 할당한다.
스코어가 85기 때문에 90 미만이다. 따라서 true기 때문에 답은 (가) 이다.
Q4. 다음 중, 틀린 문장은?
1.
if문은 조건식의 결과에 따라 실행 흐름을 달리할 수 있다. 조건문은 조건식의 결과로 흐름을 넘기기 위해서 사용된다. O
2.
if문은 조건식이 true이면 블록을 실행하고 false이면 블록을 실행하지 않는다. 좀 더 정확하게 하면 조건문의 조건식이 true일때 “해당”블록을 실행하고 다음 코드 또는 조건문 등을 실행하려 내려간다.
3.
if문의 블록 내부에는 또 다른 if문을 사용할 수 있다. 중첩 if로 여러 조건들을 사용 할 수 있다.
4.
switch문에서 사용할 수 있는 변수의 타입은 int만 가능하다. 정확히 모르던 부분이다. 정답을 맞추더라도 int만 사용해오긴 했는데 다른 boolean 또는 double, float등이 사용 될 지 몰랐다. 하지만 위 3개의 답이 맞기 때문에 틀린 문장은 4번이다.
추가적인 공부로 찾아 본 결과 switch 문은 int, double이 가능하다고 한다. double이 되는 것은 몰랐다. 기억해두자.
Q5. 두개의 숫자 a, b중 a가 큰지, b가 큰지를 구하는 프로그램입니다. (1), (2)에 들어갈 알맞은 코드가 짝지어진 것은?
if ( (1) ){
System.out.println("a가 더 큽니다.");
}
else if ( (2) ) {
System.out.println("b가 더 큽니다.");
}
else{
System.out.println("두 숫자가 같습니다.");
}
JavaScript
복사
1.
(1) a>b (2) b>a 기본적으로 이상, 초과 / 이하, 미만에 대하여 이해하는 질문이다. 이상, 이하의 경우 값이 같은 것 까지 포함하기 때문에 초과, 미만인 해당 표현이 맞다.O
2.
(1) a>=b (2) b>=a a,b가 같은 경우까지 포함하고 있다.X
3.
(1) b>a (2) a>b 순서가 잘못되었다. 처음 부분에 b가 더 큰것을 말하고 있는데 출력문은 a가 더크다고하고있고, 반대도 반대로 마찬가지다. X
4.
(1) b>=a (2) a>=b 이것도 순서가 잘못되었음과 동시에 같은 경우까지 포함하고 있다. X
Q6. 중첩 조건문은 논리 연산자를 적용해 하나의 조건문으로 만들 수 있습니다. 빈 칸에 어떤 논리 연산자가 들어가야 할까요?
if(x>10){
if(x<20){
System.out.println("조건에 맞습니다.");
}
}
//바꾼 뒤
if ( 빈칸 ){
System.out.println("조건에 맞습니다.");
}
JavaScript
복사
중첩 조건문에서 위 원본 조건문의 내용은 x는 10보다 커야되면서 동시에 x는 20보다 작아야 한다. 이 말은 두 조건이 true여야 조건에 맞습니다라는 출력이 된다는 소리다.
1.
x>10 || x<20 or연산자는 둘중에 하나라도 true면 true를 반환한다. 이말은 x가 30이면 20미만조건에 해당되지 않아도 10초과기 때문에 조건에 맞다고 잘못 나올 수 있다.X
2.
x>10 && x<20 and연산자는 둘다 맞아야 한다. 마치 수학에서 음수의 곱과 비슷한 논리(하지만 음수*음수가 양수가 되는 것은 제외해야 한다.)로 보면 된다. true&&false 면 false다, false&&true면 false다 true&&true여야 true다 false&&false면 false다. 이 논리가 위 원본 중첩 조건문과 알맞다. O
3.
x>10, x<20 논리 연산자가 사용되지 않았다. 해당 결과는 오류가 발생된다. X
4.
x>10과 x<20 “과”라는 연산자는 없다.X
Q7. 다음 프로그램의 실행 결과를 예측해보세요.
for (int i=0;i<3;i++){
System.out.println(i);
}
JavaScript
복사
for loop로 반복하는 횟수를 지정하는 문법이다. 아주 많이 사용되는 반복문이다.
i는 0이며, 3미만까지(2까지) ; i는 1씩 증가
하며 i를 출력한다.
최초 init 값은 0이며, println을 통해 출력 후 줄바꿈이 이뤄진다. 이후 i++로 i가 증가하고
i=1로 초기화 되며 조건식에서 i<3에 만족하기(true)기 때문에 다시 한번
i를 출력하고 줄바꿈,
i증가, 초기화(할당), 조건식 true, 출력, 줄바꿈… → 이 흐름으로 진행된다.
결국 i가 3에 도달했을때 조건식에서 false가 반환되면서 아래 블록으로 더이상 진행되지 않는 흐름이다.
따라서, 최초 초기화된 값은 0→1→2까지만 출력되고 반복문이 종료되는 코드이다.
1.
0 (줄바꿈) 1 (줄바꿈) 2
2.
1 (줄바꿈) 2 (줄바꿈) 3
3.
0 (줄바꿈) 1
4.
1 (줄바꿈) 2
Q8. 다음은 십의 자리 이하를 버리는 코드입니다. 변수 value의 값이 356이라면, 300이 나올 수 있도록 빈칸에 알맞은 코드를 넣어주세요. (부분점수 있음)
int value = 356;
System.out.println( (빈칸) );
JavaScript
복사
10의 자리 이하를 버린다.
356이면 300이 되도록 해야 한다는 것과 같다.
56을 없에는 방법에 대해서 생각해야 한다.
해당 값은 정수이다.
Math클래스를 사용하면 된다. Math.round()는 반올림, Math.ceil()는 올림, Math.floor()는 내림이다.
해당 조건에서는 Math.floor를 사용하면 된다. 하지만, Math.floor는 double을 반환한다. 따라서 (int)로 형변환이 필요하다.(int)(Math.floor((value/100)*100))
Q9. 주어진 input이 짝수인지 홀수인지 판별하는 switch문입니다. 빈칸에 들어갈 알맞은 코드를 넣어주세요. (산술 연산자만 사용하세요.) (부분점수 있음)
int input = 13;
switch ( (빈칸) ) {
case 0:
System.out.println("짝수입니다.");
break;
case 1:
System.out.println("홀수입니다.");
break;
}
JavaScript
복사
짝수와 홀수의 관계를 알아야 한다.
예로
1, 3, 5, 7, 9 홀수
2, 4, 6, 8, 10 짝수다.
2로 나누면 몫 값들은 다르겠지만
나머지(%결과)가 0인경우 짝수, 1인 경우 홀수다.
input%2 == 0 짝수
input%2 == 1 홀수
라는 말이다. 하지만 switch문이기 때문에 위 조건문이 0, 1일때 짝수를 출력할지, 홀수로 출력할지를 정하고 있다.
(input%2 == 0)? 0:1
?를 통해 true : false를 활용하면 코드를 절약 할 수 있다.
Q10. 다음 프로그램의 결과를 예측해보세요. (부분점수 있음)
for(int i=0;i<10;i++) {
if(i==5) continue;
if(i==7) break;
System.out.println(i);
}
JavaScript
복사
0(줄바꿈) 1(줄바꿈) 2(줄바꿈) 3(줄바꿈) 4(줄바꿈) 6(줄바꿈)
결과해석)
i는 0이란 정수로 초기화되고, 0부터 9까지 i가 증가, 내부 함수 실행이 반복되는 반복문이다.
내부 함수는 print를 통해 해당 내부 함수를 진입하게 해준 i값이 출력된다.
이후 증가식에 따라 i값이 1씩 증가되어 할당, 조건식 여부 체크, 내부 함수 실행 이 반복된다.
하지만 반복을 도는 중 내부 함수에 반복에 사용되는 변수 i에 대한 조건문이 있다.
i가 5에 도달하면 해당 반복문을 건너 뛰는 continue,
반복을 도는 중 7이 되면 그자리에서 (가까운==여긴 하나밖에없긴하다)반복문을 탈출하는 break가 있다.
따라서 출력은,
0(줄바꿈) 1(줄바꿈) 2(줄바꿈) 3(줄바꿈) 4(줄바꿈) 6(줄바꿈)
i=5가 됐을 때 출력을 건너뛰고(continue;위치에서 바로 건너뛴다. 마치 커서가 i를 담고 하나씩 실행하면서 아래로 가다가 해당 조건문의 continue;를 만나자마자 건너뛴다 생각하면 편하다.) 건너 뛰어도 증감식에 따라 i는 6으로 증가되어 다음 반복문을 실행한다. 반복문의 조건식에서 아직 종료할 조건이 충족되지 않기 때문이다.
i=7이 됐을 때 반복문을 탈출(break;)를 만난 시점에서 즉시 탈출하게 된다. continue와 마찬가지로 커서가 i를 담고 내려가면서 실행하다가 break;를 만난 시점에 즉시 가까운 반복문을 탈출한다. 하지만 반복문의 조건인 i<10의 조건이 달성되지 않았는데도, i++을 해야하는데도 해당 반복문을 종료해버린다. break; 자체가 그런 기능이고 for loop를 탈출하도록 만들어 진 것이기 때문이다.
더하여 이 결과는 println 출력문이 반복문 내부 실행 함수에서 if 조건문들보다 아래 위치 하고있기 때문에 이런 결과가 나타난다.
만약 print 출력문이 if조건문들보다 위에 위치했었으면 전혀 다른 결과가 나왔을 것이다. 내부 함수가 실행중일때 i를 담은 커서가 continue와 break 를 만나는 시점이 출력 이후에 위치 할 것이기 때문이다.