RTV forum PL | NewsGroups PL

programowanie w C - bardzo ogólne pytanie o filozofi ę. Ardu

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - programowanie w C - bardzo ogólne pytanie o filozofi ę. Ardu

Goto page Previous  1, 2, 3, 4, 5, 6  Next

Guest

Tue Oct 24, 2017 11:30 am   



On 2017-10-24 08:29, Janusz wrote:

Quote:

PRalki jeszcze nie tknąłem.
I dobrze, jeszcze sobie lub dziecku krzywdę zrobisz.


Jeżeli pralka do zabawy to:
https://www.youtube.com/watch?v=sZfrl-LQamk&ab_channel=AdamMarkiewicz

Włodek

Piotr Wyderski
Guest

Tue Oct 24, 2017 11:42 am   



Piotr Gałka wrote:

Quote:
Tak się zastanawiam do czego ona mogła by być przydatna i nie bardzo
potrafię wymyślić jakiś przykład generujący realną taką potrzebę.

A mnie się zdarza stosunkowo często, choć przypadki użycia są jedynie dwa:

1. Opuszczanie wielokrotnie zagnieżdżonych pętli.
2. Przekazywanie sterowania do wspólnego kodu obsługi błędu dla danej
sytuacji:

if (dobrze) {

// to dobrze
} else {

lbl_zle:

// bardzo zle
}

if (albo_jednak_zle) {

goto lbl_zle;
}

Quote:
A jeśli już w ogóle to chyba tylko wewnątrz jednej funkcji do jakiegoś
rozwikłania czegoś co w przeciwnym wypadku wymagało by albo dwukrotnego
napisania kilku linijek programu, albo ujęcia ich w kolejną wywoływaną
funkcję.

Dokładnie o to chodzi. Goto potrafi znacznie *podnieść* czytelność,
tylko trzeba go używać z głową. To przydatna konstrukcja, niepotrzebnie
obrosła mitami.

Pozdrawiam, Piotr

Piotr Gałka
Guest

Tue Oct 24, 2017 11:42 am   



W dniu 2017-10-24 o 12:58, J.F. pisze:

Quote:
Pomysl lepiej ile razy kombinowales, gdy jedno goto zalatwiloby sprawe,

Czasem kombinowałem, ale na prawdę nie pamiętając w ogóle o istnieniu
goto nigdy nie miałem myśli "jedno goto załatwiloby sprawę" dlatego nie
mam pojęcia czy tak było w tych przypadkach gdy kombinowałem.

Quote:
jak podano - wyjscie z zagniezdzonych petli.

Jak dopada mnie taki przypadek to robię podfunkcję z której w wielu
miejscach wychodzę przez return - w sumie to podobne do goto i możliwe
że też jest 'be'.

Quote:
Inna sprawa, ze jakbym tak zaczal mieszac za pomoca goto, to pewnie tez
bym sie pogubil :-)


Jak użyć goto tak jak wyżej opisany return to pewnie na czytelności
wiele nie traci, ale jak byłoby w funkcji kilka etykiet i gdzieś tam
skoki do nich - niektóre do przodu, niektóre do tyłu to chyba bym
zwariował próbując zrozumieć.
P.G.

Piotr Wyderski
Guest

Tue Oct 24, 2017 11:49 am   



Piotr Gałka wrote:

Quote:
Kiedyś przetestowałem break;break; i OIDP zadziałało dobrze, ale nie
byłem pewien, czy to przypadek

Przypadek, błąd w kompilatorze najprawdopodobniej. Sterowanie
nie ma prawa dojść do drugiego goto. Poza tym spróbuj tak opuścić
switcha zawartego w petli. :-)

Quote:
czy cecha języka więc dołożyłem bool który służył tylko do tego
aby zewnętrza pętla wiedziała, że wewnętrzna każe wyjść.

Czyli klasycznie zacząłeś wbijać gwoździe kombinerkami,
bo Dijkstra chlapnął, że goto jest złe.

Quote:
Potem chyba zastąpiłem wewnętrzną przez osobną funkcję
inline i wydaje mi się to lepszym/czytelniejszym rozwiązaniem niż goto.

Jeśli możesz poprawić strukturę programu w ten sposób, to zawsze warto,
nie tylko z powodu goto. Natomiast jeśli nie możesz, to... przyznaj, że
nie możesz i użyj goto, a nie kombinuj. Ta konstrukcja jest w języku
*celowo*.

