Массивы

Массивы

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:18

В данной лекции рассматриваются статические массивы. Так же существуют и динамические массивы, некоторые вещи, описанные в лекции не применимы для работы с динамическими массивами.
Лекция 6. Массивы
В процессе разработки программ часто возникает необходимость работы с однотипными объектами. Как и во многих других языках высокого уровня, в С++ для этого используются массивы.

Массив – множество элементов, принадлежащих одному типу данных. При этом существует всего одно имя переменной связанной с массивом, а обращение к конкретной ячейке происходит по ее индексу (номеру) в массиве.
При этом важно четко понимать, что индекс ячейки массива и её содержимое – разные вещи. В ячейке хранятся некоторые данные, а индекс только указывает на то, к какой именно ячейке обращается программа. Работа же с данными и с самим массивом идет через переменную, которой этот массив объявлен.

Матрица
Матрица — математический объект, записываемый в виде прямоугольной таблицы элементов кольца или поля (например, целых, действительных или комплексных чисел), которая представляет собой совокупность строк и столбцов, на пересечении которых находятся её элементы. Количество строк и столбцов матрицы задают размер матрицы. Хотя исторически рассматривались, например, треугольные матрицы, в настоящее время говорят исключительно о матрицах прямоугольной формы, так как они являются наиболее удобными и общими.
Матрицы широко применяются в математике для компактной записи систем линейных алгебраических или дифференциальных уравнений. В этом случае количество строк матрицы соответствует числу уравнений, а количество столбцов — количеству неизвестных. В результате решение систем линейных уравнений сводится к операциям над матрицами.
Для матрицы определены следующие алгебраические операции:
сложение матриц, имеющих один и тот же размер;
умножение матриц подходящего размера (матрицу, имеющую n столбцов, можно умножить справа на матрицу, имеющую n строк);
в том числе умножение на матрицу вектора (по обычному правилу матричного умножения; вектор является в этом смысле частным случаем матрицы);
умножение матрицы на скаляр.

Более строгое определение
Пусть есть два конечных множества M={1,2,…,m} и N={1,2,…n}, где n,m – натуральные числа.
Назовем матрицей m×n с любыми элементами из множества отображение вида:
Изображение
A(i,j) называется элементом матрицы, находящимся на пересечении i-ой строки иj-ого столбца;
i-ая строка состоит из элементов вида A(i,j), где j ∈[1,N];
j-ый столбец состоит из элементов вида A(i,j), где i ∈[1,M];
Таким образом, матрица размера m×n состоит в точности их:
m строк;
n столбцов;
Вопрос: сколько элементов в матрице M×N? mn элементов.

Простые (линейные) операции

Умножение матрицы на число
Умножение матрицы A на число γ заключается в построении матрицы γA=(γa_ij ).
Свойства умножения матрицы на число:
1A=A
(γα)A=γ(αA)
(γ+α)A = γA+αA
γ(A+B)= γA+ γB

Сложение матриц
Сложение матриц A+B есть операция нахождения матрицы C, такой, что c_ij=a_ij+b_ij.
Складывать можно только матрицы одинакового размера.
Свойство сложения матриц:
A+B=B+A коммутативность
(A+B)+C=A+(B+C) ассоциативность
A+Θ=A сложение с нулевой матрицей
A+(-A)= Θ существование противоположенного элемента
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49

Необходимый материал

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:22

Одномерные массивы в С++
Одномерный массив — массив, с одним параметром, характеризующим количество элементов одномерного массива. Фактически одномерный массив — это массив, у которого может быть только одна строка, и n-е количество столбцов. Столбцы в одномерном массиве — это элементы массива. На рисунке 6.1 показана структура целочисленного одномерного массива a. Размер этого массива — 16 ячеек.
Изображение

Важно обратить внимание на то, что в языке С/С++ массивы являются нульбазисными. Т.е. нумерация в массиве всегда начинается с нуля. Таким образом, массив a содержит 16 элементов. Номер последнего элемента – 15.
Синтаксис объявления массива:
Код: выделить все
<тип данных> <" "><имя переменной,используемой для обозначения массива> [<количество элементов в массиве>];

    <Тип данных> - тип данных, переменные которого хранятся в массиве.
    <имя переменной,используемой для обозначения массива> - может быть любым.
    <количество элементов в массиве> - ограничено размером целого типа int.

Пример:
int a[16];

Инициализация массива:
int a[16] = { 5,-12,-12,9,10,0,-9,-12,-1,23,65,64,11,43,39,-15 };

