Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Можно ли избавиться от goto в этом коде ? [D7]


Страницы:   1 2

Гоу ту ©   (2005-03-14 01:15:00) 

Зачем ? Просто из спортивного интереса.


 for i := 0 to High(BoxA) do
   if BoxA[i].obj = nil then begin
     Result := i;
     { some code here }
     goto End1;
   end;
 Result := Length(BoxA);
 SetLength(BoxA, Result +1);
 End1:


Defunct   (2005-03-14 06:14:00) [1]

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

Разница только в том, что в первом случае (со сдвигом части массива при удалении элемента) число возможных багов снизится т.к. всегда известно, что ВСЕэлементы массива СУЩЕСТВУЮТ(ну и как побочный эффект никакой надобности в goto или в break не возникнет).


Defunct   (2005-03-14 06:02:00) [2]

[22] продолжу
вот пример:

procedure TABox.AddItem(AObject: TObject);
begin
 Inc( fCount );
 SetLength( fItems, fCount);
 Items[fCount - 1] := AObject;
end;


Разве может быть процедура добавления более простой? И скажите в какое место здесь можно вставить Goto?


Defunct   (2005-03-14 05:55:00) [3]

> default ©  

Тривиальная задача. Пацану захотелось оставлять дыры в массиве. Ну так это его проблема, которая породила новую проблему - использование Goto.

Я бы постарался избежать этих дыр, например двухсвязным списком или еще как-то ибо дырявый (с элементами nil) BoxA это потенциальный ходячий баг.


default   (2005-03-14 05:42:00) [4]

хотя нет - 2 и 3 не аналоги 1 в [19](по принципу)
а с goto как не крути лучше всего


default   (2005-03-14 05:28:00) [5]

Defunct ©   (14.03.05 04:47) [19]
1 вариант по логике аналог [16]
а 2 и 3 аналог 1


Defunct   (2005-03-14 04:47:00) [6]

> Гоу ту
Вариант 1. (такой же длины как и оригинал)

Result := Length(BoxA);
for i := 0 to High(BoxA) do
  if BoxA[i].obj = nil then
     begin
        Result := i;
        { some code here }
        Break;
     end;

 if Result = Length(BoxA) then
    SetLength(BoxA, Result +1);


Вариант 2 (логика изменена):

 Result := Length(BoxA);
 i := Result - 1;

 while i >= 0 do
 begin
    if BoxA[i].Obj = nil then
        begin
           { some code here }
           Break;
        end;
    Dec(i);
  end;

  if i < 0 then
     SetLength(BoxA, Result +1)
  else
     Result := i;


Вариант 3 (логика изменена):

 Result := Length(BoxA);
 i := Result - 1;

 while (i >= 0) and (BoxA[i].Obj <> nil) do Dec(i);

 if i < 0 then
    SetLength(BoxA, Result +1)
 else
    begin
       Result := i;
       { some code here }
    end;


default   (2005-03-14 02:38:00) [7]

Гоу ту   (14.03.05 02:34) [17]
задумайся
результат сравнения есть логическая константа: True или False
численное же значение констант: Byte(True)=1, Byte(False)=0
последний вариант хорош, вот только логика не так проста


Гоу ту   (2005-03-14 02:34:00) [8]


