【问题标题】:C++ to C#: Pointers & ArraysC++ 两个 C#:指针和数组
【发布时间】:2011-05-16 22:59:59
【问题描述】:

下面是一个 Win32 控制台应用程序,它演示了各种指针对数组的依赖性。更改原始数组(模型)中的值,例如取消注释标记为 '// uncomment ...' 的行会导致输出更改。我的问题是如何在 C# 托管代码环境中获取或模仿这种行为(即不使用不安全和指针)?

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    float model[100];
    for(int i = 0; i < 100; i++) { model[i] = i; }

    // uncomment these to alter the results
    //model[5] = 5000;
    //model[20] = 20000;
    //model[38] = 38000;

    static const int componentCount = 5;

    float* coefs = model;                   // coefs points to model[0]
    float* mean = coefs + componentCount;   // mean points to model[0 + componentCount] == model[5]
    float* cov = mean + 3*componentCount;   // cov points to model[0 + componentCount + 3*componentCount] == model[20] 

    int ci = 2;
    float* c = cov + 9*ci;  // c points to model[0 + componentCount + 3*componentCount + 9*ci] == model[38] 

    int i = 0;
    cout <<"model : "<< model[i] << endl;   // 0
    cout <<"coefs : "<< coefs[i] << endl;   // 0
    cout <<"mean  : "<< mean[i] << endl;    // 5 (or 5000)
    cout <<"cov   : "<< cov[i] << endl;     // 20 (or 20000)
    cout <<"ci    : "<< ci << endl;         // 2
    cout <<"c     : "<< c[i] << endl;       // 38 (or 38000)

cin.get(); }

【问题讨论】:

  • 您的意思是使用数组语法取消引用您的指针,还是存在您希望 i > 0 的情况(意味着超过平均值的值或其他什么?)
  • 顺便说一句,你所做的就是所谓的“指针别名”。
  • i 可能不是 0,这只是示例。

标签: c# c++ arrays pointers


【解决方案1】:

你可以在没有不安全代码的情况下在 C# 中做同样的事情:

struct ArrayPointer<T>
{
    private T[] array;
    private int offset;
    public ArrayPointer(T[] array) : this(array, 0)
    {
    }
    private ArrayPointer(T[] array, int offset)
    {
        Debug.Assert(array != null);
        Debug.Assert(offset >= 0);
        Debug.Assert(offset < array.Length);
        this.array = array;
        this.offset = offset;
    }
    public static ArrayPointer<T> operator+(ArrayPointer<T> p1, int p2)
    {
        return new ArrayPointer<T>(p1.array, p1.offset + p2);
    }

等等。为加法、减法、递增、递减、比较、索引、数组转换等定义运算符。然后你可以说:

int[] arr = whatever;
ArrayPointer<int> pointer = arr;
pointer+=2;
pointer--;
int x = pointer[3];

等等。

这种方法有很多不错的特性。例如,当 p1 和 p2 是指向不同数组内部的指针时,如果你比较 p1 > p2,你可以做一个调试断言。这几乎总是 C 中的一个错误,但很难发现。

【讨论】:

  • 这看起来很有希望,但是当我尝试它时,我得到一个“无法将类型 'int[]' 隐式转换为 'ArrayPointer' 错误。
  • @descf:你读过我说“等等:从数组定义转换运算符”的段落吗?这不是一个完整的解决方案,这是一个解决方案的草图。
  • 好的,我明白了。我已经得到了: ArrayPointer pointer = new ArrayPointer(arr);但要达到,例如: int x = pointer[n];我必须编写一个方法来返回该索引处的值。
【解决方案2】:

您可以编写一个类来表示具有一些偏移量的数组,类似于下面的类。另外,您可能希望它实现ICollection&lt;T&gt; 或至少IEnumerable&lt;T&gt;

class ArrayWithOffset<T>
{
  T[] m_array;
  int m_offset;

  public ArrayWithOffset(T[] array, int offset)
  {
    m_array = array;
    m_offset = offset;
  }

  public T this[int i]
  {
    return m_array[offset + i]
  }
}

【讨论】:

  • 伟大的思想都一样。 :-) 我倾向于将其设为结构,因为它很小并且可以用作代数系统中的值。
  • @Eric,当您说“.. 可以用作代数系统中的值”时,您是什么意思?
  • @Matt:您可以创建一个代数系统,其中可以添加和减去数组指针,类似于添加和减去数字的方式。一个数组指针加上一个 int 是另一个数组指针。一个数组指针减去一个数组指针就是一个 int。等等。当事物在逻辑上是 时,将其建模为 值类型 是有意义的。
【解决方案3】:

使用一对参数(数组,偏移量),而不是一个参数,指向数组项的指针。

【讨论】:

    猜你喜欢
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2013-03-10
    相关资源
    最近更新 更多