Тема 6 Масиви і вказівники

Лекція 20

 Масиви.  Використання масивів

На практиці часто виникає необхідність в обробці даних у вигляді довільного набору значень, тобто масивів. Масив являє собою кінцеву іменовану послідовність величин од­ного типу, які розрізняються за порядковим номером. Опис ма­сивiв у програмі відрізняється від опису простої змінної наявніс­тю після імені квадратних дужок «[ ]», в яких задається кількість елементів масиву (розмірність). Слід нагадати, що у мові C нумерація елементів масиву починається з 0.

Розглянемо одновимірні масиви, оголошення яких допус­кае одну з таких форм запису:

<тип> <ім’я> [n];

<тип> <ім’я> [n] = {значення};

<тип> <ім’я> [  ] = {значення};

При оголошенні одновимірного масиву, коли масив відразу iніціюється, можна не вказувати його розмір. Якщо ж ініціюван­ня не здійснюється під час оголошення масиву, то кількість ін­дексів слід задати обов’язково константним виразом. Наприклад:

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[0]={0};.

За замовчуванням, якщо в оголошеному масиві ініціюється тільки декілька перших елементів, то його інші елементи ініціюються нулями. Так, у випадку, коли float mas[10]= {2.2,34.56};, останні вісім елементів масиву одержать значення 0.

Проiлюструємо використання одновимірних масивів на конкретних прикладах.

Приклад Обчислити функцію у = axi2 – sinxi аргументи якої xj – елементи одновимірного масиву, що мають значення:

х0 = −0,81; x1 = −0,58; х2 = −0,11; х3 = 0,2; х4 = 0,91; x5 = 1,83

 Алгоритм передбачає введення значень одновимірного масиву xi (і = 0…n−l), n = 6 та подальше застосування їx для обчислення функції.

У програмі спочатку описується масив дійсних значень : float х[n]. Введення елементів масиву здійснюється у циклі.

 Цей цикл містить операцію потокового введення cin >> x[i];, перед якою знаходиться пiдказка cout << “х[ ” << і << “] =”; для вказiвки номера елемента x[i]. Особливість виконання операцii введення cin >> x[i]; полягає в такому: зустрiвши її у програмi, комп’ютер призупинить виконання програми, поки не буде введене значення еле­мента х[і] і натиснута клавіша Enter, пiсля чого робота програми буде продовжена. Зазначена операцiя введення повторюється n разiв для забезпечення введення всiх елементiв масиву.

Оскільки у С індексація елементiв масиву починается з нуля, то масив float x[6] (n = 6) iз шести елементiв включае идексованi елементи x[0], x[1], x[2], …, x[5]. Програма  використовуе два цикли: один – для введення ма­сиву, інший — для обчислення функції. Операцii введення елементів масиву та обчислення значень функції можна здiйсніити в одному циклi

/* ввід елементів одномірного масиву івизначення функції проводиться в одному циклі */

#include <iostream.h>

#include <math.h>

#include <conio.h>

main ( )

{ const int n = 7;

  float x[n], y, a(10.5);

  int i;

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

  {

    cin >> x[i];        //ввід елементу масиву

    y = a * x[i] * x[i] − sin(x[i]);

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− вивід результата

   cout << " x["<<i<<"] ="<<x[i]<<" y = " << y << endl;

 }

getch ();

}

Результати обчислень:

−0.81 −0.58 −0.11  0.2  0.91  1.83
x[0] = −0.81     у = 7.61334
х[1] = −0.58     у = 4.08022
х[2] = −0.11     у = 0.236828
x[3] = 0.2        у = 0.221331
x[4] = 0.91      у = 7.90555
х[5] = 1.83      у = 34.1969

У цьому випадку передбачено введення елементів масиву в рядок, і клавішу Enter слід натиснути в кiнцi процесу введення.

Приклад  За один перегляд масиву cі(і = 0…n−l), n = 15 визна­чити значення, а також положення максимального і мінімального йо­го елементів та поміняти їх місцями.

/* визначення максимального і мінімального елементів масиву c[n] і перестановка їх місцями */

#include <iostream.h>

#include <conio.h> 

const n=15;

void main ()

