13.7 — Wprowadzenie do konstrukcji, prętów i wyboru prętów

W programowaniu jest wiele przypadków, w których potrzebujemy więcej niż jednej zmiennej, aby przedstawić coś interesującego. Jak omawialiśmy we wstępie do poprzedniego rozdziału (12.1 — Wprowadzenie do złożonych typów danych), ułamek ma licznik i mianownik połączone w jeden obiekt matematyczny.

Alternatywnie, powiedzmy, że chcemy napisać program, w którym będziemy przechowywać informacje o pracownikach firmy. Możemy być zainteresowani śledzeniem atrybutów, takich jak imię i nazwisko pracownika, stanowisko, wiek, identyfikator pracownika, identyfikator menedżera, wynagrodzenie, urodziny, data zatrudnienia itp.

Gdybyśmy mieli użyć niezależnych zmiennych do śledzenia wszystkich tych informacji, mogłoby to wyglądać mniej więcej tak:

std::string name;
std::string title;
int age;
int id;
int managerId;
double wage;
int birthdayYear;
int birthdayMonth;
int birthdayDay;
int hireYear;
int hireMonth;
int hireDay;

Jednak istnieje wiele problemów z tym podejściem. Po pierwsze, nie jest od razu jasne, czy te zmienne są rzeczywiście powiązane, czy nie (trzeba przeczytać komentarze lub zobaczyć, jak są używane w kontekście). Po drugie, istnieje teraz 12 zmiennych, którymi należy zarządzać. Gdybyśmy chcieli przekazać tego pracownika do funkcji, musielibyśmy przekazać 12 argumentów (w odpowiedniej kolejności), co spowodowałoby bałagan w naszych prototypach funkcji i wywołaniach funkcji. A skoro funkcja może zwrócić tylko jedną wartość, jak w ogóle mogłaby zwrócić pracownika?

A gdybyśmy chcieli mieć więcej niż jednego pracownika, musielibyśmy zdefiniować 12 dodatkowych zmiennych dla każdego dodatkowego pracownika (z których każdy wymagałby unikalnej nazwy)! To najwyraźniej w ogóle nie ma skali. Tak naprawdę potrzebujemy sposobu na zorganizowanie wszystkich powiązanych ze sobą fragmentów danych, aby ułatwić zarządzanie nimi.

Na szczęście w C++ dostępne są dwa typy złożone zaprojektowane z myślą o rozwiązywaniu takich problemów: struktury (które teraz przedstawimy) i klasy (które omówimy wkrótce). A struct (skrót od structure) to zdefiniowany przez program typ danych (13.1 -- Wprowadzenie do typów zdefiniowanych przez program (zdefiniowanych przez użytkownika)), który pozwala nam połączyć wiele zmiennych w jeden typ. Jak wkrótce się przekonasz, znacznie upraszcza to zarządzanie powiązanymi zestawami zmiennych!

Przypomnienie

Struktura jest typem klasy (podobnie jak klasy i związki). W związku z tym wszystko, co dotyczy typów klas, dotyczy również struktur.

Definiowanie struktur

Ponieważ struktury są typem zdefiniowanym w programie, najpierw musimy powiedzieć kompilatorowi, jak wygląda nasz typ struktury, zanim będziemy mogli go używać. Oto przykład definicji struktury dla uproszczonego pracownika:

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

Klasa struct słowo kluczowe służy do poinformowania kompilatora, że ​​definiujemy strukturę, której nadaliśmy nazwę Employee (ponieważ typy zdefiniowane w programie mają zazwyczaj nazwy rozpoczynające się z dużej litery).

Następnie w nawiasach klamrowych definiujemy zmienne, które będzie zawierać każdy obiekt Pracownik. W tym przykładzie każda utworzona przez nas Employee będzie miała 3 zmienne: an int id, an int age i a double wage. Zmienne wchodzące w skład struktury nazywane są elementami danych (lub zmiennymi składowymi).

Wskazówka

W języku potocznym member to jednostka należąca do grupy. Na przykład możesz być członkiem drużyny koszykówki, a twoja siostra może być członkinią chóru.

W C++ instrukcja member to zmienna, funkcja lub typ należący do struktury (lub klasy). Wszystkie elementy muszą być zadeklarowane w definicji struktury (lub klasy).

Będziemy często używać terminu member , więc pamiętaj, co on oznacza.

Podobnie jak używamy pustego zestawu nawiasów klamrowych do inicjowania wartości (1.4 — Przypisywanie zmiennych i inicjalizacja) normalnych zmiennych, puste nawiasy klamrowe po każdej zmiennej składowej zapewniają że zmienne składowe wewnątrz naszego Employee są wartością inicjowaną, gdy Employee został utworzony. Porozmawiamy o tym więcej, gdy w kilku lekcjach omówimy domyślną inicjalizację elementu członkowskiego (13.9 — Domyślna inicjalizacja elementu członkowskiego).

Na koniec definicję typu zakończymy średnikiem.

Dla przypomnienia, Employee to tylko definicja typu — w tym momencie nie są tworzone żadne obiekty.

Definiowanie obiektów strukturalnych

Aby użyć typu Employee , po prostu definiujemy zmienną type Employee:

Employee joe {}; // Employee is the type, joe is the variable name

Definiuje zmienną typu Employee nazwany joe. Po wykonaniu kodu tworzona jest instancja obiektu Employee zawierającego 3 elementy danych. Puste nawiasy klamrowe zapewniają inicjalizację wartości obiektu.

Tak jak w przypadku każdego innego typu, możliwe jest zdefiniowanie wielu zmiennych tego samego typu struktury:

Employee joe {}; // create an Employee struct for Joe
Employee frank {}; // create an Employee struct for Frank

Członkowie dostępu

Rozważ następujący przykład:

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

int main()
{
    Employee joe {};

    return 0;
}

W powyższym przykładzie nazwa joe odnosi się do całego obiektu struktury (który zawiera zmienne składowe). Aby uzyskać dostęp do określonej zmiennej składowej, używamy operatora wyboru elementu (operator.) pomiędzy nazwą zmiennej struktury a nazwą składową. Na przykład, aby uzyskać dostęp do elementu wiek Joego, użylibyśmy joe.age.

Zmienne składowe Struct działają tak samo jak zwykłe zmienne, więc można na nich wykonywać normalne operacje, w tym przypisywanie, arytmetykę, porównania itp....

#include <iostream>

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

int main()
{
    Employee joe {};

    joe.age = 32;  // use member selection operator (.) to select the age member of variable joe

    std::cout << joe.age << '\n'; // print joe's age

    return 0;
}

Wypisuje:

32

Jedną z największych zalet struktur jest to, że dla każdej zmiennej struktury wystarczy utworzyć tylko jedną nową nazwę (nazwy elementów są stałe w ramach definicji typu struktury). W poniższym przykładzie tworzymy dwa Employee obiekty: joe i frank.

#include <iostream>

struct Employee
{
    int id {};
    int age {};
    double wage {};
};

int main()
{
    Employee joe {};
    joe.id = 14;
    joe.age = 32;
    joe.wage = 60000.0;

    Employee frank {};
    frank.id = 15;
    frank.age = 28;
    frank.wage = 45000.0;

    int totalAge { joe.age + frank.age };
    std::cout << "Joe and Frank have lived " << totalAge << " total years\n";

    if (joe.wage > frank.wage)
        std::cout << "Joe makes more than Frank\n";
    else if (joe.wage < frank.wage)
        std::cout << "Joe makes less than Frank\n";
    else
        std::cout << "Joe and Frank make the same amount\n";

    // Frank got a promotion
    frank.wage += 5000.0;

    // Today is Joe's birthday
    ++joe.age; // use pre-increment to increment Joe's age by 1

    return 0;
}

W powyższym przykładzie bardzo łatwo jest stwierdzić, które zmienne składowe należą do Joe, a które do Franka. Zapewnia to znacznie wyższy poziom organizacji niż pojedyncze zmienne. Co więcej, ponieważ elementy Joe i Franka mają te same nazwy, zapewnia to spójność, gdy masz wiele zmiennych tego samego typu struktury.

Będziemy kontynuować eksplorację struktur w następnej lekcji, w tym przyjrzymy się, jak je inicjować.

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
751 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze