Модульне програмування

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Кафедра: Автоматика і Обчислювальна Техніка
Модульне програмування

Зміст
1. Класи пам'яті ідентифікатора
1.1 Область дії
1.2 Область видимості
1.3 Тривалість життя
2. Моделі пам'яті ОЗУ
2.1 Види моделей пам'яті
2.2 Розміщення виконуваного файлу в ОЗУ в моделі large
3. Передача даних у функцію
3.1 Передача параметрів за значенням
3.2 Передача параметрів за адресою
3.3 Передача одновимірних масивів
3.4 Передача двовимірних масивів
4. Тестування функцій
5. Практичні завдання
5.1 Вказати класи пам'яті змінної
5.2 Працюємо з адресами
5.3 Прототипи функцій
5.3.1 Свопінг
5.3.2 Індекси максимальних елементів одновимірного масиву
5.3.3 Індекси максимальних елементів двовимірного масиву
5.3.4 Кут між двома векторами
5.3.5 Визначник матриці
5.4 Виділення фрагмента програми в окрему функцію
5.5 Тестування функції
5.5.1 Сортування масиву
5.5.2 МініМакс
6. Лабораторні завдання
6.1 Лінійне рівняння
6.2 Парні елементи масиву
6.3 Знаходження простих чисел
6.4 Кількість входжень підрядка в рядок
6.5 Твір матриць
7. Додаткові завдання
Бібліографічний список

1. Класи пам'яті ідентифікатора

