Массивы указателей и указатели на указатели
Во многих случаях массивы указателей дают более компактное представление данных.
Пример
char *messages[]={“Не открыт файл”,
“Ошибка ввода”,
“Диск”,
“Тайм-аут”, } ;
В данном примере инициализируется массив указателей на 5 элементов. Литералы в основной памяти располагаются вплотную и заканчиваются ’\0’. Любой элемент массивы messages создаёт адрес литерала, а последний указатель не инициализируется.
Для работы с этими массивами можно определить временный указатель на указатель
char **mesPtr = messages;
Пример
Выполняется сортировка в алфавитном порядке вводимых с клавиатуры строк. Строки размещаются в двумерном массиве buffer. Вместо того чтобы перемещать в памяти строки, выполняется упорядочивание значений указателей, что позволяет выполнить сортировку намного быстрее. Всегда при построении подобных алгоритмов продумывать метод сокращения времени на операцию сравнения элементов и изменение взаимного расположения в памяти!
#define STOP_STR “”
#define BUF_SIZE 81
#define STR_NUMBER 100
#include <stdio.h>
#include <string.h>
main(void)
{char buffer[STR_NUMBER][BUF_SIZE];
char *pointrs[STR_NUMBER], *ptr;
int i,n,index;
/* Цикл заканчивается при вводе ENTER или достижении STR_NUMBER */
puts(“Вводите строки. Конец ввода - ENTER.\n”);
for(index=0; index<STR_NUMBER; index++)
{
ptr = gets(buffer[index]);
if(strcmp(ptr,STOP_STR)) break;
pointrs[index] = ptr;
}
puts(“Отсортированные строки”);
n=index;
for(index=0; index<n; index++)
for(i=1; i<n; i++)
if(strcmp(pointrs[i-1], pointrs[i])>0)
{ /*условие изменения порядка строк*/
ptr = pointrs[i];
pointrs[i] = pointrs[i-1];
pointrs[i-1] = ptr;
}
/*распечатка отсортированных строк*/
for(index=0; index <= n; index++)
puts(pointrs[index]);
return 0;
}
Меняются местами ссылки, но не строки и за счет этого скорость выполнения программы намного выше по сравнению с тем, если бы местами в процессе сортировки менялись сами строки. В программе используется сортировка выборкой по методу «пузырька».
Пример
int data = 5;
int *ptr = &data;
int **ptr_ptr = &ptr; /*указатель на указатель, если было бы просто ptr, то был бы адрес data*/
Пример
Ранее был объявлен массив указателей messages. Тогда для его распечатки к этому объявлению добавим: ptr_ptr
char **ptr_ptr = messages;
|
|
|
|
|
Сам массив messages необходимо инициализировать
так, чтобы последний указатель был равен 0, т.е.
надо предварительно выполнить в программе:
|
Вопросы для самоконтроля
- Можно ли в программе выполнить оператор s = “Слово”; если в программе применена следующая декларация: char s[20]; ?
- Перечислите файлы прототипов функций для работы с символами и строками!
- Можно ли инициализировать массивы указателей на строковые литералы?
- Что означает декларация «char **ptr;»?
- Что означает выражение «*(p + 2) = ‘d’», если в программе имеется следующая декларация «char p[80];»?
- Объявить указатель на массив указателей типа int из 10-ти элементов!
- Чем отличаются char *messages[10] от char(*messages)[10]?
- Дать примеры указателей на массив, массив адресов функций и т.п.!
Вопросы для самостоятельного изучения
- Запишите спецификации функций для сравнения, сцепления и определения длин строк!
Дата добавления: 2016-05-26; просмотров: 1488;