• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C++ listy powiązane - odwołanie się do elementu

Object Storage Arubacloud
0 głosów
758 wizyt
pytanie zadane 18 kwietnia 2019 w C i C++ przez Alucarddo Nowicjusz (210 p.)

Witam, jestem początkujący w programowaniu i im dalej tym większe schody się robią. Aktualnie staram się zrozumieć listy powiązane, nie do końca rozumiem jak działa wskaznik w tej funkcji, daje go bo trzeba na tę chwilę, reszte raczej rozumiem ale nie mam najmniejszego pojęcia jak teraz zrobić przykładowo 4 wrogów i odczytać ich statystyki. Pozdrawiam.

 

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <ctime>


using namespace std;

struct dane
{

    int mana;
    int hp;
    dane *nastepny;


};

dane *lista = NULL;


dane *tworzwroga()
{
    dane *przeciwnik = new dane;

    przeciwnik -> mana = 700;
    przeciwnik -> hp = 1400;
    przeciwnik -> nastepny = lista;
    lista = przeciwnik;
    return przeciwnik;





}







main()
{











}



 

1 odpowiedź

+1 głos
odpowiedź 18 kwietnia 2019 przez Szahid Pasjonat (20,930 p.)
wybrane 19 kwietnia 2019 przez Alucarddo
 
Najlepsza

Poprawiłem i okomentowałem kod. Jak masz jakieś wątpliwosci to pisz

#include <iostream>
#include <string>

 
using namespace std;
 
struct dane
{
 
    int mana;
    int hp;
    dane *nastepny;
 
 
};
 
dane *lista = nullptr; //dobrą praktyką jest uzywanie nullptr zamiast nula
 
 
void tworzwroga() // funkcja nie musi nic zwracac bo działa na wskażnikach, nie ma żadnej zmiennej lokalnej którą należałoby zwrócić
{
    dane *przeciwnik = new dane;
    // Jest  wyciek pamieci bo nigdzie nie dealokujesz tego co tutaj zaalokowałęś
 
    przeciwnik -> mana = 700;
    przeciwnik -> hp = 1400;
    przeciwnik -> nastepny = lista;
    lista = przeciwnik;
 
}
 
 
main()
{
    // taktworzysz 4 przecownikow
    tworzwroga();
    tworzwroga();
    tworzwroga();
    tworzwroga();

    auto indeks  = 1;

    while(lista!=nullptr)   // wyswietlasz do puki nie dojdziesz do konca listy czyli wezła będącego nullptr
    {
        cout<<"Dane przeciwnika nr "<<indeks<<endl;
        cout<<lista->hp<<endl;
        cout<<lista->mana<<endl;
        ++indeks;
        lista=lista->nastepny;

    }
    return 0;
}

 

komentarz 19 kwietnia 2019 przez Alucarddo Nowicjusz (210 p.)
Wielkie dzięki ! Myślałem że to będzie ten punkt w którym będę się jeszcze długo głowił co i jak, ale teraz rozumiem już prawie wszystko dzięki Twojej pomocy :>
komentarz 19 kwietnia 2019 przez Alucarddo Nowicjusz (210 p.)
W zasadzie mam jeszcze jedno pytanie. Jak działa ta funkcja ? to jest wskaznik funkcji na strukture "dane" ? Nie rozumiem tej części, a również chciałbym to zrozumieć :

dane *tworzwroga()

{

 

}
komentarz 19 kwietnia 2019 przez Szahid Pasjonat (20,930 p.)

Zgadza sie.  Jest to wskaznik na strukture dane ale już uzgodniliśmy ze   jest on tam zbedny i wystarczy void.


void tworzwroga() // funkcja nie musi nic zwracac bo działa na wskażnikach, nie ma żadnej zmiennej lokalnej którą należałoby zwrócić
{
    // elementy listy nazywane są wezłami, wezeł zawiera dane oraz wskaźnik na koleiny węzeł aby można było się iterować po liście
    dane *przeciwnik = new dane;  // alokujesz pamieć na nowy wezeł tzn tworzysz nowy węzeł gdzieś w pamięci
    // Jest  wyciek pamieci bo nigdzie nie dealokujesz tego co tutaj zaalokowałęś
  
    przeciwnik -> mana = 700; // ustawiasz atrybut nowo stworzonego węzła
    przeciwnik -> hp = 1400; // // ustawiasz atrybut nowo stworzonego węzła
    przeciwnik -> nastepny = lista; // dodałeś element na początek listy czyli aktualnie pierwszy węzeł będzie od teraz drugim z kolei, zaraz za nowo stworzonym węzłem
    lista = przeciwnik; // wskaźnik lista jest wskażnikiem na pierwszy element listy, a Ty dodałeś właśnie do niej nowy element czyli od teraz wskaźnik wskazuje właśnie na ten nowo dodany element
  
}

 

komentarz 19 kwietnia 2019 przez Alucarddo Nowicjusz (210 p.)
edycja 19 kwietnia 2019 przez Alucarddo

Okej :> w zasadzie wyciek pamięci oraz usuwanie przykładowo 3 elementu rozwiązałem tak, jest to w porządku ?

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <ctime>


using namespace std;
int x = 1;
int zwalniam;
int i=1;
struct informacje
{
    int polozenie_x;
    int polozenie_y;
    informacje *nastepny;



};

informacje *lista = nullptr;

