Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
38
Добавлен:
16.04.2013
Размер:
76.8 Кб
Скачать

Массивы и указатели

Массив (array) — это тип данных, который используется для представления последовательности однородных значений. Доступ к элементам массива производится с помощью индексов. В C++ возможны массивы любых типов, включая массивы массивов. Объявление типичного массива используется для выделения памяти, начиная с базового адреса. На самом деле имя массива является постоянным указателем, инициализованным этим базовым адресом.

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

// Простая обработка массива

#include <iostream.h>

const int SIZE = 5;

int main ( )

{ int a [SIZE]; // резервируем место для а[0],.....,а[4]

int i, sum=0;

for (i = 0; i < SIZE; ++ i) {

a[i]=i * i;

cout << “a [“ << i <<”] = ” << a[ i ] << “ “ ;

sum + = a[ i ];

}

cout « "\n сумма = “ << sum << endl;

}

Вывод этой программы выглядит так:

а[0] = 0 а[1] = 1 а[2] =4 a[3]=9 a[4]=16

sum = 30

Вышеприведенному массиву требуется память для хранения пяти целых значений. Так если а [ 0 ] хранится по адресу 1000, то в системе, отводящей для хранения цело­го 2 байта, остальные элементы массива последовательно размещаются по адресам 1002, 1004, 1006 и 1008.

Индексирование

Предположим, было сделано объявление вида:

Int I, а [размер];

Тогда для доступа к элементу массива мы можем написать: а[ i ]. В общем слу­чае эта запись выглядит так: а [выражение], где выражение это целое выражение. Указанное выражение мы называем индексом (subscript или index) элемента массива а. В C++ значение индекса должно лежать в диапазоне от 0 до размер -1. Программист всегда должен быть уверен, что все индексы находятся в пределах этих границ.

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

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

Объявления массивов

int a [100]; одномерный массив

int b [3][5]; двухмерный массив

int c [7][9][2]; трехмерный массив

Любой k-мерный массив имеет размер по каждому из своих k измерений. В приведенной таблице b содержит 3 Х 5 элементов, а c – 7 х 9 х 2 элементов. Начиная с базового адреса массива все элементы хранятся в памяти последовательно.

Инициализация

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

int а[4] = {9, 8, 7}; //а[0]=9, а[1]=8, а[2]=7

Когда список инициализаторов короче размера массива, остальные элементы инициализуются нулем. Неинициализованные внешние и статические массивы автомати­чески инициализуются нулем. Однако автоматические массивы открываются с нео­пределенными значениями.

Массиву, объявленному с явным списком инициализаторов, но без задающего его размер выражения, дается размер, соответствующий количеству инициализа­торов:

char laura[ ] = {‘l’, ‘m’, ‘p’};

равнозначно

char laura[3] = {‘l’, ‘m’, ‘p’};

Многомерный массив может быть инициализован заключенным в фигурные скобки списком инициализаторов, причем каждый ряд инициализуется своим спис­ком в фигурных скобках:

int а[2][3] = { {1, 2, 3}, {4, 5, 6} };

//то же, что {1, 2, 3, 4, 5, 6}

char name[3][9] = { "laura", "michele", "pohl" };

//завершенные '\0'

Связь между массивами и указателями

Имя массива само по себе является адресом или значением указателя. Массивы и указатели почти идентичны в смысле их использования для доступа к памяти. Од­нако существуют едва уловимые, но важные различия. Указатель — это переменная, принимающая в качестве значения адрес. А имя массива является конкретным фиксированным адресом, который может пониматься как постоянный указатель на первый (с индексом 0) элемент массива. Допустим, что мы написали следующее объявление:const int N = 100;

int a[N], *p;

и что система назначила байты памяти 300, 304, 308, ... , 696 в качестве адресов для хранения а[0],а[1],а[2],...,а[99] соответственно; при этом адрес 300 стал базовым адресом массива а. Мы полагаем, что каждый байт памяти адресуем, а для хранения целого используется четыре байта. Две инструкции

p = a; и p = &a[0];

являются равнозначными и присваивают p значение 300. Арифметика указателей предлагает альтернативу индексированию массивов. Две инструкции

p = a + 1; и p = & a [1];

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

sum = 0;

for (p = a; p < & a[N]; ++p)

sum += *p;

это равносильно

sum = 0;

for (i = 0; i < N; ++i)

sum += a[i];

Еще один способ суммирования массива:

sum = 0;

for (i=0; i<N; ++i)

sum += *(a +i)

Также как выражение *(a+i) равносильно а[i], выражение * (p + i ) равносильно p[i].

Мы не можем изменить адреса, отметим, что sizeof (a) и sizeof (p) различны. Первое выражение дает размер всего массива, тогда как второе – размер выражения – указателя.

Соседние файлы в папке Тельминов (мб)