You are on page 1of 26

Міністерство освіти i науки України

Одеський національний політехнічний університет

МЕТОДИЧНІ ВКАЗІВКИ
ДО ПРАКТИЧНИХ ЗАНЯТЬ
З ДИСЦИПЛІНИ
«Основи програмування»
для студентів денної форми навчання
спеціальності 121 – «Інженерія програмного забезпечення»

ОНПУ
ОДЕСА 2022
2
Міністерство освіти i науки України
Одеський національний політехнічний університет

МЕТОДИЧНІ ВКАЗІВКИ
ДО ПРАКТИЧНИХ ЗАНЯТЬ
З ДИСЦИПЛІНИ
«Основи програмування»
для студентів денної форми навчання
спеціальності 121 – «Інженерія програмного забезпечення»

Затверджено
на засіданні кафедри
системного програмного забезпечення
Протокол № від .2022 р.

ОНПУ
ОДЕСА 2022
3
Методичні вказівки до практичних занять з дисципліни “Основи програмування” для
студентів спеціальності 121 – «Інженерія програмного забезпечення» /Укл.: Н.О.Комлева,
Л.С.Жиро. – Одеса: ОНПУ, 2022. – 26 с.

Укладачі Н.О. Комлева, доц.


Л.С. Жиро, ас.
4
ВСТУП

Методичні вказівки й завдання до практичних занять підготовлені відповідно до програми


курсу “Основи програмування”, що вивчається студентами спеціальності 121 – «Інженерія
програмного забезпечення».
Методичні вказівки містять теоретичні питання і завдання по наступним темам: основні
програмні функції та етапи розробки програми, прості оператори та стандартні функції, умовний
оператор, оператори форматованого вводу/виводу, робота зі структурами, оператори циклу з
параметрами та без параметрів, одновимірні й двовимірні статичні та динамічні масиви робота з
власними функціями, робота з файлами. Теоретичні питання постачені ключовими підказками, для
завдань приводиться їхній розв'язок мовою програмування С.
Для полегшення виконання завдань наприкінці методичних вказівок наведений список
рекомендованої літератури.
5
Тема 1. Основні програмні терміни та етапи розробки програм

Теоретичні питання:
1. Привести класифікацію мов програмування.
2. Структура програм мовою C.
3. Алфавіт мови програмування (МП) C.
4. Засоби опису синтаксису мови.

Програмування - це один із способів відображення реального світу в термінах, зрозумілих


комп'ютеру. Мова програмування - це набір правил, що визначають, які послідовності символів
складають програму і яке обчислення описує програма.
 На першому етапі створення програми мови програмування можна розрізняти за способами,
якими вони дають можливість окреслити завдання.
Програмісти пишуть програми на різних ЯП, деякі з яких безпосередньо зрозумілі
комп'ютеру, а інші потребують проміжних стадіях обробки. Сотні наявних мов можуть бути
розділені на 2 категорії: машинно-залежні мови і машинно-незалежні мови.

Мови програмування

Маш-залеж. мови Маш-незалеж. мови

Маш. код Ассемблер Процедурно- Об’ектно-


орієнтовані мови орієнтировані
мови

Кожен комп'ютер може розуміти тільки свій машинний мову (код), який є природною мовою
конкретного комп'ютера і тісно пов'язаний з його апаратною частиною. Машинні мови в загальному
випадку складаються з послідовностей чисел (зазвичай нулів і одиниць), які є командами на
виконання одиночних елементарних операцій. Вони незручні для сприйняття людиною і
уповільнюють розробку програм.
Замість послідовностей чисел, безпосередньо зрозумілих комп'ютера, програмісти для
подання елементарних операцій стали застосовувати англомовні абревіатури, які сформували
основу мов асемблера. Для перетворення програм, написаних на таких мовах, в машинну мову були
розроблені програми-транслятори.
Для прискорення процесу програмування були розроблені мови високого рівня, машинно-
незалежні, в яких для виконання складних дій досить написати один оператор. Програми для
перетворення послідовності операторів на мові високого рівня в машинний мову називаються
компіляторами.
Об'єктно-орієнтовані мови дозволяють уявити завдання у вигляді набору взаємодіючих між
собою об'єктів.
Процедурно-орієнтовані мови розроблені для структурного програмування. Такі мови
представляють завдання у вигляді набору процедур (функцій), тобто це закінчених послідовностей
дій над будь-якими даними. Наприклад, програму, яка обчислює A + B можна представити у
вигляді набору трьох процедур:
а) приймає дані (А і В) (з клавіатури, з файлу, з голосу);
б) складає А і В;
в) видає результат (на екран, у файл, на принтер).
Для побудови програми необхідно визначити алгоритм її роботи. Алгоритм складається з
функціонально закінчених блоків, кожен з яких відповідає за виконання певної процедури.
6
Основи структурного програмування.
1. Алгоритми повинні складатися по етапах.
2. Складні частини розбиваються на прості, кожна з яких має тільки 1 вхід і 1 вихід.
3. Логіка алгоритму і програми повинні спиратися на обмежену кількість базових структур.
Завдання будь-якої складності може бути представлена схемою з обмеженим числом керуючих
структур, які можуть об'єднуватися між собою, утворюючи більш складні структури з тих же самих
схемами, що і базові структури.
До процедурно-орієнтованим мовам відносяться, наприклад С, Паскаль, Ада, Бейсік. Пізніше
кожен з них обзавівся своєю об'єктно-орієнтованої налаштуванням сумісної з процедурно-
орієнтованої версією.