void tworzwroga()
{


    int x = rand()%100+1;
    int y = rand()%100+1;
    informacje *przeciwnik = new informacje;
    przeciwnik -> polozenie_x = 0 + x;
    przeciwnik -> polozenie_y = 0 + y;
    przeciwnik -> nastepny = lista;
    lista = przeciwnik;
    if(zwalniam = 0)
    {
        delete przeciwnik;
    }

}

main()
{
    srand(time(NULL));
    tworzwroga();
    tworzwroga();
    tworzwroga();
    tworzwroga();
    tworzwroga();

    while (lista != nullptr)
    {
        cout << i << " element: " << endl;
        cout << lista -> polozenie_x << endl;
        cout << lista -> polozenie_y << endl;
        lista = lista -> nastepny;
        i++;
        x++;
        if (x == 3)
        {
            delete lista;
            lista = lista -> nastepny;
            i++;

        }
    }

    zwalniam = 0;

}

Ty przykładowo usunąłem 3 węzeł,  i dałem wskaźnik na kolejny. Jest to dobre rozwiązanie, czy nie bardzo?

 

Dzięki za poświęcony czas !

komentarz 19 kwietnia 2019 przez Szahid Pasjonat (20,930 p.)
edycja 19 kwietnia 2019 przez Szahid

Jest tu kikla błędów. Po pierwsze popełniłeś błąd nieuwagi w lini 35. Operator = to operator przypisania a == to operator porównia. Ten program nie wysypuje się ale nie działa. Jak to poprawisz to się wysypie i to Cię nakieruje nadalsze błędy. Swoja droga nie musisz implementować swojej listy tylko możesz użyć gotowej z biblioteki stl. To co próbujesz tutaj zaimplementować nazywa się forward_list. A jak  koniecznie chcesz to implementować sam to zobacz jak wygląda poprawnie zaimplementowana lista https://gitlab.com/mateusz.baczek1998/cv-adama/tree/master/List

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <ctime>
 
 
using namespace std;
int x = 1;
int zwalniam;
int i=1; // zmienne globalne to słaby pomysł a zmienna globalna o nazwie "i" to bardzo słaby pomysł :)
struct informacje
{
    int polozenie_x;
    int polozenie_y;
    informacje *nastepny;
 
 
 
};
 
informacje *lista = nullptr;
 
void tworzwroga()
{
 
 
    int x = rand()%100+1;
    int y = rand()%100+1;
    informacje *przeciwnik = new informacje;
    przeciwnik -> polozenie_x = 0 + x;
    przeciwnik -> polozenie_y = 0 + y;
    przeciwnik -> nastepny = lista;
    lista = przeciwnik;
    if(zwalniam = 0)  // jest to równowazne z if(0) czyli if(false) czyli nigdy się nie wykona
    {
        delete przeciwnik;  // nawet jak powyzszy warunek byłby poprawny to ta cześć itak sie nigdy nie wykona 
    }
 
}
 
main()
{
    srand(time(NULL));
    tworzwroga();
    tworzwroga();
    tworzwroga();
    tworzwroga();
    tworzwroga();
 
    while (lista != nullptr)
    {
        cout << i << " element: " << endl;
        cout << lista -> polozenie_x << endl;
        cout << lista -> polozenie_y << endl;
        lista = lista -> nastepny;
        i++;
        x++;
        if (x == 3)
        {
            delete lista; // usunales wskaznik na liste przez co nie możesz się odwoływać do jej elementów
            lista = lista -> nastepny; // i przez to tutaj wywala błąd bo próbujesz zrobić nullptr->następny
            i++;
 
        }
    }
 
    zwalniam = 0; // ustawiając to na 0 nie sprawisz że program skoczy w to  miejsce co napisałem że nigdy się nie wykona
 
}

 

komentarz 19 kwietnia 2019 przez Alucarddo Nowicjusz (210 p.)
Dzięki ! "zwalniam" domyślnie przyjmowało 0, robię takie głupoty że aż strach, trochę pozmieniałem i działa. Aktualnie chcę się nauczyć jak to wszystko działa dlatego robię listy sam :>
komentarz 19 kwietnia 2019 przez Szahid Pasjonat (20,930 p.)
Chodzi Ci o usuwanie w lini 61? W komentarzu masz napisane co zrobiłeś źle. Tzn usunąłeś wskźnik na pierwszy element i przez to straciłeś dostęp do pozostałych elementów.

Usuwanie np 3 elementu z 4 elementowej listy powinno wyglądać tak:

1 Iterujesz się do elementu który jest przed tym który chcesz usunąć. ( czyli w naszym przypadku drugi element)

2 Przypisujesz tymczasowemu wskaźnikowi adres elementu który jest za usuwanym elementem( w naszym przypadku adres czwartego elementu)

3 Usuwasz element ( w naszym przyppadku trzeci element)

4 Przypisujesz atrybutowi  następnego elementu  wartość ze wskaźnika tymczasowego( w naszym przypadku przypisujesz wskaźnik tymczasowy to atrubutu "następny", elementu drugiego)

Podobne pytania

0 głosów
1 odpowiedź 221 wizyt
pytanie zadane 10 maja 2020 w C i C++ przez SpoconyJelen Nowicjusz (120 p.)
0 głosów
1 odpowiedź 104 wizyt
pytanie zadane 24 października 2016 w PHP przez ShadoWs Bywalec (2,800 p.)
0 głosów
0 odpowiedzi 108 wizyt
pytanie zadane 6 stycznia 2019 w C# przez kamkow8 Początkujący (340 p.)

92,632 zapytań

141,502 odpowiedzi

319,883 komentarzy

62,015 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...