Device . Put (char_var); , 2 страница
20. Увести координати 10 крапок на площині і визначити, у якій із чвертей більше всього крапок.
21. Увести п'ять наборів сторін трикутника а, b, c і визначити для яких сторін висота буде найбільшою.
Підказка: де
22. Увести координати п'яти крапок і визначити яка з них потрапить в окружність з радіусом R і координатами центра (а, в).
Підказка: рівняння окружності має вид:
23. Увести п'ять шестирозрядних цілих чисел і знайти для яких з них сума «лівих» трьох цифр більше суми «правих» трьох.
24. Підрахувати скільки разів функція
приймає негативне значення, якщо .
25. Обчислити функцію у вигляді формули
для кожного значення i.
2 РОЗВ’ЯЗАННЯ ЗАДАЧ C ВИКОРИСТАННЯМ ОДНОВИМІРНИХ І ДВОВИМІРНИХ МАСИВІВ
2.1 Ціль роботи
Прищепити студентам навички розв’язання задач з використанням одновимірних і двовимірних масивів, складних циклів і використання покажчиків.
2.2 Методичні рекомендації з організації самостійної роботи студентів
При підготовці до роботи повторити способи опису одновимірних і двовимірних масивів, використання індексованих змінних при обробці даних, організацію введення і виведення масивів, використання покажчиків .
На відміну від задач, розглянутих у попередній лабораторній роботі, аргумент функції може бути заданий і іншим способом — у вигляді довільного набору значень.
Приклад 2.1Обчислити функціюy = axi2 – sin xi, де x1=-1, x2=-0,93, x3=-0,49, x4=0, x5=1,13, x6=0,96, x7=1,75.
При розв’язанні такої задачі кожне з перерахованих значень треба ввести в пам'ять комп'ютера, для чого буде потрібно відповідна кількість комірок. Такий довільний ряд однотипних значень, які мають одне загальне символічне ім'я (ідентифікатор), називається масивом. Окреме значення масиву називається його елементом, а місце розташування елементів у масиві визначається за допомогою його індексу. У пам'яті комп'ютера масив займає стільки комірок пам'яті, скільки в ньому елементів.
У схемі алгоритму розв‘язання задачі спочатку передбачається введення значень всіх елементів оброблюваного масиву x[n] (n =7 ).Число в дужках визначає кількість елементів масиву. Нумерація елементів масиву починається з 0ізакінчується n –1 .Далі введені елементи використовуються при обчисленні функції, шляхом вказівки індексу відповідного елемента.
Схема алгоритму розв’язання цієї задачі і програма виглядають наступним чином:
//P2_1.CPP -обчислення значень функції
// використання одновимірного масиву
#include <iostream>
так
немає |
#include <math.h>
Using namespace std;
Void main( )
{
const int n =7;
float x[n];
Int i;
Float a, y;
// Введення масиву
cout<< "Введіть значення масиву:" <<endl;
for ( i=0; i < n; i++)
{
cout << "x [" << i << "] = ";
cin >> x [ i ] ;
cout << x [ i ] << endl;
}
a = 10.5;
// Обчислення функції
for ( i = 0; i < n; i++)
{
y = a*x [ i ] * x [ i ] – sin ( x [ i ] ) ; cout << "При значенні=" << x[i]
<< "y = " << y << endl;
}
}
При запису цього алгоритму у вигляді програми спочатку треба описати масив за допомогою оператора float x [n], ввести його значення в пам'ять комп'ютера, а потім робити необхідні обчислення.
У програмі, що реалізує даний алгоритм, для введення елементів масиву використовується оператор cin >> x [i] ;, перед цим оператором знаходиться підказка cout << "x [" << i << "] = ";і зазначен номер елемента x[i], значення якого треба ввести.
Особливість виконання оператора введення cin >> x[i] ; полягає в тому, що, зустрівши його в програмі, комп'ютер призупинить її виконання поки не буде введене значення елемента x[i]і натиснута клавіша Enter, після чого обробка програми буде продовжена. Зазначений оператор включений у цикл, реалізований за допомогою оператора for, і повторюваний n разів, для забезпечення введення всіх елементів масиву.
Оскільки в мові С++ індексаціяелементів масиву починається з нуля, то масив float x[7] (n =7 )із семи елементів включає індексовані елементи x[0], x[1], x[2] … x[6]і при цьомуx[0] —звертання до першого елемента, x[1] —звернення до другого елемента масиву і т.д. Пропонована програма використовує два цикли: один — для введення елементів масиву, інший — для обчислення функції. Ці операції можна виконати й в одному циклі, тоді програма буде мати вигляд:
// Р2_2.CPP— введення елементів одновимірного масиву
// і обчислення функції здійснюється в одному циклі
#include < math.h>
#include < iostream>
Using namespace std;
Float a, y ;
Void main ( )
{
const int n =7;
float x [ n ];
Int i;
Float a, y ;
a = 10.5;
for ( i = 0; i < n ; i++)
{
cout << "x [ " << i << "] = ";
cin >> x [ i ] ;
y = a * x[ i ]*x[ i ] - sin( x[ i ] );
cout << "При значенні =" << x[і] << " y= " << y << endl;
}
}
Приклад 2.2Обробити відомість успішності групи студентів з 10 чоловік по програмуванню, підрахувавши середній бал групи і кількість відмінників.
Список оцінок представимо масивом mas[i] (i=0..9), і програма, що реалізує таку задачу, виглядає в такий спосіб :
// Р2_3.CPP— використання одновимірних масивів
// Визначення середнього бала групи і кількості відмінників
#include < math.h >
#include < iostream>
Using namespace std;
Void main ( )
{
const int n = 10; //розмірність масиву
float mas[n]; //опис одновимірного масиву
Int i, k;
Float s;
s = 0 ; // s- змінна для підсумовування оцінок групи
k = 0 ; // k - змінна для підрахунку кількості відмінників
for ( i=0; i < n; i++ )
{
cout << " mas [ " << i << "] = ";
cin >> mas [ i ] ;
cout << mas [ i ] << endl;
s = s + mas [ i ];
if ( mas[ i ] = = 5)
k =k+1;
}
cout << "Середній бал = " << s / float(n ) << endl;
cout << "Кількість відмінників =" << k<< endl;
}
У цій програмі змінна s служить для обчислення суми оцінок групи, а змінна k — для підрахунку кількості відмінників. Перед обчисленням треба задати цим змінним початкового нульового значення. Оператор
cout << " mas [ " << i << "] = ";
усередині циклу виконує роль підказки про необхідність введення чергової оцінки, а наприкінці використовується для виведення результатів обчислення ( cout << "Середній бал"<< s / float (n) << endl; cout << "Кількість відмінників =" <<k<< endl;) .
Крім одновимірних масивів, тобто таких, де положення елемента визначається за допомогою одного індексу, у практиці розв’язання задач часто застосовуються багатовимірні масиви. У них положення елемента визначається шляхом запису декількох індексів. Найбільш широке поширення одержали двовимірні масиви, які називаються матрицями. Матриці являють собою порядковий запис декількох одновимірних масивів, наприклад:
Місце розташування кожного елемента визначається за допомогою двох індексів — номера рядка і номери стовпця, тобто порядкового номера в рядку.
Індекси таких масивів записуються в квадратних дужках. Наприклад, запис М[1] [2] вказує на елемент, що знаходиться в другому рядку і третьому стовпці, тобто маючий значення -20.5 (рахунок індексів починається з 0). Для перебору всіх елементів матриці при їхньому введенні-виведенні, а також при обробці в програмі варто передбачати організацію двох циклів: один — для завдання значень індексу рядків, інший -індексу стовпців.
Приклад 2.3 До кожного елемента вищенаведеної матриці M додати число 10.
// Р2_4.CPP—використання двовимірних масивів
//До кожного елемента матриці додати число 10.
#include < iostream>
Using namespace std;
Void main ( )
{
const int n = 3; //кількість рядків матриці
const int m = 5; //кількість стовпців матриці
float M [ n] [m];
Int i, k;
Float s;
s = 10 ;
cout << " Введіть значення масиву:" << endl;
// Введення значень двовимірного масиву
for ( i = 0; i < n; i++)
for ( k = 0; k < m; k ++)
{
cout << " M [ " << i << "] = " << "[ " << k << ]" ;
cin >> M [ i ] [ k ];
cout << M [ i ] [ k ] << endl;
M [ i ] [ k ] = M [ i ] [ k ] + s ; //Можна M [ i ] [ k ] + = s ;
}
cout << "Нове значення матриці :" << endl;
//Виведення матриці в природному вигляді
for ( i = 0; i < n; i++)
{
cout << endl;
for ( k = 0; k < m; k++)
cout << M [ i ] [ k ] << " ";
}
}
У програмі при описі матриці в операторі
float M[n][m];
вказується діапазон зміни двох індексів, перший з яких призначений для індексування рядків, другий — стовпців.
При введенні, обробці і виведенні матриці для перебору всіх її елементів використовується два цикли, один із яких є вкладеним в іншій. Це дозволяє при кожнім значенні змінної iперебирати всі значення k.
Розглянута програма може бути скорочена шляхом об'єднання всіх трьох блоків циклу в один, але в такому випадку вона буде менш наочною.
2.3 Використання покажчиків
У мові С++ широко використовуються дані, що називаються покажчиками.
Покажчики — це змінні, котрі містять адресу пам'яті, розподіленої для іншої змінної. Усі змінні, розглянуті до цього, зберігали якісь значення (дані). Ці дані могли бути різних типів: символьного, цілого, дійсного і т.д. При оголошенні змінної - покажчика необхідно вказати тип даних, адресу яких буде містити змінна, і ім'я покажчика з попередньою зірочкою.
Загальний формат опису покажчика наступний:
тип * ім'я;
де тип — тип значень, на который буде вказувати покажчик;
ім'я — ім'я змінної-покажчика;
* — означає операцію над типом, що читається "покажчик" на тип.
Наведемо приклади визначень покажчиків:
int *pn; //покажчик на ціле значення;
float *pf1, *pf2 ; //два покажчики на дійсні значення;
Покажчики не прив'язують дані до якого-небудь визначеного імені змінної і можуть містити адреси будь-якого неіменованого значення. Існує адресна константа NULL, що означає "порожню" адресу.
У мові С++ знаходиться усього два оператори, що відносяться до покажчиків:
“&” — оператор " адреса значення ";
“* “— оператор "значення за адресою".
Оператор "*" , використовуваний разом з покажчиками, витягає значення, на яке вказує змінна, розташована безпосередньо після нього.
Оператор "&" , використовуваний разом з покажчиками, повертає адресу змінної, розташованої безпосередньо після нього.
Покажчики можна оголосити одним з наступних способів:
<тип> *ptr;
<тип> *ptr = <перемінна - покажчик>;
<тип> *ptr =&<ім'я змінної>;// адреса змінної
У програмі це може виглядати в такий спосіб:
int *ptx ,b ; float y; //оголошені перемінна - покажчик ptxізвичайні змінні b і y;
float *sp = &y; //покажчику spпривласнюється адреса змінної y
float *p = sp; //покажчику p привласнюється значення (адреса значення),
//яке міститься в змінній sp, тобто адреса змінної y.
При оголошенні покажчиків символ "*" може розташовуватися або перед ім'ям покажчика або записуватися відразу після оголошення типу покажчика і поширює свою дію тільки на одну змінну - покажчик, перед якою він знаходиться, наприклад:
long *pt; long* Uk; int * ki, x, h ; // оголошення описів
У разі потреби опису покажчика на комірку довільного типу, замість ідентифікатора типу записується слово void, наприклад:
void *p, *pt; // описані два покажчики на довільний тип даних
Перш ніж використовувати покажчик у програмі, йому обов'язково треба присвоїти адресу якого - небудь даного, тобто проініціалізувати, інакше можуть бути непередбачені результати.
Для доступу до значення змінної, адреса якої зберігається в покажчику, досить у відповідному операторі програми записати ім'я покажчика із символом "*" , наприклад:
int *p, *p1; //Оголошені два покажчики на комірку пам'ятіint;
int x =12, y=5, m [7 ]; //Оголошені змінніx,yі масивm,
// змінні x,y ініціалізовані
p = &y; //Покажчику p привласнена адреса змінноїy.
Тепер, якщо написати оператор виведення на екран у вигляді :
cout << "Адреса р " << p << "Значення по цій адресі= " <<*p; ,
тоді виведеться адреса комірки пам'яті, де записана змінна y і значення цієї змінної (тобто 5).
Використовуючи запис x = *p;,одержуємо x=5,тому що*p = y = 5; .
Змінити значення y можна таким чином:
y = 10; //чи*p = 10;
і виконавши операцію
*p=*p+5; // це рівнозначно операції y = y + 5;тобто y = 15.
При оголошенні покажчиків, їм потрібно привласнювати початкові значення ( ініціалізувати ), при цьому можна або привласнювати адресу об'єкта (змінної), або адресу конкретного місця пам'яті (масиву), або число 0 (нуль),наприклад:
int *pt = (char *) 0x00147; //Привласнюється адреса комірки
int *arrpt = new int [10]; // Визначається початкова адреса розміщення
//динамічного масиву
сhar *p = 0;// Ініціалізація нулем
Оскільки покажчики — це спеціальні змінні, то в операціях з іншим покажчиками вони можуть використовуватися без символу "*", тобто без розкриття посилання, наприклад:
float *pt1, *pt2 , x=15, m[5];
pt1=&x;
pt2=pt1;
pt1 = m; // або pt1 = &m[0]; m— це ім'я масиву, що
//розглядаєтьсяяк спеціальний покажчик – константа.
Наиведемо програму з використанням покажчиків:
// P2_5.CPP— застосування покажчиків
#include < iostream>
Using namespace std;
Int main ( )
{
int x = 10;
int *px = &x;
cout << " x =" << x << endl;
cout << "*px =" << *px << endl;
x* = 2; // або x = x*2;
cout << " Нове значення* px =" << *px << endl;
*px += 2; // або *px =*px + 2;
cout << " Нове значення* px=, тобто х=" << x << endl;
Return 0;
}
Результат виконання програми:
x = 10
*px = 10
Нове значення *px = 20
Нове значення*px, тобто x = 22
Сам покажчик-змінна має свою адресу, тому буде справедливим
наступний запис:
int *pt1, *pt2;
pt1 = (int*) &pt2; //тут покажчику pt1привласнюється адреса пам'яті,
//де розташована зміннаpt2
Це має сенс у ситуації, коли :
int y,*pt1, *pt2 =&y;
pt1 = (int*) & pt2; .
Існують наступні обмеження на використання операції взяття адреси "&":
— не можна визначати адресу константи ( оскільки їй не приділяється комірка пам'яті), тобто неприпустимий запис : vp = &345;
— не можна визначати адресу результату арифметичного виразу, тому наступний запис невірний :vp = & (x + y); .
Для змінних – покажчиківдозволені операції:
— присвоювання;
— інкремент і декремент;
— додавання і віднімання;
— порівняння покажчиків однакового типу.
Наприклад, демонстраційна програма з використанням змінних-покажчиків може мати вигляд:
//P2_6.CPP— використання змінних- покажчиків
#include < iostream>
Using namespace std;
Void main ( void )
{
int *ptr1 = (int*)100 ;
int *ptr2 = (int*) 200;
ptr1++;
ptr2 -= 10;
cout << "ptr1=" << ptr1 << endl;
cout << "ptr2=" << ptr2 << endl;
cout << "ptr2 - ptr1=" << ptr2 - ptr1 << endl;
}
Результат виконання програми :
ptr1 = 00000068
ptr2 = 000000A0
ptr2 - ptr1 = 14
У програмі операція ptr1++збільшить адресу на 4 байта ,оскільки дані типу int займають 4 байти,операція ptr2-=10зменьшує адресу на 40 байтів.Адреси виводяться на екран в шістнадцятковому вигляді.
2.4 Використання масивів і покажчиків
У мові С++ масиви і покажчики зв'язані між собою. При оголошенні масиву у вигляді :int mas [20];ім'я масиву masвизначається як покажчик-константа на перший (нульовий) елемент масиву, тобто на адресу першого елемента масиву &mas[0].
Для доступу до елементів масиву існує два способи:
— використання індексу елемента масиву, наприклад, mas[2]або mas[i];
—використання адресного виразу тобто виразу з покажчиком на
масив, наприклад, *( mas +2 ) чи *( mas+i ).
Ім'я масив-покажчик, можна записати в наступному вигляді:
int mas [20];
int *ptr1;
ptr1 = mas; //чи ptr1 = &mas[0];
Після оголошення масиву int mas [20]; вираз &mas[0]іmas є еквівалентними.
Для обнуління елементів оголошеного масиву досить ініціалізувати його перший елемент: int mas[10] = {0} ; При цьому першому елементу не обов'язково привласнювати значення 0. Якщо в оголошеному масиві ініціалізується трохи перших елементів, то інші ініціалізуються нулями.
Наприклад, у випадку коли float mas [10] ={ 12.2, 34.56 };, останні вісім елементів одержать значення 0.
Глобальні масиви автоматично ініціалізуються двійковими нулями, у тому числі і символьні.
При оголошенні масивів можна використовувати одну з форм запису :
< тип > < ім'я > [n] //Оголошення одновимірного
// масиву з nелементів
< тип > < ім'я > [n] = { значення } //Значення елементів масиву
< тип > < ім'я > [ ] = { значення }// розділені комою
Наприклад:
float m[6];
float m[6] = { 3.4, 4.5, 5.6, 6.7, 8.9, 10.3 };
float m[ ] = { 3.45, 4.56, 5.67, 6.78 };
Двовимірні і багатовимірні масиви описуються аналогічним образом, тобто правомірний запис :
int mas [2][5] ={ 1, 2, 3, 4, 5,
10, 11, 13, 14, 25 };
int mas [2][5] ={ {1, 2, 3, 4, 5},
{10, 11, 13, 14, 25} };
int mas [ ][5] ={ 1, 2, 3, 4, 5,
10, 11, 13, 14, 25 }; .
При оголошенні одновимірних масивів їхній розмір можна не вказувати, якщо оголошений масив відразу ініціалізується.
В оголошенні багатовимірних масивів можна опускати кількість індексів тільки першого виміру при одночасній ініціалізації. Якщо під час оголошення масивів ініціалізація не проводиться , то кількість індексів треба вказувати завжди і скрізь.
Оскільки для масивів завжди в пам'яті приділяється суцільний блок комірок пам'яті, у яких розташовуються елементи, то адресу наступного елемента mas[1] можна вказати шляхом збільшення покажчика на 1, тобто якщо p = &mas[0] , тоді p=p + 1 або( p += 1)адля i елемента масиву адреса може бути визначена як p + i; . При цьому автоматично виконується операція збільшення адреси з урахуванням типу масиву і кількості, що відводиться, байт для кожного його елемента, отже :
адреса х[і] = адреса x[0] + і*sizeof ( тип ); .
Якщо два покажчики р1ір2указують на елементи одного масиву, то до них застосовні операції відносини: == , != , < , <= , > , >= .
Наприклад, відношення вигляду р1 < р2 істинно, якщо р1указує на більш ранній елемент, ніж р2 . Всякий покажчик можна порівняти з нулем.
Варто звернути увагу, що для покажчиків, що посилаються на елементи різних масивів, результат арифметичних операцій і відносин не визначений. В арифметиці з покажчиками можна використовувати адресу не існуючого "наступного за масивом " елемента. Крім того, до покажчика можна додати деяке ціле значення, наприклад можна записати: