programing

3D 어레이는 C에 어떻게 저장됩니까?

stoneblock 2023. 8. 2. 08:39

3D 어레이는 C에 어떻게 저장됩니까?

C의 배열은 행마주 순서로 할당되는 것으로 알고 있습니다.따라서 2 x 3 배열의 경우:

0  1
2  3
4  5

메모리에 저장됩니다.

0 1 2 3 4 5

그러나 2 x 3 x 2 어레이를 사용하는 경우:

0  1
2  3
4  5

그리고.

6  7
8  9
10 11

이것들은 어떻게 메모리에 저장됩니까?다음과 같이 연속적입니다.

0 1 2 3 4 5 6 7 8 9 10 11

아니면 다른 방법인가요?아니면 어떤 것에 의존합니까?

낮은 수준에서는 다차원 배열과 같은 것이 없습니다.주어진 수의 요소를 수용할 수 있을 정도로 충분히 큰 메모리 블록이 있습니다.C에서 다차원 배열은 개념적으로 요소가 배열인 배열입니다.그래서 당신이 한다면,

int array[2][3];

개념적으로 다음과 같은 결과를 얻을 수 있습니다.

array[0] => [0, 1, 2]
array[1] => [0, 1, 2]

이것은 메모리에서 요소들이 연속적으로 배열되는 결과를 낳습니다, 왜냐하면array[0]그리고.array[1]실제로 데이터를 보유하고 있는 것은 아니며 두 개의 내부 어레이에 대한 참조일 뿐입니다.참고로 이는 다음을 의미합니다.[0, 1, 2]항목이 실제로 메모리의 공간을 차지합니다.과 같은을 볼 수 있습니다.

int array[2][3][2];

...다음과 같은 구조를 제공합니다.

array[0] => [0] => [0, 1]
            [1] => [0, 1]
            [2] => [0, 1]
array[1] => [0] => [0, 1]
            [1] => [0, 1]
            [2] => [0, 1]

이는 메모리에서 연속적으로 요소를 배열하는 것을 계속합니다(위와 같이, 오직[0, 1]항목은 실제로 메모리의 공간을 차지하며, 다른 모든 항목은 이러한 항목 중 하나에 대한 참조의 일부일 뿐입니다.보시다시피, 이 패턴은 당신이 얼마나 많은 차원을 가지고 있는지에 상관없이 계속될 것입니다.

그리고 그냥 재미로.

int array[2][3][2][5];

제공:

array[0] => [0] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]
            [1] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]
            [2] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]
array[1] => [0] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]
            [1] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]
            [2] => [0] => [0, 1, 2, 3, 4]
                   [1] => [0, 1, 2, 3, 4]

모든 "차원"은 메모리에 연속적으로 저장됩니다.

고려하다

    int arr[4][100][20];

당신은 말야로대라고 수 .arr[1]그리고.arr[2] (유형의▁().int[100][20]는 연속적입니다.
또는 그 밖의arr[1][42]그리고.arr[1][43] (유형의▁().int[20]는 연속적입니다.
또는 그 밖의arr[1][42][7]그리고.arr[1][42][8] (유형의▁().int는 연속적입니다.

네, 맞습니다. 연속적으로 저장되어 있습니다.이 예를 고려해 보십시오.

#include <stdio.h>

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

int main()
{
  int i;
  for(i = 0; i < 12; i++) {
    printf("%d ", *((int*)array3d + i));
  }
  printf("\n");
  return 0;
}

출력:

0 1 2 3 3 4 5 6 7 8 9 10

네, 그냥 순차적으로 보관하고 있습니다.다음과 같이 테스트할 수 있습니다.

#include <stdio.h>

int main (int argc, char const *argv[])
{
  int numbers [2][3][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}}};

  int i,j,k;

  printf("3D:\n");
  for(i=0;i<2;++i)
    for(j=0;j<3;++j)
      for(k=0;k<4;++k)
        printf("%i ", numbers[i][j][k]);

  printf("\n\n1D:\n");
  for(i=0;i<24;++i)
    printf("%i ", *((int*)numbers+i));

  printf("\n");

  return 0;
}

즉, 차원(N,M,L)이 있는 다중 인덱스 어레이에 대한 액세스는 다음과 같은 1차원 액세스로 변환됩니다.

array[i][j][k] = array[M*L*i + L*j + k]

당신은 당신 자신의 질문에 답했다고 생각합니다.다차원 배열은 행-주요 순서로 저장됩니다.

ANSIC 사양 섹션 3.3.2.1을 참조하십시오(구체적인 예도 있습니다).

연속적인 첨자 연산자는 다차원 배열 객체의 멤버를 지정합니다.만약 E가 x j "x ... x" k 차원의 n차원 배열(n = 2)이라면, E(l 값 이외의 다른 값으로 사용됨)는 j "x ... x" k 차원의 포인터로 변환됩니다. 만약 단항 * 연산자가 이 포인터에 명시적으로 또는 암시적으로 적용된다면, 결과는 (n - 1)-d를 가리킵니다.차원 배열. l 값이 아닌 다른 값으로 사용될 경우 자체가 포인터로 변환됩니다.따라서 배열은 행-주요 순서로 저장됩니다(마지막 첨자가 가장 빠르게 변화함).

예를 들어, 여러분은 그냥 시험해 보고 http://codepad.org/10ylsgPj 을 볼 수 있습니다.

예를 들어, 당신이 배열을 가지고 있다고 가정해 봅시다.char arr[3][4][5]이것은 5개의 문자로 구성된 4개의 배열로 구성된 3개의 배열입니다.

단순화를 위해 다음과 같은 값을 사용합니다.arr[x][y][z]이라xyz 그고리로.arr[1][2][3]저장합니다123.

메모리의 레이아웃은 다음과 같습니다.

  |  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14  15  16  17  18  19
--+--------------------------------------------------------------------------------   
00| 000 001 002 003 004 010 011 012 013 014 020 021 022 023 024 030 031 032 033 034 
20| 100 101 102 103 104 110 111 112 113 114 120 121 122 123 124 130 131 132 133 134 
40| 200 201 202 203 204 210 211 212 213 214 220 221 222 223 224 230 231 232 233 234

arr[0],arr[1]그리고.arr[2]차례로 오고 있지만, 의 각 요소는 유형입니다.char[4][5](표에 있는 세 개의 행).

arr[x][0] - arr[x][3]또한 차례로 오고 있고, 그들의 각 요소는 유형입니다.char[5]각네 - 는 (의 한 )입니다.arr[0][0])

arr[x][y][0] - arr[x][y][4]5바이트가 연이어 오고 있습니다.

주요 질문에 대한 OP의 의견에 답변하기 위해 (시간이 다소 길어질 것이므로 코멘트가 아닌 답변으로 진행하기로 결정했습니다.)

을 C로 ?array[ny][nx]ny그리고.nx 및 방향의 .y 및 x 방 수 요 입 니또한 3D 어레이를 다음과 같이 선언해야 한다는 의미입니까?array[nz][ny][nx]?

수학에서 MxN 행렬에는 행과 N개의 열이 있습니다.은 행렬요대일한반표인다같다습니음과은법입니다.a(i,j), 1<=i<=M, 1<=j<=N질문의 첫 번째 행렬은 3x2 행렬입니다.

실제로 GUI 요소 등에 일반적으로 사용되는 표기법과는 다릅니다.800x600 비트맵의 가로 방향(X축을 따라)은 800픽셀이고 세로 방향(Y축을 따라)은 600픽셀입니다.어떤 사람들은 행렬을 행렬로 표현하고 싶어 한다면, 수학적 표기법으로 행렬은 600x800 행렬(600 행, 800 열)이 될 것입니다.

이제, C의 다차원 배열은 다음과 같은 방식으로 메모리에 저장됩니다.a[i][j+1] 옆에 .a[i][j]하는 동안에a[i+1][j]N개의 원소가 떨어져 있습니다.일반적으로 "마지막 첨자가 가장 빠르게 변화한다" 또는 "행별로 저장된다"라고 합니다. 2차원 행렬의 행(즉, 첫 번째 인덱스가 동일한 요소)이 메모리에 연속적으로 배치되는 반면 열(두 번째 인덱스가 동일)은 서로 멀리 떨어져 있는 요소로 구성됩니다.성능을 고려할 때 중요합니다. (HW 캐시 등으로 인해) 인접 요소에 대한 액세스가 일반적으로 훨씬 빠르기 때문에, 예를 들어 가장 안쪽에 있는 루프가 마지막 인덱스에서 반복되도록 중첩 루프를 구성해야 합니다.

그림이라면, 아: 2D배그림이적카르안좌있테표시에면그격있수생같다니습다할각그이과음을문것라이림당네은신는상의자서가신정의열,▁thinkd▁back▁of▁2▁it▁in▁(▁if▁as:▁question▁picture▁latticed추▁is있▁may▁the▁your▁mental▁coord수▁thenab니▁that습질다생▁you▁to할같각inates▁a,문hes▁2이다과그▁yes▁array음▁ofian을array[NY][NX] 또는 형식,한 표기법항목에 수 . 그러나 실제 2D 또는 3D 데이터를 배열로 설명해야 하는 경우 인덱스의 선택은 데이터 형식, 편리한 표기법, 성능 등 다른 항목에 따라 달라질 수 있습니다.들어 내 이 예를어들비메모내표리이인 array[NX][NY]이고, "폐기가 알조차 없을 것입니다. :) :) :) 신 작 하 선 당 그 할 해 일 것 이 가 비 맵 당 트 된 은 종 것 신 도 없 다 니 입 transp 을 필 알 마 차 것 아 조 요 는 다 을 의 체 당 고 이 신 이 렇 것 업 은 을

3D 배열은 확장된 2D 배열입니다.

예를 들어 배열 - 인트라(3)(5)(6);

이것은 두 개의 2D 배열로 구성된 배열로, 배열에는 4개의 행과 3개의 열이 있는 2D 배열이 있습니다.

언급URL : https://stackoverflow.com/questions/5920944/how-are-3d-arrays-stored-in-c