1.8 Вбудовані функції
Вбудовані функції (inline) — це функції, чиє тіло підставляється в кожну точку виклику, замість того, щоб генерувати код виклику. Модифікатор inline перед вказівкою типу результату в оголошенні функції загадує компілятору згенерувати копію коду функції у відповідному місці, щоб уникнути виклику цієї функції. У результаті виходить множина копій коду функцій, вставлених у програму, замість єдиної копії, якою передається керування при кожному виклику функції. Модифікатор inline необхідно застосовувати для невеликих і часто використовуваних функцій. Наприклад,
#include <iostream.h>
inline int min (int x1, int y1)
{ if (x1 < y1)
return (x1);
else
return (y1);
}
void main( )
{ int х, у, z;
{ cout << endl << "Введіть два цілих числа ";
cin >> х >> у;
z = min(х, у);
cout << endl << " Мінімальним з " << х << " і " << у << " є "
<< z;
}
Компілятор може ігнорувати модифікатор inline, якщо вбудований код надто великий, компілятор згенерує звичайний виклик функції.
1.9 Перевантажені функції
С++ дозволяє визначати функції з однаковими іменами, але унікальними типами аргументів. У цьому разі про функції кажуть, що вони перевантажені. Перевантаження функції використовується звичайно для створення кількох функцій з однаковим ім’ям, призначених для виконання схожих задач, але з різними типами даних. Наприклад,
#include <iostream.h>
int fun (int х, int у)
{ return (х*х+у*у);}
float fun (float х, float у)
{ return (х*х+у*у); }
main( )
{ int x1 = 10, y2 = 3; float x2 = 13.75, y2 = 11.25
cout << endl <<"Сума квадратів чисел " << x1<< " і " << y1 << "дорівнює "
<< fun(x1, y1)
<< endl <<"Сума квадратів чисел " << x2<< " і " << y2 << "дорівнює "
<< fun(x2, y2)
return 0;
}
Перевантажені функції розрізняються за допомогою сигнатури — комбінації імені функції і типів її параметрів. Компілятор кодує ідентифікатор кожної функції за числом і типом її параметрів, це називається декорируванням імені, щоб мати можливість здійснювати надійне зв’язування типів. Надійне зв’язування типів гарантує, що викликається належна функція і що аргументи узгоджуються з параметрами. Компілятор виявляє помилки зв’язування і видає повідомлення про них. Кожне декороване ім’я починається з символу @, який передує імені функції. Закодований список параметрів починається з символів $g. Типи значень функцій, що повертаються, не відбиваються в декорованих іменах. Перевантажені функції можуть мати різні або однакові типи значень, що повертаються, і обов’язково повинні мати різні списки параметрів. Дві функції, відмінні лише за типами значень, що повертаються, викличуть помилку компіляції.
2.1 Завдання 1 Структури
2.1.1 Постановка завдання
У файлі оперативної систекми «Task.in» зберігається в текстовій формі відмість з відомостями про продукти. Кожен рядок цього файлу містить відо-мості про один вид продукту, представлені у такому форматі: 1…2 – порядковий номер продукту; позиція 3 – пробільних літера; позиції 4…15 – назва продукту довжиною не більше 11 имволів, в довільному місці поля; позиція 16 – пробільних літера; позиції 17…19 – вміст білка в 100 грамах продукту (ціле).
Кількість продуктів у відомості дорівнює 16. Приклад зазначеного файлу:
01 щука 20
02 сом 16
Написати:
1) визначення масиву структур для зберігання зазначеної відомості і фрагмент програми, який заповнить відомість даними, вводяться з файлу операційної системи «Task.in» (введення даних повинно здійснюватися в текстовому режимі);
2) фрагмент програми для знаходження і друку (у файл «Task.out») інформацію про продукт з найбільшим вмістом білка.
2.1.2 Програма та програмна реалізація
Дане завдання реалізоване у модулі TASK1.CPP (TASK1.EXE)
Для опису даної програми була введена структура (struct Tbook) та заданий масив (char name[20]) для зберігання даних даного типу. Реалізація програми здійснюється за допомогою файлів “Task_in” та “Task_out”. Зчитування проводиться стандартною функцією scanf згідно визначеного формату даних вхідного файлу «Task_in». Під час роботи програма визначає продукт з найбільшим вмістом білка. Результатом виконання є вивід інформації про продукт та її запис у вихідний файл «Task_out». Тіло програми повністю побудоване згідно алгоритму(додаток 7). Розглянемо програму:
// Програма Task1.cpp
#include <conio.h>
#include <process.h>
#include <fstream.h>
#include <stdio.h>
#include <dos.h>
#include <math.h>
struct Tbook
{
char name[20];
int index;
float price;
};
Tbook shelf[15];
FILE *taskin, *taskout;
void TASK1() {
clrscr();
printf("Chytania fajlu 'task.in'\n\n");
if((taskin = fopen("task.in", "rt")) == NULL)
{
perror("ERROR\n");
getch();
exit(errno); };
int i = 0;
sqrt;
while(i < 16)
{
if(fscanf(taskin,"%2i %11s %f\n",
&shelf[i].index,
shelf[i].name,
&shelf[i].price
) == EOF) break;
printf("%2i %11s %2.0f\n",
shelf[i].index,
shelf[i].name,
shelf[i].price);
i++; };
fclose(taskin);
printf("\n...zavershene!");
float max=shelf[0].price;
int ind=0;
for(i = 0; i < 16; i++)
{
if (shelf[i].price>=max){max=shelf[i].price; ind=i;}
};
printf("\n\nMaksymalnyj vmist bilka mae \"%s\" - %2.0f\n",shelf[ind].name,shelf[ind].price);
printf("\n\nZapys u fajl 'task.out'");
taskout = fopen("task.out", "w+");
fprintf(taskout, "%2i %11s %2.0f",
shelf[ind].index,
shelf[ind].name,
shelf[ind].price);
fclose(taskout);
printf("...zavershenyj!");
getch();
};
2.1.3 Тестування завдання
Для проведення тестування потрібно першочергово заповнити файл Task_in (з операційної системи). Даний файл було заповннено наступними значеннями(рис. 2.131). Після цього програму потрібно запустити. Результат виконання, а саме інформацію про продукт з найбільшим вмістом білка можна записаний у вихідному файлі Task_out(рис. 2.132).
Рис. 2.131 Task_in Рис. 2.132 Task_out
2.2 Завдання 2 Фукція
2.2.1 Постановка завдання
Знайти величину і номер першого негативного і останнього позитивного елементів у масиві дійсного типу заданого розміру.
2.2.2 Програма та програмна реалізація
Дане завдання реалізоване у модулі TASK2.CPP (TASK2.EXE)
У підпрограмі оголошено масив(float a[100]), змінна n-відповідає кількості елементів у масиві, також є дві функції (int pos, int neg) – одана шукає намер першого негативного елементу масиву, інша номер останнього позитивного елементу масиву. Тіло програми повністю побудоване згідно алгоритму(додаток 8). Розглянемо програму:
// Task2.cpp
#include <iostream.h>
#include <conio.h>
//--------------------
int pos(float *a, int n)
{ int i=n-1;
while (a[i]<0)
i--;
return i;
}
//----------------------
int neg(float *a, int n)
{
int i=0;
for (i=0; i<=n; i++)
if (a[i]<0) break;
return i;
}
//-------------------------
void TASK2()
{
clrscr();
int i,n;
int k1;
int k2;
float a[100];
cout<<"Vvedit velychynu masyvu:";
cin>>n;
if (n>1)
{
for (i=0; i<=n-1; i++ )
{
cout<<"Vvedit znachenia Masyv["<<i<<"]:";
cin>>a[i];
k1=pos(a,n);
k2=neg(a,n);
}
}
cout<<"\n\n";
cout<<"Pershyj negatyvnyj element maje nomer "<<k2+1<<",a jogo vmist: "<<a[k2]<<endl;
cout<<"Ostannij pozytyvnyj element maje nomer "<<k1+1<<",a jogo vmist: "<<a[k1];
getch();
}
2.2.3 Тестування завдання
Для перевірки даної підпрограми мною були введені дані про кількість елементів у масиві та власне сам масив. В результаті був отриманий результат - номер та власне саме значення першого негативного та останнього позитивного елементів у масиві(рис. 2.321).
Рис. 2.321 Тестовий приклад Task2.срр
2.3 Завдання 3 Масиви
2.3.1 Постановка завдання
Елемент матриці називають локальним мінімумом, якщо його значення строго менше значень всіх наявних сусідів. Підрахувти кількість локальних мінімумів заданої матриці і надрукува інформацію про кожного з них.
2.3.2 Програма та програмна реалізація
Дане завдання реалізоване у модулі TASK3.CPP (TASK3.EXE)
На початку програми оголошений масив р[10][10]. Оголошений лічильник k – який підраховує кількість локальних мінімумві у матрицці. Під час запуску підпрограма запитує користувача розмірності матриці n. Після цього вона заповняється елементами. Наступним етапом є опрацювання матриці оператором for. Після опрацювання виводиться повідомлення про кількість локальних мінімумів k та інфориація про кожного з них. Програма побудована згідно алгоритму:
void TASK3()
Розглянемо програму:
//Task3.cpp
#include <iostream.h>
#include <conio.h>
void TASK3(){
clrscr();
int i,j,n,k,k1;
k=0;
int p[10][10];
cout<<"Vvedit znachenia n:"<<"\n";
cin>>n;
for (i=0; i<=n-1; i++ ){
for (j=0; j<=n-1; j++){
cout<<"Vvedit znachenia p["<<i<<"]["<<j<<"]: ";
cin>>p[i][j];}
}
for (i=0; i<=n-1; i++ )
for (j=0; j<=n-1; j++){
k1=0;
if ((i==0) || (p[i-1][j]>p[i][j])) k1++;
if ((i==n-1) || (p[i+1][j]>p[i][j])) k1++;
if ((j==0) || (p[i][j-1]>p[i][j])) k1++;
if ((i==n-1) || (p[i][j+1]>p[i][j])) k1++;
if (k1==4){k++; cout<<"Inform pro lokalnuy minimymiv"<<endl; cout<<"p["<<i<<"]["<<j<<"]="<<p[i][j]<<endl;
}
cout<<endl;}
cout<<"Kilkist lokalnux minimymiv\n"<<k;
getch();
}
2.3.3 Тестування завдання
Для тесту були введені наступні значення(рис. 2.331). В результаті був отриманий наступний результат:
Рис. 3.31 Тестовий приклад Task3.cpp
2.4 Завдання 4 Операції над лінійним списком. Робота з динамічною пам’яттю
2.4.1 Постановка завдання
Визначено наступний покажчик на початок лінійного списку:
struct Node // NODE: вузол лінійного списку
{
Node *pLink; // Pointer LINK:
// Покажчик на черговий вузол
float Info // INFOrmation: інформація
} *Start;