- •Программирование на языке высокого уровня
- •Составитель: л.А. Прокушев
- •Подписано к печати Формат 60х84 1/16. Бумага тип. №3
- •Редакционно-издательский отдел
- •190000, Санкт-Петербург, ул. Б. Морская, 67
- •Алгоритмизация вычислительных процессов
- •Средства программирования вычислительных процессов
- •Данные и их типы
- •Константы
- •Переменные
- •Ввод-вывод данных
- •Ввод-вывод данных в стиле с
- •Форматированный ввод
- •Форматированный вывод
- •Консольный ввод-вывод
- •Функция ввода символа (без отображения):
- •Функция очистки экрана результатов:
- •Выражения и операции
- •Логические выражения и операции.
- •Работа с ветвящимися процессами Операторы
- •Оператор присваивания
- •Условный оператор (if)
- •Операторы передачи управления
- •Оператор break (прервать) используется для прерывания работы текущего сложного оператора, в теле которого находится оператор break, и передачи управления на следующий по порядку оператор.
- •Оператор выбора (switch)
- •Действие оператора выбора состоит в следующем:
- •Введите 2 числа х, y : 3 8
- •Работа с циклическими вычислительными процессами
- •Циклы с фиксированным числом повторений Оператор цикла с предусловием (while)
- •Прерывание цикла
- •Циклы с неизвестным числом повторений Вычисление рекуррентных последовательностей
- •Оператор цикла с постусловием (do)
- •Вложенные циклы и организация диалога в программе
- •Оператор цикла с параметром (for)
- •Программа:
- •Работа с массивами
- •Описание массива
- •Доступ к элементам массива
- •Указатель.
- •Занесение данных в массив
- •Многомерные массивы
- •Работа с функциями
- •Определение функции
- •Вызов функции
- •Передача параметров функции
- •Передача данных по значению
- •Передача данных по адресу
- •Прототип (шаблон) функции
- •Блочная структура программы
- •Внешние описания переменных
- •Многомодульные программы Проект программы
- •Внешние ссылки
- •Создание проекта программы
- •Работа с указателями Объявления объектов со сложными описателями
- •Массивы указателей
- •Указатель на указатель
- •Указатель на функцию
- •Использование указателя на функцию как аргумента
- •Массивы указателей на функции
Массивы указателей
Элементы массива могут иметь любой тип (кроме массива и функции) в том числе могут быть и указателями-переменными. Наиболее часто массивы указателей используется для компактного расположения строк текста, структурных переменных и других “протяженных” объектов данных.
Массивы указателей должны описываться так же, как и другие массивы. Например, интерпретируем следующее описание массива:
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>
Первая строка
Вторая строка
Прием строк завершен.
Сортировка строк по возрастанию методом ‘пузырька’
Вторая строка
Первая строка
Нажмите любую клавишу.