Programming Taskbook


E-mail:

Пароль:

Регистрация пользователя   Восстановление пароля

English

ЮФУ

Электронный задачник по программированию

©  М. Э. Абрамян (Южный федеральный университет), 1998–2023

 

Решения | C и C++ | Простое задание

PrevNext


Пример выполнения простого задания: Begin3

На данной странице приводится пошаговое описание процесса решения на языках C и C++ следующего простого задания из группы Begin.

Begin3°. Даны стороны прямоугольника a и b. Найти его площадь S = ab и периметр P = 2(a + b).

В качестве среды программирования используется среда Visual Studio Code, однако аналогичные результаты будут получены и при выполнении приведенных программ в других поддерживаемых задачником средах для разработки программ на языках C и C++.

Создание программы-заготовки и знакомство с заданием

Для создания проекта, содержащего заготовку для требуемого задания, следует воспользоваться программным модулем PT4Load. Для этого достаточно перейти в рабочий каталог задачника и с помощью ярлыка Load.lnk запустить программу PT4Load.exe (начиная с версии 4.22, для быстрого запуска любых модулей задачника можно использовать программу PT4Panel, ярлык которой располагается на рабочем столе и в любом рабочем каталоге). В результате на экране появится окно модуля PT4Load, в котором следует указать имя нужного задания. Отметим, что в заголовке этого окна указывается имя той программной среды, для которой будет создана заготовка. Например, для среды Visual Studio Code заголовок окна PT4Load будет содержать текст [Visual Studio Code (C)] или [Visual Studio Code (C++)]. Изменить текущую среду программирования можно с помощью контекстного меню модуля PT4Load.

Созданный проект-заготовка состоит из нескольких файлов, однако для решения задания нам потребуется только файл Begin3 с расширением .c в случае использования языка C и расширением .cpp для языка C++. Именно этот файл будет загружен в редактор среды Visual Studio Code. Приведем текст данного файла:

[Begin3.c]

#include "pt4.h"

void Solve()
{
    Task("Begin3");
}

[Begin3.cpp]

#include "pt4.h"
using namespace std;

void Solve()
{
    Task("Begin3");
}

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

Обратите внимание на то, что в данном файле отсутствует описание стартовой функции main, в которой производится вызов функции Solve. Поскольку при решении задачи стартовую функциу не требуется изменять, она перенесена в подключаемый заголовочный файл pt4.h.

Заголовочный файл pt4.h содержит также описания вспомогательных типов и функций, в частности, описания функций ввода-вывода, а также отладочного вывода). Реализация данных функций содержится в файле pt4.c (в случае языка C) и pt4.cpp (в случае языка C++). Поскольку содержимое этих файлов тоже не нужно редактиоровать, они не загружаются в редактор среды Visual Studio Code. Однако можно убедиться, что они находятся в том же рабочем каталоге, что и файл с именем Begin3.

Запустим программу, нажав клавишу [F5] (эту же клавишу можно использовать в редакторе среды Microsoft Visual Studio). Для запуска программы в среде Code::Blocks можно использовать клавишу [F9], а в среде Dev-C++ — клавишу [F11].

После компиляции и запуска программы мы сможем увидеть на экране окно задачника с формулировкой задания и примером исходных данных. Начиная с версии 4.11, окно задачника может отображаться в двух режимах: с динамической компоновкой, при которой каждый раздел «подстраивается» под свое содержимое, и с фиксированной компоновкой, при которой каждый раздел имеет фиксированные размеры. В предыдущих версиях задачника был доступен только режим с фиксированной компоновкой. Режим с динамической компоновкой особенно удобен для заданий с большими формулировками и большими наборами данных. Ниже приведены оба режима окна для данного задания при использовании языка C++; вначале указан режим с динамической компоновкой (для переключения режимов предназначена клавиша [F4]).




Запуск нашей программы был признан ознакомительным (и поэтому правильность решения не анализировалась), так как в ходе ее выполнения не было выполнено ни одной операции ввода-вывода.

Примечание. В версии 4.21 поддержка режима с фиксированной компоновкой была прекращена. Начиная с этой версии, команда Режим (F4), ранее применявшаяся для переключения между режимами с фиксированной и динамической компоновкой, обеспечивает отображение текста текущего задания в режиме html-документа. В дальнейшем в качестве иллюстраций будут использоваться только окна с динамической компоновкой.

Ввод исходных данных

Приступая к решению задачи, надо прежде всего организовать ввод в программу исходных данных. В нашем случае исходными данными являются вещественные числа a и b, определяющие стороны прямоугольника (в области исходных данных эти числа выделены желтым цветом и снабжены комментариями).

При вводе исходных данных важно правильно указывать их тип, в противном случае задачник зафиксирует ошибку. Продемонстрируем это на примере нашей программы, организовав считывание исходных данные в переменные целого типа, используя функцию GetN. Для этого закроем окно задачника нажав кнопку Выход, клавишу [Esc] или клавишу, которая использовалась для запуска программы ([F5] для cред Visual Studio Code и Microsoft Visual Studio, [F9] для среды Code::Blocks, [F11] для среды Dev-C++), и дополним текст функции Solve следующим образом (в дальнейшем заголовок функции Solve не будем указывать):

[C/C++]

Task("Begin3");
int a, b;
GetN(&a);
GetN(&b);

Обратите внимание на то, что в функциях ввода Get для языка C (и для языка C++, начиная с версии задачника 4.23) надо указывать адрес переменной, в которую будет записан очередной элемент исходных данных. Для получения адреса используется операция &.

Примечание. В версиях задачника, предшествующих версии 4.23, в функциях ввода Get для языка C++ в качестве параметров использовались не адреса, а сами переменные, передаваемые в виде ссылок. Поскольку в языке С механизм ссылок отсутствует, в задачнике версии 4.23 (первой версии, поддерживающей как язык C, так и язык C++) функции ввода Get реализованы одинаковым образом — с параметрами-указателями, в качестве которых надо задавать адреса переменных.

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

Поскольку мы попытались ввести исходные данные (т. е. продемонстрировали намерение выполнить задание), данный запуск программы уже не считается ознакомительным. Однако тип исходных данных был выбран нами неправильно, поэтому на информационной панели будет выведена следующая информация об ошибке (на фиолетовом фоне): «Неверно указан тип при вводе исходных данных. Для ввода 1-го элемента (вещественного типа) использована переменная целого типа»:


Следует обратить внимание на индикаторы, появившиеся в окне задачника (индикаторы были добавлены в окно задачника в версии 4.11). В окне с динамической компоновкой для индикаторов отводится специальная панель, которая располагается под информационной панелью; в качестве индикаторов используются цветные горизонтальные полосы, а также цветные квадратные маркеры.

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

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

Для правильного ввода исходных данных в нашем случае надо использовать функцию GetD, обеспечивающую ввод данных типа double. Исправим соответствующим образом содержимое функции Solve:

[C/C++]

Task("Begin3");
double a, b;
GetD(&a);
GetD(&b);

Теперь ввод данных выполнен правильно. Однако наша программа не выводит результатов. Начиная с версии 4.15, в данной ситуации выводится сообщение на светло-синем фоне: «Запуск с правильным вводом данных: все требуемые исходные данные введены, результаты не выведены». Светло-синяя индикация означает, что успешно пройден первый этап решения: ввод исходных данных. Заметим, что в предыдущих версиях задачника в аналогичной ситуации выводилось сообщение об ошибке на оранжевом фоне «Выведены не все результирующие данные. Количество выведенных данных: 0 (из 2)».

Вычисления и вывод полученных данных

Выполним необходимые вычисления и выведем результаты, используя функцию PutD:

[C/C++]

Task("Begin3");
double a, b;
GetD(&a);
GetD(&b);
double S = a * b, P = 2 * (a + b);
PutD(P);
PutD(S);