З кожним об'єктом пам'яті змінної пов'язані такі поняття: область дії, область видимості і тривалість життя. Ці три поняття об'єднуються в поняття клас пам'яті змінної. Клас пам'яті встановлюється синтаксисом і місцем розміщення визначення цієї змінної.
Специфікатор класу пам'яті в оголошенні змінної може бути auto, register, static або extern. Якщо клас пам'яті не зазначений, то він визначається за замовчуванням з контексту оголошення.
Об'єкти класів auto і register мають локальний час життя. Специфікатор static і extern визначають об'єкти з глобальним часом життя.
При оголошенні змінної на внутрішньому рівні може бути використаний будь-який з чотирьох специфікатором класу пам'яті, а якщо він не вказаний, то мається на увазі клас пам'яті auto.
Змінна з класом пам'яті auto має локальний час життя і видно лише в блоці, в якому оголошена. Пам'ять для такої змінної виділяється при вході в блок і звільняється при виході з блоку. При повторному вході в блок цієї змінної може бути виділений іншу ділянку пам'яті.
Змінна з класом пам'яті auto автоматично не ініціалізується. Вона повинна бути проініціалізувати явно при оголошенні шляхом присвоєння їй початкового значення. Значення неініціалізованої змінної з класом пам'яті auto вважається невизначеним.
Специфікатор класу пам'яті register наказує компілятору розподілити пам'ять для змінної в регістрі, якщо це є можливим. Використання реєстрової пам'яті зазвичай призводить до скорочення часу доступу до змінної. Змінна, оголошена з класом пам'яті register, має ту ж область видимості, що і мінлива auto. Число регістрів, які можна використовувати для значень змінних, обмежена можливостями комп'ютера, і в тому випадку, якщо компілятор не має в розпорядженні вільних регістрів, то перемінної виділяється пам'ять як для класу auto. Клас пам'яті register може бути вказаний тільки для змінних з типом int або покажчиків з розміром, рівним розміром int.
Змінні, оголошені на внутрішньому рівні з специфікатором класу пам'яті static, забезпечую можливість зберегти значення змінної при виході з блоку і використовувати його при повторному вході до блоку. Така змінна має глобальне час життя і область видимості всередині блоку, в якому вона оголошена. На відміну від змінних з класом auto, пам'ять для яких виділяється в стеку, для змінних з класом static пам'ять виділяється в сегменті даних, і тому їх значення зберігається при виході з блоку.
Приклад:
/ * Оголошення змінної i на внутрішньому рівні з класом пам'яті static. * /
/ * Вихідний файл file1. c * /
main ()
{...
}
fun1 ()
{Static int i = 0; ...
}
/ * Вихідний файл file2. c * /
fun2 ()
{Static int i = 0; ...
}
fun3 ()
{Static int i = 0; ...
}
У наведеному прикладі оголошені три різні змінні з класом пам'яті static, що мають однакові імена i. Кожна з цих змінних має глобальне час життя, але видима тільки в тому блоці (функції), в якій вона оголошена. Ці змінні можна використовувати для підрахунку кількості звернень до кожної з трьох функцій.
Змінні класу пам'яті static можуть ініціалізувати константним виразом. Якщо явною ініціалізації немає, то такий змінної присвоюється нульове значення. При ініціалізації константним адресним виразом можна використовувати адреси будь-яких зовнішніх об'єктів, крім адрес об'єктів з класом пам'яті auto, оскільки адреса останніх не є константою і змінюється при кожному вході в блок. Ініціалізація виконується один раз при першому вході в блок.
Змінна, оголошена локально з класом пам'яті extern, є посиланням на змінну з тим же самим ім'ям, певну глобально в одному з вихідних файлів програми. Мета такого оголошення у тому, щоб зробити визначення змінної глобального рівня дивись всередині блоку.
Приклад:
/ * Оголошення змінної i, що є ім'ям зовнішнього масиву довгих цілих чисел, на локальному рівні * /
/ * Вихідний файл file1. c * /
main ()
{...
}
fun1 ()
{Extern long i []; ...
}
/ * Вихідний файл file2. c * /
long i [MAX] = {0};
fun2 ()
{...
}
fun3 ()
{...
}
Оголошення змінної i [] як extern у наведеному прикладі робить її видимою всередині функції fun1. Визначення цієї змінної знаходиться у файлі file2. c на глобальному рівні і має бути лише одне, в той час як оголошень з класом пам'яті extern може бути декілька.
Оголошення з класом пам'яті extern потрібно при необхідності використовувати змінну, описану в поточному вихідному файлі, але нижче по тексту програми, тобто до виконання її глобального визначення. Наступний приклад ілюструє таке використання змінної з ім'ям st.
Приклад:
main ()
{Extern int st []; ...
}
static int st [MAX] = {0};
fun1 ()
{...
}
Оголошення змінної з специфікатором extern інформує компілятор про те, що пам'ять для змінної виділяти не потрібно, так як це виконано десь в іншому місці програми.
При оголошенні змінних на глобальному рівні може бути використаний специфікатор класу пам'яті static або extern, а так само можна оголошувати змінні без вказівки класу пам'яті. Класи пам'яті auto і register для глобального оголошення неприпустимі.
Оголошення змінних на глобальному рівні - це або визначення змінних, або посилання на визначення, зроблені в іншому місці програми. Оголошення глобальної змінної, яке ініціалізує цю змінну (явно чи неявно), є визначенням змінної. Визначення на глобальному рівні може задаватися в наступних формах:
1. Змінна оголошена з класом пам'яті static. Така змінна може бути ініціалізований явно константним виразом, або за умовчанням нульовим значенням. Тобто оголошення static int i = 0 і static int i еквівалентні, і в обох випадках змінної i буде присвоєно значення 0.
2. Змінна оголошена без вказівки класу пам'яті, але з явною ініціалізацією. Такий змінної за замовчуванням присвоюється клас пам'яті static. Тобто оголошення int i = 1 і static int i = 1 будуть еквівалентні.
Змінна оголошена глобально видимою у межах залишку вихідного файлу, в якому вона визначена. Вище свого опису і в інших вихідних файлах ця змінна невидима (якщо тільки вона не оголошена з класом extern).
Глобальна змінна може бути визначена тільки один раз в межах своєї області видимості. В іншому вихідному файлі може бути оголошена інша глобальна змінна з таким же ім'ям і з класом пам'яті static, конфлікту при цьому не виникає, тому що кожна з цих змінних буде видимою тільки у своєму початковому файлі.
Специфікатор класу пам'яті extern для глобальних змінних використовується, як і для локального оголошення, в якості посилання на змінну, оголошену в іншому місці програми, тобто для розширення області видимості змінної. При такому оголошенні область видимості змінної розширюється до кінця вихідного файлу, в якому зроблено оголошення.
В оголошеннях з класом пам'яті extern не допускається ініціалізація, так як ці оголошення посилаються на вже існуючі та визначені раніше змінні.
Змінна, на яку робиться посилання з допомогою специфікатора extern, може бути визначена тільки один раз в одному з вихідних файлів програми.