{   //опис масиву с[n] і його ініціалізація

  float с[n] = {6.4, 1.5, −5.6, 3.7, 18.9, 10.3, −0.6, 44.5,−0.2, 8.9, 55.3, 6.9, 4.3, 7.7, 10.9};

  float max, min;       // максим, (max) и мінім. (min) елементи

int imax, imin;        // індекси елементів

//−−−−−−−−−−−−−−−−−−−−−−−−−−вивід заданного массиву с[n]

  cout << " ***** massiv c[n] ***** n= " << n << endl;

  for (int і = 0; і < n; і++) 

  cout << с[і] << " ";

/* визначення максимального і мінімального елементів масиву та їх індексів — imax, imin */

 max = min = c[0];

  imax = imin = 0;

  for (int i =1; i<n; i++)

  {

    if (c[i] >max)

 { max = c[i];

      imax = i; }

    else

    if (с[і] < min)

    { min = с[і];

      іmin = і; }

  }

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− перестановка max и min

  c[imin] = max;

  c[imax] = min;

//−−−−−−−−−−−−−−−−−−−−−−−− вивід max, min, imax, imin

  cout << ”\n\t max=  " << max << " min= " << min << endl;

  cout << "\t imax= " << imax+1 << " imin= " << imin+1 << endl;

//−−−−−−−−−−−−−−−−−−−−−−−−вивід перетворенного масива c[n]

  cout << " **** Rezult massiv ****” << endl;

  for (int і = 0; і < n; i++)

  cout << c[i] << " " ;

  getch ();       // затримка екрану

}

Результати обчислень:

***** massiv c[n] ***** n= 15
6.4 1.5 −5.6 3.7 18.9 10.3 −0.6 44.5 −0.2 8.9 55.3 6.9 4.3 7.7 2.1 
max= 55.3          min= −5.6

imax= 11           іmin= 3 

**** Rezult massiv ****

6.5 1.5 55.3 3.7 18.9 10.3 −0.6 44.5 −0.2 8.9 −5.6 6.9 4.3 7.7 2.1     

Крім одновимірних масивів, тобто таких, де позиція еле­мента визначається за допомогою одного індексу, у практиці розв’язання задач часто застосовуються багатовимірні масиви. У них позиція елемента визначається записом декількох індек­сів. Найбільш розповсюджені двовимірні масиви або матриці. Матриці являють собою порядковий запис декількох однови­мірних масивів. Місце розташування кожного елемента визна­чається за допомогою двох індексів — номера рядка і номера стовпця, тобто порядкового номера в рядку. Індекси двовимір­них масивів записуються в квадратних дужках і нумерація ін­дексів починається з нуля (0).

Наприклад, двовимірний масив цілих чисел int а[3][4], що має три рядки та чотири стовпці:

а[0][0]

а[0][1]

а[0][2]

а[0][3]

а[1][0]

а[1][1]

а[1][2]

а[1][3]

а[2][0]

а[2][1]

а[2][2]

а[2][З]

У пам’яті комп’ютера масив розташовується безперервно за рядками:

а [0][0], а [0][1], а [0][2], а [0][3], а [1][0], а [1][1], а [1][2], а [1][3], … а [2][3].

Двовимірні (і багатовимірні) масиви оголошуються так:

int mas [2][5] ={ 1, 5, 3, 7, 4,10, 11, ІЗ, 14, 25 };

int mas [  ][5] ={ 1, 5, 3, 7, 4, 10, 11, 13, 14, 25 };

int mas [  ][5] ={ { 1, 5, 3, 7, 4 },{10, 11, 13, 14, 25} };,

тобто масив задається або списком елементів у тому порядку, и якому вони розташовані у пам’яті, або подається як масив ма­сивів, кожний з яких поміщається в свої фігурні дужки«{}». При оголошенні і одночасному ініціюванні багатовимірних ма­сивів можна опускати кількість індексів тільки першого виміру. Якщо ініціювання не здійснюється під час оголошення масиву, то кількість індексів треба вказувати явно.

Для здійснення введення−виведення, а також для обробки елементів двовимірного масиву у програмі слід передбачати організацію двох циклів: один — для задання значень індексу рядків, другий — індексу стовпців.

