[ главная ]   [ рейтинг статей ]   [ справочник радиолюбителя ]   [ новости мира ИТ ]



Ответов: 0
25-02-12 07:01







   Web - программирование
PHP


ASP






XML



CSS

SSI





   Программирование под ОС











   Web - технологии








   Базы Данных









   Графика






Данные




Программирование под ОС / Разное /

Мудрость программерская

О.ВОРОНИН

Давать советы — неблагодарное занятие. Советы никогда никто не слушает. Возможно, некоторые посчитают их очевидными. Однако, рискну. Меня несколько удивляет, как много задач программисты решают «в лоб», не заботясь ни о простоте решения, ни о скорости его выполнения, ни о стиле. Постараюсь дать несколько советов, как новичкам, так и тем, кто поопытнее.

Совет первый (и главный). Все гениальное — просто.

Обычно самое простое решение задачи — самое правильное. Простое решение чаще всего найти труднее, но его всегда легче понять, а поняв — реализовать. Но на этом дело не останавливается. Программы надо еще и отлаживать, поддерживать и изменять в угоду требованиям пользователей. Простое решение обычно более эффективно и меньше в объеме. В конце концов, оно доставляет удовольствие. Что-то щелкает в голове, и ты понимаешь — да, это ОНО. Ради этого стоит программировать.

Расчеты/таблицы/логика

Предположим, нам нужно написать код, решающий такую задачу:

• если входной аргумент  x равен  1, на выходе y:=25;

• если x равен  2, y:=30;

• если x равен  3, y:=35.

Можно выбрать один из трех подходов:

Расчет:

Таблицы:

Логика:

Для данной задачи вычисление результата — самое простое решение. Однако оно не самое быстрое.

Самое быстрое решение — табличное. Очень часто вычисление синусов и косинусов заменяется выборкой из таблицы для достижения скорости. И во многих случаях использовать таблицу проще, чем придумать формулу для вычисления результата, с помощью которой этот результат может быть вычислен. И стоит задаче чуть-чуть измениться — например, в первом варианте вместо 25 нужно получить 26, — нужно придумывать формулу заново (если это вообще возможно; в задаче случай тривиален, и подобрать формулу легко). При использовании таблиц нужно всего лишь поменять в таблице одно число.

Что касается варианта логики, оно обычно самое медленное и очень быстро разрастается при увеличении количества вариантов.

Минимизация условных операторов

Совет второй. Выбирайте один из трех подходов к решению задачи в таком порядке:

расчеты (кроме случаев, когда нужна скорость)

таблицы

логика

Использование условных операторов усложняет ваш код. Причем, он имеет тенденцию очень быстро разрастаться в размерах. Иногда очень сложно бывает разобраться во всех многократных вложениях if’ов, else и then. Кроме того, условные операторы замедляют выполнение программы.

Конечно, избежать условных операторов почти невозможно, но максима программиста такова: по каждому if’у задать себе вопрос: «Что я делаю не так?»

Совет третий. Не проверяйте то, что уже проверяли.

Возьмем пример, данный в начале статьи, и запишем его операторами if:

Что-то здесь не то. В каждом случае выполняются все три проверки. Если x=1, зачем проверять варианты 2 и 3? Вместо этого нужно сделать вложенные проверки:

Совет четвертый. Объединяйте условия вместе.

Многие вложенные структуры if ... then упрощаются с помощью объединения условий с помощью логических операторов. Например:

Вместо использования двух if’ов скомбинируем условия с помощью оператора and:

Это ближе к естественному языку и проще, особенно если условий много.

Однако из любого правила есть исключение. Если проверка наличия денег на вашем счету в банке занимает много времени, лучше сначала проверить, какой сегодня день, и записать так:

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

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

Совет пятый. Если у вас есть условия с разным весом, вкладывайте условные операторы так, чтобы первым был тот, который выполнится с большей вероятностью или является самым легким в вычислении.

Например, мы знаем, что в исходных данных для первой задачи x=3 в большинстве случаев. Тогда лучше проверить этот вариант первым (смотрите первый совет). Точно так же следует компоновать условия (то же касается предыдущего совета), если у вас «умный» компилятор.

Совет шестой. Используйте функции MIN и MAX вместо условных операторов.

Очень часто в программах встречаются ситуации, когда необходимо, чтобы значение некоторой переменной было не меньше 0 (или не больше некоторого значения). Обычно записывают так:

Гораздо проще использовать функцию max:

