В чем разница между ptr[i] и *(ptr + i)?
При использовании указателя на массив я всегда обращался к элементам с помощью индексатора, например, myPtr[i] = stuff
; Тем не менее, я недавно просматривал BitConverter
Реализация и обнаружил, что элементы были доступны, делая, *(myPtr + i) = stuff
,
Что я думал довольно странно, так как оба метода (из того, что я знаю) делают одно и то же, то есть возвращают адрес myPtr + i
За исключением (на мой взгляд) метод indexer выглядит гораздо более читабельным.
Так почему же Microsoft решила увеличивать указатели так, как они это делали, в чем разница между этими двумя методами (есть ли преимущества в производительности)?
3 ответа
Как вы заявили, они делают то же самое.
На самом деле, при доступе к int*
, и то и другое ptr[i]
а также *(ptr + i)
синтаксис пропустит проверку границ и укажет на некоторую память вне границ массива, если i
больше длины массива.
Я почти уверен, что C#, как и C++, унаследовал индексированный доступ к указателю массива, используя *(ptr + index)
синтаксис из C. Я почти уверен, что это единственная причина, по которой оба синтаксиса доступны.
Из спецификации языка CSharp (18.5.3):
Доступ к элементу указателя в форме P[E] оценивается точно как *(P + E). (...) Оператор доступа к элементу указателя не проверяет наличие ошибок за пределами границ, и поведение при доступе к элементу вне границ не определено. Это то же самое, что C и C++.
Там нет никаких различий.
Чтобы уточнить разницу между []
Оператор массива и указатель (который обсуждался в ответе dcastro), вы можете проверить вывод кода ниже.
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); }
}
}
}
Выход
1
1
1
2
2
2
0
0
Index was outside the bounds of the array.