Приклад Кожний елемент матриці М(3,4) збільшити на задане число.

// збільшення елементів матриці на задане число 

#include <iostream.h>

#include <conio.h>

main()

{

  const int n = 3, m = 4;      /* n и m – кількість стрічок і стовпців матриці */

  float М [n][m], z = 10;      // z — задане число

  int і, j;

//−−−−−−−ввід елементів матриці і їх збільшення на z

  cout << "**** Vvod matrix " << endl;

  for (і = 0; і<n; i++)

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

 { cout << " M [" << і << "]" << "[" << j << "]=";

      cin >> M [i][j];

      M [i][j] += z;            // M [i][j]= M [i][j] + z;

   }

//−−−−−−−вивід отриманої матриці

  cout << "\n\n***** Rezult matrix: ";

 for (і = 0; і < n; і++)

  { cout << endl;   

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

    cout << M [i][j] << " “;}

 getch();       // затримка екрану

}

Результати виконання програми:

***** Vvod matrix 

М [0][0]=4.5 

М [0][1]=6.7 

М [0][2]=4.8 

М [0][3]=23.6 

М [1][0]=5.7 

М [1][1]=3.7 

М [1][2]=2.9 

М [1][3]=6.1 

М [2][0]=1.2 

М [2][1]=4.5 

М [2][2]=4.6 

М [2][3]=2.7

***** Rezult matrix:

14.5   16.7   14.8   33.6

15.7   13.7   12.9   16.1

11.2   14.5   14.6   12.7

У програмі при описі матриці float M[n][m]; вказується діа­пазон змiни двох iндексiв, перший з яких призначений для iн­дексування рядків (і), другий — для індексування стовпців (j). Введення, обробка і виведення елементів матриці здійснюються за допомогою двох циклів, один з яких є вкладеним в іншій. Це дозволяє при кожному значенні змінної і перебирати всі значення змінної j. Розглянута програма може бути скорочена шляхом об’єднання всіх трьох блоків циклу в один, але в такс­му випадку вона буде менш наочною.

Приклад Елементи головної та бічної діагоналей матри­ці С(4,4) поміняти місцями. Визначити максимальний елемент пере­твореної матриці, а також номери рядка та стовпця, на перетині яких він знаходиться.

Програму розроблено з використанням алгоритму знахо­дження максимального елемента масиву та його індексів

//P65.CPP перестановка елементів головної і бічної діагоналей

//визначення максимального елемента матриці і його індексу

#include <iostream.h>

#include <conio.h>

void main ()

{ const int n = 4;

  int і, j, imax, jmax;

 float max, C[ ][n] = {  {3.6, 8.9, 1.9, 5.8},

                                {8.8, 4.1, 1.2, 6.3},

                                {2.5, 6.4, 0.1, 5.5},

                                {8.8, 4.1, 1.2, 6.3} };   //ініціалізація С[n][n]

//−−−−−−−−−−−−−−−−−−−−вивід початкової матриці

 cout << " ***** massiv C[n][n] *****"; 

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

  { cout << endl;

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

    cout << C[i][j] << " "; }

//−−−−−−−−−−−−−−−−−−−−−−−−−−− перестановка елементів 

  float rab;          // змінна для перестановки

  for (i = 0; i < n; i++)     // for (i = 0, j = n−1; i < n; i++, j−−)

 { j = n−1−i;                    // { rab = C[i][i];

  rab = C[i][i];                //C[i][i]=C[i][j];

C[i]|i] =C[i][j];             //C[i][j] = rab; }

C[i][j] = rab; }

//−−−−−−−−−−−−−−−−−−−−−−−−−−−−− вивід перетворенної матриці

 cout<<"\n\n ***** REZULT massiv ***** ";

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

  { cout << endl; 

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

    cout << C[i]|j] << "   "; }

// визначення max елемента матриці і його індексів — imax, jmax 

  max = С[0][0];

  imax = jmax = 0;  

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

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

      if (С[i][j] > max)

      { max = C[i][j];  

        imax = i; jmax = j; }

  cout << "\n\n max= " << max << "  index stroki = " << imax+1 << “ index stolbca = “<< jmax+1;

  getch();

}