Стадії розробки програми.


Після отримання завдання на розробку першим кроком в написанні програми є розробка
алгоритму рішення. Потім записується алгоритм з використанням синтаксису мови програмування.
Отримані файли зберігаєте з ім'ям myprog1.cpp, якщо працюєте в середовищі С ++ або myprog2.pas
в середовищі Паскаль. Потім компілюєте програму з метою виявлення синтаксичних (порушення
правил мови) і семантичних (смислових) помилок. Виправивши всі помилки, зазначені
компілятором, Ви повинні в результаті компіляції отримати файл з тим же ім'ям, що вихідна
програма і розширенням obj, тобто myprog1.obj або myprog2.obj. Це об'єктний модуль, який містить
команди в машинному коді для конкретного комп'ютера. Потім запускаєте компоновщик, або
редактор зв'язків, який перетворює файл з розширенням obj в завантажувальний модуль - файл з
розширенням exe, тобто myprog1.exe або myprog2.exe. При цьому збираються об'єктні файли
окремих компонентів програми і вирішуються зовнішні посилання від одного компонента до
іншого. Завантажувальний модуль являє собою машинний код, тобто послідовність одиниць і нулів,
і не потребує для запуску в наявності встановленої на комп'ютері середовища програмування.

Алфавіт - сукупність допустимих в мові символів (або груп символів розглядаються як


єдине ціле). У мові С всі компоненти формуються з безлічі символів стандарту ASCII, які задаються
кодами від 0 до 255.
Елементи алфавіту можна умовно розбити на 4 групи:
1) символи, використовувані в ідентифікаторах;
2) роздільники;
3) спеціальні символи;
4) символи, які використовуються тільки в рядках символів і коментарях.

Способи опису мов програмування. Синтаксичні діаграми.


Синтаксис мови визначається правилами побудови його мовних конструкцій. Серед
найбільш поширених способів відомі форма Бекуса і синтаксичні діаграми. Склад синтаксичних
діаграм:
─ синтаксична змінна
─ синтаксична константа
─ з'єднання змінних і констант.
7
Тема 2. Прості оператори та стандартні функції. Форматований ввід та вивід

Теоретичні питання:
1. Пріоритет операцій у виразу.
2. Приведення типів даних.
3. Прості оператори.
4. Стандартні функції.
5. Форматований ввід та вивід.

Завдання.
1. Обчислити значення функції y=a*x+b2-3, цілі значення a, x, b уводити із клавіатури. Скласти
програми на МП C.

2. Обчислити значення функції , змінні a і b мають цілий тип, змінна c –

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

Ключі до відповідей.
Теорія.
Функція printf()
Функція printf() є функцією стандартного виводу. За допомогою цієї функції можна вивести на
екран монітора рядок символів, число, значення змінної. Функція printf() повертає число виведених
символів у разі успіху або від'ємне значення у випадку помилки.
Прототип функції printf():
int printf(const char * керуючий рядок, ...);
Керуючий рядок складається з елементів двох видів. Перший з них – це символи, які
належить вивести на екран; другий – це специфікатори перетворення, які визначають спосіб
виведення наступних аргументів. Кожен такий специфікатор починається із символу %, за яким йде
код формату. Наступні параметри – змінні, значення яких необхідно вивести.
Рядок формату читається зліва направо. Коли зустрічається перша специфікація формату (якщо
вона є), то значення першого аргументу після рядка формату перетворюється і виводиться згідно
заданої специфікації. Друга специфікація формату викликає перетворення та виведення другого
аргументу і так далі, до кінця рядка формату.
Якщо аргументів більше, ніж специфікацій формату, то ці додаткові аргументи ігноруються.
Результат є невизначеним, якщо аргументів недостатньо для всіх специфікаций формату.
Найпростіша специфікація формату містить тільки символ знака процента і символ типу.
Деякі специфікатори формату
%с символ
%d або %і ціле десяткове число
%f або %F десяткове число з плаваючою комою xx.xxxx
%u десяткове ціле без знака
%s рядок символів
%% символ %
%p покажчик
%е або %Е експоненціальне подання (‘e’ – на нижньому регістрі, ‘E’) – на верхньому
%х або %Х шістнадцяткове без знака (літери на нижньому або на верхньому регістрі)
%p виводить покажчик
%o восьмеричне без знака
%g або %G залежно від того, який вивід буде коротшим, використовується %е або %f (%Е
або %F)
Крім того, до команд формату можуть бути застосовані деякі модифікатори.
Модифікатори l і h
%ld друк long int
8
%hd друк short int
%lf друк double
Крім того, у багатьох специфікаторах перетворення можна додатково вказати модифікатори,
які злегка міняють їх значення. Наприклад, можна вказувати мінімальну ширину поля, кількість
десяткових розрядів і вирівнювання по лівому краю. Модифікатор формату поміщають між знаком
відсотка і кодом формату.
Модифікатори мінімальної ширини поля
Ціле число, розташоване між знаком % і кодом формату, грає роль модифікатора мінімальної
ширини поля. Якщо вказаний модифікатор мінімальної ширини поля, то для того, щоб ширина поля
виводу була не меншою зазначеної мінімальної довжини, при необхідності вивід буде доповнений
пробілами. Якщо ж виводяться рядки або числа, які довше зазначеного мінімуму, то вони все одно
будуть відображатися повністю. За замовчуванням для доповнення використовуються пробіли. А
якщо для цього треба використовувати нулі, то перед модифікатором ширини поля слід помістити 0.
Наприклад , %05d означає, що будь-яке число, кількість цифр якого менше п'яти, буде доповнено
такою кількістю нулів, щоб число складалося з п'яти цифр.

