Programing fundamentals - 18 * Different Integers Size
Здравейте!
Споделям си решението на задачата с молба за критика (позитивна/негативна) от страна на по-опитните :)
http://pastebin.com/YHLchwkz
Целта ми беше главно да избегна използването на константи (което виждам масово).
Възможно ли е да заместя всичките dummy_* с една променлива но някакъв друг вид при такива проверки?
Благодаря!
Ще отговоря точка по точка това което (мисля че) знам:
1. Константите - може би грешно ги наричам така но са си такива :) Става дума за числата в изрази от рода на "x = a +4", " x == 5" и подобни - 4 и 5 са константи в случая. Тях не можем да променяме в хода на изпълнение на програмата. Вярно че за тях автоматично при компилиране май се заделя минималното нужно място, но така или иначе за една константа с размер INT се заделя толкова колкото и за променлива INT. В много решения видях че хората правят сравнение дали въведеното число е между двете граници на конкретния тип: if(num >= -2,147,483,648 && num <= 2,147,483,647) - едно, че пада голям copy/paste, второ - паметта която споменах задължително се заделя. (не съм на 100% сигурен. Ако беше асемблер тогава съм по-уверен) и трето че VisualStudio може да не открие някои грешки.
2. В конкретният случай мисля че дали ще декларирам променливите в началото или, както ти си направила, непосредствено преди употребата им - няма значение понеже е 100% сигурно че ще се използват.
2.1 Предполагам ако имам повече такива проверки би било добре да ги слога в няколко if/else един в друг - първо проверявам long: ако върне false излизам, ако ли не продължавам с двата int-a, после, евентуално, с двата short и т.н.
3. Това какво имаш в Catch е това което искаш да се случи ако програмта върне exception от типа посочен след Catch - грешно форматиран стринг при Parse примерно, делене на нула и т.н. Само Exception мисля че обединява всички типове exceptions.
4. Отново по тема памет - string-овете са immutable което ще рече че всеки път когато променяш съдържанието на стринг, ти заделяш нов участък от паметта за обновения текст и насочваш string-променливата към нея - с други думи ако имаш входно число с размер long, при всяко добавяне на ред към message, ти ще заделяш все повече и повече памет оставяйки в паметта старото съдържание неизползваемо (тук някой да ме светне как ще действа Garbage collector-а, моля, ако изобщо играе роля в случая :) )
И аз така:
1. Това ли се имало предвид, ясно. Няма смисъл да се изписва самата стойност, може просто да се използва int.MinValue() и int.MaxValue().
2. Не е така. В презентацията към тези упражнения се казва да се опитваме да декларираме променливата непосредствено преди да я използваме (слайдове 45, 46), даже имаше упражнения за това в Lab-a (refactor-ите).
2.1 Твърде много вложени условия ще станат и няма смисъл. А и условията не са изключващите се. Може да влиза в няколко случая едновременно. Последователни if-ове, както си го направил, е по-правилно.
4. Да, така е. Чета онлайн, че е по-добре да се използва StringBuilder. Ще го разгледам. Благодаря!
Поздрави!
В отговор на 2 + 2.1 :)
Няма изключващи се но неизпълнението на проверка за тип long прави безсмислени останалите проверки, което при последователни if-ве ... ами няма смисъл вече да проверяваш и променливите излишно се инициализират една след друга. Аз и за това съм ги извел в началото защото така или иначе се случват и си разделям програмата на няколко части: Инициализация на данни, Изчисления и Представяне на резултат. Ако едно число е от дефиниционната област на byte/sbyte/... то със сигурност ще бъде и от тази на long защото първата е подмножество на втората. Като да проверяваш къде живее човек - няма смисъл да почваш къща по къща ако може изобщо да не е от този град :)
Колкото до точка 1: не казвам задължително че директното копиране на стойностите е грешно, но със min/max или tryParse се освобождаваш от нуждата за проверка на стойността че даже може никога да не научиш каква е и пак да си работиш нормално.
4. Според мен за конкретната цел е по-лесно директно да се изписва всеки положителен резултат.
Сега като гледах твоя код ми хрумна и още нещо което аз бих направил (просто лично предпочитание):
ако дам начална стойност на canFit = true после мога да изместя редовете с него от try в catch и да му задавам стойност canFit= canFit & false; така първо давам по-нагледен смисъл на catch блоковете и второ в повечето случай спестявам на програмата няколко изпълнения на код.