Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Дата. Час




4.1 Функції дати і часу

Стандартна бібліотека С містить набір функцій для обробки дати та часу, всі вони оголошені в файлі time.h. Це такі функції:

time_t time(time_t *timer);

double difftime(time_t timel, time_t time2);

struct tm *gmtime(const time_t *timer);

struct tm *localtime(const time_t *timer);

char *asctime(const struct tm *timeptr);

char *ctime(const time_t *timer);
size_t strftime(char *s, size_t maxsize, const char *format,

const struct tm *timeptr);

time_t mktime(struct tm *timeptr);

clock_t clock(void);


У цих функціях застосовуються такі три типи: time_t, struct tm і clock_t. Вони будуть пояснені в ході розгляду функцій.

Функція time() оголошена так:

time_t time (time_t * timer);

Вона видає поточну дату і час. Тип time_t визначено як арифметичний, він здатний представляти час. Це означає, що він може бути цілим типом, таким як signed або unsigned, int або long, або типом з пересувною точкою, таким як double. В С не специфікується те, як змінна time_t представляє час. Програма не повинна вживати тип time_t безпосередньо, а лише в функціях стандартної бібліотеки.

Функція difftime() має таке оголошення:


double difftime(time_t timel, time_t time2);


Вона обчислює інтервал між двома значеннями типу time_t, даючи відповідь у секундах. Якщо час timel більш пізній, ніж time2, то результат буде додатнім, в іншому випадку – від’ємним. Функція difftime() дозволяє вимірювати часовий інтервал у секундах, навіть коли значення time_t не представлені в секундах. Цей факт демонструється в прикладі 4.1.

Приклад 4.1. – Вимірювання часових інтервалів з

використанням функцій time() і difftime()


# include <stdio.h>

# include <stdlib.h>

# include <time.h>
int main (void)

{
time_t start, end;
start = time(NULL);
if (start == (time_t)-l)

{
printf("У цій системі час недоступний\п"); exit(EXIT FAILURE);

}
printf("Зачекайте декілька секунд і натисніть клавішу ENTER / RETURN"); fflush(stdout);
getchar();
end = time(NULL);
printf("\n Інтервал часу=%.2 f секунд \n", difftime(end, start));
return 0;

}

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

Програма виводить результат у два десяткових розряди. Зазвичай змінна time_t представляє час у повних секундах, і в цьому випадку не має дробової частини. Однак, якщо цього недостатньо, С дозволяє реалізувати зберігання інформації про дробову частину секунди у змінній time_t.

4.2 Форми представлення дати і часу


Тип struct tm представляє дату і час розбитими на стандартні компоненти відповідно до Грегоріанського календара. У табл. 4.1 наведені елементи цього типу.

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

tm_sec знаходиться звичайно в діапазоні 0-59, але може приймати й значення 60 для додаткової секунди, яка іноді вставляється в цілях зберігання днів при синхронізації годин з обертанням Землі;

Таблиця 4.1 – Елементи структури struct tm

Елемент Опис
int tm_sec Секунди після хвилин (0-60)
int tm_min Хвилини після годин (0-59)
int tm_hour Години, відраховані від півночі (0-23)
int tm_mday День місяця (1-31)
int tm_mon Місяць року (від 0 – січень до 11 – грудень)
int tm_year Рік, починаючи з 1900 року
int tm_wday День тижня (від 0 – неділя до 6 – субота)
int tm_yday День року (0 – 365)
int tm_jsdst Вказівник врахування літнього часу

tm_mon починається не з 1 для січня, а з 0. Тому у перетворенні дати ця величина повинна бути скоригована на 1;

tm_mday починається з 1;

tm_year представляє роки, починаючи з 1900. Це означає, що рік 2000 буде містити величину 100, яка має більше двох останніх цифр року;

tm_yday також починається з 0 на 1 січня. 31-й день грудня – це 364-й або 365-й день для високосного року;

tm_isdst вказує чи прийнято літній час у розрахунок для певного часу, він приймає такі значення:

tm_isdst > 0 – літній час враховується;

tm_isdst = 0 – літній час не враховується;

tm_isdst < 0 – інформація недоступна.

Мова С має дві функції для конвертування значення time_t в тип struct tm, це localtime() і gmtime(), які оголошені так:


struct tm * gmtime (const time_t * timer);

struct tm * localtime (const time_t * timer);

Обидві ці функції отримують вказівник на змінну time_t, яка містить результат конвертації значення (time_t може не завжди бути типом, що гарантує можливість передачі його в якості аргумента функції). Сама змінна time_t не модифікується, але обидві функції повертають вказівник на внутрішній статичний об’єкт struct tm, що містить відповідні значення. Різниця між функціями gmtime() і localtime() полягає в тому, що lосаltime() дає результат, представлений у вигляді локального (місцевого) часу зони програми, в той час як gmtime () – GMT або UTC.

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


4.3 Строкове форматування часу


Просте форматування часу забезпечують функції asctime() і ctime(), вони генерують рядок, перед яким ставиться конкретний час у фіксованому форматі, наприклад так:


Tue Feb 29 23:59:59 2000 \n


Це 23 год 59 хв 59 с, вівторок 29 лютого 2000 року. Тут \n – відомий символ переходу на новий рядок. Цей символ у багатьох випадках доводиться згодом видаляти. Функції asctime() і ctime() оголошуються так:

char *asctime(const struct tm *timeptr);

char *ctime(const struct tm *timer);


Вони однакові, за винятком того, що ascthne () отримує вказівник на об’єкт struct tm, тоді як ctime () – на time_t. Функція ctime () призначена для виведення локального часу. Звернення ctime(timer) еквівалентно зверненню asctime(localtime (timer)).

Складне форматування часу виконує функція strftime(), вона використовується для форматування рядка подібно до функції друку printf(), але з іншими специфікаторами конвертації. Оголошується функція strftime() так:

size_t strftime(char *s, size_t maxsize, const char *format,

const struct tm * timeptr);

Тут s – покажчик на певний масив символів, у якому буде збережений результуючий рядок. Змінна maxsize являє собою максимальне число символів, які функція strftime() може записати, включаючи символ нуль (зазвичай це розмір масиву). Змінна format – це рядок формату, a timeptr – вказівник на заповнену структуру struct tm.


Таблиця 4.2 – Специфікатори конвертації функції strftime()

Специфікатор Значення
% a * Абревіатура назви дня тижня
% А * Повна назва дня тижня
% b * Абревіатура назви місяця
% В * Повна назва місяця
% З * Повна дата і час
% D День місяця (від 01 до 31)
% Н Година (годинник на 24 години від 00 до 23)
% | Година (годинник на 12 годин від 01 до 12)
% J День року (від 001 до 366)
% Т Місяць (від 01 до 12)
% М Хвилина (від 00 до 59)
% Р * Позначення АМ / РМ для годинника на 12 годин
% S Секунди (від 00 до 59)
% U Номер тижня (за кількістю неділь)
% w Назва дня тижня (від 0 – неділя до 6 – субота)
% W Номер тижня (за кількістю понеділків)
% x * Представлення повної дати
% Х * Представлення повного часу дня
% y Рік без вказівки століття (від 00 до 99)
% У Повний рік, включаючи століття
% Z Назва або абревіатура тимчасової зони (або пробіл – у разі недоступності інформації про тимчасову зону)
%% Одиночний символ %

Примітка. * – локальний специфікатор

Функція strftime() копіює символи з рядка формату в масив, на який вказує s, і конвертує послідовність двох символів % до полів часу. Вона повертає кількість символів, записаних у символьний масив, включаючи нульовий. Якщо вихідний рядок виявиться довшим, ніж maxsize, функція strftime() повертає 0 і – нічого про вміст масиву, хоча він може бути й частково заповнений. У таблиці 4.2 наведені елементи специфікаторів конвертації.

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

У різних частинах світу використовуються різні формати дат. Наприклад, у США основним форматом дати є: мм/дд/рррр, тоді як у Великобританії – дд/мм/рррр. Так що 01/02/2000 у Великобританії може читатися як 1 лютого, а в США – 2 січня 2000 року. Формати дат і номерів тижня регламентуються стандартом ISO 8601. Його повний формат дати такий:


рр-мм-ддТгг:хх:сс,

де T – розділовий знак, який відділяє дату від часу.

Відповідно до міжнародного стандарту ISO 8601 запис дати: 2000-02-29Т12: 00:00 означає рівно опівдні 29 лютого 2000 року.

Розміри поля для локально-визначених перетворень не специфіковані. Це ускладнює визначення того який розмір символьного масиву слід прийняти для забезпечення запису в нього результату.

Специфікатори %U і %W застосовуються для номерів тижня. При використанні %U перша неділя року визначається як перший день тижня, тобто дорівнює 1. При використанні %W першим днем тижня буде перший понеділок. Будь-який день, який йому передує, розглядається як нульовий, тому у конкретному додатку слід враховувати, що номери тижнів можуть не відповідати дійсним. У прикладі 4.2 показано використання функцій localtime(), asctime() і ctime().

Приклад 4.2 – Приклад використання функцій часу

#include<stdio.h>

#include<time.h>

void seda(void)

{

time_t tt;

struct tm *ptr;

tt = time(NULL);

ptr = localtime(&tt);

printf(asctime(ptr));

return;

}

void misc_ch(void)

{

time_t tt;

tt = time(NULL);

printf(ctime(&tt));

return;

}

main()

{

seda();

misc_ch();

getch();

}

Thu Feb 03 12:07:59 2011

Thu Feb 03 12:07:59 2011

Одержані результати означають, що програма виконувалася в четвер 3 лютого 2011 року о 12 годині 7 хвилин 59 секунд.

Деякі компілятори мають функції getdate() і gettime(), вони описані в файлі <dos.h>. Їх використання демонструє приклад 4.3. Крім того, показано прийом, який дозволяє видавати дату і час у будь-якому форматі (в прикладі 4.3 – державною мовою).