Результати обчислень:

***** massiv C[n][n] *****
3.6  8.9  1.9  5.8
8.8  4.1  1.2  6.3
2.5  6.4  0.1  5.5
8.8  4.1  1.2  6.3
***** REZULT massiv *****
5.8  8.9  1.9  3.6
8.8  1.2  4.1  6.3
2.5  0.1  6.4  5.5
6.3  4.1  1.2  8.8
max = 8.9 index stroki = 1 index stolbca = 2 .

 

Покажчики та масиви

Покажчики — це змінні, котрі містять адресу пам’яті, роз­поділеної для об’єкта відповідного типу. Усі змін­ні, розглянуті до цього, зберігали якісь значення (дані). Ці дані могли бути різних типів: символьного, цілого, дійсного тощо. При оголошенні змінної−покажчика слід вказати тип даних, адресу яких буде містити змінна, та ім’я покажчика з симво­лом «*».

Загальний формат опису покажчика має вигляд:

тип *ім’я;

де тип — тип значень, на який вказує покажчик;

ім’я — ім’я змінної−покажчика;

«*» — операція над типом, що читається «покажчик на тип».

Наприклад:

int *рn – покажчик на ціле значення;

float *pf1, *pf2; — два покажчики на дійсні значення.

Покажчики не прив’язують дані до якого−небудь визначе­ного імені змінної і можуть містити адреси будь−якого неімено­ваного значення. Існує адресна константа NULL, що означає порожню адресу.

Слід нагадати, що мова C налічує лише дві операції, які стосуються адрес змінних, а саме:

«&»операція взяття адреси («адреса значення»);

«*»операція розіменування («значення за адресою»).

Операція взяття адреси «&» застосовується разом зі змін­ною і повертає адресу цієї змінної. Операція розіменування «*» використовується разом з покажчиками і вилучає значення, на яке вказує змінна−покажчик, розташована безпосередньо після символа «*».

Оголошення покажчиків можна здійснити одним з таких способів:

<тип> *ptr;

<тип> *ptr = <змінна−покажчик>;

<тип> *ptr = &<ім’я змінної>;.

Наприклад:
int *ptx, b; float у; — оголошені змінна−покажчик ptx та змінні b і у;

float *sp = &у; — покажчику sp присвоюється адреса змінної у;

float *р = sp; — покажчику р присвоюється значення (адреса зна­чення), яке міститься в змінній sp, тобто адреса змінної у.

При оголошенні покажчиків символ «*» може знаходитися перед ім’ям покажчика або відразу після оголошення типу по­кажчика і поширювати свою дію тільки на одну змінну−покаж­чик, перед якою він записаний:

long *pt;   long*Uk;   int *ki, x, h; оголошення описів.

За потреби для опису покажчика на комірку довільного типу замість ідентифікатора типу записується слово void, а саме:

void *р, *pt; — опис двох покажчиків на довільний тип даних.

Перед використанням покажчика у програмі його обо­в’язково необхідно ініціювати, іншими словами, необхідно присвоїти адресу якого−небудь даного, інакше можуть бути не­передбачені результати.

Для одержання доступу до значення змінної, адреса якої зберігається в покажчику, досить у відповідному операторі про­грами записати ім’я покажчика з символом «*» — здійснити операцію розіменування.

Розглянемо фрагмент програми з поясненнями:

int *р, *р1; — оголошені два покажчики на комірку пам’яті типу int;

int х = 12, у = 5, m[7]; — оголошені змінні х, у і масив m, змінні ініційовані;

р = &у;      // р (&у); — покажчику р присвоєна адреса змінної у.

Якщо для цього фрагмента програми записати оператор ви­ведення у вигляді

cout << “Адрес р ” << р << “Значение по этому адресу = ” << *р;,

то виведеться адреса комірки пам’яті, де записана змінна у і зна­чення цієї змінної (тобто 5).

Використовуючи запис х = *р;, одержимо х = 5, тому щo *р = у = 5;.

Змінити величину параметра у можна так:

у = 10;          // *Р= 10;

*р = *р+5;    //у +=5;.

