Структурное и модульное программирование

При решении задач на компьютере алгоритм или программа должны включать два раздела:

· Описание действий, которые выполняются

· Описание данных, с которыми оперируют действия

Действие описывается с помощью операторов, а данные с помощью определений или объявлений.

В 1965 году был предложен профессором Нидерландского университета Дейкстром стиль программирования, называемый "Программирование без оператора безусловного перехода goto", вначале воспринятый отрицательно.

Однако позднее (через десятилетье) этот стиль, названный структурным программированием, получил широкое практическое применение.

Известно, что у структурного программирования много достоинств, обусловленных его свойствами.

Основными управляющими конструкциями структурного программирования являются:

· следование; если в записи программы представлены подряд несколько действий (операторов), то они будут выполняться последовательно друг за другом в том же порядке.

· если-то-иначе; условная конструкция, определяющая разветвление в порядке выполнения действий.

· циклы; в структурном программировании предусмотрены циклы трех видов

o цикл с предусловием: пока-делай while, пока истинно условие, выполняется указанное действие.

o цикл с постусловием: повторяй-пока do while, в отличие от цикла с предусловием, тело цикла должно повторяться не менее одного раза.

o цикл с заранее заданным числом повторений: for.

Перечисленные три конструкции называют базовыми конструкциями структурного программирования.

Этих конструкций достаточно для управления порядком действий в любом алгоритме.

Применение этих конструкций удобно, так как все они имеют один вход и один выход.


Ветвление (Условная конструкция):

Описание алгоритма: если-"условие" то "ветвь-то", иначе "ветвь-иначе"

//C++ реализация

if (A>B)
{
D=E; //ветвь-то
//...
}
else
{
C = F; //ветвь-иначе
//...
}

Описание алгоритма: Если условие, то "ветвь-то", все

//C++ реализация
if (A>B)
{
D=E; //ветвь-то
//...
}

1) с предусловием Пр. SUMMA = ((сумма от i=1 до 20) I)

//C++ реализация

int S, I;
I = 1; S = 0;
while (I <= 20)
{
S =+= I;
I += 1;
}

2) цикл с постусловием
...

Совместно со структурным программированием используется модульное программирование.

Модульное программирование предполагает последовательную декомпозицию или разбиение исходной задачи на функционально законченные подзадачи, которые оформляются в виде отдельных модулей, называемых в языках C/C++ функциями.

Для оценки рационального размера функции и количества ее параметров можно использовать правило "7 плюс-минус 2".

Смысл правила в том, что количество элементов (параметров функции или операторов языка программирования), которые человек воспринимает хорошо не должно превышать семи.

Следовательно, при указанной декомпозиции размер функции не превосходит обычно 25-81 строк текста, а количество параметров должно быть не более 5-9.
Понятно, что 25-81 строк текста для одной функции соответствуют в ее блоке не более 5-9 элементарным конструкциям, каждая из которых должна занимать не более 5-9 строк.

Особенность языка в том, что модули (функции Си) можно хранить в отдельных файлах, можно параллельно отлаживать, что сокращает сроки разработки программ и позволяет привлекать к работе над проектом коллективы программистов.

Модульное программирование называют также нисходящим программированием, которое для сложных программных проектов может иметь иерархический характер, то есть полученные в начале модули программ при необходимости также подвергаются декомпозиции для достижения приведенных показателей эффективного программирования.

Описание языка программирования C/C++

Язык программирования (является алгоритмическим) как средство записи алгоритмов представляет собой формализованные средства для общения человека и ПК (интерфейс).

К языку программирования предъявляются следующие требования:

· должен быть простым, чтобы быть доступным для широкого круга специалистов и неспециалистов

· должен быть однозначным при толковании алгоритма, а не как естественный язык.

· должен предполагать простой в создании и функционировании транслятор с этого языка на язык ПК.

Этим требованиям в достаточной степени удовлетворяют данные языки.

