2012-03-12 12 views
0

ファイルから標高値を2次元配列と行列に読み込み、その配列を別の関数に渡そうとしているプログラムで作業しています最大値。私は、デフォルトで配列が参照渡しされることを理解していますが、関数の配列の値を変更しようとしていないので、これはあまり重要ではありません。私は配列を呼び出すことに関するいくつかのページを見てきましたが、私はコードをコンパイルするときに私が得ているエラーのタイプの言及を見つけることができませんでした。この問題は、呼び出される引数の数や呼び出される方法にあるように思われますが、関数のさまざまな外観には矛盾が見られません。私の推測では、2次元配列を渡すことについて何かがあります。私はクラスでは言わなかったし、自分ではまだ学習していないということです。どんな助けでも大歓迎です。 コードは次のとおりです。二次元配列を二重に渡す際のエラーfunction_name

エラー:ダブル(*)[(((ロングunsigned int型)(((長い」変換することはできません

#include <fstream> 
#include <iostream> 
#include <string> 
#include <cstdlib> 

using namespace std; 

// First instance of function declaration 
double find_max(double elevations[][3600], double ilat, double ilon, int nlat, int nlon); 

int main(int argc, char *argv[]) { 

// Declare program variables 
double lat_init, lon_init; 
double lat_res, lon_res; 
double peak, valley; 
int lon_col, lat_row; 
string indat, inpoints; 
. 
. 
. 
double elevations[lat_row][lon_col]; 

// Open and read topographic data file 
ifstream topo_points; 
topo_points.open(inpoints.c_str()); 

for (int i=0; i<lat_row; i++) { 
    for (int j=0; j<lon_col; j++) 
     topo_points >> elevations[i][j]; 
} 

// Call function to find peak in the data 
peak = find_max(elevations, lat_init, lon_init, lat_row, lon_col); 

return 0; 

} 


// ***** Here lie the functions ***** 

// This function reads in the array of elevations, initial latitude and longitude 
// of the data, and the number of data points and uses this information to find 
// the latidude and longitude of the highest point on earth 
double find_max(double elev[][3600], double ilat, double ilon, int nlat, int nlon) { 

double num, max; 
double latpos, lonpos; 

max = 0; 

for (int i=0; i<nlat; i++) { 
    for (int j=0; j<nlon; j++) { 
    num = elev[i][j]; 
    if (num > max) { 
     max=num; 
     latpos= ilat - i; 
     lonpos= ilon + j; 
    } 
    } 
} 

cout << "The tallest peak on earth has an altitude of " << max; 
cout << " and is located at " << latpos << "deg latitude and "; 
cout << lonpos << "deg longitude"; 

return max; 
} 

しかし、私は次のエラーを取得する関数を呼び出すとき'double'(double(*)[3600]、double、double、int、int) 'に' 1 'を指定するとdouble(*)[3600]

+0

lon_col = 3600ですか? – tmpearce

答えて

0

動的に(つまり実行時に)決定された配列を渡して、配列の第2次元がコンパイル時に3600と判断される関数に渡そうとしていますかなり妥当なもの文句を言って、実際には)。

1

コードからわかるように、いくつかの不具合があります。

  • あなたは[lon_col]

    ダブル標高[lat_row]として、配列の上昇を定義しています。

コンパイル時にCスタイルの配列のサイズを決定できなければならないため、これはうまくいかないでしょう。 lat_rowとlon_colは変数なので、エラーです。

したがって、動的メモリ割り当てを持つ配列、またはstd :: vectorを使用することができます。これはほとんどの場合に適しています。したがって、あなたの場合、次のようなものがあります:

typedef std::vector< std::vector<double> > ElevationsType; 
ElevationsType elevations; 

そして、その配列またはdoubleの配列を使用してください。 はその後、あなたのFIND_MAX機能は次のように宣言される:

double find_max(const ElevationsType &elevations, double ilat, double ilon); 

あなただけ行うことができますので、この場合には、あなたが、NLATとnlonを渡す必要がないことに注意してください:もちろん

ElevationsType::size_type nlat, nlon, i, j; 
nlat = elevations.size(); 

for (i = 0; i != nlat; ++i) { 
    nlon = elevations[i].size(); 
    for (j = 0; j != nlon; ++j) { 
     const double element = elevations[i][j]; 
     // do whatever you need to do with the element 
    } 
} 

を、配列が固定サイズの場合、ElevationsType型のオブジェクトを作成するか、または十分なスペース(std :: vector :: reserve)を割り当ててから初期化すると、それを設定できます(std :: vector :: resize)。それが大きいと、パフォーマンスが向上する可能性があります。いわば..多くの人々のために、より面倒である

double **elevations = (double **)malloc(sizeof(double*) * lat_row); 
for (size_t i = 0; i != lat_row; ++i) { 
    elevations[i] = (double*)malloc(sizeof(double) * lat_col); 

    // initialize the elements 
    for (size_t j = 0; j != lat_col; ++j) { 
     elevations[i][j] = 100.0; /* your value */ 
     std::cout << "elevations[" << i << "][" << j << "] = " << elevations[i][j] << std::endl; 
    } 
} 

:あなたはCスタイルの配列で行くことを選択した場合

しかし、それはようなものになるだろう。そして、あなたがそのルートに入るならば、free()ですべての割り当てられたメモリの割り当てを解除するのを忘れないでください。

また、C++ new演算子を使用してメモリを割り当てることもできますが、原則はほとんど同じです。

だから、std :: vectorを使うことをお勧めします。少なくとも経験が限られていれば、作業が簡単です。また、メモリの割り当て/解放を処理し、多くの悪いこと、オーバーフロー、リークなどを引き起こします。これは、ベクターを使用すると回避されます。

+0

お返事ありがとうございました!私は、コール関数がうまく働いたプログラム変数の代わりに整数値を使って配列のサイズを設定するとすぐにそれを発見しました。私はまだC + +に少し新しく、私は過去にベクトルを使ってみましたが、私はそれらに完全に慣れていません。これは良い機会のように思えます。 – user1263011

+0

はい、Cスタイルの配列(ポインタなど)を扱うのが難しいことを避けるためには、 "std :: vector"を使用してください。しかし、それはまだ知っている便利な知っている(Cスタイルの配列)、あなたは時間がある場合は、件名の周りにたくさんの記事があります。このフォーラムの私の2つの最近の記事を最初に見てください:http://stackoverflow.com/questions/9583086/2dimensional-array-pointer-manipulation-in-c/9608139#9608139 and http://stackoverflow.com/questions/9672731 /操作多次元配列 - with-c-functions/in 9677552#9677552 – Larry