2010-11-28 53 views
2

下面是一個Win32控制檯應用程序過程,演示了陣列上各種指針的依賴關係。例如,通過取消註釋標記爲'// uncomment ...'的行來更改原始數組(模型)中的值會導致輸出更改。我的問題是如何在C#託管代碼環境中獲取或模仿此行爲(即不使用不安全和指針)?C++到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(); } 
+0

您的意思是您解引用指針使用數組語法,還是有一個情況下,你想我是> 0(意爲過去的平均什麼?值) – 2010-11-28 19:16:26

+0

順便說一句,你在做什麼叫做「指針別名」。 – chrisaycock 2010-11-28 19:20:51

+0

我可能是0以外的東西,它只是爲了舉例。 – descf 2010-11-28 19:27:10

回答

14

你可以在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中的一個錯誤,但難以捉摸。

0

而不是一個參數,指向數組項,使用參數對(數組,偏移量)。

4

你可以編寫一個代表具有某種偏移量的數組的類,類似於下面的類。另外,您可能希望它執行ICollection<T>或至少IEnumerable<T>

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] 
    } 
}