небезпечний код

небезпечний код

Книга розрахована на широке коло читачів, які цікавляться програмуванням на C # .Введіте сюди коротку анотацію

Книга: C # 4.0: повне керівництво

небезпечний код

Розділи на цій сторінці:

У C # дозволяється писати так званий "небезпечний" код. У цьому дивному на перший погляд затвердження немає насправді нічого незвичайного. Небезпечним вважається не погано написаний код, а такий код, який не може бути виконаний під повним керуванням в загальномовного виконуючого середовища (CLR). Як пояснювалося в розділі 1, результатом програмування на C # зазвичай є керований код. Проте ця мова програмування допускає написання коду, який не виконується під повним керуванням в середовищі CLR. Такий некерований код не підкоряється тим же самим засобам управління і обмеженням, що і керований код, і називається він небезпечним тому, що не можна ніяк перевірити, чи не виконує він яке-небудь небезпечне діяння. Отже, термін небезпечний зовсім не означає, що коду притаманні якісь вади. Це просто означає, що код може виконувати дії, які не підлягають контролю в керованому середовищі.







У мові C # покажчики оголошуються і використовуються таким же чином, як і в С / С ++. Якщо ви знаєте, як користуватися ними в С / С ++, то вам неважко буде зробити це і в С #. Але не забувайте, що головне призначення C # - створення керованого коду. А здатність цієї мови програмування підтримувати некерований код слід використовувати для вирішення лише особливого роду завдань. Це, скоріше, виняток, ніж правило для програмування на С #. По суті, для компіляції некерованого коду слід використовувати параметр компілятора / unsafe.

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

Основи застосування покажчиків

Звернемося до конкретного прикладу. Для того щоб зробити змінну ip покажчиком на значення типу int. необхідно оголосити її в такий спосіб.

А покажчик типу float оголошується так, як показано нижче.

Тип даних, на які буде вказувати сам покажчик, залежить від його співвідносить типу. Тому в наведених вище прикладах змінна ip може служити для вказівки на значення типу int. а змінна fp - для вказівки на значення типу float. Слід, однак, мати на увазі, що вказівником ніщо не заважає вказувати на що завгодно. Саме тому покажчики потенційно небезпечні.

Це головна відмінність слід мати на увазі при перенесенні коду C / C ++ на С #.

Оператори * і в покажчиках

Оператор * можна використовувати також в лівій частині оператора присвоювання. У цьому випадку він задає значення, на яке вказує відповідний покажчик, як у наведеному нижче прикладі.

Застосування ключового слова unsafe

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

Ця програма дає наступний результат.

Початкове значення змінної count: 99
Нове значення змінної count: 10

Застосування модифікатора fixed

У роботі з покажчиками нерідко використовується модифікатор fixed. який перешкоджає видаленню керованої змінної засобами "збірки сміття". Потреба в цьому виникає, наприклад, в тому випадку, якщо покажчик звертається до полю в об'єкті певного класу. А оскільки вказівником нічого не відомо про дії системи "збірки сміття", то він буде вказувати не на той об'єкт, якщо видалити потрібний об'єкт. Нижче наведена загальна форма модифікатора fixed:







Нижче наведено приклад застосування модифікатора fixed.

Ось до якого результату приводить виконання цієї програми.

Початкове значення змінної о.num: 19
Нове значення змінної о.num: 10

В даному прикладі модифікатор fixed перешкоджає видаленню об'єкта о. А оскільки змінна р вказує на змінну примірника о.num. то вона буде вказувати на недостовірну область пам'яті, якщо видалити об'єкт о.

Доступ до членів структури за допомогою покажчика

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

здійснюється наступним чином.

Арифметичні операції над покажчиками

Все сказане вище можна узагальнити: після кожного инкрементирования покажчик буде вказувати на область пам'яті, де зберігається наступний елемент його співвідносить типу, а після кожного декрементірованія покажчик буде вказувати на область пам'яті, де зберігається попередній елемент його співвідносить типу.

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

змінна p1 буде вказувати на дев'ятий елемент її співвідносить типу по відношенню до елементу, на який вона вказує зараз.

Якщо складати покажчики не можна, то дозволяється віднімати один покажчик з іншого, за умови, що обидва покажчика мають один і той же співвідноситься тип. Результатом такої операції виявиться кількість елементів співвідноситься типу, які поділяють обидва покажчика.

Крім додавання і віднімання цілого числа з покажчика, а також віднімання двох покажчиків, інші арифметичні операції над покажчиками не дозволяються. Зокрема, до покажчиків можна додавати або віднімати з них значення типу float або double. Не допускаються також арифметичні операції над покажчиками типу void *.

Нижче наведено приблизний результат виконання даної програми. У вас він може бути іншим, хоча проміжки між виведеними значення повинні бути такими ж самими.

порівняння покажчиків

Покажчики можна порівнювати за допомогою таких операторів відносини, як ==. <и>. Але для того щоб результат порівняння покажчиків виявилася змістовною, обидва покажчика повинні бути якимось чином пов'язані один з одним. Так, якщо змінні p1 і р2 є покажчиками на дві різні і не пов'язані разом змінні, то будь-яке їхнє порівняння, як правило, не має ніякого сенсу. Але якщо змінні p1 і р2 вказують на пов'язані разом змінні, наприклад на елементи одного масиву, то їх порівняння може мати певний сенс.

Покажчики та масиви

У C # покажчики і масиви пов'язані один з одним. Наприклад, при вказівці імені масиву без індексу в операторі з модифікатором fixed формується покажчик на початок масиву. Як приклад розглянемо наступну програму.

Нижче наведено результат виконання цієї програми.

Як випливає з наведеного вище результату, вираження

виявляються однаковими. Але оскільки друга форма більш лаконічна, то вона частіше використовується в програмуванні, коли потрібно покажчик на початок масиву.

індексування покажчиків

Коли покажчик звертається до масиву, його можна індексувати як сам масив. Такий синтаксис служить зручнішою в деяких випадках альтернативою арифметичним операціям над покажчиками. Розглянемо наступний приклад програми.

Нижче наведено результат виконання цієї програми.

Як випливає з результату виконання вищевказаних дій програми, загальна форма вираження з покажчиком

може бути замінена наступним синтаксисом індексування масиву.

Що стосується індексування покажчиків, то необхідно мати на увазі наступне. По-перше, при такому индексировании контроль кордонів масиву не здійснюється. Тому покажчик може звертатися до елементу поза межами масиву. І по-друге, для покажчика не передбачено властивість Length. визначальне довжину масиву. Тому, якщо використовується покажчик, довжина масиву заздалегідь невідома.

Покажчики і рядки

Після виконання оператора з модифікатором fixed змінна р вказуватиме на початок масиву символів, складових рядок. Цей масив закінчується символом кінця рядка, тобто нульовим символом. Тому ця обставина можна використовувати для перевірки кінця масиву. У C / C ++ рядки реалізуються у вигляді масивів, що закінчуються символом кінця рядка, а отже, отримавши покажчик типу char * на рядок, нею можна маніпулювати таким же чином, як і в C / C ++.

Нижче наведена програма, що демонструє доступ до символьної рядку за вказівником типу char *.

Ця програма дає наступний результат.

небезпечний код

Слід, однак, мати на увазі, що змінна q є покажчиком нема на ціле значення, а на покажчик типу int.







Схожі статті