2012-04-20 13 views
1

저는 Matrix 클래스를 작성하려고 노력해 왔습니다. 그리고 그것을 테스트하기 위해 main 메소드를 사용하고 있습니다. 그것은 전혀 작동하지 않습니다 ... 전혀.C++의 Matrix 클래스?

size (allRowValues의 크기를 double 크기로 나눈 값)가 0 인 이유를 알지 못합니다!

저는 디버그 프린트를 작성했지만 도움이되지 않습니다 ... 저는 정말 C++로 새롭고 모든 도움/조언을 부탁드립니다.

1 #include "matrix.h" 
2 #include <iostream> 
3 #include <sstream> 
4 
5 Matrix::Matrix(){ 
6 }; 
7 
8 Matrix::Matrix(int rows, int columns, double allRowValues []){ 
9  this->rows = rows; 
10  this->columns = columns; 
11  this->matrixValues = new double[rows*columns]; 
13  std::cout <<"ALL ROW VALUES" <<std::endl; 
14  std::cout<<"*****" <<std::endl; 
15  std::cout << sizeof (allRowValues) << std::endl; 
16  std::cout<<"*****" <<std::endl; 
17  std::cout << sizeof(allRowValues[0]) << std::endl; 
18  std::cout<<"*****" <<std::endl; 
19  int size = sizeof(allRowValues)/sizeof(double); 
20  int numberOfValues = rows * columns; 
21  int currentIndex = 0; 
22  for (int i = 0; i < numberOfValues; i++){ 
23    std::cout<< "MATRIX CONSTRUCTOR\n"; 
24    std::cout<<allRowValues <<std::endl; 
25    std::cout<<"-----"<<std::endl; 
26    std::cout<<index << std::endl; 
27    std::cout<<"-----"<<std::endl; 
28    std::cout<<size << std::endl; 
29    std::cout<<"-----"<<std::endl; 
30    if ((allRowValues) && (currentIndex < size)){ 
31     std::cout << "ARV " <<std::endl; 
32     std::cout << allRowValues[currentIndex] << std::endl; 
33     this->matrixValues[i]= allRowValues[currentIndex]; 
34     std::cout << "MAT " << allRowValues[currentIndex++] << std::endl; 
35    }else{ 
36     std::cout << "Else\n"; 
37    } 
38   } 
39   int index=0; 
40   for (int j = 0; j < rows; j++){ 
41    for (int i = 0; i < columns; i++){ 
42     std::cout << this->matrixValues[index++]; 
43    } 
44    std::cout<<std::endl; 
45   } 
46  }; 
47 
48  Matrix::Matrix(double* rowValues){ 
49   int sizeRows = sizeof(rowValues)/sizeof(double); 
50   //TODO: throw error for all rows must be the same length 
51   this->rows = sizeRows; 
52   int sizeColumns = sizeof(rowValues[0])/sizeof(double); 
53   this->columns = sizeColumns; 
54   this->matrixValues = rowValues; 
55  }; 
56 
57  double Matrix::width(){ 
58   std::cout << "Width\n"; 
59   return this->columns; 
60  }; 
61 
62  double Matrix::height(){ 
63   std::cout << "Height\n"; 
64   return this->rows; 
65  }; 
66 
67  std::string Matrix::toString(){ 
68   int numberOfValues = 0; 
69   std::cout<<matrixValues[numberOfValues]; 
70   std::string build_output; 
71   std::cout<<matrixValues; 
72   for (int i = 0; i < rows; i++){ 
73    build_output = "["; 
74    std::cout << "\n"; 
75    for (int j = 0; j < columns; j++){ 
76     std::cout << "VALUE: " <<matrixValues[numberOfValues]; 
77     build_output = matrixValues[numberOfValues]; 
78     numberOfValues++; 
79    } 
80    build_output = " ]"; 
81   } 
82   return build_output; 
83  } 
84 
85  int main(){ 
86   double values[6] = {1, 2, 3, 4, 5, 6}; 
87   std::cout <<"Values: \n"; 
88   Matrix a = Matrix(2, 3, values); 
89   std::cout << a.width() << std::endl; 
90   std::cout << a.height() << std::endl; 
91   std::cout << a.toString(); 
92   return 1; 
93 } 
+5

이 숙제입니까? 그렇지 않다면 C++ 용으로 작성된 매우 훌륭한 행렬 라이브러리가 많이 있습니다.이 라이브러리는 직접 처리하는 것보다 훨씬 빠르고 덜 버그가 있습니다. – Shep

+1

직접 해보기로 결정한 경우에도 사용자가 대화식으로 데이터를 입력하도록 강요하지 마십시오. 파일에 데이터를 넣고 파일 이름을 지정하십시오. 이렇게하면 코드가 단순 해지고 사용자에게 오류가 발생하기 쉬워집니다. –

+0

