rottingham Temat założony przez niniejszego użytkownika |
» 2019-07-05 18:14:13 Hmm... A czy to rozwiązanie jest poprawne? Można mieć dwie niezależne listy, wystarczy dla drugiej listy utworzyć drugi wskaźnik przechowujący adres ostatniego elementu i przekazać go do funkcji. Dobrze myślę? #include <iostream>
using namespace std;
struct Lista { Lista * ogon; int liczba; };
void wypisz( Lista * lista ) { if( lista ) { cout << lista->liczba << ", "; wypisz( lista->ogon ); } }
Lista * dodajKoniec( Lista *& lista, int liczba, Lista * ostatni ) { Lista * nowy = new Lista; nowy->liczba = liczba; nowy->ogon = nullptr; if( lista ) { ostatni->ogon = nowy; return nowy; } else lista = nowy; return lista; }
void zniszcz( Lista *& lista ) { while( lista ) { Lista * tmp = lista; lista = lista->ogon; delete tmp; } lista = nullptr; }
int main() { Lista * lista = nullptr, * ostatni; int liczba; while( cin >> liczba && liczba ) ostatni = dodajKoniec( lista, liczba, ostatni ); wypisz( lista ); zniszcz( lista ); }
|
|
pekfos |
» 2019-07-05 18:24:57 Powiedzmy że działa. A gdyby teraz do zadania dodać int main() { int liczba; Lista * lista = nullptr; std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( lista, liczba ); std::cout << "Koniec, oto liczby:\n"; wypisz( lista ); zniszcz( lista ); } ? Albo lepiej, dodać do przykładu struct Wezel {...}; typedef Wezel * Lista;
void utworz( Lista & lista ) { lista = nullptr; }
int main() { int liczba; Lista lista; utworz( lista ) std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( lista, liczba ); std::cout << "Koniec, oto liczby:\n"; wypisz( lista ); zniszcz( lista ); } i zakaz modyfikowania funkcji main(). Tylko czy to nie byłaby już za duża podpowiedź..? :/ |
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-07-14 22:11:13 Czy typedef Wezel * Lista; ma jakąś funkcjonalność wykraczającą poza zapewnienie większej przejrzystości? |
|
pekfos |
» 2019-07-14 23:05:56 Jest też kwestia łatwiejszego utrzymania kodu. W kodzie jest używany typ Lista, więc gdybyś chciał zmienić co się kryje pod tym typem, to możesz to zrobić w definicji aliasu, a nie we wszystkich użyciach w kodzie. |
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-07-17 15:31:46 Powiem tak. Napisałem kod, który spełnia swoją funkcjonalność. Wiem, że to nie jest ten kod, na który Ty chciałeś mnie naprowadzić drugim przykładem. Pojawiły mnie się trzy wątpliwości: 1. Czy ten kod jest dobry? 2. Czy dużo mi brakuje do rozwiązania, na które chciałeś mnie naprowadzić drugą podpowiedzią? 3. Czy funkcja zniszcz() , którą tutaj napisałem jest dobrze napisana? (różni się od tej w przykładzie - jest krótsza, ale mam wrażenie, że w pełni spełnia swoją - nomen omen - funkcję). W drugiej podpowiedzi użyłeś funkcji utworz() . Nie za bardzo miałem pomysł na jej zastosowanie. A podejrzewam, że to ona odgrywa ważny element w tym drugim sposobie. #include <iostream>
using namespace std;
struct Lista { int liczba; Lista * wezel; } * ostatni = nullptr;
Lista * ogon( Lista * ostatni ) { return ostatni; }
void dodajKoniec( Lista *& lista, int liczba ) { Lista * nowy = new Lista; nowy->liczba = liczba; nowy->wezel = nullptr; if( !lista ) { lista = nowy; ostatni = nowy; } else { ogon( ostatni )->wezel = nowy; ostatni = nowy; } }
void wypisz( Lista * lista ) { while( lista ) { cout << lista->liczba << " "; lista = lista->wezel; } }
void zniszcz( Lista *& lista ) { while( lista ) { delete lista; lista = lista->wezel; } lista = nullptr; }
int main() { int liczba; Lista * lista0 = nullptr; cout << "Wprowadz liczbe... Blad lub 0 konczy wczytywanie: " << endl; while( cin >> liczba && liczba ) dodajKoniec( lista0, liczba ); wypisz( lista0 ); zniszcz( lista0 ); }
|
|
Monika90 |
» 2019-07-17 17:42:57 struct Lista { int liczba; Lista * wezel; } * ostatni = nullptr;
|
Zmienna globalna, co gorsza ukryta w definicji klasy. Ponieważ jest to zmienna globalna, to znaczy że w programie może być tylko jedna lista na raz. delete lista; lista = lista->wezel;
|
Użycie po zniszczeniu. |
|
rottingham Temat założony przez niniejszego użytkownika |
» 2019-07-31 15:34:45 gdybyś chciał zmienić co się kryje pod tym typem, to możesz to zrobić w definicji aliasu, a nie we wszystkich użyciach w kodzie. |
Alias struktury Lista może mieć inne składowe niż ta struktura? Jak to w takim razie zapisać? Próbowałem wielu sposobów, ale bezskutecznie. |
|
pekfos |
» 2019-07-31 17:30:13 Alias struktury Lista może mieć inne składowe niż ta struktura? |
I dlaczego miałoby to wciąż nazywać się "aliasem"? Oczywiście że nie może. gdybyś chciał zmienić co się kryje pod tym typem, to możesz to zrobić w definicji aliasu, a nie we wszystkich użyciach w kodzie. |
|
Przypuśćmy że masz w kodzie milion razy użyte float do trzymania wartości temperatury i miliard razy użyte float dla innych wartości fizycznych. Nagle stwierdzasz że akurat dla temperatury chcesz mieć long double, bo akurat jest za mała precyzja, a jak zmienisz wszystkie floaty, to nie wiem, RAM ci się skończy. Wtedy albo miałeś typedef float Temperatura;
i wystarczy typ zmienić w 1 miejscu, albo byś bardzo żałował że tak tego wcześniej nie zrobiłeś. #include <iostream> using namespace std;
typedef int Lista;
void utworz( Lista & lista ); void dodajKoniec( Lista & lista, int liczba ); void wypisz( const Lista & lista ); void zniszcz( Lista & lista );
int main() { int liczba; Lista lista; utworz( lista ); std::cout << "Podaj liczby, 0 lub blad konczy:\n"; while( std::cin >> liczba && liczba ) dodajKoniec( lista, liczba ); std::cout << "Koniec, oto liczby:\n"; wypisz( lista ); zniszcz( lista ); } Ten kod skompiluje się dla dowolnego typu ukrytego pod nazwą Lista. int, float**, std::string, cokolwiek dla czego zapis Lista x; jest poprawny. Naturalnie, nie zlinkuje się, bo brakuje definicji tych funkcji. |
|
1 « 2 » 3 4 5 6 |