[Закрыть]
 
popoff.donetsk.ua
Если долгое время ходить в маске, рано или поздно можно так сжиться с ней, что потеряешь своё истинное лицо.
Начало | Новости | Статьи | Форум | Опросы | Карта сайта | Обо мне
popoff.donetsk.ua - Форум - Обсуждение статей - Технологии программирования - Флаги и оператор GOTO - Найти позицию элемента в массиве

Технологии программирования - Флаги и оператор GOTO - Найти позицию элемента в массиве

форумы popoff.donetsk.ua
Страницы: [1]
Подписаться на уведомления об изменениях в этом топике  |  << Новый  |  Старый >>  |  Ответить
Автор Сообщение
Обсуждение статьи Технологии программирования - Флаги и оператор GOTO - Найти позицию элемента в массиве
Screamer
Юрий Истомин
Янв, 2005
Сообщений: 6
Screamer url://forum.message:831
Технологии программирования - Флаги и оператор GOTO - Найти позицию элемента в массиве

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

popoff
Yuri
Июл, 2004
Сообщений: 1078
popoff url://forum.message:832

В примере поиска элемента массива на самом деле избавления от флага нет.

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

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

________________________________
Если не будет деревьев — нам нечем будет дышать, если вода загрязнится — нам нечего будет пить.
Screamer
Юрий Истомин
Янв, 2005
Сообщений: 6
Screamer url://forum.message:833

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

popoff
Yuri
Июл, 2004
Сообщений: 1078
popoff url://forum.message:848

Я, кажется, понял

1. Плохой является перегрузка значений переменных, когда в одной переменной хранится несколько разных по смыслу данных. Как в нашем случае, в одной переменной хранится одновременно и индекс в массиве и флаг, который говорит о том, найден ли результат. Что хуже, перегрузка значений или введение флагов, пока что сложно сказать.

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

Вероятно, стоило бы ввести раздел с определением терминов.

3. В формулировке задачи написана совершенно конкретная фраза:

Пусть про этот массив известно, что один из элементов равен x.



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

4. В случае с процедурой, если элемент не найден, то переменная pos просто не будет изменена.

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

5. В исходном варианте при использовании цикла while в случае, если элемент не найден, в цикл записывается значение, выходящее за пределы индексов в массиве, равное n. Это можно рассматривать как флаг «элемент не найден». Если сравнивать два способа перегрузки значений переменных, то вероятно, предложенная мной в варианте на Си перегрузка значений лучше, чем предложенная в примере на Обероне, потому что -1 явно прописана в программе, а n определяется из логики работы; значение -1 является понятным для всех массивов, о которых известно, что индекс не может быть отрицательным и для того, чтобы понять, найден ли элемент, не нужен сам массив; если используется n, то для того, чтобы понять, найден ли элемент, нужно знать, в дополнение к результату поиска, как минимум длину массива или даже весь массив, если, как в PHP, в качестве индексов допускается что-угодно (в том числе и отрицательные числа). Но если допустить в качестве индексов что-угодно, то и алгоритм поиска будет совсем другим.

6. Три приведенных варианта решения задачи поиска элемента в массиве не являются эквивалентными. В первом варианте значение переменной не изменяется, во втором - возвращается значение n, а в третьем - значение -1.

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

Найти(i);

Лично я подумал бы, что нужно найти значение, хранящееся в переменной i. Но при этом я задался бы вопросом, «а где искать?» и «а почему игнорируется результат поиска?». Этот код не говорит сам за себя и требует обязательного комментария. Код, который требует комментария, является плохим кодом.

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

9. Наша цель - показать, какой код является хорошим, а какой - плохим. При этом «хорошим» является код, работу которого можно понять без дополнительных комментариев, о котором нельзя сказать, что в нем есть какие-то «хитросплетения логики». Сравнивая два варианта, об одном можно сказать, что он лучше, чем другой, если работу первого можно понять быстрее, чем работу другого, если внести изменения в первый можно быстрее, чем во второй и если при внесении изменений в первый вариант вероятность возникновения ошибки меньше, чем при внесении изменений во второй вариант.

10. Для достижения нашей цели не требуется приводить хороший вариант решения. Достаточно привести плохой вариант и показать, чем он плох. Хороший вариант - это вариант, который не обладает рассмотренными недостатками.

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

11. Исходя из нашей цели (п.9), не имеет значения, можно ли написать вариант решения с процедурой, который не обладает недостатками, приведенными в п.7. Мы привели плохой вариант и показали, чем он плох. Мы добились нашей цели.

12. Исходя из нашей цели (п.9), нам становится все равно, каким именно образом обрабатывается ситуация «элемент не найден». Мы привели вариант плохого решения и обратили внимание на то, чем этот вариант является плохим. Мы добились нашей цели.

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

________________________________
Если не будет деревьев — нам нечем будет дышать, если вода загрязнится — нам нечего будет пить.
VNik62a
Владимир
Апр, 2008
Сообщений: 2
VNik62a url://forum.message:3026

Чрезвычайно рад встрече на сайте после некоторого перерыва. Нахожу его чрезвычайно для себя полезным и желаю автору развития и процветания
PS давно не заходил более подробные отзывы после изучения материала

Гость Hale_32bit url://forum.message:3049
Hale_32bit

Спасибо автору. Хорошие темы здесь поднимаются.

Страницы: [1]
Подписаться на уведомления об изменениях в этом топике  |  << Новый  |  Старый >>  |  Ответить
Вход
Поиск[?]:
Гинеколог, стоматолог, психотерапевт в Донецке