Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Rekomendowane odpowiedzi

Opublikowano

Struktury

 

Przypuśćmy, że chcesz zrobić sobie komputerową książkę adresową. W tej książce mają się znajdować informacje o każdym twoim kumplu: jego imię, nazwisko, adres i telefon. Jednak adres i na przykład numer telefonu to właściwie różne typy danych, powiązane ze sobą jedynie tym, że opisują jedną osobę. Jednak dużo lepiej by było mieć tego "qmpla" jako całość, a nie rozrzucone po RAMie zmienne, prawda? Właśnie do tego wymyślono struktury. Struktura łączy w sobie kilka mogących się różnić typów danych, związanych ze sobą w jakiś logiczny sposób, oraz co najważniejsze pozwala odwoływać się do nich jako do całości. Przykładowa struktura opisująca naszego kumpla mogłaby wyglądać tak:

 

 

 

struct Kumpel {

char Imie[20];

char Nazwisko[30];

char Adres[40];

int Telefon;

};

 

 

 

 

Zauważ, że deklaracja struktury kończy się średnikiem! Tak samo jak deklaracja zwykłej zmiennej. Widać wyraźnie, że w strukturze zawarte są cztery zmienne [tak zwane pola]. Jednak zmienne takie nie istnieją jeszcze w pamięci, bo struktura jest tylko definicją nowego typu zmiennej, który zwie się w tym przypadku Kumpel. Konkretną zmienną typu Kumpel trzeba dopiero utworzyć. Na przykład tak:

 

 

 

Kumpel gostek;

 

 

 

 

Od dzisiaj gostek jest twoim kumplem ;-). Jak widzisz, struktura rzeczywiście wygląda jak nowy typ danych, bo można z jego pomocą deklarować nowe zmienne. Ale podobnie jak każda inna zmienna tuż po zadeklarowaniu, struktura zawiera przypadkowe dane. Taki gostek nie ma jeszcze imienia, ani nazwiska, ani nawet nigdzie nie mieszka... Trzeba zainicjować strukturę odpowiednimi wartościami podczas deklaracji zmiennej, w podobny sposób jak z tablicą:

 

 

 

Kumpel gostek = {"Franek","Łopata","Wygwizdowo, ul.Błotna 4",8425523};

 

 

 

 

Drugim sposobem jest ustawienie każdego pola struktury z osobna. Ale jak się odwoływać do pól struktury? Służy do tego kropka. Najpierw pisze się nazwę zmiennej typu strukturowego, daje się kropkę i dopiero nazwę pola struktury. No więc wypełnimy strukturę gostek w taki właśnie sposób:

 

 

 

Kumpel gostek;

gostek.Imie = "Franek";

gostek.Nazwisko = "Łopata";

gostek.Adres = "Wygwizdowo, ul.Błotna 4";

gostek.Telefon = 8425523;

 

 

 

 

Przypomina to trochę wypełnianie formularza. Pola struktury możemy później w programie dowolnie modyfikować, odwołując się do nich przy pomocy kropki, tak jak powyżej. Aby teraz zrobić książkę adresową, trzeba po prostu zmontować tablicę, której elementami będą struktury typu Kumpel.

 

 

 

Kumpel kumple[100];

 

 

 

 

Jak widzisz, struktura jest pełnoprawnym typem danych, a więc można też z niego zbudować tablicę. Jeśli teraz chcesz sprawdzić, kto jest na piątym miejscu tablicy, robisz to tak:

 

 

 

cout << kumple[4].Nazwisko;

 

 

 

 

Najpierw wybierasz, który Kumpel [który element tablicy, będący strukturą] ma coś powiedzieć o sobie. Wyrażenie kumple[4] zostaje "zastąpione" strukturą, która jest w tym miejscu tablicy, więc teraz wystarczy odwołać się do jednego z pól tej struktury przy pomocy kropki i nazwy pola. Banał, no nie? ;-)

 

Jaki rozmiar w pamięci ma nasza struktura Kumpel? Pomyśl. Mamy trzy tablice typu char przechowujące tekst, o rozmiarach kolejno 20 bajtów, 30 bajtów i 40 bajtów. Do tego dochodzą cztery bajty na liczbę int przechowującą numer telefonu. Czyli razem powinno być 94 bajty. Czy rzeczywiście tak jest? Możemy to łatwo sprawdzić, posługując się operatorem sizeof. Używa się go podobnie jak funkcji, a zwraca nam on wielkość obiektu wyrażoną w bajtach. Sprawdźmy więc:

 

 

 

cout << sizeof(Kumpel);

 

 

 

 

Możemy sprawdzić wielkość typu, lub zmiennej, na jedno wychodzi. I co? Zgadza się? Możliwe że wynik wyszedł nieco inny, różniący się nawet do trzech bajtów. Dlaczego? Niektóre 32-bitowe kompilatory wyrównują pola struktury do 32 bitów. I tak na przykład pierwszy napis składa się z 20 bajtów, czyli 5 paczek po 32 bity. Ale już drugi napis to 30 bajtów, a więc brakuje jeszcze dwóch, by rozmiar był podzielny przez 4 bajty [32 bity]. Kompilator wyrówna więc to pole o te 2 bajty, bo dzięki temu będzie mógł traktować każdą komórkę tablicy jako wartość 32-bitową, a procesor 32-bitowy operuje szybciej na takich liczbach. Na codzień nie będzie ci zbytnio potrzebna ta wiedza, ale jeśli będziesz o tym pamiętać, to cię nie zaskoczy inny rozmiar niż przewidywany ;-).

 

Struktury przydają się do różnych zastosowań. Pierwszym z nich są, jak widzisz, bazy danych. Ale na tym nie koniec. Struktura może też określać budowę nagłówka jakiegoś pliku, na przykład BMP. Struktura może zawierać wskaźniki, nawet takie które pokazują na inne struktury tego samego typu, co pozwala na budowanie różnych konstrukcji programistycznych, takich jak listy, drzewa, kolejki, stosy, i wiele innych. Możesz użyć struktury do przechowywania informacji o elementach mapy w twojej grze, albo o parametrach jakiejś postaci. Zastosowań jest naprawdę bez liku, wystarczy tylko pomyśleć i jakieś sobie znaleźć ;-).

 

W tej lekcji narazie jeszcze nie napiszemy książki adresowej, bo nie znasz funkcji bibliotecznych do operacji na napisach. Omówię je w jednej z kolejnych lekcji i tam też napiszemy sobie taką "bazę danych".

×
×
  • Dodaj nową pozycję...