본문 바로가기

BackEnd/C

배열의 이름은 상수 형태의 포인터이다.

반응형

1. 배열의 이름은 상수 형태의 포인터


포인터는 주소값을 지니며, 더불어 참조하는 대상의 자료형 정보도 지니는 변수나 상수를 의미한다.


그런데 배열의 이름은 첫번째 요소의 주소 값이다. 


그리고 배열 또한 참조 대상에 대한 자료형 정보도 지닌다! 


그렇기 때문에 배열의 이름도 포인터이다! 예제로 증명해 보자.


1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
int main(void)
{
    int arr[3]={100200300};
 
    printf("arr[0]는 %d, *arr는 %d \n", arr[0], *arr);
 
    return 0;
}
cs


1
arr[0]는 100*arr는 100
cs


7행을 보면 배열의 이름을 이용해서 *arr 포인터 연산식을 구성했다. 


이식은 arr이 가리키는 주소에 저장된 값을 참조한다.


그리고 첫번째 배열요소에 저장된 값 100을 출력했다는 것은 arr에는 주소값이 가리키는 대상의 자


형 정보가 담겨있다는걸 증명한다.  때문에 *연산시, 4바이트 크기의 정수 형태로 데이터를 읽을 


수 있는 것이다. 그리고 *연산자는 포인터 연산자이다. 따라서 피연산자는 반드시 포인터가 와야 한


다. 결국 위 예제를 보면 배열의 이름도 포인터임을 알 수 있다.


다만 일반적인 포인터 변수와 차이점은 배열의 이름은 상수 형태의 포인터이다.


때문에 배열의 이름은 가리키는 위치를 변경시킬 수 없다.


그리고 int형 1차원 배열의 이름은 int형 포인터이고 , double형 1차원 배열의 이름은 double형 포


인터이다. 따라서 type형 1차원 배열의 이름은 type형 포인터로 일반화 시킬수 있다.


2. 배열 이름 관점에서 배열 요소에 접근하는 방법 2가지


하나는 배열 접근방식으로 arr[i] = 5;


두번째는 배열의 이름이 포인터 이기 때문에 포인터 접근방식으로 *(arr+i) = 5; 


결국 위에서는 arr 이라는 배열 이름 관점에서 


두식 arr[i]와 *(arr+i)가 동일하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int main(void)
{
    int arr[5]={12345};
    int i;
 
    for(i=0; i<5; i++)
        printf("%d ", arr[i]);
    
    printf("\n");
 
    for(i=0; i<5; i++)
        printf("%d "*(arr+i));
 
    return 0;
}
cs


1
2
1 2 3 4 5
1 2 3 4 5
cs


3. 포인터 이름 관점에서 배열 요소에 접근하는 방법 2가지


예제를 봐보자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
 
int main(void)
{
    int arr[5]={12345};
    int * pArr=arr;
    int i;
 
    for(i=0; i<5; i++)
        printf("%d ", pArr[i]);
    
    printf("\n");
 
    for(i=0; i<5; i++)
        printf("%d "*(pArr+i));
 
    return 0;
}
cs


1
2
1 2 3 4 5
1 2 3 4 5
cs


6행에 선언한  pArr은 포인터이니 15행에서의 접근방식은 당연하다. 하지만 10행에서 배열 접근 방


식은 의외이다. 이렇게 포인터의 이름을 이용해서도 배열의 형태로 접근이 가능하다!


4. 배열의 이름을 전달받는 매개변수의 또 다른 선언방식


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
#include <stdio.h>
 
void IntArrPrintf(int * arr, int len)
{
    int i;
    for(i=0; i<len; i++)
        printf("%9d ", arr[i]);
 
    printf("\n");
}
 
void DblArrPrintf(double * arr, int len)
{
    int i;
    for(i=0; i<len; i++)
        printf("%9.4f ", arr[i]);
 
    printf("\n");
}
 
int main(void)
{
    int arr1[3]={123};
    double arr2[3]={1.12.23.3};
    
    IntArrPrintf(arr1, sizeof(arr1)/sizeof(int));
    DblArrPrintf(arr2, sizeof(arr2)/sizeof(double));
 
    return 0;
}
cs


1
2
        1         2         3
   1.1000    2.2000    3.3000
cs

배열의 이름은 상수 형태의 포인터 이므로


3행을 보면 int arr[ ]대신 int * arr을 매개변수로 선언하였다.


12행을보면 double arr[ ]대신 double * arr을 매개변수로 선언하였다.


즉 2가지 방법 다 가능하다.



반응형

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

Call-By-Value vs Call-By-Reference  (0) 2019.03.14
다차원 배열 이름의 포인터형  (0) 2019.03.14
제한된 형태의 포인터 연산  (0) 2019.03.13
포인터 배열  (0) 2019.03.13
포인터의 포인터  (0) 2019.03.13