我试图理解代码如何运作,并且由于这一部分而无法理解一个非常重要的部分。你能解释一下,当我们使用* 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);
.....
}
答案 0 :(得分:11)
在C#中,括号中的任何数据类型都代表一个强制转换。在这种情况下,它正在转换为浮点指针。 C#中的*
表示指针类型。指针是特殊的数据类型,指向&#34;指向&#34;到内存中保存数据的区域。把它想象成操纵地址。在你的代码中:
if (*(f2 + row * imageWidth) > m)
代码被用作解除引用指针。这是用英语说的,是&#34;取f2
指向的地址并添加row
和imageWidth
的产品,然后取消引用(取消引用只是意味着返回f2
加上row
和imageWidth
的乘积存储的数据,并查看其是否大于m
。这是一个视觉:
-------------------------------------------
Memory Location --> | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 |
-------------------------------------------
Data --> | 86 | 130 | 190 | 221 | 12 | 99 |
-------------------------------------------
如果f2
等于1000
,则*f2
将返回86
。 *(f2 + 1)
将返回130
。现在在我的例子中,我假设float
占用一个字节的存储数据。但事实并非如此。在CLR中,float
占用4个字节(您可以看到此here)。所以(f2 + 1)
实际上等于1004,实际上会返回12
。这称为指针算术。算术可能因处理器而异。如果float的长度为8个字节,那么(f2 + 1)
将等于1008
。
因为C#的自动垃圾收集器有时想要在堆上重新定位东西,并且因为指针可以操作通常无法操作的数据,所以指针在C#中是不安全的,并且必须包含在{{阻止使用。
答案 1 :(得分:1)
float*
指的是只能在unsafe
block中使用的指针。指针正好是指向内存中某个位置的指针。使用它们的原因通常是性能,尽管在许多情况下可以实现相同的结果而不会在安全代码中降低太多性能。