Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Информатика.ЛБ

.pdf
Скачиваний:
15
Добавлен:
14.04.2015
Размер:
950.97 Кб
Скачать

{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