Повтор. Что делает эта программа?
Разбивка кода (псевдомодульность)
Вынос функций в отдельный модуль
Пример: простейшая база данных квитанций
481.83K
Категория: ПрограммированиеПрограммирование

Программирование на языке высокого уровня C++. Лекция 7. Модульное программирование

1.

Богатов Р.Н.
Программирование
на языке высокого уровня
C++ ► Лекция 7 ► Модульное прграммирование
Кафедра АСОИУ ОмГТУ, 2012

2. Повтор. Что делает эта программа?

...
FILE
*f;
...
int
count=0;
f for(;!feof(f);)
= fopen( "myfile.txt", "rt" );
for(int
i=0;;)
{
{ for(;!feof(f);)
chars[i]=='
c=' '; '; i++);
{ for(;
for(;
!feof(f)
&& c==' ';)
ifchar
(i>=N)
break;
c='
';
c = fgetc(f);
for(;
s[i]!='
'; &&
i++);
for(;
!feof(f)
c==' ';)
char s[500] = {c};
count++;
= fgetc(f);
intc j=1;
}
printf("%c",
c); && c!=' '; j++)
for(; !feof(f)
...
for(; s[j]
!feof(f)
c!=' ';)
= (c &&
= fgetc(f));
printf("%c", c = fgetc(f));
s[j-1]=0;
printf("\n");
printf( "%s\n", strrev(s) );
}}
...
fclose(f);
Мама и папа, я без вас очень скучаю. Особенно по вечерам. Но я вам не скажу, где я живу. А то вы меня
заберете, а Матроскин и Шарик пропадут...
Дорогие папа и мама, вы меня теперь просто не узнаете. Хвост у меня крючком, уши торчком, нос
холодный, и лохматость повысилась...
До свидания. Ваш сын - дядя Фёдор

3. Разбивка кода (псевдомодульность)

#include <stdio.h>
#include <conio.h>
#include <locale.h>
setlocale(LC_ALL, "Russian");
void main()
printf( "(c) Вася Пупкин, каф. АСОИУ ОмГТУ, 2012\n\n" );
{
#include "beginning.inl" // часто используемое начало
printf("Это моя первая программа.\n" );
for(int i=0; i<10; i++)
printf("%d ", i);
#include "ending.inl" // часто используемый конец
}
printf("\n\nНажмите любую клавишу для выхода...");
getch();

4. Вынос функций в отдельный модуль

#include <stdio.h>
#include
<stdio.h>
#include <conio.h>
файл main.cpp
#include
"my_lib.h"
1. Компилятор видит в проекте два cpp-файла. Они не ссылаются
#include
<locale.h>
друг на друга, поэтому компилируются раздельно в два obj-файла.
void void
main()
my_beginning()
{
{
2. В main.obj компилятор оставляет «недоделанным» вызов двух
setlocale(LC_ALL,
"Russian");
my_beginning();неизвестных
функций, про которые из my_lib.h компилятору известны
}
printf(
"(c) Вася Пупкин, каф. АСОИУ ОмГТУ, 2012\n\n" );
только их декларации (входные и выходные параметры).
}
printf("Это моя первая программа.\n" );
for(int i=0; i<10; i++)
3.i);
Редактор связей (aka «линковщик») получает задание собрать из
void printf("%d
my_ending()",
{
двух obj-файлов программу (исполнимый модуль, exe-файл). Он
#includeлюбую
<stdio.h>
printf("\n\nНажмите
клавишу для выхода...");
находит
в main.obj функцию main, которая должна быть
главной,
my_ending();
#include <conio.h>
getch();
файл
my_lib.cpp
видит
вызовы
функций,
которых
в
main.obj
нет,
находит
их
в
#include <locale.h>
}
void main()
{
}
my_lib.obj, подлинковывает (приклеивает) их и редактирует связи
void my_beginning()
(настраивает
адреса вызова этих функций). Программа готова.
{
my_beginning();setlocale(LC_ALL, "Russian");
Если есть
my_lib.obj
однажды
то его
можно );
printf(
"(c)(был
Вася
Пупкин,скомпилирован),
каф. АСОИУ ОмГТУ,
2012\n\n"
}
вместе с my_lib.h,
но без my_lib.cpp (например, чтобы скрыть
printf("Это распространять
моя
первая программа.\n"
);
void
for(int i=0;исходный
i<10; my_ending()
i++)
код, содержащий ноу-хау). В частности, эта программа будет
{ ", i);
printf("%d
благополучно
компилироваться и линковаться, если удалить my_lib.cpp, но
printf("\n\nНажмите
любую
клавишу
дляисключить
выхода...");
оставить my_lib.obj. Чтобы это
сделать,
нужно
из проекта ссылку на
getch();
my_ending();
my_lib.cpp
и добавить вместо него my_lib.obj.
}
void my_beginning();
файл my_lib.h
void my_ending();

5. Пример: простейшая база данных квитанций

#include
<stdio.h>
#include
<stdio.h>
...
#include
<stdlib.h>
#include
<conio.h>
void
db_add(void)
#include
<locale.h>
#include
<conio.h>
{...
void menu(void);
#include "main.h"
printf(
"\n\nПополнение базы 'my_database.dat'.\nВведите 0 для выхода.\n\n");
void
db_view(void)
#include
"my_database.h"
#include
"my_database.h"
{...fseek( f, 0, SEEK_END );
block
t;
int
main()
{ "\n\nСодержимое базы 'my_database.dat'\n\n"
struct block
printf(
FILE
*f;
void
db_sum(void)
while(
true
)
{
setlocale(
LC_ALL, "Russian"
);
{
"\tКвитанция:
Сумма:\n"
);
{
printf(
"Номер
квитанции:
"
);
db_open();
int number;
// номер квитанции
f, "\n\nПоиск
0, SEEK_SET
voidfseek(
db_open(void)
printf(
по);
базе 'my_database.dat'\n\n"
);
t.number=0;
menu();
double sum; // сумма
{ block
intscanf(
A t;
= 0,"%d",
B = 0;
&t.number
);
while(true)
{
};(через пробел): " );
while(
true
) {
printf(
"Введите
диапазон
printf(
"\rВыберите
режимномеров
работы:квитанций
" );
fflush(stdin);
if(
fread(
&t,
1, );
f ) !=1 ) break;
f =if(
fopen(
"ab+"
scanf(
"%d%d",
&A, sizeof(block),
&Bbreak;
);
char
c = "my_database.dat",
getche();
t.number==0
)
void);db_open(void);
"\t%6d%10.2lf\n", t.number, t.sum
if( printf(
f == NULL
fflush(stdin);
switch
(c) {)
void db_close(void);
}{
case '1': db_add(); menu(); break;
t.sum=0;
}
printf(
"Не
открыть
'my_database.dat'.
Нажмите клавишу...\n" );
case
'2': могу
db_view();
menu();
break; void db_add(void);
printf(
"\n\tКвитанция:
Сумма:\n"
);
printf(
"Сумма:
"
);
void
db_view(void);
... fseek(
case
db_sum();
getch();
f,
0, '3':
SEEK_SET
);); menu(); break;
scanf(
"%lg",
&t.sum
void db_sum(void);
exit(-1);
block
t;case '0': db_close(); return 0;
fflush(stdin);
}} sum = 0;
} if(
double
t.sum==0 ) break;
}}
while( true ) {
//-----------------------------------------------if( fread(
&t, sizeof(block), 1, f ) !=1 ) break;
fwrite(
void menu(void)
{ &t, sizeof(t), 1, f );
voidprintf("\n1.
db_close(void)
if( t.number>=A
&& добавлена.\n\n"
t.number<=B )
printf(
"Информация
);
Добавить
квитанцию.\n"
{ }
printf(
"\t%6d%10.2lf\n",
t.number,
t.sum ), sum += t.sum;
"2. Просмотр базы.\n"
fclose(f);
}
"3. Подсчёт суммы выборки.\n"
}
Выйти.\n\n");
}
printf( "0.
"\nСумма
по диапазону квитанций: %lg руб.\n\n", sum );
...
}}
...

6.

Домашнее задание
Написать модуль для работы
с комплексными числами, в
котором реализовать функции
cmplx_add, cmplx_sub,
cmplx_mul и cmplx_div
(сложения, вычитания, умножения
и деления), а также
cmplx_make (формирования
комплексного числа из
вещественных действительной и
мнимой частей), cmplx_conj
(получения сопряжённого числа)
и cmplx_print для вывода на
экран.
// наброски кода
struct CMPLX
{
double Re, Im;
};
CMPLX cmplx_make(double a, double b)
{
CMPLX c = { a, b };
return c;
}
CMPLX cmplx_add(CMPLX a, CMPLX b)
{
return cmplx_make(a.Re + b.Re, a.Im + b.Im);
}
void main()
{
CMPLX a = { -1, 3.4 };
CMPLX b = { 2.5, -10 };
cmplx_print( cmplx_add(a, b) );
}
English     Русский Правила