2009-12-13 10 views
0

2 차원 배열에 문제가 있습니다. (매우 어리 석고 Visual C가 도움이되지 않습니다. (또한 내 실수는 매우 어리 석다 고 생각하지만 여전히 찾을 수 없습니다. :(이 코드가 있습니다포인터가있는 C++ 2 차원 배열

double matrix[100][100]; //which is full with a matrix 3x4 
double nVector[10000]; // for negative doubles 
//I wanted to see if there are negative doubles in each row and column 
//and I want this to happen with function 

을 그리고이 제 기능입니다 : 나는 누군가가 (나를 도울 수 있기를 바랍니다 *(*(myMatrix+i)) : 여기에 불법 간접 : 나는 오류 C2100을 가지고

double* negativeVector(double*nVector, double*fromVector, int m, int n){ 
    int position = 0; 

    double *myNegArray = nVector; 
    double *myMatrix = fromVector; 

    for(int i = 0; i < m*n; i++) 
     if(*(*(myMatrix+i)) < 0){ 
      *(myNegArray+position) = *(*(myMatrix+i)); 
      position++; 
     } 

    return myNegArray; 
} 

//for double*nVector I'm passing nVector 
//for double*fromVector I'm passing *matrix 

비주얼 C가 나에게 말한다 행복)

미리 감사드립니다!

+1

왜 std :: vector를 사용하지 않습니까? 또한 Visual C++의 컴파일러가 올바른 것을 말하고 있습니다 ... – Partial

+0

영어로 무슨 일이 일어나고 있는지 알고 싶다면 myMatrix + i로 시작해서 무슨 일이 일어나고 있는지 산문을 작성하십시오. 그런 다음 첫 번째 '*'에 이어 두 번째에 대해서도 동일한 작업을 수행하십시오. 어딘가에 당신이하려고하는 것이 의미가 없으므로 컴파일러가 옳다는 것을 알게 될 것입니다. –

+0

와우 사람들 감사합니다. – r1seUp

답변

2

*(*(myMatrix+i))이 잘못되었습니다. 이것은 흔한 실수입니다.

2D 매트릭스는이 방법으로 액세스 할 수있는 포인터의 배열을 생성하지 않습니다. 그것은 다른 구조입니다. 배열이 포인터이더라도 2D 배열은 포인터에 대한 포인터가 아니며 두 번 반복해서 참조 할 수는 없습니다. 모든 행의 포인터를 찾을 수 없으므로 메모리의 레이아웃을 모른 채 좌표 (x, y)에서 요소에 액세스하는 다른 방법이 없습니다. 예를 들어, char **argv main()의 매개 변수는 2D 배열이 아닙니다. 배열에 대한 포인터의 배열입니다. 다른 포인터입니다.

두 가지 방법으로 해결할 수 있습니다.

하나는

double *myMatrix[100] = (appropriate cast)fromVector; 

에 의해

double *myMatrix = fromVector; 

을 대체하고 인덱스에게 그것을 myMatrix[i/n][i%n]

그러나 다음 (100)는 상수 표현식이며,이 매개 변수로 전달 될 수 없음을 기억합니다. 다른 방법으로는 인덱싱 작업을 직접 구현할 수 있습니다

  • 패스 추가 매개 변수 : 매트릭스 라인 크기 대신 *(*(myMatrix+i))의 (100)
  • 을 쓰기 :

    int row = i/n;
    int col = i%n;
    *(myMatrix+row*line_size+col)이 요소입니다 .

+0

"배열이 포인터이더라도 2D 배열은 포인터에 대한 포인터가 아닙니다." 해야합니다 : 배열이 포인터 인 경우, 2 차원 배열은 포인터에 대한 포인터입니다 (2 차원 배열은 배열의 배열이기 때문에). 이 버그는 배열이 포인터가 아니라는 것입니다. 그런 다음 2 차원 배열도 포인터에 대한 포인터가 아닙니다. 또한 2 차원 배열 *은 두 번 역 참조 될 수 있습니다. 즉, ** 행렬은 전적으로 가능합니다. –

+0

두 번째 "대체 선언"의 경우에는 double (* myMatrix) [100] = (double (*) [100]) fromVector;와 같이 표시되어야하지만 100 개의 상수가 여기에 표시됩니다. 따라서 제안 된 산술 연산을 사용할 수는 있지만, 단지 * (myMatrix + i)를 수행하는 더 복잡한 방법처럼 보입니다 (먼저 행과 열을 가져올 필요가 없습니다. 나중에 함께 추가 할 필요가 없습니다). @partial과 나 자신. –

0

난 당신이 (한 번 기능과 새로운 배열을 선언하여 두 번째의 매개 변수)를 두 번 배열을 복사하는 이유 단서가 없다 ... 당신은 또한 STL을 사용하여 생각해야 ... 표준 : : 벡터는 당신의 인생이 방법 쉽게 할 것이다, 당신은 *matrix을 통과하는 경우

double* negativeVector(double*nVector, double*fromVector, int m, int n){ 
    int position = 0; 

    double *myNegArray = nVector; 
    double *myMatrix = fromVector; 

    for(int i = 0; i < m*n; i++) 
     if(*((myMatrix+i)) < 0){ 
       *(myNegArray+position) = *((myMatrix+i)); 
       position++; 
     } 

    return myNegArray; 
} 
+0

나는 이것이 그들이 원하는 것이 아니라고 생각한다. 그들은 최상위 행의 첫 번째 m * n 요소가 아닌 크기 m * n의 정사각형을 인덱싱하려고했습니다. –

+1

@Pavel, 만약'm'과'n'이 각각 100이라면 (나는 그것들이 행과 열의 크기라고 생각합니까?),이 코드는 전체 사각형을 올바르게 색인 할 것입니다. –

1

), 당신은 실제로 통과되는 double[100] (포인터로 전달 될 일 100 두 배의 배열), 그 첫 번째 요소. 해당 포인터에 i을 사용하여 100 개의 두 배가 넘는 경우, 100 개의 두 배 100 배열이 서로 옆에 저장되므로 100 개의 두 배 배열로 넘어갑니다.

배경 : 다차원 배열은 요소 유형이 자체 배열 인 배열입니다.double a[100][100];과 같은 배열은 typedef double aT[100]; aT a[100];과 동등하게 선언 할 수 있습니다. 포인터와 같은 배열을 사용하면 임시 포인터가 배열의 첫 번째 요소 (배열 일 수 있음)에 만들어집니다. * 연산자가 이와 같은 연산이며 *a을 수행하면 double(*)[100] (100 개의 2 배 배열에 대한 포인터) 유형의 포인터가 만들어지고 역 참조됩니다. 따라서 *matrix으로 끝나는 부분은 double[100]입니다. negativeVector 함수에 전달하면 첫 번째 요소 인 double*에 대한 포인터가 생성됩니다.

포인터 매개 변수는 각각 100 개의 두 배로 구성된 두 개의 배열 각각을 가리 킵니다. 그래서 당신은 2 차원 배열에 저장된 (100 개) 배열의 첫 번째 넘어 귀하의 i 반복하기 때문에, 당신은 공식적으로 이와 정확하지 않을 것이라는 점을

double* negativeVector(double*nVector, double*fromVector, int m, int n){ 
    int position = 0; 

    double *myNegArray = nVector; 
    double *myMatrix = fromVector; 

    for(int i = 0; i < m*n; i++) 
     if(*(myMatrix + i) < 0){ 
       *(myNegArray + position) = *(myMatrix + i); 
       position++; 
     } 

    return myNegArray; 
} 

공지 사항으로 기능을 다시 작성해야합니다. 그러나 배열이 서로 옆에 할당되어야하므로 실제적으로 작동 할 것입니다 (사실, 다차원 배열을 첫 번째 스칼라 요소에 대한 포인터로 전달하는 데 충분한 작업으로 권장됩니다).

1

먼저

struct tmp { 
    bool negative; 
    double value; 
}; 

처럼 작은 구조체를 시작 싶어 수도와

tmp *myvars [100][100]; 

까지 자신의 길을.
대신 그 구조체를 사용하여 시도하고 그 다음 내가
위에 말한대로 변수를 선언 할 때 "1 회"다음 인수

(tmp *mystructpointer) 
    mystructpointer->....... 

을 통과 변수를 decalring에 포인터를 사용하려고 가능하다면 배열 대신 std::vectors 시도 직접 매트릭스에 액세스하십시오 ... 케이크의 조각 : D

+0

'Pavel Radzivilovsky'가 말한 바도 마찬가지입니다. 2D 어레이는 정상적인 arry와는 다릅니다. msdn (나는 짐작할 수 있지만) 올바른 링크를 찾을 수 없습니다. – VirusEcks

0

그 숙제입니까? 일부 템플릿 - 그냥 재미를 위해서 ;-)

double matrix[100][100]; 
double nVector[10000]; 

template< const int m, const int n > 
double* negativeVector(double* myNegArray, const double (&myMatrix)[m][n]) 
{ 
    int position = 0; 

    for(int i = 0; i < m; ++i) 
    { 
     for(int j = 0; j < n; ++j) 
     { 
      const double value = myMatrix[ i ][ j ]; 
      if (value < 0) 
      { 
       myNegArray[ position ] = value; 
       ++position; 
      } 
     } 
    } 

    return myNegArray; 
} 

int main() 
{ 
    //...initialize matrix here... 
    negativeVector(nVector, matrix); 
} 
0

가독성을 높이기 위해 std :: vector를 사용하여 이것을 다시 작성 하시겠습니까? 함수가 완료되면 nVector 매트릭스 모두 음수를 포함

negativeVector(nVector, matrix); 

(# 1) :

//I'm returning void because nvector contains the result, 
//so I don't feel the need to return anything. vectors contain their 
//own size so n and m are also not needed. Alsom pass in references 
void negativeVector(std::vector<double>& nVector, 
        std::vector< std::vector<double> >& fromVector){ 
    nVector.clear(); 
    int i,j; 
    for(i = 0; i < fromVector.size(); i++) { 
     for(j = 0; j < fromVector[i].size(); j++) { 
      if(fromVector[i][j] < 0){ 
       nVector.push_back(fromVector[i][j]); 
      } 
     } 
    } 
} 

호와 :

#include <vector> 
std::vector< std::vector<double> > matrix; //which is full with a matrix 3x4 
std::vector<double> row; 
row.resize(100,0); 
matrix.resize(100,row); 
std::vector<double> nVector; // for negative doubles, no size, we'll "push_back" 
//I wanted to see if there are negative doubles in each row and column 
//and I want this to happen with function 

이 함수의 STL 가능 버전 .

std::vectorhere에 대해 자세히 알아보십시오.

(#) 포인터가 포함 된 코드를 이해하기에는 너무 게으르고/어리 석습니다.

0

C++ Faq 사이트를 살펴보십시오. new를 사용하여 다차원 배열을 어떻게 할당합니까?지점까지

link

및 읽기는 [16.20]를지고 모든 대답을 요약하고 마지막에 당신은 매우 유용한 매트릭스 템플릿 클래스를 돌려줍니다. 잘 읽으십시오.