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

[C++] Wskaźniki i adresy, działania na strukturach.

Ostatnio zmodyfikowano 2016-01-10 13:46
Autor Wiadomość
Kordian
Temat założony przez niniejszego użytkownika
[C++] Wskaźniki i adresy, działania na strukturach.
» 2016-01-10 00:27:09
Witam, jestem dopiero raczkującym programistą i pisanie programów to dla mnie ogromny problem. Dysponuję bardzo niewielkim doświadczeniem w tym zakresie i pewnych rzeczy jeszcze nie rozumiem. Oto zadanie, które mam do wykonania:

Zdefiniuj strukturę Czlowiek, zawierająca następujące informacje: Numer
pesel (przypuśćmy, że jest to pięciocyfrowa liczba całkowita) Ulubiony
samochód Zapasowy samochód.
Moja odpowiedź:
C/C++
struct Czlowiek {
    int pesel;
    Samochod * zapasowy;
    Samochod * ulubiony;
};
Struktura Samochod oraz funkcja tworząca nowe samochody o parametrach danych wczesniej w zadaniu(prędkość losowa 60-100km/h, losowy numer rejestracyjny 4-liczbowy):
C/C++
struct Samochod
{
    int numer;
    int przebieg;
    double predkosc;
    bool sprawny;
};
Samochod losuj_samochod()
{
    Samochod s;
    s.numer = rand() % 9000 + 1000;
    s.sprawny = true;
    s.przebieg = 0;
    s.predkosc = 40.0 * rand() / RAND_MAX + 60;
   
    return s;
}
Pytanie brzmi jak wykonać następującą część polecenia:
Stwórz czlowieka o losowym numerze PESEL, którego ulubionym samochodem
jest samochód stworzony w punkcie 4, a zapasowym - nowy, losowy
samochód. Wypisz.

Mój kod, który jest błędny z bliżej nie znanych mi powodów:
C/C++
Czlowiek c1 = {
    c1.pesel = rand() / 90000 + 10000;
    c1.ulubiony = & s1;
    c1.zapasowy = losuj_samochod();
}
Gdzie s1 to samochód stworzony przy pomocy funcki losuj_samochod podanej powyżej. W skrócie: po co działam na adresie &s1 oraz dlaczego zapis c1.zapasowy=losoj_samochod() jest nieprawidłowy? Nie mam pojęcia, dlaczego powinno być inaczej, potrzebuję pomocy kogoś o większym doświadczeniu.
P-143246
carlosmay
» 2016-01-10 01:43:57
W skrócie: po co działam na adresie &s1 oraz dlaczego zapis c1.zapasowy=losoj_samochod() jest nieprawidłowy?
Niezgodność typów: Samochod* to nie to samo co Samochod .
Ponieważ składowe ulubione i zapasowe są wskaźnikami nie można do nich przypisać wprost wartości.
Wskaźniki operują na adresach więc przypisuje się do nich adresy, stąd to &s1 .
Podobnie jest z funkcją. Zwraca ona wartość, a żeby można było zwrot przypisać do wskaźnika powinna zwrócić wskaźnik.
Żeby nie było zbyt prosto obiekt tworzymy w funkcji dynamicznie i pamiętamy o zwolnieniu zasobów na koniec.
P-143248
Kordian
Temat założony przez niniejszego użytkownika
» 2016-01-10 12:07:26
Dziękuję za objaśnienie, trochę lepiej już rozumiem, ale napotkałem kolejny problem.
Wskaźniki operują na adresach więc przypisuje się do nich adresy, stąd to &s1 .
Przypisując do samochodu ulubionego adres, probując potem wypisać informacje o danym człowieku otrzymuję adres w postaci szesnastkowej, a chciałbym, żeby w konsoli wypisano informacje o samochodzie, do którego należy adres. Co powinienem zrobić? (Słyszałem o jakimś wyłuskiwaniu spod adresu, ale dokładnie nie wiem na czym to polega oraz jak podejść do problemu.)
P-143256
carlosmay
» 2016-01-10 12:14:04
Słyszałem o jakimś wyłuskiwaniu spod adresu
Dobry słuch.

Do wyłuskania wartości spod adresu należy użyć jeden z operatorów.
Bezpośredni operator wyłuskania '*' .
Pośredni operator wyłuskanie '->' (stosowany wobec składowych klas, struktur).
W niektórych przypadkach używa się jeszcze operatora '[]' .
P-143258
Kordian
Temat założony przez niniejszego użytkownika
» 2016-01-10 12:39:05
Czyli przy wypisywaniu informacji o moim czlowieku powinienem napisać:
C/C++
cout << "Ulubiony samochod: " <<* c1.ulubiony << endl;
Dobrze rozumiem? Uzywał operatora *, żeby dostać to, co kryje się pod adresem s1?
P-143259
carlosmay
» 2016-01-10 13:18:37
cout << "Ulubiony samochod: " <<( * c1.ulubiony ).przebieg << endl;
 

Czytelniejszy wydaje mi się zapis
cout << "Ulubiony samochod: " << c1.ulubiony->przebieg << endl;
 
P-143263
Kordian
Temat założony przez niniejszego użytkownika
» 2016-01-10 13:32:08
C/C++
cout << "Ulubiony Samochod: " << c->ulubiony.przebieg << endl;

Chyba coś nie gra: [Error] base operand of '->' has non-pointer type 'Czlowiek'

Nieistotne, już zauwazylem blad
P-143265
carlosmay
» 2016-01-10 13:46:38
 
Czytelniejszy wydaje mi się zapis
C/C++
cout << "Ulubiony samochod: " << c1.ulubiony->przebieg << endl;
 

znajdź różnicę:

C/C++
cout << "Ulubiony Samochod: " << c->ulubiony.przebieg << endl;
 
P-143267
« 1 »
  Strona 1 z 1