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