[C++]/[C++] 개념 모음
[C++] 함수 인자로 "string"을 전달할 때, 값 vs 포인터 vs 참조
노트포미
2024. 6. 4. 11:31
c++에서 함수 인자로 string을 전달하는 방법에는 세 가지가 있다
1. 값으로 전달
void valueFunc(string str);
[장점]
- 안전성 : 함수 내에서 원본 문자열을 수정할 수 없다. 따라서 원본 데이터가 보호된다.
- 간단함 : 함수 호출 시 특별한 문법이 필요하지 않아 가독성이 좋다.
[단점]
- 성능 문제 : 문자열을 복사해서 전달하므로, 문자열이 클 경우 성능 저하가 발생할 수 있다.
- 메모리 사용 : 원본 문자열의 복사본을 만들기 때문에 추가적인 메모리가 필요하다.
2. 포인터로 전달
void pointerFunc(string *str);
[장점]
- 유연성 : 함수 내에서 nullptr을 통해 인자가 전달되었는지 확인할 수 있다.
- 수정 가능성 : 함수 내에서 원본 문자열을 수정할 수 있다.
[단점]
- 안전성 : nullptr을 잘못 참조하면 런타임 오류가 발생할 수 있다.
- 사용의 복잡성 : 함수 호출 시 연산자를 사용해야 하므로 가독성이 떨어질 수 있다.
3. 참조로 전달
void referenceFunc(string &str);
[장점]
- 성능 : 원본 문자열을 수정할 수 있으며, 값으로 전달하는 것보다 성능이 우수하다. (복사가 일어나지 않음)
- 간단함 : 함수 호출 시 특별한 문법이 필요하지 않아 가독성이 좋다.
- 안전성 : nummptr을 사용할 수 없으므로 포인터에 비해 안전하다.
[단점]
- 수정 가능성 : 함수 내에서 원본 문자열을 수정할 수 있으므로, 원본 데이터가 변경될 수 있다.
- 명확성 부족 : 코드만 봐서는 함수 내에서 원본 문자열이 수정될지 여부를 알기 어렵다.
<복잡도 비교>
값으로 전달 | 포인터로 전달 | 참조로 전달 | |
시간 복잡도 | O(n) : 문자열의 길이에 따라 복사하는 시간이 증가한다. |
O(1) : 포인터를 전달하는 것은 주소 값을 복사하는 것이므로 일정한 시간 내에 수행된다. |
O(1) : 참조를 전달하는 것은 주소 값을 복사하는 것이므로 일정한 시간 내에 수행된다. |
공간 복잡도 | O(n) : 원본 문자열의 크기만큼 추가적인 메모리가 필요하다. |
O(1) : 포인터 자체는 4바이트 또는 8바이트(32비트 또는 64비트 시스템에 따라) 크기이다. |
O(1) : 참조 자체는 4바이트 또는 8바이트(32비트 또는 64비트 시스템에 따라) 크기이다. |
<결론>
- 값으로 전달
- 원본 데이터를 수정하지 않아야 해서, 복사본을 사용해야 할 때
- 전달하는 객체가 작을 때 (e.g int, char 같은 기본 타입이나 작은 클래스 객체)
- 함수가 전달받은 데이터를 읽기만 하고 수정하지 않을 때
- 예제 : 출력 함수, 읽기 전용 데이터 처리
- 포인터로 전달
- 인자가 전달되지 않을 수도 있는 경우, 함수 내에서 인자가 전달되었는지(nullptr인지) 확인할 필요가 있을 때
- 함수가 동적 메모리 할당을 수행하거나, 동적으로 메모리를 수정할 때
- NULL인 경우를 허용해야 할 때
- 예제 : 동적 메모리 관리, 선택적 인자 처리
- 참조로 전달
- 전달된 데이터(원본)를 수정해야 할 때
- 큰 객체를 전달해서 복사 비용을 피하고 싶을 때
- NULL을 허용하지 않을 때 (-> 안전성 높임)
- 함수가 데이터를 수정하지 않고 읽기만 해야 할 때 const참조를 사용하면, 원본 데이터의 복사를 피하면서 읽기 전용으로 사용할 수 있다.
- 예제 : 데이터 수정 함수, 성능 최적화
#예시코드
#include <iostream>
#include <string>
using namespace std;
//값으로 전달
void value_printString(string str){
cout << str << endl;
}
//포인터로 전달
void pointer_modifyString(string *str){
if(str){
*str = "Modified1";
}
}
//참조로 전달
void reference_modifyString(string &str){
str = "Modified2";
}
int main(){
string test = "Original";
//값
value_printString(test); //원본 데이터는 수정되지 않음
//포인터
pointer_modifyString(test); //원본 수정됨
cout << test << endl; //출력 : Modified1
//참조
reference_modifyString(test); //원본 수정됨
cout << test << endl //출력 : Modified2
return 0;
}