Инициализация одномерного массива выполняется в фигурных скобках после знака равно, каждый элемент массива отделяется от предыдущего запятой.
int a[]={5,-12,-12,9,10,0,-9,-12,-1,23,65,64,11,43,39,-15};
В данном случае компилятор сам определит размер одномерного массива. Размер массива можно не указывать только при его инициализации, при обычном объявлении массива обязательно нужно указывать размер массива.

При инициализации массива можно не указывать все элементы (если указан размер), в этом случае начало массив будет проинициализировано указанными элементами, а оставшаяся часть нулями:
int a[5]= {1,2,3};
Указанный выше массив будет содержать следующие элементы
{1,2,3,0,0};
Этот способ часто используется для первоначального обнуления массива:
int a[16]= {0};

Иначе, если массив не инициализировать, то его содержимое, так же как и содержимое обычной неинициализированной переменной не определено. То есть, может содержать “мусор”.
Хорошей практикой является создание отдельной константной переменной, содержащей размер массива, и использование её в коде. Это позволяет легко менять размер массива:
Эту переменную лучше всего объявлять вне функции main. То есть после блока подключения заголовочных файлов (библиотек):
Размер массива в C++ обычно хранятся в переменных типа “size_t”. Этот тип объявлен в файле “cstdlib”. Следовательно, для его использования нужно подключить этот заголовочный файл. Фактически “size_t “ это без знаковое целое (unsigned int).

В C++ принято имена константных переменных писать в верхнем регистре, разделяя слова символом нижнего подчёркивания “_”.
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49

Необходимый материал

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:23

Пример. Одномерные массивы.

Программа должна последовательно считывать десять введённых чисел с клавиатуры. Все введённые числа просуммировать, результат вывести на экран.

Код: выделить все
#include <iostream>
#include <cstdlib>

using namespace std;

const size_t ARR_LEN = 10;

int main()
{
    int array1[ARR_LEN]; // объявляем целочисленный массив
    int sum = 0;

    cout << "Enter array elements: " << endl;
    for ( size_t i = 0; i < ARR_LEN; i++ )  { // цикл для считывания чисел
        cin ≫ array1[i];  // считываем вводимые с клавиатуры числа
    }

    cout << "array1 = {";
    for ( size_t i = 0; i < ARR_LEN; i++ )  { // цикл для вывода элементов массива
        cout << array1[i] << " " ;  // выводим элементы массива на стандартное устройство вывода
    }
    cout << endl;   // Перевод строки после вывода всех элементов массива.

    for ( size_t i = 0; i < ARR_LEN; i++ ) {// цикл для суммирования чисел массива
        sum += array1[i]; // суммируем элементы массива
    }

    cout << "nsum = " << sum << endl;
    system("pause");
    return 0;
}
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49

Необходимый материал

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:25

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

Допустим, необходимо обработать некоторые данные из таблицы. В таблице есть две характеристики: количество строк и количество столбцов. Также и в двумерном массиве, кроме количества элементов массива, есть такие характеристики как, количество строк и количество столбцов двумерного массива. То есть, визуально, двумерный массив — это обычная таблица, со строками и столбцами. Фактически двумерный массив — это одномерный массив одномерных массивов. Структура двумерного массива, с именем a размера m×n показана на рисунке 6.2.

Изображение
Рисунок 6.2. Структура двумерного массива.

Синтаксис объявления массива:
Код: выделить все
<тип данных> <" "><имя переменной,используемой для обозначения массива> [<количество строк>]  [<количество столбцов>];

    <Тип данных> - тип данных, переменные которого хранятся в массиве.
    <имя переменной,используемой для обозначения массива> - может быть любым.
    [<количество строк>] [<количество столбцов>] - ограничено размером целого типа int.

Пример:
int a[5][3];
Инициализация массива:
int a[5][3] = { {4,7,8},{9,66,-1},{5,-5,0},{3,-3,30},{1,1,1} };

В данном массиве 5 строк, 3 столбца после знака присвоить ставятся общие фигурные скобочки, внутри которых ставится столько пар фигурных скобочек, сколько должно быть строк в двумерном массиве, причём эти скобочки разделяются запятыми. В каждой паре фигурных скобочек записывать через запятую элементы двумерного массива. Во всех фигурных скобочках количество элементов должно совпадать. Так как в массиве пять строк, то и внутренних пар скобочек тоже пять. Во внутренних скобочках записаны по три элемента, так как количество столбцов — три.