1.1 Область дії

Область дії змінної - це частина програми або вихідного модуля, в якій визначено об'єкт відповідний цієї змінної. Перерахуємо види областей дії.
Блок. Ця область дії починається в точці визначення змінної і закінчується в кінці блоку, що містить це визначення. Такий блок називається оточуючим. Тіло функції розглядається як блок.
Функція. Фактично збігається з тілом функції. Такий областю дії мають формальні аргументи, перераховані в заголовку функції, а також мітки, використовувані операторами goto.
Файл. Поширяться від точки визначення змінної до кінця файлу. Змінні з такою областю дії називаються глобальними і повинні визначатися поза всякої функції. Якщо глобальна змінна визначена наприкінці файлу, то її область дії фактично порожня і вгору на весь файл не поширюється. Прототип ". Такий областю дії мають змінні зі списку формальних параметрів прототипу функції.

1.2 Область видимості

Видимість змінних і функцій у програмі визначається наступними правилами.
1. Змінна, оголошена чи певна глобально, видима від точки оголошення або визначення до кінця вихідного файлу. Можна зробити змінну видимої і в інших вихідних файлах, для чого в цих файлах слід її оголосити з класом пам'яті extern.
2. Змінна, оголошена чи певна локально, видима від точки оголошення або визначення до кінця поточного блоку. Така змінна називається локальною.
3. Змінні з осяжний блоків, включаючи змінні оголошені на глобальному рівні, видимі у внутрішніх блоках. Цю видимість називають вкладеною. Якщо змінна, оголошена всередині блоку, має те ж ім'я, що й змінна, оголошена в осяжний блоці, то це різні змінні, і змінна з осяжний блоку у внутрішньому блоці буде невидимою.
4. Функції з класом пам'яті static видимі тільки у вихідному файлі, в якому вони визначені.
Мітки у функціях видимі протягом всієї функції.
Імена формальних параметрів, оголошені в списку параметрів прототипу функції, видимі тільки від точки оголошення параметра до кінця оголошення функції.

1.3 Тривалість життя

Час життя змінної (глобальної або локальної) визначається за такими правилами.
1. Змінна, оголошена глобально (тобто поза всіх блоків), існує протягом усього часу виконання програми.
2. Локальні змінні (тобто оголошені усередині блоку) з класом пам'яті register або auto, мають час життя тільки на період виконання того блоку, в якому вони оголошені. Якщо локальна змінна оголошена з класом пам'яті static або extern, то вона має час життя на період виконання всієї програми.

2. Моделі пам'яті ОЗУ

