Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
16
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Типы указателей45

В небезопасном контексте тип может быть типом указателя, типом значения или ссылочным типом. Объявления типа указателя выполняется одним из следующих способов:

type* identifier;

void* identifier; //allowed but not recommended

Любой из следующих типов может быть типом указателя.

  • sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal или bool.

  • Любой тип enum.

  • Любой тип указателя.

  • Любой пользовательский тип структуры, содержащий поля только неуправляемых типов.

Типы указателей не наследуют от объектов, не существует преобразований между типами указателей и object. Кроме того, для указателей не поддерживается упаковка и распаковка. Впрочем, можно выполнять преобразования между различными типами указателей, а также между типами указателей и целыми типами.

При объявлении нескольких указателей в одном объявлении знак * записывается только с нижележащим типом, а не в качестве префикса с каждым именем указателя. Пример.

int* p1, p2, p3; // Ok

int *p1, *p2, *p3; // Invalid in C#

Указатель не может указывать на ссылку или на структуру, содержащую ссылки, поскольку для ссылки на объект невозможен сбор мусора, даже если на нее указывает указатель. Сборщик мусора не отслеживает наличие указателей любых типов, указывающих на объекты.

Значением указателя переменной типа myType* является адрес переменной типа myType. Ниже приведены примеры объявлений типов указателей.

Пример

Описание

int* p

p — указатель на целое число

int** p

p — указатель на указатель на целое число

int*[] p

p — одномерный массив указателей на целые числа

char* p

p — указатель на знак

void* p

p — указатель на неизвестный тип

The pointer indirection operator * can be used to access the contents at the location pointed to by the pointer variable. For example, consider the following declaration:

int* myVariable;

The expression *myVariable denotes the int variable found at the address contained in myVariable.

You cannot apply the indirection operator to a pointer of type void*. However, you can use a cast to convert a void pointer to any other pointer type, and vice versa.

A pointer can be null. Applying the indirection operator to a null pointer causes an implementation-defined behavior.

Be aware that passing pointers between methods can cause undefined behavior. Examples are returning a pointer to a local variable through an Out or Ref parameter or as the function result. If the pointer was set in a fixed block, the variable to which it points may no longer be fixed.

The following table lists the operators and statements that can operate on pointers in an unsafe context:

Operator/Statement

Use

*

Performs pointer indirection.

->

Accesses a member of a struct through a pointer.

[]

Indexed a pointer.

&

Obtains the address of a variable.

++ and --

Increments and decrements pointers.

+ and -

Performs pointer arithmetic.

==, !=, <, >, <=, and >=

Compares pointers.

stackalloc

Allocates memory on the stack.

fixed statement

Temporarily fixes a variable so that its address may be found.

Косвенный оператор указателя * можно использовать для доступа к содержимому, на которое указывает переменная указателя. В качестве примера рассмотрим следующее объявление:

int* myVariable;

Выражение *myVariable обозначает переменную int, находящуюся по адресу, содержащемуся в myVariable.

Невозможно использовать косвенный оператор для указателя типа void*. Однако можно использовать приведение для преобразования указателя типа void в любой другой тип и наоборот.

Указатель может иметь значение null. При применении косвенного оператора к указателю со значением null результат зависит от конкретной реализации.

Обратите внимание, что при передаче указателей между методами может возникнуть непредусмотренное поведение. В примерах указатель возвращается в локальную переменную через параметр Out или Ref либо в виде результата функции. Если указатель был указан в фиксированном блоке, переменная, на которую он указывает, больше не может быть фиксированной.

В следующей таблице перечислены операторы, которые можно использовать для указателей в небезопасном контексте.

Оператор

Действие

*

Косвенный оператор указателя.

->

Доступ к члену структуры через указатель.

[]

Индексирование указателя.

&

Получение адреса переменной.

++ и --

Приращение и уменьшение указателей.

+ и -

Арифметические действия указателя.

==, !=, <, >, <= и >=

Сравнение указателей.

stackalloc

Выделение памяти в стеке.

Оператор fixed

Временная фиксация переменной, чтобы можно было найти ее адрес.

Pointer Conversions

The following table shows the predefined implicit pointer conversions. Implicit conversions might occur in many situations, including method invoking and assignment statements.

Implicit pointer conversions

From

To

Any pointer type

void*

null

Any pointer type

Explicit pointer conversion is used to perform conversions, for which there is no implicit conversion, by using a cast expression. The following table shows these conversions.

Explicit pointer conversions

From

To

Any pointer type

Any other pointer type

sbyte, byte, short, ushort, int, uint, long, or ulong

Any pointer type

Any pointer type

sbyte, byte, short, ushort, int, uint, long, or ulong