Информатика.ЛБ
.pdf{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 . Всякий покажчик можна порівняти з нулем.
Варто звернути увагу, що для покажчиків, що посилаються на елементи різних масивів, результат арифметичних операцій і відносин не визначений. В
арифметиці з покажчиками |
можна |
використовувати |
адресу не існуючого |
"наступного за масивом " елемента. |
Крім того, до покажчика можна додати |
||
деяке ціле значення, наприклад можна записати: |
|
||
|
р + n ; |
, |
|
де n — ціле значення, а |
р — покажчик. |
|
|
Цей вираз визначає область об'єкта, що займає n -те місце після об'єкта, |
|||
на який указує р, при цьому |
n автоматично збільшується на коефіцієнт,що |
||
дорівнює відповідній довжині об'єкта. Наприклад , якщо |
int займає 4 байти , |
то цей коефіцієнт дорівнює чотирьом.
Допускаються також порівняння покажчиків, що вказують на елементи одного масиву.
Наприклад, якщо р1< p2, то р2 - р1+1 — це число елементів масиву від р1 до р2 включно.
Таким чином, з покажчиками допускаються наступні операції :
—присвоювання значення одного покажчика іншому;
—додавання і вирахування покажчиків і даного цілого типу ( р+5 );
31
—порівняння двох покажчиків, що посилаються на елементи одного
масиву;
— присвоювання покажчику нуля і порівняння з нулем.
Інші операції з покажчиками заборонені.
Для покажчика дозволяються вирази вигляду:
р1 = mas; або р++ ,
тут р — покажчик , mas — масив.
Розглянемо демонстраційні приклади програм роботи з покажчиками.
Приклад |
2.4 |
Обчислити |
середнє |
значення |
додатних |
елементів |
одновимірного масиву. |
|
|
|
|
|
|
Наведемо кілька варіантів програмної реалізації цієї задачі. |
|
|||||
// P2_7.CPP — обчислення середнього |
значення |
|
|
|||
// |
додатних елементів масиву |
|
|
|||
// |
програма без використання покажчиків |
|
|
|||
#include < iostream> |
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
main( ) |
|
|
|
|
|
|
{ |
|
|
|
|
|
|
const int n = 5; |
|
|
|
|
||
float mas[n], s = 0; |
|
|
|
|
||
int kol = 0; |
|
|
|
|
|
|
for( |
int i = 0; i < n; i++) |
|
|
|
|
|
{ |
|
|
|
|
|
|
cout << "Введіть" << і << "елемент mas" << endl; |
|
|||||
cin >> mas[ i ]; |
|
|
|
|
||
|
if ( mas[ i ] > 0 ) |
|
|
|
|
|
|
{ |
|
|
|
|
|
|
s += mas[ i ]; |
|
|
|
|
|
|
kol ++; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
s/ = kol; |
|
|
|
|
|
|
cout << "s=" << s << endl; |
|
|
|
|||
return 0; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
Використовуючи |
ім'я масиву |
як покажчик на |
початок |
масиву |
||
(перший |
елемент), цю програму можна переписати в такий спосіб: |
32
// P2_8.CPP — обчислення середнього значення
// |
додатних елементів масиву |
// |
використання імені масиву як покажчика на його початок |
#include < iostream> using namespace std;
main ( )
{
const int n = 5; float mas[n], s = 0; int kol = 0;
for ( int i=0; i < n; i++)
{
cout << "Введіть" << і << "елемент mas" << endl; cin >> *( mas+i);
if(* ( mas+i ) > 0 )
{
s+= *(mas+i); kol++;
}
}
s/=kol;
cout << "s=" << s << endl; return 0;
}
Якщо описати покажчик, зв'язати його з масивом (адресувати на початок масиву),то використовуючи арифметику покажчиків, можна написати цю програму у вигляді:
// P2_9. CPP —— обчислення середнього значення
// |
додатних |
елементів масиву |
// |
використання арифметики покажчиків |
|
#include < iostream> |
|
|
using namespace std; |
|
|
|
main ( ) |
|
|
{ |
|
|
int kol = 0; |
|
|
const int n = 5; |
|
|
float mas[n], s = 0; |
|
|
float *pm = mas; |
// припустимий запис pm=&mas[0] |
|
|
33 |
for ( int і = 0; і < n; і++)
{
cout <<"Введіть"<< і <<"елемент mas" << endl; cin >> *pm++;
cout << mas[i] << endl; if (mas[i] > 0)
{
s+=mas[i];
kol++;
}
}
s/= kol;
cout << "s=" << s << endl; return 0;
}
У наведеній програмі при введенні масиву використовувався покажчик *pm , а при роботі з ним — ім'я масиву з індексом. Якби при роботі з масивом використовувався покажчик *pm , то результат був би не вірним. Це пояснюється тим, що покажчик *pm в операціях введення він збільшує свою адресу ( pm++) після введення чергового елемента масиву і надалі вказує ще не введений елемент.
Наведемо ще один варіант програмної реалізації цієї ж задачі.
// P2_10.СРР —— обчислення середнього значення // додатних елементів масиву
// використання покажчиків
#include < iostream> |
|
using namespace std; |
|
main ( ) |
|
{ |
|
const int n = 5; |
|
float mas[n], s = 0; |
|
float *pm = mas; |
// *pm=&mas[0] |
int kol = 0; |
|
for ( int i = 0 ; i < n ; i++)
{
cin >> *pm;
cout << "Введіть" << і << "елемент mas" << endl; if (*pm > 0)
34
{
s += *pm; kol ++;
}
pm ++;
}
s/= kol;
cout << "s=" << s << endl; return 0;
}
Приклад 2.5. Скласти програму сортування одновимірного масиву за зменшенням методом вставки.
//P2_11.CPP — сортування методом вставки (за зменшенням)
//застосування покажчиків
#include < iostream.h > #include < conio.h > main ( )
{
int stc, mas [6], i, j; int *pmas;
pmas = mas;
cout << "Введіть 6 елементів масиву" << endl; for ( i = 0; i < 6; i++) cin >>*pmas++;
//Наступний оператор знову встановлює покажчик на початок масиву
//(інакше він буде вказувати на наступну за масивом адресу)
pmas = mas;
for ( i =1; i < 6; i++)
{
stc = *(pmas + i); j = i - 1;
while ( j >= 0 && stc > *(pmas+j))
{
*(pmas+j+1) = *(pmas+j); j - - ;
}
*(pmas+j+1) = stc;
}
cout << "Результат" << endl;
35
for ( i = 0; i < 6; i++)
cout << i << " елемент " << *(pmas + i ) << endl;
//Можна використовувати і таку конструкцію оператора
//cout << i << " елемент " << * pmas++ << endl;
getch ( ); // Для затримки екрана виведення результату return 0;
}
2.5 Масиви покажчиків
Як і інші змінні, покажчики можна групувати в масиви, кожен елемент якого містить адресу рядка масиву даних у пам'яті. У такий спосіб можна зберігати дані з "рваними" краями. Цей масив схожий на двовимірну таблицю з одним виключенням: усі рядки в такому масиві можуть мати різну довжину. При збереженні рядків це дозволяє заощаджувати пам'ять, а при виконанні сортування рядків, вона виконується значно швидше, тому що змінююється тільки покажчики, а не значення рядків.
fio
|
(0) |
-> |
П |
Е |
|
Т |
Р |
|
О |
В |
|
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(1) |
-> |
І |
В |
|
А |
Н |
|
О |
В |
|
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(2) |
-> |
К |
У |
|
Ц |
И |
|
Й |
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(3) |
-> |
В |
А |
|
Р |
І |
|
Ч |
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(4) |
-> |
Ю |
Ш |
|
К |
О |
|
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(5) |
-> |
П |
Л |
|
Ю |
Щ |
|
\0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Приведемо |
програму |
реалізуючу |
виведення |
подібної інформації з |
використанням масиву покажчиків.
// P2_11.CPP #include < iostream> using namespace std; main ( )
{
char *fio [ ] = { "Петров", "Іванов" , "Куций", "Варич", "Юшко", "Плющ " };
36
int str;
for ( str = 0; str <= 5; str++)
cout << " stroka " <<( str +1 ) << ‖ = ‖ << *( fio+str ) << endl; return 0;
}
Особливістю масиву покажчиків є те, що кожен з цих покажчиків елементів масиву може вказувати на масив довільної довжини. Так двовимірний масив чисел можна записати як матрицю, і як одновимірний масив покажчиків, наприклад: int matr[5][7]; чи int *pmt [5]; .
При цьому двовимірний масив розглядається як одновимірний масив рядків, кожен елемент якого — це теж масив стовпців, тобто масив масивів, тому індексування елементів матриці записується у вигляді mas [i][j]. Якщо двовимірний масив описаний за допомогою масиву покажчиків, то доступ до mas [i][j] елемента може здійснюватися одним зі способів:
* ( pm[i]+j ) або *( *( pm+i )+j ) .
Приклад 2.6 До елементів матриці, що мають парні значення, додати число і вивести отриману матрицю в природному вигляді.
Перший варіант програмної реалізації — матриця описується явним способом і робота ведеться з її елементами.
// P2_12.CPP — робота ведеться без покажчиків.
#include < iostream> using namespace std;
void main( )
{
int mat [2][3]; int і, j;
cout << " Введіть матрицю "<< endl; for ( i = 0; i < 2; i++)
for ( j = 0; j < 3; j++) cin >> mat [i] [j] ;
// Обробка і виведення матриці cout << " Матриця mat " << endl; for ( i = 0; i < 2; i++)
{
for ( j = 0; j< 3; j++)
{
37
if ( ( mat [i][j] %2 == 0) mat[i][j] = mat[i][j] + 5; cout << mat [i][j] << " ";
} |
|
cout << endl; |
// Переведення рядка при виведенні матриці |
} |
|
}
Другий варіант програмної реалізації — матриця описана як масив покажчиків.
//P2_13.CPP — матриця описана як масив покажчиків:
#include < iostream> using namespace std; main ( )
{
int і, j, *pm[2];
cout << "Введіть матрицю "<< endl; for ( i = 0; i < 2; i++)
for ( j = 0; j < 3; j++) cin >> *( pm[i] + j );
cout << " Матриця МАТR "<< endl; for ( i = 0; i < 2; i++)
{
for ( j = 0; j < 3; j++)
{
if ( *(pm[i] + j) %2 == 0 ) *( pm [i] + j ) += 10;
cout << *( pm [i] + j) << " ";
}
cout << endl;
}
return 0;
}
У розглянутій програмі для виведення матриці можна використовувати інший вигляд оператора :
сout << ( (j == 0) ? '\t':' ') << *( pm[i]+j ) << ( (j == 2) ? '\n':' ') ;
38
Ім'я двовимірної матриці є покажчиком-константою на масив покажчиківконстант, кожний з яких указує на початок відповідної рядка матриці, наприклад для матриці mat [2] [2] маємо :
mat [0] — покажчик-константа на нульовий рядок матриці;
mat [1] — покажчик-константа на перший рядок матриці;
mat [2] — покажчик-константа на другий рядок матриці;
тобто: mat[0] == &mat[0][0];
mat[1] == &mat[1][0];
mat[2] == &mat[2][0];
Виведення матриці можна реалізувати в такий спосіб:
cout << mat [i] [j]; cout << *( mat [i] +j );
cout << *(* (mat +i )+j );
У С++ можна описати змінну, що має тип "покажчик на покажчик". Ознакою такого типу є повторення символу "*" при описі змінної, наприклад int ** pmt; при цьому пам'ять для такої змінної не виділяється. Її треба привести до відповідного масиву. При описі покажчик на покажчик можна ініціалізувати, наприклад :
int x = 20;
int *px1 = &x; int** px2 = &px1; int ***px3 = &px2;
Доступ до змінної x тепер можна здійснити одним із трьох способів:
*px1; **px2; ***px3; .
Для доступу до пам'яті через покажчики на покажчики можна використовувати як індекси так і символи "*", наприклад, еквівалентними
будуть посилання на змінну x: |
|
px1 [0] |
*px1; |
px2 [0][0] |
**px2; |
px3 [0][0][0] |
***px3; |
39
2.6Контрольні питання
1.Що таке масив?
2.Як здійснюється опис масивів у програмі?
3.Як вибирається елемент масиву з пам'яті?
4.Які ще оператори мови C++ можна використовувати для введення елементів масиву в пам'ять комп'ютера?
5.Скільки циклів треба використовувати для введення, виведення і перебору елементів матриці?
6.Як звернутися до довільного елемента масиву?
7.Які обмеження існують у C++ на розмір і розмірність масивів?
8.Як вивести на друк матрицю в природному вигляді?
2.7.Варіанти індивідуальних завдань
У запропонованих нижче варіантах завдань конкретні значення масивів задаються довільно.
1.Обчислити добуток і кількість негативних елементів масиву М(15).
2.Знайти максимальний елемент масиву Х(12) і його індекс.
3.Усі від‘ємні елементи масиву М(15) записати в масив МО, а додатні —
уМР. Вивести отримані масиви на екран.
4.Знайти мінімальний елемент масиву Х(17) і його індекс.
5.Група учнів з 20 чоловік здавала іспит. Вивести порядкові номери учнів, що одержали ―5‖ і ―4‖.
6.Обчислити суму і кількість парних елементів масиву Х(15).
7.Відсортувати елементи масиву М(17) за зменшенням значень.
8.Усі негативні елементи масиву H(15) розділити на його мінімальний елемент.
9.Елементи масиву Х(15), що мають непарні значення, записати в масив Х1, а парні — у масив Х2.
10.Відсортувати елементи масиву Y(20) за зростанням.
11.Всі елементи масиву М(15), що знаходяться раніш його мінімального елемента, записати в масив М1, а інші — у М2.
12. Обчислити y a x i2 x i і знайти максимальне значення цієї функції, якщо a = 10,5; а хi — масив чисел, що має 10 значень.
13.Знайти мінімальний елемент матриці K(3,5) і його індекс.
14.Всі елементи матриці М(4,5) з непарними значеннями замінити на 1, а
зпарними — на 0.
15.Усі від‘ємні елементи матриці Р(3,4) записати в масив РО, а додатні — у масив РР.
16.Всі елементи матриці Matr(3,5), що мають непарні значення, записати в масив М1, а парні — у масив М2.
40