3.1. Массивы
3.1.1. Одномерный массив
Массив — это группа последовательных ячеек памяти, имеющих один и тот же
тип. Чтобы обратиться к определенной ячейке, или элементу массива, мы используем
имя массива и индекс (номер) элемента в массиве. При описании задается количество
элементов в массиве в квадратных скобках, и дальнейший доступ к элементам
массива осуществляется с помощью оператора []. Нумерация элементов массива
начинается с 0, т.е. если в массиве 4 элемента, номера элементов будут от
0 до 3:
int data[4]; // описание массива из 4 элементов
// инициализация элементов массива, обращение к элементам массива по индексу
data[0]=1;
data[1]=2;
data[2]=3;
data[3]=4;
Возможна инициализация массива при объявлении в фигурных скобках,
в этом случае указывать количество элементов в массиве не обязательно, компилятор
определит это их сам:
// массив из трех элементов 0-го, 1-го, 2-го. Элементы нумеруются от 0 до размер-1
double v[3]={0.3, 2.2, 2.};
// количество элементов указывать не обязательно
char symbols[]={'a', 'b', 'c', 'd', 'e'};
3.1.2. Динамическое размещение одномерного массива
Массивы с небольшим количеством элементов легко размещаются
в статической памяти программы. Но для массивов с большим количеством элементов
намного эффективнее будет динамическое размещение (а для массивов с очень
большим количеством элементов это необходимо, так как размер сегмента данных
ограничен). В этом случае объявляется указатель на массив, а затем при помощи
ключевого слова new выделяется память для требуемого количества
элементов. Далее при работе с массивом доступ к элементам массива осуществляется
одинаково, независимо от того как он размещен в памяти. Если массив размещается
динамически, в конце программы обязательно нужно освободить память при помощи
оператора delete.
double *data; // указатель на массив
data=new double[1000]; // указатель на 0-й элемент массива
// инициализация
// после размещения в массиве "мусор" и сразу обязательно инициализировать все его элементы
for(int i=0; i<1000; i++)
{
data[i]=0.;
}
delete [] data; // обязательно освободить память
data+1; // указатель на 1-й элемент
data+100; // указатель на 100-й элемент,
*(data+4); // эквивалентно data[4]
3.1.3. Передача массива в функцию (пример 3.1)
Передача массива в функцию может осуществляться только по указателю на нулевой
элемент, с дополнительной информацией о количестве элементов в массиве:
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 3.1. Пример работы с динамическим одномерным массивом
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// Университет ИТМО
/////////////////////////////////////////////////////////////////////////////
// подключение библиотеки ввода-вывода
#include <iostream>
// подключение стандартного пространства имен для использования библиотек
using namespace std;
// прототипы функций
double sum(double data[], int n);
/////////////////////////////////////////////////////////////////////////////
// пример передачи массива в функцию
// функция вычисляет сумму всех элементов массива
// data - массив (указатель на 0-й элемент массива)
// n - количество элементов в массиве
double sum(double data[], int n)
{
double sum=0.;
for(int i=0; i<n; ++i)
{
sum+=data[i];
}
return sum;
}
/////////////////////////////////////////////////////////////////////////////
void main()
{
// объявление указателя на массив
double *data;
int count=1000; // количество элементов в массиве
// динамическое размещение массива, data - указатель на 0-й элемент массива
data=new double[count];
// вывод 10 элементов массива до инициализации (в массиве "мусор")
for(int i=0; i<10; i++)
{
cout<<data[i]<<endl;
}
cout<<"-----------------"<<endl;
// инициализация массива
for(int i=0; i<count; i++)
{
data[i]=i;
}
// вывод 10 элементов массива после инициализации
for(int i=0; i<10; i++)
{
cout<<data[i]<<endl;
}
cout<<"-----------------"<<endl;
cout<<data<<endl; // указатель на 0-й элемент
cout<<data+1<<endl; // указатель на 1-й элемент
cout<<*(data+4)<<endl; // эквивалентно data[4]
cout<<data[count-1]<<endl; // последний элемент массива
cout<<"-----------------"<<endl;
// пример передачи массива в функцию
cout<<sum(data, count)<<endl;
cout<<sum(&data[0], count)<<endl;
cout<<"-----------------"<<endl;
delete [] data; // обязательно освободить память
cout<<data[4]<<endl; // ОШИБКА! ссылка на уже несуществующий элемент массива
}
/////////////////////////////////////////////////////////////////////////////
3.1.4. Двумерный массив
Для создания двумерного массива необходимо указать в квадратных скобках
два значения – количество строк и столбцов в массиве.
тип_массива имя_массива[кол-во строк][кол-во столбцов];
Рисунок иллюстрирует индексы элементов двумерного массива. Массив содержит
три строки и два столбца.
[0][0]
|
[0][1]
|
[1][0]
|
[1][1]
|
[2][0]
|
[2][1]
|
На самом деле, в памяти двумерные массивы хранятся по строкам, как показано
на рисунке:
[0][0]
|
[0][1]
|
[1][0]
|
[1][1]
|
[2][0]
|
[2][1]
|
double matrix[3][2]; // двумерный массив 2х3
double sum=0.;
for(int i=0; i<3; i++) // номер строки
{
for(int j=0; j<2; j++) // номер столбца
{
sum+=matrix[i][j];
}
}
3.1.5. Динамическое размещение двумерного массива (пример
3.2)
Двумерный массив можно разместить динамически, только если представить его
как одномерный. В этом случае вместо доступа по индексам [ i][ j], придется
вычислять индекс одномерного массива, которому будет соответствовать необходимый
элемент двумерного массива.
Например, если двумерный массив 3х2 разместить как одномерный, элементу
[1][0] двумерного массива будет соответствовать индекс [2] одномерного массива.
0
|
1
|
2
|
3
|
4
|
5
|
[0][0]
|
[0][1]
|
[1][0]
|
[1][1]
|
[2][0]
|
[2][1]
|
/////////////////////////////////////////////////////////////////////////////
// Прикладное программирование
// Пример 3.2. Пример работы с динамическим двумерным массивом
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// Университет ИТМО
/////////////////////////////////////////////////////////////////////////////
// подключение библиотеки ввода-вывода
#include <iostream>
// подключение стандартного пространства имен для использования библиотек
using namespace std;
/////////////////////////////////////////////////////////////////////////////
void main()
{
// динамическое размещение массива 3х2
double *matrix=new double[3*2];
// инициализация массива
for(int j=0; j<2; j++) // номер столбца
{
for(int i=0; i<3; i++) // номер строки
{
matrix[i*2+j]=j*10+i;
}
}
// вывод элементов массива на экран
for(int j=0; j<2; j++) // номер столбца
{
for(int i=0; i<3; i++) // номер строки
{
cout<<matrix[i*2+j]<<" ";
}
cout<<endl;
}
delete [] matrix; //освободить память
}
/////////////////////////////////////////////////////////////////////////////
|