Пам'ять мікропроцесора Intel 80x86 має сегментовану архітектуру. Безпосередньо можна адресуватися до 64К пам'яті сегменту. Процесор 80x86 відстежує 4 різних сегменти: сегмент коду, сегмент даних, сегмент стека і додатковий сегмент. Кодовий сегмент містить машинні команди програми; в сегменті даних зберігається інформація; сегмент стека має організацію і призначення стека; допоміжний сегмент використовується для зберігання деяких допоміжних даних. Процесор 80x86 має чотири 16-розрядних сегментних регістра (по одному на сегмент) - CS, DS, SS і ES, які вказують на сегмент коду, даних, стека і додатковий сегмент відповідно. Сегмент може знаходитися в будь-якому місці пам'яті, але починатися повинен за адресою, кратному 10. Сегменти можуть перекриватися. Наприклад, всі чотири сегменти можуть починатися з однієї адреси.
Повна адреса в 8086 складається з двох 16-бітових значень: адреси сегмента і зсуву. Припустимо, що адреса сегмента даних - тобто значення в регістрі DS - дорівнює 2F84 (шістнадцяткове) і ви бажаєте обчислити фактична адреса деякого елемента даних, який має значення 0532 (підстава 16) від початку сегменту даних; як це зробити?
Обчислення адреси буде виконано наступним чином: потрібно зрушити вліво значення сегментного регістра на 4 біти (це еквівалентно одній шістнадцятковій цифрі), а потім скласти з величиною зміщення.
Отримане 20-бітове значення і є фактична адреса даних, як показано нижче:
регістр DS (після зсуву): 0010 1111 1000 0100 0000 = 2F840
зміщення: 0000 0101 0011 0010 = 00532
---------------------- - --------------------------- ----
Адреса: 0010 1111 1101 0111 0010 = 2FD72
Ділянка пам'яті величиною 16 байт називається пунктом, тому говорять, що сегмент завжди починається на кордоні параграфа.
Початковий адресу сегмента завжди є 20-бітовим числом, але сегментний регістр має всього 16 бітів - тому молодші 4 біти завжди передбачаються рівними нулю. Це означає - як було вже сказано - що початок сегмента може знаходитися тільки в адресах пам'яті, кратних 16, тобто адресах, в яких останні 4 біти (або один шістнадцяткові розряд) дорівнює нулю. Тому якщо регістр DS містить значення 2F84, то фактично сегмент даних починається в адресі 2F840.
Стандартна запис адреси має форму сегмент: зсув; наприклад, попередній адресу можна записати як 2F84: 0532. Зазначимо, що оскільки зміщення можуть перекриватися, дана пара сегмент: зсув не є унікальною; наступні адреси відносяться до однієї і тієї ж точки пам'яті:
0000: 0123
0002: 0103
0008: 00A3
0010: 0023
0012: 0003
Сегменти можуть (але не повинні) перекриватися. Наприклад, всі чотири сегменти можуть починатися з одного і того ж адреси, що означає, що вся ваша програма в цілому займе не більше 64 Кб - але тоді в межах цієї пам'яті повинні поміститися і коди програми, і дані, і стек.

2.1 Види моделей пам'яті

У 16-розрядних програмах ви можете використовувати 6 моделей пам'яті: крихітну, малу, середню, компактну, велику і величезну.
Tiny (крихітна). Ця модель пам'яті використовується в тих випадках, коли абсолютним критерієм переваги програми є розмір її завантажувального коду. Це мінімальна з моделей пам'яті. Всі чотири сегментних регістра (CS, DS, SS і ES) встановлюються на один і той же адреса, що дає загальний розмір коду, даних і стека, рівний 64К. Використовуються виключно ближні покажчики.
Small (мала). Ця модель добре підходить для невеликих прикладних програм. Сегменти коду і даних розташовані окремо один від одного і не перекриваються, що дозволяє мати 64К коду програми та 64К даних і стека. Використовуються тільки покажчики near.
Medium (середня). Ця модель годиться для великих програм, для яких не потрібно тримати в пам'яті великий обсяг даних. Для коду, але не для даних використовуються покажчики far. В результаті дані плюс стек обмежені розміром 64К, а код може займати до 1М.
Compact (компактна). Краще всього використовувати цю модель у тих випадках, коли розмір коду невеликий, але потрібно адресація великого обсягу даних. Покажчики far використовуються для даних, але не для коду. Отже, код тут обмежений 64К, а граничний розмір даних - 1 Мб.
Large (більша). Моделі large і huge застосовуються тільки в дуже великих програмах. Дальні покажчики використовуються як для коду, так і для даних, що дає граничний розмір 1 Мб для обох.
Huge (величезна). Дальні покажчики використовуються як для коду, так і для даних. Borland C зазвичай обмежує розмір статичних даних 64К; модель пам'яті huge скасовує це обмеження, дозволяючи статичними даними займати більш 64К.
Для вибору будь-якої з цих моделей пам'яті ви повинні або скористатися відповідним параметром меню інтегрованого середовища, або ввести параметр при запуску компілятора, що працює в режимі командного рядка.

