Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

05 Arrays

763 views

Published on

Published in: Business, Technology
  • Be the first to comment

05 Arrays

  1. 1. Бублик Володимир Васильович Програмування - 2 Лекція 5. Базові поняття програмування. Масиви Лекції для студентів 2 курсу
  2. 2. Визначення масиву <ul><li>Послідовність імен x[0], x[1], …, x[n] походить від команди IR LOAD x </li></ul>
  3. 3. Визначення масиву <ul><li>“ Старомодні ” масиви в стилі С </li></ul><ul><li>double x[3]; </li></ul><ul><li>Визначає три елементи пам'яті, розміщені послідовно та пронумеровані, починаючи з 0 </li></ul><ul><li>x[0], x[1], x[2] </li></ul>
  4. 4. Статичні масиви <ul><li>Але компілятор не перевіряє на коректність вихід індексу за межі масиву </li></ul><ul><li>x[-1000], x[3], x[4], x[10000] … показують в нікуди </li></ul>
  5. 5. Ініціалізація масивів <ul><li>double x[3]= {0.1, 0.2, 0.3}; </li></ul>
  6. 6. Ініціалізація масивів <ul><li>double x[3]= {0.1, 0.2, 0.3}; </li></ul><ul><li>cout<<x[0]<<' '<<x[1]<<' '<<x[2]<<endl; </li></ul><ul><li>cout<<x[ 3 ]<<' '<<x[ -1 ]<<' '<<x[ 100 ]<<endl; </li></ul><ul><li>double x [3]= {0.1, 0.2}; // не дуже добре , x[2] ? </li></ul><ul><li>// список ініціалізації коротший , ніж розмірність </li></ul><ul><li>// (довший не пропустить компілятор) </li></ul><ul><li>double z[]= {0.1, 0.2, 0.3, 0.4, 0.5}; </li></ul><ul><li>// розмірність масиву визначається </li></ul><ul><li>// списком ініціалізації </li></ul>
  7. 7. Приклад програми <ul><li>// Скалярний добуток </li></ul><ul><li>const int n=10; </li></ul><ul><li>double x[n], y[n]; </li></ul><ul><li>… // масиви ініціалізуються </li></ul><ul><li>double s = 0; </li></ul><ul><li>for (int i=0; i<n; i++) </li></ul><ul><li>s+=x[i]*y[i] </li></ul>
  8. 8. Тип елемента масиву <ul><li>Масиви стандартних типів </li></ul><ul><li>int a[100]; </li></ul><ul><li>Масиви указників (головним чином для багатомірних масивів) </li></ul><ul><li>int i=1, j=1, k=1; </li></ul><ul><li>int *ip[] = {&i, &j, &k}; </li></ul><ul><li>Але не псевдонімів </li></ul><ul><li>int & ir [] = { i , j , k }; // Error </li></ul>
  9. 9. Двомірні масиви <ul><li>// Множення матриць </li></ul><ul><li>const int n =10; </li></ul><ul><li>double a [ n ][ n ], b [ n ][ n ], c [ n ][ n ]; </li></ul><ul><li>… // масиви ініціалізуються </li></ul><ul><li>for (int i=0; i<n; i++) </li></ul><ul><li>for (int j=0; j<n; j++) </li></ul><ul><li>{ </li></ul><ul><li>c[i][j] = 0; </li></ul><ul><li>for (int k=0; k<n; k++) </li></ul><ul><li>c[i][j]+=a[i][k]*b[k][j]; </li></ul><ul><li>} </li></ul>
  10. 10. Двомірні масиви. Розміщення в пам'яті <ul><li>const int m =2 , n=3 ; </li></ul><ul><li>double a [ m ][ n ]; </li></ul><ul><li>Двомірні масиви розміщуються рядками </li></ul><ul><li>a[0][0] </li></ul><ul><li>a[0][1] </li></ul><ul><li>a[0][2] </li></ul><ul><li>a[1][0] </li></ul><ul><li>a[1][1] </li></ul><ul><li>a[1][2] </li></ul>
  11. 11. Змінна з індексом <ul><li>Одномірний масив </li></ul><ul><li>x[i] </li></ul><ul><li>Двомірний масив </li></ul><ul><li>c[i][j] </li></ul><ul><li>Що б це значило? </li></ul><ul><li>a[i,j] </li></ul>
  12. 12. Змінна з індексом <ul><li>Одномірний масив </li></ul><ul><li>x[i] </li></ul><ul><li>Двомірний масив </li></ul><ul><li>c[i][j] </li></ul><ul><li>Що б це значило? ― Типова помилка </li></ul><ul><li>a[i,j] </li></ul><ul><li>value(a[I,j]) == value (a[(i,j)]) == value(a[j]) </li></ul>
  13. 13. Звичайний цикл обробки масиву <ul><li>for (int i=0; i<n; ++i) </li></ul><ul><li>// do something with x[i] </li></ul><ul><li>{ </li></ul><ul><li>……………………………… ..; </li></ul><ul><li>// наприклад, </li></ul><ul><li>cout<<x[i]<<endl; </li></ul><ul><li>} </li></ul>
  14. 14. Зв’язок масивів і указників <ul><li>Визначення масиву за допомогою указника </li></ul><ul><li>double *x = new double[n]; // (1) </li></ul><ul><li>Якщо n константа, масив статичний </li></ul><ul><li>const int n = 100; </li></ul><ul><li>Визначення дає той же ефект, що </li></ul><ul><li>double x[n]; // ( 1S ) </li></ul><ul><li>Особливість ( 1S ) полягає у можливості ініціалізації </li></ul>
  15. 15. Адресна арифметика <ul><li>Для довільного указника або масиву x мають місце тотожності </li></ul><ul><li>x[i] == *(x+i) </li></ul><ul><li>&x[i] == x+i </li></ul>
  16. 16. Ітератор <ul><li>const int n =4; </li></ul><ul><li>int ia[n]; </li></ul><ul><li>int *pcurrent = ia; </li></ul><ul><li>int * const pend = ia +n; </li></ul><ul><li>while (pcurrent!=pend) </li></ul><ul><li>cout<< *(pcurrent++) <<endl; </li></ul>
  17. 17. Вправа <ul><li>Порівняти два способи організації циклів над масивами. Визначити переваги і недоліки кожного з них </li></ul>
  18. 18. Динамічні масиви <ul><li>Якщо n змінна, </li></ul><ul><li>int n; </li></ul><ul><li>значення якої задано на момент визначення масиву, наприклад, за допомогою вводу </li></ul><ul><li>cin>>n; </li></ul><ul><li>то масив </li></ul><ul><li>double *x = new double[n]; // (1D) </li></ul><ul><li>називається динамічним . </li></ul><ul><li>Розмір динамічного масиву стане відомим лише під час виконання програми </li></ul>
  19. 19. Сценарій обробки динамічного масиву <ul><li>int n; // Розмір динамічного масиву </li></ul><ul><li>cout <<” Give your size : ”; </li></ul><ul><li>cin >> n ; </li></ul><ul><li>// Визначення указника і створення масиву </li></ul><ul><li>int *dynar = new int [n]; </li></ul><ul><li>// Ініціалізація </li></ul><ul><li>for (int i=0; i<n; i++) </li></ul><ul><li>dynar[i] = i; </li></ul><ul><li>// Обробка </li></ul><ul><li>int *pcurrent = dynar; </li></ul><ul><li>int *pend = dynar+n; </li></ul><ul><li>while (pcurrent!=pend) </li></ul><ul><li>cout<<*(p current ++); </li></ul><ul><li>// Видалення масиву </li></ul><ul><li>delete [] dynar; </li></ul>
  20. 20. Двомірні динамічні масиви <ul><li>int m=sizex, n=sizey; </li></ul><ul><li>int **ppi; </li></ul><ul><li>ppi = new int* [m]; </li></ul><ul><li>for (int i=0; i<m; i++) </li></ul><ul><li>ppi[i]=new int [n]; </li></ul>
  21. 21. Масиви указників <ul><li>Масив указників цілих </li></ul><ul><li>int * ppi [] читається як int *( ppi []) або int **ppi </li></ul>
  22. 22. Двомірні динамічні масиви (масив масивів) <ul><li>int m=sizex, n=sizey; </li></ul><ul><li>int **ppi; </li></ul><ul><li>ppi = new int* [m]; </li></ul><ul><li>for (int i=0; i<m; i++) </li></ul><ul><li>ppi[i]=new int [n]; </li></ul>
  23. 23. Використання масивів <ul><li>Масив, а тим більше масив масивів, завжди служить джерелом помилок в програмі (бо указники!) </li></ul><ul><li>Краще всього користуватися надійнішими контейнерами для даних, залишивши для масиву роль нижнього поверху, на якому будується реалізація контейнерів </li></ul>
  24. 24. Масиви символів <ul><li>Два способи ініціалізації: </li></ul><ul><li>Стандартний для всіх масивів </li></ul><ul><li>char hello [] = </li></ul><ul><li>{’ Д’, ’о’, ’б’, ’р’, ’и’, ’д’, ’е’, ’н’, ’ь’, ’!’, ’’ }; </li></ul><ul><li>за нульовий код відповідає програма </li></ul><ul><li>Спеціальний для символів </li></ul><ul><li>char hello [] = ” Добридень! ”; </li></ul><ul><li>нульовий код вбудує система </li></ul>
  25. 25. Масиви символів <ul><li><cstring> “чистий” С </li></ul><ul><li>Обчислення довжини рядка, порівняння двох рядків, копіювання рядків і інші корисні функції </li></ul><ul><li>size_t strlen(const char *); </li></ul><ul><li>char * strcpy(char *, const char *); </li></ul><ul><li>char * strncpy(char *, const char *, size_t); </li></ul><ul><li>int strcmp(const char *, const char *); </li></ul><ul><li>char * strcat(char *, const char *); </li></ul><ul><li>char * strchr(const char *, int ch ); // search for char ch </li></ul><ul><li>char * strstr(const char *, const char * s); //search for s </li></ul><ul><li>and many other … </li></ul>
  26. 26. Куди йдемо? <ul><li>Замість масивів символів char * використовуватимемо class string </li></ul><ul><li>Замість інших масивів ― class vector </li></ul><ul><li>Замість указників на зовнішньому рівні вживатимемо інтелектуальні указники (smart pointers) </li></ul>

×