본문 바로가기
프로그래밍/C++

[정리] C++ 함수와 배열

by Nessie! 2022. 12. 2.

어떤 원소들의 합을 구하려는 함수를 만들고 싶다면, 우선 int형을 return 시키는 함수를 생성해야한다.

또한 어떤 배열인지 함수에게 전달을 해줘야 하기 때문에 배열 이름을 매개변수로 전달해주어야 한다. 그리고 배열의 크기도 함께 전달해야한다.

 

따라서 함수의 선언은 아래와 같이 할 수 있다.

int sum_arr (int arr[], int n);

 

여기서 arr은 배열의 이름, n은 배열의 크기를 넘겨주면 된다.

여기서 arr[]은 배열처럼 보이지만 실제로는 포인터다. 물론 arr은 배열처럼 사용할 수 있따.

 

그렇게 처리하는 것이 가능한 이유는 배열 이름은 포인터처럼 사용할 수 있고, 배열 이름은 그 배열의 첫 번째 원소의 주소로 인식한다. 

 

int array[30];

int sum = sum_arr(array, 30);

 

여기서 넘겨지는 array는 array 배열의 이름이다. 즉, array의 첫 번째 원소의 주소가 넘어간다.

따라서 sum_arr() 함수는 주소를 전달 받게 된다. 넘겨주는 배열은 int형 배열이므로, int* 형이라고도 볼 수 있다.

즉 int sum_arr(int* arr, int n); 이랑 int sum_arr (int arr[], int n); 이랑 같다.

 

같다곤 해도 함수 몸체에서는 int tip[] 이런식으로 작성하고 포인터처럼 쓰는 것은 불가능하다.

 

array배열에 sizeof 함수를 적용해 크기를 출력하는 것과, sum_arr에서 arr 배열에 sizeof 함수를 이용해 출력을 하면, 서로 같은 주소를 가리키고 있음에도 불구하고 다른 결과값이 출력된다.

그 이유는 array배열에 sizeof 함수를 적용하면 array 배열의 크기를 구해주지만, 매개변수로 넘겨받은 arr은 포인터 변수의 크기를 의미하기 때문에 포인터 변수의 크기만큼만 출력이 되기 때문이다.

 

sum_arr 함수는 함수의 크기를 명시해주기 때문에, 실제 배열의 크기는 30이지만, 3을 넘겨서 첫 번째부터 세 번째 원소까지만 합을 구하는 식으로 함수를 속여서 사용할 수도 있다. 또한 배열의 이름에 필요한 만큼 더해 시작 위치를 속여 전달하는 것 또한 가능하다.

int array[30]; //이런게 있을때

int sum = sum_arr(array, 3);  //이렇게 넘겨도 된다.
int sum = sum_arr(array + 4, 3);  //이렇게 넘기면 다섯 번째 원소부터 일곱 번째 원소까지있다고 알려주는 셈이다.

배열을 처리하는 함수에게 배열의 종류오 배열 원소의 개수를 알려 주려면, 두 개의 서로 독립된 매개변수를 넘겨주어야 한다.

void fillArray(int arr[], int size); //가능
void fillArray(int arr[size]);  //불가능

 

원래 함수에 일반 변수를 전달하면 복사본을 가지고 작업을 하는데, 배열은 주소를 넘기는 것이기 때문에 원본 데이터를 가지고 작업한다고 볼 수 있다. 따라서 작업 시 주의가 필요하다.

배열의 주소를 매개변수로 사용하는 것은 전체 배열을 복사하는 것보다 시간과 메모리를 절약한다. 복사본을 가지고 작업하면 메모리를 많이 요구할 뿐만 아니라 큰 데이터 블록을 복사해야 하므로 시간도 오래걸린다. 

반면 원본을 대상으로 작업하면 위의 문제점이 해결되지만 부주의에 의해 데이터가 손상될 위험이 있다.

 

이럴때 const 키워드를 이용하면 원본 데이터가 손상되는 것을 방지할 수 있다.

 

함수 선언 시 매개변수에 const 키워드를 추가하여 사용하면 된다.

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

이 선언은 포인터 arr이 상수 데이터를 지시하고 있다는 것을 의미하며, arr를 사용해서는 그 데이터를 변경할 수 없다는 것을 뜻한다. (즉 const 키워드를 붙임으로 써 arr은 상수화되어 변경할 수 없게 하겠다 라는 의미, 쉽게 말하면 읽기전용이라고 볼 수 있다.)

 

이 제한을 어기고 값을 변경하려고 시도한다면 컴파일러가 오류를 출력하고 컴파일을 중단한다.

 

따라서 값을 변경하지 않고 안전하게 읽기만 하는 함수를 사용하고 싶다면 const 키워드를 잘 사용하면 된다.

댓글