Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.26;
Скачать: CL | DM;

Вниз

Рекуррентный вызов процедуры   Найти похожие ветки 

 
Ego   (2004-12-11 10:50) [0]

Здравствуйте, всем.Писал программу, в которой была необходимость найи все подкаталоги в заданном каталоге.Я это сделал так:

procedure TForm1.ViewDir(dir:string);
 begin
  ChDir(dir);
  n:=FindFirst("*.*",faDirectory,sr);
   while n = 0 do
      if (sr.Name <> ".") and (sr.Name <> "..") then
        begin
          if sr.Attr = 16 then
            begin
            ListBox2.Items.Add(GetCurrentDir+"\"+sr.Name);
            n:=FindNext(sr);
            ViewDir(sr.Name);
            end
         else n:=FindNext(sr);
        end
      else n:=FindNext(sr);
  FindClose(sr);
 end;
Однако, эта процедура у меня не работала.Запустив отладчик я выяснил, что не работает рекуррентный вызов процедуры, то есть вся процедура выполняется только для основного каталога.В общем-то, я это обошел без труда:

procedure TForm1.Edit1Change(Sender: TObject);
begin
k:=0;
Edit1.Hint:=Edit1.Text;
ChDir(Edit1.Text);
ListBox2.Clear;
ViewDir();
repeat
 j:=ListBox2.Count;
 for i:=k to ListBox2.Count-1 do
    begin
    ChDir(ListBox2.Items[i]);
    ViewDir();
    end;
 k:=j;
until j = ListBox2.Count;
end;
..
procedure TForm1.ViewDir();
begin
n:=FindFirst("*.*",faDirectory,sr);
while n = 0 do
  if (sr.Name <> ".") and (sr.Name <> "..") then
   begin
     if sr.Attr = 16 then
       begin
       ListBox2.Items.Add(GetCurrentDir+"\"+sr.Name);
       n:=FindNext(sr)
       end
       else n:=FindNext(sr);
   end
  else n:=FindNext(sr);
FindClose(sr);
end;
но закрались сомнения и я, для проверки, написал такое:

x:=0;
..
procedure TForm1.Test();
 begin
  x:=x+1;
  if x < 100 then
    begin
     Label1.Caption:=IntToStr(x);
     Test();
    end;
 end;
Эта процедура у меня выполнялась один раз( до х = 1 ).Поэтому у меня возник вопрос: у меня проблеммы с Delphi, или такая конструкция просто невозможна?Другими словами: можно ли( и как это сделать )в Delphi вызывать процедуру из самой себя( малограмотное выражение, но, надеюсь, что понятное )?


 
Digitman ©   (2004-12-11 11:33) [1]


> закрались сомнения и я, для проверки, написал такое


вполне нормальная рекурсия ..в рез-те вызова TForm1.Test в лейбле ты должен увидеть число 99


> Однако, эта процедура у меня не работала


в справке же пример есть ...

procedure TForm1.ViewDir(dir:string);
var
 sr: TSearchRec; //при рекурсии это д.б. локальная переменная !!
 tmpdir: String;
begin
 if FindFirst(dir + "\*.*", faDirectory, sr) = 0 then
  begin
   repeat
    if ((sr.Attr and faDirectory) = faDirectory)
       and (sr.Name <> ".") and (sr.Name <> "..") then
     begin
      tmpdir := dir + "\" + sr.Name;
      ListBox2.Items.Add(tmpdir);
      ViewDir(tmpdir);
     end;
   until FindNext(sr) <> 0;
   FindClose(sr);
 end;
end;


 
Ego   (2004-12-11 11:54) [2]

вполне нормальная рекурсия ..в рез-те вызова TForm1.Test в лейбле ты должен увидеть число 99
Я и писал этот тест для того, что бы получилось 99, но получается-то 1!В чем может быть дело?Я понимаю( теперь понимаю, а раньше догадывался ), что проблема не в моем коде, но, даже не представляю, где ее искать( ну или, хотя бы, с чего начать )...


 
Digitman ©   (2004-12-11 12:03) [3]


> Ego


>  но получается-то 1


не знаю как у тебя 1 получается .. должно быть 99 .. если x - статическая переменная и непосредственно перед первым обращением к рекурсивному методу она действительно обнуляется, то я не вижу никаких причин неработоспособности кода

может у тебя где-то в области видимости тек.юнита есть еще одна процедура (именно процедура, а не процедурный метод формы) с именем Test ?


 
Ego   (2004-12-11 12:18) [4]


1:procedure TForm1.Test();
2: begin
3:  x:=x+1;
4:  if x < 100 then
5:    begin
6:     Label1.Caption:=IntToStr(x);
7:     Test();
8:    end;
9: end;

Вот как это должно выглядеть в отладчике( я так думаю ):
2-3-4-5-6-7-2-3-4 и т.д.;
вот как это выглядит:
2-3-4-5-6-7-8 и т.д...
Test, просто, единственная процедура - я ее в новой форме сделал по нажатию клавиши.Точнее есть еще ButtonClick, но, полагаю, что это не мешает.


 
Digitman ©   (2004-12-11 12:25) [5]


> Вот как это должно выглядеть в отладчике


> вот как это выглядит


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

поставь брейкпойнт на 4 и смотри, чему у тебя равно значение Х в этот момент... это разве так сложно ?


 
Ego   (2004-12-11 12:52) [6]

Разумеется я отслеживаю значение "х"!!!Значение и прибавляется и сравнивается когда надо.Проблема в строке 7.После нее должна выполняться строка 3, а выполняется 8( точнее ничего не выполняется - отладчик логические скобки не показывает )!Программа просто останавливается, вместо того, что бы гонять эту процедуру!


 
Digitman ©   (2004-12-11 13:15) [7]


> После нее должна выполняться строка 3, а выполняется 8


такого не может быть, потому что быть такого не может.
если ты, остановившись на 7, выполнишь стэп (F7),  отладчик в дан.случае ОБЯЗАН встать на 2


 
Anatoly Podgoretsky ©   (2004-12-11 13:29) [8]


  n:=FindNext(sr);
  ViewDir(sr.Name);

Убери n:=FindNext(sr);



Страницы: 1 вся ветка

Текущий архив: 2004.12.26;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.025 c
1-1102751874
Dema-X
2004-12-11 10:57
2004.12.26
ошибка еакцессволюшион LoadFromStream


6-1097231321
4MO
2004-10-08 14:28
2004.12.26
Proxy


1-1102717713
Bobby Digital
2004-12-11 01:28
2004.12.26
Memo


4-1100260115
Sergio
2004-11-12 14:48
2004.12.26
Перехват нажатие клавиш с Word-а


9-1091648899
DeadMeat
2004-08-04 23:48
2004.12.26
Статистика