Данные языки как и другие языки программирования полностью определяются заданием их алфавита (словаря исходных символов), точным описанием их синтаксиса (грамматики) и семантики (смысла).

Алфавит языка - это набор основных символов (литер), используемых для записи алгоритма.
Некоторые литеры алфавита являются составными, изображаются двумя или тремя символами, но рассматриваются как неделимые.

Существуют разные способы описания синтаксиса языка, предложенные Бэкусом и Виртом в соответствии с рисунком.

>> теория формальной грамматики, эпсилон-свободные грамматики

Из допустимых символов языка можно писать программу в соответствии с синтаксисом языка.


Удобными способами описания синтаксиса языка являются следующие:

· использование мета-лингвистических формул, которые предложены Д. Бэкусом, автором самого первого языка АЛГОЛ-60

· Использование синтаксических диаграмм, предложенных Н. Виртом, автором языка Паскаль.

На рисунке одни и те же понятия определены через металингвистические формулы и синтаксические диаграммы.

Металингвистическая формула определяет понятия путем перечисления всех его значений, используя обозначения:

· "::=" - это есть по определению

· "<определяемые понятия>" - пишется слева от предыдущего символа "это есть по определению"

· "|" - обозначает элемент "ИЛИ"

· "( )" - обозначают "И"

· "{ }" - обозначают "неограниченное повторение заключенной в них конструкции

· "[ ]" - обозначают необязательность конструкции, заключенной в эти (квадратные) скобки.

Особенности языка СИ.

В языке СИ два имени, имеющие совпадающие первые восемь символов воспринимаются одинаково.
В интегрированных средах программирования на языке СИ++ различная длина идентификаторов может задаваться программистом. Прописные и строчные буквы идентификаторов различимы.

Синтаксические диаграммы поясняют правый столбец рисунка. То есть эта схема, состоящая из линий со стрелками, прямоугольников, овалов и других геометрических фигур. В прямоугольник заключается объект, определенный (или описанный) в другом месте. В овалы или кружки - литеры или составные символы языка.
Сравнивая определения понятий обоими способами, легче понять смысл и особенности синтаксических диаграмм.

Как следует из сравнения, синтаксические диаграммы проще и нагляднее.
Поэтому именно их обычно рекомендуют использовать.

Семантика определяет смысл предложений (операторов), записанных на языке как каждого в отдельности, так и их совокупности.

Обычно смысл предложений представляется пояснениями на обычном языке или эквивалентными совокупностями других предложений языков С/С++.


Структура и конструкция программы на языках С/С++

Часть лекции пропущена

Сначала нужно выбрать прямую, а после уже выполнять вычисления.

...
следовательно, алгоритм должен последовательным перебором определить уравнение прямой и использовать его для дальнейших вычислений Q по заданному значению V.

БЛОК_СХЕМА (фото 31.01.16)
Алгоритм: начало->V->V>2->Да
V->2->Нет->

Циклический алгоритм.

Циклический алгоритм, описывающий циклический вычислительный процесс, используется, например, для многократных вычислений по одному и тому же аналитическому выражению (формуле), но с различными знамениями аргумента.

Например, для получения таблицы значений функции по заданным в интервале значениям аргумента.

Значения аргумента обычно задают его максимальным и минимальным значением, но с некоторым шагом.

Циклический алгоритм состоит из тела цикла - расчетной формулы (одно из уравнений), счетчика цикла, изменяемого на величину шага переменной, связанный с аргументом расчетной формулы, а также процедурой проверки окончания цикла.

Часто в одном алгоритме используются несколько циклов (последовательных или вложенных). При этом циклы не должны пересекаться. Они могут следовать друг за другом или включаться один в другой.

Задача цикла в нашем случае состоит в расчете значений функции по любому значению аргумента, заданному на интервале от минимального до максимального значения.

Расчет многократно повторяется для разных значений аргумента V, поэтому после каждого расчета значения Q значение V увеличивается на величину шага, равного единице.

