Что нового

Использовать ContinueLoop или только If-Else?

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
к слову говоря о ContinueLoop, его обычно указывают исключительно для прозрачности кода, т.к. никакой смысловой нагрузки в контексте кода он не несет.
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Использовать ли ContinueLoop или только If-Else?

Kaster
А если после ContinueLoop есть куча кода, который какраз-таки необходимо пропустить!?
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Использовать ли ContinueLoop или только If-Else?

`p r o x y
куча кода, которую надо пропустить - это мусор :smile:
зачем в коде участок который не надо выполнять?


Добавлено:
Сообщение автоматически объединено:

если взять тот же код gregaz, то цикл можно организовать так, где никакой участок кода не пропускается
Код:
For $i=1 To UBound($aSoft)-1
    If $aSoft[$i][1] == 'True' Then
        ; Здесь работа функции MoyFunc()
        ; Операция с файлом :  $aSoft[$i][0]
    EndIf
Next
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Использовать ли ContinueLoop или только If-Else?

Kaster
Да ладно! Не уж то ни разу не сталкивался? Конструкция очень полезная при работе с массивами. Причем очень часто используется и в других ЯП, например JavaScript, PHP.

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

Вот прям сейчас был у меня участок кода: в переменной объект на коллекцию HTML TR из таблицы. Перебор осуществляется с помощью For…In, т.е. всех-всех найденных TR. В каждом TR необходимо найти нужный TD, а уже в нем нужные данные. Но серди всех TR, встречаются такие, в которых нет нужных данных. Заведомо зная порядок ненужных TR, при их обнаружение, вызывается ContinueLoop для перехода к следующему TR. Профит: ускорение выполнения кода, из-за пропуска ненужных элементов; уменьшение вероятности возникновения ошибки.
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Использовать ли ContinueLoop или только If-Else?

`p r o x y
дай мне любой код где используется ContinueLoop, и я тебе его переделаю так, что его не будет ;)
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Использовать ли ContinueLoop или только If-Else?

Kaster
Из Encoding.au3:

Код:
For $i = 1 To $iLen
		$iAsc = Asc(StringMid($sText, $i, 1))

		If $iCheckASCIICode And $iAsc > 128 Then $bLess128 = False

		If Not BitAND($iAsc, 0x80) Then
			ContinueLoop
		ElseIf Not BitXOR(BitAND($iAsc, 0xE0), 0xC0) Then
			$iExt = 1
		ElseIf Not (BitXOR(BitAND($iAsc, 0xF0), 0xE0)) Then
			$iExt = 2
		ElseIf Not BitXOR(BitAND($iAsc, 0xF8), 0xF0) Then
			$iExt = 3
		Else
			Return False
		EndIf

		If $i + $iExt > $iLen Then Return False

		For $j = $i + 1 To $i + $iExt
			$iAsc = Asc(StringMid($sText, $j, 1))
			If BitXOR(BitAND($iAsc, 0xC0), 0x80) Then Return False
		Next

		$i += $iExt
	Next
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Использовать ли ContinueLoop или только If-Else?

Kaster [?]
так, что его не будет
Если есть большая вложенность проверок и выборок, то городить If...Else будет не слишком удобно. В место одной строки писать 2, 3, 4, 5 ......А смысл? Плюс, при большой вложенности выстраиваются отступы. Зачем же ухудшать читабельность?

Код:
For $i=1 To UBound($aSoft)-1
    $iQwe1 = _Qwe1()
	If $iQwe == -1 Then ContinueLoop
	
	$iEwq = _Ewq()
	If $iEwq == -4 Then ContinueLoop
	
	$iAsd = _Asd()
	If $iAsd == 4 Then ContinueLoop
	
	$iDsa = _Dsa()
	If $iDsa == 7 Then ContinueLoop
	
	$iAwd = _Awd()
	If $iDsa == 45 Then ContinueLoop
	
	$iFgt = _Fgt()
	If $iFgt == 14 Then ContinueLoop
	
	$iFds = _Fds()
	If $iFgt == 17 Then ContinueLoop
	
	$iVcx = _Vcx()
	If $iVcx == 14 Then ContinueLoop
Next


А вот если переписать в If…Else будет офигенная лесенка. А если условий будет 20?
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Использовать ли ContinueLoop или только If-Else?

Еще интересней вариант:

Код:
For $i = 1 To $a__MSOE_Events[0][0]
		;Compare with standard event, or with wheel *Scroll* Down and wheel *Scroll* Up events
		If $a__MSOE_Events[$i][0] = $iEvent Or ($iEvent = $MOUSE_WHEELSCROLL_EVENT And ($a__MSOE_Events[$i][0] = $iEvent+8 Or $a__MSOE_Events[$i][0] = $iEvent+16)) Then
			If $iEvent <> $a__MSOE_Events[$i][0] Then
				Local $tWheel_Struct = DllStructCreate($stMSLLHOOKSTRUCT, $lParam)
				Local $sWheelScroll_Data = DllStructGetData($tWheel_Struct, 3)
				
				If _WinAPI_HiWord($sWheelScroll_Data) > 0 Then
					If $iEvent+16 <> $a__MSOE_Events[$i][0] Then
						ContinueLoop ;Scroll Up event, but not matching
					EndIf
				Else
					If $iEvent+8 <> $a__MSOE_Events[$i][0] Then
						ContinueLoop ;Scroll Down event, but not matching
					EndIf
				EndIf
			EndIf
			
			If $a__MSOE_Events[$i][4] <> 0 And Not __MouseSetOnEvent_IsHoveredWnd($a__MSOE_Events[$i][4]) Then
				Return 0 ;Allow default processing
			EndIf
			
			$i__MSOE_EventReturn = 0
			$iBlockDefProc_Ret = $a__MSOE_Events[$i][5]
			
			$iRet = Call($a__MSOE_Events[$i][1], $a__MSOE_Events[$i][2], $a__MSOE_Events[$i][3])
			
			If @error Then
				$iRet = Call($a__MSOE_Events[$i][1], $a__MSOE_Events[$i][2])
			EndIf
			
			If @error Then
				$iRet = Call($a__MSOE_Events[$i][1])
			EndIf
			
			$i__MSOE_EventReturn = 1
			
			If $iBlockDefProc_Ret = -1 Then
				Return $iRet
			EndIf
			
			Return $iBlockDefProc_Ret ;Block default processing (or not :))
		EndIf
	Next
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Использовать ли ContinueLoop или только If-Else?

`p r o x y [?]
Код:
For $i = 1 To $iLen
        $iAsc = Asc(StringMid($sText, $i, 1))

        If $iCheckASCIICode And $iAsc > 128 Then $bLess128 = False

        If BitAND($iAsc, 0x80) Then
	        If Not BitXOR(BitAND($iAsc, 0xE0), 0xC0) Then
	            $iExt = 1
	        ElseIf Not (BitXOR(BitAND($iAsc, 0xF0), 0xE0)) Then
	            $iExt = 2
	        ElseIf Not BitXOR(BitAND($iAsc, 0xF8), 0xF0) Then
	            $iExt = 3
	        Else
	            Return False
	        EndIf
	
	        If $i + $iExt > $iLen Then Return False
	
	        For $j = $i + 1 To $i + $iExt
	            $iAsc = Asc(StringMid($sText, $j, 1))
	            If BitXOR(BitAND($iAsc, 0xC0), 0x80) Then Return False
	        Next
	        $i += $iExt
		EndIf
Next


`p r o x y [?]
Еще интересней вариант:

Код:
For $i = 1 To $a__MSOE_Events[0][0]
	If $a__MSOE_Events[$i][0] = $iEvent Or ($iEvent = $MOUSE_WHEELSCROLL_EVENT And ($a__MSOE_Events[$i][0] = $iEvent+8 Or $a__MSOE_Events[$i][0] = $iEvent+16)) Then
		If $iEvent <> $a__MSOE_Events[$i][0] Then
			Local $tWheel_Struct = DllStructCreate($stMSLLHOOKSTRUCT, $lParam)
			Local $sWheelScroll_Data = DllStructGetData($tWheel_Struct, 3)

			If Not ((_WinAPI_HiWord($sWheelScroll_Data) > 0 and $iEvent+16 <> $a__MSOE_Events[$i][0]) or (_WinAPI_HiWord($sWheelScroll_Data) <= 0 and iEvent+8 <> $a__MSOE_Events[$i][0])) Then
				If $a__MSOE_Events[$i][4] <> 0 And Not __MouseSetOnEvent_IsHoveredWnd($a__MSOE_Events[$i][4]) Then
					Return 0 ;Allow default processing
				EndIf
					$i__MSOE_EventReturn = 0
				$iBlockDefProc_Ret = $a__MSOE_Events[$i][5]
					$iRet = Call($a__MSOE_Events[$i][1], $a__MSOE_Events[$i][2], $a__MSOE_Events[$i][3])
					If @error Then
					$iRet = Call($a__MSOE_Events[$i][1], $a__MSOE_Events[$i][2])
				EndIf
				If @error Then
					$iRet = Call($a__MSOE_Events[$i][1])
				EndIf
					$i__MSOE_EventReturn = 1
					If $iBlockDefProc_Ret = -1 Then
					Return $iRet
				EndIf
					Return $iBlockDefProc_Ret ;Block default processing (or not :))
			EndIf
		EndIf
 	EndIf
Next


`p r o x y [?]
Зачем же ухудшать читабельность?
в этом скрипте, я не стал его переделывать, потому что
а) он маловероятен
б) если и возник, то свидетельствует о плохой структуре самого кода.
в) мне кажется ты его просто придумал, в обход пунктов а) и б), просто в пику :smile:
но если все же заморочиться, то да, там будет полудерево. но по мне глядя на него будет так же понятно что и на твой участок. ну а если таких кусков будет много, то это уже "острая клиническая неправильность" составления.
ну а что касается реальных, то выше я их перевернул
на самом деле, я пользуюсь всего лишь простым правилом обращения логических функций.
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Re: Использовать ли ContinueLoop или только If-Else?

Вух, что-то нафлудили. Да бы не вводить дискуссию в принципиальное отстаивание своей позиции – резюмирую.

Люблю конструкцию с использованием ContinueLoop можно заменить проверкой с помощью If-Else.

При этом, выбор в пользу одного из решений можно рассмотреть по следующим выводам:

1. Читабельность полученного кода.
Полностью зависит непосредственно от программиста: уровня знаний и понимания синтаксиса языка, а так же индивидуальных особенностей при чтении/восприятии/понимании алгоритма выполняемых условий проверки.

2. Время разработки до отладки кода.
В различных случаях, конструкции с использованием ContinueLoop представляют собой более простой/читабельный вариант. В виду того, что построение такой конструкции может включать в себя меньшее количество условий проверки. Поэтому, время разработки зависит от времени набора верной конструкции кода программистом.

Код:
If Not ((_WinAPI_HiWord($sWheelScroll_Data) > 0 and $iEvent+16 <> $a__MSOE_Events[$i][0]) or (_WinAPI_HiWord($sWheelScroll_Data) <= 0 and iEvent+8 <> $a__MSOE_Events[$i][0])) Then
	; ...
EndIf


Код:
If _WinAPI_HiWord($sWheelScroll_Data) > 0 Then
	If $iEvent+16 <> $a__MSOE_Events[$i][0] Then ContinueLoop
Else
	If $iEvent+8 <> $a__MSOE_Events[$i][0] Then ContinueLoop
EndIf
; ...


3. Время на выполнение отладки кода.
Зависит от читабельности кода, а следовательно от программиста.

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


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



Код:
просто в пику

Не в пику, а в пример. Причем в рамках примере ситуация уже может быть. В цикле опрашиваются функции и соответственно, проверяет результат выполнения каждой функции. Цикл, например, автоматизации работы сайтом. Действий от 10 до 40 легко может быть.
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
`p r o x y
те два сравнения которые ты привел, я переделал просто на автомате исключительно используя правила обращения логических функций с учетом вложенностей. если изначально строить алгоритм без использования ContinueLoop, то можно все логику перестроить таким образом, чтобы выглядело короче. но для этого надо будет вникнуть во всю логику, для чего у меня нет ни времени, ни желания. а вот по поводу,
`p r o x y [?]
проверяет результат выполнения каждой функции
ок. давай присмотримся к скрипту. в цикле выполняется функция номер один. и если ее значение не равно определенной выполняется функция два. и только если ее значение не равна чему-то там, выполняется три, и т.д. если ты считаешь что такая разветвленная структура это нормально, то мне сложно представить целесообразность построения самого алгоритма таким образом. но! если все же алгоритм уже составлен именно таким образом, то именно древовидная структура логически отвечает за ее содержимое, чего не скажешь о варианте с использованием пропусков. как ты сказал дело вкуса и привычки, но отлаживание такого кода мне видится более сложным чем с использованием иерархически согласованного условного дерева.
 

`p r o x y

«Улыбайтесь, господа!»
Команда форума
Глобальный модератор
Сообщения
596
Репутация
157
Kaster [?]
то мне сложно представить целесообразность построения самого алгоритма таким образом.

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

