- •Методические указания к лабораторным работам
- •Лабораторная работа №1 простые программы с циклами и операторами консольного ввода/вывода
- •Задание
- •Описание примера
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №2 работа с текстовыми файлами, структурами данных и меню
- •Задание
- •Структурное программирование и функциональная декомпозиция системы
- •Функции
- •Организация меню в консольном приложении
- •Структуры данных
- •Операции с файлами
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №3 разработка и спецификация функций и модулей программы
- •Задание
- •Модульная структура программ
- •Параметры командной строки
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №4 разработка и спецификация структур данных, использование указателей и динамических массивов структур
- •Задание
- •Указатели
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №5 использование объектно-ориентированного программирования в разработке приложений
- •Задание
- •Конструкторы и деструкторы
- •Конструктор по умолчанию
- •Конструктор копирования
- •Массивы объектов
- •Friend-конструкции
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №6 использование наследования, полиморфизма и абстрактных классов
- •Задание
- •Наследование данных и методов
- •Полиморфизм и виртуальные функции
- •Абстрактный класс
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №7
- •Сложные структуры из объектов классов
- •Цель работы - изучение организации различных структур данных и разработка методов манипулирования данными.
- •Задание
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №8 разработка windows-интерфейса приложения
- •Задание
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Лабораторная работа №9 разработка и использование com-сервера
- •Задание
- •Шаблоны классов
- •Использование библиотеки atl для создания серверов сом
- •Методика выполнения
- •Содержание отчета
- •Контрольные вопросы
- •Литература
Модульная структура программ
Единицей компиляции в языке С++ является файл или модуль. Исходный файл не обязательно должен содержать выполняемые операторы. Традиционно в программах на языке С++ используются два типа файлов: файлы реализации, имеющие расширение .сpp, и заголовочные файлы (файлы интерфейса), имеющие расширение .h. В заголовочных файлах обычно располагаются именованные константы, макроопределения и объявления, а в файлах реализации — определения переменных и функций. Заголовочные файлы подключаются посредством директивы препроцессора #include.
Обычный способ доступа к внешним определениям в файле состоит в создании отдельного файла заголовка, содержащего внешние объявления и поддерживающего необходимые для корректного использования определения типов. Объявления заголовочного файла включаются в любой файл, использующий внешние функции и объекты.
Разделение большой программы на модули (файлы) может облегчить процесс создания, понимания и сопровождения программ. При этом связанные функции и структуры могут группироваться для облегчения их чтения и понимания, а локальные модификации могут иметь ограниченный эффект. Кроме того, код, разделенный на файлы, легче перерабатывать для повторного использования в другой программе. Это обычный способ повторного использования кода, например, в библиотеках.
После того как проведены функциональная и модульная композиции, т. е. определена структура программы, можно переходить к следующему этапу — написанию кода.
Пример модульной структуры программы.
Глобальные переменные и функции
Любые переменные, описанные в файле (модуле) вне какой-либо функции и не имеющие спецификатора класса памяти (auto, register, extern или static), по умолчанию относятся к глобальному классу памяти и называются глобальными или внешними. Для глобальных переменных память отводится только один раз и сохраняется за ними до окончания выполнения программы. Если не указано никакое инициализирующее значение, то таким переменным по умолчанию присваивается нулевое значение. Это положение относится и к структурным типам переменных.
Область видимости таких переменных простирается от точки описания до конца файла. Если внутри блока определена автоматическая переменная, имя которой совпадает с именем глобальной переменной, то внутри блока глобальная переменная становится невидимой.
Доступ к глобальным переменным возможен и из других модулей (файлов); для этого следует задать спецификатор памяти extern. Если описание extern применяется к переменной, расположенной внутри функции, то его действие распространяется только на данную функцию, если же оно расположено вне какой-либо функции, то его действие распространяется до конца модуля.
При использовании спецификатора класса памяти extern переменная только объявляется и память под нее не выделяется. Следует иметь в виду, что переменная должна быть определена в каком-нибудь одном модуле — в нескольких модулях переменную с одним и тем же именем определять нельзя.
Все функции по умолчанию считаются внешними или глобальными. К любой функции из любого модуля возможно обращение, если для нее не указан спецификатор static. Другими словами, функция определяется один раз, но может быть объявлена много раз, с помощью спецификатора extern.
Пример оформления модуля
Каждый модуль должен предваряться заголовком, который, как минимум, содержит:
название модуля;
краткое описание его назначения;
краткое описание входных и выходных параметров с указанием единиц измерения;
список используемых (вызываемых) модулей;
краткое описание алгоритма (метода) и/или ограничений;
ФИО автора программы;
идентифицирующую информацию (номер версии и/или дату послед ней корректировки).
Стиль оформления текстов модулей определяет использование отступов, пропусков строк и комментариев, облегчающих понимание программы. Как правило, пропуски строк и комментарии используют для визуального разделения частей модуля, что позволяет прояснить структуру программы: Обычно дополнительный отступ обозначает вложение операторов языка.
При использовании комментариев переводить с английского языка каждый оператор программы не нужно: любой программист, знающий язык программирования, на котором написана программа, без труда прочитает тот или иной оператор. Комментировать следует цели выполнения тех или иных действия, а также группы операторов, связанные общим действием, т. е. комментарии должны содержать некоторую дополнительную (неочевидную) информацию.
Функции для работы с бинарным файлом
Чтение неформатированных данных из потока:
size_t fread( void *buffer, size_t size, size_t count, FILE *stream );
Параметры
Buffer – место для размещения данных
Size – размер единицы данных в байтах
Count – макс. кол-во единиц, которые должны быть прочитаны
Stream – указатель на структуру FILE.
Возвращает количество действительно прочитанных данных.
Запись неформатированных данных в файл:
size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Параметры:
Buffer – указатель на место размещения записываемых данных
Size – размер единицы данных в байтах
Count – макс. кол-во единиц, которые должны быть записаны
Stream – указатель на структуру FILE.
Возвращает количество фактически записанных данных
Пример
/* FREAD.C: This program opens a file named FREAD.OUT and
* writes 25 characters to the file. It then tries to open
* FREAD.OUT and read in 25 characters. If the attempt succeeds,
* the program displays the number of actual items read.
*/
#include <stdio.h>
void main( void )
{
FILE *stream;
char list[30];
int i, numread, numwritten;
/* Open file in text mode: */
if( (stream = fopen( "fread.out", "w+t" )) != NULL )
{
for ( i = 0; i < 25; i++ )
list[i] = (char)('z' - i);
/* Write 25 characters to stream */
numwritten = fwrite( list, sizeof( char ), 25, stream );
printf( "Wrote %d items\n", numwritten );
fclose( stream );
}
else
printf( "Problem opening the file\n" );
if( (stream = fopen( "fread.out", "r+t" )) != NULL )
{
/* Attempt to read in 25 characters */
numread = fread( list, sizeof( char ), 25, stream );
printf( "Number of items read = %d\n", numread );
printf( "Contents of buffer = %.25s\n", list );
fclose( stream );
}
else
printf( "File could not be opened\n" );
}
Результат
Wrote 25 items
Number of items read = 25
Contents of buffer = zyxwvutsrqponmlkjihgfedcb