Quote:
Kilka lat temu kupiłem sobie ostatnią książkę Stroustrupa o C++.
Nie przebrnąłem przez całą. Utkwiło mi w pamięci, że według niego jak
funkcja ma więcej jak 7 linijek to znaczy, że program jest źle
napisany.

Nie pierwsza to i nie ostatnia głupota, a papier w mordę nie da...

Pozdrawiam, Piotr

J.F.
Guest

Tue Oct 24, 2017 11:52 am   



Użytkownik "Piotr Gałka" napisał w wiadomości grup
dyskusyjnych:osn8vc$r5s$1$PiotrGalka@news.chmurka.net...
W dniu 2017-10-24 o 12:58, J.F. pisze:
Quote:
jak podano - wyjscie z zagniezdzonych petli.

Jak dopada mnie taki przypadek to robię podfunkcję z której w wielu
miejscach wychodzę przez return - w sumie to podobne do goto i
możliwe że też jest 'be'.

Inna sprawa, ze jakbym tak zaczal mieszac za pomoca goto, to pewnie
tez bym sie pogubil :-)

Jak użyć goto tak jak wyżej opisany return to pewnie na czytelności
wiele nie traci, ale jak byłoby w funkcji kilka etykiet i gdzieś tam
skoki do nich - niektóre do przodu, niektóre do tyłu to chyba bym
zwariował próbując zrozumieć.

W assemblerze mi sie nie mylilo :-)

IMO - to sie stad wzielo, i moze troche z numerowania linii jak w
Basicu i moze kart jak w czasach Fortranu.

Bardzo poczatkujacy programisci w basicu rozwijajac program bardzo
szybko tworza takie dzikie struktury z wieloma zupelnie niepotrzebnymi
skokami, a potem sami sie w tym gubia.
Wiec Wirth zabronil skokow i mial spokoj (choc w Pascalu goto jak
najbardziej jest, za to nie ma break i continue).

Byc moze ma to jeszcze cos wspolnego z dowodzeniem poprawnosci
programow - w tak "dzikiej" strukturze trudno dowod przeprowadzic.

J.

Piotr Gałka
Guest

Tue Oct 24, 2017 12:07 pm   



W dniu 2017-10-24 o 13:42, Piotr Wyderski pisze:
Quote:

A mnie się zdarza stosunkowo często, choć przypadki użycia są jedynie dwa:

1. Opuszczanie wielokrotnie zagnieżdżonych pętli.
2. Przekazywanie sterowania do wspólnego kodu obsługi błędu dla danej
sytuacji:

if (dobrze) {

    // to dobrze
} else {

lbl_zle:

    // bardzo zle
}

if (albo_jednak_zle) {

    goto lbl_zle;
}

Taka konstrukcja z cofaniem się w kodzie jest dla mnie trudna.
Nie rozumiem czy zakładasz, że albo_jednak_zle może być true po
wykonaniu bloku dobrze, czy else.
Jak po else to znaczyło by, że kod //bardzo zle nie gwarantuje, że
albo_jednak_zle będzie false - czyli może się zapętlić.
A jak po dobrze to by znaczyło, że warunek dobrze nie jest 100% pewny.

Kiedyś dawno błędy zawsze obsługiwałem tak, że wszystkie funkcje
zwracały int i każda wyższa reagowała na to, co zwraca niższa jak
umiała, a jak nie to przekazywała błąd wyżej (czasem nadając mu już inny
numer). Nigdy nie obsługiwałem błędów danej funkcji w niej samej.

Od jakiegoś czasu staram się używać try{throw;}catch bo nie trzeba
myśleć o przekazywaniu wyżej błędów przychodzących z dołu.

Quote:
Dokładnie o to chodzi. Goto potrafi znacznie *podnieść* czytelność,

Możesz mieć rację, ale nie będę używał goto, bo tak (tu tupnięcie nogą) Smile
P.G.

Piotr Wyderski
Guest

Tue Oct 24, 2017 12:07 pm   



Piotr Gałka wrote:

Quote:
Pomysl lepiej ile razy kombinowales, gdy jedno goto zalatwiloby sprawe,

Czasem kombinowałem, ale na prawdę nie pamiętając w ogóle o istnieniu
goto nigdy nie miałem myśli "jedno goto załatwiloby sprawę" dlatego nie
mam pojęcia czy tak było w tych przypadkach gdy kombinowałem.

Piotrze, powody niechęci do goto były dwa:

1. Fatalny styl programowania ówczesnych początkujących programistów.

