2014-06-16 9 views
6

Używając wskaźnika do tablicy, zawsze uzyskiwałem dostęp do elementów za pomocą indeksera, na przykład myPtr[i] = stuff; jednak ostatnio szukałem ponad BitConverter's implementation i odkryłem, że dostęp do elementów odbywa się poprzez: *(myPtr + i) = stuff.Jaka jest różnica między ptr [i] a * (ptr + i)?

Co uważałem za dość dziwne, ponieważ obie metody (z tego, co wiem) robią dokładnie to samo, to znaczy zwracają adres myPtr + i, z tym wyjątkiem (moim zdaniem) metoda indeksowania wygląda o wiele bardziej czytelnie.

Dlaczego firma Microsoft zdecydowała się na inkrementację wskaźników tak, jak to zrobili, jaka jest różnica między tymi dwiema metodami (czy są korzyści z wydajności)?

+0

Generują tę samą IL. To tylko kwestia stylu. –

+0

Metoda "ToBoolean" jest świetna. Komentarze nie pasują do kodu, a ma świetne "x == 0? false: true' wzór zamiast zwykłego 'x! = 0'. – CodesInChaos

Odpowiedz

4

Jak stwierdzono, robią to samo.

W rzeczywistości, podczas uzyskiwania dostępu do int* obie ptr[i] i *(ptr + i) składnie pominie sprawdzić granice, a do pewnego punktu pamięci poza granice tablicy jeśli i jest większa niż długość tablicy.

Jestem całkiem pewny, że C#, a także C++, odziedziczył indeksowany dostęp do wskaźnika tablicy, używając składni *(ptr + index) z C. Jestem pewien, że jest to jedyny powód, dla którego obie syntakty są dostępne.

+0

Więc 'myPrt [i]' to tylko cukier syntaktyczny? Poza tym nie ma innych różnic? – Sam

+0

@Sam Tak, nie powinno być żadnej innej różnicy. – dcastro

+0

@dcastro O ile pamiętam, użycie indeksera może dać ci 'IndexOutOfRangeException', podczas gdy' * (ptr + index) 'wskaże ci tylko pamięć poza tablicą. – AndreySarafanov

1

Aby wyjaśnić różnicę między operatorem tablicy i wskaźnikiem (który omówiono pod odpowiedzią dcastro), można sprawdzić wyjście poniżej kodu.

unsafe { 
    int[] arr = new[] { 1, 2 }; 
    fixed(int* ptr = arr) { 
     for(int i = 0; i < arr.Length + 1; i++) { 
      try { System.Console.WriteLine(*(ptr + i)); } catch(Exception e) { System.Console.WriteLine(e.Message); } 
      try { System.Console.WriteLine(ptr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); } 
      try { System.Console.WriteLine(arr[i]); } catch (Exception e) { System.Console.WriteLine(e.Message); } 
     } 
    } 
} 

wyjściowy

1 
1 
1 
2 
2 
2 
0 
0 
Index was outside the bounds of the array. 
2

Z CSharp Language Specification (18.5.3)

on dostęp elementem wskaźnik z postaci P [k] oceniano tak, jak * (p + e) . (...) Operator dostępu do elementu wskaźnika nie sprawdza błędów out-of-bounds i zachowania, gdy dostęp do elementu out-of-bounds jest niezdefiniowany. To jest to samo co C i C++.

Nie ma różnic.

Powiązane problemy