Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

18.5.1Косвенное обращение по указателю

Выражение_косвенного_обращения_по_указателю состоит из звездочки (*) с последующим унарным_выражением.

выражение_косвенного_обращения_к_указателю: * унарное_выражение

Унарный оператор * означает косвенное обращение по указателю и используется для получения переменной, на которую указывает указатель. Результатом вычисления *P, где P — это выражение типа указателя T*, является переменная типа T. Применение унарного оператора * к выражению типа void* или к выражению не типа указателя является ошибкой времени компиляции.

Результат применения унарного оператора * к указателю со значением null определяется реализацией. В частности, нет гарантии, что по этой операции будет выдана исключительная ситуация System.NullReferenceException.

Если указателю присвоено недопустимое значение, поведение унарного оператора * является неопределенным. Среди недопустимых значений для разыменования указателя унарным оператором * неправильно выровненный адрес указываемого типа (см. пример в §18.4) и адрес переменной после окончания ее времени жизни.

Для целей анализа определенного присваивания переменная, полученная вычислением выражения вида *P, считается изначально присвоенной (§5.3.1).

18.5.2Доступ к члену по указателю

Доступ_к_члену_по_указателю состоит из первичного_выражения, за которым следует лексема "->" и затем идентификатор.

доступ_к_элементу_по_указателю: первичное_выражение -> идентификатор

В доступе к члену по указателю вида P->I, P должно быть выражением типа указателя, отличного от void*, а I должно обозначать доступный член того типа, на который указывает P.

Доступ к члену по указателю вида P->I вычисляется точно так же, как (*P).I. Описание оператора косвенного обращения по указателю (*) см. в §18.5.1. Описание оператора доступа к члену (.) см. в §7.6.4.

В примере

using System;

struct Point { public int x; public int y;

public override string ToString() { return "(" + x + "," + y + ")"; } }

class Test { static void Main() { Point point; unsafe { Point* p = &point; p->x = 10; p->y = 20; Console.WriteLine(p->ToString()); } } }

оператор -> используется для доступа к полям и вызова метода структуры с помощью указателя. Поскольку операция P->I совершенно эквивалентна (*P).I, метод Main можно было записать так:

class Test { static void Main() { Point point; unsafe { Point* p = &point; (*p).x = 10; (*p).y = 20; Console.WriteLine((*p).ToString()); } } }

18.5.3Доступ к элементу по указателю

Доступ_к_элементу_по_указателю состоит из первичного_выражения_создания_не_массива, за которым следует выражение, заключенное в скобки «[" и "]».

доступ_к_элементу_по_указателю: первичное_выражение_создания_не_массива [ выражение ]

В доступе к элементу по указателю вида P[E], P должно быть выражением типа указателя, отличного от void*, а E должно быть выражением, которое может быть неявно преобразовано к типу int, uint, long или ulong.

Доступ к элементу по указателю вида P[E] вычисляется точно так же, как *(P + E). Описание оператора косвенного обращения по указателю (*) см. в §18.5.1. Описание оператора добавления к указателю (+) см. в §18.5.6.

В примере

class Test { static void Main() { unsafe { char* p = stackalloc char[256]; for (int i = 0; i < 256; i++) p[i] = (char)i; } } }

доступ к элементу по указателю используется для инициализации символьного буфера в цикле for. Поскольку операция P[E] совершенно эквивалентна *(P + E), этот пример можно было записать так:

class Test { static void Main() { unsafe { char* p = stackalloc char[256]; for (int i = 0; i < 256; i++) *(p + i) = (char)i; } } }

Оператор доступа к элементу по указателю не проверяет на ошибки выхода за допустимые границы, и поведение при доступе к элементу вне границ является неопределенным. Это так же, как в C и C++.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]