2. Niedostateczny rozwój metod translacji w zakresie analizy i
optymalizacji tzw. nieredukowalnych grafów przepływu, do których
powstania *może* doprowadzić goto, a konstrukcje "strukturalne"
w rodzaju break i continue nie. Jestem osobiście przekonany, że
o to właśnie tak naprawdę poszło, a mitologię dorobiono później.
No ale lata 60. się jakiś czas temu skończyły i problemu grafów
nieredukowalnych już nie ma, kompilatory robią transformacje,
które się nie śniły pionierom... No ale trendy narzuca ten, kto
pisze podręczniki... :-)

Quote:
Jak dopada mnie taki przypadek to robię podfunkcję z której w wielu
miejscach wychodzę przez return - w sumie to podobne do goto i możliwe
że też jest 'be'.

A jak masz kaskadowe returny? Funkcja bardziej niż z siebie nie wróci
i się zaczynają piętrowe ifki do obsługi takich sytuacji. Dobrze użyte
goto jest dobre, ale to konstrukcja dla ekspertów. Tylko jest różnica
między zakazywaniem a rekomendowaniem nieużywania.

Pozdrawiam, Piotr

Piotr Gałka
Guest

Tue Oct 24, 2017 12:12 pm   



W dniu 2017-10-24 o 13:52, J.F. pisze:
Quote:

W assemblerze mi sie nie mylilo :-)

Nigdy nie pisałem w assemblerze tylko raz pisałem assembler Smile

P.G.

Piotr Gałka
Guest

Tue Oct 24, 2017 12:17 pm   



W dniu 2017-10-24 o 14:07, Piotr Wyderski pisze:
Quote:

A jak masz kaskadowe returny? Funkcja bardziej niż z siebie nie wróci
i się zaczynają piętrowe ifki do obsługi takich sytuacji.

Na szczęście throw wróci nie tylko z siebie Smile i jeszcze po drodze
wszystko posprząta wywołując odpowiednie destruktory.
P.G.

Piotr Wyderski
Guest

Tue Oct 24, 2017 12:27 pm   



Piotr Gałka wrote:

Quote:
Taka konstrukcja z cofaniem się w kodzie jest dla mnie trudna.

No to jej nie używaj, to nie jest ani przymusowe, ani nawet częste.
Ja się tylko sprzeciwiam wieszaniu psów na tym niezwykle użytecznym
narzędziu. Kolega ujął to w charakterystyczny dla siebie sposób:
"jak się umie, to można nawet pić aceton".

Quote:
Nie rozumiem czy zakładasz, że albo_jednak_zle może być true po
wykonaniu bloku dobrze, czy else.

To jest szkic pewnego ogólnego sposobu programowania: ścieżka
najbardziej prawdopodobna powinna być fizycznie najprostsza,
liniowa, bo to podnosi czytelność programu. Nawet kosztem ścieżek
obsługi błędów.

Quote:
Jak po else to znaczyło by, że kod //bardzo zle nie gwarantuje, że
albo_jednak_zle będzie false - czyli może się zapętlić.

Potencjalnie tak, milczące założenie to niekontynuowalność
ścieżki błędnej: rzucenie wyjątku, ustawienie errno, return,
jak kto ma w coding standard ustalone.

Quote:
A jak po dobrze to by znaczyło, że warunek dobrze nie jest 100% pewny.

No bo często nie jest. Stopniowo sobie odsiewasz możliwości na
ścieżce głównej. Jeśli warunek jest fałszywy, to stan na 100% nie
jest poprawny, jeśli jest prawdziwy, to *być może* jest poprawny.
Trochę jak w filtrach Bluma. Goto pozwala Ci niezwielokratniać
ścieżek obsługi błędu (zakładając, że taka unifikacja ma sens
logiczny i rozmawiamy tylko o sprawach organizacji strukturalnej).

Quote:
Kiedyś dawno błędy zawsze obsługiwałem tak, że wszystkie funkcje
zwracały int i każda wyższa reagowała na to, co zwraca niższa jak
umiała, a jak nie to przekazywała błąd wyżej (czasem nadając mu już
inny numer). Nigdy nie obsługiwałem błędów danej funkcji w niej samej.

To działa dopóki realizujesz to konsekwentnie. Wystarczy
w jednym miejscu zapomnieć i obsługa błędów zdycha. Druga
sprawa to ta obsługa wyżej, to złożona sprawa. Funkcja
wyższego poziomu często nie ma kontekstu do właściwego
zinterpretowania błędu i popadamy w drugą skrajność:
użytkownik dostaje w twarz komunikatem, że pod adresem
0x1234 znaleziono wartość 0x5678 i pomimo absolutnej
poprawności przekazanych mu informacji nie ma pojęcia,
co z tym zrobić. Drugi koniec spektrum wyznacza autentyczny
wpis do logu o treści "Coś jebło, aborting". Trzeba znaleźć
złoty środek. :-)

