Może pomoże link cytowany z powyższego linka z przykładem:
Może pomoże link cytowany z powyższego linka z przykładem:
Drzewo.
Cały dowcip w tym że "problem" ibidem to:
A wystarczy: każdą operację przydziału księgować true/false; tam gdzie istotne sprawdzać te zapiski; gdy zajdzie potrzeba uwalniać te zasoby które były przydzielone.
Wariantem jest trik z NULL. Można po prostu nie zastanawiać się czy wywołać free(ptr). Bo jeżeli ptr dostało pamięć to trzeba, a jak nie dostało (calloc itp.) to ptr jest NULL, free(NULL) będzie nieszkodliwe, to i tak można.
Przykład poproszę, coby nie pozostać na domysłach.
Może inaczej, zaproponuj wydajniejsze rozwiązanie bez goto dla przypadku omawianego tutaj:
A ja poproszę o Porsche. Może być model redakcyjny sterowany radiowo. Coby nie.
Przecież już napisałem jak to zrobić. Co do wydajności: mit. Jeżeli chcesz mieć szybko to piszesz w Asemblerze, jeżeli dobrze to w czymkolwiek byle nie Asembler. Wydajność nie zależy od zysku 1% "bo goto jest szybsze". Wydajność osiąga się algorytmem O(N^2.4) zamiast O(N^3).
Anyway, choć prawdopodobnie tego nie zrozumiesz, to mogłoby być tak:
double GetData (const char* name){ int returnedValue = NAN; FILE *file = Open(name) ; Buffer *buffer = AllocateBuffer(); if ( file && buffer) { returnedValue =..... } Close(file); FreeBuffer(buffer); return returnedValue; }
I to działa. Bo to na Close i na FreeBuffer spada odpowiedzialność za poprawne obsłuzenie sytuacji gdy nie trzeba zwalniać zasobu. A dowiadują się o tym, bo dostają NULL.
Proste. Skuteczne. Niemal RAII, tyle że w zwykłym C.
Jedyne co tracimy to czas na próbę alokacji bufora gdy już file było NULL. Ale to sytuacja wyjątkowa i można to zaakceptować. Ewentualnie dodać jeszcze jedno if oraz Buffer* buffer = NULL;
REDUKCYJNY
Odpuściłbym arduino - tylko złe nawyki utrwali.
Wielu próbuje przysłonić brak własnych umiejętności dowodząc wyższość arduino nad C. Niestety ich argumentacja jest wywodzona właśnie z braku umiejetności.
Mi natomiast przytrafiła się taka sytuacja jednokrotnie.
double
Arduino ::= hardware ułatwiające użycie MCU Atmega 328 w różnorodnych, zwykle amatorskich, projektach.
C ::= język programowania powstały w latach siedemdziesiątych ubiegłego wieku, uważany obecnie za najlepsze narzędzie do programowania MCU.
Arduino IDE ::= środowisko programistyczne ułatwiające (w założeniu) tworzenie oprogramowania w języku C++ dla Arduino.
C++ ::= język powstały przez rozszerzenie języka C tak, iż programy w C są (w 99.99%) programami w C++, ale programy w C++ nie są programami w C.
Dodatkowo: przy programowaniu MCU nie używa się wielu rzeczy, które są możliwe na komputerach klasy PC.
Stąd porównywanie Arduino do C to jak porównywanie kaczki do różowego.
Miałoby sens porównywanie Arduino IDE do Atmel Studio. W takim porównaniu Atmel Studio okazuje się lepsze co do możliwości, ale znacznie mniej wygodne dla początkujących. U
slawek snipped-for-privacy@fakeemail.com napisał(a):
Mówimy o C i tego się trzymajmy, ok?
Wypuść powietrze, zastanów się i odpisz w, temacie _konkretnego_ przykładu z linka.
Dnia Tue, 25 Apr 2017 22:16:57 +0200, ToMasz napisał(a):
goto skasowano wlasnie dlatego.
Za dlugie programy bylo, czesto z dzikimi skokami (co w polowie skutkiem numeracji linii).
Bo czesto trudno powiedziec ze to srednika brakuje.
J.
Użytkownik "Marek" snipped-for-privacy@fakeemail.com napisał w wiadomości grup dyskusyjnych: snipped-for-privacy@news.neostrada.pl...
Jeden rzut oka i widać że autor tutoriala robi fundamentalny błąd. Zamiast po prostu sprawdzać czy jest dobrze (tzn. czy nie ma błędu)... sprawdza czy jest błąd. Niby to to samo, ale skutki poważne - zwłaszcza że nadużywa return - biedak musi wywoływać cleanup wiele razy. (Ok, zaraz niedouczeni koderzy podniosą wrzask, że to nie jeden cleanup, ale wiele różnych. Cóż, warto sprawdzić czy rzeczywiście? Przecież można sprzątanie napisać tak, aby działało tak samo dobrze w każdym przypadku, np. free(NULL) jest bezproblemowe. )
Przy prostszych sprawach wystarczy takie coś bez goto:
int big_function() { int success = 0;
/* do some work */
if( !error1 ) { ... /* do some more work */ if( !error2 ) { ... /* do some more work */ if( !error3 ) { ... /* do some more work */ success = 1; } } }
/* clean up*/
return success; }
Przy bardziej poważnych programach można zrobić to nawet ładniej, ale obawiam się że i tak tego nie zrozumiesz, a zwłaszcza tego gdzie teraz jest clean-up.
int big_function(Task* list) { int success = 1; while ( *list && ( list->doWork(list) || success = 0 )) list = list->next; return success; }
Zgadza się. Bez problemu programuje się to w C.
Masz rację - błednie utożsamiłem Arduino z Bascom.
Acha i to jest to eleganckue rozwiazanie bez goto, rewelacja.
A konkretnie czego w tym nie rozumiesz?
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.