Казалось, мы ничего не выигрываем. Зато

можно записать так:

Совет седьмой. Используйте деление вместо условных операторов.

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

От этого оператора if можно избавиться:

где mod — взятие остатка от деления. А зачем, спросите вы. Но допустим, вы не знаете, на какое значение будет увеличиваться x. Может, даже и на отрицательное, то есть x будет уменьшаться. Как записать это условными операторами?

Попробуйте-ка разобраться! С вычислением остатка все гораздо проще:

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

Совет восьмой. Не используйте флаги, сразу устанавливайте данные.

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

К примеру, у вас есть две сетевые карты. Единственное, чем они отличаются, это номера портов ввода/вывода. Естественно записать такой код:

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

Однако неудобно использовать номера портов каждый раз, поэтому объявим константы:

Совет девятый. Не используйте флаги, сразу устанавливайте функцию.

Такой прием называется векторизацией. Этот совет полностью аналогичен предыдущему. Если вы устанавливаете флаг только для последующего выбора одной из функций, лучше сразу записать адрес самой функции.

К примеру, код для печати символа на принтере отличается от того, который выводит его на экран. В плохой программе можно было бы написать:

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

Предпочтительнее использовать векторизованное исполнение. Например:

Если количество необходимых к векторизации функций велико, предпочтительнее таблица функций (см. далее).

Совет десятый. Не устраивайте лишние проверки.

Даже авторы журнала «Мой компьютер» иногда используют такой код:

Зачем делать проверку истинности флага лишний раз, если это делает сам оператор if? Нужно записывать так:

А вместо

лучше

Очень часто встречаешь и такое:

Налицо лишняя проверка. Надо записывать так:

Использование таблиц решений.

Совет одиннадцатый. Используйте таблицы решений.

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

Таблица данных с одним измерением.

В первом нашем примере рассмотрена простая одномерная таблицы данных:

Мы просто выбираем из таблицы значение y по значению x, взятому в качестве индекса в таблице:

Еще пример. Нужно вычислить степени тройки. Решение «в лоб»:

Однако вместо того чтобы вычислять ответ при помощи умножения тройки на саму себя n раз, можно все такие ответы вычислить заранее и записать в таблицу:

Такое решение гораздо быстрее. Еще раз повторюсь, что часто такие таблицы применяются для вычисления синусов и косинусов.

Таблица функций с одним измерением.

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

Это хорошо, если у вас обрабатываются три-четыре клавиши. Если их больше, лучше использовать таблицу функций:

Конечно, позиция процедур в таблице должна соответствовать коду клавиши. Тогда вся предыдущая громоздкая структура управления пишется одной строкой:

Таблица данных с двумя измерениями.

Возьмем такую задачу. У нас есть два флага: fr — принимает значение истина, когда происходит чтение данных с диска, fw — принимает значение истина, когда происходит запись данных на диск. Необходимо вывести текст Чтение, если происходит чтение с диска, Запись, когда происходит запись, Чтение/запись, если чтение и запись происходит одновременно. И наконец, не нужно ничего выводить, если ничего не происходит.

Реализация с помощью структур управления:

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

Итоги

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

использовать




Комментарии

 Ваш комментарий к данному материалу будет интересен нам и нашим читателям!



Последние статьи: Программирование под ОС / Разное /

Комментарии к небольшой серии статей о недокументированных возможностях MS-DOS
15-02-2010   

Описываемые возможности проникновения в DOS и недокументированное поведение функции 13h являются серьезной прорехой с точки зрения недопущения несанкционированных действий и в то же время лакомым кусочком для создателей вирусов... подробнее

Кол. просмотров: общее - 3155 сегодня - 0

Программирование портов ввода/вывода
17-01-2010   

Обычно ПК имеет как минимум 2 последовательных и 1 параллельный интерфейс. Они являются специальными устройствами и отображаются следующим образом... подробнее

Кол. просмотров: общее - 3274 сегодня - 0

Особенности языков программирования и файловый ввод-вывод
17-01-2010   

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

Кол. просмотров: общее - 3392 сегодня - 0

Prolog - Лабораторная работа, работа со списками 2.
14-12-2009   

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

Кол. просмотров: общее - 3225 сегодня - 0

Prolog - Вписать треугольник в окружность.
14-12-2009   
Кол. просмотров: общее - 3359 сегодня - 0



  WWW.COMPROG.RU - 2009-2012 | Designed and Powered by Zaipov Renat | Projects