알고리즘 문제풀이를 Java로 진행하다가 해결되지 않은 궁금증이 하나 생겨서 정리해 둡니다.
제가 C++로 알고리즘 문제풀이를 하던 당시에는 함수 (function)이 있었고, 이 함수가 필요로 하는 매개변수 (parameter)가 있었습니다.
이 매개변수는 단순한 int나 char형 값일 수도 있었지만, vector나 set이 넘어오는 경우도 있었습니다.
이 때 따로 포인터를 이용하여 call by reference로 지정해 주지 않는다면, 기본적으로 call by value로 매개변수를 받아서 수행하였습니다.
Java에서 비슷한 방식으로 문제를 접근하다 보니 이해되지 않는 상황을 마주하게 되었습니다.
비슷하게 메소드를 작성하고, 이를 C++에서와 같은 방식으로 사용하였는데, 매개변수가 배열일 때는 제가 기대한 것과 다른 결과가 나오는 것을 확인했습니다.
아래의 비교를 보시면 이해가 됩니다.
1. 메소드의 매개변수가 int형인 경우
위 내용을 보시면 이해하기에 어렵지 않으실 겁니다.
int형 변수 b는 3이라는 값을 가지고 있습니다.
add_three라는 메소드는 매개변수로 받은 값에 3을 더한 값을 반환합니다.
그래서 실행 결과 역시 예상 그대로 잘 나옵니다.
여기까지는 문제가 없습니다.
2. 메소드의 매개변수가 int형 배열인 경우
위 내용 역시 큰 차이가 없습니다.
차이점이 있다면 b가 int형 배열 {1, 2, 3, 4}가 되었고, add_three는 입력으로 받은 배열의 3번째 인덱스에 3을 더한 배열을 반환합니다.
input에는 직접 조작을 하지 않고, result라는 배열을 따로 만든 후에 값을 조작하였습니다.
출력으로는 add_three 사용 이전의 b, add_three 사용 이후의 b와 c를 차례로 출력합니다.
제가 기대하는 값은 {1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 7} 입니다.
실행 결과를 보시면, 기대와는 다르게 배열 b의 3번째 인덱스의 값 역시 바뀐 것을 확인할 수 있습니다.
관련 질문을 StackOverflow에도 업로드 하였습니다: https://stackoverflow.com/questions/70819989/using-an-array-as-the-parameter-for-a-method-in-java
제가 얻은 답입니다.
Java에서는 배열의 복사는 값의 복사가 아니라 레퍼런스의 복사로 이루어집니다.
int[] b = { 1, 2, 3, 4};
int[] c = b;
위와 같은 코드는 결국 c가 b의 값을 복사하는 것이 아니라, c와 b가 같은 레퍼런스를 가리키게 되는 것입니다.
이러니 제가 생각한대로 실행이 안될만 하네요.
이것을 제가 의도한 대로 (C++에서 쓰던대로) 구현하려면 아래와 같습니다.
class Main {
static int[] add_three(int[] input) {
int[] result = input;
result[3] += 3;
return result;
}
public static void main(String[] args) {
int[] b = {1, 2, 3, 4};
for (int i = 0; i < 4; i++) System.out.print(b[i] + " ");
System.out.println();
int[] c = new int[4];
for (int i = 0; i < 4; i++) {
c[i] = b[i];
}
c = add_three(c);
for (int i = 0; i < 4; i++) System.out.print(b[i] + " ");
System.out.println();
for (int i = 0; i < 4; i++) System.out.print(c[i] + " ");
System.out.println();
}
}
단순히 Java의 문법 뿐만 아니라, Java 자체에 대해서도 더 이해하고, call by value와 call by reference에 대해서도 한층 더 배울 수 있는 좋은 경우였습니다.
'개발 > 기타' 카테고리의 다른 글
[CS Study] 1. 디자인 패턴과 프로그래밍 패러다임 (1) (0) | 2022.07.24 |
---|---|
Windows WSL 환경에서 Homebrew 설치하기 (0) | 2022.02.16 |
IntelliJ 단축키 / 구문 정리 (0) | 2022.01.22 |
게임 프로그래밍 직군 면접을 준비한다면 (4) | 2021.07.22 |
[C++] 문자열 substr와 코딩 테스트에서의 활용 (2) | 2021.04.11 |
댓글