본문 바로가기
<개인공부>/[C언어, C++]

[C언어] 배열포인터, 포인터배열 정리 (pointer)

by 사용자 BlockDMask 2017. 7. 14.
반응형

안녕하세요! BlockDMask 입니다 

오늘은 많이들 햇갈려 하는 

array pointer pointer array pointer pointer array array pointer.

C언어의 포인터 개념과 배열 개념을 조금은 알고 계셔야 내용을 이해할 수 있을 것 입니다.

포인터배열, 배열포인터를 간단하게 정리해보겠습니다.

우리나라말은 끝까지 들어보라고 하지 않씁니까. 뒤에있는게 중요하다는 뜻이죠.

포인터"배열" / 배열"포인터" 시작하겠습니다.

이해를 돕기위해 직접 그림도 그렸습니다. 손그림이었는데 이번에 ppt로 바꾸어봤습니다.

훨씬 이해하기 편하지 않을까 싶습니다.


<목차>

1. 포인터 배열이란.

2. 배열 포인터란.


1. 포인터 배열이란


 포인터 의 배열이다.

 배열의 요소가 포인터들로 이루어져 있다.


 선언방법 : char* arr[3]; 

배열 요소의 자료형이 char* (포인터)인 배열

그 배열의 요소의 개수가 3개.


arr[0]은 어떤 메모리를 가리키고 있다. (포인터 이다)

arr[1]도 어떤 메모리를 가리키고 있다. (오호 포인터 이다)

arr[2]도 어떤 메모리를 가리키고 있다. (이것도 포인터 이다)

이 세개들의 배열이다.

char* arr[3]은 메모리 3곳을 가리키고 있는 배열 입니다.


 포인터 배열 예제1) const char* 문자열 이용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main(void) {
    const char* arr[3];    //포인터 배열 선언.
    int i;
 
    arr[0= "BlockDMask";        //arr[0]은 -> 문자열 주소를 가리킵니다.
    arr[1= "C Programming";    //arr[1]은 -> 문자열 주소를 가리킵니다.
    arr[2= "point_arr";        //arr[2]은 -> 문자열 주소를 가리킵니다.
 
    for (i = 0; i < 3; i++
    {
        printf("arr[%d] -> %s\n", i, arr[i]);
    }
 
    return 0;
}
cs


- 포인터 배열 예제 1 결과


예제 1번을 그림으로 표현하자면 이렇습니다.

(제가 직접 그렸습니다.)

 포인터 배열 예제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
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void) {
    char* arr[3];
    char tmp[30];    //문자를 받을 char 배열 30자 까지만 받자
    int len, i;
 
    for (i = 0; i < 3; i++
    {
        printf("[%d] : ", i);    
        scanf("%s", tmp);        //문자열 입력받기
        len = strlen(tmp) + 1;    //문자열 길이 + 1 할당 ('\0' 문자 포함)
        printf("[%d] : tmp \t주소 : %p\n", i, &tmp);    //tmp 주소 출력
 
        arr[i] = (char*)malloc(sizeof(char* len);    //메모리 할당
        printf("[%d] : arr[%d]\t주소 : %p\n\n", i, i, &arr[i]);    //할당받은 arr[i] 메모리 주소 출력
 
        strcpy(arr[i], tmp);    //문자열을 arr[i]가 가리키고 있는 메모리로 복사
    }
 
    printf("\n");
    for (i = 0; i < 3; i++
    {
        printf("arr[%d] = %s\t주소 : %p\n", i, arr[i], &arr[i]);
    }
 
    for (i = 0; i < 3; i++
    {
        free(arr[i]);    //메모리 해제
    }
    return 0;
}
cs


- 포인터 배열 예제 2 결과


결과를 보면 arr[0], arr[1], arr[2]가 malloc으로 할당 받은 메모리를 가리키는 포인터 이고.

가리키고 있는 메모리에 strcpy(arr[i], tmp)로 사용자로부터 입력받은 문자열을 복사 하게 됩니다.

그렇게 되면 arr[0] -> 문자열 을 가리키게 됩니다.

결과를 보면 해당 주소에 입력한 문자들이 잘 들어온 것을 알 수 있습니다.


예제 2번을 그림으로 표현하자면 이렇습니다.

(제가 직접 그렸습니다22)



2. 배열 포인터란


 배열을 가리키는 "하나의 포인터" 입니다.

특정 사이즈의 배열'만' 가리킬 수 있는 하나의 포인터이다. (여러개가 아닙니다. 딱 하나의 포인터 입니다.)

음.. 특정 사이즈의 배열을 마치 하나의 새로운 타입이라고 생각하면 좀더 쉬울 듯 합니다. 그 새로운 타입을 가리키는 포인터 입니다.


 선언 방법 "타입이름 (*변수명)[N]"

* 포인터가 타입쪽에 붙는게 아니라 변수이름 쪽에 소괄호 안에 붙게 됩니다.

선언 방법 = 타입이름 (*변수이름)[N]


 선언예시

char (*arr)[3];

char 타입의 인덱스를 3개 가지고 있는 배열"을 가리키는 포인터입니다. 

그냥 하나의 포인터라고 생각하시면됩니다.


int* pNum; 이거랑 같은 포인터의 종류 중에 하나인데, 단지 가리키는 타입이 다른것뿐 입니다.

pNum은 int 타입을 가리키는 것 뿐이고

여기 arr은 char타입의 배열 사이즈[3]인 타입을 가리키는 것 뿐 입니다.


기억합시다. 배열 포인터는. 그냥 하나의 포인터 이다.


 배열 포인터 예제

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
#include <stdio.h>
int main(void)
{
    char (*arr)[3];
 
    char tmp1[3= { 'b''l''o' };
    char tmp2[3= { 'c''k''\0' };    //문자열의 끝을 알리는 '\0'을 추가
    char tmp3[5= { 'd''m''a''s''k'};    //배열의 사이즈가 다릅니다. 가리키기 불가.
    printf("tmp1[3]의 주소 : %p\n", tmp1);
    printf("tmp2[3]의 주소 : %p\n", tmp2);
    printf("tmp3[5]의 주소 : %p\n", tmp3);
 
    printf("\n"); printf("\n");
 
    arr = &tmp1;    //arr은 tmp1의 주소를 가리킵니다.
    printf("arr의 주소 : %p\t 문자열 : ", arr);
    for (int i = 0; i < (int)sizeof(*arr); i++)
    {
        printf("%c", (*arr)[i]);
    }
    printf("\n");
 
    arr = &tmp2;    //arr은 tmp2의 주소를 가리킵니다.
    printf("arr의 주소 : %p\t 문자열 : ", arr);
    for (int i = 0; i < (int)sizeof(*arr); i++)
    {
        printf("%c", (*arr)[i]);
    }
    printf("\n");
 
    //arr = &tmp3; 배열의 사이즈가 다르다는것은 타입이 다르다는 뜻 입니다.
    return 0;
}
cs


 배열 포인터 예제 결과


배열 "포인터" 예제를 그림으로 표현하자면 이렇습니다.

(제가 직접 그렸습니다. 333)


감사합니다. 이상으로 C언어 포인터배열, 배열포인터 리뉴얼 포스팅을 마치겠습니다.

이해가 안가는 부분이 있다면 편하게 댓글 남겨주세요.


다시한번 말씀드리겠지만

"포인터 배열"은 포인터가 여러개 모여서 배열 있는것이고

"배열 포인터"배열 타입을 가리키는 하나의 포인터 라는 것 입니다.

반응형

댓글17

  • 켄드릭라마 2018.03.22 20:24

    배열 포인터요! 2차원 배열 이상부터 부분 배열의 개념이 있기 때문에, 배열포인터를 사용 가능한 것으로 알고 있습니다.
    예로 드신 코드는 1차원 배열이라서 문제가 있지 않나요? 제 컴퓨터에서 실행시켜보니 쓰레기값들이 섞여 나오는군요
    답글

    • 아 죄송합니다. 예제가 char의 배열로 인해서 문자열 취급이 안되서 %s로 프린트를 하게되면 문자열의 끝을 알지 못해서 그런식으로 쓰레기 값이 나오는 것 같습니다. 예제를 수정해서 올리도록하겠습니다.

  • 2019.04.04 22:25

    비밀댓글입니다
    답글

  • lune 2019.05.24 22:41

    안녕하세요~ 블로그 잘 보고 있습니다
    코딩하다가 문제가 생겨서 도움이 필요하여 그런데
    도와주실 수 있으시다면 메일주소 받을 수 있을까요?
    답글

    • 안녕하세요 BlockDMask 입니다.
      저도 시간이 많은 편은 아니라서, 시간을 많이 내서 도와드릴수는 없지만, 한번 확인정도는 할 수 있을것 같습니다.
      blockdmask@gmail.com 입니다.

  • redniche 2019.06.12 18:57

    저기 아래쪽 배열 포인터에서 arr 배열의 원소에서 각 앞부분을 a[0], a[1], a[2], a[3]이 가리키고 있는 형태가 되어야할거 같은데요.
    답글

    • redniche 2019.06.12 19:01

      아 잘못말했다.
      arr배열에서 각원소들이 tmp1[3]의 각 원소의 주소를 가리키고 있어야할거 같은데요.

    • 그림은 맞습니다, 헷갈리신거 같으니 다시 글을 수정해야할것 같습니다.
      하나의 타입이기 때문에 그 배열을 가리키는 포인터 일 뿐입니다.

  • abc 2019.10.24 10:13

    안녕하세요. 포스팅 잘 봤습니다. 좋은 정보 공유해주셔서 감사해요

    배열 포인터 그림에서 tmp2[3] = d | e 아닌가요? f가 있어서 여쭤봤습니다.
    답글

  • 유지훈 2020.05.06 14:26

    안녕하세요? C,C++ 공부하는데 도움을 많이 받고 있습니다. 정말 감사드립니다.
    위의 내용 중 궁금한게 있는데요,,
    포인터 배열 예제2에서, char* arr[3]으로 선언하셨는데, 그러면 arr[0],arr[1],arr[2]의 메모리 공간은 1바이트 간격으로 할당되어야 한다고 생각했습니다. 그런데 실제로 4바이트씩 차이가 나네요?
    이게 왜 그런지 궁금합니다.
    답글

    • Favicon of https://meongco.tistory.com 너부륌 2020.07.17 11:44 신고

      저도 그것이 궁금하긴 한데요. 다른것도 궁금해서 질문합니다.
      arr[0]이 어떤 한'문자'만 가르키는 포인터잖아요? 근데 왜 arr[0]="문자열" 이 가능한건가요?

    • 프린이 2020.12.16 06:22

      본문에서 arr은 char형의 배열이아니라
      char*형의 배열입니다.
      쉬운예시로 string의 배열이라고 생각하시면됩니다.

    • 프린이 2020.12.16 06:23

      그리고 4바이트씩 차이나는 이유는
      char* arr[]은 char*형의 배열이란 뜻입니다. char형의 배열이 아닙니다.
      char*형의 배열입니다.
      기본적으로 char*이든 int*이든 포인터는 주소값을 저장하는 4바이트크기의 데이터타입이기 때문에 4바이트씩 차이나는게 맞습니다.

    • 초보 2020.12.31 19:32

      궁금한게 있는데 char* arr[]의 경우 arr[1],arr[2],arr[3] 등 배열의 각요소가 char 변수를 가리키는 포인터 변수로 채워지고,
      char *arr[]의 경우 우리가 아는 string 변수처럼
      arr이 arr[0]의 포인터 값을 가리키는 것 아닌가요?

      제가 자 몰라서 답변해주시면 감사하겠습니다.

  • 유지훈 2020.05.06 14:40

    배열 포인터에서,
    for (int i = 0; i < (int)sizeof(*arr); i++)
    {
    printf("%c", (*arr)[i]);
    }
    이렇게 올려주셨는데, (int)sizeof(*arr) -> (char)sizeof(*arr)로 바꾸어야 될 것 같습니다.
    답글