ВІКІСТОРІНКА
Навигация:
Інформатика
Історія
Автоматизація
Адміністрування
Антропологія
Архітектура
Біологія
Будівництво
Бухгалтерія
Військова наука
Виробництво
Географія
Геологія
Господарство
Демографія
Екологія
Економіка
Електроніка
Енергетика
Журналістика
Кінематографія
Комп'ютеризація
Креслення
Кулінарія
Культура
Культура
Лінгвістика
Література
Лексикологія
Логіка
Маркетинг
Математика
Медицина
Менеджмент
Металургія
Метрологія
Мистецтво
Музика
Наукознавство
Освіта
Охорона Праці
Підприємництво
Педагогіка
Поліграфія
Право
Приладобудування
Програмування
Психологія
Радіозв'язок
Релігія
Риторика
Соціологія
Спорт
Стандартизація
Статистика
Технології
Торгівля
Транспорт
Фізіологія
Фізика
Філософія
Фінанси
Фармакологія


Використання масивів і покажчиків

 

У мові С++ масиви і покажчики зв'язані між собою. При оголошенні масиву у вигляді :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[0] = {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 . Всякий покажчик можна порівняти з нулем.

Варто звернути увагу, що для покажчиків, що посилаються на елементи різних масивів, результат арифметичних операцій і відносин не визначений. В арифметиці з покажчиками можна використовувати адресу не існуючого "наступного за масивом " елемента. Крім того, до покажчика можна додати деяке ціле значення, наприклад можна записати:

р + n ; ,

де n— ціле значення, а р — покажчик.

Цей вираз визначає область об'єкта, що займає n -те місце після об'єкта, на який указує р, при цьому nавтоматично збільшується на коефіцієнт,що дорівнює відповідній довжині об'єкта. Наприклад , якщо intзаймає 4 байти , те цей коефіцієнт дорівнює чотирьом.

Допускаються також gjhsdyzyyz покажчиків, що вказують на елементи одного масиву.

Наприклад, якщо р1< p2,тер2 - р1+1 — це число елементів масиву від р1дор2включно.

Таким чином, з покажчиками допускаються наступні операції :

— присвоювання значення одного покажчика іншому;

— додавання і вирахування покажчиків і даного цілого типу ( р+5 );

—порівняння двох покажчиків, що посилаються на елементи одного масиву;

— присвоювання покажчику нуля і порівняння з нулем.

Інші операції з покажчиками заборонені.

Для покажчика дозволяються вирази вигляду:

 

р1 = mas;або р++ ,

 

тут р— покажчик , mas — масив.

Розглянемо демонстраційні приклади програм роботи з покажчиками.

Приклад 2.4Обчислити середнє значення позитивних елементів одновимірного масиву.

Наведемо кілька варіантів програмної реалізації цієї задачі.

// P2_7.CPP — обчислення середнього значення

// додатних елементів масиву

//програма без використання покажчиків

#include <iostream.h>

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_8.CPP — обчислення середнього значення

// додатних елементів масиву

//використання імені масиву як покажчика на його початок

#include < iostream.h>

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.h>

Main ( )

{

int kol = 0;

const int n = 5;

float mas[n], s = 0;

float *pm = mas; //припустимийзапис pm=&mas[0]

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.h >

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)

{

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;

for ( i = 0; i < 6; i++)

cout << i << " елемент " << *(pmas + i ) << endl;

//Можна використовувати і таку конструкцію оператора

// cout << i << " елемент " << * pmas++ << endl;

getch ( ); //Для затримки екрана виведення результату

return 0;

}

Масиви покажчиків

Як і інші змінні, покажчики можна групувати в масиви, кожен елемент якого містить адресу рядка масиву даних у пам'яті. У такий спосіб можна зберігати дані з "рваними" краями. Цей масив схожий на двовимірну таблицю з одним виключенням: усі рядки в такому масиві можуть мати різну довжину. При збереженні рядків це дозволяє заощаджувати пам'ять, а при виконанні сортування рядків, вона виконується значно швидше, тому що змінююється тільки покажчики, а не значення рядків.

Fio

(0) -> П Е Т Р О В \0  
(1) -> І В А Н О В \0  
(2) -> К У Ц И Й \0    
(3) -> В А Р І Ч \0    
(4) -> Ю Ш К О \0      
(5) -> П Л Ю Щ \0      

Приведемо програму реалізуючу виведення подібної інформації з використанням масиву покажчиків.

// P2_11.CPP

#include <iostream.h>

Main ( )

{

char *fio [ ] = { "Петров",

"Іванов" ,

"Куций",

"Варич",

"Юшко",

"Плющ " };

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.h >

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++)

{

if ( ( mat [i][j] /2 )*2 == mat[i][j])

mat[i][j] = mat[i][j] + 5;

cout << mat [i][j] << " ";

}

cout << endl; //Переведення рядка при виведенні матриці

}

}

Другий варіант програмної реалізації матриця описана як масив покажчиків.

 

//P2_13.CPP — матриця описана як масив покажчиків:

#include < iostream.h >

Main ( )

{

int і, j, *pm[2];

cout << "Введіть матрицю "<< endl;

for ( i = 0; i < 2; i++)

for ( j = 0; j < 3; j++)

cin >> *( pm[i] + j );

cout << " Матриця МАТ "<< endl;

for ( i = 0; i < 2; i++)

{

for ( j = 0; j < 3; j++)

{

if ( *(pm[i] + j) / 2*2 == *( pm[i] + j ) )

*( pm [i] + j ) += 10;

cout << *( pm [i] + j) << " ";

}

cout << endl;

}

return 0;

}

У розглянутій програмі для виведення матриці можна використовувати інший вигляд оператора :

 

сout << ( (j == 0) ? '\t':' ') << *( pm[i]+j ) << ( (j == 2) ? '\n':' ') ;

Ім'я двовимірної матриці є покажчиком-константою на масив покажчиків-констант, кожний з яких указує на початок відповідної рядка матриці, наприклад для матриці 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;

2.6 Контрольні питання

1. Що таке масив?

2. Як здійснюється опис масивів у програмі?

3. Як вибирається елемент масиву з пам'яті?

4. Які ще оператори мови C++ можна використовувати для введення елементів масиву в пам'ять комп'ютера?

5. Скільки циклів треба використовувати для введення, виведення і перебору елементів матриці?

6. Як звернутися до довільного елемента масиву?

7. Які обмеження існують у C++ на розмір і розмірність масивів?

8. Як вивести на друк матрицю в природному вигляді?

 

© 2013 wikipage.com.ua - Дякуємо за посилання на wikipage.com.ua | Контакти