Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Вниз

Можно ли избавиться от goto в этом коде ?   Найти похожие ветки 

 
Гоу ту   (2005-03-14 01:15) [0]

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


 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:


 
default ©   (2005-03-14 01:22) [1]

можно, конечно


 
Гоу ту   (2005-03-14 01:27) [2]


> default ©   (14.03.05 01:22) [1]
> можно, конечно

Только ты не знаешь как ?


 
default ©   (2005-03-14 01:28) [3]

например, так

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


 
default ©   (2005-03-14 01:29) [4]

goto End1; только выкинь...
Гоу ту   (14.03.05 01:27) [2]
задавой вопрос не только о факте возможности, но и о реализациии:)


 
default ©   (2005-03-14 01:31) [5]

блин
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;


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

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


 
default ©   (2005-03-14 01:34) [7]

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


 
default ©   (2005-03-14 01:34) [8]

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


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


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

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


 
default ©   (2005-03-14 01:42) [10]

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


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


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

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


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

Ну, так разбей это дело на 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;



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


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


 
default ©   (2005-03-14 01:55) [13]

строку 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;


 
GuAV ©   (2005-03-14 02:03) [14]

Exit + finally

abort + except


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


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

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


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

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


 
default ©   (2005-03-14 02:17) [16]


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:34) [17]


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

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


 
default ©   (2005-03-14 02:38) [18]

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


 
Defunct ©   (2005-03-14 04:47) [19]

> Гоу ту
Вариант 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 05:28) [20]

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


 
default ©   (2005-03-14 05:42) [21]

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


 
Defunct ©   (2005-03-14 05:55) [22]

> default ©  

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

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


 
Defunct ©   (2005-03-14 06:02) [23]

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

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


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


 
Defunct ©   (2005-03-14 06:14) [24]

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

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



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

Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.04 c
6-1106301265
Соловьев
2005-01-21 12:54
2005.03.27
idFTP или NMFTP и Firewall


3-1109774688
Belkova
2005-03-02 17:44
2005.03.27
Обновление БД


14-1110346714
КаПиБаРа
2005-03-09 08:38
2005.03.27
Рынок программ для сотовых телефонов


1-1110811572
tytus
2005-03-14 17:46
2005.03.27
Работа с большими файлами.


4-1108454861
Morf
2005-02-15 11:07
2005.03.27
Как найти значение в памяти любого приложения?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский