Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DOROGOVA.pdf
Скачиваний:
245
Добавлен:
05.06.2015
Размер:
853.4 Кб
Скачать

5. Массивы

Переменные, с которыми мы имели дело до сих пор, могут хранить только одно значение в каждый момент времени, и поэтому крайне неудобны в некоторых случаях. Примером может служить следующая простая задача:

Вычислить сумму пяти чисел.

int num , sum=0 , i ;

for (i=0, sum=0 ; i<5 ; i++)

{scanf(“%d”,&num);

sum=sum+num;

}

В цикле 5 раз вводим значение переменной num и, используя аккумулятор sum, подсчитываем сумму. При этом, при вводе второго значения, первое теряется, при вводе третьего утрачивается второе, и так

далее. Сумму чисел мы подсчитали, но исходные значения данных будут потеряны. Если же стоит задача сохранить исходные данные, нам потребуется определить 5 переменных, а использование цикла для ввода данных и вычисления будет невозможно.

Пример: Вычислить сумму 5-ти чисел с сохранением исходных данных. int num1, num2, num3, num4, num5,sum=0;

scanf(“%d”,&num1);

sum=sum+num1;

scanf(“%d”,&num2);

sum=sum+num2;

scanf(“%d”,&num3);

sum=sum+num3;

scanf(“%d”,&num4);

sum=sum+num4;

scanf(“%d”,&num5);

sum=sum+num5;

Такой подход к решению данной задачи неэффективен, кроме того, в некоторых случаях невыполним (допустим, нам нужно просуммировать тысячу чисел).

Для разрешения подобных трудностей в программировании введена "специальная переменная", которая называется массивом.

Массив это совокупность элементов одинакового типа (базового типа, такого как double, float, или более сложного) с применением общего для всех имени.

Массив это сложный (или структурированный) тип данных, он представляют собой удобное средство группирования связанных переменных. В С++ массивы могут быть как одномерными, так и многомерными.

5.1. Одномерные статические массивы

Статическим называется массив, размер которого определяется во время компиляции и не меняется во время исполнения программы.

Массивы предназначены для хранения набора единиц данных, каждая из которых идентифицируется индексом или набором индексов.

Индекс целое число, указывающее на конкретный элемент массива.

Перечислим свойства статических массивов:

Массив состоит из многих элементов одного и того же типа.

Число элементов назначается при определении массива и в дальнейшем не меняется.

Ко всему массиву целиком можно обращаться по имени.

Выбор элемента массива производится по его индексу.

Первый элемент массива имеет индекс равный нулю.

Элементами массива не могут быть функции и элементы типа void.

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

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

5.2.Объявление массива. Обращение к элементу массива

Вязыке С имеется два формата для объявления массива:

тип имя_массива [константное_ выражение]; тип имя_массива [ ];

Тип в объявлении массива задает тип его элементов. [Константное-выражение] задает количество элементов массива.

[Константное-выражение] может быть опущено, если при объявлении массив инициализируется или если массив объявлен как формальный параметр функции.

Так же как переменные, массивы должны быть определены до их использования:

Примеры определения массивов: int ter[100];

char string[20]; float d[50];

Из объявления массива компилятор должен получить информацию о типе элементов массива и их количестве. В нашем примере объявляется три массива:

массив целого типа с именем ter в 100 элементов;

символьный массив с именем string в 20 элементов;

массив из 50 вещественных чисел с именем d.

Для обращения к элементам массива следует указывать имя массива и индекс элемента заключенный

вквадратные скобки.

Внашем примере к первому элементу массива ter обращаются как к ter[0], ко второму как к ter[1], к третьему как к ter[2] и так далее. Еще раз обращаю внимание, что нумерация элементов массива начинается с нуля, поэтому массив ter, содержит элементы от ter[0] до ter[99], а элемента с номером ter[100] не существует.

Компилятор не контролирует ошибку обращения к несуществующему элементу массива, например ter[105], то есть ошибки на этапе компиляции в подобных случаях не возникает, но при запуске такой программы реакция компьютера непредсказуема:

возможно, произойдет ошибка времени выполнения;

или программа выдаст неверные результаты;

в худшем случае компьютер зависнет и его придется перезагрузить.

Число, заключенное в квадратные скобки, называется индексом. Как уже указывалось ранее, индекс необходим для работы, или как чаще говорят, для обращения к элементам массива.

Элементы массивов могут участвовать в операциях как простые переменные соответствующего типа, это могут быть любые инструкции, где используется переменная: в процедурах ввода, вывода и в выражениях. К элементу массива всегда обращаются через его индекс.

Пример: Программа, вводит с клавиатуры одномерный массив из 5 целых чисел, после чего выводит количество ненулевых элементов. Перед вводом каждого элемента выводится подсказка с номером

элемента.

 

#include <stdio.h>

 

#include <conio.h>

 

#define SIZE 5

// размер массива

void main()

 

{

 

int a[SIZE];

//массив

int n = 0;

// кол-во ненулевых эл-тов

int i;

// индекс

printf("Введите массив целых чисел.\n"); for (i = 0; i < SIZE; i++)

{ printf("a[%i] ->",i+1); scanf("%i", &a[i]);

if (a[i] != 0) n++;

}

printf("В массиве %i ненулевых элемента.\n", n); printf("\nДля завершения нажмите <Enter>"); getch();

}

Заметим, что в данном варианте программы размер массива задан с помощью именованной константы SIZE. Такой подход весьма распространен, так как позволяет при необходимости легко изменить размер массива. В самом деле, если мы захотим обработать массив из 100 элементов, то исправления следует

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

