OberonCore
https://forum.oberoncore.ru/

Объяснение циклов начинающим
https://forum.oberoncore.ru/viewtopic.php?f=7&t=2191
Страница 2 из 4

Автор:  Доровских Александр [ Среда, 09 Декабрь, 2009 20:16 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Да уж! Раньше я понимал, что такое циклы и что они разные бывают. А почитал все, что здесь понаписали и понял, что ничего не понял :oops: . как все сложно :roll: .
Об чем спорим? Об чем копья ломаем? И что начинающий отсюда вынесет? Как то проще надо быть. Ближе к народу, товарищи!

Автор:  Илья Ермаков [ Среда, 09 Декабрь, 2009 20:20 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Кусок этой ветки явно надо отделить.

На усмотрение Info21, т.к. подфорум его.

Автор:  Alexey_Donskoy [ Среда, 09 Декабрь, 2009 22:17 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Info21 писал(а):
Ценная методическая находка, считаю :D
На самом деле иногда даже необходимая. Вот же писали тут недавно про ступор у некоторых учеников и студентов. И у меня были такие студенты, только подобным образом удавалось из ступора вывести. Главное - чтоб не вспоминал что-то судорожно, а думать сам начал, пусть по-простецки, но сам! И сам доходил до решения. Инициатива - у ученика, а от учителя - только справка :)

Автор:  Peter Almazov [ Среда, 09 Декабрь, 2009 23:47 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Вот хорошая цитата о трудности (и важности) сдвига парадигмы в восприятии циклов из книги HOW TO THINK ABOUT ALGORITHMS, Jeff Edmonds, 2008:

One of the first important paradigm shifts that programmers struggle to make is from viewing an algorithm as a sequence of actions to viewing it as a sequence of snapshots of the state of the computer. Programmers tend to fixate on the first view, because code is a sequence of instructions for action and a computation is a sequence of actions. Though this is an important view, there is another. Imagine stopping time at key points during the computation and taking still pictures of the state of the computer. Then a computation can equally be viewed as a sequence of such snapshots. Having two ways of viewing the same thing gives one both more tools to handle it and a deeper understanding of it.

Автор:  Valery Solovey [ Четверг, 10 Декабрь, 2009 01:16 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Илья Ермаков писал(а):
Я не понимаю, что подразумевается под "кубиковом подходом". Это вопрос реализации (как именно записать).

Природа цикла вообще, как одного из шаблонов поведения, не меняется.
Понятие инварианта цикла - тоже.
Методы проектирования цикла - тоже.

Нет, это вопрос не реализации, а представления. Цикл - это как отдельная сущность, неделимый элемент. В принципе, Дейкстра о том же говорит, только форма представления чуть-чуть другая. Но более подробная. : )

Автор:  Galkov [ Четверг, 10 Декабрь, 2009 01:24 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Valery Solovey писал(а):
Цикл - это как отдельная сущность, неделимый элемент

Вопрос, между прочим...
Тот же Дейкстра дает рекурсивное определение цикла. Я сам видел :D
Но механизм рекурсии все равно вводить надо. Ну как же без такого важного Атома

Автор:  Valery Solovey [ Четверг, 10 Декабрь, 2009 10:32 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

То есть, как это вопрос? У вас там кубик можно разломать на 4 кубика или ещё как-нибудь? Или его копия будет выполняться по-иному, нежели оригинал?

По поводу рекурсии. Интересно, как вам удасться добавить рекурсию в графический язык. С одной стороны, язык графический, и рекурсия должна быть видна явно. Не сам факт рекурсии, а именно... процесс что ли? С другой стороны, возможно ли это в принципе (добавить рекурсию так, чтобы она была видна явно)?

Автор:  Валерий Лаптев [ Четверг, 10 Декабрь, 2009 15:24 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

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

Автор:  Valery Solovey [ Четверг, 10 Декабрь, 2009 16:20 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

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

Но вообще-то упоминалось не про обозначение рекурсивного вызова, а про обозначение самой рекурсии.

Автор:  Galkov [ Четверг, 10 Декабрь, 2009 16:37 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Федор Васильевич, отделяйте к чертовой матери :D
Точнее: например с этого поста, и с присоединением к этому топику
Ибо, у Паниковского тоже есть свое мнение, но если я его начну высказывать, то это больше будет похоже на "... и тут Остапа понесло"

Автор:  Galkov [ Среда, 16 Декабрь, 2009 00:50 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Valery Solovey писал(а):
То есть, как это вопрос? У вас там кубик можно разломать на 4 кубика или ещё как-нибудь?
Ну может и не разломать... а посмотреть чего у нее у нутре - можно
Дабл-клик - и ты уже у нее у нутре: вот тебе Думатель, вот тебе Решатель, вот - и Неонка... А вот и провода, их соединяющие.
В принципе, цикл и рекурсия - похожие понятия в философском смысле, наверное.
А вопрос в том, что "новички" пытаются делать его делать "кольцеванием". Что де факто (но мне кажется неправильным идеологически) у нас является "не совсем правильной рекурсией".
И в некоторых случаях это работает (есть у нас специальные кодовые заморочки для таких любителей)
Было бы правильно такую "закольцованную посылку сигнала" делать "отложенной". Типа, разъемное соединение обладает своим FIFO-буфером данных. В котором данные накапливаются, если этот метод уже занят, а выполнение метода повторяется до исчерпания буфера.

Можно говорить об едином базовом элементе с входными точками doStart и doStop и одной выходной. И из него сотворять циклы различного калибра... Да хоть бы и Дейкстры... Или анти-Дейкстры
Много о чем говорить можно, если иметь кодогененрцию, которая все эти разговоры не будет превращать в потерю эффективности :D


Valery Solovey писал(а):
Но кто знает, может удасться это изобразить графически...
А чего там знать-то. Да как два пальца :D
Тут у меня правда серьезные разногласия с Автором. Философские, по поводу понимания, что такое рекурсия в ООП
((т.е., мы тоже люди, и у нас есть свои тараканы, и скелеты в шкафу))
Вот я, например, думаю, что повторный вход в метод объекта - это полное фуфло, а не рекурсия. Ибо, если про функцию можно говорить, что она реентерабельна (т.е., работает только с локальными переменными и аргументами), то про метод объекта - фигу.
Объект, это как раз такая штука, что обладает своей памятью. Причем, как правило, а не в виде исключения.
Ну вот, развивая идею динамического создания контекста (в стеке) для простых функций, я и делаю вывод, что рекурсия в ООП, это: создание нового объекта => вызов нужных методов для него => уничтожение его

Про изобразить. У нас есть разновидность мультика, называемая динамической. Т.е., мультик на схеме стоит, но его как бы и нет (типа пустой), пока ему не скажешь магическое слово ##add (если сказать несколько раз - будет массив объектов).
И есть у этого мультика режим (невыбранный элемент в вышеупомянутом массиве) "одноразового использования" - специально делал, в общем-то...

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

Автор:  Galkov [ Четверг, 17 Декабрь, 2009 18:47 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Alexey_Donskoy писал(а):
Потому что эта кубиковая модель алгоритмических конструкций, по-моему, тоже вполне академична и к тому же позволяет решать ряд практически полезных задач. В общем, ничуть не меньше и не хуже "классического" подхода!

Про академичность: как бы по факту - оно еще не совсем так.... По факту - шли не от теории, а от практики. Отсюда следуют, как все плюсы, так и все минусы существующего сегодня
НО, этот подход таки заслуживает академического изучения. И как результат - преврашения в "академичный подход"
Чем сейчас и занимаюсь :) В смысле, изучаю эту "академичность" в классических ЯВУ ((оказалось, что я многого не знаю))

И что интересно, как люди по разному читают классиков :D Вот Илья прочитал Дейкстру, и говорит, что цикл - это нечто особенное, в сравнении с иными конструктами. А я прочитал его же, и вижу - да одно и то же: семантика у любого синтаксического конструкта (и цикла - тоже) определяется "преобразователем предикатов". Ну да, у разных конструктов - разные преобразователи... дык на то они и "разные" :)

Надо продумать в "кубиковом подходе" (как Вы его называете) эти преобразователи для атомов (+структурных конструкций), и получится академичность, наверное :)
Ну типа: семантика "кубика" (или любой схемы, которую можно инкапсулировать в "кубик") определяется набором (на каждую левую/нижнюю точку) преобразователей предикатов из известных предикатов для верхних/правых точек.
Конь, конечно, еще не валялся, но это выполнимо, наверное

Ну еще кое-что сделать надо (мне кажется), чтобы, действительно - было не хуже "классического" подхода

Автор:  Valery Solovey [ Четверг, 17 Декабрь, 2009 19:13 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Galkov писал(а):
Надо продумать в "кубиковом подходе" (как Вы его называете) эти преобразователи для атомов (+структурных конструкций), и получится академичность, наверное :)
Вообще-то, академичность серьёзный людей не интересует. Им нравится адекватность.

Да и преобразователями предикатов себя ограничивать не стоит (если получится обнаружить другой подход по доказательству).

А цикл как таковой отличается от последовательности. Это "другой уровень". Точнее, переход на другой уровень. Думаю, что-то в этом роде Илья и имел в виду.

Но средства определения конструкции цикла такие же, как и для других конструкций. Поэтому, если считать, что конструкция есть то, с помощью чего её определяют, то да - цикл не отличается от остального.

P.S. Термин "другой уровень" придуман мной для меня, чтобы объяснять себе вещи некоторого рода. Когда я его себе называю, я в курсе, что имеется в виду. Вам его интерпретировать не стоит: почти нет шансов, что в такой туманной форме Вы его воспримите правильно. А подобрать стоящее определение этому понятию я пока не смог. Тяжеловато как-то.

Автор:  Galkov [ Четверг, 17 Декабрь, 2009 19:31 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Ну не знаю...
Мне показалось, что те, кто интересуется "доказательностью" - тоже серьезный людь :)
Не без исключений, конечно же

Скажем, мне встречалось утверждение, что в ответственных программах (читаем - очень серьезных) "тестирование" проводить вообще нельзя.
И человек, это говоривший, мне показался очень серьезным :D

Автор:  Alexey_Donskoy [ Четверг, 17 Декабрь, 2009 20:14 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

А "другой уровень" возникает всегда!
Так, в квадратике действия может быть вычисление формулы, то есть вызов процедур.
Да и каждый квадратик априорно может быть т.н. макроблоком, т.е. инкапсулировать кучу всего на текущем логическом уровне.
Действительно атомарных действий ведь нет! Либо инструкция процессора, либо инструкция ВМ...

Вот и получается, что цикл один в один соответствует вызову специфической процедуры... Именно по своей метаинформационной сути!

Автор:  Илья Ермаков [ Четверг, 17 Декабрь, 2009 21:48 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

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

А стоит связаться с циклами как таковыми - это как начать оперировать с пределами вместо просто величин..
Есть опять же параллели с итерационным решением уравнения (в случае циклов - в предикатах). Т.е. весьма специфическая семантика. А не просто "вход-обработка-выход".

Автор:  Valery Solovey [ Четверг, 17 Декабрь, 2009 22:30 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Alexey_Donskoy писал(а):
А "другой уровень" возникает всегда!
Так, в квадратике действия может быть вычисление формулы, то есть вызов процедур.
Да и каждый квадратик априорно может быть т.н. макроблоком, т.е. инкапсулировать кучу всего на текущем логическом уровне.
Действительно атомарных действий ведь нет! Либо инструкция процессора, либо инструкция ВМ...
Вот в том-то и дело, что вызов не обязан быть переходом на "другой уровенть". Этого не достаточно. Те уровни, про которые Вы говорите, построены человеком для... скажем так, для удобства. Я же имею в виду нечто иное.

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

Взять для примера тот же цикл. Скажем, нужно взять из базы 10 записей и заполнить их содержимым 10 структур данных. Перед циклом мы выполняем Запрос, на который из базы приходят записи. В Цикле мы заполняем Структуры. Если внести Запрос в Цикл, то в лучшем случае нам придётся устанавливать соединение 10 раз, а в худшем (и мне кажетя, что так реализовано большинство БД) - получим 10 одинаковых объектов. Если вынести часть инициализации Структуры за пределы Цикла, то полностью проинициализированным будет только один объект.

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

Автор:  Валерий Лаптев [ Четверг, 17 Декабрь, 2009 23:10 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Я в первой своей книжке "С++.Экспресс-курс" в 2003 писал так:
Код:
#include <iostream.h>
int main()
{  int k;    //  объявление переменной
   cout << "Введите множитель от 1 до 9: ";
   cin >> k;    //  ввод числа
   if ((0 < k) && (k < 10))    //  внешние скобки обязательны
   {  cout << k << "*1=" << k*1 << endl;    //  составной оператор
      cout << k << "*2=" << k*2 << endl;
      cout << k << "*3=" << k*3 << endl;
      cout << k << "*4=" << k*4 << endl;
      cout << k << "*5=" << k*5 << endl;
      cout << k << "*6=" << k*6 << endl;
      cout << k << "*7=" << k*7 << endl;
      cout << k << "*8=" << k*8 << endl;
      cout << k << "*9=" << k*9 << endl;
      cout << k << "*10=" << k*10 << endl;
   }
   else cout << "Неправильное значение множителя!" << endl;
   return 0;
}

Цитата:
Вернемся к программе "Таблица умножения с проверкой множителя", приведенной в листинге 1.4. Теперь наша программа делает именно то, что и требовалось: сначала просит ввести множитель: если множитель правильный, то вычисляется и выводится на экран соответствующая таблица умножения; если множитель неправильный, то программа выводит сообщение об ошибке и заканчивает работу. Все правильно. Однако рассмотрим вывод таблицы умножения внимательнее. Операторы вывода отличаются один от другого всего в двух местах: в текстовой константе и в выражении умножения. Хотелось бы заменить десять очень похожих операторов одним-единственным, который отработает за все десять.
Это не пустой интерес программиста, которому лень написать десять почти одинаковых строк, это очень важная проблема. Представьте себе, что надо вычислять не десять вариантов, а 573. Или даже миллион! Если 573 еще можно написать вручную, то миллион мы просто не осилим: если в секунду писать по одному оператору, то в течение суток мы напишем 86 400 операторов. На всю программу у нас уйдет 2 недели! А представляете размер такой программы? Поэтому сокращение текста программы за счет однотипных вычислений — это очень важное действие.
Разумеется, это можно сделать, если повторить выполнение оператора вывода десять раз. И при каждом повторении (которые в программировании обычно называются итерациями) требуется изменить текстовую константу и второй множитель в выражении умножения. Для решения этих проблем мы заменим явную целую константу переменной. Эта переменная должна увеличиваться на 1 при каждом повторении. Назовем нашу переменную именем i. Значение переменной i представляет собой номер итерации. Обычно такие переменные называют счетчиками. В языке С++ принято (хотя это и не обязательно) начинать считать с нуля. С учетом этого соглашения мы можем написать схему так:
i = 0;
пока (условие истинно)
увеличить i;
вывод одной строки таблицы умножения
Мы специально сдвинули две строки вправо, чтобы подчеркнуть тот факт, что эти строки должны повторяться, пока … что? Разберемся с условием повторений. Последний раз повторение оператора вывода должно произойти при значении i, равном 9. Как только i станет больше 9, повторения должны прекратиться. Поэтому условие можно записать так: i < 10.
На языке С++ повторение выполнения можно организовать, если использовать оператор цикла. В С++ имеется три оператора цикла, но в данном случае мы используем оператор с предусловием, который записывается так:
while (условие) оператор;
Слово while является зарезервированным словом С++. Этот оператор цикла работает следующим образом: пока условие истинно, выполняется заданный оператор; как только условие стало ложным, заданный оператор пропускается и начинает работать следующий после цикла оператор. Условие записывается точно так же, как и в операторе if. И точно так же на месте заданного оператора можно прописать составной оператор в фигурных скобках. Составной оператор называется телом цикла. Наша схема на С++ будет выглядеть так:
i=0; // начальное значение
while (i < 10) // условие продолжения
{ ++i; // увеличение переменной на 1
cout << k << "*" << i << "=" << k*i << endl;
}
Мы преобразовали текстовую константу в операторе вывода. По сравнению с первоначальным вариантом от нее осталось только два неизменных символа: звездочка и равно, — остальное превратилось в переменные, имеющие разные значения в разный момент времени. Теперь можно написать полную программу с циклом (листинг 1.7).

Автор:  Galkov [ Пятница, 18 Декабрь, 2009 10:27 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

А мне вот что показалось, в связи с этим :roll:
Тут у Вас смешаны во едино два разных понятия
1) Представление некого массива как бы разных действий, как некого единого, но чем-то параметризированного
2) Объединение тупой конструкции большого количества, уже одинаковых, действий - в единую конструкцию по имени Цикл

Первое - очень фундаментальное действие, и не в ИТ придуманное. Вся наука, наверное, на нем построена. Те же законы сохранения в физике - дошло же до кого-то, что каждый из них является конкретной реализацией более фундаментального принципа. Математики называют это абстрагированием от каких-то частностей, видимо.
Как этому научить - не знаю. Но если вы это научитесь внедрять в сознание на уровне инстинктов, то получите производство по созданию настоящих ученых.
Причем, это ведь работает и без цикла - длинное "тело" выделили в функцию, и пишите: MyFunc(1);MyFunc(100);MyFunc(10);MyFunc(31);
Вот и я пытаюсь "абстрагироваться" (типа рефлекс), говоря: "... а по-моему, они одинаковые", а Вы сопротивляетесь :D

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

Автор:  Валерий Лаптев [ Пятница, 18 Декабрь, 2009 10:35 ]
Заголовок сообщения:  Re: Объяснение циклов начинающим

Ценное размышление. Спасибо!

Страница 2 из 4 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/