Приклад 4.3 – Застосування функцій getdate() і gettime()

# include <stdio.h> / * Системна дата і час * /
# include <dos.h>
main()
{

char naz [12] [10] = {"січня", "лютого", "березня", "квітня",

"травня", "червня", "липня", "серпня",

"вересня", "жовтня", "листопада", "грудня"};
struct dat{int y;
char d;
char m;};
struct tim{
char m;
char o;
char h;
char s;};
struct dat *dp;
struct tim *dt;
clrscr();

gettime(dt);

getdate(dp);
printf("Програма виконана о %d год %d хв %d сек\n", dt->o, dt->m, dt->s);
printf("Була дата: %d %s %d-го року\ n", dp->d, naz[dp->m-1], dp->y);
getch ();
}

Програма виконана o 13 год 22 хв 8 cek

Була дата: 3 лютого 2011-го року

Зчитування дати і часузабезпечує функція mktime(). За своєю суттю вона протилежна функції localtime(). Ця функція приймає заповнений struct tm і конвертує його в значення time_t. Крім того, вона модифікує елементи struct tm так, що ті опиняються в потрібних діапазонах. Оголошення функції mktime() виглядає так:


time_t mktime (struct tm *timeptr);


Ця функція приймає вказівник на об’єкт struct tm, який вона може зчитувати та модифікувати, і повертає значення time_t.

4.4 Визначення часу виконання програми


Останньою функцією в переліку бібліотеки time.h, поданому на початку цього розділу, є функція clock(). На відміну від інших, вона не має відношення до дат і призначена для визначення часу роботи центрального процесора. Ця функція оголошується так:


clock_t clock (void);


Файл time.h додатково визначає також тип clock_t і макрос CLOCKS_PER_SEC. Змінна clock_t часто є 32-бітовою. Це дозволяє мати максимальне значення, яке дорівнює 2147483647. Оскільки компілятор не контролю переповнення цілочислових даних під час виконання довготривалих програм, цей контроль повинна виконувати прикладна програма.

Функція clock() повертає значення, яке, будучи поділеним на CLOCKS_PER_SEC, дорівнює часу в секундах. Іншими словами: для конвертації інтервалу між двома викликами функції clock() в секунди потрібно поділити різницю на число CLOCKS_PER_SEC. Значення цього макроса залежить від технічних характеристик комп’ютера і в різних системах буде різним. Деякі ранні версії С мають подібний макрос CLK_TCK.

Функція clock() корисна для визначення часу роботи CPU при виконанні тієї чи іншої програми. У прикладі 4.4 показано спосіб її використання.

Приклад 4.4 – Використання функції clock()

# include<stdio.h>

# include<time.h>
int main (void)

{
clock_t start, end;

start = clock();
/ * Текст програми, час виконання якої визначається * /

end = clock();
printf([dbl] Interval =%f seconds.2 \n [dbl], (double) (end-start)/

(Double) CLOCKS_PER_SEC);
return 0;

}


Слід звернути увагу на те, що єдине значення clock() не має сенсу, корисною може бути тільки різниця між двома значеннями, що видаються функцією clock(). У прикладі 4.4 ця різниця дорівнює end-start.


КЛАСИ

5.1 Основні поняття

З розвитком засобів обчислювальної техніки появлялися й нові методики програмування, зокрема такі:

- програмування безпосередньо в машинних кодах. Це найбільш трудоміский вид програмування, який вимагав від програміста знання будови обчислювальної машини та особливостей машинних команд. Такі програми найважче налагоджувати, бо їхній текст містить усього два символи: 0 і 1;

- програмування мовою асемблер. Робота програміста стала продуктивнішою, команди замінювалися більш зрозумілими словами, застосовувалися ідентифікатори змінних, автоматично розподілялася пам’ять комп’ютера;

- програмування мовами високого рівня, таких, наприклад, як Фортран;

- програмування мовами структурного програмування (Паскаль, С). Особливістю цієї методики є можливість застосування структур (іноді їх називають записами), вже розглянених нами в попередніх розділах;

- об’єктно-орієнтоване програмування (С++).

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

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

Поняття об’єкта тісно пов’язано з поняттям класу. Клас – це тип, він являє собою подальший розвиток поняття структури (мовою С – struct), головною його особливістю є наявність функцій. Об’єкт – це представник певного класу. Візьмемо, наприклад, клас “собака”, який моделює поведінку (бігає, подає голос) та властивості (колір, вага), загальні для всіх собак. Якщо такий клас доповнити відомостями про конкретного собаку (певну реакцію на подразники, білий колір, вага 10 кг), то одержимо об’єкт класу “собака”. Як видно з цього прикладу, класом можна назвати модель деякого абстрактного об’єкта.

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

Оголошення класу має такий вигляд:

class ім’я класу

{перелік закритих функцій і змінних;

public: перелік відкритих функцій і змінних;

}список об’єктів; //не обов’язковий

