Чтение онлайн

на главную - закладки

Жанры

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

Применение ключевого слова unsafe

Любой код, в котором используются указатели, должен быть помечен как небезопасный с помощью специального ключевого слова unsafe. Подобным образом можно пометить конкретные типы данных (например, классы и структуры), члены класса (в том числе методы и операторы) или отдельные кодовые блоки как небезопасные. В качестве примера ниже приведена программа, где указатели используются в методе Main , помеченном как небезопасный.

// Продемонстрировать применение указателей и

ключевого слова unsafe.

using System;

class UnsafeCode {

// Пометить метод Main как небезопасный, unsafe static void Main { int count = 99;

int* p; // создать указатель типа int

p = &count; // поместить адрес переменной count в переменной р

Console.WriteLine("Исходное значение переменной count: " + *р) ;

*р = 10; // присвоить значение 10 переменной count,

// на которую указывает переменная р

Console.WriteLine("Новое значение переменной count: " + *р);

Эта программа дает следующий результат.

Исходное значение переменной count: 99 Новое значение переменной count: 10

Применение модификатора fixed

В работе с указателями нередко используется модификатор fixed, который препятствует удалению управляемой переменной средствами "сборки мусора'7. Потребность в этом возникает, например, в том случае, если указатель обращается к полю в объекте определенного класса. А поскольку указателю ничего не известно о действиях системы "сборки мусора", то он будет указывать не на тот объект, если удалить нужный объект. Ниже приведена общая форма модификатора fixed:

fixed (тип* р = &фиксированный_объект) {

// использовать фиксированный объект

}

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

Ниже приведен пример применения модификатора fixed.

// Продемонстрировать применение оператора fixed.

using System;

class Test {

public int num;

public Test (int i) { num = i; }

}

class FixedCode {

// Пометить метод Main как небезопасный, unsafe static void Main {

Test о = new Test(19);

fixed (int* p = &o.num) { // использовать модификатор fixed для размещения

// адреса переменной экземпляр о.num в переменной р

Console.WriteLine("Исходное значение переменной о.num: " + *р);

*р = 10; //

присвоить значение 10 переменной count,

// на которую указывает переменная р

Console.WriteLine("Новое значение переменной о.num: " + *р);

}

}

}

Вот к какому результату приводит выполнение этой программы.

Исходное значение переменной о.num: 19 Новое значение переменной о.num: 10

В данном .примере модификатор fixed препятствует удалению объекта о. А поскольку переменная р указывает на переменную экземпляра о . num, то она будет указывать на недостоверную область памяти, если удалить объект о.

Доступ к членам структуры с помощью указателя

Указатель может указывать на объект типа структуры при условии, что структура не содержит ссылочные типы данных. Для доступа к члену структуры с помощью указателя следует использовать оператор-стрелку (->), а не оператор-точку (.). Например, доступ к членам структуры

struct MyStruct { public int a; public int b;

public int Sum { return a + b; }

}

осуществляется следующим образом.

MyStruct о = new MyStruct;

MyStruct* p; // объявить указатель

p = &o;

p->a = 10; // использовать оператор -> p->b =20; // использовать оператор ->

Console.WriteLine("Сумма равна " + p->Sum);

Арифметические операции над указателями

Над указателями можно выполнять только четыре арифметические операции: ++, —, + и -. Для того чтобы стало понятнее, что именно происходит в арифметических операциях над указателями, рассмотрим сначала простой пример. Допустим, что переменная pi является указателем с текущим значением 2000, т.е. она содержит адрес 2000. После выполнения выражения

pl++;

переменная pi будет содержать значение 2004, а не 2001! Дело в том, что после каждого инкрементирования переменная pi указывает на следующее значение типа int. А поскольку тип int представлен в C# 4 байтами, то в результате инкрементирования значение переменной pi увеличивается на 4. Справедливо и обратное: при каждом декрементировании переменной pi ее значение уменьшается на 4. Например выражение

pl—;

приводит к тому, что значение переменной pl становится равным 1996, если раньше оно было равно 2000!

Все сказанное выше можно обобщить: после каждого инкрементирования указатель будет указывать на область памяти, где хранится следующий элемент его соотносимого типа, а после каждого декрементирования указатель будет указывать на область памяти, где хранится предыдущий элемент его соотносимого типа.

Арифметические операции над указателями не ограничиваются только инкрементированием и декрементированием. К указателям можно добавлять и вычитать из них целые значения. Так, после вычисления следующего выражения:

Поделиться:
Популярные книги

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Девочка для Генерала. Книга первая

Кистяева Марина
1. Любовь сильных мира сего
Любовные романы:
остросюжетные любовные романы
эро литература
4.67
рейтинг книги
Девочка для Генерала. Книга первая

На границе империй. Том 6

INDIGO
6. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.31
рейтинг книги
На границе империй. Том 6

Кодекс Крови. Книга ХVI

Борзых М.
16. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVI

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Мерзавец

Шагаева Наталья
3. Братья Майоровы
Любовные романы:
современные любовные романы
эро литература
короткие любовные романы
5.00
рейтинг книги
Мерзавец

Усадьба леди Анны

Ром Полина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Усадьба леди Анны

Не грози Дубровскому! Том II

Панарин Антон
2. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том II

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

(Не)свободные, или Фиктивная жена драконьего военачальника

Найт Алекс
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(Не)свободные, или Фиктивная жена драконьего военачальника

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия