문제

2 차원 배열을 선언 할 때

int random[height][width];

그런 다음 함수에서 사용합니다

void populate(int random[height][width], int x, int y)

모든 함수 외부에 선언 된 오류 변수 크기 유형을 제공합니다. 나는 내가 뭔가 잘못하고 있다는 것을 알고 있습니다. 나는 단지 기억이 나쁘다 ...

도움이 되었습니까?

해결책

나는 지금 강화하고 다차원 배열이 C 또는 C ++의 뇌 노력의 가치가 없다고 말할 것입니다. 단일 차원 배열 (또는 더 나은 표준 컨테이너)을 사용하고 인덱싱 기능을 작성하는 것이 훨씬 좋습니다.

inline int index (int x, int y)
{
  return x + y * width;
}

이제 당신의 문제에 대해. C ++는 C99 가변 길이 배열을 지원하지 않습니다. 컴파일러는 컴파일 시간에 배열의 크기를 알아야합니다. 예를 들어 다음은 작동하지 않습니다.

int dim = 4;
int ar[dim];

만약에 dim ~이었다 const, 컴파일러가 정확히 얼마나 넓은지를 알 수 있기 때문에 작동합니다. ar (가치 때문에 dim 변하지 않을 것입니다). 이것은 아마도 당신이 직면 한 문제 일 것입니다.

컴파일 타임에 크기를 변경하려면 템플릿 참조를 작성하는 것과 같이 더 어려운 일을해야합니다. C/C ++에 배치 된 방식으로 인해 다차원 배열에 대한 포인터를 사용할 수 없습니다. 템플릿 예제는 다음과 같은 수차처럼 보일 수 있습니다.

template <int Width, int Height>
void populate(int (&(&random)[Width])[Height], int x, int y);

이것은 추악합니다.

런타임에는 사용해야합니다 new 데이터를 할당하거나 컨테이너 유형을 사용합니다.

다른 팁

컴파일 타임에서 치수가 알려지지 않기 때문에 기능 외부에서 비 스턴트 치수 (너비, 높이)로 배열을 정의 할 수 없습니다. 상수를 사용하거나 동적으로 (힙 또는 스택 프레임에) 동적으로 할당해야합니다.

배열이 매개 변수로 직접 전달되면 (전달 값) 배열의 첫 번째 요소에 대한 포인터로 감소합니다. 서명에서 배열의 크기를 명확하게 읽을 수 있더라도 해당 크기는 컴파일러에 의해 무시됩니다. 그 행동은 C와 호환됩니다.

C ++를 사용하면 더 이상 배열을 참조 할 수 있으며 더 이상 문제가되지 않습니다.

int extract_value( int (&a)[10][10], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[10][10] = {};
   a[5][5] = 1;
   std::cout << extract_value( a, 5, 5 ) << std::endl;
   int b[5][5];
//   extract_value( b, 2, 2 ); // error: the function takes an array of 10x10
}

함수 매개 변수는 정확히 일치해야합니다. 즉, 10x10 요소의 배열 만 필요합니다. 배열 크기의 함수를 템플릿으로하여 해당 제한을 제거 할 수 있습니다. 일단 당신이 그것에 있으면 유형도 있습니다.

template <typename T, int Rows, int Cols>
T extract_value( T (&a)[Rows][Cols], int row, int col ) {
   return a[row][col];
}
int main() {
   int a[5][7] = {};
   extract_value( a, 3, 4 );
   int b[8][2] = {};
   extract_value( b, 7, 1 ); // correct, the compiler matches sizes
   double c[4][4] = {};
   extract_value( c, 2, 2 ); // different types are allowed
}

이 솔루션은 크기가 시간 상수를 컴파일해야하며 배열을 쌓아야한다는 점에서 여전히 번거 롭습니다. 이에 대한 해결책은 버퍼 (선형)에서 동적 메모리를 취하고 n- 코디네이트 시스템에서 1 차원 배열로 변환하여 이전에 제안 된 바와 같이 값을 얻는 일부 클래스를 정의하는 것입니다. 이것에서 그것을하는 방법에 대한 힌트를 얻을 수 있습니다. 자주하는 질문 2D 매트릭스 구현을 제공하는 연산자 과부하에 대해. 구현 된 후에는 함수/메소드의 매개 변수로 사용할 수 있습니다.

내 권장 사항은이 마지막 경로를 따르는 것입니다. N- 차원 배열을 1D 벡터로 전환하는 클래스로 캡슐화합니다 (C ++ FAQ 라이트는 원시 포인터를 사용하고 STL 컨테이너를 선호합니다).

나는 예를 들어 다음과 같이 설명 할 것이다.

// 글로벌

const int ARRAY_SIZE = 16 struct ArrayType_t arrayType[ARRAY_SIZE];

Array_Size가 일정한 int로 선언 되더라도 컴파일 시간에 값이 초기화되지 않으므로 컴파일러는 배열의 크기를 알지 못하고 그러한 오류를 제공합니다. 그러나 해시 정의로 만들 경우#define ARRAY_SIZE 16 struct ArrayType_t arrayType[ARRAY_SIZE] ===> array_size는 컴파일 시간에 정의되며 컴파일러는 컴파일 시간에 배열의 크기를 알 수 있기 때문에 작동합니다.

다음과 같은 것을 사용할 수 있습니다.

void populate(int height, int width, int **random)
{
    //here you can work from random[0][0] to random[height][width]
}

그런 다음 다음과 같이 사용할 수 있습니다.

int main()
{
    int height=10;
    int width=20;
    int **myarray = new int*[height];
    for( int i=0; i< height; i++ ) myarray[i] = new int[width];
    populate( height, width, myarray);
}

그러나 물론, 당신은 버퍼 오버플로를 조심해야 할 것입니다

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top