Дані, доступні для використання лише всередині об’єкта (закриті) оголошуються як private (прийнято за замовчуванням), а дані доступні ззовні – public. Закриті функції і змінні доступні тільки для інших членів цього класу. Відкриті функції і змінні доступні для будь-якої частини програми, яка має клас. Функції, оголошені всередині опису класу, називаються функціями-членами (member functions). Їх визначення має такий вигляд:

тип ім'я класу:: ім'я функції-члена (параметри)

{ тіло функції;

}

Дві двокрапки після імені класу називаються операцією розширення області видимості (scope resolution operator).

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

Складемо програму (приклад 5.1), яка буде підносити до квадрату число 3.

Приклад 5.1. – Опис та використання класу klac

# include <iostream.h>

class klac { //оголошення класу klaс

int a; // змінна а, доступна лише для функції kwadrat()

public:

int kwadrat(int); // функція kwadrat(), доступна ззовні

};

int klac::kwadrat(int b) //визначення функції kwadrat()

{

a = b*b;

return a;

}

int main(void)

{

klac cob; // створення об’єкта сob типу klac

cout<<"\n"<<cob.kwadrat(3)<<"\n"; //використання функції kwadrat()

return 0;

}

У цій програмі застосовується файл iostream.h, в якому знаходяться операції потокового вводу – cin та виводу – cout. Вони призначені для потокового вводу-виводу даних, тому працюють швидше, ніж відомі функції, такі, наприклад, як scanf() і printf(). Нижче, після цієї директиви оголошено клас klaс, який має два члени: закрита змінна a та відкрита функція kwadrat() – обидва цілого типу. За цим оголошенням слідує визначення функції kwadrat(), яка має один вхідний параметр – змінну b цілого типу. В тілі функції змінній a, закритій для інших, але доступній для функції kwadrat(), присвоюється значення квадрату вхідного параметра. Результат виконання функції повертається в ту програму, яка її викликає (в даному випадку – в головну, main).

Наприкінці прикладу подано сам текст програми main. На її початку оголошено об’єкт cob типу klac та відбувається звернення до функції kwadrat() з параметром 3.

Під час виконання головної програми буде створено об’єкт cob типу klac, після чого виконається операція cout, яка містить звернення до функції kwadrat() та буде виведено на екран результат її виконання – число 9. Звернемо увагу на те, що при зверненні до функції kwadrat() в головній програмі вказано ім’я об’єкта cob, яке відділяється від імені функції символом крапка. Однак, при зверненні до змінної a всередині функції kwadrat() не вживається ні ім’я об’єкта, ні крапка.

5.2 Конструктори і деструктори

Мова С++ надає можливість використовувати дві спеціальні функції: конструктор та деструктор. Вони включається в опис класу і мають те ж ім’я, що й клас, лише перед описом деструктора ставиться значок ~ (тільда). Ці функції виконуються автоматично і не повертають ніякого значення. Конструктор виконується під час створення об’єкта, а деструктор – при закінченні головної програми. Їх, зокрема, можна використати, першу – для ініціалізації змінних, другу – для вилучення об’єкта з пам’яті.

Конструктор показаний у прикладі 5.2.

Приклад 5.2 – Застосування конструктора

# include <iostream.h>

// Оголошення класу klac

class klac

{

int a;

public:

klac(); // Конструктор

void kwadrat();

};

// Ініціалізація а = 3 конструктором при створенні об'єкта cob

klac::klac()

{

a = 3;

}

// Функція kwadrat(), піднесення числа a до квадрату і виводу результату

void klac::kwadrat()

{

cout << a*a;

return;

}

int main(void) // Головна програма

{

klac cob; // Створення об'єкта cob

cob.kwadrat(); // Виклик функції kwadrat()

return 0;

}

Як видно з цього прикладу, конструктор викликається при створенні об’єкта cob.

Функція деструктор може виконувати будь-яку роботу. Крім того, вона застосовується для вилучення об’єкта, створеного тим класом, де вона описана. Тоді звільняються зайняті ним ресурси: пам’ять та ін. Вона теж включається в оголошення класу, в програмі прикладу 5.3 показано її застосування.

Приклад 5.3 – Застосування деструктора

# include <iostream.h>

// Оголошення класу klac:

class klac

{

int a;

public:

klac(void); // Конструктор

~klac(void); // Деструктор

void kwadrat(void);

};

// Визначення конструктора:

klac::klac(void)

{

a = 3; // Ініціалізація змінної a

}

// Визначення деструктора:

klac::~klac(void)

{

cout << "Звільнення ресурсів\n";

}

// Визначення функції kwadrat():

void klac::kwadrat(void)

{

cout << a*a << "\n"; // Піднесення до квадрату і вивід

return;

}

int main(void) // Головна програма:

{

klac cob; // Створення об'єкта cob

cob.kwadrat(); // Виклик функції kwadrat()

return 0;

}

