Разделы презентаций


Опасный код

Содержание

Причины использования опасного кода. Управляемый код не допускает использование указателей. Указатели — это переменные, которые хранят адреса других объектов. Указатели в некотором роде подобны ссылкам в С#. Основное различие между ними

Слайды и текст этой презентации

Слайд 1Опасный код
С# позволяет программистам писать то, что называется "опасный

кодом"
(unsafecode).
Опасный код — это код, который не выполняется

под полным управлением системы Common Language Runtime (CLR).

Опасный код С# позволяет программистам писать то, что называется

Слайд 2Причины использования опасного кода.
Управляемый код не допускает использование указателей.


Указатели — это переменные, которые хранят адреса других объектов. Указатели

в некотором роде подобны ссылкам в С#. Основное различие между ними заключается в том, что указатель может указывать на что угодно в памяти, а ссылка всегда указывает на объект "своего" типа. Но если указатель может указывать на что угодно, возможно неправильное его использование. Кроме того, работая с указателями, можно легко внести в код ошибку, которую будет трудно отыскать.
Тем не менее указатели существуют, причем для некоторых типов программ (например, системных утилит) -они — необходимы.
Причины использования опасного кода. Управляемый код не допускает использование указателей. Указатели — это переменные, которые хранят адреса

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

"опасные", поскольку они выполняются вне управляемого контекста.
Объявление и использование указателей

в С# происходит аналогично тому, как это делается в C/C++. Однако: особенность С# — создание управляемого кода.
Его способность поддерживать неуправляемый код позволяет применять программы к задачам специальной категории. Но такое С# программирование уже не подпадает под определение стандартного. И в самом деле, чтобы скомпилировать неуправляемый код, необходимо использовать опцию компилятора /unsafe.
Программирование опасного кодаВсе операции с указателями должны быть отмечены как

Слайд 4Использование указателей
Указатели — это переменные, которые хранят адреса других

переменных.
Формат объявления переменной-указателя: ТИП* имя_переменной;
int* ip; float* fp;
Здесь

переменную ip можно использовать для
указания на int-значение, а переменную fp — на float-значение.
Однако не существует реального средства, которое могло бы помешать указателю указывать на"бог-знает-что".
Вот потому-то указатели потенциально опасны.
Использование указателей Указатели — это переменные, которые хранят адреса других переменных. Формат объявления переменной-указателя: ТИП* имя_переменной; int*

Слайд 5Различие между способами объявления указателей в С# и C/C++
При

объявлении типа указателя в C/C++ оператор " * " не

распространяется на весь список переменных, участвующих в объявлении.
То есть C/C++ при выполнении инструкции int* p, q; объявляется указатель р на int-значение и int-переменная с именем q.
Эта инструкция эквивалентна объявлениям: int* p ; int q;
В C# инструкция эквивалентна объявлениям: int* р; int* q;
Различие между способами объявления указателей в С# и C/C++ При объявлении типа указателя в C/C++ оператор

Слайд 6Операторы "*" и "&"
Оператор "&" — унарный. Он

возвращает адрес памяти, по которому расположен его операнд.
Пример
int *

i p ;
int num = 10;
ip = #
Оператор работы с указателями (*) служит дополнением к первому (&) он указывает на значение переменной, адресуемой заданным указателем
int val = *ip;
Оператор "*" также можно использовать с левой стороны от оператора присваивания.
*ip = 100;
Операторы

Слайд 7Использование ключевого слова unsafe
Код, в котором используются указатели, должен

быть отмечен как "опасный" с помощью ключевого слова unsafe.
Так

можно отмечать отдельные инструкции и методы целиком.

Использование ключевого слова unsafe Код, в котором используются указатели, должен быть отмечен как