'sizeof'는 나쁜 디자인입니다. 컴파일러가 32 비트에서 8 바이트를, 64 비트에서 16 바이트를 선택하면 어떻게 될까요? 'sizeof'에 의존하지 마십시오. – CppLearner

답변

2

double allRowValues[]은 배열이 아니라 포인터를 선언합니다. sizeof(allRowValues)/sizeof(double) 표현식은 포인터의 크기와 double의 크기 사이의 비율을 계산합니다. 복식이 더 큰 경우 결과는 분명히 0입니다.

어떤 이유로 든 다른 생성자에서도 동일한 실수가 발생하지만 (sizeof(rowValues)/sizeof(double)), 이번에는 분명히 인수가 포인터입니다. 그리고 두 배 배열의 크기 하나의 요소, 즉 double과 double의 크기 사이의 비율 인 sizeof(rowValues[0])/sizeof(double)이 있습니다. 이것은 분명히 하나입니다.

sizeof 연산자가 마술처럼 첫 번째 요소에 대한 포인터가있는 배열의 크기를 알 수 있다고 생각됩니다. 그것은 할 수 없다. 또는 배열과 포인터 사이에 혼란이있을 수 있습니다. 그들은 not the same입니다. , 배열 (double[100] 같은 유형 T[N]의 즉 개체) 자신의 첫 번째 요소에 대한 포인터 단지 붕괴 대부분의 시간

(즉 T*, double* 등) 과정에서 크기 정보를 잃는. 이것이 "배열을 전달하려는"경우 포인터를 전달할 수없는 이유입니다. 크기 정보를 어떻게 든 전달해야합니다.

명시 적으로 크기를 추가 인수로 전달하거나 버퍼의 끝 (반복자 스타일)을 나타내는 다른 포인터를 전달할 수 있습니다. 배열에 대한 참조를 전달할 수도 있습니다 (따라서 포인터에 부식되지 않으므로 크기 정보가 보존됩니다). 그리고 템플릿을 사용하여 크기 정보를 얻습니다.

  • std::vector<std::vector<double>> : 당신은 기성품 솔루션을 사용하는 경우 이제 이러한 문제를 이해

    template <std::size_t N, std::size_t M> 
    void pass_a_2d_array_by_reference(double(&the_array)[N][M]) { // N and M are the sizes 
        // do stuff 
    } 
    

    , 당신은 그들을 전혀-수 없습니다 그것은 매우 좋은 해결책 경우입니다 연속 저장이 필요하지 않습니다. 지그재그 배열을 원할 경우 가장 좋은 방법이기도합니다.

  • boost::multiarray<double, 2> : 더 많은 차원의 배열과 마찬가지로 잘 작동하는 또 다른 훌륭한 솔루션입니다.
  • 다양한 요구에 따라 기존 솔루션이 많이 있습니다. 주변을 둘러보세요.
+0

나는 또한 간단한 2 차원 행렬 클래스 템플릿을 작성했다.이 템플릿은 학습 연습 일 경우에 살펴보고 아이디어를 얻을 수있다. http://ideone.com/gytw7 –

+0

템플릿 생성자를 제공하는 것이 가치가있다. C 스타일 행렬 (일반적으로'const' 및'static')에서 초기화를 허용하기 위해'template Matrix :: Matrix (double (& init) [N] [M])' –

+0

예! 나는 당신이 코멘트를 썼을 때 그것을 덧붙였다 : –

-1

C 스타일 배열 double allRowValues[] 대신 std::vector<double>& (또는 std :: array)을 사용해야합니다. 따라서 크기를 allRowValues.size()으로 쉽게 얻을 수 있습니다.

C++ 자주 묻는 질문 라이트 : Why should I use container classes rather than simple arrays?

참조 :
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/container/array

+0

_should_를 _could_로 변경하면 추가 생성자 일지라도 _-_ _에 대한 논쟁을 원할 것입니다. – Shahbaz

+0

. 이 경우 C 스타일의 행렬에서 크기를 가져와야하며, 템플릿 생성자를 사용하고 'double *'을 취하지 않아도되지만 C 스타일 행렬에서 초기화를 지원하는 좋은 주장이 있습니다. –

+0

@Shahbaz 이해가 안됩니다. C++ 벡터에 비해 c- 배열의 장점은 무엇입니까? 그런 다음 C 스타일의 행렬에 대해서, 행렬 차원이 템플릿 인수 인 경우 플러스를 봅니다. 이 경우에는'std :: array , n>'이있다. – log0

0

당신이 (내가 추천하지 않는) C 스타일 배열을 주장하는 경우 당신은 또한 템플릿 솔루션을 사용할 수 있습니다 :

template<int size> 
Matrix::Matrix(int rows, int columns, double (&allRowValues) [size]){ 
... 
} 

전반적으로, 나는 선반, 0123와 같은 허용 오픈 소스 매트릭스 라이브러리.

+0

-1로 설명해 주겠니? – enobayram