В чем разница между 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.
Другие вопросы по тегам