프로그래밍 언어에서 함수 호출 방식은 중요한 개념 중 하나입니다. 각 언어마다 함수 호출 시 변수의 전달 방식이 다르기 때문에 이를 이해하고 정확히 사용하는 것이 필요합니다. 이번 포스트에서는 Python, C, C++, Java에서 함수 호출 방식이 어떻게 다르고, 실제 코드에서는 어떻게 동작하는지 알아보겠습니다.
1. Python: Call by Object Reference
Python에서는 함수에 변수를 전달할 때 객체의 참조가 전달됩니다. 이는 "Call by Object Reference" 또는 "Call by Assignment"라고 불립니다.
- 변경 가능한 객체 (mutable objects)와 변경 불가능한 객체 (immutable objects)에 따라 동작이 다릅니다.
변경 가능한 객체 예시
def modify_list(lst):
lst.append(10)
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # 출력: [1, 2, 3, 10]
리스트(my_list)는 함수 내에서 수정되었고, 원본 리스트도 변경된 것을 확인할 수 있습니다.
변경 불가능한 객체 예시
def modify_number(num):
num += 10
my_number = 5
modify_number(my_number)
print(my_number) # 출력: 5
파이썬에서 정수(my_number)는 불변 객체이기 때문에 함수 내에서의 변경이 원본에 영향을 주지 않습니다.
2. C: Call by Value와 포인터 사용
C에서는 기본적으로 값에 의한 호출 (Call by Value)을 사용하지만, 포인터를 통해 마치 참조를 전달하는 것처럼 구현할 수 있습니다.
값에 의한 호출 예시
#include <stdio.h>
void modify(int x) {
x += 10;
}
int main() {
int num = 5;
modify(num);
printf("%d\n", num); // 출력: 5
return 0;
}
num의 값이 함수 내에서 변경되었지만, 원본 num에는 영향을 미치지 않습니다.
포인터를 사용한 참조 예시
#include <stdio.h>
void modify(int *x) {
*x += 10;
}
int main() {
int num = 5;
modify(&num);
printf("%d\n", num); // 출력: 15
return 0;
}
포인터를 사용하여 변수의 주소를 전달하면, 함수 내에서 원본 변수를 수정할 수 있습니다.
3. C++: 다양한 호출 방식
C++에서는 값에 의한 호출 (Call by Value), 참조에 의한 호출 (Call by Reference), 그리고 포인터를 모두 지원합니다.
값에 의한 호출 예시
void modify(int x) {
x += 10;
}
int main() {
int num = 5;
modify(num);
std::cout << num; // 출력: 5
}
변수 num의 값이 복사되어 전달되므로, 함수 내에서의 변경이 원본에 영향을 주지 않습니다.
참조에 의한 호출 예시
void modify(int &x) {
x += 10;
}
int main() {
int num = 5;
modify(num);
std::cout << num; // 출력: 15
}
참조를 사용하여 함수에 전달된 변수의 값을 직접 수정할 수 있습니다.
포인터를 사용한 호출 예시
void modify(int *x) {
*x += 10;
}
int main() {
int num = 5;
modify(&num);
std::cout << num; // 출력: 15
}
포인터를 사용해 변수의 주소를 전달함으로써, 함수 내에서 원본 변수를 수정할 수 있습니다.
4. Java: Call by Value
Java에서는 모든 인자가 값에 의한 호출 (Call by Value)로 전달됩니다. 하지만 객체 참조의 경우 참조 값이 전달되므로, 객체의 상태를 변경할 수 있습니다.
기본 자료형 예시
public class Main {
public static void modify(int x) {
x += 10;
}
public static void main(String[] args) {
int num = 5;
modify(num);
System.out.println(num); // 출력: 5
}
}
기본 자료형은 값이 복사되어 전달되므로 함수 내에서 변경해도 원본에 영향을 미치지 않습니다.
객체 참조 예시
public class Main {
public static void modify(StringBuilder str) {
str.append(" World");
}
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
modify(sb);
System.out.println(sb); // 출력: Hello World
}
}
객체 참조가 값으로 전달되어, 함수 내에서 객체의 상태를 변경할 수 있습니다.
결론
언어마다 함수 호출 방식이 다르며, 각 언어의 특성에 맞게 코드를 작성하는 것이 중요합니다. Python은 객체 참조 전달, C는 값에 의한 호출과 포인터, C++은 다양한 호출 방식, 그리고 Java는 값에 의한 호출만을 지원합니다. 이 차이를 잘 이해하고 적절히 활용하여 코드를 작성하면 더 효율적이고 오류가 적은 프로그램을 만들 수 있습니다.
'컴퓨터 과학 > 프로그래밍 언어 개념' 카테고리의 다른 글
프로그래밍 언어 개념 Chapter 2.1 :: 언어의 변천 (0) | 2023.09.27 |
---|---|
프로그래밍 언어 개념 Chapter 1.1 :: 프로그래밍 언어 소개 (0) | 2023.09.11 |