함수 const 배열 매개변수 사용 – C++ 자습서 34

함수 const 배열 매개변수

const는 상수를 만드는 키워드 입니다. 정확히는 변수를 상수화 하는 키워드입니다. const 개념은 변수와 포인터에서 다루는 내용으로 이 포스팅은 함수에서의 적용을 알아보겠습니다.

const 키워드와 포인터

아래의 예제는 const 포인터를 선언합니다. 원래 변수인 var 는 변경가능하지만 포인터인 *ptr 의 값은 변경이 불가능합니다.

#include<iostream>

    using std::cout;
    using std::endl;

int main()
{
    int var = 15;
    const int *ptr = &var;


    cout << *ptr << endl;

    // *ptr 은 변경불가 
    // *ptr = 20;

    // var는 변경불가
    var = 33;

    cout << *ptr << endl;

    return 0;
}

[실행결과]
15
33

이것을 배열을 함수의 매개변수로 넘길 때 적용하는 이유가 있습니다. 배열을 함수에게 전달하면 원본의 주소가 전달됩니다. (함수 배열 매개변수) 에 설명해 놓았습니다. 약간은 tricky 한데 결론적으로 배열은 포인터와 유사하게 동작합니다. ‘배열 = 포인터’ 는 아니지만 내부의 동작이 비슷해서 개념을 잡는 것이 조금 혼란스럽습니다. 함수의 원형이 void sumArray(int array[]) 라고 한다면 void sumArray(int * array) 로도 사용 가능한 이유는 배열의 메모리 주소를 받기 때문입니다.

const 배열 매개변수

현재는 C++에서 프로그램을 만들 때는 배열보다는 STL Container 의 vector 가 권장됩니다. 배열은 다소 원초적이고 제어가 힘듭니다. 하지만 레가시 코드 중에 배열을 많이 사용하고 있고 또 C++ 의 원리를 정확하게 이해하기 위해서 배열을 학습하는 것 입니다.

언매니지드 언어인 C++ 자체가 어렵고 사용이 힘들다는 것은 모두가 인정하는 사실입니다. 이 포스팅을 쓸 때 일부 참고하는 Stephen Prata 의 C++ 기초플러스에서도 포인터의 어려움에 대해서 지적하고 있습니다.

const 를 함수의 매개변수로 사용하는 핵심은 배열을 읽기 전용 모드로 사용하기 위해서 입니다. 정확히는 배열의 원본 내용을 수정하는 것을 막기 위해서 입니다. 아래 예제의 함수 원형에 const int arr[] 은 const int * arr 과 같은 표현입니다. 포인터로 매개변수는 값에 직접 접근이 가능하므로 변경할 수도 있습니다. 하나의 배열을 여러 함수에서 사용하다 보면 의도치 않게 배열의 값을 수정하는 일도 생길 수 있는데 const 로 제한을 걸어 놓으면 이를 방지할 수 있습니다.

코드를 읽을 때 const 키워드가 붙어있으면 배열의 값에 수정을 하지 않았다는 것을 알 수 있기 때문에 디버깅이 수월해집니다. 그래서 값의 변경이 필요 없으면 const 키워드를 매개변수에 붙이는 것은 좋은 습관입니다. C++의 객체 지향 프로그래밍에서는 자체적으로 접근제어를 하지만 여기서 보는 것은 순수한 함수에 작성에 관한 내용입니다.

#include<iostream>
#include<random>

#define SIZE 5

void showSumArr(const int arr[], int n);

using std::cout;
using std::endl;
using std::cin;

// random 숫자 생성을 위해 사용
using std::random_device;
using std::mt19937;

int main()
{
    const int constArray[SIZE] = {1,3,5,7,9};
    int myArray[SIZE];

    random_device rd;
    mt19937 gen(rd());

    for (int i = 0; i < SIZE; i++)
    {
        myArray[i] = gen()%100;
    }
    
    showSumArr(constArray, SIZE);
    showSumArr(myArray, SIZE);
    
    return 0;
}

void showSumArr(const int arr[], int count)
{
    int total = 0;

    for (int i = 0; i < count; i++)
    {
        total += arr[i];
    }

    cout << "-> the sum of the array is " << total << endl;
}

이 예제에서는 const 를 사용하는 또 한가지 장점을 보여줍니다. const 키워드가 붙은 함수는 일반 배열과 const 배열을 둘 다 받아서 사용할 수 있습니다. 함수 안에서 배열의 값에 대한 변경은 어쨋든 불가능하기 때문에 뭐를 받건 값만 바꾸지 않으면 됩니다.

좀 더 제한을 하면 const int arr[] 을 const int * const arr 처럼 포인터 자체도 상수로 만들 수 있는데 함수에 어느 정도의 제한을 가할 것인가는 설계에 적합하도록 결정될 부분입니다.

요약

조금은 어려운 const 의 함수 매개변수 사용에 대해서 알아봤습니다. const 는 변수를 상수로 만들 때 사용하고 포인터 변수에 사용하는 방식으로 함수에 배열을 매개변수로 전달할 때 사용합니다. 배열의 원본에 접근을 제한하고 읽기 모드로 사용할 수 있도록 하여 함수 작성 시 프로그램의 안정성을 위해 권장합니다.

말이 어렵지만 배열의 데이터를 보호하기 위해 필요한 부분으로 이해하고 직접 코드를 작성해서 연습하는 것이 도움이 됩니다.

참고문서

배열 C++ 함수에 배열전달 MicroSoft

C++ 랜덤 <random> MicroSoft

Leave a Comment