2단원 숙제 정답: 변수, 기본형, 진법, 형변환¶
문제 1. 대입은 오른쪽부터¶
a=12
b=7
처음: a=7, b=12
a=a+b: a=19, b=12
b=a-b: a=19, b=7
a=a-b: a=12, b=7
각 대입문은 오른쪽 계산을 모두 끝낸 뒤 왼쪽 변수에 저장한다. 이 방법은 덧셈 결과가 int 범위를 넘으면 실패할 수 있으므로, 일반적으로는 tmp 변수를 이용한 교환이 더 안전하다.
문제 2. 컴파일러의 관점¶
| 항목 | 결과 | 이유 |
|---|---|---|
| ① | 컴파일 오류 | b + 1의 산술 결과는 int다. int를 byte에 자동 대입할 수 없다. |
| ② | -128 |
명시적 형변환은 가능하다. 127 다음의 8비트 값은 10000000, 즉 -128이다. |
| ③ | 컴파일 오류 | final 상수는 한 번 초기화한 뒤 값을 변경할 수 없다. |
| ④ | 컴파일 오류 | 3.14는 접미사가 없으므로 double 리터럴이다. float f = 3.14f;로 써야 한다. |
문제 3. 리터럴과 진법¶
| 변수 | 타입 | 10진수 값 |
|---|---|---|
a |
long |
3,000,000,000 |
b |
int |
51,966 |
c |
int |
45 |
d |
char |
65 ('A') |
45 / 2d / 55 / A
0b101101은 32 + 8 + 4 + 1이므로 45다. %x는 소문자 16진수, %o는 8진수, %c는 문자로 출력한다.
문제 4. printf의 폭과 정밀도¶
[00042]
[Java ]
[Jav]
[ 3.142]
%05d는 폭 5칸을 0으로 채운다. %-6s의 -는 왼쪽 정렬이고, %.3s는 앞의 3글자만 출력한다. %8.3f는 소수점 아래 3자리로 반올림한 뒤 전체 폭 8칸에 오른쪽 정렬한다.
문제 5. Scanner의 입력 버퍼 함정¶
name에는 빈 문자열 ""이 저장되므로 출력은 []다. nextInt()는 숫자만 읽고 줄 끝의 개행 문자는 남겨 둔다. 다음 한 줄을 nextInt()와 nextLine() 사이에 넣는다.
sc.nextLine(); // nextInt() 뒤에 남은 줄바꿈 소비
수정된 핵심 부분은 다음과 같다.
int age = sc.nextInt();
sc.nextLine();
String name = sc.nextLine();
문제 6. 진법 변환과 표현¶
0x2F + 0b1010 = 47 + 10 = 5757(10) = 111001(2) = 71(8) = 39(16)0.1011(2) = 1×2^-1 + 0×2^-2 + 1×2^-3 + 1×2^-4 = 0.5 + 0.125 + 0.0625 = 0.6875
문제 7. 8비트 2의 보수¶
37은 8비트로 00100101이다.
00100101 (37)
11011010 (1의 보수)
+ 1
----------
11011011 (-37)
따라서 16진수로는 0xDB이다. -37 + 37의 계산은 다음과 같다.
11011011
+ 00100101
----------
1 00000000
8비트 밖으로 나간 자리올림은 버리므로 최종 결과는 00000000, 즉 0이다.
문제 8. char는 문자이면서 정수다¶
57
10
C
| 식 | 결과 타입 | 이유 |
|---|---|---|
(int)c |
int |
문자 '9'의 유니코드 값은 57 |
c - '0' + 1 |
int |
char의 산술 연산은 int로 승격; 57 - 48 + 1 |
(char)('A' + 2) |
char |
'A' + 2는 int이므로 char로 명시적 변환 |
문제 9. float의 정밀도 손실¶
f=91234568
back=91234568
false
float는 10진수 약 7자리 정밀도이므로 8자리 정수 91234567을 정확히 저장하지 못하고 가까운 값 91234568으로 바꾼다. 다시 int로 변환해도 이미 잃은 원래의 1자리 정보는 복구되지 않는다.
문제 10. 명시적/자동 형변환¶
-126
-3
2
2.5
③은 두 피연산자가 int라서 정수 나눗셈을 먼저 수행하고, ④는 2.0이 double이므로 5가 double로 자동 형변환된 뒤 실수 나눗셈을 수행한다.
문제 11. 1바이트 진법 리포트¶
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Decimal (0-255): ");
int value = sc.nextInt();
String hex = Integer.toHexString(value);
String binary = Integer.toBinaryString(value);
binary = String.format("%8s", binary).replace(' ', '0');
System.out.printf("decimal : %3d%n", value);
System.out.printf("hex : 0x%s%n", hex);
System.out.printf("binary : %s%n", binary);
}
}
String.format("%8s", binary)는 최소 폭 8칸에 오른쪽 정렬한 문자열을 만들고, 앞 공백을 0으로 바꿔 8자리 2진수로 만든다.
문제 12. 입력값의 의미를 지켜라¶
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Student code: ");
// 앞의 0도 학생 번호의 일부이므로 수가 아닌 문자열로 보존한다.
String code = sc.nextLine();
System.out.printf("Registered: [%s-A]%n", code);
}
}
int로 읽으면 00721은 수치값 721이 되어 앞의 0 정보가 사라진다. 값이 계산 대상이 아니라 식별 대상이면 String이 적절하다.