13.  Масиви

Бяла мъгла обгръща каменния масив в далечината,
виденията изчезват, в гората една вейка си маха
сама, като че ми се заканва нещо с пръст.
Йордан Радичков, ПЕДЯ ЗЕМЯ


Дефиниране и използване на масиви, масивите като параметри.
    Масивите са елемент на езика С за съхраняване на елементи от един и същи тип.  Използват се и в езика С++ като по-бърза и по-ефективна структура в сравнение с типа (шаблона) вектор (вж 12. Вектори). Затова пък масивите са по-неудобни за работа - например техният размер се задава при дефинирането и не може да се променя.
* Дефиниране и използване:
 - дефиниция на вектор с 10 елемента тип double:
double salaries[10];
- на елементът с индекс 4 се задава стойност 355:
salaries[4] = 355;
- елементите на масива се номерират (индексират), започвайки от 0:
salaries[0] - първи елемент
salaries[1] - втори елемент
salaries[2] - трети елемент
salaries[3] - четвърти елемент
...
salaries[9] - десети елемент

* Задаване на стойности на елементите на масив.
const int SAL_MAXSIZE = 10;
double sal[SAL_MAXSIZE]; /* фиксираме дължината на масива */
int sal_size = 0;        /* брой на използваните елементи на масива */
bool more = true;
/* необходими са 2 условия за прекратяване на цикъла - спиране на въвеждането или запълване на всички елементи на масива */
while (more and sal_size < SAL_MAXSIZE)
{ cout << "Enter salary or 0 to quit";
  double x;
  cin >> x;
  if (cin.fail()) more = false
  else
  { sal[sal_size] = x; /* задаване на стойност на елемент на масива */
    sal_size++;        /* увеличаване с 1 на използваните елементи */
  }
}

* Mасивите като параметри на функции.
    За да се обозначи, че един формален параметър на функция е масив, след името му се пише []. Масивите винаги се предават чрез псевдоним (по адрес). За масив - входен параметър на функция обикновено се използва константен псевдоним.
double maximum(const double a[], int a_size)
{  if (a_size == 0) return 0;
   double highest = a[0];
   int i;
   for (i = 1; i < a_size; i++)
      if (a[i] > highest) highest = a[i];
   return highest;
}
    Следващата програма чете заплати от стандартен вход и отпечатва максималната заплата.
// salarray.cpp
#include <iostream>
using namespace std;

void read_data(double a[], int a_maxsize, int& a_size)
{ a_size = 0;
  double x;
  while (a_size < a_maxsize and (cin >> x))
  { a[a_size] = x; a_size++; }
}

double maximum(const double a[], int a_size)
{ if (a_size == 0) return 0;
  double highest = a[0];
  int i;
  for (i = 1; i < a_size; i++)
     if (a[i] > highest) highest = a[i];
  return highest;
}

int main()
{ const int SALARIES_MAXSIZE = 100;
  double salaries[SALARIES_MAXSIZE];
  int salaries_size = 0;

  cout << "Please enter all salary data: ";
  read_data(salaries, SALARIES_MAXSIZE, salaries_size);

  if (salaries_size == SALARIES_MAXSIZE and not cin.fail())
     cout << "Sorry - extra data ignored\n";

  double maxsal = maximum(salaries, salaries_size);
  cout << "The maximum salary is " << maxsal << "\n";
  return 0;
}

Please enter all salary data: 200 240 250 210 290 310 205 q
The maximum salary is 310

Масиви от символи.
    Съхраняването и обработката на низове в езика С (т.н. С-низове ) се извършва в масиви от символи. Всеки низ завършва със специален символ с ASCII код 0.

char greeting[6] = "Hello";
char greeting[] = "Hello";
char greeting[10] = "Hello";
Символ H e l l o '\0'
Индекс 0 1 2 3 4 5

Превръщането С-низ в типа string и обратно става по следния начин:

string s = "ABCD";
char c[] = s.str();
char c[] = "1234";
string s = static_cast<string>(c);

    Пример с използване на функцията atoi от библиотеката cstdlib за превръщане на низ в число:
string year = "1999";
int y = atoi(year.c_str());
    Важно е да не се забравя символа за край на низ при използване на масиви от символи, защото много функции, които работят със С-низове и операцията изходен поток определят дължината на низа по този символ.
    Използването на български букви в типа string създава някои проблеми. Обикновено може да се работи нормално с член-функциите на класа, но не може да се извличат букви от низа, защото елементите на string са от тип char, който съхранява числа от -127 до 127. Решението е да се записват низове с български букви като С-низове с елементи от тип unsigned char (числа от 0 до 255) по следния начин:
unsigned char s_bul[] = "АБВГ";



Двумерни масиви.
    За съхранение и обработка на матрици се използват двумерни масиви. При дефиниране на масива се задават броя на редовете и броя на стълбовете.
// matrix.cpp
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const int BAL_ROWS = 6;
const int BAL_COLS = 5;

double future_value(double init_bal, double p, int nyear)
{  double b = init_bal * pow(1 + p/12/100, 12*nyear);
   return b;
}

/* втората размерност на двумерния масив се задава като константа */
void print_table(const double table[][BAL_COLS], int table_rows)
{  int i, j;
   cout << fixed << setprecision(2);
   for (i = 0; i < table_rows; i++)
   {  for (j = 0; j < BAL_COLS; j++)
         cout << setw(10) << table[i][j];
      cout << "\n";
   }
}

int main()
{  double bal[BAL_ROWS][BAL_COLS]; /* дефиниране на двумерен масив */
/* двоен цикъл за обхождане на елементите на двумерен масив */
   for (int i = 0; i < BAL_ROWS; i++)
      for (int j = 0; j < BAL_COLS; j++)
         bal[i][j] = future_value(10000, 5+i*0.5, 5+j*5);
   print_table(bal, BAL_ROWS);
   return 0;
}

  12833.59  16470.09  21137.04  27126.40  34812.90
  13157.04  17310.76  22775.84  29966.26  39426.72
  13488.50  18193.97  24540.94  33102.04  44649.70
  13828.17  19121.84  26442.01  36564.47  50561.98
  14176.25  20096.61  28489.47  40387.39  57254.18
  14532.94  21120.65  30694.52  44608.17  64828.80