внести в одном месте при определении константы SIZE , а не в двух местах, как требовалось бы при использовании обычных числовых констант.

При работе с именованными константами следует помнить, что задавать их следует до момента первого использования. Так в нашем примере значение константы SIZE определено раньше объявления массива int a[SIZE]; и использования в цикле for (i = 0; i < SIZE; i++)

Обращение к элементам массива осуществляется по индексу, так инструкция

scanf("%i", &a[i]); в цикле последовательно вводит данные в элементы массива, начиная от a[0] до a[SIZE -1] ( так как индекс i пробегает значения от 0 до SIZE -1).

5.3. Инициализация массива

После того как массив определен, в него можно вводить информацию. Как правило, перед тем, как начать работать с данными массива требуется присвоить им начальное значение.

Начальные значения элементам статического массива можно присвоить при его определении.

Формат определения массива с инициализацией демонстрирует следующий пример: int temps[5] = {45, 56, 12, 98, 12};

Таким образом, создано пять элементов, со следующими значеними: temps[0] = 45

temps[1] = 56 temps[2] = 12 temps[3] = 98 temps[4] = 12

Пример показывает инициализацию массива, то есть одновременное определение и задание начальных значений массива.

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

Пример: Автоматическое вычисление длины массива. double d[]={1.5 , 2.0 , 3.75 , 5.0 , 3.1, 6.2};

В результате такого определения создается массив и присваиваются начальные значения, его элементам:

d[0]= 1.5 d[1]=2.0 d[2]=3.75 d[3]=5.0 d[4]= 3.1 d[5]= 6.2

Если в определении массива указан его размер, то количество начальных значений не может быть больше количества элементов, меньше может быть.

Если список инициализации меньше заявленной длины, то начальные значения получают элементы с меньшими индексами, конец же массива остается неинициализированным. В этом случае говорят, что массив заполнен не полностью.

Пример: Неполного заполнения, созданного массива. double d[8]={1.5 , 2.0 , 3.75 , 5.0 , 3.1};

Начальные значения получают элементы d[0] - d[4], при этом элементы d[5] - d[7] не определены.

После того, как массив задан (определен) и инициализирован (элементы массива получили начальные значения), можно приступать к работе с данными массива, то есть считывать или записывать информацию в массив.

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

Следует отметить, что в языке С определены только одномерные массивы, но элементом массива может быть массив.

Многомерный массив определяется как массив массивов, при этом количество его индексов определяет размерность массива.

Количество используемых индексов может быть различным, массивы с одним индексом называют одномерными, с двумя двумерными и так далее.

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

Одномерный массив нестрого соответствует вектору в математике, двумерный матрице. Чаще всего применяются массивы с одним или двумя индексами, реже с тремя, еще большее количество индексов встречается крайне редко.

В следующем примере определен массив A из 2-х элементов, каждый из которых в свою очередь состоит из 3-х элементов.

int A[2][3];

Это двумерный массив из 2-х строк и 3-х столбцов, который можно представить в виде следующей матрицы:

A[0][0] A[0][1] A[0][2]

A[1][0] A[1][1] A[1][2]

Поскольку многомерный массив это массив массивов, его можно инициализировать следующим образом:

int w[3][3] = { { 2, 3, 4 },

{3, 4, 8 },

{1, 0, 9 }

};

После чего элементы массива получают свои начальные значения:

w[0][0] =2

w[0][1]=3

w[0][2]=4

w[1][0]=3

w[1][1]=4

w[1][2]=8

w[2][0] =1

w[2][1]=0

w[2][2]=9

Тот же результат можно получить и одномерным списком инициализации: int w[3][3] = { 2, 3, 4 , 3, 4, 8 , 1, 0, 9 }

или

int w[9] = { 2, 3, 4 , 3, 4, 8 , 1, 0, 9 }

Подобно одномерным массивам, многомерные массивы можно инициализировать не полностью. Пример: Присвоить начальные значения элементам первого столбца матрицы.

double z[3][6]={ {1},{2},{3},{4} };

5.5. Выход индекса за границы массива

Что произойдет, если программист обратится к памяти за пределами объявленного массива, то есть если индекс массива превысит максимально возможное значение? В большинстве языков программирования, подобные ошибки контролируются, например программа, написанная на языке Паскаль,

вэтом случае выдаст ошибку времени выполнения.

Вязыке С++ никакой проверки "нарушения границ" массивов не выполняется!

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

со стороны компилятора при трансляции программы и без выдачи сообщений об ошибке во время работы программы.

Пример: Выход за границу массива. #include <iostream.h>

void main()

{

int err[10],i;

for (i=0;i<10;i++) err[i]=i;

for (i=0;i<20;i++) cout<<err[i]<<'\t'<<endl;

}

В примере объявлен массив из 10 элементов. В первом цикле for, при записи в массив нарушение границ не происходит, во втором же цикле на экран выводится 20 элементов. Этот пример не приведет к сбою компьютера, так как ошибка происходит при чтении данных, и мы лишь видим ошибочный результат на экране. Если же выход за границы массива произойдет при записи данных, то есть в первом цикле, то результат работы программы непредсказуем!

Этот пример демонстрирует, что вся ответственность за соблюдение границ массивов лежит на программисте. В программе должны быть либо объявлены массивы достаточно больших размеров, чтобы в них без осложнений помещались все необходимые данные, либо предусмотрены проверки нарушения границ массивов.

Почему в языке С++ не предусмотрены столь необходимые с точки зрения надежности программного кода функции проверки? Дело в том, что с самого начала проблема повышения эффективности

PDF created with FinePrint pdfFactory Pro trial version http://www.fineprint.com

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]