После запуска программы мы можем убедиться, что найденные значения выведены в разделе результирующих данных. Но из-за того, что вначале мы вывели значение периметра P, а затем — значение площади S, решение по-прежнему признано неверным, а сообщение об ошибке имеет вид «Ошибочное решение». Подобное сообщение означает, что все исходные данные были введены, все результирующие данные выведены, но значения полученных результатов не совпадают с контрольными:


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

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

Правильное решение и его тестирование

Исправим допущенную ошибку, поменяв местами два последних оператора в функции Solve:

[C/C++]

PutD(S);
PutD(P);

После запуска исправленной программы на экране появится окно прогресса тестирования:

Данное окно отображается на экране, если программа успешно обработала хотя бы один набор исходных данных. Полоса прогресса показывает, сколько тестов было успешно пройдено к текущему моменту, а текст над полосой дублирует эту информацию и позволяет определить количество тестов, которое должна успешно пройти программа, чтобы задание считалось выполненным. Тестирование программы завершается в двух случаях: когда будет успешно пройдено требуемое число тестов или когда при прохождении очередного теста будет выявлена ошибка. Если при очередном тестовом испытании произойдет «зависание» программы (например, из-за зацикливания алгоритма), то для завершения работы программы следует закрыть окно прогресса тестирования, нажав на кнопку с крестиком в его правом верхнем углу.

В нашем случае решение не содержит ошибок, поэтому после прохождения трех успешных тестов на экране появится окно задачника с сообщением «Задание выполнено!». Выполнение задания Begin3 завершено:


Возможность автоматического тестирования программы на нескольких наборах исходных данных была реализована в версии 4.13 задачника. В предыдущих версиях для тестирования на различных наборах данных программу требовалось запускать несколько раз; при этом на информационной панели выводилась информация о количестве успешно пройденных тестов. Возможность подобного «пошагового» тестирования сохранена и в версии 4.13; для этого надо дополнить имя задания в функции Task символом «!» (восклицательный знак).

С помощью модуля PT4Results можно просмотреть информацию о ходе выполнения задания (начиная с версии 4.11, этот модуль можно вызывать непосредственно из окна задачника; для этого достаточно нажать клавишу [F2] или щелкнуть мышью на метке с описанием этой клавиши, размещенной в правом верхнем углу окна задачника):

Begin3      c04/02 14:57 Ознакомительный запуск.
Begin3      c04/02 15:07 Неверно указан тип при вводе исходных данных.
Begin3      c04/02 15:09 Запуск с правильным вводом данных.
Begin3      c04/02 15:12 Ошибочное решение.
Begin3      c04/02 15:15 Задание выполнено!

Буква «c», указанная перед датой, означает, что задание выполнялось на языке C++ (для языка C используется заглавная буква: «C»).

Примечание 1. Для вывода полученных результатов не обязательно предварительно сохранять их в особых переменных. Приведем соответствующий вариант решения:

[C/C++]

Task("Begin3_ru");
double a, b;
GetD(&a);
GetD(&b);
PutD(a * b);
PutD(2 * (a + b));

Примечание 2. При решении задачи на языке C++ можно использовать дополнительные средства ввода-вывода, позволяющие оформить ввод и вывод более компактным образом. В частности, функций групп Get–Put можно использовать специальный поток ввода-вывода pt, определенный в файле pt4.cpp:

[C++]

Task("Begin3");
double a, b;
pt >> a >> b;
pt << a * b << 2 * (a + b);

Начиная с версии 4.15, поток ввода-вывода pt можно использовать совместно с итераторами ptin_iterator<T> и ptout_iterator<T> для организации ввода и вывода последовательностей.

Начиная с версии 4.22, для ввода исходных данных можно также использовать функции GetBool, GetInt, GetDouble, GetChar и GetString, возвращающие введенные значения. Применяя функцию GetDouble, мы можем получить решение задачи Begin3, состоящее всего из двух операторов:

