5 minute read

C++ 에서 배열을 인자로 받는 함수 작성

참조자를 사용하지 않는 경우, 어떠한 경우에도 배열은 인자로 넘어갈 시 pointer로 decay 됨

아래와 같이 parameter로 받는 배열의 크기가 3임을 명시했음에도 불구하고 포인터로 넘어가진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

void f(int b[3]) {
    std::cout << "b size: " << sizeof(b) << std::endl;
}
// void f(int b[]), void f(int *b) 로도 받을 수 있고, 결과는 모두 같다.

int main() {
    int a[3] = { 1, 2, 3 };
    std::cout << "a size: " << sizeof(a) << std::endl;
    f(a);
    return 0;
}
1
2
a size: 12
b size: 8

아래와 같이 reference 로 넘기면 완전하게 넘기는 것이 가능해진다.

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

void g(int (&c)[3]) {
    std::cout << "c size: " << sizeof(c) << std::endl;
}

int main() {
    int a[3] = { 1, 2, 3 };
    std::cout << "a size: " << sizeof(a) << std::endl;
    g(a);
    return 0;
}
1
2
a size: 12
c size: 12

추가적으로 배열을 넘길 때… 아래 방식은 모두 동일한 결과를 나타낸다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
using namespace std;

void pointertaker1(int *a, int *b, int size_a, int size_b)
{
    for (int i = 0; i < size_a; i++)
    {
        cout << a[i] << "\n";
        cout << flush;
    }
    for (int i = 0; i < size_b; i++)
    {
        cout << b[i] << "\n";
        cout << flush;
    }
}

void pointertaker2(int a[], int b[], int size_a, int size_b)
{
    for (int i = 0; i < size_a; i++)
    {
        cout << a[i] << "\n";
        cout << flush;
    }
    for (int i = 0; i < size_b; i++)
    {
        cout << b[i] << "\n";
        cout << flush;
    }
}

void pointertaker3(int a[4], int b[5], int size_a, int size_b)
{
    for (int i = 0; i < size_a; i++)
    {
        cout << a[i] << "\n";
        cout << flush;
    }
    for (int i = 0; i < size_b; i++)
    {
        cout << b[i] << "\n";
        cout << flush;
    }
}

int main()
{
    int a[4] = {1,3,5,7};
    int b[5] = {2,4,6,8,10};
    cout << "\npointer taker1" << endl;
    pointertaker1(a,b,sizeof(a)/sizeof(int), sizeof(b)/sizeof(int));
    cout << "\npointer taker2" << endl;
    pointertaker2(a,b,sizeof(a)/sizeof(int), sizeof(b)/sizeof(int));
    cout << "\npointer taker3" << endl;
    pointertaker3(a,b,sizeof(a)/sizeof(int), sizeof(b)/sizeof(int));
    return 0;
}

결과물

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
pointer taker1
1
3
5
7
2
4
6
8
10

pointer taker2
1
3
5
7
2
4
6
8
10

pointer taker3
1
3
5
7
2
4
6
8
10

pointertaker3 은 문서상 a와 b의 원소 갯수가 4와 5인 것을 알려줄 뿐, 컴파일 상에서는 아무런 영향도 없다. 심지어 넘겨주는 배열 원소 갯수와 달라도 컴파일이된다…! 즉, pointertaker3가 아래와 같아도 결과는 똑같다.

1
void pointertaker3(int a[40], int b[30], int size_a, int size_b)

Leave a comment