Студопедия
Новини освіти і науки:
МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах


РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання


ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ"


ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ


Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків


Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні


Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах


Гендерна антидискримінаційна експертиза може зробити нас моральними рабами


ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ


ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів



Контакти
 


Тлумачний словник
Авто
Автоматизація
Архітектура
Астрономія
Аудит
Біологія
Будівництво
Бухгалтерія
Винахідництво
Виробництво
Військова справа
Генетика
Географія
Геологія
Господарство
Держава
Дім
Екологія
Економетрика
Економіка
Електроніка
Журналістика та ЗМІ
Зв'язок
Іноземні мови
Інформатика
Історія
Комп'ютери
Креслення
Кулінарія
Культура
Лексикологія
Література
Логіка
Маркетинг
Математика
Машинобудування
Медицина
Менеджмент
Метали і Зварювання
Механіка
Мистецтво
Музика
Населення
Освіта
Охорона безпеки життя
Охорона Праці
Педагогіка
Політика
Право
Програмування
Промисловість
Психологія
Радіо
Регилия
Соціологія
Спорт
Стандартизація
Технології
Торгівля
Туризм
Фізика
Фізіологія
Філософія
Фінанси
Хімія
Юриспунденкция






Перерахований та обмежений типи

Begin

End.

Begin

Begin

Begin

Begin

Begin

Begin

Repeat

Begin

Begin

Else

End

Begin

Begin

writeln;

write('Введіть коефіцієнти a,b,c квадратного рівняння : ');

readln(a,b,c);

d:=sqr(b)-4*a*c;

if d>=0 then

if d=0 then writeln('Єдиний корінь: x=',-b/(2*a):8:3)

