Czy w c# istnieje mechanizm, który pozwala na przerwanie nested loops?
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
if (warunek) {
//zakończ iteracje na wszystkich pętlach
}
}
Czy w c# istnieje mechanizm, który pozwala na przerwanie nested loops?
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
if (warunek) {
//zakończ iteracje na wszystkich pętlach
}
}
@Adin: Wtedy wyjdziesz tylko z pętli b.
Pętla a wykona się kolejny raz...
using System;
public class Test
{
public static void Main()
{
int x1 = 3;
int y1 = 4;
for (int a = 0; a <= x1; a++)
{
for (int b = 0; b <= y1; b++)
{
if (a == 2 && b == 2)
{
Console.WriteLine("zakończ iteracje na wszystkich pętlach");
break;
}
Console.WriteLine(string.Format("a:{0}, b:{1}", a, b));
}
}
}
}
wynik:
a:0, b:0
a:0, b:1
a:0, b:2
a:0, b:3
a:0, b:4
a:1, b:0
a:1, b:1
a:1, b:2
a:1, b:3
a:1, b:4
a:2, b:0
a:2, b:1
zakończ iteracje na wszystkich pętlach
a:3, b:0
a:3, b:1
a:3, b:2
a:3, b:3
a:3, b:4
Wyszło tylko z jednej pętli. OP pytał o loops, czyli liczba mnoga.
return.goto: https://www.programiz.com/csharp-programming/gotobool. Kiedy będziesz chciał wyjść ze wszystkich pętli, to po prostu w zagnieżdżonej pętli ustawisz zmienną na true i wykonasz break. W pozostałych pętlach sprawdzisz, czy wartość tej zmiennej to true - jeśli tak, to te pętle też niech wykonają break.Jest goto, z drugiej strony dokumentacja odradza (i dobrze)

Wydzielenie funkcji jest zwykle najbardziej czytelnym sposobem, bo wtedy masz jakiś konkretny kawałek kodu, który ma swoją nazwę, który zwraca jakąś konkretną wartość (np. true/false) i który można potem użyć w innych miejscach.
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
if (warunek) {
//zakończ iteracje na wszystkich pętlach
}
}
nie wiem, czy to abstrakcyjny przykład, czy konkretny, ale jeśli konkretny to wygląda jak szukanie czegoś w prostokątnym obszarze pikseli. Zastanów się, czego szukasz i czy nie można by z tego funkcji zrobić.
Ewentualnie jakaś flaga ustawiana przez główną pętlą i sprawdzanie jej wewnątrz każdej wewnętrznej.
To już prościej spowodować, że warunek pętli zewnętrznej przestanie być spełniony:
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
if (warunek) {
a = x1 + 1;
break;
}
}
Ale po co dodawać jakieś dodatkowe flagi, checki, warunki gdy można zrobić zwykłe goto? :D to naprawde nie gryzie
Ewentualnie wydzielenie do funkcji
Dziękuje za pomoc. GOTO mi się najbardziej podoba.
Jeśli masz zagnieżdżoną pętlę to wydziel ją do osobnej funkcji i zamiast break użyj return. Goto nigdy nie jest poprawną odpowiedzią jeśli chodzi o czytelność kodu.
WeiXiao napisał(a):
to naprawde nie gryzie
naprawdę gryzie. W najmniej odpowiednim momencie