Quote:
Możesz mieć rację, ale nie będę używał goto, bo tak (tu tupnięcie
nogą) Smile


W tym zakresie wykazuję się pełnym ekumenizmem. Smile
Rób *porządnie*, a nie skupiaj się na narzędziach do osiągnięcia tego celu.

Quote:
Od jakiegoś czasu staram się używać try{throw;}catch bo nie trzeba
myśleć o przekazywaniu wyżej błędów przychodzących z dołu.

Niestety nie Ty jeden. Pilny lot do USA z dokładnie tego
powodu już ćwiczyliśmy, bo się produkcyjny system w środku
nocy zatrzymał i to niestety nie w warzywniaku. :-)

Pozdrawiam, Piotr

Piotr Wyderski
Guest

Tue Oct 24, 2017 12:36 pm   



Piotr Gałka wrote:

Quote:
Na szczęście throw wróci nie tylko z siebie Smile

Chyba, że na swej drodze spotka rycerza Kacz Trzy Kropy
i potem Pszemol nie ma telefonu. Wink))

Quote:
i jeszcze po drodze wszystko posprząta wywołując odpowiednie destruktory.

Destruktory wywoła, ale liczenie, że posprząta, wymaga wulkanu
optymizmu. Niestety zwykle system przejdzie ze stanu "mniej-więcej
wiadomo, co się dzieje" do "kompletnie nie wiadomo, więc radośnie
działajmy dalej". Mało który zawodowy programista C++ potrafi pisać
kod bezpieczny ze względu na wyjątki (choć jest przekonany, że potrafi)
i różne Google pozakazywały używania wyjątków w swoim kodzie.

Pozdrawiam, Piotr

J.F.
Guest

Tue Oct 24, 2017 12:58 pm   



Użytkownik "Piotr Wyderski" napisał w wiadomości grup
dyskusyjnych:osnadg$lfn$1@node1.news.atman.pl...
Piotr Gałka wrote:
Quote:
Pomysl lepiej ile razy kombinowales, gdy jedno goto zalatwiloby
sprawe,
Czasem kombinowałem, ale na prawdę nie pamiętając w ogóle o
istnieniu
goto nigdy nie miałem myśli "jedno goto załatwiloby sprawę" dlatego
nie
mam pojęcia czy tak było w tych przypadkach gdy kombinowałem.

Piotrze, powody niechęci do goto były dwa:
1. Fatalny styl programowania ówczesnych początkujących programistów.

IMO - dzis bylby podobnie fatalny, tylko dzis od poczatku sie ich uczy
w "strukturalnym jezyku", nawet jesli to (Visual) Basic.

Quote:
2. Niedostateczny rozwój metod translacji w zakresie analizy i
optymalizacji tzw. nieredukowalnych grafów przepływu, do których
powstania *może* doprowadzić goto, a konstrukcje "strukturalne"
w rodzaju break i continue nie. Jestem osobiście przekonany, że
o to właśnie tak naprawdę poszło, a mitologię dorobiono później.

Cos w tym jest, bo istotnie optymalizacja moze byc trudna ... ale juz
IMP Fotran H bardzo dobrze optymalizowal, a na C i Pascala bylo
jeszcze za wczesniej.
Pascal ... tam sie chyba na optymalizatorze nie skupiano.

Quote:
No ale lata 60. się jakiś czas temu skończyły i problemu grafów
nieredukowalnych już nie ma, kompilatory robią transformacje,
które się nie śniły pionierom... No ale trendy narzuca ten, kto
pisze podręczniki... :-)

Jak dopada mnie taki przypadek to robię podfunkcję z której w
wielu
miejscach wychodzę przez return - w sumie to podobne do goto i
możliwe
że też jest 'be'.
A jak masz kaskadowe returny? Funkcja bardziej niż z siebie nie wróci
i się zaczynają piętrowe ifki do obsługi takich sytuacji.

No, goto miedzy funkcjami nie dziala :-)

Quote:
Dobrze użyte
goto jest dobre, ale to konstrukcja dla ekspertów. Tylko jest różnica
między zakazywaniem a rekomendowaniem nieużywania.

