Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2009 лекции ПЯВУ часть1.doc
Скачиваний:
22
Добавлен:
27.03.2015
Размер:
823.3 Кб
Скачать

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

Массивы могут содержать указатели [1]. Типичным использованием такой структуры данных является формирование массива строк. Каждый элемент такого массива – строка, но в С строка является, по существу, указателем на ее первый символ. Таким образом, каждый элемент в массиве строк в действительности является указателем на первый символ строки (см. рис. 5.3.). Рассмотрим объявление массива строкsuit

char *suit[4] = {“весна”, “лето”, “осень”, “зима”};

Элемент объявления suit[4]указывает массив из четырех элементов. Элемент объявленияchar*указывает, что тип каждого элемента массиваsuit– «указатель наchar». Четыре значения, размещаемые в массиве – это «весна», «лето», «осень», «зима». Каждое из них хранится в памяти как строка, завершающаяся нулевым символом, которая на один символ длиннее, чем число символов текста, указанного в кавычках. Эти четыре строки имеют длину 6, 5, 6 и 5 символов соответственно. Хотя это и выглядит так, словно эти строки помещены в массивsuit, на самом деле в массиве хранятся лишь указатели. Таким образом, хотя размер массиваsuitфиксирован, он обеспечивает доступ к строкам символов любой длины.

suit[0]

 

в'

е'

с'

н'

а'

\0'

suit[1]

 

л'

е'

т'

о'

'\0'

suit[2]

 

о'

с'

е'

н'

ь'

'\0'

suit[3]

 

з'

и'

м'

а'

'\0'

Рис. 5.3. Выделение памяти под массивы указателей

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

5.5. Динамическое выделение памяти под массивы

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

int i,k;

char c;

char * MyArr;

cout << "Enter a number" << endl;

cin >> i;

//выделение памяти под массив символьного типа

MyArr = new char[i];

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

{

MyArr[k] = k+60;

c = MyArr[k];

printf("%c\n", c);

}

//освобождение памяти из-под массив

delete [] MyArr;

Рис. 5.4. Работа с одномерным динамическим массивом

В случае если заранее неизвестны размеры массивов, тогда необходимо выделять память под массивы уже в процессе выполнения программы, получив от пользователя или рассчитав размер массива (рис. 5.4, 5.5 и 5.6).

int i,j, k, c;

int ** MyArr;

cout << "Enter two numbers" << endl;

cin >> i >> j;

//выделение памяти под двумерный массив

//сначала под массив указателей

MyArr = new int*[i];

//потом под каждый из подмассивов

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

{

MyArr[k] = new int[j];

}

//******************************************

Рис. 5.5. Выделение памяти под двумерный динамический массив

//вывод на экран элементов массива

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

{

for (k=0; k<j;k++)

{

MyArr[c][k] = c+k;

cout << MyArr[c][k] << '\t';

}

cout << endl;

}

//***************************************

//освобождение памяти

//сначала у каждого подмассива

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

delete []MyArr[k];

//потом у массива указателей

delete [] MyArr;

//************************************

Рис. 5.6. Работа с двумерным массивом и освобождение памяти из-под двумерного динамического массива