notes

Массивы

Массивы

  1. Массив - набор однотипных элементов, расположенных в памяти друг за другом, доступ к которым осуществляется по индексу
  2. С++ позволяет определять массивы на стеке
     // array 1 2 3 4 5 0 0 0 0 0
     int m[10] = { 1, 2, 3, 4, 5};
    
  3. Переменная массива хранит указатель на первый элемент этого массива.
  4. Получение значения по индексу работает следующим образом
     m[i] => *(m + i)
    
  5. Арифметика указателей
     int m[10] = {1, 2, 3, 4, 5};
     int *p = &m[0]; // адрес начала массива
     int *q = &m[9]; // адрес последнего элемента массива
    
    • (p + k) - сдвиг на k ячеек типа int вправо
    • (p - k) - сдвиг на k ячеек типа int влево
    • (q - p) - количество ячеек между указателями
    • p[k] - эквивалентно *(p + k)
  6. Заполнениие массива по указателю
     int m[10] = {};
     for (int *p = m; p < m+9; ++p)
     {
         *p = (p - m) + 1;
     }
     // массив заполнен числами от 1 до 10
    
  7. Передача массива в функцию
     int max_element (int *m, int size) {
         int max = *m;
         for (int i = 1; i < size; ++i) {
             if (m[i] > max) {
                 max = m[i];
             }
         }
         return max
     }
    

Многомерные встроенные массивы

  1. С++ позволяет определять многомерные массивы
     int m2d[2][3] = { {1, 2, 3}, {4, 5, 6} };
     for (size_t i = 0; i != 2; ++i ) {
         for (size_t j = 0; j !=3; ++j) {
             cout << m2d[i][j] << ' ';
         }
         cout << endl;
     }
    
  2. Элементы m2d располагаются в памяти по строчкам

Динамические массивы

  1. Для выделения одномерных динамических массивов обычно используют оператор new [].
     int * m1d = new int [100];
    
  2. Какой тип долен быть у указателя на двумерный массив ?
    • Пусть m - указатель на двумерный массив типа int.
    • Значит m[i][j] имеет тип int (точнее int &).
    • m[i][j] <=> *(m[i] + j), т.е. тип m[i] - int *
    • аналогично m[i] <=> * (m + i), т.е. тип m - int **.
  3. Чему соответствует значение m[i] ?
    • Это адрес строки с номером i.
  4. Чему соотвествует значение m
    • Это адрес массива с указателями на строки.

Двумерные массивы

  1. Неэффективная схема 2 Dimentional Array

     int ** create_array2d(size_t a, size_t b) {
         int ** m = new int * [a];
         for (size_t i = 0; i != a; ++i) {
             m[i] = new int [b];
         }
    
         return m;
     }
    
     void free_array2d (int ** m, size_t a) {
         for (size_t i = 0; i != a; ++i) {
             delete [] m[i];
         }
    
         delete [];
     }
    
  2. Эффективная схема

    2 Dimentional Array Effective

     int ** create_array2d (size_t a, size_t b) {
         int ** m = new int * [a];
         m[0] = new int[a * b];
    
         for (size_t i = 1; i != a; ++i) {
             m[i] = m[i - 1] + b;
         }
    
         return m;
     }
    
     void free_array2d (int ** m) {
         delete [] m[0];
         delete [] m;
     }