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

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

Элементы массива могут иметь любой тип (кроме массива и функции) в том числе могут быть и указателями-переменными. Наиболее часто массивы указателей используется для компактного расположения строк текста, структурных переменных и других “протяженных” объектов данных.

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

c har *massage [20] ;

1) объект с этим именем есть

2) массив из 20 элементов

3) указателей

4) на символьные данные.

При описание можно задать инициализацию массива :

char *massage [ ] = { “Не открыт файл”,

“Ошибка ввода”,

“Диск”,

“Тайм – аут” };

Компилятор резервирует место для 4-х указателей-констант, равных адресам начала в памяти соответствующих строковых литералов.

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

char array [ ] [16] = { “Не открыт файл”,

“Ошибка ввода”,

“Диск”,

“Тайм – аут” };

Внутреннее преставление массивов array и massage в памяти при компиляции можно представит следующей схемой.

Массив char array [4] [16] (размер 4*16 = 64 байта):

адреса (16-чные):

019С

Н

е

о

т

к

р

ы

т

ф

а

й

л

0

0

01AC

О

ш

и

б

к

а

в

в

о

д

а

0

0

0

0

01BC

Д

и

с

к

0

0

0

0

0

0

0

0

0

0

0

0

01CC

Т

а

й

м

-

а

у

т

0

0

0

0

0

0

0

0

Массив указателей char *massage [4] (размер 8 байт):

0194

01DC

01EB

01F8

01ED

Строковые литералы, адресами которых инициировался массив char *massage [4] (размер 42 байта):

01DС

Н

е

о

т

к

р

ы

т

ф

а

й

л

0

01EB

О

ш

и

б

к

а

в

в

о

д

а

0

01F8

Д

и

с

к

0

01ED

Т

а

й

м

-

а

у

т

0

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

Пример. Выполнить сортировку вводимых с клавиатуры строк в алфавитном порядке. Признаком завершения ввода является ввод пустой строки (“”). Вводимые строки помещаются в двухмерный массив. Сортировка объектов предполагает перемещение их в памяти. Однако перенос текстовых строк из одного места памяти в другое требует значительных затрат времени и места в памяти. Намного проще будет работа с массивом указателей. Он сортируется так, чтобы первый элемент указывал на “наименьшую” (по коду символов) строку, а последний – на “наибольшую” строку. Таким образом сортируется не массив строк, а массив указателей на них.

В программе для сравнения строк в лексикографическом порядке используется библиотечная функция

int strcmp (const char *s1, const char *s2);

где *s1, *s2 – указатели на строки.

Программа:

#include<stdio.h>

#include<conio.h>

#include<string.h> /* для функции strcmp() */

#define STOPSTR “” /* символ окончания строки */

#define BUFSIZE 81 /* размер буфера */

#define STRNUM 100 /* количество строк */

void main() /* главная программа */

{ char buffer [STRNUM][BUFSIZE]; /* массив для приема строк */

char *pointers [STRNUM], *ptr; /* массив указателей */

int i, ns, ind; /* параметры циклов */

clrscr(); /* очистка экрана */

puts (“Введите строки, заканчивая нажатием клавиши <Enter>.”);

puts (“Для завершения ввода нажмите <Enter>”);

for (ind=0; ind < STRNUM; ind++) /* цикл ввода строк в buffer */

{ gets (buffer[ind]; /* ввод строки */

if ( !strcmp(buffer[ind], STOPSTR)) /* если введена пустая строка */

break; /* закончить цикл ввода строк*/

pointers [ind] = buffer [ind]; /* запись указателя в массив */

}

ns = ind; /* запись числа строк */

puts (“Прием строк завершен.”);

puts (“Сортировка строк по возрастанию методом ‘пузырька’:”);

for (ind=0; ind < ns; ind++) /* цикл по строкам */

for ( i=ns -1; i >= ind; i- -) /* обратный цикл по строкам */

{ if (strcmp(pointers[i –1], pointers[i]) > 0) /* если строка i > i-1, */

{ ptr = pointers[i]; /* то перестановка */

pointers[i] = pointers[i –1]; /* местами */

pointers[i –1] = ptr; /* указателей */

}

}

for ( i=0; i >= ns; i++) /* цикл пока есть строки */

puts (pointers[i]); /* вывод строк по указателям */

puts (“\nНажмите любую клавишу.”);

getch(); /* задержка экрана */

}

Результаты программы:

Введите строки, заканчивая нажатием клавиши <Enter>.

Для завершения ввода нажмите <Enter>

ПЕРВАЯ СТРОКА

ВТОРАЯ СТРОКА

Прием строк завершен.

Сортировка строк по возрастанию методом ‘пузырька’

ВТОРАЯ СТРОКА

ПЕРВАЯ СТРОКА

Нажмите любую клавишу.