2.2 Розміщення виконуваного файлу в ОЗУ в моделі large

Моделі пам'яті влаштовані по-різному. Розглянемо розташування областей пам'яті в моделі large.
Область коду містить машинні коди функцій програми. Функції, приєднані до exe-файлу на стадії компонування, розміщуються поза області коду.
Область даних містить глобальні та статичні змінні, рядкові константи.
У стеці розміщуються локальні змінні, параметри, що передаються функціям, і ряд інших даних. Як правило, стек росте зверху вниз, займаючи пульсуючу безперервну область. У разі переповнення стека відбувається його "налезаніе" стека на область даних і видається відповідне повідомлення. Перевірка стека збільшує час роботи програми і її можна відключити в Options-Entry/Exit Code Generation-Stack options-Test stack overflow.
У купу дані розміщуються лише за вказівкою програміста і не мають імені. До них можна звернутися тільки за адресою, розташованому в локальної або глобальної змінної.


Рис.1. Сегментація для моделі пам'яті Large

3. Передача даних у функцію

Сі - мова суто процедурний і основний логічною одиницею програми є функція. Формат опису функції наступний:
[Тип значення] імя_функціі (список параметрів)
{Тіло функції
[Return возвращаемое_значеніе]}
У дужках поміщена необов'язкова частина конструкції.
У списку параметрів вказують дані, які необхідно передати у функцію. Нижче розглянуті різні способи передачі даних у функцію.

3.1 Передача параметрів за значенням

Параметри функції передаються за значенням і можуть розглядатися як локальні змінні, для яких виділяється пам'ять при виконанні функції і виробляється ініціалізація значеннями фактичних параметрів. При виході з функції значення цих змінних губляться. Оскільки передача параметрів відбувається за значенням, у тілі функції не можна змінити значення змінних в зухвалому функції, які є фактичними параметрами.
Наприклад:
void print_num (int i, int j)
{Printf ("значення i =% d. Значення j =% d.", i, j);}
Звернення в програмі до даної функції буде таким:
print_num (6, 19);

3.2 Передача параметрів за адресою

Розглянемо приклад функції, яка змінює значення змінних місцями:
void change (int x, int y)
{Int k = x;
x = y;
y = k;
}
У даній функції значення змінних x і y, які є формальними параметрами, міняються місцями, але оскільки ці змінні існують тільки усередині функції change, значення фактичних параметрів, використовуваних при виклику функції, залишаться незмінними. Для того щоб змінювалися місцями значення фактичних аргументів можна використовувати функцію наведену в наступному прикладі.
Приклад:
void change (int * x, int * y)
{Int k =* x;
* X =* y;
* Y = k;
}
При виклику такої функції в якості фактичних параметрів повинні бути використані не значення змінних, а їх адреси change (& a, & b);

3.3 Передача одновимірних масивів

При передачі одновимірного масиву в функцію слід враховувати, що ім'я масиву не містить інформації про розмір цього масиву. Тому необхідно передавати два параметри: ім'я масиву і розмір.
Приклад.
int sum (int A [], int Dim); / / прототип
int sum (int A [], int Dim); / / заголовок
{
....
} / / Телофункціі
void main ()
{
int res, A [] = {2,1,3,2};
res = sum (A,
4);
} / / Виклик функції sum
Формальний аргумент імені масиву може мати вигляд int * A.
int sum (int * A, int Dim); / / прототип
Для визначення розміру масиву при виконанні функції можна використовувати вираз sizeof (A) / sizeof (int) або sizeof (A) / sizeof (A []). Наприклад,
res = sum (A, sizeof (A) / sizeof (A []));