> default ©   (14.03.05 02:17) [16]
> Byte(Result=Length(BoxA)
> идеалогически правильно следовать [12] или оставить первый
> вариант

Первый вариант. Ибо, вот какой результат даст эта строка +Byte(Result=Length(BoxA)) ? Надо задуматься.
Так, что да-здравствует гоу ту, и правильная логика. Если не нашли объект, то добавляем новый. Как словами говорим, так программу и пишем, безо всяких извращений.


default   (2005-03-14 02:17:00) [9]


Result := Length(BoxA);
for i := 0 to High(BoxA) do
  if BoxA[i].obj = nil then begin
    Result := i;
    { some code here }
    Break
  end;
 SetLength(BoxA, Length(BoxA) + Byte(Result=Length(BoxA));

вообщем, как видишь, воображение может создавать всё новые и новые модификации:)
идеалогически правильно следовать [12] или оставить первый вариант


Гоу ту   (2005-03-14 02:14:00) [10]


> > Но стало длиннее. А значит хуже.
> > И непонятнее.
> Хм. длиннее - значит хуже и непонятнее? Длина и понятность
> как-то коррелируются?

В вашем предложении да, а в моём нет. Нефиг переделывать чужие предолжения.


> default ©   (14.03.05 01:55) [13]
> строку Result := Length(BoxA); можно безболезненно вынести
> в начало кода

Два вызова функции SetLength вместо одного. Ла и логика извращённая. Сначала одну длину устанавливаем, потом другую. Уж лучше гоу ту, чем так.


GuAV   (2005-03-14 02:03:00) [11]

Exit + finally

abort + except


default   (2005-03-14 01:55:00) [12]

строку Result := Length(BoxA); можно безболезненно вынести в начало кода
отмена Goto по-любому потребует внесения дополнительного кода
можно ещё так

Result := Length(BoxA);
SetLength(BoxA, Result +1);
for i := 0 to High(BoxA)-1 do
  if BoxA[i].obj = nil then begin
    Result := i;
    { some code here }
    SetLength(BoxA, High(BoxA));
    Break
  end;


Просто Джо   (2005-03-14 01:50:00) [13]

Ну, так разбей это дело на 2 функции, примерно так:

function X(var BoxA: TArr): Integer;

 // возвращает номер пустого эл-та
 // или -1, если пустых нет
 function GetNilElementIndex: Integer;
 var
   I: Integer;
 begin
   Result := -1;
   for I := 0 to High(BoxA) do
     if BoxA[I].obj = nil then
     begin
       Result := I;
       Break
     end;    
 end;

begin
 Result := GetNilElementIndex;
 if  Result = -1 then
 begin
   Result := Length(BoxA);
  SetLength(BoxA, Result +1);
 end;
end;



> Но стало длиннее. А значит хуже.
> И непонятнее.


Хм. длиннее - значит хуже и непонятнее? Длина и понятность как-то коррелируются? Это новость.


Гоу ту   (2005-03-14 01:46:00) [14]


> Просто Джо ©   (14.03.05 01:32) [6]
> Тогда достаточно заменить Goto на Exit.

Нельзя. Там дальше ещё код идёт.


default   (2005-03-14 01:42:00) [15]

Гоу ту   (14.03.05 01:38) [9]
если у тебя после End1: ничего не должно выполняться, то делай Exit как тебе сказали в [6]


Гоу ту   (2005-03-14 01:38:00) [16]


> default ©   (14.03.05 01:28) [3]
> например, так

Но стало длиннее. А значит хуже.
И непонятнее.


default   (2005-03-14 01:34:00) [17]

Result намекает об этом, но всё же не факт


default   (2005-03-14 01:34:00) [18]

Просто Джо ©   (14.03.05 01:32) [6]
тут не очерчены рамки подпрограммы да и вообще что это подпрограмма


Просто Джо   (2005-03-14 01:32:00) [19]

Если я правильно интерпретировал ваши намерения, то в случае, если не один из элементов массива не равен nil, то результат функции должен быть равен старой длине массива, а новая длина массива должна быть увеличена на 1? Если же хоть один элемент массива равен nil, то функция возвращает индекс первого такого элемента? Так? Тогда достаточно заменить Gotoна Exit. А вообще, переписать нафик.


default   (2005-03-14 01:31:00) [20]

блин
Result := 0;
for i := 0 to High(BoxA) do
 if BoxA[i].obj = nil then begin
   Result := i;
   { some code here }
   Break
   end;
if BoxA[Result].obj <> nil then begin
 Result := Length(BoxA);
 SetLength(BoxA, Result +1);
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо