Yumox Temat założony przez niniejszego użytkownika |
R. 45 Struktury - zadanie domowe ppkt a » 2020-01-04 15:47:55 Cześć, czy funkcja napisana przeze mnie z zadania 1 w rozdziale struktury jest napisana poprawnie? void dodajPoczatek( Lista *& lista, int liczba ) { Lista * nowy = new Lista; nowy->liczba = liczba; if( lista == 0 ) nowy->ogon = 0; else nowy->ogon = lista; lista = nowy; }
W zadaniu 2 pisze aby nie odwiedzać wszystkich węzłów, a moja funkcja dodajPoczatek() ich nie odwiedza czyli muszę znaleźć tylko rozwiązanie dla funkcji dodajKoniec()? |
|
pekfos |
» 2020-01-04 16:07:05 1. Tak 2. Czy cokolwiek w zadaniu 2 ma chociaż sens w odniesieniu do dodajPoczatek()? Jest jasno napisane, o jaką funkcję chodzi. |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-01-04 16:18:47 Czy tak zmodyfikowana funkcja: void dodajKoniec( Lista *& lista, int liczba, Lista *& wskaznik ) { Lista * nowy = new Lista; nowy->liczba = liczba; nowy->ogon = 0; if( lista == 0 ) wskaznik = lista; if( lista ) ostatni( wskaznik )->ogon = nowy; else lista = nowy; wskaznik = nowy;
i program główny: int main() { int liczba; Lista * lista = 0; Lista * wskaznik = 0; std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( lista, liczba, wskaznik ); std::cout << "Koniec, oto liczby:\n"; wypisz( lista ); zniszcz( lista ); }
są dobrym rozwiązaniem? W podpowiedzi pisało że może być potrzebna kolejna struktura, ale chyba nie jest to konieczne? |
|
pekfos |
» 2020-01-04 17:24:37 Teraz opisujesz listę dwoma zmiennymi, które muszą być spójne by kod działał poprawnie. Lepszym rozwiązaniem jest opakowanie ich w drugą strukturę. |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-01-04 17:38:39 Chodzi o takie coś? Utworzenie kolejnej struktury w której będzie wskaźnik na Lista? struct Listawsk { Lista * wskaznik; Lista * lista; }; czyli funkcja powinna wyglądać tak: void dodajKoniec( Lista *& lista, int liczba, Lista *& wskaznik ) { Lista * nowy = new Lista; nowy->liczba = liczba; nowy->ogon = nullptr; if( lista == nullptr ) wskaznik = lista; if( lista ) ostatni( wskaznik )->ogon = nowy; else lista = nowy; wskaznik = nowy; }
a program główny tak? int main() { int liczba; Listawsk obiekt; obiekt.wskaznik = nullptr; obiekt.lista = nullptr; std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( obiekt.lista, liczba, obiekt.wskaznik ); std::cout << "Koniec, oto liczby:\n"; wypisz( obiekt.lista ); zniszcz( obiekt.lista ); }
|
|
pekfos |
» 2020-01-04 18:15:03 dodajKoniec( obiekt.lista, liczba, obiekt.wskaznik );
Po co zostawiasz tu możliwość podania błędnych argumentów? Wszystkie funkcje powinny przyjmować referencję na (stałą) strukturę opisującą listę, zamiast poprzedniego wskaźnika / referencji na wskaźnik. |
|
Yumox Temat założony przez niniejszego użytkownika |
» 2020-01-04 19:22:04 Wydaje mi się, że teraz rozwiązanie jest poprawne tylko funkcja wypisz() nie przyjmuje jako argumentu wskaźnika na tą nową strukturę bo przy wywołaniu rekurencyjnym wyskakuje błąd, że jest wskaźnik na nieodpowiedni typ. #include <iostream> struct Lista; struct Listawsk { Lista * wskaznik; Lista * lista; }; struct Lista { Lista * ogon; int liczba; };
void wypisz( Lista * lista ) { if( lista ) { std::cout << lista->liczba << ", "; wypisz( lista->ogon ); } }
Lista * ostatni( Lista * lista ) { if( lista ) while( lista->ogon ) lista = lista->ogon; return lista; }
void dodajKoniec( Listawsk * obiekt, int liczba ) { Lista * nowy = new Lista; nowy->liczba = liczba; nowy->ogon = nullptr; if( obiekt->wskaznik == nullptr ) obiekt->wskaznik = nowy; if( obiekt->lista ) ostatni( obiekt->wskaznik )->ogon = nowy; else obiekt->lista = nowy; obiekt->wskaznik = nowy; }
void zniszcz( Listawsk * obiekt ) { while( obiekt->lista ) { Lista * tmp = obiekt->lista; obiekt->lista = obiekt->lista->ogon; delete tmp; } obiekt->lista = nullptr; }
int main() { int liczba; Listawsk obiekt; obiekt.wskaznik = nullptr; obiekt.lista = nullptr; std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( & obiekt, liczba ); std::cout << "Koniec, oto liczby:\n"; wypisz( obiekt.lista ); zniszcz( & obiekt ); }
|
|
pekfos |
» 2020-01-04 21:21:04 teraz rozwiązanie jest poprawne tylko funkcja wypisz() nie przyjmuje jako argumentu wskaźnika na tą nową strukturę bo przy wywołaniu rekurencyjnym wyskakuje błąd, że jest wskaźnik na nieodpowiedni typ. |
To trzeba zmienić implementację. Przestało być wygodnie z rekurencją, to można ją wywalić i zrobić iteracyjnie - jak powinno być zresztą od samego początku. W kursie ta rekurencja jest użyta tylko dla demonstracji i oswajania z konceptem, a nie dlatego że wypisywanie listy, z jakiegoś niewyjaśnionego w kursie powodu, musi być zrobione akurat rekurencyjnie. Powiedzmy, że jest ok. Będę musiał pewnie przerobić tą lekcję, żeby krok ze wstawieniem nowej struktury już był zrealizowany jako drugi przykład. Jak dotąd każdy temat dotyczący tego zadania ma jakieś dziwne rozwiązanie, typu dorzucony bez ładu i składu nowy argument. Tu nie jest inaczej. Bez trudu można by wywalić w powietrze twoje trójargumentowe dodajKoniec() jeśli pierwszy element listy doda się funkcją dodajPoczatek() ;) A może trzeba dorzucić wymaganie, by lista trzymała informację o swojej długości? Może kolejny argument do funkcji dodającej by był wystarczającym impulsem by pomyśleć o użyciu wiedzy z bieżącej lekcji? |
|
« 1 » 2 |