Остання операція означає збільшення значення змінної у цi­лого типу на 5, тобто у= 15.

При ініціюванні покажчиків їм можна присвоювати або адресу об’єкта (змінної), або адресу конкретного місця пам’яті (масиву), або число 0 (нуль), а саме:

int *pt = (char *) 0x00147; — присвоюється адреса комірки;

int *arrpt = new int [10]; — визначається початкова адреса розмі­щення динамічного масиву;

char *р = 0; — здійснюється ініціювання нулем.

Оскільки покажчики — це спеціальні змінні, то в операці­ях з іншими покажчиками вони можуть використовуватися без символа «*», тобто без розкриття посилання, наприклад:

float *pt1, *pt2, х=15, m[5];

pt1 = &x; 

pt2 = pt1;

pt1 = m;         //pt1 = &m[0];

де m — ім’я масиву, що розглядається як спеціальний покаж­чик−константа.

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

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

#include <iostream.h>

#include <conio.h>

int main ( )

{ int x = 10;

  int *px (&x);   // 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, т. e. x = " << x << endl;

  getch();     //затримка екрану

}

Результат виконання програми:

х = 10 

*рх = 10

Новое значення *рх = 20 

Результат *рх, т. е. х = 22

Для змінної−покажчика існує своя адреса і тому будуть до цільними записи:

int *pt1, *pt2;

pt1 = (int*) &pt2; — покажчику pt1 присвоюється адреса пам’ятi де розташована змінна pt2.

Це має сенс у випадку, коли

int у, *pt1, *pt2 = &у;

pt1 = (int*) & pt2;.

Обмеження на застосування операції взяття адреси:

·         не можна визначати адресу літеральної константи (оскіль­ки для неї не виділяється комірка пам’яті), тобто такий запис, як vp = &345; — неприпустимий;

·         не можна визначати адресу результату арифметичного виразу, тобто запис vp = &(x + y); теж неприпустимий.

Дозволені операції для змінних−покажчиків:

·         операція розіменування «*»;

·         операція взяття адреси «&»;

·         операція присвоювання «=»;

·         операції інкремент «++» і декремент « –»;

·         операції додавання «+» і віднімання «−»;

·         операції відношення (порівняння) покажчиків однакового типу: «==», «!=», «<», «<=», «>», «>=».

У мові C масиви і покажчики зв’язані між собою: ім’я масиву визначається як покажчик−константа на початковий (нульовий)елемент масиву. Так, наприклад, при оголошенні одновимірного масиву у вигляді int mas [20]; його ім’я mas – покажчик на адресу початкового елемента масиву &mas[0].

Існує два способи доступу до елементів масиву:

·         з використанням індексу елемента масиву, наприклад, mas[2] або mas[i];

·         з використанням адресного виразу, тобто виразу з по­кажчиком на масив, наприклад, *(mas + 2) або *(mas + і).

Ім’я покажчика на масив можна записати так:

int mas [20];

int *ptr1;

ptr1 = mas;      //ptr1 = &mas[0];,

тут вирази &mas[0] і mas — еквівалентні.

Оскільки в комп’ютері для масивів завжди є суцільний блок комірок пам’яті, в яких розташовуються їх елементи, то адресу наступного елемента mas[1] можна вказати шляхом збільшення покажчика на 1, а саме:

р = &mas[0];

р++;            //р=р  + 1;

Таким чином, адреса і−го елемента визначається як р + і. При цьому з урахуванням типу масиву і відведеної кількості байтів для кожного його елемента автоматично виконується операція збiльшення адреси, тобто:

адреса х[і] = адреса х[0] + i*sizeof (тип); .

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

До двох покажчиків р1 і р2, що вказують на елементи од­ного масиву, застосовують операції відношення: «==», «!=», «<», «<=», «>», «>=». При цьому значення покажчиків роз­глядаються як цілі числа, а результат порівняння дорівнює 0 ( »неправда») або 1 («істина»). Так, відношення вигляду р1<р2 є «істина», якщо р1 указує на більш ранній елемент, ніж р2. Будь−який покажчик можна порівняти з нулем.