[C++]

Task("Begin3");
double a = GetDouble(), b = GetDouble();
pt << a * b << 2 * (a + b);

Примечание 3. При работе в редакторе Visual Studio Code можно переключаться на другие задачи, если для них уже созданы заготовки (требуется лишь, чтобы заготовки соответствовали одному и тому же языку). Для этого достаточно перейти в режим проводника (нажав [Ctrl]+[Shift]+[E]) и выполнить двойной щелчок мышью на требуемом файле с расширением .c или .cpp. Можно также переключаться между уже загруженными в редактор файлами и запускать любой из них на выполнение. Кроме того, можно создавать новые заготовки с помощью программы PT4Load, не закрывая окно редактора Visual Studio Code; при этом новая заготовка будет добавлена к уже загруженным в редактор файлам.

Особой ситуацией, при которой требуется обязательный вызов программы PT4Load, является переключение между программами, связанными с заданиями из задачника, и обычными консольными программами (которые тоже можно создавать с помощью программы PT4Load, используя особые внешние группы заданий; примером такой группы является группа Hello). Кроме того, программу PT4Load надо вызывать, если требуется переключиться на другой язык программирования (например, с языка C на язык C++). Заметим, что при решении задач на нескольких языках удобнее предусмотреть для каждого языка особый рабочий каталог, настроив эти каталоги с помощью программы PT4Setup.

Другие поддерживаемые среды для языков C и C++ (например, Dev-C++ или, для C++, Microsoft Visual Studio) требуют создания более сложных проектов, поэтому для перехода к новому заданию необходимо всегда использовать программу PT4Load, причем перед вызовом PT4Load необходимо закрыть среду с ранее загруженным проектом для предыдущего задания.

Примечание 4 (для версии задачника 4.22). В редакторе VS Code при запуске программ с решениями задач из задачника Programming Taskbook на языках C и C++ используется упрощенный режим отладки, при котором отключены отладочные средства, отображаемые на стандартной панели отладки . В частности, нажатие на правую кнопку этой панели не приведет к завершению программы с решением (вместо этого будет завершена вспомогательная программа, используемая задачником для запуска учебных программ, однако окно задачника останется на экране). Поэтому желательно завершать выполнение учебной программы стандартным способом, закрывая ее окно кнопкой Выход или клавишами [Esc] или [F5]. Однако в ситуации, когда учебная программа «зависает» (например, в результате зацикливания), подобный способ оказывается невозможным.

В других средах разработки завершить зависшую программу можно с помощью специальной команды меню (например, в среде Microsoft Visual Studio для этого предназначена команда Debug | Stop Debugging, кнопка в виде красного квадратика и клавиатурная комбинация [Shift]+[F5], а в среде Dev-C++ — команда Execute | Stop Execution, кнопка в виде красного крестика и клавиша [F6]). Для редактора Visual Studio Code в случае зависания учебной программы на языках C и C++ следует использовать специальное средство, предоставляемое задачником: окно прогресса тестирования, которое отображается на экране сразу после запуска программы (в других средах это окно появляется только на последующих этапах тестирования, когда первый тест был пройден успешно — см. рисунок этого окна в начале пункта «Правильное решение и его тестирование»):

В случае зависания программы окно прогресса тестирования принимает следующий вид:

Для завершения зависшей программы достаточно закрыть окно прогресса тестирования с помощью кнопки закрытия или комбинации [Alt]+[F4]. При этом будет выведено диалоговое окно, в котором надо выбрать вариант Закрыть программу:

В версии 4.23 исполняемый файл с учебной программой запускается из среды VS Code без использования вспомогательной программы, поэтому для его завершения допустимо использовать правую кнопку стандартной панели отладки.


PrevNext

 

Рейтинг@Mail.ru

Разработка сайта:
М. Э. Абрамян, В. Н. Брагилевский

Последнее обновление:
01.01.2023