Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Czy dobrze skomentowałem (rozumiem) kod listy jednokierunkowej

Ostatnio zmodyfikowano 2016-05-06 23:07
Autor Wiadomość
locf
Temat założony przez niniejszego użytkownika
Czy dobrze skomentowałem (rozumiem) kod listy jednokierunkowej
» 2016-05-06 20:14:30
Witam ponownie

Uczę się teraz listy jednokierunkowej. Wskażniki też dopiero co "opanowałem".
Na jednej ze stron znalazłem ciekawe wytłumaczenie zagadnienia list jednokierunkowych, które jest częściowo skomentowane.
Ja sobie do każdej linii kodu dodałem swój komentarz, tylko nie wiem, czy prawidłowo rozumiem poszczególne instrukcje.
Prośba do Was, byście rzucili okiem i ewentualnie poprawili/ wyprowadzili mnie z błędu, jeśli skomentowałem coś nie tak jak trzeba.

C/C++
struct slistEl
{
    slistEl * next;
    typ_danych data;
};

Tworzę strukturę typu
slistEl
, której polami są zmienna
next
, będąca wskaźnikiem do pokazywania na zmienne strukturalne typu
slistEl
. Drugim polem jest zmienna
data
 typu
typ_danych
.


C/C++
while( p )
{
    ...
    p = p->next;
}
Wykonuj pętlę dopóki kolejne elementy listy nie zawierają w swoim polu
next
 znaku
NULL
.

Kod
p = p->next
oznacza, że za nową wartość zmiennej
p
 przyjmij adres następnego elementu listy, który jest przechowywany w polu
next
 tej zmiennej
p
, dlatego zmienna
p
 jest nadpisana adresem zawartym w polu
next
 
C/C++
unsigned l_size( slistEl * p )
{
    unsigned c = 0; // zerujemy licznik
   
    while( p )
    {
        c++; // zwiększamy licznik o 1
        p = p->next;
    }
   
    return c;
}

Ten kod różni się od poprzednich tylko tym, że mamy zliczyć ilość elementów listy, więc za każdym obiegiem pętli wzrasta wyzerowany licznik, który jest zmienną
c


Dołączanie nowego elementu na początek listy

C/C++
void l_push_front( slistEl * & head, char v )
{
    slistEl * p = new slistEl;
   
    p->data = v; // inicjujemy element
    p->next = head;
    head = p;
}

Mam funkcję, która ma dwa argumenty. Jeden to zmienna
v
 typu
char
, drugi to zmienna
head
 przyjmowana przez referencję. Czyli chodzi o to, że zmienna
head
 może być zmieniona?

Instrukcja
slistEl * p = new slistEl;

oznacza, że operator
new
 znajduje odpowiednią liczbę bajtów na nienazwany obiekt danych typu
slistEl
, zwraca ten adres i przypisuje go do zmiennej
p
, która jest wskaźnikiem do pokazywania na zmienne typu
slistEl
. Czyli wskaźnik
p
 pokazuje na adres przypisany nienazwanemu obiektowi danych typu
slistEl

Kod
C/C++
p->data = v

oznacza, że w polu
data
 nowozalokowanego (nowoutworzonego) obiektu danych typu
slistEl
 wpisuję daną
v

 
Kod
C/C++
p->next = head

W polu
next
 nowozalokowanego obiektu danych typu
slistEl
 wpisuję adres przechowywany przez zmienną
head
. Czyli teraz głowa nie pokazuje już na następny element listy, lecz na ten nowozalokowany obiekt danych typu
slistEl


head = p

W zmiennej
head
 w polu
next
 umieszczam adres nowozalokowanego obiektu danych typu
slistEl
, na który wskazuje wskaźnik
p
, dlatego muszę
head
 nadpisać zawartością wskaźnika
p
, dzięki czemu zmienna
head
 jest „połączona” nowoutworzonym obiektem typu
slistEl


Algorytm usuwania elementu z początku listy jednokierunkowej
Tutaj się trochę pogubiłem na początku, więc co do poniższego komentarza mam największe wątpliwości

C/C++
void l_pop_front( slistEl * & head )
{
    slistEl * p;
    p = head;
    if( p )
    {
        head = p->next;
        delete p;
    }
}


slistEl * p;
oznacza, że zmienna
p
 jest wskaźnikiem do pokazywania na zmienne strukturalne typu
slistEl

p = head;
tutaj chyba zmienna
p
 staje się zmienną
head
, więc zmienna
p
 „robi” tymczasowo za głowę?
Czyli przypisuję wskaźnikowi
p
 adres zmiennej
head
, więc teraz wskaźnik
p
 zawiera adres zmiennej
head
, bo zmienna
head
 jest przekazywana przez referencję (&)?
Ona jest tylko po to, by zachować ciągłość?

Tutaj to przypisanie adresu zmiennej
head
 ma chyba charakter tymczasowy (pomocniczy)?

C/C++
if( p )
jeśli w polu
next
 zmiennej
p
, która wskazuje na zmienną
head
, nie ma wartości
NULL
, to wykonuję
if

head = p->next;

W zmiennej
p
 umieszczam zawartość pola
next
 usuwanego elementu, czyli zmienna
head
 wskazuje już na element następny po elemencie usuwanym


delete p

usuwam zmienną
p
P-147985
carlosmay
» 2016-05-06 22:13:21
Ogólnie sens jest złapany.

Zmieniłbym zliczanie elementów na zmienną statyczną:
- inkrementował przy dodawaniu elementu do listy.
- dekrementował przy usuwaniu z listy.
- funkcję (metodę) zwracającą wartość tej zmiennej
C/C++
unsigned l_size()
{
    return c;
}
P-147997
locf
Temat założony przez niniejszego użytkownika
» 2016-05-06 23:07:31
dzięki
P-147998
« 1 »
  Strona 1 z 1