Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Оператори checked и unchecked




 

Процесом генерації виключень, що виникають при переповнюванні, можна управляти за допомогою ключових слів checked і unchecked, які використовуються як операції, якщо вони використовуються у виразах, і як оператори, якщо вони стоять перед блоком, наприклад:

a = checked (b + с); // для виразу (перевірка включена)

unchecked

{ // для блоку операторів (перевірка вимкнена)

а = b + с:

}

Перевірка не розповсюджується на функції, викликані в блоці.

 

 

4.5. Рекомендації по програмуванню

Головна мета, до якої потрібно прагнути, - отримати зрозумілу програму якомога простішої структури. Всі технології програмування направлені на досягнення саме цієї мети, оскільки тільки так можна добитися надійності програми і легкості її модифікації.

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

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

При кодуванні програми необхідно пам'ятати про принципи структурного програмування: програма повинна складатися з чіткої послідовності блоків - базових конструкцій, кожна з яких має один вхід і один вихід. Конструкції можуть вкладатися, але не перетинатися.

Програма має бути “прозора”. Якщо яку-небудь дію можна запрограмувати різними способами, то перевага повинна віддаватися не найбільш компактному і навіть не найбільш ефективному, а зрозумілішому. Особливо це важливо тоді, коли пишуть програму одні, а супроводжують інші, що є широко поширеною практикою. «Непрозоре» програмування може спричинити величезні витрати, пов'язані з пошуком помилок при відладці.

Для запису кожного фрагмента алгоритму необхідно використовувати найбільш відповідні засоби мови. Наприклад, галуження на декілька напрямів за значенням цілої або рядкової змінної ефектніше записати за допомогою одного оператора switch, а не декількох операторів if. Для перегляду масиву краще користуватися циклом for або foreach. Оператор goto застосовують дуже рідко, наприклад, в операторі вибору switch або для примусового виходу з декількох вкладених циклів, а в більшості інших ситуацій краще використовувати інші засоби мови, такі як break або return.

Для організації циклів користуйтеся найбільш відповідним оператором. Цикл do застосовується тільки в тих випадках, коли тіло у будь-якому випадку потрібно буде виконати хоч би один раз, наприклад, при перевірці введення. При використанні циклів треба прагнути об'єднувати ініціалізацію, перевірку умови виходу і приріст в одному місці. При записі ітеративних циклів (у яких для перевірки умови виходу використовуються співвідношення змінних, що формуються в тілі циклу), необхідно передбачати аварійний вихід після досягнення заздалегідь заданої максимальної кількості ітерацій. Це підвищує надійність програми.

 

Безглуздо використовувати перевірку на рівність true або false:

bool busy;

if (busy = = true) {... } // погано! Краще if (busy)

if (busy = = false) {... } // погано! Краще if (!busy)

 

Слід уникати зайвих перевірок умов. Наприклад:

 

if (а < b) с = 1;

else if (а > b) с = 2;

else if (а == b) с = 3;

 

Замість цих операторів можна написати:

 

if (а < b) с = 1;

else if (а > b) с = 2;

else с = 3;

 

Або навіть так:

 

с = 3;

if (а < b) с = 1;

if (а > b) с = 2;

 

Якщо перша гілка оператора if забезпечує передачу управління, використовувати гілку else немає необхідності:

 

if (i > 0) break;

// тут i <= 0

 

В деяких випадках умовна операція краще умовного оператора:

 

if (z = = 0) i = j; else i = k; // краще так: i = z = = 0? j: k;

 

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

У програмі корисно передбачати реакцію на невірні вхідні параметри. Це може бути генерація виключення (переважно), друк повідомлення або формування ознаки результату з його подальшим аналізом. Повідомлення про помилку має бути інформативним і підказувати користувачеві, як її виправити. Наприклад, при введенні невірного значення в повідомленні має бути вказаний допустимий діапазон.

Укладайте потенційно небезпечні фрагменти програми в блок try, що перевіряється, і обробляйте хоч би виключення типу Exception, а краще - всі виключення, які можуть в нім виникнути, окремо.

Після написання програму слід ретельно відредагувати - прибрати непотрібні фрагменти, згрупувати описи, оптимізувати перевірки умов і цикли, перевірити, чи оптимальне розбиття на методи, і так далі. З першого разу без помарок хороший текст не напишеш, будь то твір, стаття або програма. Проте не слід намагатися оптимізувати все, що “попадається під руку”, оскільки головний принцип програміста той же, що і лікаря: “Не нашкодь!”.

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

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

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

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

Вкладені блоки повинні мати відступ в 3-5 символів, причому блоки одного рівня вкладеності мають бути вирівняні по вертикалі. Форматуйте текст по стовпцях скрізь, де це можливо, це робить програму набагато зрозумілішою:

 

string but = "qwerty";

double ex = 3.1234;

int number = 12;

byte z = 0;

if (done) Console.WriteLine("Сума ряду - " + у);
else Console.WriteLine("Ряд розходиться");:

if(x>= 0 && x < 10) у = t * x;

else if(x >= 10) у = 2 * t;

else у = x;

 

