이중 포인터를 사용하여 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
'programing' 카테고리의 다른 글
Spring Junit 응용 프로그램 컨텍스트를 테스트 클래스에서 더럽힌 후 재설정하는 방법은 무엇입니까? (0) | 2023.08.07 |
---|---|
"모듈은 호환되지 않는 버전의 Kotlin으로 컴파일되었습니다.메타데이터의 이진 버전은 1.5.1이며 예상 버전은 1.1.16입니다. (0) | 2023.08.07 |
복원 지점에서 Win10을 복구하면 데이터는 삭제되지만 데이터베이스 및 테이블은 Maria에 남아 있습니다.DB (0) | 2023.08.07 |
XML 파일 루프 가져오기 (0) | 2023.08.02 |
다른 PHP 스크립트에서 PHP 스크립트 실행 (0) | 2023.08.02 |