Слайд 8Пример
using System;
class UnsafeCode {
unsafe public static void Main() {
int count

= 99;
int* p;
р = &count;
Console.WriteLine("count= " +*p);
*р =

10;
Console.WriteLine("Новый count= " + *р);
}
}
Примерusing System;class UnsafeCode {unsafe public static void Main() {	int count = 99;	int* p; 	р = &count; 	Console.WriteLine(

Слайд 9Использование модификатора fixed
При работе с указателями часто используется модификатор

fixed.
Он предотвращает удаление управляемых переменных системой сбора мусора.
Это

необходимо втом случае, если, например, указатель ссылается на какое-нибудь поле в объекте класса.
Поскольку указатель "ничего не знает" о действиях "сборщика мусора", то в случае удаления такого объекта этот указатель будет указывать на неверный объект.
fixed (type* p = &var) {
// Использование зафиксированного объекта.
}

Использование модификатора fixed При работе с указателями часто используется модификатор fixed. Он предотвращает удаление управляемых переменных системой

Слайд 10Пример использования модификатора fixed
using System;
class Test {
public int num;
public

Test(int i) { num = i ; }
class FixedCode {
unsafe

public static void Main() {
Test Sо = new Test(19);
fixed (int* p = So.num)
{Console.WriteLine("Начальное значение поля So.num равно " + *р);
*р = 10;
Console.WriteLine("Новое значение поля So.num равно " + *р);
}}}
Пример использования модификатора fixed using System;class Test {public int num;public Test(int i) { num = i ;

Слайд 11Доступ к членам структур с помощью указателей
Указатель может ссылаться

на объект структурного типа, если он не содержит ссылочных типов.

При доступе к члену структуры посредством указателя необходимо использовать оператор "стрелка" (->)


Слайд 12Пример
struct MyStruct {
public int x;
public int y;
public int sum() {

return x + y; }
}
------------------
MyStruct о = new MyStruct (

) ;
MyStruct* p; // Объявляем указатель.
р = & о;
р->х = 10;
р->у = 20;
Console.WriteLine("Сумма равна " + p->sum());

Слайд 13Арифметические операции над указателями
С указателями можно использовать : ++,

--, + и -.
int* p;
p =2000;
p++; //p =?
p=p+9;

//p =?
Несмотря на то что складывать указатели нельзя, один указатель можно вычесть из другого(если они оба имеют один базовый тип).
Разность покажет количество элементов базового типа, которые разделяют эти два указателя.
Помимо сложения (и вычитания) указателя и (из) целочисленного значения, а также вычитания двух указателей, над указателями никакие другие арифметические операции не выполняются.
Например, с указателями нельзя складывать float- или
double-значения.
Арифметические операции над указателями С указателями можно использовать : ++, --, + и -. int* p; p

Слайд 14Пример
using System;
class PtrArithDemo {
unsafe public static void Main() {
int x;
int

i;
double d;
int* ip = &i;
double* fp = &d;
Console.WriteLine("int double\n");
for(x=0; x

< 10; x++) {
Console.WriteLine((uint) (ip) + " " +(uint) (fp));
fp++;
ip++;}
}}
Примерusing System;class PtrArithDemo {unsafe public static void Main() {int x;int i;double d;int* ip = &i;double* fp =

Слайд 15Сравнение указателей
Для сравнения указателей любого типа можно использовать следующие операторы:

==   !=      =.
Операторы сравнения сравнивают адреса двух операндов, как если бы они

были беззнаковыми целыми числами.
Для того чтобы результат сравнения указателей поддавался интерпретации, сравниваемые указатели должны быть каким-то образом связаны.
То есть, если pi и р2 указывают на переменные, между которыми существует некоторая связь (как, например, между элементами одного и того же массива), то результат сравнения указателей pi и р2 может иметь определенный смысл.
Сравнение указателейДля сравнения указателей любого типа можно использовать следующие операторы: ==   !=      =.Операторы сравнения сравнивают адреса двух операндов, как

Слайд 16Пример
using System;
class PtrCompDemo {
unsafe public static void Main() {
int[] nums

= new int[11];
int x;
// Находим средний элемент массива,
fixed (int* start

= &nums[0]) {
fixed(int* end = &nums[nums.Length-1]) {
for(x=0; start+x <= end-x; x++) ;
}
}
Console.WriteLine(
"Средний элемент массива имеет номер " + х ) ;
}}
Примерusing System;class PtrCompDemo {unsafe public static void Main() {int[] nums = new int[11];int x;// Находим средний элемент

Слайд 17Указатели и массивы
В С# указатели и массивы связаны между собой.

Например, имя массива без индекса образует указатель на начало этого

массива.
using System;
class PtrArray {
unsafe public static void Main() {
int[] nums = new int[10];
fixed(int* p = &nums[0]; p2 = nums;) {
if(p == p2)
Console.WriteLine("Указатели р и р2 равны");
}}}
Указатели и массивыВ С# указатели и массивы связаны между собой. Например, имя массива без индекса образует указатель

Слайд 18Индексация указателя
Указатель, который ссылается на массив, можно индексировать так,

как если бы это было имя массива.
Этот синтаксис обеспечивает

альтернативу арифметическим операциям над указателями, поскольку он более удобен в некоторых ситуациях.
(ptr + i) эквивалентно ptr[i]
При индексировании указателя необходимо помнить следующее.
Во-первых, при этом нарушение границ массива никак не контролируется. Следовательно, существует возможность получить доступ к "элементу" за концом массива, если на него ссылается указатель.
Во-вторых, указатель не имеет свойства Length. Поэтому при использовании указателя невозможно узнать длину массива.
Индексация указателя Указатель, который ссылается на массив, можно индексировать так, как если бы это было имя массива.

Слайд 19Указатели и строки
Несмотря на то что в С# строки

реализованы как объекты, к отдельным их символам можно получить доступ

с помощью указателя.
Для этого достаточно присвоить
char*-указателю адрес начала этой строки, используя fixed-инструкцию:
fixed(char* p = str ) { II . . .

Указатели и строки Несмотря на то что в С# строки реализованы как объекты, к отдельным их символам

Слайд 20Массивы указателей
Указатели, подобно данным других типов, могут храниться в

массивах.
int * [ ] p t r s =

new int * [3];
Чтобы присвоить адрес int-переменной с именем var третьему элементу этого
массива указателей, запишите следующее:
ptrs[2] = &var;
Чтобы получить значение переменной var, используйте такой синтаксис:
*ptrs[2]
Массивы указателей Указатели, подобно данным других типов, могут храниться в массивах. int * [ ] p t

Слайд 21sizeof
sizeof -Для получения размера (в байтах) одного из С#-типов

значений.
sizeof(тип)
Оператор sizeof можно использовать только в контексте опасного (unsafe)

кода. Таким образом, он предназначен в основном для специальных ситуаций, особенно при работе со смешанным (управляемым и неуправляемым) кодом.
NB Начиная с версии 2.0 языка C# при применении оператора sizeof к встроенным типам больше не требуется использовать небезопасный режим.
sizeof sizeof -Для получения размера (в байтах) одного из С#-типов значений. sizeof(тип)Оператор sizeof можно использовать только в

Слайд 22Boxing\Unboxing
Упаковка-преобразование представляет собой процесс преобразования типа значения в тип object

или любой другой тип интерфейса, реализуемый этим типом значения.
Когда

тип значения упаковывается средой CLR, она создает программу-оболочку значения внутри System.Object и сохраняет ее в управляемой куче.
Операция распаковки-преобразования извлекает тип значения из объекта. Упаковка-преобразование является неявной; распаковка-преобразование является явной.
Концепция упаковки и распаковки лежит в основе единой системы типов C#, в которой значение любого типа можно рассматривать как объект.
Boxing\UnboxingУпаковка-преобразование представляет собой процесс преобразования типа значения в тип object или любой другой тип интерфейса, реализуемый этим

Слайд 23Пример
Упаковка
int i = 123;
// The following line boxes i.
object o

= i;
Распаковка
o = 123;
i = (int)o; // unboxing

ПримерУпаковкаint i = 123;// The following line boxes i.object o = i; Распаковкаo = 123;i = (int)o;

Слайд 24Упаковка
int i = 123;
object o = i;

Упаковкаint i = 123;object o = i;

Слайд 25Распаковка
int i = 123; // a value type
object

o = i; // boxing
int j = (int)o;

// unboxing

Распаковкаint i = 123;   // a value typeobject o = i;   // boxingint

Слайд 26Резюме
По сравнению с простыми операциями присваивания операции упаковки-преобразования и распаковки-преобразования

являются весьма затратными процессами с точки зрения вычислений.
При выполнении

упаковки-преобразования типа значения необходимо создать и разместить новый объект.
Объем вычислений при выполнении операции распаковки-преобразования, хотя и в меньшей степени, но тоже весьма значителен
РезюмеПо сравнению с простыми операциями присваивания операции упаковки-преобразования и распаковки-преобразования являются весьма затратными процессами с точки зрения

Обратная связь

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

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика