programing

이중 포인터를 사용하여 2차원 배열을 표현할 수 없는 이유는 무엇입니까?

oldcodes 2023. 8. 7. 23:03
반응형

이중 포인터를 사용하여 2차원 배열을 표현할 수 없는 이유는 무엇입니까?

이중 포인터를 사용하여 2차원 배열을 표현할 수 없는 이유는 무엇입니까?

arr[2][5] = {"hello","hai"};
**ptr = arr;

여기서 이중 포인터(**ptr)가 이 예에서 작동하지 않는 이유는 무엇입니까?

제가 그림을 그리려고 합니다.

int array[10][6];

그리고.

int **array2 = malloc(10 * sizeof *array2);
for (int i = 0; i < 10; ++i)
    array2[i] = malloc(6 * sizeof **array2);

기억 속의 모습과 그들이 어떻게 다른지 (그리고 그들은 서로에게 캐스팅될 수 없다는 것)

array다음과 같은 모양:

 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| | | | | | | | | | | | | ..............| | | (10*6 elements of type int)
 - - - - - - - - - - - - - - - - - - - - - -
< first row >< second row> ...

array2다음과 같은 모양:

 _ _ _ _ _ _ _ _ _ _ 
| | | | | | | | | | | (10 elements of type int *)
 - - - - - - - - - - 
 | |     ....      |     _ _ _ _ _ _
 | |                \-->| | | | | | | (6 elements of type int)
 | |                     - - - - - -
 | |
 | |      _ _ _ _ _ _
 |  \ -->| | | | | | | (6 elements of type int)
 |        - - - - - -
 |
 |
 |      _ _ _ _ _ _
  \ -->| | | | | | | (6 elements of type int)
        - - - - - -

라고 말할 때array[x][y]으로 해석하면,*((int *)array+x*6+y)

편한라고 당이말할때신말.array2[x][y]으로 해석하면,*(*(array2+x)+y)의 경우:array이 공식은 또한 작동합니다(게시물의 끝까지 읽은 후 주석).

즉, 정적 2D 배열은 실제로 행이 한 줄에 배치된 1D 배열입니다.지수는 다음 공식으로 계산됩니다.row * number_of_columns_in_one_row + column.

그러나 동적 2D 배열은 포인터의 1D 배열에 불과합니다.그러면 각 포인터가 다른 1d 배열을 가리키도록 동적으로 할당됩니다.사실, 그 포인터는 무엇이든 될 수 있습니다.그럴 수도 있겠지요NULL또는 단일 변수를 가리키거나 다른 배열을 가리킵니다.그리고 각각의 포인터는 개별적으로 설정되어 있기 때문에 다른 성질을 가질 수 있습니다.

이 포터를전하의 ,array어딘가에, 당신은 그것을 던질 수 없습니다.int **(어떤 일이 일어날지 상상해 보세요.int의 셀 값array포인터로 해석되고 참조되지 않음 -> 쾅!분할 오류!).하지만 당신은 생각할 수 있습니다.array의1차원배의 로서.int [6]는 유형이 있는입니다; 그은유형있요열 1d다니입.int [6]그것을 적으려면, 당신은 말합니다.

int (*p)[6] = array;

C에서 2차원 배열은 배열의 배열입니다.

이를 참조하려면 포인터 대 어레이가 필요하며, 이중 포인터가 필요하지 않습니다.

char array[2][6] = {"hello", "hai"};
char (*p)[6] = array;
//char **x = array;  // doesn't compile.

이중 포인터가 "2차원 데이터"를 참조하려면 포인터 배열의 첫 번째 요소를 참조해야 합니다.그러나 C의 2차원 배열(배열 배열)은 포인터 배열과 동일하지 않으며, 2-D 배열만 정의하면 해당하는 포인터 배열이 존재하지 않습니다.

둘 사이의 유일한 유사점은[][]데이터에 액세스하는 데 사용되는 구문: 데이터 자체의 구조는 상당히 다릅니다.

포인터 대 포인터가 있다는 것은 각 행(또는 열)이 다른 행/열과 다른 길이를 가질 수 있다는 것을 의미합니다.

