포인터 변수를 가리키는 또 다른 포인터 변수를 더블 포인터 또는 이중 포인터 라고 한다. 선언은 다음과 같이 * 연산자를 두 개 이어서 선언 한다.

int **dptr;

 

int main(void)
{
    double num = 3.14;
    double *ptr = #
    double **dptr = &ptr;
}

위와 같이 코드를 작성하게 되면 num 변수에는 3.14가 저장되어 있고, ptr변수는 num 변수의 주소를 가리키고 있고, dptr 변수는 ptr변수의 주소를 가리키고 있다. 또한 dptr 변수를 사용하여 다음과 같이 ptr변수와 num 변수에 접근할 수 있다. 

*dptr = ....;		// ptr 변수에 접근
*(*dptr) = ....;	// num 변수에 접근

*(*dptr)의 경우 괄호의 생략이 가능하여 **dptr로 접근할 수도 있다.

#include <stdio.h>

int main(void)
{
    double num = 3.14;
    double *ptr = &num;
    double **dptr = &ptr;
    double *ptr2;

    printf("%9p %9p\n", ptr, *dptr);
    printf("%9g %9g\n", num, **dptr);
    ptr2 = *dptr;   // ptr2 = ptr과 같음
    *ptr2 = 10.22;
    printf("%9g %9g\n", num, **dptr);
    return 0;
}
/* output : 
 0061FF10  0061FF10
     3.14      3.14
    10.22     10.22
*/

위와 같이 코드를 작성했을때 num 변수는 ptr변수와 ptr2변수가 가리키고 있고, ptr변수는 dptr변수가 가리키고 있다.

위와 같은 경우 변수 num에 접근하는 방법은 다음과 같다.

**dptr = 10.5;
*ptr = 10.5;
*ptr2 = 10.5;
num = 10.5;

위 4개의 경우 모두 num 변수에 10.5가 저장된다.

 

배열은 시작점의 주소를 가리키는 하나의 포인터이다. 포인터를 요소로 갖는 배열은 더블 포인터가 된다. 따라서 다음과 같이 포인터를 요소로 갖는 배열은 더블 포인터를 이용하려 접근할 수 있다.

#include <stdio.h>

int main(void)
{
    int num1 = 10, num2 = 20, num3 = 30;
    int *ptr1 = &num1;
    int *ptr2 = &num2;
    int *ptr3 = &num3;

    int *ptrArr[] = {ptr1, ptr2, ptr3};
    int **dptr = ptrArr;

    printf("%d %d %d\n", *(ptrArr[0]), *(ptrArr[1]), *(ptrArr[2]));
    printf("%d %d %d\n", *(dptr[0]), *(dptr[1]), *(dptr[2]));
    return 0;
}
/* output : 
10 20 30
10 20 30
*/

 

'Language > C, C++' 카테고리의 다른 글

[C] 2차원 배열의 포인터  (0) 2020.12.30
[C] 삼중 포인터  (0) 2020.12.28
[C] 3차원 배열  (0) 2020.12.26
[C] 2차원 배열  (0) 2020.12.24
[C] 포인터에서 const 사용  (0) 2020.12.20

3차원 배열은 2차원 배열에서 높이의 개념이 추가된 배열이다. 3차원 배열은 다음과 같이 높이. 세로, 가로의 길이를 순서대로 선언한다.

int arr[2][3][4];	// 높이2, 세로3, 가로4

sizeof 연산을 이용하여 3차원 배열의 크기를 확인해보면 int 자료형의 크기 x 높이 x 세로 x 가로로 직육면체 형태의 배열임을 알 수 있다.

#include <stdio.h>

int main(void)
{
    int arr[2][3][4];
    printf("3차원 배열의 크기 : %d\n", sizeof(arr));
    return 0;
}
// output : 3차원 배열의 크기 : 96

 

3차원 배열은 다음과 같이 선언하고 접근한다.

#include <stdio.h>

int main(void)
{
    int sum = 0;
    int arr[3][3][2] = {
        {
            {1,2},
            {3,4},
            {5,6}
        },
        {
            {7,8},
            {9,10},
            {11,12}
        },
        {
            {13,14},
            {15,16},
            {17,18}
        }
    };

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            sum += arr[0][i][j];
        }
    }
    printf("첫번째 면 모든 값의 합 : %d\n",sum);
    sum = 0;

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            sum += arr[2][i][j];
        }
    }
    printf("세번째 면 모든 값의 합 : %d\n",sum);

    return 0;
}
// output : 
// 첫번째 면 모든 값의 합 : 21
// 세번째 면 모든 값의 합 : 93

3차원 배열은 2차원 배열의 형태를 갖는 여러개의 면이 겹쳐져 있는 형태이다.

'Language > C, C++' 카테고리의 다른 글

[C] 삼중 포인터  (0) 2020.12.28
[C] 더블 포인터  (0) 2020.12.28
[C] 2차원 배열  (0) 2020.12.24
[C] 포인터에서 const 사용  (0) 2020.12.20
[C] Call - by - value, Call - by - reference  (0) 2020.12.20

2차원 배열은 다음과 같이 선언한다.

int arr[3][4];	// 세로가 3, 가로가 2인 int형 2차원 배열

2차원 배열의 선언 방식은 세로와 가로의 길이를 각각 명시한다. 이 선언으로 할당되는 배열의 모습은 다음과 같다.

  1열  2열 3열 4열
1행 [0][0] [0][1] [0][2] [0][3]
2행 [1][0] [1][1] [1][2] [1][3]
3행 [2][0] [2][1] [2][2] [2][3]

위 표에서 삽입된 두개의 숫자는 배열에 접근할 때 사용하게 되는 인덱스값이다. 배열의 이름이 arr이고 배열의 자료형이 TYPE라 할 때 2차원 배열의 선언 형태는 다음과 같다.

TYPE arr[세로길이][가로길이];

 

sizeof 연산자를 이용하여 2차원 배열의 크기를 확인해보면 다음과 같다.

#include <stdio.h>

int main(void)
{
    int arr[3][4];
    printf("2차원 배열 크기 : %d\n", sizeof(arr));
    return 0;
}
// output : 2차원 배열 크기 : 48

int 형 배열이기 때문에 한 칸에 4씩 계산하여 48이 나온다.

 

2차원 배열은 다음과 같이 접근하여 값을 저장할 수 있다.

arr[2][1] = 5;
arr[0][1] = 3;

 

2차원 배열의 메모리 주소값도 1차원 배열과 동일한 구조이다. 예를 들어 세로3, 가로2인 2차원 배열을 선언하여 메모리 주소를 확인하면 다음과 같다. 

#include <stdio.h>

int main(void)
{
    int arr[3][2];
    
    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            printf("%p \n", &arr[i][j]);
        }
    }

    return 0;
}
/* output :
0061FF00 
0061FF04 
0061FF08
0061FF0C
0061FF10
0061FF14
*/

int 형 2차원 배열이기 때문에 4바이트 만큼 차이가 나는 상태로 1열로 할당되어 있다.

 

2차원 배열도 선언과 동시에 초기화가 가능하다. 

int arr[3][3] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}
};

위 코드처럼 행 단위로 초기화 할 값들을 별도의 중괄호로 명시해야 한다. 

다음 코드와 같이 초기화를 생략한 요소가 있다면 빈 공간은 0으로 초기화 된다.

int arr[3][3] = {
    {1},
    {4,5},
    {7,8,9}
};

다음 코드와 같이 한 줄로 초기화 하는 것도 가능하다. 

int arr[3][3] = {1,2,3,4,5,6,7};

위 코드와 같이 부족한 부분이 있다면 마찬가지로 0으로 채워진다.

#include <stdio.h>

int main(void)
{
    int arr1[3][3] = {
        {1,2,3},
        {4,5,6},
        {7,8,9}
    };

    int arr2[3][3] = {
        {1,2,3},
        {4,5},
        {7}
    };

    int arr3[3][3] = {1,2,3,4,5,6};

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            printf("%d ", arr1[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            printf("%d ", arr2[i][j]);
        }
        printf("\n");
    }
    printf("\n");

    for(int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            printf("%d ", arr3[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}
/* output : 
1 2 3 
4 5 6
7 8 9

1 2 3
4 5 0
7 0 0

1 2 3
4 5 6
0 0 0
*/

 

1차원 배열처럼 배열의 길이를 명시하지 않고 초기화 하는것도 가능하다. 그러나 다음과 같이 가로와 세로의 길이를 모두 명시하지 않는 것은 불가능하다.

int arr[][] = {1,2,3,4,5,6,7,8};

배열의 요소가 8개 이므로 1x8, 2x4, 4x2, 8x1의 경우로 여러개의 경우가 있기 때문이다.  그래서 하나를 알려줘야 하는데, 다음과 같이 세로의 길이는 생략이 가능하다. 가로 길이는 생략이 불가능하다. 가로의 길이를 생략하면 위 코드와 같이 컴파일러에서 에러를 발생한다.

int arr[][4] = {1,2,3,4,5,6,7,8};
int arr2[][2] = {1,2,3,4,5,6,7,8};

 

'Language > C, C++' 카테고리의 다른 글

[C] 더블 포인터  (0) 2020.12.28
[C] 3차원 배열  (0) 2020.12.26
[C] 포인터에서 const 사용  (0) 2020.12.20
[C] Call - by - value, Call - by - reference  (0) 2020.12.20
[C] 함수 인자로 배열 전달  (0) 2020.12.20

+ Recent posts