1

Matrix クラスを作成しようとしており、main メソッドを使用してテストしています。それは機能していません...まったく。

サイズ (allRowValues のサイズを double のサイズで割った値) がゼロである理由がわかりません!

私はいくつかのデバッグ プリントを書いていますが、役に立ちません... 私は本当に 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 }
4

3 に答える 3

2

double allRowValues[]配列ではなくポインタを宣言します。次に、この式sizeof(allRowValues)/sizeof(double)は、ポインターのサイズと のサイズの比率を計算しますdouble。double の方が大きい場合、結果は明らかにゼロです。

なぜか他のコンストラクタでも同じミスが起きますが( sizeof(rowValues)/sizeof(double))、今回の引数は明らかにポインタです。次にsizeof(rowValues[0])/sizeof(double)、double の配列の 1 つの要素のサイズ、つまり double と double のサイズ (明らかに 1) の比率です。

sizeofオペレーターは、最初の要素へのポインターが与えられた配列のサイズを魔法のように知ることができるという信念があるようです。できません。または、配列とポインターが混同されている可能性があります。それらは同じではありません

T[N]ほとんどの場合、配列 (つまり、 などの型のオブジェクト) は最初の要素 (つまり、 など)double[100]へのポインターに減衰し、その過程でサイズ情報が失われます。これが、「配列を渡す」つもりなら、ポインタを渡すことができない理由です。何らかの方法でサイズ情報を渡す必要があります。T*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
}

これらの問題を理解したので、市販のソリューションを使用すれば、これらの問題をまったく解決できません。

  • std::vector<std::vector<double>>: 連続したストレージが必要ない場合、これは非常に優れたソリューションです。ギザギザの配列が必要な場合にも最適です。
  • boost::multiarray<double, 2>: さらに多くの次元の配列でも同様に機能する、もう 1 つの非常に優れたソリューションです。
  • さまざまなニーズに対して、他にも多くの既存のソリューションがあります。周りを見回してください。
于 2012-04-20T16:42:51.283 に答える
0

Cスタイルの配列(私はお勧めしません)を主張する場合は、テンプレート化されたソリューションを使用することもできます。

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

全体として、 eigenなどの既成のパーミッシブオープンソースマトリックスライブラリをお勧めします。

于 2012-04-20T17:07:19.333 に答える
-1

std::vector<double>&c-style array の代わりに a (または std::array)を使用する必要がありますdouble allRowValues[]。したがって、 でそのサイズを簡単に取得できますallRowValues.size()

c++ faq-lite:単純な配列ではなくコンテナ クラスを使用する必要があるのはなぜですか?

参照:
http://en.cppreference.com/w/cpp/container/vector
http://en.cppreference.com/w/cpp/container/array

于 2012-04-20T16:46:55.590 に答える