2

コードがどのように機能するかを理解しようとしていますが、この部分のために非常に重要な部分を理解できませんでした。float* の意味と、x ではなく *x を使用した場合の違いを説明していただけますか?

反復ごとに f1 と f2 の値が変わるのはなぜですか? IplImages[0] と IplImages[1] .toPointer が原因ですか? 説明してください。

List<IplImage> IplImages;

float* f1 = (float*)IplImages[0].ImageData.ToPointer();
float* f2 = (float*)IplImages[1].ImageData.ToPointer();
.
.
.
.
if (*(f2 + row * imageWidth) > m)
 {
   m = *(f2 + row * imageWidth);
   .....
 }
4

2 に答える 2

11

C# では、括弧内のデータ型はキャストを表します。この場合、浮動小数点ポインターにキャストしています。C#の*はポインター型を表します。ポインタは、データが保持されているメモリ内の領域を「指す」特別なデータ型です。アドレスの操作と考えてください。ここにあなたのコードで:

if (*(f2 + row * imageWidth) > m)

コードは逆参照ポインターとして使用されています。これが英語で言っていることは、「 が指すアドレスf2に と の積を追加し、rowimageWidth参照 (逆参照とは、 に格納されたデータに と の積を加えたものを返すことを意味します)f2よりも大きいかどうかを確認することです。. ビジュアルは次のとおりです。rowimageWidthm

                       -------------------------------------------
Memory Location -->    | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 |
                       -------------------------------------------
            Data -->   |  86  |  130 | 190  |  221 |  12  | 99   |
                       -------------------------------------------

f2等しい場合は1000*f2を返し86ます。*(f2 + 1)戻り130ます。floatこの例では、 1 バイトのストレージ データを使用すると想定しています。しかし、そうではありません。CLR では、float4 バイトを占めます (ここで確認できます)。したがって(f2 + 1)、実際には 1004 に等しくなり、実際には が返され12ます。これはポインタ演算と呼ばれます。算術演算は、プロセッサによって異なる場合があります。float の長さが 8 バイトの場合、(f2 + 1)と等しくなり1008ます。

C# の自動ガベージ コレクターはヒープ上のデータを再配置する必要がある場合があり、ポインターは通常は操作できないデータを操作できるため、ポインターは C# では安全ではなく、使用するにはunsafeブロックにラップする必要があります。

于 2014-09-30T16:21:56.223 に答える