1

C コードの再帰関数に行き詰まっています (C コードは書いていません)。ここに私が変換しているスニペットがあります:

int makeroad(float x1, float y1, float x2, float y2, float var, float X[], float Y[], float prec)
{
//stuff
k+=makeroad(x,y,x2,y2,var,X+k,Y+k,prec);
}

これが何をしているのか完全にはわかりません。これは、C コードでその名前を持つ唯一の関数であるため、オーバーロードの問題ではありません。それ自体を再帰的に呼び出すと、X および Y 配列に k が追加されます。C# に入れると次のようになります。

int makeroad (float x1, float y1, float x2, float y2, float var, float[] X, float[] Y, float prec)
    {
      //stuff
      k += makeroad(x, y, x2, y2, var, X + k, Y + k, prec);
    }

Visual Studio は、X + k と Y + k が無効であることを教えてくれます。元の C コードはコンパイルされ、Visual C++ Express 2010 で正常に動作します。大文字と小文字の x 変数と y 変数がそれぞれ混乱したとは思いません。あった場合、コードはまったくの運で機能しています。

何か案は?

4

3 に答える 3

0

array+kC では、最初の要素の位置を渡すことによって C の配列が渡されるため(つまり、k 番目の項目へのポインターを渡すだけで、既存の要素から最初の k 要素を除いた配列を "作成" できます (つまり、" new" 配列は、"元の" 配列と同じ要素を参照するため、まったく新しいものではありません)。

C# では、配列が連続したメモリへのポインタとして扱われないため、これは機能しません。迅速な修正が必要な場合は、新しい配列を作成し、要素を k 番目から最後までコピーしてから、Array.Copyこの新しい配列を再帰関数に渡すことができますが、これは遅く、アルゴリズムが変更された場合は機能しません配列の要素 (他の配列はコピーであるため、変更は反映されません)。

より良い解決策は、配列をそのままkパラメーターとして渡し、ルーチンがその位置から配列を使用して開始するようにすることです。実質的な速度のペナルティなしで同じ動作を実現する必要があります。

于 2010-12-29T23:32:19.530 に答える
0

X + k および Y + k は、配列へのポインターです。呼び出された関数の配列の先頭部分を「スキップ」できます。

C コードを他の CLR コードと混在させることができるので、実際にこれを変換する必要はありません。

本当に必要だと思うなら、X、Y、k を渡し、k を X と Y への開始オフセットとして使用するように「もの」を書き直すことを検討してください。この場合、著者は C を非常に効率的に使用しており、それが困難になっています。別の言語に移植します。

于 2010-12-29T23:33:37.437 に答える
0

C では配列は参照によって渡されるため、実際に渡されるのは配列の先頭へのポインターです。たとえば、「X + k」を渡すと、k から始まるサブ配列へのポインタが渡されます。

C# が配列パラメーターで何をするのか、まったくわかりませんし、したくもありません。

于 2010-12-29T23:27:53.117 に答える