3.4 Передача двовимірних масивів

Спосіб 1. При передачі двовимірного масиву в функцію слід враховувати, що кількість елементів у рядку масиву є частиною типу імені цього масиву. Так наприклад, для масиву int A [3] [4] ім'я масиву А має тип int (*) [4], тобто А - це покажчик на одновимірний масив з 4 елементів типу int.
Тому необхідно передавати два параметри: ім'я масиву і кількість рядків у масиві.
Приклад.
int sum2 (int A [] [4], int M); / / прототип
int sum2 (int A [] [4], int M); / / заголовок
{
....
} / / Телофункціі
void main ()
{
int res, A [] [4] = {{2,1,3,2}, {2,3,4,5}}; / / два рядки, чотири столобца
res = sum2 (A,
2); / / виклик функції sum2
}
Формальний аргумент імені масиву може мати вигляд int (* A) [4].
int sum2 (int (* A) [4], int M); / / прототип
Для визначення розміру масиву при виконанні функції можна використовувати вираз sizeof (A) / sizeof (A []). Наприклад,
res = sum2 (A, sizeof (A) / sizeof (A []));
Спосіб 2. Інший спосіб передачі двовимірного масиву у функцію складається в зануренні фактичного двовимірного масиву з розмірами MxN в двовимірний масив завідомо великих розмірів. Пі цьому досить взяти великий розмір стоки, наприклад, 100.
int sum3 (int A [] [100], int M, int N); / / прототип
int sum3 (int A [] [100], int M, int N); / / заголовок
{
....
} / / Телофункціі
void main ()
{
int res, A [2] [100] = {{2,1,3,2}, {2,3,4,5}} / * два рядки, чотири стовпці з чатічной ініціаліазаціей * /
res = sum3 (A, 2,4); / / виклик функції sum3
}
Спосіб 3. Третій спосіб передачі двовимірного масиву у функцію складається в емуляції фактичного двовимірного масиву з розмірами MxN за допомогою одновимірного масиву з розміром M * N. Пі цьому M * N повинне бути менше 64К.
int sum4 (int A [], int M, int N); / / прототип
int sum4 (int A [], int M, int N); / / заголовок
{
....
} / / Телофункціі
void main ()
{
int res, A [2] [4] = {{2,1,3,2}, {2,3,4,5}} / * два рядки, чотири стовпці * /
res = sum4 ((int *) A, 2,4); / / виклик функції sum4
}

4. Тестування функцій

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

5. Практичні завдання

5.1 Вказати класи пам'яті змінної

Що надрукує програма? Вкажіть область дії, область видимості і тривалість життя всіх змінних n.
int n = 1;
void main ()
{
printf ("% d", n);
static int n = 3;
printf ("% d", n);
while (n -)
{
printf ("% d", n);
int n = 10;
printf ("% d", n);
printf ("% d",:: n + n);
}
}

5.2 Працюємо з адресами

У деякої програми в моделі large при роботі в відладчик регістри містять такі значення:
CS = 1ADF, DS = 1AE3, SS = 1B26, SP = 0FD2.
Знайдіть розміри областей пам'яті.
Вкажіть діапазони можливих адрес для:
змінної int n = 2, якщо вона а) глобальна, б) статична, в) локальна;
вмісту покажчика char * str = "Hello";
значення адресної константи main;
вмісту покажчика int * A = (int *) malloc (1000).

5.3 Прототипи функцій

5.3.1 Свопінг

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

5.3.2 Індекси максимальних елементів одновимірного масиву

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

5.3.3 Індекси максимальних елементів двовимірного масиву

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

5.3.4 Кут між двома векторами

Напишіть прототип функції, яка знаходить кут у радіанах між двома векторами з простору R n.

5.3.5 Визначник матриці

Напишіть прототип функції, яка знаходить визначник квадратної матриці з розмірами nxn.

5.4 Виділення фрагмента програми в окрему функцію

