나만의 개발노트

[C++] 함수 인자로 "string"을 전달할 때, 값 vs 포인터 vs 참조 본문

[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비트 시스템에 따라) 크기이다.

<결론>

  1. 으로 전달
    • 원본 데이터를 수정하지 않아야 해서, 복사본을 사용해야 할 때
    • 전달하는 객체가 작을 때 (e.g int, char 같은 기본 타입이나 작은 클래스 객체)
    • 함수가 전달받은 데이터를 읽기만 하고 수정하지 않을 때
    • 예제 : 출력 함수, 읽기 전용 데이터 처리

 

  1. 포인터로 전달
    • 인자가 전달되지 않을 수도 있는 경우, 함수 내에서 인자가 전달되었는지(nullptr인지) 확인할 필요가 있을 때
    • 함수가 동적 메모리 할당을 수행하거나, 동적으로 메모리를 수정할 때
    • NULL인 경우를 허용해야 할 때
    • 예제 : 동적 메모리 관리, 선택적 인자 처리
  2. 참조로 전달
    • 전달된 데이터(원본)를 수정해야 할 때
    • 큰 객체를 전달해서 복사 비용을 피하고 싶을 때
    • 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;
}

'[C++] > [C++] 개념 모음' 카테고리의 다른 글

[C++] 함수 인자로 "배열"을 전달할 때, 포인터 vs 참조 방법  (0) 2024.06.04
[C] <stdio.h>  (0) 2024.05.21
[C] <string.h>  (0) 2024.05.21
[C++] vector::assign  (0) 2024.05.18
[C++] vector<T>  (0) 2024.05.17