C#将数组指针传递给从特定偏移量开始的函数 我将C++应用移植到C语言,并遇到指针的一些问题。
我试图实现的是传递一个带有偏移量的数组指针,以便传递的函数可以处理数组的正确部分。我不想更改函数的签名来为偏移量添加额外的值C#将数组指针传递给从特定偏移量开始的函数 我将C++应用移植到C语言,并遇到指针的一些问题。,c#,arrays,pointers,porting,C#,Arrays,Pointers,Porting,我试图实现的是传递一个带有偏移量的数组指针,以便传递的函数可以处理数组的正确部分。我不想更改函数的签名来为偏移量添加额外的值 >,这是我想在C中传递的C++代码的一个例子: void DoSomething(双p[]) { p[0]=0.4; p[1]=0.4; } int main() { 双向量[3]; 向量[0]=0.2; 向量[1]=0.2; 向量[2]=0.2; 剂量测定法(&向量[1]); } 我怎么能这么做?记住我不能通过补偿 [编辑] 谢谢大家的回答。 首先,我必须道歉:我在
>,这是我想在C中传递的C++代码的一个例子:
void DoSomething(双p[])
{
p[0]=0.4;
p[1]=0.4;
}
int main()
{
双向量[3];
向量[0]=0.2;
向量[1]=0.2;
向量[2]=0.2;
剂量测定法(&向量[1]);
}
我怎么能这么做?记住我不能通过补偿
[编辑]
谢谢大家的回答。
首先,我必须道歉:我在复制代码时犯了一个大错误
我写
DoSomething( Vector[1] );
在最后一行,而不是
DoSomething( &Vector[1] );
这一点已得到纠正
然后我意识到我对签名不是很清楚
- 我可以稍微更改函数的签名,但不能添加任何参数
- 我已经在使用“不安全”和“固定”关键字,所以它不会伤害我
- 它不需要是高效的代码,因为这种移植的目的是快速而肮脏地实现其他人为原型项目编写的算法。如果项目是“OK go”,代码将被丢弃在垃圾中并改写为C++ dll。
- 函数“DoSomething”实际上是其他一些函数的嵌套,它被设计为一个快速的数学工作,但遗憾的是,我自己没有编写它的所有知识。这就是为什么我认为作者已经很好地设计了它的功能,因为它已经在世界范围内使用
DoSomething
的签名,就不可能做到,但您可以避免同时传递数组和它在所有位置并排偏移。您可以通过创建一个组成数组并跟踪偏移量的类来实现这一点:
public class ArrayReference<T> : IEnumerable<T>
{
//you can keep these entirely private if you prefer
public T[] Array { get; private set; }
public int Offset { get; private set; }
public ArrayReference(T[] array, int offset)
{
Array = array;
Offset = offset;
}
public T this[int index]
{
get
{
return Array[index + Offset];
}
set
{
Array[index + Offset] = value;
}
}
public int Length
{
get
{
return Array.Length - Offset;
}
}
public IEnumerator<T> GetEnumerator()
{
for (int i = Offset; i < Array.Length; i++)
yield return Array[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public static ArrayReference<T> operator +(
ArrayReference<T> reference, int offset)
{
return new ArrayReference<T>(reference.Array, reference.Offset + offset);
}
public static ArrayReference<T> operator -(
ArrayReference<T> reference, int offset)
{
return new ArrayReference<T>(reference.Array, reference.Offset - offset);
}
public static implicit operator ArrayReference<T>(T[] array)
{
return new ArrayReference<T>(array, 0);
}
public static implicit operator T[](ArrayReference<T> reference)
{
return reference.ToArray();
}
}
公共类数组引用:IEnumerable
{
//如果你愿意,你可以把这些完全保密
公共T[]数组{get;private set;}
公共int偏移量{get;private set;}
公共数组引用(T[]数组,int偏移量)
{
数组=数组;
偏移量=偏移量;
}
公共T此[int索引]
{
得到
{
返回数组[索引+偏移];
}
设置
{
数组[索引+偏移]=值;
}
}
公共整数长度
{
得到
{
返回数组。长度-偏移量;
}
}
公共IEnumerator GetEnumerator()
{
for(int i=Offset;i
根据您的具体需求,您可能希望在此基础上添加其他功能。您可以根据需要/想要公开尽可能多或尽可能少的底层阵列功能。更新代码以显示使用扩展方法的链接。您可以轻松地返回任何和所有更改,并更新任何需要的内容
List<double> Vector;
Vector.Add(0.2);
Vector.Add(0.2);
Vector.Add(0.2);
DoSomething(Vector.GetRange(index,count));
事实上,这不是你在C#中的做法 唯一的方法是使用不安全的代码,即使这样,它也不是一个好的实现,因为您的方法是不安全的,并且您的数组必须是固定的
fixed
关键字会阻止垃圾收集器将数组移动到内存中的另一个位置,但它可能会导致内存分区,进而降低性能
此外,即使通过设计,这也不是一件好事,因为您不知道方法中的数组边界
但如果你真的想这么做,就用枚举器
在您的主要方法中:
double[] d = new double[3];
d[0] = 1.0;
d[1] = 2.0;
d[2] = 3.0;
IEnumerator<double> e = d.AsEnumerable().GetEnumerator();
e.MoveNext();
tryEnumerate(e);
这也是相当差的C++代码。我自己会用一个统计员,我同意IdeaHat和Yack的观点。可以写入
p[3]=0.4代码>在C++ >代码> DoSomething < /代码>中。您如何知道数组边界?您可以这样使用LINQ:var filtered=Vector.GetRange(index,count)。。。。将向量数组更改为List@JohnPeters-必须指出,这将创建一个新阵列。系统希望更改数组中的元素,因此这在功能上不起作用。如果不更改被调用方法的签名,则无法实现这一点。你为什么反对那样做?将偏移量本身推送到需要偏移量的方法有什么错?这不起作用DoSomething会更改数组的元素--这只会更改副本。这就是创建列表的副本。对该副本的更改不会影响原始列表。是的,创建新对象类型是解决此问题的C#方法。就我个人而言,我认为更改DoSomething()
函数会更容易。但每个人都有自己的。请注意,这会改变方法的签名,就像传递偏移量一样。@Hogan在这个非常简单的示例中,传递带有数组的偏移量可能足够简单,当然,但在一个非常复杂的程序中,它会处理大量偏移量不断变化的数组,实际上,把所有的逻辑都包装起来是合理的
OriginalList().GetRange(Index,Count).DoSomething();
double[] d = new double[3];
d[0] = 1.0;
d[1] = 2.0;
d[2] = 3.0;
IEnumerator<double> e = d.AsEnumerable().GetEnumerator();
e.MoveNext();
tryEnumerate(e);
static void DoSomething(IEnumerator<double> e)
{
while(e.MoveNext())
Console.WriteLine(e.Current.ToString());
}