시작 요소에 대한 포인터와 행/열당 요소 수를 지정하는 정수를 사용하여 2D 배열을 나타낼 수도 있습니다.

void matrix_set(double *first, size_t row_size, size_t x, size_t y, double value)
{
  first[y * row_size + x] = value;
}

가변 크기의 다차원 배열과 유사한 객체를 얻기 위해 각 행에 포인터 배열을 만드는 것은 통사적 설탕을 위해 값비싼 설계 선택입니다.하지 마세요.

변수 크기의 다차원 배열을 올바르게 수행하는 방법은 다음과 같습니다.

if (w > SIZE_MAX/sizeof *m/h) goto error;
m = malloc(w * h * sizeof *m);
if (!m) goto error;
...
m[y*w+x] = foo;

만약 당신이 그것을 "예쁘게 보이기"를 원한다면 당신은 쓸 수 있습니다.m[y][x]당신은 아마도 C++과 같은 다른 언어를 사용해야 합니다.

법적 코드에 대해 이야기하는 것으로 시작하겠습니다.(각 선언 앞에 있는 문자로 가정하여) 작성한 내용은 몇 가지 이유로 컴파일되지 않습니다. 이니셜라이저가 너무 많습니다(arr[0]에는 6개의 문자가 있고 크기는 5개입니다). 물론 char**p에는 char[2][5]와 호환되는 유형이 없습니다.이러한 문제를 해결하면 다음과 같은 이점을 얻을 수 있습니다.

char arr[2][6] = { "hello", "hai" };
char (*p)[6] = arr;

더블 포인터 없이.위의 단일 문자에 액세스하려면 해당 문자가 나오는 요소를 지정해야 합니다.

char* pc = *arr;

ar에서 첫 번째 요소의 문자에 액세스하려는 경우 작동합니다.

C++에는 2차원 배열이 없습니다.위의 첫 번째 정의는 char의 배열[2] 또는 배열[6]을 정의합니다.암시적 배열을 포인터로 변환하면 포인터가 [6]개의 char 배열로 변환됩니다.물론 그 이후에는 포인터 변환을 위한 배열이 없습니다. 더 이상 배열이 없기 때문입니다.

언어에서 표현으로 이어지는 두 가지 요소는 영원히 존재합니다.

어느 정도 C는 디스젠듐에 가깝습니다.

위의 예를 들어, 우리는 2D 배열을 다른 형태로 할당하거나 변환하려고 합니다.

#include <stdio.h> 
  
int main() 
{ 
        char array[2][6] = {"hello", "hai"};
        int h, i;
        for (h = 0; h < 2; h++) 
                for (i = 0; i < 6; i++) 
                        printf("%c\n", *(*(array+h) + i));
        char (*p)[6] = array;
        for (h = 0; h < 2; h++) 
                for (i = 0; i < 6; i++) 
                        printf("%c\n", *(*(p+h) + i));
        char **x = array;
        for (h = 0; h < 2; h++) 
                        printf("%c\n", *(x+h));
} 

그리고 그 결과물은,

h
e
l
l
o

h
a
i



h
e
l
l
o

h
a
i



h
i

요즘 컴파일러는 너무 똑똑해서 실패하는 대신 경고만 할 것입니다.

main.c:14:13: warning: initialization from incompatible pointer type [enabled by default]
  char **x = array;

이 시점에서 우리는 이중 포인터가 이중 배열이 아니라는 것을 이해할 수 있어야 합니다.

첫번째h출처hello제2의i출처hai거리는 포인터 크기와 동일한 8바이트입니다.

게다가, 우리는 할 수 있습니다.

char *y[2];
for (h = 0; h < 2; h++) 
        y[h] = array[h];
for (h = 0; h < 2; h++)
        printf("%s\n", y[h]);
for (h = 0; h < 2; h++)
        for (i = 0; i < 6; i++)
                printf("%c\n", *(*(p+h) + i));

하지만 이 과제는 한 줄짜리 진술이 아닙니다.

그리고 그 결과물은,

hello
hai
h
e
l
l
o

h
a
i

언급URL : https://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays

반응형