2차원 어레이를 할당하는 이상한 방법?
프로젝트에서 누군가 이 선을 긋고 있습니다.
double (*e)[n+1] = malloc((n+1) * sizeof(*e));
(n+1)*(n+1)의 2차원 배열을 만들 수 있습니다.
아마도, 지금까지 제가 물어본 그 누구도 이것이 정확히 어떤 역할을 하는지, 어디서 유래했는지, 왜 작동해야 하는지(소문에 의하면, 그렇긴 하지만, 저는 아직 구입하지 않았습니다) 말할 수 없었기 때문입니다.
제가 뭔가 명백한 것을 놓치고 있는 것 같습니다만, 위 줄에 대해 설명해 주시면 감사하겠습니다.왜냐하면 개인적으로, 나는 우리가 실제로 이해하는 것을 사용한다면 훨씬 더 기분이 좋을 것 같기 때문이다.
 ''e 、 열 、 of of of of of of の 배열 입니다.n + 1「」의 double.
에서 참조 를 사용하다e입니다.e아아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.n + 1「」의 double
malloc은 단순히 인 "Call"을 합니다.e (위)을  됩니다. (위)를 구하다.n + 1를 에 malloc능 . alloc본본 of of of of of of of of of of of of of of of의 배열을 n + 1「」의 배열n + 1의 double.
이 관용구는 자연스럽게 1D 어레이 할당에서 제외됩니다.해 보겠습니다.T:
T *p = malloc( sizeof *p * N );
간단하죠?표현 *p은 ★★★★★★★★★★★★★T, (그래서)sizeof *p sizeof (T)N-  의 T이는 모든 유형에 해당됩니다.
 이번에는, 제이대대대uteuteuteute now now로 바꿔볼까요T" " " "와 같은 됩니다.R [10] 우리의 가 됩니다
R (*p)[10] = malloc( sizeof *p * N);
여기서의 의미론은 1D 할당 방식과 완전히 동일하며 변경된 것은 다음 유형의 데이터뿐입니다.pT *은 , , , , , , , , , , , , , , , , , , , , , , .R (*)[10].표현*p은 ★★★★★★★★★★★★★T '유형'입니다.R [10], (그래서)sizeof *p sizeof (T)은 와와다다 which에 해당합니다.sizeof (R [10]) 공간을 해 놓고 N타타에 10「」의 요소 R
더  갈 수 . 를 들어, 더 멀리 갈 수 있다.R는, 그 자체가  타입입니다.int [5]대체하다R 우리는 ★★★★★★★★★★★★★★★★★.
int (*p)[10][5] = malloc( sizeof *p * N);
 거래 - ★★★★★★★★★★★★★★★★★★」sizeof *p is is is is is와 sizeof (int [10][5])「」, 「」, 「」를 할 수 있을 N타타에 10타타에 5을 지정합니다.int
이것이 할당측입니다.접근측에서는 어떨까요?
 때 주의해 주세요.[]첨자 연산은 포인터 산술의 관점에서 정의됩니다.a[i]되어 있습니다.*(a + i)1. 따라서 첨자 연산자는[] 은 암묵적으로 포인터를 폐기합니다.한다면p에 대한 포인터입니다.T포인트 투 포인트의 값에 액세스 하려면 , 유니리와의 참조를 명시적으로 실시해 주세요.*연산자:
T x = *p;
또는 를 사용하여[]첨자 연산자:
T x = p[0]; // identical to *p
따라서 만약p배열의 첫 번째 요소를 가리키면 포인터의 첨자를 사용하여 해당 배열의 모든 요소에 액세스할 수 있습니다.p:
T arr[N];
T *p = arr; // expression arr "decays" from type T [N] to T *
...
T x = p[i]; // access the i'th element of arr through pointer p
자, 그럼 다시 치환 작업을 하고T어레이 타입으로R [10]:
R arr[N][10];
R (*p)[10] = arr; // expression arr "decays" from type R [N][10] to R (*)[10]
...
R x = (*p)[i];
바로 눈에 띄는 차이점 중 하나는 명백한 역참조라는 것입니다.p첨자 연산자를 적용하기 전에.우리는 구독을 원하지 않습니다.p, 델은 무엇을 서브스크립트 하고 싶은가?p (이 경우 어레이)를 가리킵니다. arr[0]단항이래*첨자보다 우선순위가 낮다[] 괄호를 으로 그룹화해야 .p* 위에서  때 *p is is is is is와 p[0]할 수 있습니다.
R x = (p[0])[i];
아니면 그냥
R x = p[0][i];
 「 」의 는,p어레이를  2D 어레이에  수 .p다음과 같이 합니다.
R x = p[i][j]; // access the i'th element of arr through pointer p;
               // each arr[i] is a 10-element array of R
에 도달하고, 이 결론으로 대체하다, 라고 하면 됩니다.Rint [5]:
int arr[N][10][5];
int (*p)[10][5]; // expression arr "decays" from type int [N][5][10] to int (*)[10][5]
...
int x = p[i][j][k];
이 동작은 다음과 같습니다.p의 어레이를  하고 있는 , 를 개입시켜 되어  메모리를 포인트  있는 경우.malloc
이 관용어에는 다음과 같은 이점이 있습니다.
-  단 한  돼요. 나누면 .T **arr = malloc( sizeof *arr * N ); if ( arr ) { for ( size_t i = 0; i < N; i++ ) { arr[i] = malloc( sizeof *arr[i] * M ); } }
- 할당된 어레이의 모든 행은 *continuous*이며, 이는 위의 단편적인 할당 방식과는 다릅니다.
-  해제는, 1개의 할 수 .freearr[i]전에 전에할당 해제를 할당 취소할 수 있arr..
경우에 따라서는 힙이 심하게 단편화되어 연속된 청크로 메모리를 할당할 수 없거나 각 행의 길이가 다른 "jagged" 어레이를 할당하려는 경우 등 단편적인 할당 방법이 선호될 수 있습니다.하지만 일반적으로, 이것이 더 나은 방법입니다.
1. 어레이는 포인터가 아닙니다.대신 필요에 따라 어레이 식이 포인터 식으로 변환됩니다.
이것은 2D 어레이를 동적으로 할당하는 일반적인 방법입니다.
- e형식의배열에대한 배열 포인터입니다 유형 배열에 반환되는 배열이 포인터입니다.- double [n+1].
- sizeof(*e)따라서 한 따라서 1의 크기인뾰족한 타입을 제공한다의 크기의pointed-at 형식의 형식을 준다.- double [n+1]array.어레이를 설정합니다.
- 당신은 공간을 할당하다에 방을 할당하며n+1그러한 배열입니다.이러한 어레이.
- 당신은 어레이포인터를 설정합니다는 배열 포인터를 세웠다.e배열의 이 배열의 첫번째 배열에서 지적합니다.이 어레이의 첫 번째 어레이를 가리킵니다.
- 이것은 당신이를 통해를 사용합니다.e~하듯이로e[i][j]2D배열에 개별 항목에 액세스 하려면.2D배열의 개별수 있습니다 액세스할 항목에.
개인적으로 이 스타일은 훨씬 읽기 쉽다고 생각합니다.
double (*e)[n+1] = malloc( sizeof(double[n+1][n+1]) );
언급URL : https://stackoverflow.com/questions/36794202/freaky-way-of-allocating-two-dimensional-array
'itsource' 카테고리의 다른 글
| Java에서 개체 배열을 문자열 배열로 변환하는 방법 (0) | 2022.08.16 | 
|---|---|
| Vue에서 구성 요소가 생성되었을 때 기능을 구현하는 방법은 무엇입니까? (0) | 2022.08.16 | 
| vuejs에서 제목 태그를 동적으로 바인딩 (0) | 2022.08.16 | 
| Vuex에 있는 다른 상점의 getter를 어떻게 부르죠? (0) | 2022.08.16 | 
| Vuejs 자 컴포넌트 입력과 함께 폼 제출 (0) | 2022.08.16 |