- •Предисловие
- •Знакомство с языком C
- •Структура программы
- •Пример простой программы
- •Более сложный пример
- •Контрольные вопросы
- •Основные понятия, объявление переменных, типы данных
- •Объявление переменных
- •Примеры описаний переменных:
- •Основные типы данных
- •Производные типы.
- •Контрольные вопросы
- •Ввод/вывод с помощью функций printf() и scanf().
- •Модификаторы спецификаций преобразования используемые в функции printf()
- •Применение функции scanf()
- •Контрольные вопросы
- •Операции
- •Простейшие арифметические операции
- •Операция присваивания
- •Использование в выражениях операндов разных типов
- •Операции преобразования типов
- •Дополнительные арифметические операции
- •Дополнительные операции присваивания
- •Операции отношения
- •Логические операции
- •Приоритеты операций
- •Таблица 3. Таблица приоритетов рассмотренных выше операций
- •Контрольные вопросы
- •Операторы
- •Оператор-выражение
- •Ветвление
- •Условный оператор
- •Оператор switch
- •Оператор break
- •Циклы
- •Цикл while
- •Цикл do…while
- •Цикл for
- •Другие операторы
- •Оператор continue
- •Оператор goto
- •Оператор вызова функции
- •Контрольные вопросы
- •Обработка числовых последовательностей
- •Последовательная обработка
- •Обработка числовых последовательностей
- •Примеры
- •Контрольные вопросы
- •Последовательная обработка символьных данных
- •Символьные данные
- •Последовательная обработка символов
- •Функции getchar( ) и putchar( )
- •Контрольные вопросы
- •Обработка массивов
- •Массивы
- •Объявление массива
- •Использование и обработка массивов
- •Примеры
- •Контрольные вопросы
- •Указатели и динамические массивы
- •Указатели
- •Динамическое выделение памяти
- •Статические и динамические массивы
- •Контрольные вопросы
- •Подпрограммы
- •Описание подпрограмм
- •Параметры подпрограмм
- •Область действия переменных
- •Примеры
- •Контрольные вопросы
- •Рекурсивные функции
- •Понятие рекурсивной функции
- •Контрольные вопросы
- •Символьные строки и функции обработки строк
- •Посимвольная обработка строк
- •Пример программы
- •Контрольные вопросы
- •Структуры
- •Тип данных структура
- •Контрольные вопросы
- •Работа с файлами
- •Примеры
- •Контрольные вопросы
- •Массивы и функции как параметры
- •Указатели на функции
- •Массивы и указатели
- •Указатели и двумерные массивы
- •Пример
- •Технологии программирования
- •Структурное программирование
- •Модульное программирование
- •Объектно-ориентированное программирование
- •Компонентное программирование
- •Структурная декомпозиция задачи и разработка алгоритмов и программ методами сверху вниз и снизу вверх
- •Контрольные вопросы
- •Модульное программирование
- •Работа с графикой на языке C и модуль graphics.h
- •Типы видео мониторов и их режимы
- •Инициализация графики
- •Система координат
- •Основные графические функции
- •Функции рисования
- •Функции изменения параметров рисования
- •Шаблоны линий
- •Шаблоны закраски
- •Задание на расчетно-графическую работу
- •Порядок выполнения работы
- •Задание
- •Задание для вариантов 1-11
- •Задание для вариантов 12-20
- •Задание для вариантов 21-40
- •Пример исходных данных для вариантов 12-16
- •Задание для вариантов 41-60
- •Варианты индивидуальных заданий
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •Вариант 6
- •Вариант 7
- •Вариант 8
- •Вариант 9
- •Вариант 10
- •Вариант 11
- •Вариант 12
- •Вариант 13
- •Вариант 14
- •Вариант 15
- •Вариант 16
- •Вариант 17
- •Вариант 18
- •Вариант 19
- •Вариант 20
- •Вариант 21
- •Вариант 22
- •Вариант 23
- •Вариант 24
- •Вариант 25
- •Вариант 26
- •Вариант 27
- •Вариант 28
- •Вариант 29
- •Вариант 30
- •Вариант 31
- •Вариант 32
- •Вариант33
- •Вариант 34
- •Вариант 35
- •Вариант 36
- •Вариант 37
- •Вариант 38
- •Вариант 39
- •Вариант 40
- •Вариант 41
- •Вариант 42
- •Вариант 43
- •Вариант 44
- •Вариант 45
- •Вариант 46
- •Вариант 47
- •Вариант 48
- •Вариант 49
- •Вариант 50
- •Вариант 51
- •Вариант 52
- •Вариант 53
- •Вариант 54
- •Вариант 55
- •Вариант 56
- •Вариант 57
- •Вариант 58
- •Вариант 59
- •Вариант 60
- •Задания на курсовую работу
- •Требования к курсовой работе
- •Этапы разработки программ
- •Содержание отчета по курсовой работе
- •Задания к курсовой работе
- •Литература
- •Функции консольного ввода/вывода
- •Функции обработки строк
- •Функции преобразования данных
Задания на курсовую работу
Требования к курсовой работе
Основная цель курсовой работы - научиться разрабатывать на языке высокого уровня (С/С++) сложные программы, имеющие многофункциональную структуру.
Работа должна быть выполнена в течение одного семестра. Для выданного преподавателем задания необходимо разработать и отладить на компьютере программу на языке С (или С++) и оформить отчет по курсовой работе. Список индивидуальных заданий приведен ниже.
Оценка курсовой работы зависит от качества выполнения и оформления курсовой работы, от результатов и сроков ее защиты.
Программа должна иметь многофункциональную структуру: состоять не из одной главной функции main(), но и еще из нескольких подпрограмм. Можно оформить отдельные функции в виде отдельных модулей, которые компилируются раздельно, а потом с помощью компоновщика объединяются в единый загрузочный модуль (exe-файл).
Всю необходимую функциям информацию следует передавать в виде параметров, а не через глобальные переменные, изменение которых трудно отследить.
Программа должна удовлетворять требованиям структурного программирования, должна содержать комментарии, поясняющие назначение каждой функции, ее параметров, локальных переменных и отдельных ее частей. Программа должна быть хорошо читаемой и понятной не только Вам, но и любому пользователю, знакомому с языком С (С++). Для наглядности программы соблюдайте ступенчатую форму записи, имена функций и переменных выбирайте осмысленные (Вам самим это поможет при отладке программы).
Программа должна быть отлажена. Для этого нужно обдуманно подобрать набор тестов, на котором будет проверяться работа программы,
164
причем делать это нужно не после написания программы, а до написания (тесты "черного ящика") и в процессе написания (тесты "белого ящика").
О содержании отчета по курсовой работе смотрите ниже, в приложении 1 приведен пример отчета.
Технология создания сложных программ хорошо изложена в учебных пособиях Хохлова Д.Г. "Основы технологии модульного программирования" [1] и Павловской Т.А. "C/C ++. Программирование на языке высокого уровня" (часть I) [2]. Необходимо следовать их рекомендациям. Не поленитесь, прочитайте литературу, иначе много времени будет потрачено впустую, а желание программировать может вообще пропасть. Научитесь профессиональному подходу к созданию сложных программ.
В книге [3] Вы можете посмотреть примеры решения подобных задач.
Этапы разработки программ
Разработка любой сложной программы осуществляется поэтапно [1,2]. I этап. Разобравшись в постановке задачи, нужно создать так
называемую внешнюю спецификацию программы, которая включает в себя:
−описание входных и выходных данных;
−описание задачи, реализуемой программой;
−способ обращения к программе;
−описание возможных аварийных ситуаций и ошибок пользователя. Входные и выходные данные должны быть представлены в удобной для
пользователя форме.
На этом этапе полезно подобрать тесты “черного ящика” для проверки программы (т.е. рассматривая программу как черный ящик, подобрать такой набор тестов, чтобы учесть все возможные ситуации, в том числе и ошибочные). Это поможет лучше понять задачу.
II этап. Разработка внутренних структур для представления входных, выходных и промежуточных данных.
165
От выбора структур данных будет во многом зависеть алгоритм решения задачи. Например, если выходные данные должны представлять собой сортированную таблицу, можно создать в памяти таблицу в виде вектора, а затем выполнить ее сортировку, а можно создать динамическую сортированную таблицу в виде списка.
III этап. Проектирование структуры программы.
На этом этапе применяется технология нисходящего проектирования программ. Задача разбивается на подзадачи, которые можно рассматривать раздельно. Каждая подзадача оформляется как отдельная функция (подпрограмма). Для каждой подпрограммы составляется внешняя спецификация, аналогичная приведенной выше.
Затем при пошаговой детализации каждая подзадача может быть разбита на еще более мелкие подзадачи, которые также оформляются как отдельные функции. При разработке структуры функции вначале нужно выбрать наиболее эффективный метод решения задачи и записать в обобщенной форме алгоритм (например, в виде укрупненной блок-схемы), затем решить, какие части алгоритма (блоки схемы) целесообразно представить в виде отдельных функций.
Здесь важно продумать интерфейс – способ взаимодействия функций. Интерфейс функции определяется ее заголовком (где указываются имя функции, ее параметры и тип возвращаемого значения).
На этом этапе нужно также решить, из каких модулей будет состоять программа. Модуль может содержать одну или несколько взаимосвязанных функций и общие для функций данные. Каждый модуль помещается в отдельный файл (с расширением .c или .cpp) и компилируется автономно. Получившиеся в результате компиляции объектные модули объединяются в единый исполняемый модуль (exe-файл) с помощью компоновщика (Linker).
Разбиение программы на модули уменьшает время перекомпиляции программы и облегчает процесс отладки, позволяя отлаживать программу по частям. Чем более независимы модули, тем легче отлаживать программу.
166
Одна из основных задач – хорошо продумать интерфейс модулей. Интерфейсом модуля являются заголовки всех функций и описания доступных извне типов, переменных и констант.
Примечание. Описания глобальных типов данных, констант, переменных и прототипы всех функций лучше поместить в отдельный файл с
расширением |
.h , а в остальные файлы (с расширением .c |
или .cpp) |
|
включать эти |
описания с помощью директивы |
#include |
“имя.h” . |
Глобальные переменные, правда, лучше не использовать (тогда интерфейс каждой функции будет полностью определяться ее заголовком).
Таким образом, на данном этапе строится модульная и функциональная структура программы и определяется интерфейс между модулями и функциями, а также разрабатываются обобщенные алгоритмы функций.
Процесс проектирования структуры программы является итерационным, поскольку в сложных программах невозможно сразу продумать все детали.
IV этап. Структурное программирование и тестирование программы. Процесс программирования и тестирования также организуется по
принципу «сверху-вниз». Вначале описывается главная функция программы, затем функции следующего уровня и т. д. Параллельно разрабатываются тесты для проверки каждой функции и каждого модуля. Набор тестов должен быть достаточно большим.
Тесты подбираются по методам «черного и белого ящиков». В методах «черного ящика» программа (подпрограмма) рассматривается, как черный ящик: известно только какие выходные данные должны получиться при определенных входных данных. Каждый тест должен содержать определенные входные данные и ожидаемый результат. Тесты должны охватывать как правильные, так и неправильные входные данные. Например, если входные данные читаются из заданного файла, то следует взять и «неправильные тесты»: например, когда файла с заданным именем нет в указанной папке, когда файл пустой. Тесты «черного ящика» следует подбирать еще на предыдущем этапе.
167
В тестах «белого ящика» учитывается алгоритм программы (подпрограммы). Каждая ветвь в структурах ветвления (операторы if, switch), каждый цикл должны проверяться при тестировании. Например, программа выводит меню из четырех пунктов, и в зависимости от номера выбранного пункта либо вызывает одну из трех подпрограмм, либо завершает свою работу (см. пример программы в приложении). Необходимо взять, по крайней мере, пять тестов: по одному для каждого пункта меню и с неверным номером пункта меню.
Прежде чем тестировать программу на компьютере полезно выполнить ручное тестирование. Это поможет выявить и исправить ошибки еще до ввода программы.
При написании программы и ее тестировании по принципу «сверхувниз» функции нижнего уровня (еще не написанные) заменяются так называемыми «заглушками». В простейшем случае «заглушки» просто выдают сообщение о том, что подпрограмма вызвана. Например, для проверки работы главной функции программы, описанной в приложении 1, вместо каждой из трех вызываемых подпрограмм (Date, MiddleAge, Diagnos) можно написать «заглушку». Пример для функции Date:
void Date (FILE *f)
{ puts ("\nФункция Date вызвана ");
}
После отладки главной функции и написания определения, например, функции Date, «заглушка» этой функции заменяется на ее определение и выполняется тестирование этой функции (совместно с главной). Затем постепенно добавляются и проверяются остальные функции.
Если в процессе тестирования функции результаты окажутся неверными, то нужно будет отладить эту функцию. В процессе отладки может измениться не только алгоритм функции, но и появиться новые подпрограммы, т.е. может измениться функциональная структура программы.
168