- •СОДЕРЖАНИЕ
- •ПРЕДИСЛОВИЕ
- •ГЛАВА 1. Введение в алгоритмы
- •1.1. Этапы решения задач на ЭВМ
- •1.2. Понятие алгоритма
- •1.3. Свойства алгоритмов
- •1.4. Сложность алгоритма
- •1.7. Пример простейшего линейного процесса
- •1.7. Пример циклического процесса
- •ГЛАВА 2. Базовые средства языка Си
- •2.1. Алфавит языка Си
- •2.2. Лексемы
- •2.3. Идентификаторы и ключевые слова
- •2.4. Комментарии
- •2.5. Простейшая программа
- •2.7. Декларация объектов
- •2.8. Данные целого типа (integer)
- •2.9. Данные символьного типа (char)
- •2.10. Данные вещественного типа (float, double)
- •ГЛАВА 3. Константы в программах
- •3.2. Константы вещественного типа
- •3.4. Строковые константы
- •ГЛАВА 4. Обзор операций
- •4.1. Операции, выражения
- •4.3. Операция присваивания
- •4.4. Сокращенная запись операции присваивания
- •4.7. Операции сравнения
- •4.8. Логические операции
- •4.10. Операция «,» (запятая)
- •ГЛАВА 5. Обзор базовых инструкций языка Си
- •5.2. Стандартные математические функции
- •5.3. Функции вывода данных на дисплей
- •5.4. Функции ввода информации
- •ГЛАВА 6. Составление разветвляющихся алгоритмов
- •6.1. Краткая характеристика операторов языка Си
- •ГЛАВА 7. Составление циклических алгоритмов
- •7.1. Понятие циклического кода
- •7.2. Оператор с предусловием while
- •7.4. Оператор цикла с предусловием и коррекцией for
- •ГЛАВА 8. Операторы и функции передачи управления
- •8.1. Оператор безусловного перехода goto
- •8.2. Операторы continue, break и return
- •8.3. Функции exit и abort
- •Советы по программированию
- •ГЛАВА 9. Указатели
- •9.1. Определение указателей
- •9.2. Операция sizeof
- •9.3. Инициализация указателей
- •9.4. Операции над указателями
- •ГЛАВА 10. Массивы
- •10.1. Понятие массива
- •10.2. Одномерные массивы
- •10.4. Строки как одномерные массивы данных типа char
- •10.5. Указатели на указатели
- •10.8. Работа с динамической памятью
- •10.9. Библиотечные функции
- •10.10. Пример создания одномерного динамического массива
- •ГЛАВА 11. Функции пользователя
- •11.1. Декларация функции
- •11.2. Вызов функции
- •11.3. Передача аргументов в функцию
- •11.4. Операция typedef
- •11.5. Указатели на функции
- •ГЛАВА 12. Классы памяти и область действия объектов
- •ЗАДАНИЕ 4. Обработка массивов
- •Первый уровень сложности
- •Второй уровень сложности
- •ЗАДАНИЕ 5. Функции пользователя
- •Первый уровень сложности
- •Второй уровень сложности
- •12.3. Статические и внешние переменные
- •12.4. Область действия переменных
- •Советы по программированию
- •13.1. Структуры
- •13.5. Вложенные структуры
- •13.6. Массивы структур
- •13.7. Размещение структурных переменных в памяти
- •13.8. Объединения
- •13.9. Перечисления
- •13.10. Битовые поля
- •ГЛАВА 14. Файлы в языке Си
- •14.1. Открытие файла
- •14.2. Закрытие файла
- •14.3. Запись-чтение информации
- •14.5. Дополнительные файловые функции
- •Советы по программированию
- •ЗАДАНИЕ 7. Создание и обработка файлов
- •Первый уровень сложности
- •Второй уровень сложности
- •ГЛАВА 15. Динамические структуры данных
- •15.1. Линейные списки
- •15.2.1. Алгоритм формирования стека
- •15.2.2. Алгоритм извлечения элемента из стека
- •15.2.3. Просмотр стека
- •15.2.4. Алгоритм освобождения памяти, занятой стеком
- •15.2.5. Алгоритм проверки правильности расстановки скобок
- •15.3.1. Формирование очереди
- •15.3.2. Алгоритм удаления первого элемента из очереди
- •15.4. Двунаправленный линейный список
- •15.4.1. Формирование первого элемента
- •15.4.3. Алгоритм просмотра списка
- •15.4.5. Алгоритм удаления элемента в списке по ключу
- •15.5. Нелинейные структуры данных
- •15.5.1. Бинарные деревья
- •15.5.2. Основные алгоритмы работы с бинарным деревом
- •15.5.4. Вставка нового элемента
- •15.6. Построение обратной польской записи
- •15.6.1. Алгоритм, использующий дерево
- •15.6.2. Алгоритм, использующий стек
- •15.6.3. Пример реализации
- •15.7. Понятие хеширования
- •15.7.2. Примеры хеш-функций
- •15.7.3. Схемы хеширования
- •15.7.4. Примеры реализации схем хеширования
- •Вариант 2. Двунаправленные списки
- •ГЛАВА 16. Переход к ООП
- •16.1. Потоковый ввод-вывод
- •16.3. Проблема ввода-вывода кириллицы в среде Visual C++
- •16.4. Операции new и delete
- •16.6. Шаблоны функций
- •Первый уровень сложности
- •Второй уровень сложности
- •6.1. Основные понятия
- •6.3. Примитивы GDI
- •6.5. Получение описателя контекста устройства
- •6.6. Основные инструменты графической подсистемы
- •6.7. Закрашивание пустот
- •6.8. Рисование линий и кривых
- •6.9. Пример изображения графика функции sin
- •6.10. Рисование замкнутых фигур
- •6.11. Функция Polygon и режим закрашивания многоугольника
- •6.13. Управление областями вывода и отсечением
- •ЗАДАНИЕ 11. Создание графических изображений
- •ЛИТЕРАТУРА
Приложение 6
«книжные» с засечками (переменный шаг), FF_SWISS – без засечек (переменный шаг), FF_SCRIPT – «рукописные» и курсивные;
lpszFace – имя шрифта, обычно совпадает с именем его дискового файла; если NULL – система подбирает шрифт, наиболее отвечающий заданным требованиям, иначе явно указанный шрифт перекрывает их.
Функция CreateFontIndirect (const LOGFONT* lplgFont); использует в качестве аргумента структуру с полями аналогичного назначения.
Параметры шрифта не включают цвет отображающего инструмента.
Управление цветом выводимого текста осуществляется функциями |
Р |
|||||||||||
|
COLORREF SetTextColor (hdc, crColor); |
|
|
|||||||||
|
COLORREF GetTextColor (hdc); |
|
|
|||||||||
Базовой функцией вывода символа является |
|
|
||||||||||
|
BOOL TextOut (hdc, nXStart, nYStart, lpString, cbString); |
|||||||||||
|
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
И |
||
Позицией символа считается верхний левый угол его знакоместа. |
||||||||||||
|
|
|
|
6.7. Закрашивание пустот |
У |
|
|
|||||
|
|
|
|
|
|
|
|
Г |
|
|
|
|
Если выбранные перо или кисть не сплошные, то они не воздействуют |
||||||||||||
на фоновые промежутки, например, междуБштрихами, однако эти |
||||||||||||
промежутки заполняются фоновым цветом, для работы с которым служат |
||||||||||||
функции |
|
|
|
|
|
|
|
а |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
COLORREF SetBkColor(hdc, crColor); |
|
|
|
|
|||||||
|
|
|
|
|
|
|
к |
|
|
|
|
|
|
COLORREF GetBkColor(hdc); |
|
|
|
|
|||||||
первая из |
которых устанавлив |
е |
|
|
|
|
текущий |
|||||
|
новый, а вторая – получает |
|||||||||||
фоновые |
цвета; признак шибки |
– значение CLR_INVALID. |
|
Функция |
||||||||
SetBkColor возвращает значение предыдущего цвета. |
|
|
|
|
||||||||
Функции |
|
|
ает |
|
|
|
|
|
|
|||
|
о |
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
||
|
int SetBkMode (hdc, iBkMode); |
|
|
|
|
|||||||
|
|
|
и |
|
|
|
|
|
|
|
|
|
|
int GetBkMode (hdc); |
|
|
|
|
|
|
|
||||
|
|
л |
|
|
|
|
|
|
|
|
|
|
соответственно устанавливают новый или определяют текущий режим фона, |
||||||||||||
0 – пр знакбошибки; параметр int iBkMode – режим фона, по умолчанию |
||||||||||||
белый (OPAQUE) – сначала рисуется фон, затем передний план; режим |
||||||||||||
и |
|
|
|
|
|
|
|
|
|
|
|
|
TRANSPARENT – отменяет заполнение пустот, в этом случае цвет фона |
||||||||||||
игнорируется и пустоты заполняться не будут. |
|
|
|
|
||||||||
Б |
|
|
|
|
|
|
|
|
|
|
|
|
6.8. Рисование линий и кривых
Теоретически все, что необходимо драйверу устройства для рисования,
это функции SetPixel и GetPixel.
Значительно более эффективным является использование стандартных функций рисования отрезков и других сложных графических операций.
225
Приложение 6
На представление линий, созданных с использованием функций, влияют атрибуты контекста устройства: текущая позиция, перо, режим фона (для несплошных перьев), цвет фона (для режима фона OPAQUE) и режим рисования.
Функция
LineTo (hdc, xEnd, yEnd);
рисует отрезок прямой из текущего положения пера, определенного в контексте устройства, до точки (xEnd, yEnd), которая не включается в
отрезок. В контексте текущее положение пера по умолчанию
установки текущей позиции нарисует отрезок, начинающийсяРв левом верхнем углу рабочей области окна.
устанавливается в точку (0,0) и функция LineTo без предварительной
Для рисования отрезка из точки (xStart, yStart) в точку (xEnd, yEnd) необходимо сначала для установки (изменения) текущего положения пера
использовать функцию |
|
И |
|
MoveToEx (hdc, xStart, yStart, &pt); |
|
||
У |
|||
|
|||
pt – структура типа POINT, определяющая предыдущую позицию. После |
|||
чего, используя LineTo (hdc, xEnd, yEnd); будет нарисованГ |
отрезок до точки |
(xEnd, yEnd), не включая ее в отрезок, и текущее положение пера установится |
||||
в точку (xEnd, yEnd). |
|
Б |
||
Узнать текущее положение пера можно с помощью функции |
||||
|
GetCurrentPositionEx (hdc,а&pt); |
|||
Следующий фрагме программыкотображает в рабочей области окна |
||||
сетку с интервалом в 100 пиксел й, начиная от левого верхнего угла: |
||||
|
|
|
е |
|
GetClientRect (hwnd, &rect); (см. Пример 1, Сообщение WM_PAINT); |
||||
for (x = 0; x < rect.right; x += 100) |
{ |
|||
|
MoveToEx (hdc, x, 0, NULL); |
|
||
|
|
нт |
|
|
|
LineTo (hdc, x, rect.bottom); |
|
||
} |
|
о |
|
|
for (y = 0; yи< rect.bottom; y += 100) { |
||||
|
MoveToEx (hdc, 0, y, NULL); |
|
||
|
л |
|
|
|
|
LineTo (hdc, rect.right, y); |
|
||
} б |
|
|
|
|
Когда необходимо соединить отрезками массив точек pt размером |
||||
и |
|
|
|
|
cPoint, можно использовать функцию |
|
|||
Б |
Polyline (hdc, pt, cPoint); |
|
||
|
|
|
|
Например, определим массив из 5 точек (10 значений), описывающих контур прямоугольника:
POINT pt [5] = { 100, 100, 200, 100, 200, 200, 100, 200, 100, 100 };
используем функцию Polyline (hdc, pt, 5). Следует обратить внимание, что первая и последняя точки совпадают.
226
Приложение 6
Функция Polyline не учитывает и не изменяет текущее положение пера. Функция PolylineTo использует текущее положение для начальной точки и устанавливает текущее положение в конец последнего нарисованного отрезка. Предыдущий пример будет выглядеть
MoveToEx (hdc, pt[0].x, pt[0].y, NULL); PolylineTo (hdc, pt + 1, 4);
Для рисования дуги эллипса (рис. П 6.2) используется функция
Arc (hdc, x1, y1, x2, y2, xStart, yStart, xEnd, yEnd); |
|
Р |
||||||||||
в которой значения (x1, y1) задают левый верхний угол, (x2, y2) – правый |
||||||||||||
нижний; (xStart, yStart) – начало дуги; (xEnd, yEnd) – конец дуги. |
|
|||||||||||
|
|
x1 |
yStart |
xStart |
|
|
|
И |
||||
|
|
|
|
|
|
|
||||||
y1 |
|
|
|
|
|
У |
|
|||||
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
Г |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
||
xEnd |
|
|
|
|
|
|
Б |
|
|
|
||
yEnd |
|
|
|
|
|
а |
|
|
|
|
||
|
|
|
|
|
|
|
x2 |
y2 |
|
|
||
|
|
|
|
к |
|
|
|
|||||
|
|
|
|
|
|
|
|
|||||
|
|
|
е |
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
||||
Рис. П 6.2. Фигура, нарисованная с использованием функции Arc |
||||||||||||
|
|
т |
|
|
|
|
|
|
|
|
|
|
Чтобы нарисовать одну или более связанных кривых Безье, |
||||||||||||
используются функции |
|
|
|
|
|
|
|
|
|
|
|
|
о |
|
|
|
|
|
|
|
|
|
|
||
PolyBezier (hdc, pt, iCount); |
|
|
|
|
|
|
||||||
PolyBezierTo (hdc, pt, iCount); |
|
|
|
|
|
|||||||
и |
|
|
|
|
|
|
|
|
|
|
|
pt – массив структур т па POINT. В функции PolyBezier первые четыре точки идут в таком лпорядке: начальная точка, первая контрольная точка, вторая контрольнаябточка, конечная точка кривой Безье. Каждая следующая кривая Безье тре ует три новых точки, поскольку начальная точка следующей кривойиесть конечная точка предыдущей и т.д. Параметр iCount = 1+3*n – равен ед н це плюс три, умноженное на число отображаемых кривых.
Б 6.9. Пример изображения графика функции sin
Программа содержит массив из 1000 структур POINT. В цикле от 0 до 999 член x структуры растет от 0 до cxClient. В каждом цикле член структуры определяет значение синуса и масштабируется до размеров клиентской области окна. Вся кривая целиком отображается с использованием одного вызова функции Polyline (рис. П 6.3).
Текст программы может быть следующим:
#include <windows.h> #include <math.h>
227
Приложение 6
#define NUM 1000
#define TWOPI (2 * 3.14159)
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{ |
|
|
|
|
|
|
|
|
|
|
|
static char szAppName[] = "Sin" ; |
|
|
|
|
|
|
|||||
HWND |
hwnd ; |
|
|
|
|
|
|
|
|
|
|
MSG |
msg ; |
|
|
|
|
|
|
|
|
|
|
WNDCLASSEX wndclass ; |
|
|
|
|
|
И |
|||||
wndclass.cbSize |
= sizeof (wndclass) ; |
|
|
|
|
Р |
|||||
wndclass.style |
= CS_HREDRAW | CS_VREDRAW ; |
||||||||||
wndclass.lpfnWndProc |
|
= WndProc ; |
|
Г |
|
|
|||||
wndclass.cbClsExtra |
= 0 ; |
|
|
|
|
У |
|
||||
wndclass.cbWndExtra |
|
= 0 ; |
|
|
Б |
|
|||||
wndclass.hInstance |
= hInstance ; |
|
|||||||||
wndclass.hIcon |
= LoadIcon (NULL, IDI APPLICATION) ; |
||||||||||
wndclass.hCursor |
= LoadCursor (NULL, IDC_ARROW) ; |
|
|||||||||
|
|
|
|
|
|
а |
|
|
|
|
|
wndclass.hbrBackground=(HBRUSH) GetStockObject(WHITE_BRUSH); |
|||||||||||
|
|
|
|
|
к |
|
|
|
|
|
|
wndclass.lpszMenuName = NULL ; |
|
|
|
|
|
||||||
|
|
|
|
е |
|
|
|
|
|
|
|
wndclass.lpszClassName = szAppName ; |
|
|
|
|
|
||||||
wndclass.hIconSm |
|
= LoadIcon (NULL, IDI_APPLICATION) ; |
|||||||||
|
|
т |
|
|
|
|
|
|
|
||
RegisterClassEx (&wndclass) ; |
|
|
|
|
|
|
|||||
hwnd = CreateWindow (szAppName, "Second Example", |
|
|
|||||||||
|
о |
|
|
|
|
|
|
|
|
||
|
WS OVERLAPPEDWINDOW, |
|
|
|
|||||||
|
и |
|
|
|
|
|
|
|
|
|
|
|
CW USEDEFAULT, CW_USEDEFAULT, |
|
|||||||||
|
CW USEDEFAULT, CW_USEDEFAULT, |
|
|||||||||
|
NULL, NULL, hInstance, NULL) ; |
|
|
|
|||||||
ShowWindow (hwnd, iCmdShow) ; |
|
|
|
|
|
||||||
б |
|
|
|
|
|
|
|
|
|
|
|
UpdateWindow (hwnd) ; |
|
|
|
|
|
|
|
|
|||
и} |
|
(&msg, NULL, 0, 0)) { |
|
|
|
|
|||||
while (GetMessageл |
|
|
|
|
|||||||
TranslateMessage (&msg) ; |
|
|
|
|
|
|
|||||
Б} |
|
|
|
|
|
|
|
|
|
|
|
DispatchMessage (&msg) ; |
|
|
|
|
|
|
|||||
return msg.wParam ; |
|
|
|
|
|
|
|
|
|
||
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, |
|||||||||||
WPARAM wParam, LPARAM lParam) |
|
|
|
|
|
||||||
{ |
|
|
|
|
|
|
|
|
|
|
|
static int cxClient, cyClient ; |
|
|
|
|
|
|
|||||
HDC |
hdc ; |
|
|
|
|
|
|
|
|
|
|
int |
i ; |
|
|
|
|
|
|
|
|
|
|
228 |
|
|
|
|
|
|
|
|
|
|
|