Вычисления заканчиваются при достижении V значения 12.
Иначе выполняется очередной цикл расчетов.

Алгоритм является оптимальным для нашей задачи и реализуется в такой же последовательности на языках программирования.

Циклический процесс получения таблицы значений Q (цены) как функции от V (объема продукции) можно представить в виде блок-схемы.


 

Кусочно-линейная аппроксимация.

Необходимо оценить в итоге точность расчетов.

Подставленные значения по графику не всегда совпадут с табличными.
Будет погрешность, которую необходимы высчитать.

delta = (|Qт-Qр|)/(Qmax-Qmin).

Будет задана локальная и глобальная погрешность.

Глобальная - суммарная - по всем точкам.

Курсовая работа. Кусочно-линейная аппроксимация. Но это не самая удачная. Точки перегиба не соответствуют поведению реальных объектов. Необходимо использовать более высокие степени (полиномы 2-й, 3-й степени - кубического сплайна).

Погрешности заданы. Необходимо так провести прямые, чтобы их количество было минимально, а погрешности не превышали заданные. Алгоритм должен автоматически выбирать количество прямых.

Сначала проводим через две точки - с огромной погрешностью.

Чем больше точек, тем проще.

Все алгоритмы должны быть реализованы в виде программ.

И надо исследовать зависимость погрешности от количества прямых.

Исследование, определение максимума-минимума, определение автоматизации для определения количества отрезков, использование полинома.

Любой шаг алгоритма обосновывать.

 


Таблица управляющих символов

--[теория формальных языков]--

\n - переход к новой строке
\r - возврат каретки
\t - горизонтальная табуляция
\v - вертикальная табуляция
\b - возврат на одну позицию
\f - переход к новой странице
\\ - обратная косая черта
\>> - кавычки
\' - апостроф

Строковая константа представляет собой последовательность символов (0 и более), заключенную в кавычки.

Для записи и запоминания строковых констант используется 1 байт на каждый символ строки и в нулевой байт автоматически добавляется признак конца строки.

То есть, нулевой байт является фактически ограничителем строки.
Для составления строковых констант можно использовать любые печатные символы или управляющие коды, которые представлены выше.

Пример размещения строки в оперативной памяти компьютера можно представить в виде следующего рисунка.

\n и \0 занимают по байту, как и буквы с точкой в предложении "Строка. \n"

"Эта строка содержит симовол табуляции \t". "В строке указан символ, вызывающий звуковой сигнал: \07". "Последняя строка пустая, в ней нет символов, но для ее хранения используется 1 байт - завершающий нулевой байт."

Структура СИ-Программы

СИ-программа - это совокупность одного или нескольких модулей.

Модулем является самостоятельно транслируемый файл, такой файл обычно содержит одну или несколько функций.

Функция состоит из операторов языка СИ.

Таким образом структуру СИ-программы можно представить в виде рисунка.

СИ-программа

· модуль (файл с определениями и операторами), внешнее определение данных

o функция, внутренние определения данных; операторы

o ...

o функция, внутренние определения данных; операторы

· ...

· модуль

>> структура регулярная, чем упрощается построение и понимание готовых программ.

Термин "функция" в языках СИ\СИ++ включает понятия подпрограмма, процедура, функция, используемая в других языках программирования.

Программа на языках СИ\СИ++ может содержать одну функцию (главную функцию main) или любое число функций в зависимости от задачи.

Выполнение программы начинается с главной функции.

>> СИ-программа с одним модулем (файлом) и двумя функциями чтения с клавиатуры одной строки символов заканчивается символом "\n". Каждый символ печатается с его десятичным, восьмеричным и шестнадцатеричным кодами.

# include <stdio.h>//препроцессорная директива, используется для функций ввода-вывода в результате выполнения директивы на место строки помещается содержимое файла stdio.h