В арифметиці з покажчиками можна використовувати ад­ресу неіснуючого «наступного за масивом» елемента. До покаж­чиків можна додавати або віднімати від них цілу величину.

В обох випадках результатом операції буде покажчик на вихід­ний тип, значення якого на вказане число елементів більше або менше вихідного. Тобто, якщо до покажчика р можна додати деяку цілу величину n, а саме: р + n, то цей вираз визначає ділянку об’єкта, що займає n−не місце після об’єкта, на який вказує р, при цьому n автоматично збільшується на коефіцієнт, що дорівнює відповідній довжині об’єкта. Наприклад, якщо int займає 4 байти, то цей коефіцієнт дорівнює чотирьом.

Допускається також операція віднімання покажчиків, що вказують на елементи одного масиву. Так, якщо р1 < р2, то р2 – р1 + 1 — це число елементів масиву від р1 до р2 включно.

Наведемо приклади програм роботи з покажчиками.

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

Розглянемо перший варіант програмної реалізації цієї задачі  .

/* визначення середнього значення додатніх елементів масиву */

//−−−−−−−−−−−−−−−− програма без покажчиків

#include <iostream.h>

#include <conio.h>

main( )

{ const int n = 10;

  float mas[n], s = 0;

  int i, kol = 0;

  cout << "Ввід масива " << endl;

  for(i =0; і < n; i++)

    cin >> mas[i]; 

      for(i = 0; і < n; i++)  

        if (mas[i] > 0) 

{ s += mas[i];           //накопление суммы

          kol++;  //подсчет положительных елементов

        }

 cout.precision(3 ) ; 

  cout << "Середн. арифм. = " << s/kol << endl; 

 getch();         //затримка екрану

}

Результати виконання програми:

Ввід масива

1.56 −4.78 6.5 7.89 −3.6 9.45 7.4 −8.43 9.3 −10.2

Середн. арифм. = 7.02

Використовуючи ім’я масиву як покажчик на початок масиву (перший елемент), можна навести другий варіант програми :

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

#indude <iostream.h>

#include <conio.h>

main ( )

{ const int n = 10; 

  float mas[n], s; 

  int i, kol = 0;

  for (і = 0, s = 0; і < n; i++)

  { сіn >> *(mas+i);

    if (*(mas+i) > 0)

     { s += *(mas+i);

       kol++; } 

  } 

  cout.precision(3); 

  cout <<"\n Середнє арифм.  = " << s/kol << endl; 

  getch();

}

Якщо описати покажчик і зв’язати його з масивом (адре­сувати на початок масиву), то з використанням арифметики покажчиків можна написати третій варіант  цiєї програми.

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

#include <iostream.h>

#include <conio.h>

main ( )

{ const int n = 10;

  int і, kol(0);

  float mas[n], s(0);

  float *pm = mas;         //pm= &mas[0];

for (і = 0; і < n; i++) 

  { cout << "Введіть" << і << "елемент mas" << endl;

    cin >> *pm++;

    cout << mas[i] << endl;

    if (mas[i] >0)

    { s += mas[i];

      kol++; } 

  }

  cout.precision(3);

  cout << "\n Середнеє арифм. = " << s/kol << endl;

  getch();

}

У цій програмі для введення масиву застосований покажчик *рm, а для роботи з масивом — ім’я масиву з індексом.

В останньому випадку використання покажчика *рm призвело б до помилкового результату, оскільки цей покажчик в опера­ціях введення збільшує свою адресу (рm++) після введення чергового елемента масиву і надалі вказує на ще не введений елемент.

Наведемо четвертий варіант програмної реалiзації прикладу:

/* використання покажчиків

#include <iostream.h>

#include <conio.h>

main ( )

{ const int n = 10;

  float mas[n], s = 0;

  float *pm = &mas[0];     //pm *= &mas[0];

 int i, kol = 0;

  for (і = 0; і < n; i++)

  { cout << "Введіть" << і << "елемент mas" << endl;

    cin >> *pm; 

    if (*pm >0)

    { s += *pm;

      kol++;

      pm++; } 

  }

  cout.precision(3);

  cout << ”\n Середнє арифм.  = " << s/kol << endl;

 getch();

}