Функція scanf()
Функція scanf() – функція форматованого вводу. З її допомогою можна вводити дані зі стандартного
пристрою вводу (з клавіатури). Такими даними можуть бути цілі числа, числа з плаваючою комою,
символи, рядки і покажчики. При введенні чисел роздільниками можуть бути символи пробілу,
табуляції або нового рядка.
Прототип функции scanf(): int scanf(const char * керуючий рядок, …)
Все сказане для функції printf() можна застосувати і до scаnf(). Перший параметр – рядок зі
специфікаторами формату, наступні – змінні, куди будуть записані введені значення. Слід звернути
увагу на те, що передавати змінні-параметри в функцію scanf() необхідно за адресою, тобто перед
ідентифікатором змінної ставити символ & (наприклад scanf ("%d", &x);). Детальніше про передачу
параметрів у функцію за адресою буде сказано далі.
Функція scanf() повертає число змінних, яким було присвоєно значення.

Завдання.
1. #include <stdio.h>
#include <math.h>
void main() {
int a,x,b;
float y;
printf(”\n Уведіть значення змінних a, x, b:”);
scanf(“%d%d%d”, &a, &x, &b);
y=a*x+sqr(b)-3;
printf(”\nЗначение у=%f”, y);
}

2. #include <stdio.h>
#include <math.h>
void main() {
int a,b;
float y,c,t1,t2;
scanf(“%d%d%f”, &a, &b, &c);
t1=sqrt(b/c);
t2=pow((20-a),3);
y=2*a/t1+t2;
printf(“%f”, y);}
9
Тема 3. Умовний оператор

Теоретичні питання:
1. Умовний оператор МП C.
2. Вкладення умовних операторів.
3. Перевірка значень змінних на коректність за допомогою умовного оператора.

Завдання.
1. Обчислити значення функції по формулі:

Скласти програми на МП C.
2. Вивести на екран максимальне зі значень для двох функцій:

.
Скласти програму на МП C.
3. Вирішити квадратне рівняння. Скласти програму на МП C.

Ключі до відповідей.
Теорія.
1. Існує два варіанти оператора:
if S A і if S A;
else B;
S – деяке логічне вираження істинність якого перевіряється;
А – оператор, який виконується, якщо вираження S істинно;
B – оператор, який виконується, якщо вираження S неправильно;
У другому випадку, якщо умова S невірна, не виконується ніяких дій.
2. if S1 A else
if S2 B
else C

Завдання.
1.
#include <stdio.h>
#include <math.h>
void main() {
int a,b,y;
scanf(“%d%d”, &a, &b);
if (a>b) y=2-a+b;
else
if (b>a) y=-b+2*a;
else y=sqr(a)+sqr(b);
printf(“%d”, y);
10
}

2.
#include <stdio.h>
#include <math.h>
void main() {
int x;
float y1,y2;
scanf(“%d”, &x);
y1=5*x+2*sin(x);
y2=tan(x)-3*sqr(x);
if (y1>y2) printf(“%f”, y1);
else printf(“%f”, y2);
}

3.
#include <stdio.h>
#include <math.h>

void main() {
float x1, x2, D;
int a, b, c;
printf("Input parametres (a, b, c) for equation a*x^2 + bx + c = 0\n");
scanf("%d%d%d", &a, &b, &c);

D=b*b-4*a*c;
if (D<0) printf("No real roots\n"); // якщо дискримінант
// менше нуля, коренів немає
else if(D>0) { // якщо дискримінант більше нуля, 2 кореня
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
printf("Equation has 2 roots:\nx1 = %f\nx2 = %f\n", x1, x2);
}
else { // якщо дискримінант дорівнює нулю, 1 корінь x1 = (-b/2*a);
printf("Equation has 1 root:\nx = %f\n", x1);
}
}
11
Тема 4. Оператори циклів

Теоретичні питання:
1. Оператор циклу з параметром МП C.
2. Оператор циклу із передумовою МП С.
3. Оператор циклу з постумовою МП С.
4. Обчислення математичних функцій на заданому діапазоні та організація меню користувача
за допомогою циклів.

Задачі.
1. Увести із клавіатури 20 цілих чисел. Обчислити їхню суму й вивести її на екран. Скласти
програми на МП C.
2. Увести із клавіатури задане користувачем кількість дробових чисел. Підрахувати число
позитивних, негативних і нульових значень. Скласти програму на МП C.
1. Увести із клавіатури послідовність цілих чисел до введення першого нуля. Обчислити середнє
арифметичне значення введеної послідовності. Скласти програму на МП C.
2. Обчислити суму убутних членів ряду доти, поки член ряду лежить у межах заданої погрішності.
, 0<x<1
Використовувати оператори з передумовою і постумовою. Скласти програму на МП C.

Ключі до відповідей.
Теорія.
1. Стандартний вид циклу for для мови С наступний:
for (ініціалізація; умова; збільшення)
оператор;
1. ініціалізація- установка початкового значення змінної циклу;
2. умова – вираження, що визначає умова роботи циклу;
3. збільшення- характер зміни змінної циклу на кожній ітерації.
Цикл for працює доти, поки умова дійсна. Коли умова стає неправильним, виконання триває з
оператора, що випливає за циклом for .

2. Стандартний вид циклу із передумовою наступний


while (умова)оператор;

де оператор – це або порожній або складений оператор. Умовою може бути будь-яке вираження, що
має в якості істини ненульове значення.
3. Стандартний вид циклу do/while наступний:
do{
послідовність операторів;
} while (умова);
12

Задачі.
1.
#include <stdio.h>
const n=20;
void main() {
int i,x,sum=0;
for (i=0;i<n;i++) {
scanf(“%d”, &x);
sum+=x;
}
printf(sum;
}

2.
#include <stdio.h>
void main() {
int i,x,n,k1,k2,k3;
printf(”Уведіть кількість чисел: “;
scanf(“%d”, &n);
k1=k2=k3=0;
for (i=0; i<n; i++) {
scanf(“%d”, &x);
if (x>0) k1++;
if (x<0) k2++;
if (x==0) k3++;
};
printf(”\n Кількість позитивних чисел = %d“, k1);
printf(”\nКількість негативних чисел = %d“, k2);
printf(”\nКількість нульових чисел = %d“, k3);
}

3.
#include <stdio.h>
void main() {
int sum=0,i=1,x;
float sr;
scanf(“%d”, &x);
while (x!=0) {
sum+=x;
scanf(“%d”, &x);
i++;
}
sr=(float)sum/i;
printf(“%f”, sr);
}

4. Використання циклу з передумовою


#include <stdio.h>
#include <conio.h>
#include <math.h>
13
void main()
{
float s,sn,x,e,ch;
int j,fact,znak;
printf("\nInput x,e: ");
scanf((“%f%f”, &x, &e);
s=x; j=2;
fact=1;
ch=pow(x,2);
znak=1;
sn=ch/(j*fact*j)*znak;
while (fabs(sn)>e) {
s+=sn;
printf(“\n%f %f”, sn, s);
ch*=x;
fact*=j;
j++;
znak*=(-1);
sn=ch/(j*fact*j)*znak;
}
printf("\nS=%6.2f", s);
getch();
}

Використання циклу з постумовою


#include <stdio.h>
#include <conio.h>
#include <math.h>
void main() {
float s,sn,x,e,ch;
int j,fact,znak;
printf("\nInput x,e: ");
scanf((“%f%f”, &x, &e);
s=x;
j=2;
fact=1;
ch=pow(x,2);
znak=1;
do {sn=ch/(j*fact*j)*znak;
ch*=x;
fact*=j;
j++;
znak*=(-1);
s+=sn;
printf(“\n%f %f”, sn, s);
}while (fabs(sn)>e)
printf("\nS=%6.2f", s);
getch();
}
14
Тема 5. Одновимірні та двовимірні статичні та динамічні масиви

Теоретичні питання:
1. Поняття масиву.
2. Доступ до елементів масиву. Складання програм із застосуванням одновимірних та двовимірних
масивів.
3. Ініаціалізація масивів, обробка значень їх елементів.
4. Вивід значень елементів масиву у вигляді послідовності.

Задачі.
1. Задати масив з 10 цілих чисел. Замінити всі позитивні елементи масиву на останній негативний
елемент. Скласти програми на МП С.
2. Із двох масивів сформувати третій, дані в якім будуть розташовуватися в упорядкованому виді.
Скласти програми на МП С.
3. У масиві 5х5 цілих чисел поміняти місцями рядки, що містять найбільший і найменший елементи
масиву. Скласти програми на МП С.
4. Для матриці 10х10 визначити, чи є вона симетричної щодо головної діагоналі.

Ключі до відповідей.
Теорія.
1. Масив – це впорядкований набір змінних одного типу. Масиви містять фіксоване число
компонентів, яке задається при визначенні змінних типу масиву.
2. Для звертання до елемента масиву використовується вид: ім'я масиву[індекс]. Індекс задає місце
елемента в масиві. Обмежень на кількість індексів немає. Для доступу до елемента двовимірного
масиву необхідно вказати індекси рядка і стовпця, на перетинанні яких розташований шуканий
елемент.
3. Стандартний вид одновимірного масиву наступний:
тип ім'я_змінної [розмір];
тип – базовий тип;
розмір – визначає кількість елементів масиву.
В одномірному масиві повний розмір масиву в байтах:
загальне_число_в _байтах=sizeof(тип)* число елементів
Синтаксис для оголошення масиву mas дійсних чисел з 10 рядків і 8 стовпців: float mas[10][8];
4. Для виводу значень елементів одновимірного масиву потрібно перебрати їх за допомогою циклу
з параметром, значення параметру використовувати у якості індексу елементу масиву.
Для виводу значень елементів двовимірного масиву потрібно перебрати їх за допомогою подвійного
циклу з параметром, при цьому значення параметру зовнішнього циклу зіставляється з номером
рядка (перший індекс двовимірного масиву), а значення параметру внутрішнього циклу
зіставляється з номером стовпця (другий індекс двовимірного масиву).

Задачі.
1.
#include <stdio.h>
#include <conio.h>
void main() {
const n=10;
int x[n],i,neg;
printf("\nInput "<<n<<" elements of array: ";
for (i=0;i<n;i++) scanf(x[i];

for (i=0;i<n;i++)
if (x[i]<0) neg=x[i];
for (i=0;i<n;i++) { if (x[i]>0) x[i]=neg;
printf(x[i]<<' ';
15
}
getch();
}

2.
#include <stdio.h>
#include <conio.h>
void main() {
const m=10,n=8;
int a[m],b[n],c[m+n],i,j,k;

printf("\nInput "<<m<<" elements of array a: ";


for (i=0;i<m;i++) scanf(“%d”, &a[i]);

printf("\nInput "<<n<<" elements of array b: ";


for (i=0;i<n;i++) scanf(“%d”, &b[i]);

i=j=0;
for (k=0;k<m+n;k++) {
if (((a[i]<=b[j])&&(i<m))|| (j>=n))
{
c[k]=a[i];
i++;
}

else if (((b[j]<a[i])&&(j<n))||(i>=m)) { c[k]=b[j];


j++;
}
}

for (k=0;k<m+n;k++) printf(“%d ”, c[k]);


getch();
}

3.
#include <stdio.h>
#include <conio.h>
void main() {
const n=5;
int mas[n][n],i,j,min,max,imin,imax,temp;
printf("\nInput elements of matrix: ";
for (i=0;i<n;i++)
for (j=0;j<n;j++) scanf(“%d”, &mas[i][j]);

for (i=0;i<n;i++) {
for (j=0;j<n;j++) printf(“%d”, mas[i][j]);
printf('\n'; }

min=max=mas[0][0];
for (i=0;i<n;i++)
for (j=0;j<n;j++) {
if (mas[i][j]<min) { min=mas[i][j];
imin=i;
}
16
if (mas[i][j]>max) { max=mas[i][j];
imax=i;
}
}

for (j=0;j<n;j++) { temp=mas[imin][j];


mas[imin][j]=mas[imax][j];
mas[imax][j]=temp;
}
printf(“\n”);
for (i=0;i<n;i++) {
for (j=0;j<n;j++) printf(“%d ”, mas[i][j]);
printf('\n'; }
getch();
}

4.
#include <stdio.h>
#include <conio.h>
void main() {
const n=10;
int mas[n][n],i,j,flag=1;
for (i=0;i<n;i++)
for (j=0;j<n;j++) scanf(“%d”, &mas[i][j]);

for (i=0;i<n;i++) {
for (j=0;j<n;j++) printf(“%d ”, mas[i][j]);
printf('\n'; }

for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (mas[i][j]!=mas[j][i]) flag=0;

if (flag) printf("\nMatrix is symmetric");


else printf("\nMatrix is not symmetric");
getch();
}
17
Тема 6. Роботи зі структурами

Теоретичні питання:
3. Поняття структурованих типів даних.
4. Структури в МП С.
5. Ввід/вивід, корекція та аналіз елементів структур

Задачі.
1. Створити дві структури типу "товар", про кожну з яких відомі такі дані: вартість, рік
виробництва. Вивести дані про товар, у якої найбільш пізній рік виробництва.

Ключі до відповідей.
Теорія.
1. Структуровані типи даних представляють сукупності значень, тобто одна змінна містить кілька
значень. Структури в мові С – це похідні типи даних, вони створюються з об'єктів інших типів. З
використанням структур зручно описувати об'єкти реального світу, що мають властивості різних
типів (цілі, дійсні, масиви й ін.). Елементами структури можуть бути дані будь-якого типу,
включаючи і інші структури, а також покажчик на ту ж саму структуру.

2.
Перш ніж зі структурою можна буде працювати, необхідно описати її, для чого необхідно визначити
так називаний структурний шаблон:
struct struct_tag
{
type1 іtem1;
type2 іtem2;
...
typeN іtemN;
};
Ключове слово struct визначає, що все, що стоїть за ним є структурою. Далі йде ім'я типу структури
struct_tag, називаної також тегом. Воно ідентифікує структуру для того, щоб можна було
створювати перемінні цього типу. Саме "зміст" структури (її елементи) укладено у фігурні дужки.
Однак шаблон у представленому виді не створює змінної. Для її визначення необхідно записати
struct struct_type structVariable;
У цьому описі struct struct_type грає ту ж роль, що іnt чи float у відповідних описах.
Ще одним способом створення змінної структурного типу є сполучення опису шаблона і визначення
змінних:
struct struct_tag
{
type1 item1;
type2 item2;

typeN itemN;
} structVariable1, structVariable2;
Якщо не передбачається створення додаткових змінних, то ім'я типу структури struct_tag можна
опустити:
struct
{
type1 item1;
type2 item2;

typeN itemN;
} structVariable1, structVariable2;
18
Полем структури може бути інша структура (вкладена). У цьому випадку спочатку повинна бути
описана вкладена структура, а потім основна:
struct struct_tag_inside
{
type1 іtem1_inside;
type2 іtem2_inside;
...
typeN іtemN_inside;
};
struct struct_tag
{
type1 іtem1;
type2 іtem2;
...
struct_tag_inside item_inside
...
typeN іtemN;
} element;
У цьому випадку для доступу до поля іtem1_іnsіde структури іtem_іnsіde необхідно вказати:
element. item_inside. іtem1_inside

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

Задачі.
1.
#include <stdio.h>
void main() {
struct tovar
{
float cost;
int year;
};
tovar b1,b2;
printf("\nInput information for tovar 1: ");
scanf(“%f%d”, &b1.cost, &b1.year);
printf("\nInput information for tovar 2: ");
scanf(“%f%d”, &b2.cost, &b2.year);

if (b1.year>b2.year)
printf(“%f%d”, b1.cost, b1.year);
else
if (b2.year>b1.year)
printf(“%f%d”, b2.cost, b2.year);
else printf("Are equal");
}
19
Тема 7. Робота з власними функціями

Теоретичні питання:
1. Поняття підпрограми.
2. Підпрограми в МП С.

Задачі.
1. Написати програму з функцією, що визначає максимальне з трьох чисел.
2. Увести з клавіатури число і перевернути в ньому цифри навпаки.
3. З матриці 5х5 скласти одномірний масив, що містить мінімальні значення по кожному рядкові.
Скласти програму на ЯП С.

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

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

Задачі.
1.
#include <stdio.h>
int maximum (int,int,int); // прототип функції
void main()
{
int a,b,c;
printf(”Enter three integers: ”);
scanf(“%d%d%d”, &a, &b, &c);
printf(”Maximum is: %d”, maximum(a,b,c));
}
// Визначення функції maximum
int maximum (int x, int y, int z)
{
int max=x;
20
if (y>max) max=y;
if (z>max) max=z;
return max;
}
2.
#include <stdio.h>
void invers(int &x);
void main()
{
int number;
scanf("%d", &number);
invers(number);
printf("\n%d", number);
}

void invers(int &x)


{
int y=0, n;
n = x%10;
while (n!=0)
{
y = y*10+n;
x = (x-n)/10;
n = x%10;
}
x = y;
}

3.
#include <stdio.h>
#include <conio.h>
int a[5][5],b[5];
int i,j;
int find_min(int);
void main() {
for (i=0;i<5;i++)
for (j=0;j<5;j++) scanf(“%d”, &a[i][j]);
for (i=0;i<5;i++) {
for (j=0;j<5;j++) printf(“%d “, a[i][j]);
printf(“\n”);
}
for (i=0;i<5;i++) {
b[i]=find_min(i);
printf(“%d “, b[i]);
}
getch();
}
int find_min (int x) {
int min=1000;
for (j=0;j<5;j++)
if (a[x][j]<min) min=a[x][j];
return min;
}
21
Тема 8. Робота з файлами

Теоретичні питання:
1. Створення, читання та запис у бінарні та текстові файли даних.
2. Переміщення файлового показника.
3. Закриття файлів.

Задачі.
1. У бінарний файл записати випадковий набір чисел, потім ці числа переписати в текстовий файл.
2. Створити файл test.txt, що розміщується в корневій папці диску D. Зчитати з клавіатури рядок і
вмістити його у файл. Потім дані з файлу зчитати, поки не буде досягнутий кінець файлу. Зчитані
дані, їх коди і звіт про роботу вивести на консоль.
3. Сформувати масив з даними виду: прізвище студента, номер курсу. Занести ці дані в бінарний
файл. Зчитати дані з бінарного файлу, вибрати студентів, які навчаються на заданому курсі.
Інформацію про цих студентів занести в текстовий файл, використовуючи функції форматованого
виводу у файл.

Ключі до відповідей.
Теорія.
1. Файли даних – обов'язковий елемент практично будь-якої програмної системи. Вони
використовуються як вихідні дані для розв’язання різних задач, а також можуть бути результатами
роботи програм. Особливість цього структурованого типу даних у тому, що інформація звичайно
знаходиться на дисках, а не в оперативній пам'яті. Тому розміри файлів можуть бути практично
необмеженими.
Оскільки доступ до дисків виконується значно повільніше ніж до оперативної пам'яті,
звичайно при роботі з файлами в пам'яті створюються буфери, у які копіюється з диска або
накопичується в результаті роботи програми інформація. Ця інформація при вичерпанні або
заповненні буфера обновляється або записується на диск.
Для відкриття файлів використовується функція fopen, яка приймає два параметри. Перший –
це ім'я файлу, другий – режим роботи з файлом, в якому він буде відкритий. Ця функція повертає
покажчик на структуру FILE (дескриптор файлу), який необхідно присвоїти створеному нами
вказівником.
Існують різні режими відкриття файлу:
 Режим запису даних "w" – покажчик поточної позиції встановлюється на початок файлу,
якщо зазначений у функції fopen() файл не існує, то він створюється. Необхідно пам'ятати, що
відкриття існуючого файлу в режимі "w" призводить до знищення його старого змісту.
 Режим читання даних "r" – можливий тільки для створеного раніше файлу, при цьому
покажчик поточної позиції встановлюється на початок файлу. Якщо відкривається на читання файл
не існує, функція fopen() повертає порожній покажчик зі значенням NULL.
 Режим додавання даних "a" – покажчик поточної позиції встановлюється на кінець файлу.
Дані, раніше поміщені у файл, залишаються без змін. Якщо вказується неіснуючий файл, то він
створюється заново.
Також можна вказати додаткові умови режиму відкриття файлу:
"b" – двійковий потік;
"t" – текстовий потік;
"+" – оновлення файлу.
У мові С розрізняють два способи введення-виводу у файл – форматований і
неформатований. При форматованому введенні зчитується одна або кілька змінних певного типу,
при неформатованому – зчитується задана кількість байт. Функціями неформатованого введення-
виведення є fwrite() і fread(), використовувані для читання і запису відповідно. Як аргумент їм
передається адреса записуваної або зчитуваної величини, розмір одного екземпляру, кількість
зчитувальних величин та ім'я логічного файлу. Вони визначається як
int fwrite(const char * array, size_t size, size_t count, FILE * stream);
int fread(const char * array, size_t size, size_t count, FILE * stream);
22

Для форматованого введення-виведення у файл використовуються функції fscanf() і fprintf()


аналогічні відповідним функціям форматованого введення-виведення, проте виконують це стосовно
до файлу, відповідно їх першим параметром є покажчик на файл.
int fprintf (FILE * fp, const char * theString, …);
int fscanf (FILE * fp, const char * theString, …);

2. Прикладна програма, що працює з файлами, не управляє процесом обміну даних з


файлом. Після кожного читання або запису покажчик файла (адреса, за якою читається або
записується інформація) переміщається на новий запис – порцію даних, котрими здійснюється
обмін. Навіть із коротких зауважень про файли випливає, що це повинен бути спеціальний і досить
складний тип даних.
int fseek (FILE * fp, long int offset, int beginning) – встановлює курсор на заданий байт файлу.
Призначення цієї функції - підтримувати операції введення/виводу з довільним доступом.
Параметр offset вказує кількість байтів, на яку слід перемістити курсор файлу від точки, заданої
параметром beginning, який задається макросами SEEK_SET (початок файлу), SEEK_CUR (поточна
позиція), SEEK_END (кінець файлу). Повертання нульового значення свідчить про успішне
виконання функції fseek(), а ненульового – про виникнення збою.
void rewind (FILE * fp) – встановлює курсор на початок файлу.
3. Якщо робота з файлом даних завершується за допомогою спеціальної команди, то дані з
буфера вивіду записуються у файл. Якщо такої команди нема, а завершується робота програми, то
буфер знищується без збереження даних у файлі.
Функція fclose() закриває потік, відкритий раніше функцією fopen(). Вона записує всі дані,
що залишилися в буфері, у файл і закриває його, використовуючи команди операційної системи.
Помилка, що виникла при закритті файлу, може породити безліч проблем, починаючи з втрати
даних і руйнування файлів і закінчуючи непередбачуваними наслідками для програми. Крім того,
функція fclose() звільняє керуючий блок файлу, пов'язаного з потоком, дозволяючи використовувати
цей блок повторно. Операційна система обмежує кількість одночасно відкритих файлів, тому перш
ніж відкрити один файл, слід закрити інший.
Прототип функції fclose() виглядає наступним чином:
int fclose(FILE * fp)
Якщо функція повернула нульовий покажчик, значить, файл відкритий успішно, значення
EOF є ознакою помилки.

Задачі
1.
#include <stdio.h>
#include <assert.h>

int main(void)
{
FILE * binaryFile;
binaryFile = fopen("file.bin", "wb"); // створення бінарного файлу

int numbOfItems;
char boofer;

printf ("Input symbols: ");


while ((boofer=getchar())!=EOF)//зчитуємо файли до EOF
fputc(boofer, binaryFile);
fclose(binaryFile); // закриваємо і зберігаємо файл

if ((binaryFile = fopen("file.bin", "rb")) == NULL)


{ // виконуємо перевірку відкриття файлу
23
printf ("Error opening the file");
return 1;
}

char charArray[255] = { }; // створюємо масив символів, ініціалізуємо його порожнім


символом
int i;

// зчитуємо символи з файлу. Умовою виходу є повернення fread () символу EOF


for ( i = 0; fread ( &charArray[i], sizeof(char), 1, binaryFile); i++);

printf ("%s", charArray);

FILE * textFile = fopen ("file.txt", "w"); // створюємо новий текстовий файл


assert(textFile); //Перевіряємо файл на відкриття за допомогою макросу assert
fprintf(textFile, "%s", charArray); // записуємо туди зчитані з бінарного файлу символи
fcloseall();
return 0;
}

2.
#include < stdio.h > //Для printf, getc, fopen, fclose, feof
#include <locale.h>

int main (void)


{ setlocale(LC_ALL,"rus");
// Змінна, в яку буде поміщений покажчик
// на створений потік даних
FILE *mf;
// Змінна, в яку по черзі будуть поміщатися зчитувальні байти
int sym;
char str[100];
printf("Введите строку для заполнения файла test: ");
gets(str);
// Відкриття файлу з режимом доступу "тільки читання"
// і прив'язка до нього потоку даних
printf ("Открытие файла: ");
mf=fopen ("d:\\test.txt","w");
fputs(str,mf);
fclose(mf);

mf = fopen ("d:\\test.txt","r");

// Перевірка відкриття файлу


if (mf == NULL) {printf ("ошибка\n"); return -1;}
else printf ("выполнено\n");

printf ("Коды считанных символов:\n");

// Читання (побайтно) даних з файлу в нескінченному циклі


while (1)
{
// Читання одного байта з файлу
24
sym = fgetc (mf);

// Перевірка на кінець файлу або помилку читання


if (sym == EOF)
{
// Перевіряємо що саме сталося: скінчився файл
// або це помилка читання
if (feof (mf) != 0)
{
//Якщо файл закінчився, виводимо повідомлення про
//завершення читання і виходимо з нескінченного циклу
printf ("\nЧтение файла закончено\n");
break;
}
else
{
//Якщо при читанні сталася помилка, виводимо
// повідомлення і виходимо з нескінченного циклу
printf ("\nОшибка чтения из файла\n");
break;
}
}
// Якщо файл не закінчився, і не було помилки читання
// виводимо код зчитаного символу на екран
printf ("\nкод %d, символ %c",sym,sym);
}
// Закриваємо файл
printf ("Закрытие файла: ");
if ( fclose (mf) == EOF) printf ("ошибка\n");
else printf ("выполнено\n");

return 0;
}

3.
#include <stdio.h>
int main()
{
struct student
{
char surname[20];
int course;
};
const int n=5;
student s[n];

int i;
for (i=0;i<n;i++)
{
printf("Input surname and course for %d student: ",i+1);
scanf("%s%d",s[i].surname,&s[i].course);
}
FILE* f1;
f1=fopen("d:\\f1.dat","w+");
25
if (f1==NULL)
{
printf("Error1");
return 1;
}
fwrite(s,sizeof(s),1,f1);// запис масиву в бінарний файл
fseek(f1,0,0); // переводимо курсор в початок файлу
fread(s,sizeof(s),1,f1);// читання масиву з файлу
FILE* f2;
f2=fopen("d:\\f2.dat","w"); // створюємо текстовий файл
if (f2==NULL)
{
printf("Error2");
return 2;
}
int c;
printf("Input number of course: ");
scanf("%d",&c);
for (i=0;i<n;i++)
if (s[i].course==c)
// запис обраних студентів в текстовий файл
fprintf(f2,"%20s%4d\n",s[i].surname,s[i].course);
fcloseall();
return 0;
}
26
ЛІТЕРАТУРА

Основна література
1. Павловская Т.А. С/С++. Программирование на языке высокого уровня : учеб. пособие /
Т.А. Павловская .- СПб. : Питер, 2002.- 460 с. (1 прим.)
2. Глибовець А.М. Практикум з мови програмування СІ : навч. посібник / А.М. Глибовець,
М.М. Глибовець, В.С. Проценко .- К. : Вид. дім. "Києво-Могилянська академія", 2010.- 209 с. (1
прим.)
3. Прата С. Язык программирования С : лекции и упражнения : учебник : пер. с англ. /
Стивен Прата .- М.; СПб.; К. : ДиаСофтЮП, 2002.- 896 с. (1 прим.)
4. Свирский А.В. Основы программирования. Задачи и решения : лабораторный практикум /
А.В. Свирский .- О. : АстроПринт, 1999.- 144 с. (2 прим.)
5. Павловская Т.А. С/С ++. Программирование на языке высокого уровня : учебник для вузов
/ Т.А. Павловская .- СПб. : Питер, 2005.- 461 с. (2 прим.)
6. Ковалюк Т.В. Основи програмування : Підручник для ВНЗ / Т.В. Ковалюк .- К. : Вид.
група BHV, 2005.- 384 с. (30 прим.)
7. Романовская Л.М. Программирование в среде СИ для ПЭВМ ЕС / Л.М. Романовская, Т.В.
Русс, С.Г. Свитковский .- М. : Финансы и статистика, 1991.- 362 с. (31 прим.)

Додаткова література
8. Березин Б.И., Березин С.Б. Начальный курс С и C++. – М.: ДИАЛОГ-МИФИ, 2001. – 288 с.
9. Бузюков Л.Б., Петрова О.Б. Современные методы программирования на языках C и C++:
учебное пособие. – СПб. : Линk, 2008. – 288 с.
10. Ван Тассел Д. Стиль, разработка, эффективность, отладка и испытание программ. – М.:
Мир, 2011. – 320 с.
11. Дейтел Х., Дейтел П. Как программировать на С: Третье издание. Пер. с англ. – М.:
Бином-Пресс, 2002. – 1168 с.
12. Керниган Б., Ритчи Д. Язык программирования Си. – СПб.: «Невский Диалект», 2001. –
352 с.
13. Кочан С. Программирование на языке С. – М.: Изд. дом «Вильямс», 2007. – 496 с.
14. Паппас К., Мюррей У. Программирование на С и C++. – Киев: BHV, «Ирина», 2000. –
287 с.
15. Пауэрс Л., Снелл М. Microsoft Visual Studio. – БХВ-Петербург, 2009. – 1200 с.
16. Пахомов Б. С/C++ и MS Visual C++ 2010 для начинающих. – БХВ-Петербург, 2011. – 736 с.
17. Подбельский В.В., Фомин С.С. Программирование на языке Си. — М.: Финансы и
статистика, 2004. – 600 с.
18. Рендольф Н., Гарднер Д., Андерсон К., Минутилло М. Microsoft Visual Studio 2010 для
профессионалов. – М.: Изд. дом «Вильямс», 2011. – 1184 с.
19. Шилдт Г. Полный справочник по C. – М.: Изд. дом «Вильямс», 2002. – 704 с.

You might also like