Wręcz przeciwnie, goto ma mniejszy narzut kognitywny, bo nie trzeba skakac i analizowac kilku funkcji
SomePixelTransformation(int [,] arr)
{
for (int a = 0; a <= x1; a++)
{
for (int b = 0; b <= y1; b++)
{
if (xyz)
goto endLoop;
}
}
endLoop:
(...)
return arr;
}
vs
SomePixelTransformation(int [,] arr)
{
PerformSomeTransformation(arr);
(...)
return arr;
}
PerformSomeTransformation(int [,] arr)
{
for (int a = 0; a <= x1; a++)
{
for (int b = 0; b <= y1; b++)
{
if (xyz)
return arr;
}
}
return arr;
}
WeiXiao napisał(a):
Wręcz przeciwnie, goto ma mniejszy narzut kognitywny, bo nie trzeba skakac i analizowac kilku funkcji
Przecież drugi przykład jest znacznie prostszy do przeanalizowania. Wiem że ciężko na przykładzie tak prostego kodu który się samemu napisało to odczuć ale w pierwszym przypadku widząc kod po raz pierwszy i natrafiając na etykietę musisz przerwać standardową analizę kodu i szukać wszystkich skoków. Jeszcze jak jest jedna etykieta i jeden skok to w porządku ale od tego się zaczyna. Znacznie łatwiej ogarniać mniejsze, nazwane (nazwą metody) fragmenty kodu.
W dobrym kodzie metody są tak proste że w ogóle nie musisz ich analizować bo z nazwy, argumentów i zwracanych wartości od razu wiadomo do czego służą; w przypadku jednej większej metody z goto musisz ją przeanalizować w całości.
ale w pierwszym przypadku widząc kod po raz pierwszy i natrafiając na etykietę musisz przerwać standardową analizę kodu i szukać wszystkich skoków.
W pierwszym mam te etykietę dosłownie przed oczami i co najwyżej mogę przerwać analizę, a w drugim MUSZĘ ją przerwać i zerknąć niżej, albo scrollnac, albo przeskoczyć.
W dobrym kodzie metody są tak proste że w ogóle nie musisz ich analizować bo z nazwy, argumentów i zwracanych wartości od razu wiadomo do czego służą; w przypadku jednej większej metody z goto musisz ją przeanalizować w całości.
W dobrym kodzie, jak taki kiedyś spotkam to dam znać.
Pracowałem przy web devie w dotnet, przy low lvlu (fw) w C, przy narzędziach w C++, przy open-source kobyłach z milionami linii
i serio uważam że im mniej tych "uncle bobowych" funkcyjek, które są raz uzywane w całym programie i są na siłe wydzielone, tym niższy narzut kognitywny ma taki kod.
Dla mnie idealny kod ma m.in takie cechy: relatywnie krótki, dobrze opisany, z komentarzami opisującymi dlaczego coś się stało, niewymagający skakania po X metodach (lub nie dej boze plikach) podczas analizy.
Oskarlesk napisał(a):
Czy w c# istnieje mechanizm, który pozwala na przerwanie nested loops?
Da się choć wymaga to egzotycznego użycia wątków.
W ten sposób możesz efektywnie wyskoczyć z każdego zagnieżdżenia bez nadużywania goto
Ciekawostka: w PHP break potrafi wyskoczyć z zagnieżdżonej pętli.
break przyjmuje argument liczbowy, który mówi o ile stopni zagnieżdżenia wyskoczyć.
https://www.php.net/manual/en/control-structures.break.php
break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. The default value is 1, only the immediate enclosing structure is broken out of.
Spine napisał(a):
Ciekawostka: w PHP
breakpotrafi wyskoczyć z zagnieżdżonej pętli.
breakprzyjmuje argument liczbowy, który mówi o ile stopni zagnieżdżenia wyskoczyć.https://www.php.net/manual/en/control-structures.break.php
break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of. The default value is 1, only the immediate enclosing structure is broken out of.
Java też ma takie coś:
outer:
for (String a : foo) {
for (String b : bar) {
if (b.equals("buzz")) {
System.out.println("Skipping outer loop for " + a + " due to " + b);
continue outer;
}
}
System.out.println("Processing " + a);
}
Jest brzydkie rozwiazanie, ale still ładniejsze niż go:to[1]:
end = false;
for (int a = 0; a <= x1; a++)
for (int b = 0; b <= y1; b++) {
if (warunek) {
end = true;
break;
//zakończ iteracje na wszystkich pętlach
}
if(end)
{
break;
}
}
Poza tym to wydzielenie do innej funkcji i return.
[1] Jeśli się nie myle to break to też go:to pod spodem, ale reviewer Ci klepnie.
WeiXiao napisał(a):
no ta, o wiele lepsze niż goto, szkoda tylko że buga tam masz :D
Ta, jeszcze class, deklaracji funkcji itd brakuje. Nie tylko "var", którego umyślnie nie dodałem, bo nie kojarzyłem jak to jest w c# z deklaracja zmiennych.
Jak się tak czepiasz na CR jak tu to radziłbym przestać, bo jesteś realnie frajerem. Napocisz się w komciach a typ międzyczasie robi na OE, lub gra w lola. Stara metoda na frustratów :D. Sami Ci mówią jak masz pisać kod a Ty robisz coś innego. Potem "yea, sure" i akceptowanie zmian.
WeiXiao napisał(a):
jakie classy/vary? o czym ty piszesz? xd to algorytmicznie nie działa
A, czyli zszedłeś niżej, "}" w innej linii. Nawet nie brałem pod uwagę, że ktoś może nie zczaić o co chodzi w powyższym kodzie. xD Jako mod potraktowałbym twoje posty jako zwykły spam.
ale taki jest point :D
Na sile unikacie uzycia goto bo profesor w szkole wam powiedzial ze to zle
Dodajecie jakies zmienne, flagi, warunki, a koniec koncow wychodzą jakies bugi których nawet nie widzicie na pierwszy rzut oka, dopiero jak ktos wam zwroci uwage :D
z goto by to dzialalo nawet jak gubisz klamry i scope :D
Na sile unikacie uzycia goto bo profesor w szkole wam powiedzial ze to zle
Czy ja gdzieś pisałem, że goto jest złe samo w sobie? Pisałem tylko o CR. Walczysz z wymyślonym potworem :D
z goto by to dzialalo nawet jak gubisz klamry i scope
Szkoda, że już zpushowałem na proda. :D
Pisałem że masz awersję, a z czego ona wynika to nie wiem, podejrzewałem szkołe albo goto considered harmful
<troll> OE? Proszę cię, to jakieś rozwiązanie dla klasy średniej lub niższej? dla niewolnika? no bardzo super, lecisz na dwie roboty heheNapocisz się w komciach a typ międzyczasie robi na OE, lub gra w lola.
Jakbyś po prostu się lepiej urodził, np. w Izraelu, albo miał wujka w PZPN, czy znajomości w establishmencie amerykańskim to byś nie musiał nawet pracować, a gdzie tam jakies OE
</troll>
WeiXiao napisał(a):
Pisałem że masz awersję, a z czego ona wynika to nie wiem, podejrzewałem szkołe albo goto considered harmful
Ja mam awersję bo pracowałem w językach, w kodzie i w czasach gdzie goto było czymś powszechnym. Profesorzy nie mówią że "goto jest złe" z czapy tylko z doświadczenia a młodsze pokolenie jak zawsze lubi się buntować i kwestionować stare zasady. No i to czasem dobrze ale jakość przeciętnego kodu leci na łeb ostatnimi laty.
Cytując klasyka, ehh coraz więcej amatorów pcha się do zabawy
Profesorzy
doświadczenie
Dobre, nie znałem.
Ja mam awersję bo pracowałem w językach, w kodzie i w czasach gdzie goto było czymś powszechnym.
Ja też pracowałem w języku gdzie goto jest powszechne: C
I jakoś nie miałem z nim żadnego problemu. O wiele, wiele bardziej przerażały mnie mem issues.
WeiXiao napisał(a):
Na sile unikacie uzycia goto bo profesor w szkole wam powiedzial ze to zle
Nigdy żaden profesor tak nie powiedział.
Ale widzę, że masz jakiś problem z tym słynnym profesorem. Pokaż na misiu gdzie Cię dotykał:

z goto by to dzialalo nawet jak gubisz klamry i scope :D
Problem z goto nie polega na jego użyciu, tylko na tym, że przy sensownie napisanym kodzie w ogóle nie ma gdzie tej patoinstrukcji wstawić.
Dyskutowanie nad goto to ściśle juniorska dyskusja, aż mi się studia przypomniały
somekind napisał(a):
Problem z goto nie polega na jego użyciu, tylko na tym, że przy sensownie napisanym kodzie w ogóle nie ma gdzie tej patoinstrukcji wstawić.
Z tego pośrednio wynika że architekci C# i innych języków z goto zakładali że sensowny kod w nim napisany będzie mniejszością.
Widać doświadczenie.
loza_prowizoryczna napisał(a):
Z tego pośrednio wynika że architekci C# i innych języków z goto zakładali że sensowny kod w nim napisany będzie mniejszością.
Widać doświadczenie.
Po prostu przewidzieli istnienie @WeiXiao.