C의 동적 다차원 어레이를 사용하는 방법은 무엇입니까?
C를 사용하여 동적으로 할당된 다차원 어레이를 사용할 수 있는 방법을 아는 사람이 있습니까?가능할까요?
C99부터 C에는 동적 경계가 있는 2D 어레이가 있습니다.이러한 비스트가 스택에 할당되지 않도록 하려면(필요한 경우) 다음과 같이 한 번에 쉽게 할당할 수 있습니다.
double (*A)[n] = malloc(sizeof(double[n][n]));
이치노에 2D로 수 있기 때문에 할 수 .A[i][j]
마지막에 있는
free(A);
Randy Meyers는 가변 길이 배열(VLA)에 대해 설명하는 일련의 기사를 작성했습니다.
동적 할당의 경우 malloc 사용:
int** x;
x = malloc(dimension1_max * sizeof(*x));
for (int i = 0; i < dimension1_max; i++) {
x[i] = malloc(dimension2_max * sizeof(x[0]));
}
//Writing values
x[0..(dimension1_max-1)][0..(dimension2_max-1)] = Value;
[...]
for (int i = 0; i < dimension1_max; i++) {
free(x[i]);
}
free(x);
가 2D인 됩니다.dimension1_max
*dimension2_max
640 어레이(이미지 640*480을 dimension1_max
, = 640dimension2_max
. 그런 = 480을 사용하여 수 그런 다음 다음을 사용하여 어레이에 액세스할 수 있습니다.x[d1][d2]
서 ''는d1
, = 0.639d2
0 . 479. = 0 . 479 .
그러나 SO 또는 Google에서 검색하면 예를 들어 이 SO 질문에서 다른 가능성을 발견할 수 있습니다.
이 경우 어레이는 메모리의 인접 영역(640*480바이트)을 할당하지 않으므로 이를 가정하는 기능에 문제가 발생할 수 있습니다.따라서 어레이가 조건을 만족시키려면 위의 malloc 블록을 다음과 같이 바꿉니다.
int** x;
int* temp;
x = malloc(dimension1_max * sizeof(*x));
temp = malloc(dimension1_max * dimension2_max * sizeof(x[0]));
for (int i = 0; i < dimension1_max; i++) {
x[i] = temp + (i * dimension2_max);
}
[...]
free(temp);
free(x);
기본
은 c를 사용하여 및 .[]
int ary1[5];
는 5개의 정수로 이루어진 배열을 선언합니다.가 매겨지기 때문에 0부터 매겨집니다.ary1[0]
요소, 첫 번째 요소입니다.ary1[4]
마지막 요소입니다.메모 1: 디폴트의 초기화는 없기 때문에, 어레이가 최초로 사용하고 있는 메모리에는 아무것도 포함되어 있지 않습니다.주의 2:ary1[5]
정의되지 않은 상태(접근할 수 없을 수도 있음)에서 메모리에 액세스하기 때문에 사용하지 마십시오.
다차원 어레이는 어레이 어레이로 구현됩니다(어레이의 (...)).그렇게
float ary2[3][5];
는 각각5개의 부동소수점 번호의 3개의 1차원 배열로 이루어진 배열을 선언합니다., 이제ary2[0][0]
는 첫 의 첫 입니다.ary2[0][4]
는 첫 배열의 이며, 、 번 、 is 、 is 、 of of of of is is is is is is of is is is is is is is 。ary2[2][4]
는 마지막 배열의 마지막 요소입니다.89년 기준에서는 이 데이터는 연속되어야 하지만(내 K&R 2차 페이지 216의 A8.6.2 참조), 패딩에 대해서는 불가지론적인 것으로 보인다.
둘 이상의 차원으로 동적 전환을 시도하고 있습니다.
컴파일 시 어레이 크기를 모를 경우 어레이를 동적으로 할당할 수 있습니다.시도해 보는 것은 유혹적이다.
double *buf3;
buf3 = malloc(3*5*sizeof(double));
/* error checking goes here */
컴파일러가 할당 패드를 채우지 않으면 동작합니다(1차원 배열 사이에 여분의 공간이 있습니다).다음 제품을 사용하는 것이 더 안전할 수 있습니다.
double *buf4;
buf4 = malloc(sizeof(double[3][5]));
/* error checking */
쓸 수buf[i][j]
buf
잘못된 유형을 가집니다. 사용할 수 .
double **hdl4 = (double**)buf;
hdl4[2][3] = 0; /* Wrong! */
는 '예상'을 기대하기 입니다.hdl4
더블 주소의 주소입니다. 사용하실 수 .double incomplete_ary4[][];
이치노
그래서 뭘 할 수 있죠?
- 행과 열을 직접 계산하십시오.
- 함수에서 작업 할당 및 수행
- 포인터 배열을 사용합니다(qrdl이 말하는 메커니즘).
계산은 네가 해라
다음과 같이 각 요소에 대한 메모리 오프셋을 계산합니다.
for (i=0; i<3; ++i){
for(j=0; j<3; ++j){
buf3[i * 5 + j] = someValue(i,j); /* Don't need to worry about
padding in this case */
}
}
함수에서 작업 할당 및 수행
필요한 크기를 인수로 사용하는 함수를 정의하고 정상적으로 진행합니다.
void dary(int x, int y){
double ary4[x][y];
ary4[2][3] = 5;
}
이 는, 「 」입니다.ary4
는 로컬 변수이므로 반환할 수 없습니다.배열을 사용한 모든 작업은 호출하는 함수로 수행해야 합니다.
포인터 배열
다음 사항을 고려하십시오.
double **hdl5 = malloc(3*sizeof(double*));
/* Error checking */
for (i=0; i<3; ++i){
hdl5[i] = malloc(5*sizeof(double))
/* Error checking */
}
, 이제hdl5
는 각각 더블 배열을 가리키는 포인터의 배열을 가리킵니다.하여 이 수 것입니다. - 비 、 2 차 、 2 차 、 는 、 는는는는는는 。hdl5[0][2]
.- 이것은 첫첫행행 -- -- -- gets- gets- gets- gets - - - by 。-그그 그차 차 2 차차차 차차 차차 차차차 gets gets gets gets gets gets gets gets gets gets gets by by by by2차원 입니다.double ary[3][5];
.
이 구조는 2차원 배열보다 유연하지만(행의 길이가 같을 필요는 없기 때문에) 일반적으로 접근 속도가 느리고 메모리도 더 많이 필요합니다(중간 포인터를 보관할 장소가 필요).
가드를 설정하지 않았기 때문에 모든 어레이의 사이즈는 사용자가 직접 파악해야 합니다.
산술
c는 벡터, 행렬 또는 텐서 수학에 대한 지원을 제공하지 않습니다. 사용자가 직접 구현하거나 라이브러리를 가져와야 합니다.
스케일러에 의한 곱셈이나 같은 등급의 어레이의 덧셈과 감산은 간단합니다.요소에 루프하여 그대로 조작하기만 하면 됩니다.이너 제품도 마찬가지로 직설적입니다.
외부 제품은 더 많은 루프를 의미합니다.
컴파일 시 열의 수를 알고 있다면 매우 간단합니다.
#define COLS ...
...
size_t rows;
// get number of rows
T (*ap)[COLS] = malloc(sizeof *ap * rows); // ap is a *pointer to an array* of T
를 할 수 있다ap
2D:
ap[i][j] = x;
작업을 마치면 할당해제합니다.
free(ap);
컴파일 시 컬럼의 수를 알 수 없지만 가변장 배열을 지원하는 C99 컴파일러 또는 C2011 컴파일러를 사용하는 경우 다음과 같이 매우 간단합니다.
size_t rows;
size_t cols;
// get rows and cols
T (*ap)[cols] = malloc(sizeof *ap * rows);
...
ap[i][j] = x;
...
free(ap);
컴파일 시 열의 수를 알 수 없고 가변 길이 배열을 지원하지 않는 C 버전을 사용하는 경우 다른 작업을 수행해야 합니다.모든 요소를 (일반 어레이와 같이) 연속된 청크에 할당해야 하는 경우 메모리를 1D 어레이로 할당하고 1D 오프셋을 계산할 수 있습니다.
size_t rows, cols;
// get rows and columns
T *ap = malloc(sizeof *ap * rows * cols);
...
ap[i * rows + j] = x;
...
free(ap);
메모리를 연속적으로 사용할 필요가 없는 경우는, 다음의 2 단계의 할당 방법을 실행할 수 있습니다.
size_t rows, cols;
// get rows and cols
T **ap = malloc(sizeof *ap * rows);
if (ap)
{
size_t i = 0;
for (i = 0; i < cols; i++)
{
ap[i] = malloc(sizeof *ap[i] * cols);
}
}
ap[i][j] = x;
할당은 2단계 프로세스이므로 할당 해제도 2단계 프로세스여야 합니다.
for (i = 0; i < cols; i++)
free(ap[i]);
free(ap);
malloc이면 됩니다.
int rows = 20;
int cols = 20;
int *array;
array = malloc(rows * cols * sizeof(int));
도움말에 대해서는 다음 문서를 참조하십시오.
http://courses.cs.vt.edu/~cs2704/spring00/mcquain/Notes/4up/Managing2DARays.pdf
.make_3d_array
N1
,N2
★★★★★★★★★★★★★★★★★」N3
각 차원에 있는 요소를 랜덤 번호로 채웁니다. 표기법을 할 수 있습니다.A[i][j][k]
그 요소에 액세스 할 수 있습니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Method to allocate a 2D array of floats
float*** make_3d_array(int nx, int ny, int nz) {
float*** arr;
int i,j;
arr = (float ***) malloc(nx*sizeof(float**));
for (i = 0; i < nx; i++) {
arr[i] = (float **) malloc(ny*sizeof(float*));
for(j = 0; j < ny; j++) {
arr[i][j] = (float *) malloc(nz * sizeof(float));
}
}
return arr;
}
int main(int argc, char *argv[])
{
int i, j, k;
size_t N1=10,N2=20,N3=5;
// allocates 3D array
float ***ran = make_3d_array(N1, N2, N3);
// initialize pseudo-random number generator
srand(time(NULL));
// populates the array with random numbers
for (i = 0; i < N1; i++){
for (j=0; j<N2; j++) {
for (k=0; k<N3; k++) {
ran[i][j][k] = ((float)rand()/(float)(RAND_MAX));
}
}
}
// prints values
for (i=0; i<N1; i++) {
for (j=0; j<N2; j++) {
for (k=0; k<N3; k++) {
printf("A[%d][%d][%d] = %f \n", i,j,k,ran[i][j][k]);
}
}
}
free(ran);
}
모든 것을 한 번에 할당하는 방법은 없습니다.대신 포인터의 배열을 만들고 포인터별로 포인터의 메모리를 만듭니다.예를 들어 다음과 같습니다.
int** array;
array = (int**)malloc(sizeof(int*) * 50);
for(int i = 0; i < 50; i++)
array[i] = (int*)malloc(sizeof(int) * 50);
은 론론음음음음음음음음음음음음 the the the라고 도 있습니다.int* array[50]
첫 번째 malloc은 건너뛰지만 필요한 스토리지를 동적으로 할당하려면 두 번째 세트가 필요합니다.
한 번에 할당하는 방법을 해킹하는 것은 가능하지만, 커스텀 룩업 기능이 필요하지만 항상 작동하도록 쓰는 것은 귀찮을 수 있습니다.를 들면, '하다, 하다, 하다' 같은 경우가 있습니다.L(arr,x,y,max_x) arr[(y)*(max_x) + (x)]
후 50*L
크 、 : :
#define L(arr,x,y,max_x) arr[(y)*(max_x) + (x)]
int dim_x = 50;
int dim_y = 50;
int* array = malloc(dim_x*dim_y*sizeof(int));
int foo = L(array, 4, 6, dim_x);
하지만 프리프로세서 매크로로 하고 있는 일의 효과를 모르는 한, 이것은 훨씬 더 악랄한 것입니다.
int rows, columns;
/* initialize rows and columns to the desired value */
arr = (int**)malloc(rows*sizeof(int*));
for(i=0;i<rows;i++)
{
arr[i] = (int*)malloc(cols*sizeof(int));
}
// malloc를 사용하면 메모리 누수가 발생하므로 malloc 대신 new를 사용합니다.여기에 코드를 입력합니다.
int **adj_list = new int*[rowsize];
for(int i = 0; i < rowsize; ++i)
{
adj_list[i] = new int[colsize];
}
언급URL : https://stackoverflow.com/questions/917783/how-do-i-work-with-dynamic-multi-dimensional-arrays-in-c
'programing' 카테고리의 다른 글
오류: [vuex]에서 문자열이 유형으로 예상되지만 정의되지 않았습니다. (0) | 2022.07.27 |
---|---|
vuejs2는 사용자가 @ 키를 눌렀는지 여부를 수신합니다. (0) | 2022.07.27 |
Vue SPA - 브라우저에서 렌더링할 때 .vue 파일을 숨기는 방법 (0) | 2022.07.27 |
클릭 시 특정 (이) 버튼 클래스를 변경하는 방법Vue.js 2.0 사용 (0) | 2022.07.27 |
경로의 File.separator와 슬래시의 차이 (0) | 2022.07.27 |