listy dwukierunkowe

Jachu
Użytkownik
Użytkownik
Posty: 42
Rejestracja: 5 lut 2008, o 08:03
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 7 razy
Pomógł: 2 razy

listy dwukierunkowe

Post autor: Jachu »

Musze napisać program który tworzy listę, tak żeby można było do niej coś dopisywać (wskazać na jeden element i po nim dodać jakiś nowy element).

Napisałem cos takiego:

Kod: Zaznacz cały

#include <stdio.h>
#include <stdlib.h>

struct element
       {
       float wartosc;
       struct element *prev;
       struct element *next;
       };
       
int dodaj (struct element *wskazany, float liczba) 
    {
     struct element *nowy; 
     nowy=(struct element*)malloc(sizeof(struct element));
     nowy->wartosc=liczba;
     nowy->next=wskazany->next;
     nowy->prev=wskazany;
     wskazany->next=nowy; 
     nowy->next->prev=nowy;
     free(nowy);
     return 1;
    };

void wypisz (struct element *wskazany)
    {
    printf("ten element to %f
",wskazany->wartosc);
    };
    
int main(int argc, char *argv[])
{

    struct element *wskazany = NULL;
    float x;
    
    while(x!=0)
    {
    wypisz(&wskazany);
    scanf("%f",&x);
    dodaj (&wskazany,x);
    };
  
  system("PAUSE");	
  return 0;
}

Sama funkcja dodawania raczej jest dobra, ale jak pierwszy raz pościłem program to można było dopisywać poszczególne liczby, a teraz już po pierwszym się wysypuje i nie wiem dlaczego.

Poza tym mam pytanie, jak mam zrobić takie coś żebym mógł wybierać jeden element i po nim coś wpisać lub go usunąć. Bo te elementy się w ogóle nie nazywają to jak się do nich odwołać. Skoro ten pierwszy jest "wskazany"(tak go nazwałem), następny ma tylko wskaźnik do wskazanego, jeszcze następny do tego drugiego itd. to jak to zrobić żeby po wypisaniu x elementów nagle wskazać np. na 5 ? albo wypisać 5,6 i 10 ?
Awatar użytkownika
Dedemonn
Użytkownik
Użytkownik
Posty: 689
Rejestracja: 21 lut 2007, o 19:40
Płeć: Mężczyzna
Lokalizacja: Z kompa
Podziękował: 26 razy
Pomógł: 137 razy

listy dwukierunkowe

Post autor: Dedemonn »

Juhu pisze:Poza tym mam pytanie, jak mam zrobić takie coś żebym mógł wybierać jeden element i po nim coś wpisać lub go usunąć. Bo te elementy się w ogóle nie nazywają to jak się do nich odwołać. Skoro ten pierwszy jest "wskazany"(tak go nazwałem), następny ma tylko wskaźnik do wskazanego, jeszcze następny do tego drugiego itd. to jak to zrobić żeby po wypisaniu x elementów nagle wskazać np. na 5 ? albo wypisać 5,6 i 10 ?
Pierwszy element na liście nazywany jest 'głową'. Aby przechodzić po liście, musisz gdzieś sobie ten element zapamiętać. (najlepiej jest utworzyć kolejną strukturę 'lista', w której przechowujesz wskaźnik na głowę). Gdy chcesz odwołać się do jakiegoś elementu, to musisz znać jego wartość lub indeks w liście. Przekazujesz funkcji głowę i przechodzisz po liście dopóki go nie znajdziesz. (lub jeśli już masz strukturę 'lista', to implementujesz odpowiednią do tego funkcję, która już wie gdzie ma głowę ;])
Gdy usuwasz to dodatkowo modyfikujesz wskaźniki next, prev danych elementów.
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

listy dwukierunkowe

Post autor: soku11 »

Co do kodu, który się w ogólne nie kompiluje tak ogólnie:
W funkcji dodaj tworzysz nowy element za zadanym. Niby ok, ale co się stanie, jeśli wskazany będzie NULLem?
- Wysypie się na linijce: nowy->next=wskazany->next;
Co jeśli wskazany jest ostatnim elementem na liście?
- Wysypie się na linijce nowy->next->prev=nowy;
I dodatkowo czemu tworzysz nowy obiekt, dołączasz go do listy, a później od razu kasujesz?
- Wysypie się przy próbie przejście po tej liście (niewyzerowane wskaźniki)
W funkcji main:
- Niezdefiniowane zachowanie w while(x!=0). Po pierwsze, x na początku ma losowe wartości, więc albo się to wykona albo nie. I ogólnie rzecz biorąc kod może się nie skończyć (poczytaj o precyzji liczb zmiennoprzecinkowych)
- Zły argument w wywołaniu funkcji wypisz.
- Zły argument w wywołaniu funkcji dodaj.
- Sztuczne i zbędne zatrzymywanie pracy, które nie działa na każdej platformie. W dodatku z użyciem funkcji, która do tego nie służy.
Ogólnie dziwnie wygląda angielski w połączeniu z polskim w kodzie...

Pozdrawiam.
Awatar użytkownika
steal
Użytkownik
Użytkownik
Posty: 1043
Rejestracja: 7 lut 2007, o 18:35
Płeć: Mężczyzna
Lokalizacja: Białystok|Warszawa
Podziękował: 6 razy
Pomógł: 160 razy

listy dwukierunkowe

Post autor: steal »

Sztuczne i zbędne zatrzymywanie pracy, które nie działa na każdej platformie. W dodatku z użyciem funkcji, która do tego nie służy.
Więc co zalecasz?
soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1823 razy

listy dwukierunkowe

Post autor: soku11 »

1. Odpalanie tego pod terminalem.
2. Przerzucenie się na IDE, które samo zatrzymuje na końcu program i czeka na klawisz.
3. Pobranie jakiegoś znaku ze standardowego wejścia (np. getchar()).

Pozdrawiam.
ODPOWIEDZ