МІНІСТЕРСТВО ОСВІТИ ТА НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
ОПРАЦЮВАННЯ АГРЕГОВАНИХ ТИПІВ ДАНИХ МОВОЮ С
МЕТОДИЧНІ ВКАЗІВКИ
до лабораторних робіт
з дисципліни
“Проблемно-орієнтовані мови програмування”
для студентів базового напрямку 6.0804 "Комп’ютерні науки"
Затверджено
на засіданні кафедри
програмного забезпечення.
Протокол № 5 від 18 .02 .2004 р.
Львів – 2004
“Опрацювання агрегованих типів даних мовою С”: Методичні вказівки до лабораторних робіт/ Укл.: В.М. Семотюк, Є.В Левус, Т.О. Кототєєва. – Львів: Видавництво Національного університету “Львівська політехніка”, 2004. – 23 с.
Укладачі
Семотюк В.М., канд. тех. наук, доцент каф. програмного забезпечення
Левус Є.В, канд. тех. наук, ст. викладач каф. програмного забезпечення
Коротєєва Т.О., канд. тех. наук, доцент каф. програмного забезпечення
Відповідальний за випуск: Грицик В.В.,
д-р. техн. наук, професор
Рецензенти: Камінський Р.М., канд. ф.-м. наук, доцент кафедри ПЗ
Марцишин Р.С., канд. техн. наук, доцент кафедри АСУ
Лабораторна робота № 1
Тема: засоби мови C для опрацювання символьних рядків
Мета: здобути практичні навики опрацювання текстової інформації з врахуванням особливостей організації символьних рядків у мові С
Теоретичні відомості
Особливим випадком масиву є так званий рядковий літерал - послідовність будь-яких символів, укладених у парні подвійні лапки. У С, на відміну від багатьох інших мов програмування, відсутній спеціальний рядковий тип. Замість цього рядковий літерал у С представляється в пам'яті комп’ютера як масив елементів типу char, наприкінці якого поміщений символ '\0' (нуль-термінатор). Такий масив називають рядком у форматі ASCIIZ або просто ASCIIZ-рядком. Як і з будь-яким масивом символів, із рядковим літералом зв'язаний вказівник-константа на перший елемент масиву.
Адреса першого символу рядкового літерала використовується по-різному, у залежності від того, для чого використовується літерал. Якщо рядковий літерал застосовується для ініціалізації масиву типу char, адреса його першого символу стає синонімом імені масиву.
Якщо літерал використовується для ініціалізації вказівника типу char *, адреса першого символу літерала буде початковим значенням вказівника.
І, нарешті, якщо літерал використовується у виразі в тих місцях, де дозволяється застосовувати вказівник, компілятор підставляє у вираз замість літерала адресу першого його символу.
Важливо пам’ятати, що при виконанні операції присвоювання в комірку пам'яті, відведеній для вказівника, пересилається не масив символів, а тільки вказівник на його початок, тобто адреса першого символу літерала.
Ім'я масиву - це приклад вказівника-константи. Тому помилкою буде спроба використовувати його в деяких операціях адресної арифметики. Наприклад, не можна виконати "пересилку" рядка символів у масив.
Спеціальна опція управляє роботою компілятора з літералами (у IDE це - Main Menu-Options-Code Generation-Merge Duplicated Strings). Якщо опція виключена (-d-для компілятора командного рядка), для кожного рядкового літерала в сегменті даних програми буде створений свій ASCIIZ-рядок.
Якщо опція включена (-d для компілятора командного рядка), компілятор блокує появу цілком ідентичних рядкових літералів у пам'яті. Якщо в тексті програми зустрічається літерал, цілком ідентичний раніше записаному, новий масив не створюється, а використовується посилання на вже наявну копію.
При замовчуванні розглянута опція виключена.
Завдання
Вважаючи, що введене речення з клавіатури складається з довільної кількості слів, між якими є довільна кількість пробілів, і закінчується речення крапкою, виконати один з таких варіантів завдань:
Посортувати всі слова тексту за першою буквою згідно з алфавітом і видрукувати їх у стовпчик.
Надрукувати введене речення трьома способами: а) великими літерами; б) починаючи кожне слово великою літерою; в) великі літери замінити малими, а малі - великими.
У введеному реченні визначити середню довжину слова.
Визначити відсоток вживання у введеному реченні кожної з голосних літер. Результат записати в спадному порядку.
Сформувати нове речення зі слів введеного, в яких немає вказаної користувачем літери.
Ввести два речення. Поміняти місцями передостаннє слово першого речення на перше слово другого речення.
Визначити і надрукувати найкоротше та найдовше слово з введеного речення.
Визначити і надрукувати два найкоротших слова з введеного речення.
Надрукувати ті слова з введеного речення, в яких є подвоєння літер, або вивести повідомлення про їх відсутність.
Вилучити з введеного речення всі слова, які містять задану користувачем комбінацію з двох символів.
Замінити у введеному реченні слово з заданим порядковим номером відповідною кількістю однакових заданих користувачем символів. У випадку, коли номер перевищує введену кількість слів друкувати відповідне повідомлення про реальну кількість слів у введеному реченні.
Ввести речення і ключове слово. Надрукувати всі слова з введеного речення, які не містять літер із заданого ключового слова, або вивести повідомлення про їх відсутність.
Поміняти місцями два слова з введеного речення, порядкові номери яких задає користувач.
Визначити і надрукувати слово з введеного речення, в якому найбільше разів зустрічається задана літера.
Вилучити з введеного речення слово, задане своїм порядковим номером. У випадку, коли номер перевищує введену кількість слів друкувати відповідне повідомлення про реальну кількість слів у введеному реченні.
Порахувати кількість різних букв у введеному реченні.
Надрукувати всі слова з введеного речення, які містять понад 8 літер.
Сформувати колонку зі слів введеного речення, роздрукувавши кожне слово в інверсному порядку (ззаду - наперед).
Сформувати і надрукувати нове речення зі зворотнім до введеного порядком слів.
Надрукувати ті слова з введеного речення, які складаються з усіх різних літер, або вивести повідомлення про їх відсутність.
Порахувати кількість заданих трьох літер у введеному реченні.
Ввести речення і ключове слово. Визначити, чи є у введеному реченні слово, яке складається з тих самих літер, що й задане ключове слово.
Ввести два речення. Визначити і надрукувати літери з обох речень, які не є спільними. Відповідні заголовні та малі літери вважаються однаковими.
Замінити у введеному реченні четверте по порядку слово на задане користувачем. У випадку, коли кількість слів менша чотирьох, друкувати відповідне повідомлення про реальну кількість слів у введеному реченні.
Порахувати кількість приголосних у введеному реченні.
Визначити і надрукувати два найдовших слова з введеного речення.
Сформувати і надрукувати речення, у якому відносно введеного речення попарно поміняні слова своїми місцями.
Ввести два речення. Визначити і надрукувати літери з обох речень, які є спільними. Відповідні заголовні та малі літери вважаються однаковими.
Контрольні запитання
Яка структура символьного рядка у мові С?
Яка особливість символьного рядка у мові С як масиву символів?
Яка роль імені символьного рядка?
Яка роль адреси першого символу символьного рядка?
Чому не можна виконати "пересилку" рядка символів у масив?
Як уникнути повторного відведення місця в пам’яті для однакових символьних рядків?
Лабораторна робота № 2
Тема: організація роботи з багатовимірними масивами даних у мові С
Мета: навчитися організовувати в пам’яті ЕОМ багатовимірні масиви та освоїти основні методи програмування алгоритмів обробки масивів даних засобами мови С
Теоретичні відомості
Мова С підтримує багатовимірні масиви. Розмірність (dimension) масиву - це число індексів, використовуваних для посилання на конкретний елемент масиву. Багатовимірні масиви повинні описуватися і можуть при описі ініціалізуватися.
Елементи багатовимірних масивів зберігаються в пам'яті в порядку зростання крайнього правого індексу (або, як іноді говорять, по рядках). Список початкових значень, що задаються при описі масиву, відповідає порядку елементів масиву в пам'яті. Особливий випадок - ініціалізація двовимірного масиву рядковими літералами. Рядки масиву ініціалізуються символами рядкових літералов. Наприкінці кожного літерала міститься символ '\0'.
Багатовимірні масиви можуть ініціалізуватися і без вказівки однієї (крайньої лівої) із розмірностей масиву, у квадратних дужках. Компілятор у цьому випадку визначає число елементів за числом членів у списку ініціалізації.
Якщо необхідно проініціалізувати не всі елементи рядка, а тільки декілька перших елементів, у списку ініціалізації можна використовувати фігурні дужки, що охоплюють значення для рядка.
Ім'я двовимірного масиву є вказівником-константою на масив вказівників -констант. Елементами масиву вказівників є вказівники-константи на початок кожного із рядків масиву.
Як і для одновимірних масивів, доступ до елементів двовимірного масиву може здійснюватися по індексу або за допомогою механізму вказівників. У останньому випадку "точкою відліку" може бути як найперший елемент масиву, так і перший елемент кожного із рядків, тобто можуть використовуватися як вказівник-константа, що задається ім'ям масиву, так і вказівники на рядки масиву.
Наведені форми доступу до елементів масиву дають цілком рівноцінний по продуктивності і розміру машинний код.
Завдання
Написати програму для обробки даних, організованих у масив, згідно завдання наведеного варіанту. У програмах використати різні форми звертання до елементів багатовимірних масивів і масивів символьних рядків, у тому числі за допомогою конструкцій “вказівник на масив” і “вказівник на вказівник”. Враховувати, що кожен рядок матриці чи символьний рядок можна опрацьовувати як окремий елемент.
Варіанти індивідуальних завдань:
Ввести прямокутну матрицю цілих чисел. Надрукувати номери рядків матриці, всі елементи яких непарні (або вивести повідомлення про відсутність таких рядків). Переставити елементи всіх інших рядків у зворотному порядку.
Ввести декілька речень. У реченнях з найбільшою кількістю слів вилучити найкоротше слово.
Ввести послідовність слів. Визначити два слова, які мають найбільше спільних літер.
Ввести прямокутну матрицю дійсних чисел. Поміняти місцями два рядки матриці, з відповідно найбільшою і найменшою сумою елементів.
Ввести декілька речень. Слова з цих речень, які містять задану літеру, об’єднати в нове речення.
Ввести прямокутну матрицю цілих чисел. Циклічно зсунути її рядки на 2 вгору. Циклічний зсув передбачає, що елементи двох перших рядків матриці заносяться на відповідні місця зсунутих елементів двох останніх рядків.
Ввести квадратну матрицю дійсних чисел. Обчислити значення сум обох великих діагоналей матриці. Здійснити транспонування матриці.
Ввести прямокутну матрицю цілих чисел. Вилучити з матриці рядок і стовпчик, на перетині яких знаходиться її найменший елемент.
Ввести 7 цілих беззнакових чисел, менших за 1000. Сформувати з цих чисел матрицю розмірністю 710, кожен рядок якої заповнити 0 та 1 відповідно до двійкового коду введеного числа. Визначити число, двійковий код якого має найбільше 1.
Ввести прямокутну матрицю дійсних чисел. Вилучити з матриці рядок, добуток елементів якого є найбільшим.
Ввести прямокутну матрицю дійсних чисел. Циклічно зсунути її рядки на 1 униз. Циклічний зсув передбачає, що елементи останнього рядка матриці заносяться на відповідні місця зсунутих елементів першого рядка.
Ввести прямокутну матрицю дійсних чисел. Визначити номери двох рядків введеної матриці, скалярний добуток яких є найменшим.
Ввести послідовність речень. Визначити, в якому з них найменше слів. Надрукувати це речення заголовними літерами.
Ввести послідовність речень. Визначити, в якому з них є найбільше слів довжиною меншою за середню довжину усіх введених слів. Надрукувати це речення заголовними літерами.
Ввести послідовність речень. Вилучити з речень слова довжиною більшою за середню довжину усіх введених слів.
Ввести прямокутну матрицю дійсних чисел. Вилучити з матриці рядок з найменшою сумою елементів.
Ввести прямокутну матрицю дійсних чисел. Зсунути її рядки на 2 вгору (два старших рядки матриці втрачаються). Звільнені останні рядки матриці заповнити 0.
Ввести послідовність речень. У реченнях з найкоротшим словом, замінити передостаннє слово на ключове, введене користувачем.
Ввести прямокутну матрицю дійсних чисел. Обчислити кількість нульових елементів в матриці. Рядок, в якому найбільше елементів замінити на перший рядок матриці.
Ввести прямокутну матрицю дійсних чисел. Обчислити кількість недодатніх елементів матриці. Стовпець, в якому найбільше недодатніх елементів замінити на останній стовпець матриці.
Ввести послідовність слів. Відсортувати і роздрукувати їх в абетковому порядку. Визначити слово, в якому найбільше різних літер.
Ввести послідовність речень. Визначити середню довжину слова в кожному з речень. Надрукувати речення з найдовшими словами.
Ввести послідовність слів. Відсортувати їх у порядку спадання довжини та роздрукувати заголовними літерами.
Ввести прямокутну матрицю дійсних чисел. Вилучити з матриці рядки з нульовою сумою елементів. Передбачити, що таких рядків може бути декілька.
Ввести послідовність речень. У кожному з них поміняти місцями перше слово з останнім, замінивши заголовну літеру на малу та навпаки.
Ввести послідовність слів. Слова, які мають задану комбінацію двох літер роздрукувати заголовними літерами.
Ввести прямокутну матрицю дійсних чисел. Вилучити з матриці рядки, у яких найчастіше зустрічається комбінація від’ємного елемента по сусідству з додатнім.
Ввести прямокутну матрицю дійсних чисел. Вилучити з матриці рядок, для якого модуль різниці добутку елементів та їх суми є найбільшим.
Контрольні запитання
Як задається опис багатовимірного масиву?
Як зберігаються в пам’яті багатовимірні масиви?
Як ініціалізуються багатовимірні масиви?
Яка особливість ініціалізації масивів літералами?
Як ініціалізувати частину елементів багатовимірного масиву?
Яку ролі відіграє ім’я двовимірного масиву?
Як здійснюється доступ до елементів багатовимірного масиву за допомогою індексів?
Як звертатися до елементів багатовимірного масиву за допомогою вказівників?
Лабораторна робота № 3
Тема: програмування функцій мовою С
Мета: оволодіти основними прийомами створення функцій та передачі даних між ними на основі понять формальних і фактичних параметрів
Теоретичні відомості
Програма на мові С складається з однієї або декількох функцій. Функція - це логічно самостійна іменована частина програми, якій можуть передаватися параметри і яка може повертати якесь значення. Стандарт ANSI мови С передбачає такий формат визначення функції:
[тип_даних ] ім'я_функції (список_аргументів | void)
{ опис даних
оператори
[ return ] (вираз)
}
Сукупність речень у фігурних дужках часто називають тілом функції. Зустрівши визначення функції, компілятор створює самостійну секцію коду програми, що на етапі компонування об'єднується з іншими функціями. Синтаксис мови С забороняє усередині визначення функції поміщати визначення ще однієї функції.
Поле "тип_даних" задає тип значення, що повертається функцією. Якщо воно відсутнє, вважається, що функція повертає значення типу int. Якщо поле "тип_даних" містить ключове слово void, функція не повертає ніякого значення.
Поле "ім'я_функції" - це особливий тип вказівника, званого вказівником на функцію. Його значенням є адреса точки входу у функцію. Для кожного посилання на функцію (точка виклику) компілятор підставляє машинну інструкцію виклику процедури з поверненням. У результаті керування передається в точку входу функції. Будь-яка функція містить машинну інструкцію повернення RET. Її виконання повертає керування в точку виклику
Поле "список_аргументів" визначає аргументи (або параметри), передані у функцію, і містить будь-яку комбінацію типів і імен. Якщо функція має декілька аргументів, їхній тип і імена розділяються комою. Це поле у визначенні функції називають списком формальних аргументів (або параметрів). Для кожного виклику функції з параметрами компілятор добавляє в точці виклику машинні інструкції запису копій формальних аргументів у стек. Копії аргументів у стеку називають фактичними аргументами (або параметрами). Значення фактичних аргументів послідовно ставляться у відповідність формальним аргументам.
Поле "список_аргументів" - не обов'язкова частина у визначенні функції. Якщо у функцію не передаються ніякі аргументи, це поле - порожнє або містить ключове слово void.
Стандарт ANSI мови С вимагає, щоб функції, що повертають відмінні від int значення, були оголошені до першого посилання на них. Це "попереднє" оголошення, що називається прототипом функції, сповіщає компілятор про тип значення, що повертається, кількість і типи аргументів. Використовуючи прототип, компілятор може виконати, ретельний контроль числа аргументів і відповідність їхніх типів у викликах функції і її визначенні.
Обробляючи виклик функції, компілятор вставляє в код програми послідовність машинних команд, що виконують наступні дії:
1) запис у стек копій змінних або констант, перерахованих у списку аргументів (якщо поле "список_аргументів" у прототипі функції - не void);
2) виклик процедури з поверненням (або "близький", або "далекий" у залежності від заданого явно або неявно типу функції).
Функція в процесі виконання вибирає копії аргументів із стека. Таким чином, формальні і фактичні аргументи ізолюються один від одного.
При передачі параметрів у функцію (при їхньому записі в стек) виконується додатково перетворення типів фактичних аргументів до типу, що зазначений у прототипі функції.
Завдання
Задано функцію. Знайти визначений інтеграл з точністю Е=10-3 для заданих границь [a,b] за допомогою трьох методів: 1) прямокутників; 2) трапецій; 3) Сімпсона. Метод задавати з клавіатури відповідним номером.
Варіанти індивідуальних завдань:
f= sin 2 (x/2), a=0, b=/2;
EMBED Equation.3 , a=0, b=1;
f= cos 2 (4x), a= -/2, b=0;
EMBED Equation.3 , a=0, b=3;
f= 1/ EMBED Equation.3 (x +1) 2 , a= 0, b=7;
EMBED Equation.3 , a=0, b=/2;
f= (1+sin 2x) 2 , a= 0, b= /4;
f= 1/cos 2 (x/3), a= 0, b= ;
EMBED Equation.3 , a= 0, b= ;
EMBED Equation.3 , a= 0, b=ln2;
EMBED Equation.3 , a=1, b=9;
EMBED Equation.3 , a=-2, b=-1;
EMBED Equation.3 , a= 0, b= 100;
f= EMBED Equation.3 (2x-1), a= 0, b= 4.5;
EMBED Equation.3 , a= 0, b= 2;
f= (1+2x), a= 0, b= 4;
EMBED Equation.3 , a= 0, b=ln2;
EMBED Equation.3 , a= 0, b= ;
EMBED Equation.3 , a=0, b=3;
EMBED Equation.3 , a=0, b=2;
f= x/ (x2 + 3), a= 1, b= 3;
f= x/(3x +2) , a= 0, b= 2;
f= (3x2 +x-2)/(3x+1), a= 0, b=1;
f= cos4 x, a= 0, b= ;
EMBED Equation.3 , a= 0, b= 1;
EMBED Equation.3 , a= 0, b= ;
EMBED Equation.3 , a= 1, b= e;
EMBED Equation.3 , a= 0, b= .
Контрольні запитання
Яке призначення функцій у мовах високого рівня?
Який загальний вигляд опису функції у мові С?
Яке призначення елементів заголовку в описі функції (типу функції? параметрів функції?).
Що складає тіло функції?
Який тип повертає функція за замовчанням у мові С?
Що означає тип функції void?
Що таке прототип функції і як він використовується?
Як реалізується компілятором механізм звертання до функції?
Лабораторна робота № 4
Тема: опрацювання масивів із використанням функцій
Мета: навчитися організувати опрацювання масивів із використанням функцій, для яких масиви передаються як параметри
Теоретичні відомості
У загальному випадку існують два стилі передачі параметрів функції:
1) виклик функції з передачею значень (Call-By-Value);
2) виклик функції з передачею адрес змінних (Call-By-Reference).
Виклик із передачею значень - це проста передача копій змінних у функцію, що не залишає ніяких можливостей для впливу функції на змінні в точці виклику. Виклик функції за значенням застосовується в тих випадках, коли загальний об'єм переданих у функцію аргументів невеликй і функція не повертає великий об'єм даних.
Виклик із передачею адрес припускає, що як параметри функції передаються не копії змінних, а копії адрес змінних. Використовуючи вказівник, функція здійснює доступ до потрібних комірок пам'яті. Тому що відома адреса об'єкта в пам'яті, можна змінити його значення. Тому при виклику з передачею адрес функція може змінити значення змінних у точці виклику.
Виклик функції з передачею адрес дозволяє розробляти функції, що мають доступ до масивів і інших протяжних об'єктів даних. Якщо в список змінних включене ім'я масиву, то у функцію передається тільки адреса початку масиву.
Наприклад, так виглядає функція, що виконує копіювання рядка з одного місця пам'яті в інше (тобто дії, аналогічні бібліотечної функції strcpy):
#include <stdio.h>
char*my_strcpy(char*,char*);
void main(void)
{char *str1="Literal \0",*str2;
my_strcpy(str2,str1);
while (*str2)
printf("%c",*str2++);
}
char * my_strcpy(char*destination,char*source)
{char*ret_ptr=destination;
while(*source)
*destination++=*source++;
*destination='\0';
return ret_ptr;
}
Якщо програмісту зручніше маніпулювати з елементами масиву, попередню програму можна записати так:
#include <stdio.h>
#include <conio.h>
char*my_strcpy(char*,char*);
void main(void)
{clrscr();
char *str1="Literal \0",*str2;
my_strcpy(str2,str1);
while (*str2)
printf("%c",*str2++);
getchar();
}
char * my_strcpy(char destination[],char source[])
{char *ret_ptr=destination; int i=0;
while(source[i])
{ destination[i]=source[i];
i++;
}
destination[i]='\0'; //carrying over the symbol '\0'
return ret_ptr;
}
Відзначимо, що код другої функції має приблизно таку ж продуктивність, як і першої, але на пару десятків байтів довший. До речі, перший рядок функції my_strcpy() можна записати і так:
char * my_strcpy(char * destination, char * source)
а для доступу до елементів як і раніше використовувати індекс.
Завдання
Написати функцію для обчислення суми елементів квадратної матриці, що розташовані вижче побічної діагоналі. З її допомогою знайти мінімальне значення такої суми в k матрицях.
У двовимірному масиві записані слова, що є послідовністю цифр, яка завершуються 0. Необхідно роздрукувати слова через кому, узявши друкований рядок у дужки. Довжина друкованого рядка 60 символів. Видрук слова оформити у вигляді функції.
Наприклад: вхідні дані - 123023402303450
234450234567010
234455677670450
результат - (123,234,23,345)(23445,234567,1)(23445567767,45)
Написати функцію для обміну рядків двовимірного масиву з її допомогою відсортувати масив по елементах третього стовпчика.
Написати функцію для знаходження визначника квадратної матриці порядку 3. З її допомогою знайти серед введених матриць таку, визначник якої найбільший.
Розробити функцію, яка вилучає з речення слово, задане своїм порядковим номером (якщо таке слово є в реченні). На основі розробленої функції вилучити друге та шосте слово з введеного речення.
Написати функцію для підсумовування елементів матриці. З її допомогою додати вихідну матрицю і транспоновану.
Написати функцію для видалення рядка з двовимірного масиву. Рядки, що залишилися, повинні бути розташовані щільно. За допомогою розроблених функцій виключити з масиву рядки з номерами від А до В.
Написати функцію визначення скалярного добутку двох векторів. З її допомогою визначити чи є введена матриця ортонормована, тобто така, що скалярний добуток кожної пари різних рядків дорівнює 0, а скалярний добуток рядка самої на себе дорівнює 1.
Елемент матриці є сідловою точкою, якщо він є найменшим у своєму рядку і найбільшим у своєму стовпчику (або навпаки: найбільшим у своєму рядку і найменшим у своєму стовпчику). Написати функції для знаходження максимального та мінімального елементів вектора. З їх допомогою для заданої матриці визначити всі сідлові точки.
Написати функцію обміну стовпчика і рядка квадратної матриціі. З її допомогою поміняти місцями ті рядки і стовпчики, перші елементи яких збігаються.
Написати функцію транспонування квадратної матриці. З її допомогою визначити чи є задана матриця симетричною. (Матриця називається симетричною, якщо транспонована матриця дорівнює вихідній).
Написати функцію для обчислення суми елементів квадратної матриці, що розташовані нижче головної діагоналі. З її допомогою знайти максимальне значення такої суми в n матрицях.
Написати функцію, що перевіряє чи є від’ємні елементи в зазначеному рядку двовимірного масиву. Видалити з масиву всі рядки з від’ємними елементами, видалений рядок заповнюється 0 і переноситься в кінець масиву.
Написати функцію, що перевіряє за зростанням чи спаданням упорядкований зазначений рядок двовимірного масиву. Впорядкувати за зростанням всі рядки двомірного масиву, що неупорядковані за спаданням.
Написати функцію, для пошуку максимального елемента в зазначеному рядку двовимірного масиву. Зсунути в двовимірному масиві всі рядки циклічно вправо на кількість елементів рівну максимальному елементу в цьому рядку.
Визначити чи можна в двовимірному масиві знайти такий стовпчик, що розбиває масив на два так, що сума елементів у першому більша, ніж сума елементів у другому. Той стовпчик, що розбиває вихідний масив, у частини не входить.
Розробити функцію, яка визначає найдовше слово у заданому символьному рядку і повертає довжину цього слова. На основі розробленої функції визначити і надрукувати найдовше слово серед усіх слів групи введених речень.
Написати функцію для обміну стовпців матриці. З її допомогою відсортувати матрицю по елементах другого рядка.
Написати функцію, яка вилучає із заданої матриці дійсних чисел всі рядки, в яких мінімальний елемент не є першим, і повертає кількість вилучених рядків (вилучення рядка полягає в підтягуванні всіх наступних рядків угору). На основі розробленої функції перевірити і модифікувати введену з клавіатури матрицю.
Написати функцію, яка замінює у заданому символьному рядку всі слова, що містять вказану літеру на відповідну кількість символів '*'. Використовуючи розроблену функцію, "закодувати" всі слова з введених речень, в яких зустрічається задана користувачем літера.
Написати функцію, яка формує з заданого речення нове з інверсним порядком слів. На основі розробленої функції надрукувати введені речення зі зворотним порядком слів.
Написати функцію, яка визначає, чи входить до складу заданого символьного рядка вказане користувачем ключове слово. На основі розробленої функції визначити, в якому з речень найбільше разів зустрічається заданий ключовий набір символів.
Написати функцію, що перевіряє чи є нульові елементи в зазначеному стовпці двовимірного масиву. Видалити з масиву всі стовпці з нульовими елементами, а видалений стовпець заповнюється 0 і переноситься в кінець масиву.
Написати функцію, яка обчислює суму елементів заданого масиву Визначити чи можна у ввведеному двовимірному масиві знайти такий рядок, що розбиває масив на два так, що сума елементів у першому більша, ніж сума елементів у другому. Той рядок, що розбиває вихідний масив, у частини не входить.
Написати функцію, що перевіряє чи сума елементів головної діагоналі двовимірного масиву більша за суму елементів побічної діагоналі. На основі цієї функції перевірити 5 введених матриць.
Написати функцію, яка перевіряє чи матриця є розрідженою. З її допомогою визначити кількість роздріджених матриць серед введених. (Матриця вважається розрідженою, якщо кількість нульових елементів більші за її порядок).
Написати функцію, яка обчислює суму елементів під головною діагоналлю. З її допомогою знайти серед введених матриць такі, сума елементів яких під головною діагоналлю рівна 0.
Написати функцію, яка вилучає із заданої матриці дійсних чисел всі cстовпці, в яких максимальний елемент не є останнім, і повертає кількість вилучених стовпців (вилучення стовпця полягає в підтягуванні всіх наступних стовпців вліво). На основі розробленої функції перевірити і модифікувати введену з клавіатури матрицю.
Контрольні запитання
Які є два способи передачі параметрів функції?
У чому суть виклику функції з передачею значень параметрів і передачею адрес параметрів?
Коли доцільно використовувати виклик функції з передачею значень параметрів а коли - з передачею адрес параметрів?
Як передати масив як параметр функції?
Як опрацьовуються масиви, передані у функцію, за допомогою індексів та вказівників ?
Лабораторна робота № 5
Тема: організація структур мовою С
Мета: навчитися організовувати структури та розробляти алгоритми обробки структур засобами мови С
Теоретичні відомості
Структурні змінні, або просто структури, - це об'єднання однієї або більше змінних, можливо, різних типів, в одну область пам'яті, що має для простоти одне ім'я. Окремі складові частини структурної змінної будемо далі називати полями.
Як і будь-яка змінна, структурна змінна повинна описуватися. Цей опис складається з двох кроків:
1) задання шаблона структури;
2) власне опис структурної змінної.
Кожний шаблон має власне ім'я для того, щоб компілятор міг розрізняти різні шаблони. У тому випадку, якщо у функції використовується єдиний шаблон, він може не мати імені. Імена шаблонів повинні бути унікальними в межах їхньої області визначення. Синтаксис задання шаблона такий:
struct pattern_name
{ type1 field_name1;
type2 field_name2;
…………
typeN field_nameN;
};
де pattem_name - ім'я шаблона, що задовольняє правилам задання ідентифікаторів мови С; type1, type2,... , typeN - будь-які типи, наприклад int, char, float; field_name1, field_name2,... , field_name - імена полів, що задовольняють правилам задання ідентифікаторів мови С. Наприклад:
struct BOOK { char name [20];
char title[44];
int year; float price; };
Імена полів в однім шаблоні повинні бути унікальними. Однак у різних шаблонах можна використовувати однакові імена полів. Крім того, імена шаблонів перевіряються на "унікальність" один з одним, а не з мітками або іменами змінних. Тому ім'я шаблона може і збігатися з іменами полів, змінних або мітками.
Коли заданий шаблон, може бути описана структурна змінна. Опис структурної змінної складається із завдання типу й імені структурної змінної. Наприклад:
struct BOOK first_book;
Тут описується структурна змінна за наведеним раніше шаблоном BOOK. Компілятор виділить під змінній число байтів пам'яті, достатнє для збереження всіх її полів. У даному випадку це 70 байт. Число байтів, виділене під структурну змінну, не завжди дорівнює сумі довжин окремих полів через вплив додаткового чинника внутрішнього представлення структурних змінних, називаного вирівнюванням. Точно виділене число байтів завжди повертає операція sizeof (struct pattem_name). Наприклад, sizeof (struct BOOK) поверне завжди 70, однак для інших шаблонів можливі варіанти.
Синтаксис мови програмування С дозволяє сполучати опис шаблона і структурної змінної, наприклад так:
struct BOOK { char name [20];
char title[44];
int year; float price;
} first_book, child_book, dog_book;
Для доступу до окремих полів структурної змінної використовують операцію ‘.’, формуючи посилання на потрібне поле з імені структурної змінної і імені потрібного поля. Таке посилання може розташовуватися в будь-якому місці виразів, де припустимі посилання на прості змінні. Наприклад, якщо зроблено раніше розглянутий опис структурних змінних, коректними будуть наступні вирази:
first_book.year=1992;
dog_book.year=first_book.year;
strcpy(child_book. title, "Програмування в середовищі С");
scanf("%f", &first_book.price);
Посилання на поле структурної змінної мають усі властивості звичайних змінних. Якщо поле - це масив символів, то, наприклад, child_book.title - це вказівник-константа на перший елемент масиву. Можна визначити адресу першого байта поля структурної змінної звичайною операцією узяття адреси. Наприклад, &first_book.price - це адреса першого байта поля. Природно, що посилання на поле структурної змінної може розташовуватися як зліва, так і справа від операції присвоювання. Так само, як і для звичайних операндів, діють правила перетворення типів при змішуванні операндів різних типів.
Якщо структурні змінні відповідають одному шаблону, допускається операція присвоювання таких структурних змінних. Наприклад, для раніше описаних структурних змінних first_book, child_book і dog_book будуть коректними такі вирази:
first_book=child_ book;
flrst_book = child_book = dog_book;
Операція присвоювання структурних змінних приводить до фізичного пересилання в пам'яті числа байтів, рівного розміру шаблона структурної змінної. У наведеному прикладі три структурні змінні будуть мати поля, що збігаються з полями структурної змінної dog_book.
При описі структурної змінної дозволяється виконувати ініціалізацію полів змінної.
Дозволяється об'єднувати задання шаблона, опис структурних змінних і їхню ініціалізацію в одному реченні мови С.
Для спрощення опису структурних змінних можна використовувати оператор typedef опису власного типу даних. Це спрощує текст програми і заощаджує сили на повторний набір слова struct при описі структурних змінних. Загальна форма речення конструювання власного типу даних:
typedef опис_типу ім'я_нового_типу;
Наприклад:
typedef struct BOOK { char name[20];
char title[44];
int year; float price;
}MY_BOOKS;
Потім можна використовувати сконструйований тип для опису необхідних даних, наприклад так:
MY BOOKS dog_book; /* те ж саме, що і struct BOOK,
але запис дещо коротший */
Тут використовується для створення власного типу іменований шаблон BOOK. Однак використання імені шаблона зовсім не обов'язкове, тобто можна записати:
typedef struct { char name[20];
char title[44];
int year; float price;
}BOOKS;
typedef struct {char class, subclass;
int number;
}MY_UDC;
Завдання І
З клавіатури ввести послідовність записів, які містять дані про результати сесії студентів групи: <Прізвище>, <Ім’я>, <Дата народження>, <Список екзаменаційних оцінок>. Сукупність даних про студентів групи оформити у масив. Роздрукувати введені дані у вигляді таблиці, а також подати інформацію згідно варіанту.
Варіанти індивідуальних завдань
Відсортувавати дані за прізвищами студентів в алфавітному порядку. Визначити двох студентів з найвищим середнім балом.
Відсортувавати дані за прізвищами студентів в порядку протилежному алфавітному. Визначити п’ять студентів з найнижчим середнім рейтинговим балом.
Відсортувавати дані за віком студентів у зростаючому порядку. Роздрукувати список студентів з рейтинговим балом нижчим від середнього балу в групі.
Відсортувавати дані за віком студентів у спадному порядку. Роздрукувати список студентів з рейтинговим балом вищим від середнього балу в групі.
Роздрукувати список студентів, які отримали оцінки 2 на іспитах, у алфавітному порядку за прізвищем.
Роздрукувати список студентів, які отримали лише оцінки 5 на іспитах, у зростаючому порядку за віком.
Роздрукувати список студентів у зростаючому порядку за рейтинговим балом.
Роздрукувати список студентів, молодших середнього віку у групі, впорядкований у алфавітному порядку за прізвищем.
Роздрукувати список студентів, старших середнього віку у групі, впорядкований за зростанням рейтингового балу.
Роздрукувати список студентів, які отримали оцінки 4 і 5 на іспитах, у спадному порядку за віком. Визначити двох наймолодших студентів серед них.
Роздрукувати список студентів, які не отримали жодної оцінки 2 на іспитах, у алфавітному порядку за прізвищем. Визначити двох найстарших студентів серед них.
Роздрукувати список студентів, які не отримали жодної оцінки 5 на іспитах, впорядкований за середнім рейтинговим балом. Визначити найстаршого та наймолодшого студентів серед них.
Роздрукувати список студентів, народжених восени, впорядкований в алфавітному порядку за прізвищем.
Роздрукувати список студентів, народжених влітку, впорядкований в порядку зростання рейтингового балу.
Завдання ІІ
З клавіатури ввести послідовність записів, які містять дані про книгу : <Автор>, <Назва книги>, <Рік видання>, <Кількість сторінок>, <Вартість>. Сукупність даних про книги бібліотеки оформити у масив. Роздрукувати введені дані у вигляді таблиці, а також подати інформацію згідно варіанту.
Варіанти індивідуальних завдань
Відсортувавати дані за прізвищами авторів в алфавітному порядку. Визначити дві книги з найбільшою кількістю сторінок.
Відсортувавати дані за прізвищами авторів в порядку протилежному алфавітному. Визначити п’ять найновіших книг за роком видання .
Відсортувавати дані за назвою в порядку протилежному алфавітному. Визначити шість найстаріших книг за роком видання .
Відсортувавати дані за назвою в алфавітному порядку. Визначити три найдорожчяих книги за вартістю.
Відсортувавати у зростаючому порядку дані за роком видання. Визначити три книги з найменшою кількістю сторінок.
Відсортувавати у зростаючому порядку дані за вартістю. Визначити книги авторів з прізвищем, що починається на букву А.
Відсортувавати у спадному порядку дані за роком видання. Визначити книги з назвою, що починається на букву А.
Відсортувавати у зростаючому порядку дані за кількістю сторінок. Визначити книги з кількістю сторінок, більшою за середню в бібліотеці.
Відсортувавати у спадному порядку дані за вартістю. Визначити книги видані пізніше 1980 року.
Відсортувавати у спадному порядку за вартістю дані про книги видані раніше 1975 року.
Відсортувавати за назвою в алфавітному порядку дані про книги, вартість яких більша середньої в бібліотеці.
Відсортувавати за прізвищем в алфавітному порядку дані про книги, вартість яких менша середньої в бібліотеці.
Відсортувавати у зростаючому порядку за роком видання дані про книги з кількістю сторінок меншою за середню в бібліотеці.
Відсортувати у зростаючому порядку за вартістю дані про книги, видані з 1991 року.
Контрольні запитання
Що таке структура в мові С?
Яки загальний вигляд опису структури?
Які є два підходи до опису структурної змінної?
Як здійснюється доступ до окремих полів структурної змінної?
Які операції можна виконувати із змінними структурного типу?
Коли можна копіювати одну структуру в іншу?
Як використовується оператор typedef ?
Лабораторна робота № 6
Тема: організація обміну інформацією з дисковими файлами
Мета: здобути практичні навики у використанні дискових файлів для зчитування та занесення інформації
Теоретичні відомості
Будемо розглядати потокове введення-виведення, при якому обмін даними робиться побайтно. Таке уведення-виведення можливе як для власне пристроїв побайтового обміну (друкувальний пристрій, дисплей), так і для файлів на диску, хоча пристрої зовнішньої пам'яті, строго говорячи, є пристроями поблочного обміну, тобто за одне звертання до пристрою робиться зчитування або запис фіксованої порції даних.
При роботі з потоком можна робити наступні дії:
• відкривати і закривати потоки (зв'язувати вказівники на потоки з конкретними файлами);
• вводити і виводити: символ, рядок, форматовані дані, порцію даних довільної довжини;
• аналізувати помилки потокового введення-виведення й умову досягнення кінця потоку (кінця файла);
• управляти буферизацією потоку і розміром буфера;
• одержувати і встановлювати вказівник (індикатор) поточної позиції в потоці.
Для того щоб можна було використовувати функції бібліотеки введення-виведення мови С, у програму необхідно включити заголовний файл stdio. h (#include <stdio. h>), що містить прототипи функцій уведення-виведення, а також визначення констант, типів і структур, необхідних для роботи функцій обміну з потоком.
Перед тим , як почати працювати з потоком, його необхідно ініціалізувати, тобто відкрити. При цьому потік зв'язується у виконуваній програмі зі структурою визначеного типу FILE.
Вказівник на потік, наприклад fp, повинен бути оголошений у програмі в такий спосіб:
#include <stdio. h>
FILE *fp;
Вказівник на потік набуває значення у результаті виконання функції відкривання потоку:
fp = fopen (ім'я_файла, режим_відкривання);
Файл, зв'язаний із потоком, можна відкрити в одному із наступних шести режимів:
"w" - новий текстовий файл відкривається для запису. Якщо файл вже існував, той попередній уміст...