else writeln('Два корені : x1=',(-b+sqrt(d))/(2*a):8:3,, x2=',(-b-sqrt(d))/(2*a):8:3)

else {d<0} writeln('Корнів немає');

readln;

end.

Щоб не заплутатися в структурі цієї програми, варто пам'ятати таке правило: else завжди відноситься до останнього оператора if.Якщо ж у програмі потрібно, щоб else відносилося до одного з попередніх if, то прийдеться скористатися складеним оператором:

Приклад 5: користувач вводить натуральне число, задача програми — поставити слово «учень» у потрібну форму в сполученні з числівником (наприклад: 1 учень, 3 учня, 9 учнів і т.п.)

write('Число учнів (1..20) --> '); readln(n);

write(n,' учень');

if n<5 then begin

if n>1 then writeln('а');

writeln('ів');

readln;

end.

У цьому прикладі довелося використовувати складений оператор (begin ... end;) для того щоб частина else відносилася не до оператора if n>1, а до if n<5.

2. Оператор вибору (case)

Крім оператора умовного переходу і циклів у Турбо Паскалі мається ще одна керуюча конструкція, одна з назв якої — оператор вибору. Насправді це ускладнений оператор if, він дозволяє програмі виконуватися не двома способами, у залежності від виконання умови, а декількома, у залежності від значення деякого виразу. У загальному виді цей оператор виглядає так:

case Вираз of

Варіант1: Оператор1;

Варіант2: Оператор2;

...

Варіант: Оператор;

[else Операторl;]

end;

(Пояснення: квадратні дужки означають те, що частина else може бути відсутньою).

Вираз в найпростіших випадках може бути цілочисельним чи символьним. Як варіанти можна застосовувати:

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

2. Інтервал, наприклад: 1..5, 'а'..'z'.

3. Список значень або інтервалів, наприклад: 1,3,5..8,10,12.

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

Розглянемо приклад. Нехай користувач вводить ціле число від 1 до 10, програма повинна приписати до нього слово «учень» з необхідним закінченням (нульове, «я» або «ів»).

 

program SchoolChildren;

var n: integer;

write('Число учнів --> '); readln(n);

write(n);

case n of

2..4: write('я');

5..10: write('ів');

else write (' учень');

end;

readln;

end.

 

Можна також удосконалити програму для довільного натурального n:

 

write(n);

case n mod 100 of

11..19: write('iв');

else case n mod 10 of

2..4: write('я');

0,5..9: write('ов');

else write (' учень');

end;

end;

Оператори циклів у Паскалі

У реальних задачах часто потрібно виконувати ті самі оператори кілька разів. Можливі різні варіанти: виконувати фрагмент програми фіксоване число раз, виконувати, поки виконується деяка умова , і т.п. У зв'язку з наявністю варіантів у Паскалі існує 3 типи циклів.

1. Цикл із післяумовою (Repeat)

На Паскалі записується так:

repeat <оператор> until <умова>.

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

Приклад (підрахунок суми натуральних чисел від 1 до 100):

var i,sum: integer;

sum:=0; i:=0;

i:=i+1;

sum:=sum+i;

until i=100;

writeln('Сума дорівнює: ',sum);

readln;

end.

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

2. Цикл із предумовою (While)

Цей цикл записується так:

while <умову> do <оператор>.

(Поки умова істинна, виконувати оператор). Суть у наступному: поки умова істинна, виконується оператор (у цьому випадку оператор може не виконатися жодного разу, тому що умова перевіряється до виконання). Під оператором тут розуміється або простий, або складений оператор (тобто декілька операторів, обмежених begin ... end).

Розглянемо той же приклад, виконаний за допомогою while:

var i,sum: integer;

sum:=0; i:=0;

while i<100 do begin

i:=i+1;

sum:=sum+i;

end;

writeln('Сума дорівнює: ',sum);

readln;

end.

3. Цикл із лічильником або параметром (For)

Записується так:

for <змінна>:=<поч> to <кін> do <оператор>. Замість to можливе слово downto. Розглянемо такий приклад: потрібно вивести на екран таблицю квадратів натуральних чисел від 2 до 20.

var i: integer;

for i:=2 to 20 do

writeln(i,' ',sqr(i));

end.

При виконанні циклу відбувається наступне: зміннй i присвоюється початкове значення (2), потім виконується оператор (простий чи складовий), після цього до i додається 1, і перевіряється, чи не стало значення і рівним кінцевому (20). Якщо ні, то знову виконується оператор, додається 1, і т.д. У випадку, коли замість to використовується downto, усе відбувається навпаки: одиниця не додається, а віднімається. Наприклад, цикл, що виведе ту ж таблицю, але в зворотному порядку:

for i:=20 downto 2 do

writeln(i,' ',sqr(i));

У завершення запишемо програму про підрахунок суми чисел від 1 до 100 за допомогою for:

var i, sum: integer;

sum:=0;

for i:=1 to 100 do

sum:=sum+i;

writeln(sum);

end.


Концепція типів даних. Типи даних в мові Pascal

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

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

 
 

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

На основі стандартних скалярних типів мається можливість утворювати скалярні типи користувача. Є два способи створення нових скалярних типів - обмежені і перераховані типи.

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


Цілий тип.

Ця група типів позначає множину цілих чисел у різних діапазонах. Мається п'ять цілих типів, що розрізняються припустимим діапазоном значень і розміром займаної оперативної пам'яті. Цілі типи позначаються ідентифікаторами Integer, Byte, Shortint, Word, Longint; їх характеристики наведені в наступній таблиці.

Цілий тип Діапазон значень Розмір пам’яті
Shorting -128…127 1 байт
Integer -32768…32767 2 байта
Longint -2147483648…2147483647 4 байта
Byte 0…255 1 байт
Word 0…65535 2 байта

Значення цілих типів можуть зображуватися в програмі двома способами: у десятковому виді (традиційно, у виді послідовності цифр) і в шестнадцятовому виді. В останньому випадку цифри старше 9 позначаються латинськими буквами від А до F, а на початку ставиться символ '$' (знак долара). Максимально припустимий діапазон зображень десяткового числа є — -2147483648…2147483647

Над цілими значеннями припустимі наступні операції:

чотири арифметичних дії, що мають звичний зміст. Ці дії позначаються символами:

+ додавання

- віднімання

* множення

/ ділення

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

Div — ділення на ціло

Mod — узяття залишку від цілочисельного ділення.

При застосуванні до цілих значень усі перераховані операції (крім ділення) дають цілий результат. Операція ділення завжди дає дійсний результат.

Для цілих визначені дві вбудовані функції abs і sqr.

Опис змінних цілого типу на Паскалі має такий вигляд:

Var a,b,c,:(integer)


Дійсні типи

Ця група типів позначає множину дійсних значень у різних діапазонах. Turbo Pascal підтримує чотири різних дійсних типи. Вони іменуються ідентифікаторами Real, Single, Double, Extended і Соmр і мають наступні характеристики:

Дійсний тип Діапазон значень Число цифр мантиси Розмір пам’яті
Real 2.9е-39 ..1.7e38 11-12 6 байт
Single 1.5e-45 .. 3.4e38 7-8 4 байт
Double 5.0e-324 .. 1.7e308 15-16 8 байт
Extende 3.4e-4932 ..1.1e493 19-20 10 байт
Comp -2e+63 ..+2e+63-1   8 байт

ЗАУВАЖЕННЯ:

1. Хоча тип Comp вважається дійсним типом, він містить тільки цілі числа з дуже значного діапазону, що представляються в обчисленнях як дійсні (з нульовою мантисою).

2. Усі дійсні типи, крім real, можуть використовуватися в програмі, узагалі говорячи, тільки якщо в конфігурації персонального комп'ютера мається математичний співпроцесор Intel 8087/80287. Для коректної компіляції програми, що використовує ці типи, необхідно установити директиву компілятора {$N+}. Крім того, можна залучити засоби програмної емуляції апаратних операцій з дісними типами, установивши директиву {$E+}. Якщо ця остання директива встановлена, то програма буде виконуватися правильно незалежно від наявності математичного співпроцесора, хоча її об'єктний код буде трохи великим по розміру.

Дійсні значення можуть зображуватися у формі з фіксованою точкою й у формі з плаваючою точкою. У першому випадку ціла і дробова частини дійсного числа відокремлюються символом '.' (крапка). Обидві ці частини повинні обов'язково бути присутнім, наприклад:

17.384

0.5

Наступні приклади демонструють неправильні форми запису чисел:

.3 (правильно 0.3)

10. (правильно 10.0)

Дійсне число у формі з плаваючою крапкою записується як пара виду

<мантиса> E <порядок>

Таке позначення розуміється як "мантиса, помножена на 10 у степені, рівному порядку". Наприклад, 7E-2 означає 7 ´ l0-2,- 12.25E+6 або 12.25E6 позначають 12.25 ´ l06. Мантиса представляється у виді цілого числа або як дійсне з фіксованою точкою; порядок позначається цілим числом; допускаються як додатні, так і від’ємні значення порядку.


Бульовий (логічний) тип

Мається два значення бульового типу, що представляють логічні значення (істина/хиба). Ці значення позначаються за допомогою стандартних ідентифікаторів

true (істина)

false (хиба)

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

false < true

Описуються в програмі так:

var v1,v2, … vn: boolean;

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

and логічне множення

orлогічне додавання

xor додавання по модулі 2 (виключаюче або )

not логічне заперечення (унарная операція)

Ці операції мають звичайний в логіці зміст.

Значення булевского типу займають один байт пам'яті.

Приклад: написати програму виведення на екран таблиі істинності для операції and.

program logik;

uses crt;

var a,b,c:boolean;

clrscr;

for a:=false to true do

for b:=false to true do

c:=a and b;

writeln(a,' and ',b,'=',c)

end;

end.


Символьні і рядкові змінні

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

1. Символьний тип

Тип даних, змінні якого зберігають рівно один символ (букву, цифру, розділовий знак і т.п.) називається символьним, а в Паскалі — char. Оголосити змінну такого типу можна так:

var ch: char;

Для того щоб записати в цю змінну символ, потрібно використовувати оператор присвоювання, а символ записувати в апострофах, наприклад: ch:='R';. Для символьних змінних можливо також використання процедури readln, наприклад:

write(‘Вийти з гри? (Так/Ні)’); readln(ch);

if ch=’Т’ then ...{виходити}...

else ...{продовжувати}...;

Символьні змінні в пам'яті комп'ютера зберігаються у виді числових кодів, інакше кажучи, у кожного символу є порядковий номер. Наприклад, код пробілу дорівнює 32, код ‘A’ — 65, ‘B’ — 66, ‘C’ — 67, код символу ‘1’ — 48, ‘2’ — 49, ‘.’ — 46 і т.п. Деякі символи (з кодами, меншими 32) є керуючими, при виведенні таких символів на екран відбувається якась дія, наприклад, символ з кодом 10 переносить курсор на новий рядок, з кодом 7 — викликає звуковий сигнал, з кодом 8 — зміщує курсор на одну позицію вліво. Під збереження символу виділяється 1 байт (байт складається з 8 біт, а біт може приймати значення 0 чи 1), тому усього можна закодувати 28=256 різних символів. Кодування символів, що використовується Турбо-Паскалі, називається ASCII (American Standard Code for Information Interchange — американський стандартний код для обміну інформацією).

Для того щоб одержати в програмі код символу потрібно використовувати функцію chr, наприклад:

var i: byte; {число, що займає 1 байт, значення — від 0 до 255}

ch: char;

...

readln(i); writeln('символ з кодом ',i,' — це ',chr(i));

Якщо як код використовується конкретне число, а не вираз і не змінну, то можна використовувати символ «#», скажемо так: ch:=#7;. Для переходу від коду до символу використовується функція ord (від слова ordinal — порядковий). Наявні знання дозволяють нам написати програму, що видає на екран таблицю з кодами символів:

program ASCII;

var ch: char;

for ch:=#32 to #255 do write(ord(ch),'—>',ch,' ');

readln;

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

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

1. succ (від succeedent — наступний), вона видає символ з наступним кодом.

2. pred (від predecessor — попередник), видає символ з попереднім кодом.

Якщо спробувати в програмі одержати succ(#255) чи pred(#0), то виникне помилка. Користаючись цими функціями можна переписати попередню програму і по-іншому:

...

ch:=#32;

while ch<>#255 do begin

write(ord(ch),'—>',ch,' ');

ch:=succ(ch);

end;

...

 

Порівняння символів. Також як і числа, символи можна порівнювати на =, <>, <, >, <=, >=. У цьому випадку Паскаль порівнює не самі символи, а їхні коди. Таблиця ASCII складена таким чином, що коди букв (латинських і більшості національних) зростають при русі за алфавітом, а коди цифр розташовані один за одним: ord(‘0’)=48, ord(‘1’)=49, ... ord(‘9’)=57. Порівняння символів можна використовувати скрізь, де вимагаються логічні вирази: в операторі if, у циклах і т.п.

2. Рядковий тип

Для збереження рядків (тобто послідовностей із символів) у Турбо-Паскалі мається тип string. Значеннями рядкових змінних можуть бути послідовності різної довжини (від нуля і більше, довжині 0 відповідає порожній рядок). Оголосити рядкову змінну можна двома способами:

або var s: string; (максимальна довжина рядка — 255 символів),

або var s: string[n]; (максимальна довжина — n символів, n — константа чи конкретне число).

Для того щоб записати значення в рядкову змінну використовуються ті ж прийоми, що і при роботі із символами. У випадку присвоювання конкретного рядка, це рядок повинний записуватися в апострофах (s:='Hello, world!'). Приведемо найпростіший приклад з рядками: програма запитує ім'я в користувача, а потім вітає його:

program Hello;

var s: string;

write('Як Вас кличуть: ');

readln(s);

write('Привіт, ',s,'!');

readln;

end.

 

Збереження рядків. У пам'яті комп'ютера рядок зберігається у виді послідовності із символьних змінних, у них немає індивідуальних імен, але є номера, що починаються з 1). Перед першим символом рядка мається ще і нульовий, у якому зберігається символ з кодом, рівним довжині рядка. Нам абсолютно байдуже, які символи зберігаються в байтах, що знаходяться за межами кінця рядка. Розглянемо приклад. Нехай рядок s оголошений як string[9], тоді після присвоювання s:=’Привіт’; вона буде зберігається в наступному виді:

Номер байта
Уміст #6 ‘П’ ‘р' ‘и' ‘в' ‘і' ‘т' ‘ю' ‘s’ ‘%’

Для того щоб у програмі одержати доступ до n-го символу рядка використовується запис s[n]. Якщо поміняти значення s[0] то це відіб'ється на довжині рядка. У наступному прикладі з рядка 'Привіт' ми зробимо 'Привіт!': s[0]:=#7; s[7]:='!';.

Порівняння рядків. Рядки порівнюються послідовно, по символах. Порівнюються перші символи рядків, якщо вони рівні — то другі, і т.д. Якщо на якомусь етапі з'явилося розходження в символах, то меншим буде той рядок, у якого менший символ. Якщо рядки не розрізнялися, а потім один з них закінчився, то він і вважається меншим. Приклади: 'ананас'<'кокос', 'свиня'>'свинина', ''<'A', 'hell'<'hello'.

Склеювання (конкатенація) рядків. До рядків можна застосовувати операцію «+», при цьому результатом буде рядок, що складається з послідовно записаних «складових». Приклад: після дії s:= 'abc'+'def'+'ghi'; перемінна s буде містити ‘abcdefghi’.

Процедури і функції для роботи з рядками.Найбільше часто уживається функція length(s: string): integer (після двокрапки записаний тип значення, що повертається функцією, у нашому випадку — ціле число). Ця функція повертає довжину рядка s.

Інші процедури і функції приведені в таблиці:

Чи процедура функція Призначення Приклад
функція Copy(s: string; start: integer; len: integer): string Повертає вирізку зі строкової змінної s, починаючи із символу з номером start, довжина якої len s:=’Безглуздий’; s1:=Copy(s,4,4); {у s1 стане ‘глузд’}
функція Pos(s1: string; s: string): byte Шукає підрядок s1 у рядку s. Якщо знаходить, то повертає номер символу, з якого починається перше входження s1 у s; якщо s1 не входить у s, то функція повертає 0 n:=pos(‘міністр’, ‘адміністратор’); {=3} n:=pos(‘abc’, ‘stuvwxyz’);{=0}
процедура Insert(s1: string; s: string; start: integer) Вставляє рядок s1 у рядкову змінну s починаючи із символу з номером start. S:=‘кот’; insert(‘мпо’,s,3); {у s стане ‘компот’}
процедура Delete(s: string; start: integer; len: integer) Видаляє зі рядкової змінної s фрагмент, що починається із символу з номером start і довжиною len s:= ‘трикутник’; delete(s,4,6); {у s залишиться ‘три’}

1. Перерахований тип

Припустимо, що нам потрібна земінна для збереження дня тижня. У цьому випадку можна скористатися цілим типом (наприклад byte) і зберігати дні тижня у вигляді чисел 1, 2, ... 7, але це буде не дуже наочно. Турбо Паскаль надає більш зручний варіант, а саме створення перерахованого типу, наприклад, такого:

type Days = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

Після цього можна оголосити змінну цього типу (var day: Days;) і використовувати її. Нижче приведені приклади використання:

day:=Wed;

...

if day>Fri then writeln('Сьогодні вихідний');

...

if day=Mon then writeln('Почався робочий тиждень');

Як ви вже помітили значення перерахованого типу можна порівнювати, при цьому меншим вважається те, що оголошено раніш (лівіше) у визначенні типу.

Для змінних перерахованих типів можливе застосування функцій succ і pred, наприклад, succ(Wed) дає Thu, Pred(Sun) дає Sat. Якщо спробувати написати Pred(Mon) чи Succ(Sun), то вже на етапі перевірки програми компілятором виникне помилка.

Збереження значень перерахованого типу побудоване досить просто: зберігаються цілі числа від 0 до n, у нашому випадку n=6. Існує функція Ord, що дозволяє одержати те число, у виді якого зберігається яке-небудь значення перерахованого типу, наприклад Ord(Wed) дає 2. При необхідності можна одержати значення перерахованого типу по його чисельному представленню, наприклад, Days(1) є Tue. Після всього сказаного можна помітити, що при порівнянні величин перерахованого типу у дійсності порівнюються їхні порядкові номери (Ord).

 

Приклад використання перерахованих типів:

Нехай корабель може рухатися тільки по чотирьох напрямках: на північ, на захід, на південь і на схід, тобто поточний напрямок руху визначається змінною типу Directions = (North, West, South, East);. Цьому кораблю можна подавати накази наступних типів: уперед, назад, уліво, вправо, тобто будь-який наказ задати змінною типу Orders = (Ahead, Back, Left, Right);. Нехай корабель рухався по напрямку d1, після чого йому дали наказ p. Програма повинна визначити, у якому напрямку корабель буде рухатися після виконання наказу.

 

program Ship;

type Courses = (North, West, South, East);

Orders = (Ahead, Back, Left, Right);

var d1, d2: Courses;

p: Orders;

i: integer;

s: string;


Читайте також:

  1. Політична ситуація в Україні дещо відрізнялася під загальноросійської. Тут вплив більшовиків був обмежений.




Переглядів: 1026

<== попередня сторінка | наступна сторінка ==>
Структура програми мови Turbo Pascal | Множинний тип

Не знайшли потрібну інформацію? Скористайтесь пошуком google:

 

© studopedia.com.ua При використанні або копіюванні матеріалів пряме посилання на сайт обов'язкове.


Генерація сторінки за: 0.021 сек.