Розбивка програми на функції
# Include <stdio. h>
void main ()
{
int a, b, div, mod;
printf ("Введіть два цілих числа");
scanf ("% d% d", & a, & b);
div = a / b;
mod = a% b;
printf ("\ n% d /% d =% d", a, b, div);
printf ("\ n% d%%% d =% d", a, b, mod);
}
Виділіть у три окремих функції фрагменти, пов'язані з введенням даних, з обчисленнями і з організацією виводу результатів. Обчислювальна функція повинна бути одна. Глобальні змінні не використовувати.

5.5 Тестування функції

5.5.1 Сортування масиву

Наступний прототип функції сортує масив А розміром n за зростанням на місці оригінального масиву void sort (int A [], int n);
Напишіть тест цієї функції для трьох різних варіантів вихідних даних.

5.5.2 МініМакс

Функція знаходить мінімальне та максимальне з двох чисел типу int і має прототип
void MinMax (int a, int b, int * pmin, int * pmax);
Напишіть тест для цієї функції.

6. Лабораторні завдання

6.1 Лінійне рівняння

Написати функцію, яка вирішує лінійне рівняння a ∙ x + b = 0 з перевіркою виходу за діапазон типу float. Прототип функції
int linur (float a, float b, float * px);
Функція отримує: a і b - коефіцієнти рівняння, px - покажчик на клітинку, в яку буде поміщений єдиний корінь рівняння.
Функція повертає:
0 - немає рішення,
1 - знайдено єдине рішення,
2 - будь-яке число є рішенням,
3 - рішення єдине, але не входить в діапазон типу змінної x.
Висновок текстової інформації з результатами вирішення організувати з використанням оператора switch. Вихід з програми повинен бути єдиним. Організувати тестування функції linur.

6.2 Парні елементи масиву

Напишіть функцію, яка знаходить всі парні елементи одновимірного масиву елементів типу int. Організувати тестування функції.
Прототип функції
int Chot (int A [], int DimA, int FoundA []);

6.3 Знаходження простих чисел

Напишіть функцію, яка знаходить всі прості числа і їх кількість до long N включно. Натуральне число m> 1 називається простим, якщо воно ділиться тільки на 1 і на саме себе. Організувати тестування функції.
Прототип функції.
long AllProst (long N, long Prost [], int DimProst, int * flag);

6.4 Кількість входжень підрядка в рядок

Напишіть функцію, яка визначає кількість входжень підрядка в рядок. Організувати тестування функції.
Прототип функції
int NumStrStr (char * str, char * substr);

6.5 Твір матриць

Напишіть функцію, яка знаходить добуток двох прямокутних матриць з узгодженими розмірами. Організувати тестування функції.
Прототип функції
void MMult (float A [], float B [], float AB [], int m, int n, int k);
Тут одномірні масиви емулюють двовимірні масиви.

7. Додаткові завдання

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

Бібліографічний список

1. Керніган Б. Мова програмування Сі / Б. Керніган, Д. Рітчі. СПб.: Невський діалект, 2001.352 с.
2. Подбельський В.В. Програмування на мові Сі / В.В. Подбельський, С.С. Фомін. М.: Фінанси і статистика, 2004.600 с.
3. Програмування в Сі. Організація вводу-виводу: метод. вказівки / сост. С.П. Трофімов. Єкатеринбург: УГТУ, 1998.14 с.
4. Програмування в Сі. Динамічний розподіл пам'яті: метод. вказівки / сост. С.П. Трофімов. Єкатеринбург: УГТУ, 1998.13 с.
Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Лабораторна робота
51.7кб. | скачати


Схожі роботи:
Модульне програмування 2
Модульне програмування Turbo Pascal
Основні поняття математичного програмування Побудова моделі задачі лінійного програмування
Програмування мовою С з використанням об єктно орієнтованого програмування
Програмування мовою С з використанням обєктно-орієнтованого програмування
Програмування
Програмування в СІ
Програмування
Програмування інтерфейсу
© Усі права захищені
написати до нас