Tylko zanim czlowiek ekspertem zostanie, to trzeba cwiczenia zaliczyc,
albo mlodszego programiste zaliczyc, i uslyszy sie "w tym programie
jest goto, to jest zly program, prosze to poprawic" ...

J.

Piotr Wyderski
Guest

Tue Oct 24, 2017 1:05 pm   



J.F. wrote:

Quote:
Cos w tym jest, bo istotnie optymalizacja moze byc trudna ...

Starsze podręczniki o konstrukcji kompilatorów poświęcały
temu spory procent swojej objętości.

Quote:
No, goto miedzy funkcjami nie dziala Smile

Ale jeśli da się przenieść główny koszt wydajnościowy
do funkcji liściowej, co jest częste, to da się ją
"spłaszczyć" przy pomocy goto i względny koszt propagacji
błędów znacznie spadnie.

Quote:
Tylko zanim czlowiek ekspertem zostanie, to trzeba cwiczenia zaliczyc,
albo mlodszego programiste zaliczyc, i uslyszy sie "w tym programie jest
goto, to jest zly program, prosze to poprawic" ...

Zazwyczaj bez rzetelnego wyjaśnienia, dlaczego program jest zły.
Ja z kolei dwóch pracowników przekonałem do goto po prostu pokazując
im tak napisany program. Ale to byli znakomici programiści. :-)

Pozdrawiam, Piotr

Janusz
Guest

Tue Oct 24, 2017 3:36 pm   



W dniu 2017-10-24 o 11:58, Piotr Gałka pisze:
Quote:
W dniu 2017-10-24 o 11:22, Janusz pisze:

Tak się zastanawiam do czego ona mogła by być przydatna i nie bardzo
potrafię wymyślić jakiś przykład generujący realną taką potrzebę.
Znalazłby się, np wyjście z podwójnej pętli, breakiem wyjdziesz tyle że
pętlę wyżej gdzie musisz testować warunek dalszego wyjścia, jak widzisz
zaciemnia się kod i robi się to mało eleganckie.


Kiedyś przetestowałem break;break; i OIDP zadziałało dobrze, ale nie
byłem pewien, czy to przypadek, czy cecha języka więc dołożyłem bool
który służył tylko do tego aby zewnętrza pętla wiedziała, że wewnętrzna
każe wyjść. Potem chyba zastąpiłem wewnętrzną przez osobną funkcję
inline i wydaje mi się to lepszym/czytelniejszym rozwiązaniem niż goto.
Ale inline nic nie zmienia, to jest tylko sposób wywołania funkcji,

nadal masz zagnieżdżone pętle i potrzebę bezbolesnego wyjścia z tego
bagna.

Quote:
Kilka lat temu kupiłem sobie ostatnią książkę Stroustrupa o C++.
Nie przebrnąłem przez całą. Utkwiło mi w pamięci, że według niego jak
funkcja ma więcej jak 7 linijek to znaczy, że program jest źle napisany.
Wg mnie bzdura, rozdrabnianie funkcji a do tego dąży ta niby "zasada"

także zaciemnia program.

--
Pozdr
Janusz

Piotr Gałka
Guest

Tue Oct 24, 2017 6:31 pm   



W dniu 2017-10-24 o 17:36, Janusz pisze:
Quote:
Ale inline nic nie zmienia, to jest tylko sposób wywołania funkcji,
nadal masz zagnieżdżone pętle i potrzebę bezbolesnego wyjścia z tego
bagna.

Chodziło mi tylko o czytelność. Napisałem inline aby podkreślić, że da
się to zrobić bez pogarszania wydajności.

Zrozumienie co robi pętla:

for(;Wink
{
jakies dzialania
if(wewn_petla())break;
inne dzialania
}

wydaje mi się łatwiejsze gdy między działaniami przed i po jest tylko
jedna linijka a nie ileś tam wewnętrznej pętli.

Oczywiście to rzecz względna i zależy od konkretnej sytuacji. Jak tę
wewnętrzną pętlę da się w jednej linijce zapisać:

bool flag=false;
for(;Wink{... ; if(..){flag=true;break;}}
if(flag)break;

to robienie z niej funkcji nie ma wielkiego sensu, ale jak ona ma z 10
linijek to już bym się zastanawiał, a przy 20 to chyba już bym się nie
zastanawiał.
P.G.

Goto page Previous  1, 2, 3, 4, 5, 6  Next

elektroda NewsGroups Forum Index - Elektronika Polska - programowanie w C - bardzo ogólne pytanie o filozofi ę. Ardu

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map