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

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

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

char *massage [20];

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

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

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

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

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

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

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

“Диск”,

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

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

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

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

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

“Диск”,

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

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

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

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

019С Н е   о т к р ы т   ф а й л    
01AC О ш и б к а   в в о д а        
01BC Д и с к                        
01CC Т а й м - а у т                

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

  01DC 01EB 01F8 01ED

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

01DС Н е   о т к р ы т   ф а й л    
01EB О ш и б к а   в в о д а        
01F8 Д и с к                        
01ED Т а й м - а у т                

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

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

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

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>

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

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

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

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

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

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

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: