2010-03-30 59 views
7

下面的C++程序編譯和運行正常:C#中的指針使int數組?

#include <stdio.h> 

int main(int argc, char* argv[]) 
{ 
    int* test = new int[10]; 

    for (int i = 0; i < 10; i++) 
      test[i] = i * 10; 

    printf("%d \n", test[5]); // 50 
    printf("%d \n", 5[test]); // 50 

    return getchar(); 
} 

最接近C#簡單的例子,我可以彌補這方面的問題是:

using System; 

class Program 
{ 
    unsafe static int Main(string[] args) 
    { 
     // error CS0029: Cannot implicitly convert type 'int[]' to 'int*' 
     int* test = new int[10]; 

     for (int i = 0; i < 10; i++) 
      test[i] = i * 10; 

     Console.WriteLine(test[5]); // 50 
     Console.WriteLine(5[test]); // Error 

     return (int)Console.ReadKey().Key; 
    } 
} 

那麼,如何使指針?

+1

問問自己爲什麼要直接用託管語言操作指針。 – BlackICE 2010-03-30 16:11:29

+8

因爲我很無聊:D – y2k 2010-03-30 16:18:22

+3

在您嘗試使用C#編寫不安全的代碼之前,閱讀規範的第18章 - 減少兩次 - 減輕您的無聊。 – 2010-03-30 16:28:20

回答

27

C#不是C++ - 不要指望在C++中工作在C++中的工作是相同的。它是一種不同的語言,在語法上有一些靈感。

在C++中,數組訪問是指針操作的簡稱。這就是爲什麼以下是相同的:

test[5] 
*(test+5) 
*(5+test) 
5[test] 

但是,這是不正確的C#中。因爲System.Int32上沒有索引器屬性,因此5[test]無效C#。

在C#中,你很少想處理指針。你最好只把它當作直接一個int數組:

int[] test = new int[10]; 

如果你確實想對付指針數學出於某種原因,你需要你的標誌方法unsafe,並把它變成一個fixed context。這在C#中並不典型,而且可能完全沒有必要。

如果你真的想這個工作,你可以在C#做的最接近的是:

using System; 

class Program 
{ 
    unsafe static int Main(string[] args) 
    { 
     fixed (int* test = new int[10]) 
     { 

      for (int i = 0; i < 10; i++) 
       test[i] = i * 10; 

      Console.WriteLine(test[5]); // 50 
      Console.WriteLine(*(5+test)); // Works with this syntax 
     } 

     return (int)Console.ReadKey().Key; 
    } 
} 

(同樣,這是非常奇怪的C# - 不是我建議你...)

+1

感謝您深思熟慮的答案。我只是想看看C#是否能夠實現如此低級別的內存管理。基本上你說的是這種索引不能完成?即使使用固定的上下文,我也無法獲得任何工作。你知道我們是否完全被Int32卡住了,甚至是一個本地類型還是一個抽象? – y2k 2010-03-30 16:10:47

+0

@Joshua:我編輯了我的答案,告訴你如何實際完成它 - 但我真的不推薦它 – 2010-03-30 16:11:57

+0

在運行C#的平臺上,System.Int32是本地int類型。但是在引擎蓋下int []是你在C++中看到的同一塊內存。如果你做'test [5]',那麼CLR將會進行邊界檢查,然後是指針運算和取消引用。在這種情況下,你不會失去任何低級別的操作。 – 2010-03-30 16:17:02

5

您需要使用fixed關鍵字針陣列所以它不會被GC感動:

fixed (int* test = new int[10]) 
{ 
    // ... 
} 

然而,在C#不安全的代碼超過個例外。我試圖將你的C代碼翻譯成非不安全的C#代碼。

+2

注意:使用固定的變量不應該有一個很好的理由,因爲它使得GC的工作更難......而且即使不使用所有內存(內存碎片整理),也可能導致內存不足。 。 – Peter 2010-03-30 16:27:16

0

您需要學習C#語言。儘管與C/C++有語法上的相似之處,但它與Java一樣,有一個非常不同的方法。

在C#中,對象默認情況下表現爲引用。也就是說,您不必指定指針參考(&)和取消引用(*)語法。