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

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

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

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

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

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

Пример 44.

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

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

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>

Первая строка

Вторая строка

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

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

Вторая строка

Первая строка

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