Аннотация: Теоретические предпосылки структурного программирования. Локальность действий и условий, требования к программным структурам. Призраки и подпорки. Сеть данных и совместность. Циклический и рекурсивный варианты.
— Учитель,- проговорил Сунь У-кун.- Я человек простой и вашего городского языка не понимаю. Что значат подпорки к стене?
— Когда люди начинают строить дом и хотят сделать его прочным и крепким, то между стенами они ставят подпорки. Но проходит время, и здание рушится, а это значит, что подпорки сгнили.
У Чэн-энь. «Путешествие на Запад», глава 2
Общая характеристика структурного программирования
На самом деле изложение структурного стиля не может уместиться в рамки одной лекции. Но данный стиль программирования (вернее, его вариант, основанный на циклах и массивах, слегка пополненный рекурсивными процедурами) описывается и навязывается как единственно возможный во всех ныне предлагаемых учебных пособиях по программированию на традиционных языках. В связи с этим мы имеем право предположить, что обучающийся знаком с ним (более того, знаком только с ним, и мы надеемся, что он еще не потерял способность воспринимать другие стили). И хотя Вы считаете, что с этим вариантом структурного стиля уже освоились, особенности, опускаемые в традиционных изложениях, могут полностью изменить Ваш взгляд на данный стиль.
#Архитектура приложения и кода
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Cancel Create
mipt_oop / week_1 / structured_programming.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cannot retrieve contributors at this time
170 lines (118 sloc) 9.42 KB
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents Copy raw contents
Copy raw contents
Понятие о структурном программировании
Структурное программирование — парадигма разработки программ с помощью представления их в виде иерархической структуры блоков. Сюда входит три пункта:
- Любая программа состоит из трех типов конструкций: последовательное исполнение, ветвление, цикл.
- Логически целостные фрагменты программы оформляются в виде подпрограмм. В тексте основной программы вставляется инструкция вызова подпрограммы. После окончания подпрограммы исполнение продолжается с инструкции, следующей за командой вызова подпрограммы.
- Разработка программы ведется поэтапно методом «сверху вниз».
Первый пункт скорее важен не тем, что в нем есть, а тем, чего в нем нет: в нем нет оператора безусловного перехода goto. Именно это отличает структурное программирование от процедурного. Благодаря пункту два в языках высокого уровня появились новые синтаксические конструкции: функции и процедуры.
Как учиться ПРАВИЛЬНО, ЭФФЕКТИВНО и БЫСТРО
Пункт три самый важный и является сутью парадигмы структурного программирования.
Проектирование «сверху вниз»
Как было сказано выше, сама суть структурного программирования лежит в подходе к проектированию программы. Для понимания этого приведем процесс решения конкретной задачи во времени.
Условие. Пусть в некоторой стране зарплата сотрудника дорожной патрульной службы состоит из штрафов, накладываемых на водителей за превышение скорости в 60 км/ч, штраф напрямую зависит от номера автомобиля, а рабочий день заканчивается с приездом начальника, при этом начальника штрафовать нельзя. Требуется посчитать зарплату сотрудника за день.
Входные данные подаются построчно, в каждой строке — скорость (целое число) и номер автомобиля (6 символов — 1 буква, 3 цифры и еще 2 буквы).
Штраф для автомобильных номеров зависит от количества совпадающих цифр: три совпадают — 1000 у.е., две любые цифры совпадают — 500 у.е., все цифры разные — 100 у.е.
Примечание: все комментарии в примерах будут на русском языке, что нарушает PEP 8. Это сделано для простоты восприятия примера.
Шаг №1. Предположим, что все уже написано для нас:
def main(): salary = calculate_salary() print(salary) if __name__ == «__main__»: main()
Шаг №2. Но это не будет работать, так как функция calculate_salary отсутствует. Исправим это:
def main(): salary = calculate_salary() print(salary) def calculate_salary(): «»» Функция считает зарплату сотрудника ДПС, считывая исходные данные с клавиатуры. :returns: Зарплата сотрудника .. todo:: Реализовать функцию «»» pass if __name__ == «__main__»: main()
Теперь код будет успешно выполняться, но сейчас функция ничего не делает. В документации к функции явно указано, что ее надо реализовать. Такая функция называется заглушкой и широко используется в практике программирования.
Шаг №3. Займемся реализацией функции. Предположим, что у нас написаны все необходимые функции, и напишем calculate_salary так:
def calculate_salary(): «»» Функция считает зарплату сотрудника ДПС, считывая исходные данные с клавиатуры. :returns: Зарплата сотрудника «»» sum_of_fines = 0 speed_of_car, number_of_car = read_data() while not detect_chief(number_of_car): if speed_of_car > 60: sum_of_fines += calculate_fine(number_of_car) speed_of_car, number_of_car = read_data() return sum_of_fines
Заметим, что в этом решении делегировано в отдельные функции всё, что только можно было делегировать. Разве что проверка превышения скорости осталась без собственной функции, но она уж и так слишком тривиальна.
Заметим, что в групповой разработке ПО старший программист на этом завершил бы свою работу. Ему осталось только сформулировать для каждой из функций её заглушку и документирующий комментарий, раздать работу по написанию мелких функций младшим программистам и идти пить чай.
Шаг №4. На данном этапе пропустим написание функций-заглушек и сразу приведём окончательное решение.
def main(): salary = calculate_salary() print(salary) def calculate_salary(): «»» Считает зарплату сотрудника ДПС, считывая исходные данные с клавиатуры. :returns: зарплата сотрудника «»» sum_of_fines = 0 speed_of_car, number_of_car = read_data() while not detect_chief(number_of_car): if speed_of_car > 60: sum_of_fines += calculate_fine(number_of_car) speed_of_car, number_of_car = read_data() return sum_of_fines def read_data(): «»» Считывает следущую строку данных.
:returns: tuple(int, str) — скорость, номер машины «»» data = input().split() return int(data[0]), data[1] def detect_chief(number_of_car): «»» Проверяет, принадлежит ли данный номер начальнику.
:param number_of_car: номер автомобиля :returns: True, если номер принадлежит начальнику, иначе False «»» return number_of_car == «A999AA» def calculate_fine(number_of_car): «»» Считает штраф для автомобиля с конкретным номером. :param number_of_car: номер автомобиля :returns: Целое число, размер штрафа «»» if is_super_number(number_of_car): return 1000 elif is_good_number(number_of_car): return 500 else: return 100 def is_super_number(number_of_car): «»» Проверяет, является ли номер «крутым» (совпадение трёх цифр) :param number_of_car: номер автомобиля :returns: True, если номер «крутой», иначе False «»» return number_of_car[1] == number_of_car[2] == number_of_car[3] def is_good_number(number_of_car): «»» Проверяет, является ли номер «хорошим» (совпадение двух цифр) :param number_of_car: номер автомобиля :returns: True, если номер «хороший», иначе False «»» return number_of_car[1] == number_of_car[2] or number_of_car[1] == number_of_car[3] or number_of_car[2] == number_of_car[3] if __name__ == «__main__»: main()
Обычно перед использованием функции сначала реализуют ее. Мы же сейчас делали все наоборот. Сначала использовали функцию, потом писали для нее заглушку и только вконце дописывали реализацию. В этом и заключается процесс проектирования «сверху вниз».
Источник: github.com
Как правильно структурировать многофайловую программу на с++?
Пишу небольшую имитация компьютера на с++, возник такой вопрос. Есть класс mySimpleComputer в файле mySimpleComputer.cpp, для него есть заголовочный файл с тем же названием, в котором прописаны макросы. Как подключить эти файлы к main правильно, что бы использовать этот класс. Нужно ли подключать cpp файл, или класс нужно описывать в hpp файле, или как то ещё?
Отслеживать
задан 13 фев 2022 в 6:08
103 7 7 бронзовых знаков
Обычно cpp файлы не подключают. Класс обычно помещают в hpp файл, а его реализацию помещают в cpp файл. Ну и потом подключают этот hpp файл к файлу с main , но компилировать нужно оба cpp файла.
– user361068
13 фев 2022 в 7:27
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
#include #include «reporter.h» int main()
#ifndef REPORTER_H_ #define REPORTER_H_ #include class Reporter < public: std::string report(); >; #endif // REPORTER_H_
#include «reporter.h» std::string Reporter::report()
$ g++ -I. main.cpp reporter.cpp $ ./a.out This is report.
Отслеживать
ответ дан 13 фев 2022 в 8:17
Stanislav Volodarskiy Stanislav Volodarskiy
25.9k 3 3 золотых знака 15 15 серебряных знаков 47 47 бронзовых знаков
Спасибо большое, пример очень помог
13 фев 2022 в 8:41
13 фев 2022 в 14:37
Стандартной практикой в программах на C или C++ заключается в том, что мы храним все объявления классов, констант, макросов, глобальных переменных и прототипов функций в файлах заголовков ( *.h файлах) и включаем этот файл заголовка везде, где это необходимо.
Включение заголовочного файла директивой #include равносильно копированию содержимого заголовочного файла.
Уже как структурировать конкретно вашу программу по директориям и файлам зависит от вашей архитектуры от того как вы планируете спроектировать программу.
Отслеживать
ответ дан 13 фев 2022 в 7:50
2,792 1 1 золотой знак 7 7 серебряных знаков 24 24 бронзовых знака
- c++
- ооп
- классы
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Источник: ru.stackoverflow.com