Новости

НОУ ІНТУЇТ | лекція | Мова програмування і середовище розробки. цілі курсу

  1. Windows-проект Додамо в Рішення новий проект, аналогічно тому, як був доданий консольний проект....
  2. Як оцінити час роботи методу
  3. Попередні відомості про делегатів - функціональному типі даних
  4. клас TimeValue
  5. підсумки

Windows-проект

Додамо в Рішення новий проект, аналогічно тому, як був доданий консольний проект. В якості типу проекту виберемо "Windows Forms Application", дамо проекту ім'я "WindowsFormsToMathTools". Результат цієї роботи показаний на Мал. 1.9 .

При створенні проекту DLL автоматично створювався в проекті один порожній клас, в консольному проекті створювався клас, що містить метод Main з порожнім кодом методу. У Windows-проект автоматично створюються два класи - клас з ім'ям Form1 і клас з ім'ям Program.

Перший з цих класів є спадкоємцем класу Form з бібліотеки FCL і успадковує всі властивості і поведінку (методи і події) батьківського класу. Клас Form підтримує організацію інтерфейсу користувача в візуальному стилі. Форма є контейнером для розміщення візуальних елементів управління - кнопок (Button), текстових полів (TextBox), списків (ListBox) і більш екзотичних елементів - таблиць (DataGridView), дерев (TreeView) та багатьох інших елементів. З деякими елементами управління ми познайомимося вже в цьому прикладі, інші будуть зустрічатися в відповідних місцях нашого курсу.

Класи в C # синтаксично не є неподільними і можуть складатися з декількох частин, кожна з яких починається з ключового слова "partial" (частковий). Таким є і побудований автоматично клас Form1. Можливість розбиття опису одного класу на частини з'явилася ще у версії мови C # 2.0, що полегшує роботу над великим класом. Кожна частина класу зберігається в окремому файлі зі своїм ім'ям. Одна частина класу Form1 лежить в файлі з ім'ям "Form1.Designer.cs". Ця частина класу заповнюється автоматично інструментарієм, званим Дизайнером форми. Коли ми займаємося візуальним проектуванням форми і розміщуємо на ній різні елементи управління, міняємо їх властивості, надаємо формі потрібний вид, задаємо обробників подій для елементів управління, то Дизайнер форми транслює наші дії в дії над об'єктами відповідних класів, створює відповідний код і вставляє його в потрібне місце класу Form1. Передбачається, що розробник проекту не втручається в роботу Дизайнера і не коригує частина класу Form1, створену Дизайнером. Проте, розуміти код, створений Дизайнером, необхідно, а іноді корисно і коригувати його. Інша частина класу Form1, що зберігається у файлі "Form1.cs", призначена для розробника - саме в ній розташовуються автоматично створювані обробники подій, що відбуваються з елементами управління, код яких створюється самим розробником. Така технологія програмування, заснована на роботі з формами, називається візуальної, подієво керованої технологією програмування.

Клас Program, автоматично створюваний в Windows-проект, містить точку входу - статичний метод Main, про важливу роль якого ми вже говорили. На відміну від консольного проекту, де тіло процедури Main спочатку було порожнім і повинно було заповнюватися розробником проекту, в Windows-проектах процедура Main вже готова і, як правило, розробником не змінюється. Що ж робить автоматично створена процедура Main, текст якої можна бачити на Мал. 1.9 ? Вона працює з класом Application бібліотеки FCL, викликаючи по черзі три статичних методу цього класу - EnableVisualStyles, SetCompatibleTextRenderingDefault, Run. Про призначення перших двох методів можна судити по їх змістовним іменах. Основну роботу виконує метод Run - в процесі його виклику створюється об'єкт класу Form1 і відкривається форма - візуальний образ об'єкта, з якої може працювати кінцевий користувач проекту. Якщо, як годиться, форма спроектована і заповнена елементами управління, то кінцевому користувачеві залишається вводити власні дані в поля форми, натискати на кнопки, взагалі бути ініціатором виникнення різних подій в світі об'єктів форми. У відповідь на виникаючі події починають працювати обробники подій, що призводить до бажаних (або не бажаним) змін світу об'єктів. Типовою ситуацією є проведення обчислень за даними, введеним користувачем, і відображення результатів цих обчислень в полях форми, призначених для цих цілей.

Побудова інтерфейсу форми

Перш ніж зайнятися побудовою інтерфейсу форми, перейменуємо клас Form1, давши йому, як годиться, змістовне ім'я - FormResearchSinus. Зауважте, перейменування об'єктів класу хоча і можна робити вручну, але це далеко не кращий спосіб, до того ж, що загрожує помилками. Для цих цілей слід використовувати можливості, що надаються меню Refactor | Rename. Паралельно з перейменуванням класу слід перейменувати і файл (файли) з описом класу.