Двух мерный массив так же, как и одномерный массив, можно заполнить только частью элементов:
int a[5][3] = {{4,7,8}};
По аналогии с двухмерным, можно создавать и многомерные массивы.
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49

Re: Необходимый материал

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:26

Передача массива в функцию
Часто возникает задача передачи массива в функцию в качестве параметра.
Одномерный массив
Передача одномерного массива в функцию
Для того чтобы передать массив функцию, его нужно указать в качестве параметра, как и обычную переменную:
Код: выделить все
void printOneDimArr(int arr[ARR_LEN])
{
    for(size_t i=0; i<ARR_LEN; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

Листинг 6.3. Функция вывода одномерного массива, вариант 1.

В случае одномерного массива, указание размерности можно упустить, а реальный размер массива передавать в качестве второго параметра:
void printOneDimArr(int arr[], size_t size)
{
for(size_t i=0; i<size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
Листинг 6.4. Функция вывода одномерного массива, вариант 2.

Массив в функцию передаётся “по ссылке”, то есть при изменении массива внутри функции, переданный массив так же будет изменён:
Код: выделить все
#include <iostream>
#include <cstdlib>

using namespace std;

const size_t ARR_LEN = 5;

void printOneDimArr(int arr[], size_t size);
void fillOneDimArr(int arr[], size_t size);

int main()
{
    int arr[ARR_LEN] = {0};
    printOneDimArr(arr, ARR_LEN);

    fillOneDimArr(arr, ARR_LEN);
    printOneDimArr(arr, ARR_LEN);

    return 0;
}


Код: выделить все
void printOneDimArr(int arr[], size_t size)
{
    for(size_t i=0; i<size; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}


Код: выделить все
void fillOneDimArr(int arr[], size_t size)
{
    for(size_t i=0; i<size; i++) {
        arr[i] = i;
    }
}

Листинг 6.5. Заполнение одномерного массива.

После выполнения, приведённой выше программы, на экране компьютера будет следующее:
Код: выделить все
0 0 0 0 0
0 1 2 3 4
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49

Re: Необходимый материал

Сообщение EgorovAD MEPhI » 11 ноя 2013, 09:27

Передача двухмерного массива в функцию
Передача двухмерного массива в функцию выполняется аналогично с одномерным массивом, за исключением некоторых ограничений, о которых будет сказано ниже:
Код: выделить все
void printTwoDimArr(int arr[ARR_LEN1][ARR_LEN2])
{
    for(size_t i=0; i<ARR_LEN1; i++) {
        for(size_t j=0; j<ARR_LEN2; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

Листинг 6.6. Функция вывода двухмерного массива.

Ограничение заключается в том, что в случае с двухмерным массивом, мы не можем упустить размерность массива в объявлении функции. То есть следующая функция не будет компилироваться:
void printTwoDimArr(int arr[][], size_t size1, size_t size2);

Так же как и одномерные массивы, двухмерные массивы передаются в функцию “по ссылке”:
Код: выделить все
#include <iostream>
#include <cstdlib>

using namespace std;

const size_t ARR_LEN1 = 5;
const size_t ARR_LEN2 = 3;

void printTwoDimArr(int arr[ARR_LEN1][ARR_LEN2]);
void fillTwoDimArr(int arr[ARR_LEN1][ARR_LEN2]);

int main()
{
    int arr[ARR_LEN1][ARR_LEN2] = {{0}};
    printTwoDimArr(arr);

    fillTwoDimArr(arr);
    printTwoDimArr(arr);

    return 0;
}

void printTwoDimArr(int arr[ARR_LEN1][ARR_LEN2])
{
    for(size_t i=0; i<ARR_LEN1; i++) {
        for(size_t j=0; j<ARR_LEN2; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

void fillTwoDimArr(int arr[ARR_LEN1][ARR_LEN2])
{
    for(size_t i=0; i<ARR_LEN1; i++) {
        for(size_t j=0; j<ARR_LEN2; j++) {
            arr[i][j] = i*ARR_LEN2 + j;
        }
    }
}

Листинг 6.7. Заполнение двухмерного массива.
Приведённый выше код выведет на экран следующее:
Код: выделить все
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

0 1 2
3 4 5
6 7 8
9 10 11
12 13 14
EgorovAD MEPhI
Администратор
 
Сообщений: 155
Зарегистрирован: 04 ноя 2011, 11:49


Вернуться в Тема 6. Массивы и Vector

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2