매개변수(parameter)는 함수를 호출할 때 외부에서 전달된 값을 함수 내부에서 사용하기 위해 정의하는 변수다.
매개변수는 함수 내부에서 선언되지는 않지만, 지역 범위(local scope)를 가지며 함수 호출 시 생성, 종료되면 소멸한다.
함수에 인수를 전달하는 방법에는 세 가지가 있다.
- 값에 의한 호출(Call by Value)
- 참조에 의한 호출(Call by Reference)
- 주소에 의한 호출(Call by Address)
Call by Value
'Call by Value 방식'은 함수 호출 시 전달하려는 변수의 복사본을 함수로 전달하는 방법이다. 이때 매개변수로 복사된 데이터는 함수 내부에서 독립된 메모리 공간을 차지하게 된다. 따라서 함수 내부에서 수정하더라도 원본 데이터에는 영향을 미치지 않는다.
[특징]
- 안전성 : 함수가 복사본을 사용하기 때문에 함수 내부의 연산이 호출자의 원본 데이터를 보호할 수 있다.
- 디버깅 용이 : 본 값이 변경되지 않아, 함수에서 오류가 발생하더라도 원본 값이 보존되어 문제 해결이 비교적 쉽다.
[제한사항]
- 메모리 소비 : 원본 데이터의 복사본을 생성하기 때문에, 데이터의 크기가 클 경우 메모리 사용향이 증가한다.
- 성능 저하 : 큰 객체나 배열 등의 복사본을 생성하고 전달하는 과정에서 오버헤드가 발생할 수 있다.
Call by Reference
Call by Reference 방식은 함수의 매개변수를 & 기호를 사용하여 선언해 전달하려는 값의 참조를 함수로 전달하는 방법이다. 전달된 변수는 함수 내에서 참조되며 원본 변수와 같은 메모리 공간을 공유한다. 따라서 함수 내부에서 참조 변수를 수정하면 원본 데이터를 직접 읽거나 수정할 수 있다.
[특징]
- 메모리 효율성 : 큰 객체나 구조체를 함수에 전달할 때 복사본을 생성하지않아 메모리와 CPU를 절약할 수 있다.
- 원본 데이터 수정 가능 : 함수 내에서 원본 데이터를 직접 수정할 수 있어 반환값 없이도 값을 변경할 수 있다.
[제한사항]
- 원본 데이터 보호 부족 : 함수가 원본 데이터를 직접 수정할 수 있어 의도치 않은 데이터 변경이 발생할 수 있다.
- 복잡성 증가 : 함수 호출에 따른 값의 변화를 예상하기 어렵게 만들어 코드 이해가 복잡해질 수 있다.
Call by Address
Call by Address는 함수에 데이터를 전달할 때 원본 데이터의 주소(address)를 전달하는 방식이다. 함수는 이 주소를 포인터 매개변수로 받아 원본 데이터가 위치한 메모리 주소를 가리킨다. 따라서 함수 내부에서 역참조(*pointer)를 통해 이 주소에 접근하면 원본 데이터를 직접 읽거나 수정할 수 있다.
[특징]
- 메모리 효율성 : 큰 객체나 구조체를 함수에 전달할 때 복사본을 생성하지않아 메모리와 CPU를 절약할 수 있다.
- 원본 데이터 수정 가능 : 함수 내에서 원본 데이터를 직접 수정할 수 있어 반환값 없이도 값을 변경할 수 있다.
- 동적 메모리 관리에 가능 : 주소를 전달받기 때문에 함수 내부에서 메모리 할당이나 해제 작업이 가능하다.
[제한사항]
- 잘못된 메모리 접근 위험 : 포인터가 유효하지 않은 주소를 참조할 경우, 프로그램이 예기치 않게 종료되거나
원하지 않는 동작이 발생할 수 있다. - 복잡성 증가 : 포인터는 코드의 복잡성을 높이며, 특히 메모리 관리에 더욱 신경써야 한다.
잘못 관리할 경우 메모리가 해제된 후에도 포인터가 해당 위치를 참조하는 "댕글링 포인터",
해제되지 않은 메모리로 인해 발생하는 "메모리 누수"와 같은 버그가 발생할 수 있다.
어떤 상황에 어떤 방식을 사용해야 하는가?
Call by value : 작은 크기의 데이터 타입(int, float 등)이나 원본 데이터 보호가 중요한 경우
Call by reference : 여러 값을 반환해야 하거나 대규모 데이터를 다룰 때 유용
Call by adress : 동적 메모리 할당이 필요한 경우나, 원본 데이터 수정이 필요한 경우
'C++' 카테고리의 다른 글
| [C/C++] Value Category (lvalue, rvalue) (0) | 2024.11.08 |
|---|