Займемося тепер побудовою інтерфейсу - розміщенням в формі елементів керування. Класичним прикладом інтерфейсу, що підтримує сервіси стандартного класу Math, є інженерний калькулятор. У нашому класі реалізована поки тільки одна функція - Займемося тепер побудовою інтерфейсу - розміщенням в формі елементів керування , Так що можемо побудувати поки калькулятор однієї функції. Але і цілі у нас інші - ми займаємося дослідженням того, наскільки коректно і точно запропоновані алгоритми дозволяють обчислити цю функцію.

Проведемо ще одне важливе дослідження - оцінимо час, що витрачається на обчислення функції. Тимчасові оцінки роботи проекту і його окремих частин - вкрай важлива частина роботи розробника проекту. У багатьох випадках потрібно побудувати тимчасової профіль роботи проекту, виявити його найбільш вузькі місця, на виконання яких йде основний час роботи, що дозволить цілеспрямовано займатися оптимізацією проекту, спрямованої на зменшення часу роботи. Слід пам'ятати, що інтерактивний стиль роботи сучасних додатків вимагає швидкої реакції системи на дії користувача. Користувач має право замислюватися при виборі своїх дій, але від системи в більшості випадків чекає негайної відповіді. Так що поставимо мету - отримати час, що витрачається комп'ютером на обчислення функції як стандартним методом класу Math, так і методами класу MyMath з бібліотеки MathTools.

на Мал. 1.10 показаний інтерфейс спроектованої форми.


Мал.1.10.

Інтерфейс форми класу FormResearchSinus

Для наших цілей достатній скромний інтерфейс. У форму включено текстове поле для введення значення аргументу Для наших цілей достатній скромний інтерфейс , Три текстових поля призначені для відображення результату обчислень функції трьома різними методами. У формі є окремий контейнер для оцінки тимчасових характеристик. У контейнер поміщені три текстових поля, в яких буде відображатися час, що витрачається на обчислення функції кожним з аналізованих методів. Оскільки комп'ютери швидкі, заміряти час, необхідний на одноразове обчислення функції, просто неможливо. Змиритися час, що витрачається на багаторазове виконання методу (окремої ділянки коду). У контейнері розміщено вікно, що дозволяє задати число повторів обчислення функції при вимірюванні часу роботи. Всі текстові поля забезпечені мітками, прояснюють сенс кожного поля. Для вхідних текстових полів (аргумент функції і число повторів) задані значення за замовчуванням. У формі знаходиться командна кнопка, клацання по якій призводить до виникнення події Click цього об'єкта, а обробник цієї події запускає обчислення значень функції, отримання оцінок часу обчислення і виведення результатів у відповідні текстові поля. Який сценарій роботи користувача? Коли під час запуску проекту відкривається форма, користувач може в відповідних полях задати значення аргументу функції і число повторів, після чого натиснути кнопку з написом "Обчислити sin (x)". У вихідних текстових полях з'являться результати обчислень. Змінюючи вхідні дані, можна спостерігати, як змінюються результати обчислень. Можна буде переконатися, що при всіх поставлених значеннях аргументу функції значення функції, обчислені трьома різними методами, збігаються з точністю до 9 знаків після коми, а час обчислень методу, вбудованого в стандартний клас Math, приблизно в два рази менше, ніж час спроектованих нами методів , що, втім, не дивно і цілком очікувано. Реалізація обчислення стандартних математичних функцій реалізована на апаратному рівні, тому практично неможливо написати власний код, який працює ефективніше.

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

Як оцінити час роботи методу

Давайте подумаємо, як можна оцінити час роботи методу класу або окремого фрагмента коду. По-перше, можна провести теоретичну оцінку. Наприклад, для функції Давайте подумаємо, як можна оцінити час роботи методу класу або окремого фрагмента коду , Як ми бачили, на одному кроці циклу потрібно близько 10 операцій (без урахування різну складність операцій). Число ітерацій залежить від значення аргументу. Максимальне значення аргументу по модулю не перевищує , Але і в цьому випадку 15 ітерацій досить, щоб поточний член суми по модулю став менше . Сучасному комп'ютера середньої потужності з частотою 1,6 GHz буде потрібно менше 1 секунди для обчислення функції при числі повторів .

Чим вважати операції, найчастіше простіше безпосередньо виміряти реальний час обчислень. У бібліотеці CLR для цих цілей створено клас DateTime, що дозволяє працювати з датами і часом. У цього класу є чудовий статичний метод Now, виклик якого повертає в якості результату об'єкт класу DateTime, що задає поточну дату і поточний час (по годинах комп'ютера). Численні властивості цього об'єкта - Year, Month, Hour, Second і багато інших дозволяють отримати все характеристики дати і поточного часу. Поточний час можна також вимірювати і в одиницях, званих "тиками", де один тик дорівнює 100 наносекунд або, що те ж, Чим вважати операції, найчастіше простіше безпосередньо виміряти реальний час обчислень секунди.

