본문 바로가기

💻 내 소개 안녕하세요 엄청짱 프로그래머 손다빈 입니다.
  • 나이 : 96년생
  • 특이사항 : MZ세대, INFJ, 오른손잡이, 아이폰 유저
  • 좋아하는 음식 : 햄버거피자치킨솥뚜껑삼겹살떡볶이오튀김밥
  • 취미 : 개발, Programming, 코딩, 프로그래밍, Coding

🥷기술
Unity
Godot
Cpp
Javascript
D3
Vue

🐱 우리집 고양이 소개
츄르 먹은 후 츄르 먹기 전
  • 이름 : 콜라
  • 나이 : 8살
  • 종 : Nado moreum

📱 개인 프로젝트
🏢 참여한 프로젝트
빌런즈 Life is Pair 도씨어부키우기 직장상사혼내주기 서바이벌빙고 SlitherCoin

🌱 내 잔디밭

2차원 배열의 포인터 형 본문

글 묶음/지옥에서 온 C++

2차원 배열의 포인터 형

초긍정 개발자 다빈맨 2020. 6. 30. 18:48

| 배열과 포인터의 관계

int main(void)
{
    int arr[3] = { 1, 2, 3 };
    int *ptr = arr;
 
    printf("%d", ptr[0]);
    printf("%d", *(ptr + 1));
}

위 예제는 배열과 포인터의 관계를 이해하는 간단한 예제입니다. 예제에서 ptr은 값의 변경이 가능한 변수 형태의 포인터이고 arr은 배열의 첫번째 요소 주소값을 가리키고 있는 상수 형태의 포인터라는 것은 C언어를 공부했다면 많은 분들이 알고 있는 사실입니다. 때문에 ptr 포인터 변수에 arr 을 대입해서 간접적으로 ptr 변수로 배열의 값을 참조할 수 있습니다.

 

하지만 포인터 변수에 배열의 이름을 대입하는 경우 실제로 포인터의 부식(Decay)이 일어나기 때문에 이 둘을 완전히 동일한 타입의 변수라고 생각하면 안됩니다. 포인터 부식에 관한 내용은 배열과 포인터는 다릅니다 에서 정리하였습니다.

 

| 2차원 배열의 포인터 형

int arr1[3] = { 1, 2, 3 };
int *ptr1 = arr1; // 1차원 포인터는 단일 포인터 변수에 담을 수 있다!

int형 1차원 배열 arr이 단일 포인터 변수 ptr에 대입이 가능한 것은 위에서 확인했습니다.

int arr2[2][3] = { {1, 2, 3},{4, 5, 6} };
int **ptr2 = arr2; // 그렇다면 2차원 포인터는 이중 포인터 변수에 담으면 되나?!

그렇다면 int형 2차원 배열을 담기 위해서 필요한 포인터 변수는 위와 같이 이중 포인터 변수일까요? 

#include<stdio.h>
 
int main(void)
{
    int num1 = 3, num2 = 5, num3 = 2;
    int *ptrArr[3] = { &num1, &num2, &num3 };
    
    int **pptr = ptrArr;
 
    printf("%d \n", *pptr[0]);
    printf("%d \n", *pptr[1]);
    printf("%d \n", **(pptr+2));
}

아쉽게도 이중 포인터 변수의 쓰임새는 이미 있습니다. 위 예제를 보면 포인터를 저장하고 있는 배열인 포인터 변수를 저장할 때 이중 포인터가 사용됩니다. 따라서 2차원 배열의 포인터를 변수에 대입하기 위해서는 다음과 같은 형식으로 변수를 정의해야 합니다.

#include<stdio.h>
 
int main(void)
{
    int arr[2][3] = 
    {
        {1, 2, 3}
    ,   {4, 5, 6}
    };
    int(*ptr)[3] = arr;
 
    printf("%d \n", ptr[0][0]);
    printf("%d \n", *(*(ptr+1))+1);
    printf("%d \n", (*ptr+0)[2]);
}

자료형 (*배열 포인터 이름) [배열의 가로길이]

 

위 형식으로 선언된 포인터 변수로 2차원 배열의 주소를 담을 수 있습니다. 별거 아닌 내용이지만 제가 C언어를 처음 배웠을때 헷갈려했던 기억이 있어서 글을 쓰기 좋은 주제라고 생각했습니다. 부족한 설명이지만 도움이 되는 내용이었으면 합니다.

 

| 정리

int (*ptr)[3]; // 배열 포인터 (배열의 주소값을 담는 포인터)
int  *ptr [3]; // 포인터 배열

위 둘을 잘 구분하자. 완전히 다른 의미이기 때문!