Для розділення методів і інших логічно закінчених фрагментів користуйтеся порожніми рядками або коментарем вигляду

 

//---------------------------------------------------------------------------

 

Позначайте кінець довгого складеного оператора, наприклад:

while (true)

{

while (х < у)

{

for(i=0; i<10; + + i)

{

for(j = 0; j<10; + + j)

{

// дві сторінки коду

} // end for (j = 0; j < 10; ++ j)

} // end for (i = 0; i < 10; ++ i)

} // end while (x < у)

} // end while (true)

 

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

 

 

РОЗДІЛ 5. КЛАСИ: ОСНОВНІ ПОНЯТТЯ

Всі програми, які приведені в роботі, складалися з одного класу і єдиним методом Main. Починаючи з цього розділу, розглядається вивчення створення і використання класів.

Клас є типом даних, визначуваним користувачем. Він має бути однією логічною суттю, наприклад, бути моделлю реального об'єкту або процесу. Елементами класу є дані і функції, призначені для їх обробки.

Опис класу містить ключове слово class, за яким слідує його ім'я, а далі у фігурних дужках - тіло класу, тобто список його елементів. Крім того, для класу можна задати його базові класи (предки) і ряд необов'язкових атрибутів і специфікаторів, що визначають різні характеристики класу:

 

[ атрибути ] [ специфікатори ] class ім'я_класу [: предки ]

тіло класу

 

Як бачите, обов'язковими є тільки ключове слово class, а також ім'я і тіло класу. Ім'я класу задається програмістом за загальними правилами С#. Тіло класу - це список описів його елементів, взятий у фігурні дужки. Список може бути порожнім, якщо клас не містить жодного елементу. Таким чином, простий опис класу може виглядати так:

 

class Demo {}

 

Необов'язкові атрибути задають додаткову інформацію про клас. Оскільки ми вивчаємо поки основні поняття про клас, то відкладемо розгляд атрибутів до розділу 12.

Специфікатори визначають властивості класу, а також доступність класу для інших елементів програми. Можливі значення специфікаторів перераховані в таблиці 5.1.

Таблиця 5.1

Специфікатори класу

 

Специфікатор Опис
  new Використовується для вкладених класів. Задає новий опис класу замість успадкованого від предка. Застосовується в ієрархіях об'єктів
  public Доступ не обмежений
  protected Використовується для вкладених класів. Доступ тільки з елементів даного класу і похідних класів
  internal Доступ тільки з даної програми (збірки)
  protected internal Доступ тільки з даного класу і похідних класів або з даної програми (збірки)
  private Використовується для вкладених класів. Доступ тільки з елементів класу, усередині якого описаний даний клас

Продовження таблиці 5.1

 

Специфікатор Опис
  abstract Абстрактний клас. Застосовується в ієрархіях об'єктів
  sealed Безплідний клас. Застосовується в ієрархіях об'єктів
  static Статичний клас

 

Клас можна описувати безпосередньо усередині простору імен або усередині іншого класу. У останньому випадку клас називається вкладеним. Залежно від місця опису класу деякі з цих специфікаторів можуть бути заборонені.

Специфікатори 2-6 називаються специфікаторами доступу. Вони визначають, звідки можна безпосередньо звертатися до даного класу. Специфікатори доступу можуть бути присутніми в описі тільки у варіантах, приведених в таблиці, а також можуть комбінуватися з рештою специфікаторів.

У цьому розділі ми вивчатимемо класи, які описуються в просторі імен безпосередньо (тобто не вкладені класи). Для таких класів допускаються тільки два специфікатори: public і internal, за умовчанням, тобто якщо жоден специфікатор доступу не вказаний, мається на увазі специфікатор internal.

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

Об'єкти створюються явним або неявним чином, тобто або програмістом, або системою. Програміст створить екземпляр класу за допомогою операції new, наприклад:

 

Demo a = new Demo (); // створення екземпляра класуDemo

Demo b = new Demo (); // створення іншого екземпляра класуDemo

 

Як ви пам'ятаєте, клас відноситься до посилальних типів даних, пам'ять під яких виділяється. Таким чином, змінні х і у зберігають не самі об'єкти, а посилання на об'єкти, тобто їх адреси. Якщо достатній для зберігання об'єкту об'єм пам'яті виділити не вдалося, операція new генерує виключення Outofmemory-exception. Рекомендується передбачати обробку цього виключення в програмах, що працюють з об'єктами великого об'єму.

Для кожного об'єкту при його створенні в пам'яті виділяється окрема область, в якій зберігаються його дані. Крім того, в класі можуть бути присутніми статичні елементи, які існують в єдиному екземплярі для всіх об'єктів класу. Часто статичні дані називають даними класу, а останні - даними екземпляра.

Функціональні елементи класу не тиражуються, тобто завжди зберігаються в єдиному екземплярі. Для роботи з даними класу використовуються методи класу (статичні методи), для роботи з даними екземпляра - методи екземпляра, або просто методи.

До цих пір ми використовували в програмах тільки один вид функціональних елементів класу - методи. Поля і методи є основними елементами класу. Крім того, в класі можна задавати цілу гамму інших елементів, приведених на рис. 5.1.

