Прошу оценить код 3
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Учел все замечания в прошлом посте http://code-live.ru/forum/cpp/310/, конкретно:
(Черепу)
switch-а вslct_month()ушел и отправил его в knockdown вместе с расСчетом :)))В общем вот код, как всегда буду рад любому комментарию (за них всегда СПАСИБО):
По логике программы в общем неплохо. Только тебя не смущает, что код функций
Gas(),Light(),Water()совпадает с точностью до констант? В своём варианте твоей программы я не зря сделал функциюcalc_cost()...Я смотрю, ты про структуры уже прочитал. Скоро до классов доберёшься )) Только ты применяешь структуры не всегда к месту.
В структуре
dataсобраны вместе логически несвязанные значения. Зачем тогда структура?Смотрим на функции, где используется эта структура:
int AccountMenu(data input)— используется только полеmonth.double Gas(data input, const string type[]),double Light(data input, const string type[]),double Water(data input, const string type[])— используется только для передачи вInputReadout().int InputReadout(data input, const string type[])— реально используется только полеmonth. Вместо остальных полей можно (нужно!) использовать локальные переменные).double TotalSum(pabServ total, data input)— используется только полеmonth.main()— используются поляmonthиchoice. Ноchoiceиспользуется в качестве локальной переменной (это значение вообще больше ни где не используется).Итого, из всех полей структуры
dataдействительно необходимо только полеmonth.Т.е. везде, где в сигнатурах функций написано
data <имя переменной>, можно совершенно спокойно написатьint <имя переменной>, и использовать эту переменную для передачи номера месяца.Не понравилась эквилибристика с адресами для передачи строки в ф-цию
InputReadout(). Во-первых, нет необходимости передавать глобальный массив констант в качестве параметра в ф-цииGas()и т.п. Он и так там доступен. Во-вторых, в ф-циюInputReadout()достаточно передать константную ссылку на строку. Т.е. прототип функции может выглядеть так:или ещё проще:
поскольку массив
type_calcвInputReadout()тоже доступен. А с позиций перфекционизма можно написать и так:Естественно, надо внести соответствующие изменения и в ф-ции
Gas()и т.п. для корректного вызоваInputReadout().Ещё один эквилибр здесь:
Что здесь происходит? При вызове ф-ции
TotalSum()создаётся копия переменнойtotal(структура полностью копируется), затем в копии изменяем полеsum, затем возвращаем значение только этого поля, что бы присвоить это значение оригиналу.Упрощаем:
В обоих случаях имеем возможность изменить значение непосредственно в структуре, которая передаётся в качестве параметра.
В качестве затравки:
Структура
pabServпросто просится быть преобразованной в класс. Туда же подтянутсяprice1(2, 3),type_calcиenum RecourceLabel. Суммы по газу, свету, воде можно держать в массиве, также, как и расценки.Верно, когда я редактировал последний вариант кода, я обратил внимание на функции
Gas(), Light(), Water(). Мне так и захотелось собрать их воедино. Только не все так просто... Этот код только пиджак в который осталось впихнуть самое главное расчет газа, света и воды. В каждом из этих расчетов используются свои ограничения по месяцам, в которых определена (или не определена) льгота, соответственно от размера льготы зависит вариант расчета, который будет в корне отличаться от такового за газ, свет или воду (три варианта расчета за газ, три — за свет и два за воду). При этом при выводе каждого и общего расчетов помимо отдельных расчетов и общей суммы, нужно вывести льготу на данные показания, сумму льготы и сумму к оплате (без учета льготы).То есть, есть ли смысл на данном этапе объединять функции
Gas(), Light(), Water(), а потом из них, допустим, вызывать функции расчета? Или вписать код расчетов в нынешние функции?В общем, согласно твоим корректировкам, код я «причесал»...
На данном этапе, предварительно поверхностно ознакомившись с классами, я понимаю, что сейчас весь этот мусор нужно структурировать. Я на пороге знакомства с классами и думаю, что нам будет о чем поговорить :)))
To be continued...
Зачем ты в этих функциях:
передаёшь аргументы как указатели? Единственное место, где должен быть указатель — это второй аргумент ф-ции
TotalSum(), поскольку это массив. Номер месяца везде лучше передавать просто какint. Указатель в параметрах функции, да ещё неконстантный, всегда наводит на мысль, что этот параметр используется как выходной (т.е. параметр изменяется внутри функции), что, в данном случае, неверно и вводит в заблуждение. Кроме того добавляется лишняя косвенная адресация. Мелочь, но зачем?К сожалению (к счастью?), я не знаю всех фишек, которые ты собираешься реализовать в своей программе. Поэтому пока за объединение функций агитировать не буду. Кроме того, если ты таки переведёшь программу на классы, может оно и само-собой рассосётся.
Thanks a LOT :)
Помимо того, что надо знать, как писать код, нужно понимать как правильно его писать, так, чтобы он работал с минимальными затратами, не был двусмысленным и был понятен для чтения.
Спасибо, Череп, что ты меня поправляешь и направляешь. Я прекрасно понимаю, что все эти «камни в огороде», пойдут только на пользу. Я это вижу даже по тому, что первоначальный код, этой программы, был более чем в 300 строк, а сейчас 200.
Что можно сказать, еще многому нужно научиться и с каждым шагом все интересней и интересней.
СПАСИБО!!! :)))