# Call by value์ Call by reference
์๋นํ ๊ธฐ๋ณธ์ ์ธ ์ง๋ฌธ์ด์ง๋ง, ํท๊ฐ๋ฆฌ๊ธฐ ์ฌ์ด ์ฃผ์ ๋ค.
# call by value
๊ฐ์ ์ํ ํธ์ถ
ํจ์๊ฐ ํธ์ถ๋ ๋, ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ์์์๋ ํจ์๋ฅผ ์ํ ๋ณ๋์ ์์๊ณต๊ฐ์ด ์์ฑ๋จ (์ข ๋ฃ ์ ํด๋น ๊ณต๊ฐ ์ฌ๋ผ์ง)
call by value ํธ์ถ ๋ฐฉ์์ ํจ์ ํธ์ถ ์ ์ ๋ฌ๋๋ ๋ณ์ ๊ฐ์ ๋ณต์ฌํด์ ํจ์ ์ธ์๋ก ์ ๋ฌํจ
์ด๋ ๋ณต์ฌ๋ ์ธ์๋ ํจ์ ์์์ ์ง์ญ์ ์ผ๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ local value ์์ฑ์ ๊ฐ์ง
๋ฐ๋ผ์, ํจ์ ์์์ ์ธ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋๋ผ๋, ์ธ๋ถ ๋ณ์ ๊ฐ์ ๋ณ๊ฒฝ์๋จ
# ์์
void func(int n) {
n = 20;
}
void main() {
int n = 10;
func(n);
printf("%d", n);
}
printf๋ก ์ถ๋ ฅ๋๋ ๊ฐ์ ๊ทธ๋๋ก 10์ด ์ถ๋ ฅ๋๋ค.
# call by reference
์ฐธ์กฐ์ ์ํ ํธ์ถ
call by reference ํธ์ถ ๋ฐฉ์์ ํจ์ ํธ์ถ ์ ์ธ์๋ก ์ ๋ฌ๋๋ ๋ณ์์ ๋ ํผ๋ฐ์ค๋ฅผ ์ ๋ฌํจ
๋ฐ๋ผ์ ํจ์ ์์์ ์ธ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด, ์๊ท๋จผํธ๋ก ์ ๋ฌ๋ ๊ฐ์ฒด์ ๊ฐ๋ ๋ณ๊ฒฝ๋จ
void func(int *n) {
*n = 20;
}
void main() {
int n = 10;
func(&n);
printf("%d", n);
}
printf๋ก ์ถ๋ ฅ๋๋ ๊ฐ์ 20์ด ๋๋ค.
# Java ํจ์ ํธ์ถ ๋ฐฉ์
์๋ฐ์ ๊ฒฝ์ฐ, ํจ์์ ์ ๋ฌ๋๋ ์ธ์์ ๋ฐ์ดํฐ ํ์
์ ๋ฐ๋ผ ํจ์ ํธ์ถ ๋ฐฉ์์ด ๋ฌ๋ผ์ง
primitive type(์์ ์๋ฃํ) : call by valueint, short, long, float, double, char, booleanreference type(์ฐธ์กฐ ์๋ฃํ) : call by referencearray, Class instance
์๋ฐ์ ๊ฒฝ์ฐ, ํญ์ call by value๋ก ๊ฐ์ ๋๊ธด๋ค.
C/C++์ ๊ฐ์ด ๋ณ์์ ์ฃผ์๊ฐ ์์ฒด๋ฅผ ๊ฐ์ ธ์ฌ ๋ฐฉ๋ฒ์ด ์์ผ๋ฉฐ, ์ด๋ฅผ ๋๊ธธ ์ ์๋ ๋ฐฉ๋ฒ ๋ํ ์์ง ์๋ค.
reference type(์ฐธ์กฐ ์๋ฃํ)์ ๋๊ธธ ์์๋ ํด๋น ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๋ณต์ฌํ์ฌ ์ด๋ฅผ ๊ฐ์ง๊ณ ์ฌ์ฉํ๋ค.
๋ฐ๋ผ์ ์๋ณธ ๊ฐ์ฒด์ ํ๋กํผํฐ๊น์ง๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋, ์๋ณธ ๊ฐ์ฒด ์์ฒด๋ฅผ ๋ณ๊ฒฝํ ์๋ ์๋ค.
์๋์ ์์ ์ฝ๋๋ฅผ ๋ด๋ณด์.
User a = new User("gyoogle"); // 1
foo(a);
public void foo(User b){ // 2
b = new User("jongnan"); // 3
}
/*
==========================================
// 1 : a์ User ๊ฐ์ฒด ์์ฑ ๋ฐ ํ ๋น(์๋ก ์์ฑ๋ ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์์)
a -----> User Object [name = "gyoogle"]
==========================================
// 2 : b๋ผ๋ ํ๋ผ๋ฏธํฐ์ a๊ฐ ๊ฐ์ง ์ฃผ์๊ฐ์ ๋ณต์ฌํ์ฌ ๊ฐ์ง
a -----> User Object [name = "gyoogle"]
โ
b -----------
==========================================
// 3 : ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์๋ก ์์ฑ๋ ์ฃผ์๊ฐ์ b๊ฐ ๊ฐ์ง๋ฉฐ a๋ ๊ทธ๋๋ก ์๋ณธ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํด
a -----> User Object [name = "gyoogle"]
b -----> User Object [name = "jongnan"]
*/
ํ๋ผ๋ฏธํฐ์ ๊ฐ์ฒด/๊ฐ์ ์ฃผ์๊ฐ์ ๋ณต์ฌํ์ฌ ๋๊ฒจ์ฃผ๋ ๋ฐฉ์์ ์ฌ์ฉํ๊ณ ์๋ Java๋ ์ฃผ์๊ฐ์ ๋๊ฒจ ์ฃผ์๊ฐ์ ์ ์ฅ๋์ด ์๋ ๊ฐ์ ์ฌ์ฉํ๋ call by reference๋ผ๊ณ ์คํดํ ์ ์๋ค.
์ด๋ C/C++์ Java์์ ๋ณ์๋ฅผ ํ ๋นํ๋ ๋ฐฉ์์ ๋ณด๋ฉด ์ ์ ์๋ค.
// c/c++
int a = 10;
int b = a;
cout << &a << ", " << &b << endl; // out: 0x7ffeefbff49c, 0x7ffeefbff498
a = 11;
cout << &a << endl; // out: 0x7ffeefbff49c
//java
int a = 10;
int b = a;
System.out.println(System.identityHashCode(a)); // out: 1627674070
System.out.println(System.identityHashCode(b)); // out: 1627674070
a = 11;
System.out.println(System.identityHashCode(a)); // out: 1360875712
C/C++์์๋ ์์ฑํ ๋ณ์๋ง๋ค ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋นํ๊ณ ์ด์ ๊ฐ์ ๋ฎ์ด์์ฐ๋ ํ์์ผ๋ก ๊ฐ์ ํ ๋นํ๋ค.
(*
ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ๊ฐ์ ์ฃผ์๊ฐ์ ๊ฐ๋ฆฌํฌ ์ ์๋๋ก ํ ์ ์๋ค.)
Java์์ ๋ํ ์์ฑํ ๋ณ์๋ง๋ค ์๋ก์ด ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ๋ ๊ฒ์ ๋ง์ฐฌ๊ฐ์ง์ง๋ง, ๊ทธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๊ฐ ์์ฒด๋ฅผ ์ ์ฅํ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ์ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋นํ๊ณ ์ด ์ฃผ์๊ฐ์ ์ ์ฅํ๋ ๊ฒ์ด๋ค.
์ด๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ํ๋ผ ์ ์๋ค.
C/C++ | Java
|
a -> [ 10 ] | a -> [ XXXX ] [ 10 ] -> XXXX(์์น)
b -> [ 10 ] | b -> [ XXXX ]
|
๊ฐ ๋ณ๊ฒฝ
a -> [ 11 ] | a -> [ YYYY ] [ 10 ] -> XXXX(์์น)
b -> [ 10 ] | b -> [ XXXX ] [ 11 ] -> YYYY(์์น)
b = a;
์ผ ๋ a์ ๊ฐ์ b์ ๊ฐ์ผ๋ก ๋ฎ์ด ์์ฐ๋ ๊ฒ์ ๊ฐ์ง๋ง, ์ค์ ๊ฐ์ ์ ์ฅํ๋ ๊ฒ๊ณผ ๊ฐ์ ์ฃผ์๊ฐ์ ์ ์ฅํ๋ ๊ฒ์ ์ฐจ์ด๊ฐ ์กด์ฌํ๋ค.
์ฆ, Java์์์ ๋ณ์๋ [ํ ๋น๋ ๊ฐ์ ์์น]๋ฅผ [๊ฐ]์ผ๋ก ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด๋ค.
C/C++์์๋ ์ฃผ์๊ฐ ์์ฒด๋ฅผ ์ธ์๋ก ๋๊ฒผ์ ๋ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด ์๋ก์ด ๊ฐ์ผ๋ก ๋ฎ์ด ์ฐ์ฌ ๊ธฐ์กด ๊ฐ์ด ๋ณ๊ฒฝ๋๊ณ , Java์์๋ ์ฃผ์๊ฐ์ด ๋ฎ์ด ์ฐ์ฌ์ง๋ฏ๋ก ์๋ณธ ๊ฐ์ ์ ํ ์ํฅ์ด ๊ฐ์ง ์๋ ๊ฒ์ด๋ค. (๊ฐ์ฒด์ ์์ฑ๊ฐ์ ์ ๊ทผํ์ฌ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ง์ ์ ๊ทผํ์ฌ ๋ณ๊ฒฝํ๋ ๊ฒ์ด๋ฏ๋ก ์ด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ณ์๋ค์์ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ค.)
๊ฐ์ฒด ์ ๊ทผํ์ฌ ์์ฑ๊ฐ ๋ณ๊ฒฝ
a : [ XXXX ] [ Object [prop : ~ ] ] -> XXXX(์์น)
b : [ XXXX ]
prop : ~ (์ด ๋ํ ๋ณ์์ด๋ฏ๋ก ์ด๋๊ฐ์ ~๊ฐ ์ ์ฅ๋์ด์๊ณ prop๋ ์ด์ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์๋ ์
)
prop : [ YYYY ] [ ~ ] -> YYYY(์์น)
a.prop = * (a๋ฅผ ํตํด prop๋ฅผ ๋ณ๊ฒฝ)
prop : [ ZZZZ ] [ ~ ] -> YYYY(์์น)
[ * ] -> ZZZZ
b -> Object์ ์ ๊ทผ -> prop ์ ๊ทผ -> ZZZZ
์์ ๊ฐ์ ์ด์ ๋ก Java์์ ์ธ์๋ก ๋๊ธธ ๋๋ ์ฃผ์๊ฐ์ด๋ ๊ฐ์ ๋ณต์ฌํ์ฌ ๋๊ธฐ๋ ๊ฒ์ด๋ฏ๋ก call by value๋ผ๊ณ ํ ์ ์๋ค.
์ถ์ฒ : Is Java โpass-by-referenceโ or โpass-by-valueโ? - Stack Overflow (opens new window)
# ์ ๋ฆฌ
Call by value์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ ๊ฐ์ ๋ณต์ฌํด์ ํจ์๋ก ์ ๋ฌํ๊ธฐ ๋๋ฌธ์ ์๋ณธ์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ค. ํ์ง๋ง ์ธ์๋ฅผ ๋๊ฒจ์ค ๋๋ง๋ค ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋นํด์ผํด์ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ๋ ์ก์๋จน๋๋ค.
Call by reference์ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ ํ ๋น ๋ฌธ์ ๋ ํด๊ฒฐํ์ง๋ง, ์๋ณธ ๊ฐ์ด ๋ณ๊ฒฝ๋ ์ ์๋ค๋ ์ํ์ด ์กด์ฌํ๋ค.