Маючи в своєму арсеналі такий клас, не складе великих труднощів виміряти час, необхідний на виконання деякої ділянки коду. Досить мати дві змінні з іменами, наприклад, start і finish класу DateTime. Зміною start дамо значення, що повертається функцією Now перед початком вимірюваного ділянки коду, а змінної finish - в кінці ділянки коду. Різниця часів дасть нам необхідну оцінку тривалості виконання коду.

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

Додамо в цю бібліотеку новий клас. Ось опис цього класу, поки порожнього, але містить заголовки коментар:

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MathTools {/// <summary> /// Клас спроектований для отримання оцінок часу /// виконання різних методів. /// Вбудовані делегати визначають сигнатури методів /// </ summary> public class TimeValue {}}

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

Попередні відомості про делегатів - функціональному типі даних

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

public delegate double DToD (double arg1);

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

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

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

клас TimeValue

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

public class TimeValue {public delegate double DToD (double arg1); /// <summary> /// Повертає час в секундах, /// витрачений на обчислення count раз /// методу fun з сигнатурою, яка задовольняє /// делегату DToD (double to double) /// </ summary> / // <param name = "count"> число повторень </ param> /// <param name = "fun"> ім'я функції </ param> /// <param name = "x"> аргумент </ param> / // <returns> час в мілісекундах або тиках </ returns> public static double EvalTimeDToD (int count, DToD fun, double x) {DateTime start, finish; double res = 0; start = DateTime.Now; for (int i = 1; i <count; i ++) fun (x); finish = DateTime.Now; // res = (finish- start) .Ticks; res = (finish - start) .Milliseconds; return res; }}

Час можна вимірювати в різних одиницях, наприклад, в тиках або мілісекундах. Статичний метод EvalTimeDToD, який реалізує сервіс класу, влаштований досить просто. Дві змінні start і finish класу DateTime викликають властивість Now, облямований цикл по числу повторів викликів методу, функціональний тип якого заданий делегатом, а ім'я передається в якості фактичного параметра при виклику методу EvalTimeDToD.

Ще одне важливе зауваження варто зробити з приводу точності оцінок, одержуваних при використанні механізму об'єктів DateTime. Слід враховувати, що властивість Now не повертає в точності даний час в момент її виклику. Це пов'язано з механізмами операційної системи, коли в реальності на комп'ютері працюють кілька процесів і система обробки переривань має деякий фіксований квант часу при перемиканні процесів. Тому, запускаючи вимір часу обчислень на одних і тих же даних, можна отримувати різні дані з точністю, яка визначається характеристиками системи переривань. Це істотно не впливає в цілому на отримання тимчасових характеристик, але не дозволяє порівнювати методи, час виконання яких можна порівняти з похибкою тимчасових оцінок.

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


Мал.1.11.

Порівняльні результати точності і часу обчислення функції sin (x)

підсумки

Ця лекція носить оглядовий характер. У ній вводиться багато понять з широкого кола галузей, пов'язаних як з мовою програмування, так і середовищем розробки, операційною системою. З цієї причини вона може бути важка для сприйняття тих, хто тільки осягає початку програмування. Нехай Вас не бентежить, якщо при її читанні залишилися незрозумілі речі. Сподіваюся, що деяке загальне враження про процес створення і виконання проектів, написаних на мові C # і створюваних в середовищі Visual Studio 2008, вона все ж дає. Добре було б повернутися до читання цієї лекції вже після проходження основного курсу.

Ще більші труднощі можуть виникнути при розборі прикладу, в якому я дозволив собі на початковому етапі застосовувати досить просунуті і різноманітні засоби мови C # і Visual Studio 2008. Проте і в цьому випадку хотілося б, щоб Ви повторили всі дії, які пов'язані з побудовою рішення, що включає три проекти. Моя мета - продемонструвати вже з перших кроків можливості мови C # з побудови коду, що відповідає вимогам промислового продукту.

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

На цьому я закінчу оглядове розгляд Visual Studio. Net і її каркаса Framework. Net. Однією з кращих книг, докладно висвітлюють цю тему, є книга Джеффрі Ріхтера, перекладена на російську мову: "Програмування на платформі. Net Framework". Вкрай цікаво, що для Ріхтера мови є лише надбудовою над каркасом, тому він говорить про програмування, що використовує можливості виконавчої середовища CLR і бібліотеки FCL.

Який сценарій роботи користувача?
Що дає оптимізація методу, розглянута нами в класі MyMath?

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

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: