Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТП_ЛабРаботы.doc
Скачиваний:
13
Добавлен:
28.09.2019
Размер:
716.8 Кб
Скачать

Модульная структура программ

Единицей компиляции в языке С++ является файл или модуль. Исходный файл не обязательно должен содержать выполняемые операторы. Традиционно в программах на языке С++ используются два типа файлов: фай­лы реализации, имеющие расширение .с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