함수 배열 매개변수 C++
목차
함수에 배열을 매개변수로 사용하는 방법을 알아보겠습니다. 그전에 함수를 호출할 때 포인터를 사용하지 않으면 call by value 로 값에 의한 호출이 일어납니다. 값에 의한 호출에서는 원본 데이터의 값을 변경할 수 없습니다. 예를 들어 var 라는 변수를 값에 의한 호출을 했다면 함수의 내부에서 var의 값을 변경할 수 없습니다.
아래의 예제에서 main 함수에서 count 는 5이고 그 변수를 받아서 functionScope에서 count 를 3으로 변경했지만 함수의 호출이 끝난 후 main 함수에서는 여전히 5 입니다. 이는 count 는 이름이 같지만 다른 영역에 있기 때문입니다. main-count 와 functionScope-count 이렇게 별개의 변수로 보면 됩니다. 이것이 call by value 값에 의한 호출입니다.
#include<iostream> void functionScope(int); using std::cout; using std::cin; using std::endl; int main() { int count = 5; functionScope(count); cout << "main count : " << count << endl; return 0; } void functionScope(int count) { count = 3; for (int i = 0; i < count; i++) { cout << "i : " << i << endl; } cout << "functionScope count : " << count << endl; }
참조에 의한 호출에 대해서는 포인터에 관한 포스팅에서 좀 더 설명하기로 하고 함수의 매개변수로 배열을 사용하는 것을 알아보겠습니다.
매개변수로 배열을 사용하는 함수의 원형은 int function(int array[]) 처럼 [] 기호가 붙어 있습니다. 그런데 중요한 차이가 있습니다. 앞서 값에 의한 호출에서는 원본을 전달하지 않는다고 했는데 배열을 전달할 때는 원본을 전달합니다. 이것이 무슨 의미인지 혼동 스러울 수 있습니다. 아래의 예제를 보면 함수를 호출할 때 myArray라는 이름을 그대로 전달합니다. 이것이 무엇을 의미하는지 배열의 사용법을 조금 알아야 하는데요.
배열의 사용법은 조금 아래 보기로 하고 예제를 알아보겠습니다. 배열이 함수에 전달되면 원본의 주소가 전달됩니다. 배열 myArray는 실제로는 &myArray[0] 와 같습니다. 첫번째 배열 요소의 주소입니다. 그래서 배열을 전달하면 원본을 변경할 수 있습니다. 아래의 예제는 배열을 받는 매개변수의 이름은 다르지만 배열을 복사하는게 아니라 참조를 사용하는 것 입니다. (정확히는 주소를 전달하는 형태)
*참고 : 함수의 원형에서 (int array[]) 와 (int *array) 는 같은 의미입니다. 주소를 넘겨 주므로 포인터가 받는 것과 같습니다.
#include<iostream> #define SIZE 7 int sumArray(int array[], int n); double averageArray(int array[], int n); using std::cout; using std::endl; int main() { int myArray[SIZE] = {15,9,29,51,13,25,17}; // 합계 int sum = sumArray(myArray, SIZE); cout << "- sum of array : " << sum << endl; // 평균 double average = averageArray(myArray, SIZE); cout << "- average of array : " << average << endl; return 0; } int sumArray(int array[], int n) { int result = 0; for (int i = 0; i < n; i++) { result += array[i]; } return result; } double averageArray(int array[], int n) { double result = 0.0; for (int i = 0; i < n; i++) { result += array[i]; } return result/n; } [실행결과] - sum of array : 159 - average of array : 22.7143
배열을 전달하면 무엇이 전달되는지는 다음의 예제를 통해 알 수 있습니다. 다소 테크닉 적인 부분입니다만, 실행결과를 보면 배열의 0번째 요소의 주소와 myArray 이름이 같다는 것을 알 수 있습니다. 처음 보면 좀 이해가 안가는데 이것이 C++의 방식입니다.
#include<iostream> using std::cout; using std::cin; using std::endl; int main() { int myArray[3] = {11,33,55}; for (int i = 0; i < 3; i++) { cout << "myArray[" << i << "] = " << myArray[i] << " : " << &myArray[i] << endl; } cout << "-> myArray : " << myArray << " : " << &myArray << endl; for (int i = 0; i < 3; i++) { cout << "(myArray+" << i << ") = " << *(myArray+i) << " : " << (myArray+i) << endl; } return 0; } [실행결과] myArray[0] = 11 : 0x7ffc44fa59dc myArray[1] = 33 : 0x7ffc44fa59e0 myArray[2] = 55 : 0x7ffc44fa59e4 -> myArray : 0x7ffc44fa59dc : 0x7ffc44fa59dc (myArray+0) = 11 : 0x7ffc44fa59dc (myArray+1) = 33 : 0x7ffc44fa59e0 (myArray+2) = 55 : 0x7ffc44fa59e4
다음은 배열을 매개변수로 전달하여 원본을 바꾸는 예제입니다. 함수에게 전달하여 배열의 값을 입력받고 함수를 빠져나온 후 main 함수에서 확인해보면 바뀌어 있습니다.
#include<iostream> #define SIZE 5 void changeArray(int arr[], int n); using std::cout; using std::endl; using std::cin; int main() { int myArray[SIZE] = {0,}; changeArray(myArray, SIZE); for (int i = 0; i < SIZE; i++) { cout << "myArray[" << i << "] = " << myArray[i] << endl; } return 0; } void changeArray(int arr[], int count) { count--; while(1) { cout << "숫자를 입력하시오 (" << count << ") 번 요소" << endl; cin >> arr[count]; count--; if(count < 0) break; } return; } [실행결과] 숫자를 입력하시오 (4) 번 요소 13 숫자를 입력하시오 (3) 번 요소 42 숫자를 입력하시오 (2) 번 요소 53 숫자를 입력하시오 (1) 번 요소 56 숫자를 입력하시오 (0) 번 요소 77 myArray[0] = 77 myArray[1] = 56 myArray[2] = 53 myArray[3] = 42 myArray[4] = 13
요약
C/C++ 의 어려움은 특히 문법이 많이 어렵습니다. 강의들을 잘 보면 딱히 이해가 안되는 개념은 별로 없을 겁니다. 하지만 문법의 테크닉은 좀 어렵게 느껴지기도 합니다. & * [ ] ( ) 이런 연산자에 따라 의미가 완전히 달라지기도 하고 또 같은 결과를 내기 위한 방법이 여러가지가 있어서 선택의 문제도 있습니다. 어떤 문법이 더 효율적인가? 100% 알기 쉽지가 않습니다. 특히 포인터나 참조 메모리 이런 부분에서 한계를 느끼기 쉬운데요. 연습을 많이 해서 어느 정도 한계를 극복할 필요가 있습니다. C++ 은 아쉽게도 쉽게 설명하는 방법들이 별로 없는 것 같습니다. 이런 부분을 인정하고 노력을 한다면 그 노력은 노오력이 아니라 언젠가 분명히 실력으로 보상받을 수 있을 겁니다. 물론 인내심과 시간이 조금 필요하겠지요.
참고문서
C 언어 코딩 도장: 64.1 배열 매개변수 사용하기 (dojang.io)