함수 배열 매개변수 C++ 자습서 33

함수 배열 매개변수 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)

Leave a Comment