Реализация рекурсивных процедур
Такой вариант процедуры не требует внимания к параметрам, которые пере-, даются в стеке при вызове рекурсивной процедуры, так как после возврата из нее они попросту не нужны и удаляются из стека. Но стоит нам в процедуре DrawPattern изменить порядок обращения к процедуре Ellipse, как ситуация резко меняется. Рассмотрим второй вариант организации процедуры DrawPattern.
VOID DrawPattern (HWND hwnd.HDC hdc.INT_DWORD x.INT_DWORD y.INTJMRD r,INT_DWORD p) //DrawPattern – рекурсивная процедура DrawPatten (вариант 2) вывода на экран узора //из окружностей на псевдоязыке (фрагмент) //Вход: х и у – координаты центра окружности; r – радиус окружности: //р – порядок узора, hwnd – дескриптор окна. HDC – контекст устройства. ПЕРЕМЕННЫЕ HWND hwnd: HDC hdc; INT_DWORD hdc .x .y .r.p НАЧ_ПРОГ ЕСЛИ (р) ТО //пока р*0 НАЧ_БЛОК_1 //рисуем еще четыре окружности по с центрами по краям этой DrawPattern (hwnd .hdc. х-r. у .r, р-1) DrawPattern (hwnd .hdc. х. у-r .r. р-1) DrawPattern (hwnd .hdc. х+r. у, r, р-1) DrawPattern (hwnd .hdc. х. у+r .r. р-1) //Ellipse – функция Win32 API для вывода эллипса (окружности), вписанного //в прямоугольник (квадрат) с координатами правого верхнего угла (x_up .y_up) //и левого нижнего угла (x_low .y_low): //Ellipse(HDC hdc. INT_DW0RD x_up. INT_DWORD y_up. INTJMJRD x_low. INT_DWORD yjow) //так как для рисования нужны координаты прямоугольника, а не центра окружности, //то преобразуем их при вызове Ellipse:. Ellipsethdc .x_up-r .y_up-r .x_low+r, y_low+r) КОН_БЛОК_1 КОН_ПРОГ
Если в первом варианте процедуры DrawPattern – DrawPattern1 окружности рисовались перед очередной рекурсивной передачей управления в процедуру DrawPattern, то во втором варианте это делается в последнюю очередь – во время обратного хода по цепочке вызовов процедуры DrawPattern. Это уже требует наличия локальных переменных в процедуре и их сохранения на период пока осуществляются рекурсивные вызовы процедуры DrawPattern. Приведем соответствующие фрагменты основной программы и функции DrawPattern_2 из DLL-библиотеки maket dll.DLL.
Из этого фрагмента хорошо видно, в чем разница между размещением параметров, передаваемых в рекурсивную процедуру, и локальными переменными этой процедуры. Для доступа к параметрам используются положительные смещения относительно адреса в ВР (это скрыто от нас с помощью директивы ARG), а для доступа к локальным параметрам – отрицательные смещения.
Разница в изображениях возникла из-за разных мест в программе, где вызывается функция InvalidateRect. Попробуйте самостоятельно исправить этот "дефект".