Литмир - Электронная Библиотека
A
A

Задание

1. Скомпилируйте файл

calculator08buggy.cpp
.

2. Пройдитесь по всей программе и добавьте необходимые комментарии.

3. В ходе комментирования вы обнаружите ошибки (специально вставленные в код, чтобы вы их нашли). Исправьте их; в тексте книги их нет.

4. Тестирование: подготовьте набор тестовых вводных данных и используйте их для тестирования калькулятора. Насколько полон ваш список? Что вы ищете? Включите в список отрицательные числа, нуль, очень маленькие числа и “странный” ввод.

5. Проведите тестирование и исправьте все ошибки, которые пропустили при комментировании.

6. Добавьте предопределенное имя

k
со значением
1000
.

7. Предусмотрите возможность вычисления функции

sqrt()
, например
sqrt(2+6.7)
. Естественно, значение
sqrt(x)
— это квадратный корень из числа
x;
например
sqrt(9)
равно
3
.

8. Используйте стандартную функцию

sqrt()
, описанную в заголовочном файле
std_lib_facilities.h
. Не забудьте обновить комментарии и грамматику.

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

10. Предусмотрите возможность использовать функцию

pow(x,i)
, означающую “умножить
x
на себя
i
раз”; например
pow(2.5,3)
равно
2.5*2.5*2.5
. Аргумент
i
должен быть целым числом. Проверьте это с помощью оператора
%
.

11. Измените “ключевое слово объявления” с

let
на
#
.

12. Измените “ключевое слово выхода” с

q
на
exit
. Для этого понадобится строка для кодирования инструкции “выход”, как мы уже делали для инструкции “let” в разделе 7.8.2.

Контрольные вопросы

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

2. Почему выражение “

1+2; q
”, введенное в программу, не приводит к выходу из нее после обнаружения ошибки?

3. Зачем нам понадобилась символьная константа с именем

number
?

4. Мы разбили функцию

main()
на две разные функции. Что делает новая функция и зачем мы разделили функцию
main()
?

5. Зачем вообще разделять код на несколько функций? Сформулируйте принципы.

6. Зачем нужны комментарии и как они должны быть организованы?

7. Что делает оператор

narrow_cast
?

8. Как используются символические константы?

9. Почему важна организация кода?

10. Как мы реализовали оператор

%
(остаток) применительно к числам с плавающей точкой?

11. Что и как делает функция

is_declared()
?

12. Реализация “ключевого слова”

let
использует несколько символов. Как обеспечен ввод этой лексемы как единого целого в модифицированном коде?

13. Сформулируйте правило, определяющее, что является именем в калькуляторе и что нет?

14. Чем хороша идея о постепенной разработке программ?

15. Когда следует начинать тестирование?

16. Когда следует проводить повторное тестирование?

17. Как вы принимаете решение о том, какие функции следует сделать отдельными?

18. Как вы выбираете имена для переменных и функций? Обоснуйте свой выбор.

19. Зачем нужны комментарии?

20. Что следует писать в комментариях, а что нет?

21. Когда следует считать программу законченной?

Термины

Программирование. Принципы и практика использования C++ Исправленное издание - _062.png

Упражнения

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

2. Реализуйте оператор присваивания

=
, чтобы можно было изменять значение переменной после ее объявления с помощью инструкции
let
.

3. Реализуйте именованные константы, которые действительно не могут изменять свои значения. Подсказка: в класс

Variable
необходимо добавить функцию-член, различающую константы и переменные и проверяющую это при выполнении функции
set_value()
. Если хотите дать пользователю возможность объявлять собственные именованные константы (а не только
pi
и
e
), то необходимо добавить соответствующее обозначение, например
const pi = 3.14;
.

4. Функции

get_value()
,
set_value()
,
is_declared()
и
define_name()
оперируют переменной
var_table
. Определите класс
Symbol_table
с членом
var_table
типа
vector<Variable>
и функциями-членами
get()
,
set()
,
is_declared()
и
define()
. Перепишите программу так, чтобы использовать переменную типа
Symbol_table
.

5. Модифицируйте функцию

Token_stream::get()
так, чтобы, обнаружив символ перехода на следующую строку, она возвращала лексему
Token(print)
. Для этого требуется обеспечить поиск разделителей и обработку символа
'\n'
. Для этого можно использовать стандартную библиотечную функцию
isspace(ch)
, возвращающую значение
true
, если символ
ch
является разделителем.

6. Каждая программа должна содержать подсказки для пользователя. Пусть при нажатии клавиши

<Н>
калькулятор выводит на экран инструкции по эксплуатации.

7. Измените команды

q
и
h
на
quit
и
help
соответственно.

8. Грамматика в разделе 7.6.4 является неполной (мы уже предостерегали вас от чрезмерного увлечения комментариями); в ней не определена последовательность инструкций, например

4+4;
5–6;
, и не учтены усовершенствования, описанные в разделе 7.8. Исправьте грамматику. Кроме того, добавьте в первый и все остальные комментарии программы все, что считаете нужным.

105
{"b":"847443","o":1}