Jesli ktos z was zna jakis artykul z ktorego moge dowiedziec sie wiecej o liscie podczepianej i nauczyc sie ja tworzyc to poprosilbym o link, najlepiej do artykulu po polsku jesli nie to po angielsku.I mam tez pytanie czy lista podczepiana to to samo co rekursywna ?
nie spotkalam sie z okresleniem lista podczepiana (ani rekursywna...). byc moze chodzi ci o liste jednokierunkowa/dwukierunkowa i cykliczna? http://pl.wikipedia.org/wiki/Lista
No i Spartan pomyliles sie, mowiles ze po przeczytaniu tego wszystko stanie sie dla mnie jasne, przeczytalem 2 razy i nic nie jest dla mnie jasne, program z twojego linku jest inny niz ten z tego kodu:
#include <stdio.h>
#include <stdlib.h>
typedef struct element {
struct element *next;
unsigned long val;
} el_listy;
el_listy *first; /* To jest wskaznik first na strukture el_listy tak ? */
void dodaj_do_listy (el_listy *lista, unsigned long liczba)
{
el_listy *wsk, *nowy;
wsk = lista;
while (wsk->next != NULL)
{
wsk = wsk->next; /* Nie rozumiem jak dziala przesuwanie wskaznika, z tego co mysle to "wsk" to jest to el_listy *first tak ? a wiec jak to dziala el_listy *first = *wsk.next ? prosilbym o wyjasnienie jak dziala tutaj to przesuwanie. */
}
nowy =(el_listy*) malloc (sizeof(el_listy));
nowy->val = liczba;
nowy->next = NULL;
wsk->next = nowy;
}
void wypisz_liste(el_listy *lista)
{
el_listy *wsk=lista;
while( wsk != NULL )
{
printf ("%lu\n", wsk->val);
wsk = wsk->next;
}
}
int jest_pierwsza(el_listy *lista, int liczba)
{
el_listy *wsk;
wsk = lista;
while (wsk != NULL) {
if ((liczba%wsk->val)==0) return 0;
wsk = wsk->next;
}
return 1;
}
int main ()
{
unsigned long i = 3;
const unsigned long END = 1000;
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2; /* i tutaj te dwie linijki, ta i ta pod spodem z nextem... ten first->val i first-> next to bedzie to "wsk" uzywane w funkcjach tak ? w takim razie ktora ma wartosc */
first->next = NULL;
for (;i!=END;++i) {
if (jest_pierwsza(first, i))
dodaj_do_listy (first, i);
}
wypisz_liste(first);
return 0;
}
Przeczytalem ale dalej nie rozumiem jak dziala to przesuwanie wskaznika, moglby ktos przetlumaczyc mi to wyrazenie "wsk = wsk->next" ? nie rozumiem tego wyrazenia prosilbym o tlumaczenie oraz o co chodzi z tym pierwszym elementem, i wgl o co chodzi najpierw next ma wartosc null a w pierwszej funkcji program zawziecie wyszukuje wartosci null nexta, nie rozumiem w cale, link mi nic nie wyjasnia, prosilbym o dodatkowe wyjasnienia.
Moglby ktos pomoc mi to zrozumiec ?
Czego nie rozumiesz? Przeczytales zawartosc linka ktorego ci dalam?
Tak i tego i tego co dal spartan nic mi nie swita, wkleje tutaj caly kod i wypisze czego dokladnie nie rozumiem
#include <stdio.h>
#include <stdlib.h>
typedef struct element {
struct element *next;
unsigned long val;
} el_listy;
el_listy *first; /* I co to jest wskaznik na cala strukture el_listy, i ma wartosc 2 tak ? bo potem bedzie first->val=2, czyli el_listy *first na poczatku ma wartosc 2 czy NULL jak next ? To pierwsza rzecz teraz w drugiej kolejnosci opisywania moich niejasnosci przejde do funkcji main. */
void dodaj_do_listy (el_listy *lista, unsigned long liczba)
{
el_listy *wsk, *nowy;
wsk = lista;
while (wsk->next != NULL)
{
wsk = wsk->next; /* Tutaj nie wiem po co to juz wgl, bo w funkcji jest_pierwsza wskaznikowi dalismy juz wartosc NULL tak ?*/
}
nowy =(el_listy*) malloc (sizeof(el_listy));
nowy->val = liczba; /* jesli dodamy liczbe do nowy.val bedzie ona zmieniona automatycznie w first.val ? Pozatym jak jedna zmienna "val" w strukturze el_listy przechowuje tyle liczb ? W ostatniej funkcji mam te same problemy co w tych.*/
nowy->next = NULL;
wsk->next = nowy;
}
void wypisz_liste(el_listy *lista)
{
el_listy *wsk=lista;
while( wsk != NULL )
{
printf ("%lu\n", wsk->val);
wsk = wsk->next;
}
}
int jest_pierwsza(el_listy *lista, int liczba)
{
el_listy *wsk; /* tutaj el_listy *first = el_listy *wsk - tak ? */
wsk = lista;
while (wsk != NULL) { /* i tutaj mam problem bo nie wiem jaka wartosc ma ten el_listy *wsk, jesli NULL to po co ten while */
if ((liczba%wsk->val)==0) return 0;
wsk = wsk->next; /* a tego kompletnie nie rozumiem, jak dziala to przesuwanie, ale opisze jak ja to widze i prosilbym o poprawe, wiec:
wsk = wsk->next wydaje mi sie ze jest rownowazne z: el_listy *wsk = el_listy *wsk->next - tak czy nie ? no bo teraz przypisalismy chyba wartosc NULL do "wsk" tak ? Chyba zadego przesuwania tu nie bylo tylko nadanie wsk wartosci NULL ktora ma next, tak ? teraz do funkcji dodaj_do_listy */
}
return 1;
}
int main ()
{
unsigned long i = 3;
const unsigned long END = 1000;
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2; / * tutaj first.val = 2 i first.next = NULL, a wiec el_listy *first jaka ma wartosc ? Oraz *first to byl wskaznik na strukture el_listy i teraz jest przekazywany nie jako wskaznik ale samo first do funkcji "jest_pierwsza" "dodaj_do_listy" oraz "wypisz_liste" tak ? I teraz chcialbym przejsc do funkcji "jest_pierwsza".*/
first->next = NULL;
for (;i!=END;++i) {
if (jest_pierwsza(first, i))
dodaj_do_listy (first, i);
}
wypisz_liste(first);
return 0;
}
Okej opisalem jak najlepiej umialem, bylbym b.wdzieczny za rzetelna pomoc i objasnienie.
Moze ktos cos jednak ?
Bo Ty w ogólnie nie rozumiesz jak działa( a przynajmniej ma działać ) taka lista.
To po kolei.
Hm, pare piw i szlugi jescze mi zostały, to co mi tam, napisze coś dłuższego.
el_listy *first;
To wskaźnik na pierwszy element, czyli korzeń listy, od niego cała lista sie zaczyna, musimy wiedzieć gdzie jest początek, inaczej dostęp do listy byłby niemożliwy.
W funkcji main alokujesz przestrzeń dla tego jednego, konkretnego, korzeniowatego elementu, on jest początkiem, a dzieje sie to tutaj
first =(el_listy*) malloc (sizeof(el_listy));
first->val = 2;
Tutaj natomiast przypisujesz korzeniowi wartość dwa (Uprzedzam pytanie, to nie jest właściwość listy że pierwszy element zawsze jest dwójką, po prostu taki program przekleiłeś, co szuka liczb pierwszych, pierwsza z liczb pierwszych to dwójeczka.)
first->next = NULL;
Tutaj, ustawiamy wskaźnik na następny element na NULL
, w praktyce oznacza to że nasz korzeń nie ma "przed sobą" nic, jest smutny i sam ( Ten wariant listy nie może "patrzyć" za siebie, jedynie w przód )
No to jedziemy dalej, tutaj for (;i!=END;++i)
szukamy sprawdzamy liczby od i
do END
(Czy są pierwsze).
Tutaj if (jest_pierwsza(first, i))
, sprawdzamy pierwszość, to chyba rozumiesz, a przesuwanie wygląda tak:
(Posłuże sie rysowaniem pokeboli :D, ten upośledzony inny pokebol to korzeń)
Czyli while (wsk != NULL)
sprawdza czy aktualnie wskazywany pokebol nie jest ostatnim pokebolem, jeśli nie ma za nim innych, to jest.
Natomiast wsk = wsk->next;
przesuwa poke-wskaźnik na następny element listy, i są to te strzałki na obrazku.
W przypadku jak zrozumiesz zrób taniec radości przy tym
Tak, wiem ze struct element *next to nastepny element a struct element *first to element pierwszy, nazwy sa mocno sugestywne, ale nie rozumiem dlaczego nimi sa, przeciez rownie dobrze nastepny element moglibysmy nazwac struct element *asdasdasd i to tez bylby nastepne a pierwszy moglby byc struct element *nananana i to tez bylby pierwszy, a wiec dlaczego one oznaczaja to co oznaczaja ? dlatego ze w strukturze stworzymy wskaznik na ta strukture to on automatycznie bedzie nastepnym jej elementem ?
Wyraźnie napisałem Ci to wyżej.
Musisz znać pierwszy element, powiedz mi w takim razie, jak chciałbyś przeiterować (przelecieć, przejść się, whateva) po liscie bez informacji gdzie ta lista sie zaczyna?
przesuwania nie rozumiem, next dostalo wartosc NULL to po co przesuwac skoro next ma wartosc null ciagle ;c
Nie ciągle. NULLa ma na samym końcu, jest to swoisty wyznacznik końca listy.
Rada na przyszłość: jeśli nie rozumiesz jakiegoś zagadnienia, algorytmu, czegokolwiek -
weź kartkę, długopis i na podstawie kodu źródłowego wykonuj odpowiednie kroki.
Ale w main od razu dajemy next wartosc null a przeciez next w sobie powinno miec adres struktury element chyba ? a wiec next ma w sobie adres do struktury element i przypisujemy mu wartosc null... nie rozumiem poza tym jak el_listy *first wskazuje na 1 element first wskazuje chyba na adres pamieci
Jest tam NULL
bo jescze wtedy ten węzeł nie ma następcy.
Powiedz mi czy po pierwszym wywołaniu dodaj_do_listy
dalej tam będzie NULL
?
Chwila, w dodaj_do_listy tworzymy nowy element i do obiektu val nowego elementu wpisujemy wartosc nowej liczby pierwszej a do elementu next wartosc null, ale wsk->next juz ma wartosc nowego elementu, a ten nowy element ma w sobie val o wartosci nowej liczby i next o wartosci null tak ?
Powiedzmy.
A potrafisz wyjaśnić dlaczego w nowym elementcie do next
przypisujemy NULL
?
BTW. Czy Ty jesteś studentem?
while (wsk->next != NULL)
{
wsk = wsk->next; /* przesuwamy wsk aż znajdziemy ostatni element */
}
Przy pierwszym odwiedzeniu tego while'a wsk mialo wartosci val=2 i next=null wiec nie trzeba bylo przesuwac i przeszlo dalej, poszlismy dalej do wsk->next zostaly wprowadzone wartosci val=nowa pierwsza liczba i next->null, gdy drugi raz odwiedzamy ten while, wsk ma wartosci: val=2 i next=gdzie val=nowa liczba i next nexta=null, wiec przypisujemy wsk wartosc val znajdujacej sie w next i petla wykonuje sie znowu a teraz wsk ma juz w val wartosc val=nowa liczba i next=null, i petla sie konczy i wchodzimy znowu tam gdzie przypisujemy wsk->next nowa liczbe, potem znowu szukamy nastepnej liczby i znowu odwiedzamy while teraz nasz wsk ma tak jak wtedy wartosc val=2 i next=ktory ma wartosc val=druga z kolei liczba pierwsza a next nie ma wartosci null(tylko wartosc val=trzecia liczba pierwsza i next=null) wiec przypisujemy wsk wartosc val=druga liczba pierwsza i next=val=trzecia liczba pierwsza i next=null i wykonujemy znowu, teraz wsk ma wartosc val=druga(liczba pierwsza) i next= val=trzecia liczba i next =null czyli przypisujemy wsk ta wartosc i wchodzimy znowu, teraz wsk ma wartosc val=trzecia liczba pierwsza i next=null i petla sie konczy, Troche dlugo to opisalem ale dobrze czy zle ? ;p
btw.nie jestem.
Lista boli tylko za pierwszym razem.
Dorób do tego unit testy to wszystko wyjdzie.
- dodanie n elementów i sprawdzenie liczby elementów
- dodanie na początku, na końcu, w środku
- usunięcie na początku, na końcu, w środku
- odczytanie pierwszego, ostatniego, n-tego elementu
Frameworki do testowania w C (nie testowałem ich):
- MinUnit: http://www.jera.com/techinfo/jtns/jtn002.html
- Check: http://check.sourceforge.net/
- CUnit: http://cunit.sourceforge.net/
- CMocka: https://cmocka.org/
- CuTest: http://cutest.sourceforge.net/
- CppUTest: http://cpputest.github.io/
- cmockery: https://code.google.com/p/cmockery/
Pewnie ktoś kto programuje (więcej) w C będzie mógł podać coś konkretniej.
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.