Тут деструктор викликається для вилучення об’єкта cob при закінченні виконання програми.

5.3 Конструктор з параметрами

Конструктору можна передати параметри. Для цього потрібно додати необхідні параметри в оголошення і визначення конструктора. Потім під час оголошення об’єкта параметри задаються як аргументи. Це показано в прикладі 5.4

Приклад 5.4 – Конструктор з параметрами

# include <iostream.h>

class myclass

{

int a;

public:

myclass(int x); // конструктор

void show();

};

myclass::myclass(int x)

{

cout << "У конструкторі\n";

a = x;

}

void myclass::show()

{

cout << a << "\n";

return;

}

int main(void)

{

myclass ob(4);

ob.show();

return 0;

}

Тут конструктор myclass() має один параметр. Значення, передане в myclass() використовується для ініціалізації змінної а. Аргумент 4 передається об’єкту ob(4) в якості аргумента. Деструктор, на відміну від конструктора, параметрів не має.

У цій програмі конструктору передавалися константи, але так само можна передавати й змінні. Це показано в прикладі 5.5.

Приклад 5.5 – Передача параметрів конструктору

# include <iostream.h>

class myclass

{

int i, j;

public:

myclass(int a, int b);

void show();

};

myclass::myclass(int a, int b)

{

i = a;

j = b;

}

void myclass::show()

{

cout << i << ' ' << j << "\n";

}

void main(void)

{

int x, y;

cout << "Введіть два цілі числа: ";

cin >> x >> y;

// використання змінних для створення ob

myclass ob(x, y);

ob.show();

return 0;

}

У цьому прикладі розкрита важлива властивість об’єктів: вони можуть створюватися в міру необхідності.

5.4 Спадкування

Спадкування – це механізм, за допомогою якого один клас (похідний) може успадковувати властивості іншого (базового). Базовий клас визначає всі властивості, які є загальними для всіх похідних. Утворення похідного класу показано в прикладі 5.6.

Приклад 5.6 – Демонстрація похідного класу

//Базовий клас

class B

{

int i;

public:

void set_i(int n);

int get_i();

};

//Похідний клас D

class D: public B

{

int j;

public:

void set_j(int n);

int mul();

};

Після імені класу D стоїть двокрапка, за якою є ключове слово public та ім’я класу B. Це означає, що клас D буде успадковувати всі компоненти класу B. Саме ключове слово public інформує компілятор про те, що, оскільки B буде успадковуватися, то всі відкриті елементи базового класу будуть відкритими елементами похідного класу. Проте всі закриті елементи базового класу залишаються закритими. Механізм спадкування подано в прикладі 5.7.

Приклад 5.7 – Спадкування

// Приклад спадкування

# include <iostream.h>

// Визначення базового класу

class base

{

int i;

public:

void set_i(int n);

int get_i();

};

// Визначення похідного класу

class derived: public base

{

int j;

public:

void set_j(int n);

int mul();

};

// Визначення i у базовому класі

void base::set_i(int n)

{

i = n;

}

// Повернення значення i у базовому класі

int base::get_i()

{

return i;

}

// Визначення j у похідному класі

void derived::set_j(int n)

{

j = n;

}

// Повернення значення i із base та j – із derived

int derived::mul()

{

// похідний клас може викликати функції-члени базового класу

return j * get_i();

}

int main(void)