Опис елементів класу:

• Константи класу зберігають незмінні значення, пов'язані з класом.

• Поля містять дані класу.

• Методи реалізують обчислення або інші дії, що виконуються класом або екземпляром.

• Властивості визначають характеристики класу в сукупності із способами їх завдання і отримання, тобто методами запису і читання.

• Конструктори реалізують дії з ініціалізації екземплярів або класу в цілому.

• Деструктори визначають дії, які необхідно виконати до того, як об'єкт буде знищений.

• Індексатори забезпечують можливість доступу до елементів класу по їх порядковому номеру.

• Операції задають дії з об'єктами за допомогою знаків операцій.

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

• Типи - це типи даних, внутрішні по відношенню до класу.

Перші п'ять видів елементів класу ми розглянемо в цьому розділі, а останні - в подальших. Але перш ніж почати вивчення, необхідно поговорити про привласнення і порівняння об'єктів

 

5.1. Привласнення і порівняння об'єктів

 

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

Рисунок ілюструє ситуацію, коли було створено три об'єкти, а, b і с, а потім виконано привласнення b = с. Старе значення b стає недоступним і очищається складальником сміття. З цього виходить, якщо змінити значення однієї величини посилального типу, це може відбитися на іншій (в даному випадку, якщо змінити об'єкт через посилання с, об'єкт b також змінить своє значення).

Аналогічна ситуація з операцією перевірки на рівність. Величини значущого типу рівні, якщо рівні їх значення. Величини посилального типу рівні, якщо вони посилаються на одні і ті ж дані (на рисунку об'єкти b і с рівні, але а не рівне b навіть при рівності їх значень або якщо вони обидві рівні null).

Рис. 5.1. Склад класу

Рис. 5.2. Привласнення об'єктів

5.2. Дані: поля і константи

 

Дані, що містяться в класі, можуть бути змінними або Змінні, описані в класі, називаються полями класу.

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

 

[ атрибути ] [ специфікатори ] [ const ] тип ім'я [ = начальне_значення ]

 

Атрибути будуть розглянуті в розділі 12, а можливі специфікатори полів і констант перераховані в таблиці 5.2. Для констант можна використовувати тільки специфікатори 1- 6.

 

Таблиця 5.2.

Специфікатори полів і констант класу

 

Специфікатор Опис
  new Новий опис поля, що приховує успадкований елемент класу
  public Доступ до елементу не обмежений
  protected Доступ тільки з даного класу і похідних класів
  internal Доступ тільки з даної збірки
  protected internal Доступ тільки з даного класу і похідних класів і з даної збірки
  private Доступ тільки з даного класу
  static Одне поле для всіх екземплярів класу
  readonly Поле доступне тільки для читання
  volatile Поле може змінюватися іншим процесом або системою

 

За умовчанням елементи класу вважаються за закриті (private). Для полів класу цей вид доступу є переважним, оскільки поля визначають внутрішню будову класу, яка має бути прихована від користувача. Всі методи класу мають безпосередній доступ до його закритих полів.

Поля, описані із специфікатором static, а також константи існують в єдиному екземплярі для всіх об'єктів класу, тому до них звертаються не через ім'я екземпляра, а через ім'я класу. Якщо клас містить тільки статичні елементи, екземпляр класу створювати не потрібно.

Звернення до поля класу виконується за допомогою операції доступу (крапка). Праворуч від крапки задається ім'я поля, зліва - ім'я екземпляра для звичайних полів або ім'я класу для статичних. У лістингу 5.1 приведені приклад простого класу Demo і два способи звернення до його полів.

 

 

Лістинг 5.1. Клас Demo, що містить поля і константу

using System;

namespace ConsoleApplication1

{

class Demo

{

public int a = 1; // поле даних

public const double с = 1.66; // константа

public static string s = "Demo"; // статичне поле класу

double y; // закрите поле даних

}

 

class Classl

{

static void Main()

{

Demo x = new Demo(); // створення екземпляра класу Demo

Console. WriteLine (x.a); // x.a - звернення до поля класу

Console. WriteLine (Demo.с); // Demo.с - звернення до константи

Console. WriteLine (Demo.s); // звернення до статичного поля

}

}

}

 

Поле у вивести на екран аналогічним чином не вдасться: воно є закритим, тобто недоступно ззовні (з класу Classl). Оскільки значення цьому полю явним чином не привласнене, середовище привласнює йому значення нуль.

Всі поля спочатку автоматично ініціалізувалися нулем відповідного типу (наприклад, полям типу int привласнюється 0, а посиланням на об'єкти - значення nu11). Після цього полю привласнюється значення, задане при його явній ініціалізації. Завдання початкових значень для статичних полів виконується при ініціалізації класу, а звичайних - при створенні екземпляра.

 

Поля із специфікатором readonly призначені тільки для читання. Встановити значення такого поля можна або при його описі, або в конструкторі (конструктори розглядаються далі в цьому розділі).

 




Поделиться с друзьями:


Дата добавления: 2014-12-27; Просмотров: 489; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.277 сек.