함수 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 는 변수를 상수로 만들 때 사용하고 포인터 변수에 사용하는 방식으로 함수에 배열을 매개변수로 전달할 때 사용합니다. 배열의 원본에 접근을 제한하고 읽기 모드로 사용할 수 있도록 하여 함수 작성 시 프로그램의 안정성을 위해 권장합니다.
말이 어렵지만 배열의 데이터를 보호하기 위해 필요한 부분으로 이해하고 직접 코드를 작성해서 연습하는 것이 도움이 됩니다.