{

derived ob;

ob.set_i(10); // завантаження i у base

ob.set_j(4); // завантаження j у derived

cout << ob.mul(; // вивід числа 40

return 0;

}

У визначенні mul() викликається функція get_i() базового класу B, а не похідного D, це означає, що відкриті члени базового класу стають відкритими членами похідного. Але у функції mul() замість прямого доступу до i необхідно викликати get_i() тому, що закриті члени базового класу (змінна i) залишаються закритими для похідних класів.

5.5 Віртуальні функції

Функція похідного класу може мати таку ж назву, як і функція базового класу. Розглянемо варіант виклику такої функції, він поданий у прикладі 5.7.

Приклад 5.7 – Віртуальні функції

# include <stdio.h>

class base

{

public:

int i;

base(int x); // конструктор

void func(void)

{

printf("Базова функція %d", i);

return;

}

};

//текст конструктора

base::base(int x)

{

i = x;

return;

};

class der1: public base

{

public:

der1(int x):base(x) { }; //конструктор

void func()

{

printf("Функція з похідного класу %d", i*i);

return;

}

};

int main(void)

{

base * pc; // вказівник на базовий клас

base ob(2); // створити примірник об'єкта базового класу

der1 ob1(2); // створити примірник об'єкта похідного класу

pc=&ob; // вказівник на об'єкт базового класу

pc->func(); // виклик функції базового класу

pc=&ob1; // вказівник на об'єкт похідного класу

pc->func(); // спроба виклику функції похідного класу

return 0;

}

На перший погляд здається, що в першому випадку буде викликатися функція базового класу, а в другому – похідного. Проте, і у тому, і в іншому випадку буде викликана функція базового класу. Справа в тому, що компілятору важко визначити яку реально функцію ми маємо на увазі і він на стадії компілювання підставляє у всіх тих випадках, де зустрічається ім’я func(), адресу функції базового класу. Такий процес установки адрес називається “раннім зв’язуванням”. Іноді вживається термін “статичне зв’язування”. Якщо ж потрібно, щоб у другому випадку, тобто коли покажчик pc указує на похідний клас, викликалася функція цього класу, її ще в базовому класі варто зазначити як віртуальну. У нашому випадку замість рядка void func() варто написати virtual void func(). Після цього програма прикладу буде працювати задовільно.

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

У випадку використання віртуальних функцій адреса функції, що викликається, буде визначена в процесі виконання коду програми. Такий процес називається “пізнім зв’язуванням”, вживається також термін “динамічне зв’язування”.

Для подальшого з’ясування властивостей віртуальних функцій розглянемо ще один приклад, який є розвитком першого. Це приклад 5.8.

Приклад 5.8 – Властивості віртуальних функцій

# include <stdio.h>

class base

{

public:

int i;

base(int x); //конструктор

virtual void func()

{

printf("Базова функція %d\n", i);

return;

};

};

//текст конструктора

base::base(int x)

{

i = x;

return;

};

class der1: public base

{

public:

der1(int x):base(x) { }; //конструктор

void func()

{

printf("Функція з похідного класу %d\n", i*i);

return;

}

};

class der2: public base {

public:

der2(int x):base(x) { }; //конструктор

};

int main(void)

{

base * pc; // вказівник на базовий клас

base ob(2); // створити примірник об'єкта базового класу

der1 ob1(2); // створити примірник об'єкта похідного класу 1

der2 ob2(2); // створити примірник об'єкта похідного класу 2

pc=&ob; // вказівник на об'єкт базового класу

pc->func(); // виклик функції базового класу

pc=&ob1; // вказівник на об'єкт похідного класу 1

pc->func(); // спроба виклику функції похідного класу

pc=&ob2; // вказівник на об'єкт похідного класу 2

pc->func(); // спроба виклику функції похідного класу

return 0;

}

Тут введено ще один похідний клас. У ньому функція func() не визначена. У цьому випадку буде викликатися функція класу батька, тобто з’явиться рядок: Базова функція 2. Якщо потрібно, щоб викликалася функція батьківського класу, не слід визначати її в похідному. А, якщо потрібно, щоб для класу об’єктів der2 викликалася функція класу der1, треба зробити клас der2 спадкоємцем не класу base, а класу der1.

Отже, якщо потрібно, щоб у всіх похідних класах обов’язково була визначена віртуальна функція, то в базовому класі її треба визначити так:

virtual void func() = 0;

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

5.6 Перевантаження функцій

Дві або більше функцій, які мають одне й те ж ім’я, називаються перевантаженими. Зазвичайно такі функції відрізняються кількістю і типом аргументів. Під час звернення до цих функцій компілятор автоматично вибере одну з них на підставі кількості або типів параметрів. Перевантаження функцій показано в прикладі 5.9.

Приклад 5.9 – Перевантаження функцій

# include <iostream.h>

void k(int a); // прототип першої функції

void k(int a, float b); // прототип другої функції

void k(int a) // опис першої функції

{

cout << a <<"\n";

}

void k(int a, float b) // опис другої функції

{

cout <<a<<"\n"<< b <<"\n";

}

int main(void)

{

k(4); // виклик першої функції

k(5, 10.2); // виклик другої функції

return 0;

}

Тут головна програма двічі викликає функцію k(), але з різною кількістю параметрів, тому виконуватися будуть різні функції.

5.7 Вказівники на об’єкти

Доступ до члена об’єкта можливий не тільки через точку (.), але й через вказівник на об’єкт. У цьому випадку застосовують стрілку (мінус-більше: ->), що показано в прикладі 5.10.

Приклад 5.10 – Використання вказівника на об’єкт

# include <iostream.h>

class myclass

{

int a;

public:

myclass(int x); // конструктор

int get();

};

myclass::myclass(int x)

{

a = x;

}

int myclass::get()

{

return a;

}

int main(void)

{

myclass ob(120); // створення об'єкта

myclass *p; // створення покажчика на об'єкт

p = &ob; // передача адреси ob у p

cout << "Значення, одержуване при використанні об'єкта:" << ob.get();

cout << "\n";

cout << "Значення, одержуване при використанні покажчика:" << p->get();

return 0;

}

У цій програмі оголошення myclass *p створює вказівник на об’єкт myclass (але – не сам об’єкт). Передача адреси об’єкта ob змінній p відбувається у виразі p = &ob. Для одержання доступу до об’єкта через вказівник p використовується вираз:

p->get().

6 ВАРІАНТИ ЗАВДАНЬ ДЛЯ ВИКОНАННЯ ПРАКТИЧНИХ РОБІТ

Варіант 1. Екологiчний стан атмосферного повiтря за даними газохроматографiчного аналiзу

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.1 додатка А. Вона містить такі дані про екологiчний стан атмосферного повiтря за даними газохроматографiчного аналiзу:

1 – назва області України;

2 – назва населеного пункту;

3 – геоморфологічна прив’язка місця відбору проби;

4 – дата відбору проби;

5 – вміст вуглекислого газу, мг/м3;

6 – вміст СО, мг/м3;

7 – вміст SO2, мг/м3;

8 – вміст бензину, мг/м3;

9 – вміст HCl, мг/м3.

Рекомендації до створення структур:

1 – Області: код області, назва області;

2 – Населені пункти: код населеного пункту, код області, назва населеного пункту, геоморфологічна прив’язка місця відбору проби;

3 – Дані відбору проб: код населеного пункту, дата відбору проби, вміст вуглекислого газу, вміст СО, вміст SO2, вміст бензину, вміст HCl;

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про розподіл максимальних значень вмісту SO2 у атмосферному повітрі кожного населеного пункту по кварталах поточного року. Навпроти назв областей і населених пунктів установити максимальні значення вмісту речовини за кожний квартал. Передбачити вивід підсумкових максимальних значень по вертикалі для областей і по горизонталі. До заголовка звіту додати слова “станом на” і встановити поточну дату.

Задача 5. Виготовити звіт у якому відобразити усереднений вміст речовин у атмосферному повітрі кожного населеного пункту протягом поточного року. У звіт внести назви областей, населених пунктів та геоморфологічну прив’язку місця відбору проб. Підвести підсумки (середні значення) для кожної області. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 2. Реалізація продукції хлібозаводу

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.2 додатка А. Вона містить такі дані про реалізацію продукції хлібозаводу:

1 – назва виробу;

2 – постачальник сировини;

3 – дата реалізації виробу;

4 – торгова точка;

5 – кількість, шт;

6 – ціна за одну булку, грн;

7 – наявність п’ятивідсоткової націнки за поставку.

Рекомендації до створення структур:

1 – Хлібовироби: код виробу, назва виробу, ціна за одиницю виробу;

2 – Постачальник: код постачальника, назва постачальника сировини;

3 – Торгова точка: код торгової точки, назва торгової точки, наявність п’ятивідсоткової націнки за поставку;

4 – Збут: код виробу, код постачальника, код торгової точки, кількість, дата.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про розподіл виручки за проданий товар у поточному році по постачальниках сировини. Навпроти назв товарів установити значення виручки для кожного постачальника. Передбачити підсумки по вертикалі і по горизонталі. Виручка дорівнює ціні, помноженій на кількість товару, плюс п’ятивідсоткова націнка, якщо вона є.

Задача 5. Виготовити звіт, вказати назви виробів, назви торгових точок та сумарну кількість кожного проданого товару в поточному році в тих торгових точках, де відсутня торгова націнка. До заголовка звіту додати слова “станом на” і встановити поточну дату. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 3. Нафтогазоносні родовища України

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.3 додатка А. Вона містить такі дані про нафтогазоносні родовища України:

1 – назва регіону;

2 – назва області України;

3 – назва родовища;

4 – місце розташування родовища;

5 – тип родовища;

6 – розміри за покладами нафти;

7 – розміри за покладами газу;

8 – рік відкриття;

9 – рік введення в розробку.

Рекомендації до створення структур:

1 – Регіон: код регіону, назва регіону;

2 – Область: код регіону, код області, назва області України;

3 – Родовище: код області України, код родовища, назва родовища, місце розташування родовища, код типу родовища, код розміру за покладами нафти, код розміру за покладами газу, рік відкриття, рік введення в розробку;

4 – Тип родовища: код типу родовища, тип родовища;

5 – Розміри родовища: код розміру родовища, розміри родовища.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про розподіл кількості родовищ в областях за типом родовища. Навпроти назв регіонів і областей, розділених комами, установити значення кількості для кожного типу родовища. Передбачити підсумки по вертикалі і по горизонталі. До заголовка звіту додати слова “станом на” і встановити поточну дату.

Задача 5. Виготовити звіт з відомостями про родовища, куди внести назви регіонів, назви родовищ та різницю в роках між моментом відкриття і введення в розробку. Відібрати лише нафтогазові родовища. До заголовка звіту додати слова “станом на” і встановити поточну дату. Підсумувати різницю в роках для регіонів і для всього звіту. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 4. Запаси нафти у родовищах України

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.4 додатка А. Вона містить такі дані про запаси нафтопродуктів у родовищах України:

1 – назва регіону;

2 – назва області України;

3 – назва родовища;

4 – місце розташування родовища;

5 – розміри за покладами нафти;

6 – розміри за вмістом газу;

7 – рік відкриття;

8 – рік введення в розробку.

Рекомендації до створення структур:

1 – Регіон: код регіону, назва регіону;

2 – Область: код регіону, код області, назва області України;

3 – Родовище: код родовища, код області України, назва родовища, місце розташування родовища, код розміру за покладами нафти, код розміру за покладами газу, рік відкриття, рік введення в розробку;

4 – Розміри родовища: код розміру родовища, розміри родовища.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про розподіл кількості родовищ за розмірами за покладами нафти по областях. Навпроти назв областей установити значення кількості родовищ для кожного розміру за покладами нафти. Передбачити підсумки по вертикалі і по горизонталі.

Задача 5. Виготовити звіт, куди внести назви регіонів і родовищ, відкритих протягом останніх 10 років, рік відкриття та розміри за покладами нафти. Відібрати лише великі та середні родовища за покладами нафти. До заголовка звіту додати слова “станом на” і встановити поточну дату. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 5. Газосховища України

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.5 додатка А. Вона містить такі дані про газосховища України:

1 – назва комплексу;

2 – назва газового сховища;

3 – об’єм газового сховища, млн м3;

4 – кількість свердловин;

5 – добова продуктивність свердловин;

6 – кількість запомпованого газу, млн. м3;

7 – кількість вибраного газу, млн. м3;

8 – дата занесення даних.

Рекомендації до створення структур:

1 – Комплекс: код комплексу, назва комплексу;

2 – Сховище: код комплексу, код газового сховища, назва газового сховища, об’єм газового сховища, кількість свердловин, добова продуктивність свердловин;

3 – Рух газу: код газового сховища, кількість запомпованого газу, кількість вибраного газу, дата занесення даних.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про розподіл кількості вибраного газу подекадно для поточного місяця. Навпроти назв комплексів і сховищ, розділених пробілом, установити значення кількості за кожну декаду. Передбачити підсумки по вертикалі і по горизонталі.

Задача 5. Виготовити звіт для взятого з форми комплексу про кількість запомпованого газу для кожного сховища на поточну дату. До заголовка звіту додати слова “станом на” і покласти поточну дату. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 6. Нафтобази України

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.6 додатка А. Вона містить такі дані про нафтобази України:

1 – назва регіону;

2 – назва області;

3 – назва нафтобази;

4 – кількість резервуарів;

5 – сумарний об’єм резервуарів, м3;

6 – кількість нафтопродукту, тис. тон;

7 – дата обліку.

Рекомендації до створення структур:

1 – Регіон: код регіону, назва регіону;

2 – Область: код регіону, код області, назва області;

3 – Нафтобаза: код області, код нафтобази, назва нафтобази, кількість резервуарів, об’єм резервуарів;

4 – Нафтопродукти: код нафтобази, кількість нафтопродукту, дата обліку.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

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

Задача 5. Виготовити звіт для введеного під час виконання програми регіону про поточний вміст нафтопродуктів. До його заголовка додати слова “станом на” і встановити поточну дату. Врахувати, що дані в базу поступають нерегулярно, тому в звіт необхідно внести останні дані. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 7. Транспортування газу по території України

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.7 додатка А. Вона містить такі дані про транспортування газу по території України:

1 – назва газопроводу;

2 – кількість ниток газопроводу;

3 – діаметр однієї нитки, мм;

4 – назва підприємства, яке експлуатує газопровід;

5 – добова кількість запомпованого газу, м3;

6 – дата представлення даних;

Рекомендації до створення структур:

1 – Підприємство: код підприємства, назва підприємства, яке експлуатує газопроводи, логотип підприємства;

2 – Газопровід: код газопроводу, назва газопроводу, кількість ниток газопроводу, діаметр однієї нитки;

3 – Облік газу: код газопроводу, код підприємства, поточна кількість перепомпованого газу за добу, м3, дата представлення даних.

Задача 2. Підготувати і занести в структури контрольні дані.

Задача 3. Створити зв’язані списки із масивів структур.

Задача 4. Виготовити звіт про сумарний об’єм транспортованого газу за поточний рік по кожному газопроводу для підприємства, показаного на відкритій для перегляду формі. До заголовка звіту додати назву газопроводу, слова “станом на” і встановити поточну дату.

Задача 5. Виготовити звіт про розподіл кількості транспортованого газу на кожному підприємстві по газопроводах у поточному році. Навпроти назв підприємств установити значення кількості для кожного газопроводу. Передбачити підсумки по вертикалі і по горизонталі. Завдання виконати у двох варіантах: використати масиви структур та зв’язані списки.

Задача 6. Скласти програму мовою С для сортування зв’язаних списків.

Задача 7. Виготовити два індекси, один для числових даних, другий – для літерних. Дані вибрати самостійно.

Задача 8. Скласти програму для пошуку даних за допомогою індексів. Зразки даних для пошуку підібрати самостійно.

Варіант 8. Забезпеченість України паливно-мастильними

матеріалами

Задача 1. Утворити масиви структур на основі інформації, зразки якої подані в таблиці А.8 додатка А. Вона містить такі дані про забезпеченість паливно-мастильними матеріалами:

1 – назва регіону;

2 – назва області;





Дата публикования: 2014-11-18; Прочитано: 909 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.159 с)...