//Прототип функции: используется компилятором для проверки правильности записи заголовка в определении функции.
void convert (int);
//выполнение программы наинается с ее главной функции.
int main (void)возвращает ноль при успехе.
int ch; //прочитанный символ, на экран выводится две нижние строки, являющиеся аргументами функции экранного вывода
printf (Программа изображает символы и их коды);
printf (Наберите строку символов и нажмите клавишу enter);
ch = getchar ();подождать ввода символа
{
while (ch!= '\n'); // вызов функции печатати символа и его десятичного, восьмеричного и шестнадатиричного кодов.
Комплилятор контролирует правильность вызова функции, используя ее прототип
convert (ch);
ch = getchar();ввод следующего символа
}
printf ("Обработка закончена");
return 0;

void convert (int ch) //изображаем символ
printf ("Символ, 10-чный, 8-чный, 16-ричный") //непечатные сиволы имеют коды от 0 до 31 и десятичный код символа ' ' равен 32
if (ch<' ') printf (управляющий непечатный символ)//один и тот же символ печатается вначале в символьном формате %c, затем в форматах %d, %o, %x чисел.
printf("символы с форматом")
return;

Этот пример показывает структуру программы и оформление программы с использованием комментариев. Далее запишем необходимые пояснения.

 

#include <> препроцессорная команда, включает текст программы с библиотечными функциями

Препроцессор обрабатывает текст СИ-программы до начала компиляции.

Препроцессор - специальный компонент транслятора после обработки текста препроцессором транслятор препроцессорные команды не обрабатывает.

В каждой СИ-программе имеется только одна главная функция, с которой начинается исполнение программы.

Другие функции могут быть вызваны из main или какой-нибудь другой функции в процессе выполнения программы.

Эти функции могут находиться в том же модуле (файле) что и функция main или в других модулях.

Функция может иметь ноль или более аргументов.

Аргументы являются переменными, которые используются для передачи данных между функциями.

Однако главная функция main не имеет аргументов, а функция convert имеет один аргумент-переменную ch.

Каждая функция после своего заголовка содержит блок начинающийся с открывающейся фигурной скобки и заканчивающийся закрывающейся.

Кроме блока фигурными скобками в языке обозначают начало и конец составного оператора.

После закрывающейся фигурной скобки, обозначающей конец составного оператора или блока точка с запятой не ставится.

Выделенный таким образом фигурными скобками блок содержит определение данных, за которыми следуют операторы функции.

Определения данных создают переменные, которые будут использованы в функции.
Операторы задают действия, которые должны быть выполнены над переменными.

Все элементы данных должны быть определены перед их использованием.
Определение данных всегда завершается точкой с запятой. Кроме того, операторы также завершаются точкой с запятой.

Любые данные в алгоритмических языках характеризуются своими типами (специальными конструкциями языка, которые рассматриваются компилятором как образцы для создания других элементов программ.


Переменные, константы и функции.

Тип определяет формат внутреннего представления объекта данного типа.
То есть число смежных байтов памяти.

Из этого вытекает ограничение на множество допустимых значений и множества допустимых операций.

Типы данных разделяются на основные (базовые, фундаментальные) и производные (составные, структурированные)

Фундаментальные типы предопределены в языке и предназначены для описания простых скалярных переменных.

В языке СИ определены следующие пять основных типов данных для описания числовых-символьных и логических переменных, которым соответствуют ключевые слова:

· для описания символьных переменных char

· для представления целочисленных переменных int

· для представления чисел с плавающей точкой float and dooble одинарной и двойной точности соответственно

· для описания переменной не имеющей значений void - для определения обобщенного указателя или функции не имеющей значения.

· bood

· wjchar_t

На основе стандартных типов, определенных в языке создаются описания производных типов, которые предназначены для описания множества однотипных величин семантически (по смыслу) связанных между собой.

К ним относятся: массивы, структуры, функции, классы, указатели, ссылки.
Указатели используются для хранения адресов областей памяти объектов программы определенных типов.