드디어 내일이면 주말이라는 생각에 한시름 놓게 되지만 이 포스터에 주말동안은 유튜브 영상 정리든 문제풀이든 최소 하나씩을 올린다고 선언해 놓고 포스팅하겠다.
오늘 배운 것은 자료형(type)과 전위연산자, 후위연산자의 차이, 실수를 연산할 때 생기는 (부동소수점) 문제점, 배열과 문제 풀이였다.
- 자료형(type)
- 기본형
- 참조형
두가지로 나뉘게 된다.
일단은 기본형이다. 자바에서 기본으로 제공하는 변수 저장소, 그래서 기본형 타입이고 사진으로 쉽게 정리한 것을 보면 이렇다.
기본형 타입을 코드로 살펴보면
// 논리계열
boolean b = true; // or false
// 문자계열(사실 숫자가 저장됨, 왜냐하면 문자는 사실 숫자이다.)
char c = 'a'; // 'a' 는 사실 97 이다.
// 정수계열
byte bt = 1;
short s = 2;
int i = 3;
long l = 4L; // 자동형변환에 의해서 4라고 써도 됨
// 실수계열
float f = 5.5f;
double d = 5.5;
기본형은 변수 선언을 하면 실제 값을 변수에 저장한다. (스택에 쌓아둔다)
참조형은 작동방식이 조금 다르다. 참조형에 변수 선언을 하면 메모리(RAM)의 주소 값을 저장한다. 우리가 출력하거나 코드를 작성하면 그 주소 값을 통해서 주소안에 저장되어있는 객체를 사용하는 방식으로 작동한다.
메모리의 주소 값은 힙(Heap)이라는 공간과 연결하고 거기 존재하는 객체를 스택(Stack)으로 불러와서 사용하게 된다.
// 아래 기본형 변수들은 실제로 숫자를 가지고 있다.
boolean b = true;
char c = 'a'
byte bt = 1;
short s = 2;
int i = 3;
long l = 4L;
float f = 5.5f;
double d = 5.5;
// 기본형 변수 8종을 제외한 모든 변수는 참조형 변수이다.
// 참조형 변수에는 실체가 없다. 실체는 외부에 저장된다.
// 참조형 변수에는 실체를 조종할 수 있는 리모콘이 저장된다.
// 자바에서 리모콘의 크기는 모드 같다.
// 그래서 모든 참조형 변수의 크기는 8바이트 이다.(JVM 마다 다름, 딱히 중요하지 않음)
String str;
str = "안녕" + "하세요.";
// 엄밀히 말하면 str 에는 "안녕하세요." 가 들어있지 않다.
// str 에는 "안녕하세요." 라는 문자열 객체를 조종할 수 있는 리모콘이 들어있다.
String s1 = "하하";
String s2 = "하하하하하하하";
// s1과 s2의 크기는 같다.
// s1과 s2가 각각 가리키는 객체들은 서로 크기가 다르다.
- 전위연산자와 후위연산자
```java - +i; //전위연산자
i++; //후위연산자우리가 여태 작성한 코드중에 이런 형태를 몇번 접했었는데 이게 사칙연산의 위치에 따라서 전위연산 후위연산으로 구분해서 부른다.
전위에 있냐 후위에 있냐의 차이로 값을 먼저 더하는지 뒤에 더하는지 정해진다.
사진으로 보면 조금 더 이해가 쉽다. 연산자의 위치를 잘못두면 생각했던 값이 안나올 수도 있으니 주의해야한다.
- 부동소수점
강사님이 부동소수점 자체는 자세하게 알 필요가 없다고 하셨다. java든 컴퓨터 언어로 실수를 계산할 때 생길 수 있는 문제중 하나라고 주의 하라고 하셨다. 컴퓨터는 이진수를 사용하는데, 그 이진수 때문에 생기는 문제라고 하셨다.
위의 사진과 같이 부등호의 영역, 지수의 영역, 가수의 영역이 차례로 나뉘는데, 소수점으로 넘어가면서 이진법때문에 그 0과 1의 개수가 23비트를 넘어가면서 문제가 발생한다고 한다.
- 배열
여기서 조금 애를 먹었다. 배열 자체를 이해하지 못한게 아니고 그냥 문제 풀이에서 이상한 곳에서 막혔다..
쓸데 없는 말은 치우고 일단 배열에 대해서 알아보자.
int[] array = new int[];
이 형태가 배열을 불러오는 코드이고, 자료형은 참조형이다. 참조형이니 당연히 위의 참조형 방식대로 작동한다.
내가 풀었던 문제는 코드업의 기초문제풀이 - 1094 (이상한 출석번호 부르기 2)였고 문제는 이렇다.
//정보 선생님은 수업을 시작하기 전에 이상한 출석을 부른다.
//
//선생님은 출석부를 보고 번호를 부르는데,
//학생들의 얼굴과 이름을 빨리 익히기 위해 번호를 무작위(랜덤)으로 부른다.
//
//그리고 얼굴과 이름이 잘 기억되지 않는 학생들은 번호를 여러 번 불러
//이름과 얼굴을 빨리 익히려고 하는 것이다.
//
// 출석 번호를 n번 무작위로 불렀을 때, 각 번호(1 ~ 23)가 불린 횟수를 각각 출력해보자.
import java.util.Scanner;
class Main {
public static void main(String[] args) {
int n, i;
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int[] arr = new int[n];
for(i = 0; i <= n; i++){
arr[i] = sc.nextInt();
}
for(i = n - 1; i >= 0; i--){
System.out.printf("%d", arr[i]);
}
}
}
우선 정답은 위의 코드고 내가 문제를 겪은 부분은 배열 때문인데,
int[] arr = new int[n]; //배열 선언과 배열의 int 값에 입력 값 n번만큼 객체를 생성하겠다는 코드이다.
이게 왜 문제가 됐냐면, 배열의 규칙 때문이다.
int[] arr = new int[3]; // 배열을 선언했고 객체를 세개 생성한다는 뜻이다.
// 그럼 Heap 구역에 int 값을 저장할 수 있는 객체가 3개가 생성이 되는데.
// 순서가 1부터가 아니고 0부터 생성이 된다. 이게 java의 절대 규칙인데 내가 이 사실을 몰랐다.
// Ex int[] arr = new int[3];에 생성된 객체
int [0]
int [1]
int [2] // 이렇게 세개가 생성되는 것.
내가 저지른 실수를 코드로 위의 코드와 비교해보자.
int n, i;
Scanner sc = new Scanner(System.in);
n = sc.nextInt(); // n에 변수 입력을 하면
int[] arr = new int[n]; // 입력값만큼 객체 생성하도록 코드를 짰다.
for(i = 1; i <= n; i++){ // 여기서부터 문제가 발생하는데 배열은 0부터 시작이다. 근데 i의 값이 벌써 1이다.
arr[i] = sc.nextInt();
}
for(i = n; i >= 1; i--){ //여기도 마찬가지 배열의 값에 3이 들어간다면 0, 1, 2 객체가 생성이 되니 n - 1을 해줘야
// index 범위안에 존속하게 된다.
System.out.printf("%d", arr[i]);
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
at org.example.Main.main(Main.java:22)
변수 설정 하나 잘못해서 이런 오류가 계속 생겼고 나는 배열의 규칙을 제대로 파악하기 전까지 이 문제를 계속 해결하지 못했다.
그래도 구글링의 힘으로 어찌저찌 해결했고.. 해결하니까 되게 후련했다. 이 맛에 문제를 푸는구나 싶었고 엄청 별 것 아닌 문제로 혼자 계속 고민하던게 좀 바보 같다고 느껴지기도 했다.
아무래도 재미를 붙힐 수 있을 것 같다. 아직 배우고 있는게 언어에서 걸음마조차 안될지도 모르지만 나는 어찌됐던간에 시작했다. 부디 끝까지 잘 해내는 나의 모습을 보고 싶다.
'Coding History' 카테고리의 다른 글
국비 지원 IT(웹앱개발) 취업반 강의 6일차 (0) | 2024.06.04 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 5일차 (2) | 2024.06.03 |
국비 지원 IT(웹앱개발) 취업반 강의 3일차 (0) | 2024.05.30 |
국비 지원 IT(웹앱개발) 취업반 강의 2일차 (0) | 2024.05.29 |
국비 지원 IT(웹앱개발) 취업반 강의 1일차 (0) | 2024.05.28 |