본문 바로가기

BackEnd/C

1차원 배열을 함수의 인자로 전달

반응형

1. 배열 전달의 기본 원리


함수를 호출하면서 값을 전달할때 배열을 통째로 전달할 수 없다. 즉 배열을 매개변수로 선언하는 


방법은 존재하지 않는다. 대신 배열의 주소 값을 전달한다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void ArrPrintf(int arg[]);
 
int main(void)
{
    int arr[3]={123};
    ArrPrintf(arr);
 
    return 0;
}
 
void ArrPrintf(int arg[])
{
    int i;
 
    for(i=0; i<3; i++)
        printf("%4d", arg[i]);
 
    printf("\n");
}
cs

1
   1   2   3
cs


6행에서 배열의 주소값을 전달하고 있다.


11행에서 배열의 주소값을 전달받는 매개변수의 선언방식을 보면 배열의 길이를 나타내는 숫자를 


생략한다. 이 선언은 배열의 주소 값 저장을 위한 4바이트 크기의 매개변수 선언이다. 


그리고 이 선언은 배열의 이름이 아님에도 불구하고 16행에서처럼 이 배개변수의 이름을 배열의 이


처럼 사용하여 배열 요소에 접근 하여 값의 참조가 허용된다. 그리고 아래에서 처럼 값의 변경도 


허용된다.



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
void IncreArrElm(int arg[]);
void ArrPrintf(int arg[]);
 
int main(void)
{
    int arr[3]={123};
    printf("*** 증가 이전 배열정보 출력 *** \n");
    ArrPrintf(arr);
 
    IncreArrElm(arr);
 
    printf("*** 증가 이후 배열정보 출력 *** \n");
    ArrPrintf(arr);
 
    return 0;
}
 
void IncreArrElm(int arg[])
{
    int i;
 
    for(i=0; i<3; i++)
        arg[i]=arg[i]+1;
}
 
void ArrPrintf(int arg[])
{
    int i;
 
    for(i=0; i<3; i++)
        printf("%4d", arg[i]);
 
    printf("\n");
}
cs


1
2
3
4
*** 증가 이전 배열정보 출력 ***
   1   2   3
*** 증가 이후 배열정보 출력 ***
   2   3   4
cs


23행에서 보면 인자로 전달받은 배열정보를 이용해서 배열 요소의 값을 1씩 증가시키고 있다.


이로써 함수로 전달된 배열의 주소값을 통해 배열에 직접 접근하여 값을 변경하는것이 가능하다.


2. 배열의 매개변수 선언에 const 키워드


변수의 이름 앞에 const를 붙이면 상수화 시키는 키워드인데, 전역변수,지역변수 뿐만 아니라 매개


변수 에도 붙일 수 있다. const를 붙이면 매개변수에 저장된 값의 변경은 불가능하다. 이는 코드의 


안정성을 높여준다.



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
void IncreArrElm(int arg[]);
void ArrPrintf(const int arg[]);
 
int main(void)
{
    int arr[3]={123};
    printf("*** 증가 이전 배열정보 출력 *** \n");
    ArrPrintf(arr);
 
    IncreArrElm(arr);
 
    printf("*** 증가 이후 배열정보 출력 *** \n");
    ArrPrintf(arr);
 
    return 0;
}
 
void IncreArrElm(int arg[])
{
    int i;
 
    for(i=0; i<3; i++)
        arg[i]=arg[i]+1;
}
 
void ArrPrintf(const int arg[])
{
    int i;
 
    for(i=0; i<3; i++)
        printf("%4d", arg[i]);
 
    // arg[i]=arg[i]+1;  // 실수로 삽입된 코드
 
    printf("\n");
}
cs


26행을 보면 arg가 const로 선언되었다. 이는 arg를 이용한 배열 값의 변경을 허용하지 않겠다는 것


다. 따라서 33행과 같은 실수를 범할 경우 컴파일러는 에러를 발생시키고, 안정성을 높여준다.


3. 배열의 길이 계산


1) 함수 안에서 배열의 길이 계산


앞서 말했지만 아래의 매개변수 int arg[ ] 는 배열의 이름이 아니다. 주소값 저장을 위한 4바이


트 크기의 변수이다. 따라서 반환 값은 배열의 크기가 아닌 변수의 크기인 4가 된다. 따라서 함


수 안에서 인자로 전달된 배열의 주소값만 가지고 배열의 길이를 계산하는 방법은 없다.




2 ) 함수 밖에서 배열의 길이 계산


그래서 아래와 같이 함수의 인자로 배열의 길이도 미리계산해서 더불어 전달해야 한다.




아래 코드의 예시를 봐보자


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
void IncreArrElm(int arg[], const int len);
void ArrPrintf(const int arg[], const int len);
 
int main(void)
{
    int arr1[3]={123};
    int arr2[5]={12345};
 
    printf("*** 증가 이전 배열정보 출력 *** \n");
    ArrPrintf(arr1, sizeof(arr1)/sizeof(int));
    ArrPrintf(arr2, sizeof(arr2)/sizeof(int));
 
    IncreArrElm(arr1, sizeof(arr1)/sizeof(int));
    IncreArrElm(arr2, sizeof(arr2)/sizeof(int));
 
    printf("*** 증가 이후 배열정보 출력 *** \n");
    ArrPrintf(arr1, sizeof(arr1)/sizeof(int));
    ArrPrintf(arr2, sizeof(arr2)/sizeof(int));
 
    return 0;
}
 
void IncreArrElm(int arg[], const int len)
{
    int i;
 
    for(i=0; i<len; i++)
        arg[i]=arg[i]+1;
}
 
void ArrPrintf(const int arg[], const int len)
{
    int i;
 
    for(i=0; i<len; i++)
        printf("%4d", arg[i]);
 
    printf("\n");
}
cs


13,14행에서 배열의 길이를 계산하여 인자로 전달하고 있다.


반응형

'BackEnd > C' 카테고리의 다른 글

포인터  (0) 2019.03.11
2차원 배열을 함수의 인자로 전달  (0) 2019.03.11
2차원 배열의 각 행의 주소 계산법  (0) 2019.03.10
2차원 배열과 1차원 배열의 관계  (0) 2019.03.10
2차원 배열의 이해와 적용  (0) 2019.03.10