И все же, но ... так дело вкуса и привычку или же все же но? Хорошо, когда есть ИМХО. Не хорошо - монополизировать.
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
`p r o x y [?]
И все же, но ... так дело вкуса и привычку или же все же но?
моя твоя не понимать :D
Хорошо, когда есть ИМХО
это просто замечательно. у меня оно тоже есть.
Не хорошо - монополизировать.
так и представляю себе во всех вывесках страны
[box title=Афиша]Внимание, внимание. Горячие новости. Kaster монополизировал использование условных операторов. Отныне любой кто будет использовать ContinueLoop будет преследоваться по закону[/box] :rofl:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster [?]
куча кода, которую надо пропустить - это мусор
smiley.gif

зачем в коде участок который не надо выполнять?
Позвольте с Вами не согласиться. Сейчас пытаюсь написать графическую оболочку для umodel.exe, который распаковывает пакеты для игр. Все расширения (upk, umap, xxx, ... это пока только те, которые знаю), с которыми он работает, выяснить мне не удалось. Зато я знаю, с которыми он точно не работает. В итоге я использую следующую конструкцию:
Код:
;...
$aFiles = _FileListToArray(@ScriptDir, '*', 1)
;...
For $i = 1 To $aFiles[0]
	Switch StringRegExpReplace($aFiles[$i], '^.*\.', '')
		Case 'txt', 'au3', 'exe', 'rar', 'cmd', 'bat', 'DLL', '7z', 'ico'
			ContinueLoop
	EndSwitch
;дальше некоторый кусок кода, который запускает umodel.exe, читает консольный вывод и т.д. и т.п.
;...
Next
В такой ситуации, ИМХО, использование ContinueLoop считаю самым оптимальным. Если я не прав, поправьте меня. :smile:

PS
Всех с мужчин с Днем защитника Отечества. :beer:
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Код:
;...
$aFiles = _FileListToArray(@ScriptDir, '*', 1)
;...
For $i = 1 To $aFiles[0]
    If Not StringRegExp($aFiles[$i], '^.*\.(txt|au3|exe|rar|cmd|bat|DLL|7z|ico)')
        ;дальше некоторый кусок кода, который запускает umodel.exe, читает консольный вывод и т.д. и т.п.
    EndIf
;...
Next
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster
Согласен. :smile:
Только у меня разное кол-во файлов выдает:
Код:
#include <File.au3>

$j = 0
$aFiles = _FileListToArray(@SystemDir, '*', 1)
$iStart = TimerInit()
For $i = 1 To $aFiles[0]
	If Not StringRegExp($aFiles[$i], '^.*\.(txt|au3|exe|rar|cmd|bat|DLL|7z|ico)') Then
		$j += 1
	EndIf
Next
$sTime = StringFormat('%.2f', TimerDiff($iStart))
MsgBox(64, $aFiles[0], 'Time: ' & $sTime & @LF & 'Files: ' & $j)

Код:
#include <File.au3>

$j = 0
$aFiles = _FileListToArray(@SystemDir, '*', 1)
$iStart = TimerInit()
For $i = 1 To $aFiles[0]
	Switch StringRegExpReplace($aFiles[$i], '^.*\.', '')
		Case 'txt', 'au3', 'exe', 'rar', 'cmd', 'bat', 'DLL', '7z', 'ico'
			ContinueLoop
	EndSwitch
	$j += 1
Next
$sTime = StringFormat('%.2f', TimerDiff($iStart))
MsgBox(64, $aFiles[0], 'Time: ' & $sTime & @LF & 'Files: ' & $j)
:wacko:
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles
возможно в моем шаблоне где-то ошибка. проверить не могу. но смысл я думаю понятен :smile:
я не оспариваю факт, что можно использовать и то и другое. просто у каждого свое виденье "правильного кода". так вот в моем, не должно быть участков кода которые пропускаются. даже если окончательный результат одинаковый я стараюсь писать так, чтобы каждая строка скрипта что-то делала.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Kaster [?]
...не должно быть участков кода которые пропускаются...

...чтобы каждая строка скрипта что-то делала...
Но ведь и конструкция If...Else...EndIf, и любой другой условный оператор, все равно пропускает определенные участки кода в зависимости от входящего условия. ИМХО, какая разница при помощи чего пропускать.
 

Talany

Знающий
Сообщения
136
Репутация
11
Kaster сказал(а):
madmasles
возможно в моем шаблоне где-то ошибка. проверить не могу. но смысл я думаю понятен :smile:
я не оспариваю факт, что можно использовать и то и другое. просто у каждого свое виденье "правильного кода". так вот в моем, не должно быть участков кода которые пропускаются. даже если окончательный результат одинаковый я стараюсь писать так, чтобы каждая строка скрипта что-то делала.

Полность согласен!! Зачем лишний раз напрягать память...

А конструкцию If...Else...EndIf.... ты же не будеш писать

Код:
$i=1
IF $i = 1 Then
    msgbox(0,0,$i)
Else
    ContinueLoop
EndIf
 
Автор
kaster

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
madmasles [?]
ИМХО, какая разница при помощи чего пропускать.
ну с этим сложно поспорить :smile: но я имел в виду пропуски другого характера. именно пропуск, а не результат выбора. когда часть скрипта в ветке условного оператора, код (для меня) более понятен, т.к. организован иерархически. а ContinueLoop это некий goto, который, по мне, слегка нарушает и порядок, и самое главное хронологию.
 
Верх