Указатели (pointers). Компьютерные технологии (программирование на C#)
В отличие от ссылочного типа указатель существует сам по себе как число, независящее от объекта, на который он «указывает». Поэтому указатели можно складывать как целые числа. Например, указатель pb++ будет содержать адрес на единицу больший pb. Результатом должен быть байт *pb, «стоящий под указателем» pb. В данном случае это число 0, так как младший (первый) байт целого числа 256 равен нулю… Читать ещё >
Указатели (pointers). Компьютерные технологии (программирование на C#) (реферат, курсовая, диплом, контрольная)
Отдельной категорией типов в C# являются указатели (pointer). Это адреса объектов типов-значений. Только объекты типов-значений и только те, у которых нет полей ссылочного типа (так называемые «неуправляемые типы» — unmanaged types), могут быть поставлены под указатели. Указатели не являются классами. Блок кода или метод, в котором применяются указатели, должен предваряться служебным словом unsafe (небезопасный). При компиляции проекта с небезопасным кодом в свойствах проекта на странице Build должен быть поднят флажок Allow unsafe code.
Наберите для примера код с использованием указателя так, чтобы метод Main класса _2 проекта MainExe имел вид.
int i = 256;
unsafe.
{.
byte* pb = (byte*)&i;
System.Console.WriteLine (*pb);
}.
System.Console.ReadLine ();
Выполните эту версию проекта MainExe.
В строке.
byte* pb = (byte*)&i;
описан указатель pb на тип byte;
указатель pb инициализирован значением адреса & переменной целого типа i;
так как адрес &i относится к типу int* - «указатель на целое», то оператором (byte*) проводится его преобразование в «указатель на байт».
Результатом должен быть байт *pb, «стоящий под указателем» pb. В данном случае это число 0, так как младший (первый) байт целого числа 256 равен нулю, а старший — единице.
В отличие от ссылочного типа указатель существует сам по себе как число, независящее от объекта, на который он «указывает». Поэтому указатели можно складывать как целые числа. Например, указатель pb++ будет содержать адрес на единицу больший pb.
В вышеприведенном примере кода вместо WriteLine (*pb)распечатайте *++pb, затем pb[0] и pb[1]. Указатель ++pb равносилен указателю pb+1 и несет адрес второго байта числа i. Выражения pb[0]и pb[1] равносильны *pb и *(pb+1). Значение *++pb и pb[1]при i=256 должно быть 1. Замените 256 на 512. Посмотрите результат.
Если объекту отвечает некоторый указатель и этот объект оказывается уничтоженным автоматической «сборкой мусора», то адрес указателя теряет смысл. Чтобы избежать такой ситуации в C# применяется оператор fixed, «замыкающий» доступ «сборщика мусора» к объекту в блоке кода, в котором определен и действует указатель на этот объект.
Другой способ избежать сборки мусора при работе с указателями позволяет зарезервировать область стека достаточного объема для хранения данных под указателем. Оператор, резервирующий n байт памяти под указатель buffer, имеет вид byte* buffer = stackalloc byte[n];. Используется служебное слово stackalloc. Такое резервирование возможно лишь внутри блока unsafe. Например, в методе static unsafe void DoSmth (int n).
{.
byte* buffer = stackalloc byte[n];
//Код, работающий с буфером buffer.
}.
Область buffer будет освобождена (возвращена в «кучу») только по окончанию метода DoSmth.