Преобразования указателей

Для указателей поддерживаются неявные преобразования из любого типа указа­теля к типу void*. Любому указателю можно присвоить константу null. Кроме того, допускаются явные преобразования:

□ между указателями любого типа;

□ между указателями любого типа и целыми типами (со знаком и без знака).

Корректность преобразований лежит на совести программиста. Преобразования никак не влияют на величины, на которые ссылаются указатели, но при попытке получения значения по указателю несоответствующего типа поведение програм­мы не определено1.

Инициализация указателей

Ниже перечислены способы присваивания значений указателям:

1. Присваивание указателю адреса существующего объекта:

- с помощью операции получения адреса:

int a = 5; // целая переменная

int* р = &а; //в указатель записывается адрес а

ПРИМЕЧАНИЕ

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

- с помощью значения другого инициализированного указателя.

int* r = р;

- с помощью имени массива, которое трактуется как адрес:

int[] b = new int[] {10, 20, 30, 50}; // массив

fixed (int* t = b){...};// присваивание адреса начала массива
fixed (int* t = &b[0]){...}; // то же самое

ПРИМЕЧАНИЕ

Оператор fixed рассматривается позже.

2. Присваивание указателю адреса области памяти в явном виде:

char* v = (char *)0x12F69E;

Здесь 0xl2F69E — шестнадцатеричная константа, (char *) — операция приведе­ния типа: константа преобразуется к типу указателя на char.

ПРИМЕЧАНИЕ

Использовать этот способ можно только в том случае, если адрес вам точно извес­тен, в противном случае может возникнуть исключение.

3. Присваивание нулевого значения:

int* хх = null;

Как правило, если в документации встречается оборот «неопределенное поведение* (undefined behavior), ничего хорошего это не сулит.

4. Выделение области памяти в стеке и присваивание ее адреса указателю: int* s = stackalloc int [10];

Здесь операция stackalloc выполняет выделение памяти под 10 величин типа int (массив из 10 элементов) и записывает адрес начала этой области памяти в переменную s, которая может трактоваться как имя массива.

ПРИМЕЧАНИЕ

Специальных операций для выделения области динамической памяти (хипа) в С# не предусмотрено. В случае необходимости можно использовать, например, сис­темную функцию НеарAllос (пример см. в спецификации языка).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: