[Powered by Google Translate] Porozmawiajmy o elemencie.
Kodowanym nam sposób na grupy kilka zmiennych razem
w ładnym opakowaniu.
To chyba najłatwiej zobaczyć przykład od razu,
więc powiedzieć struct,
następnie otworzyć nawias kręcone,
w tej struktury, musimy int wiek,
char * name,
i to jest to.
To może wydawać się dziwne, ze średnikiem po nawiasem klamrowym,
ale to jest w rzeczywistości z niezbędnym elemencie.
Każdy poprawny typ można iść w definicji struktury.
Tutaj użyliśmy int i char *,
ale można także używać tablicy, powiedzmy, 100 elementów
lub nawet innego struct.
Gdy używasz przypisać struktury w C,
tworzysz nowe typy
z kolekcji innych typów.
Tutaj robimy nowy typ
z liczby całkowitej i A * char.
Jak zobaczymy później, typ struct
jest wiele sposobów równoważnych innego rodzaju jesteś przyzwyczajony.
Zazwyczaj będę porównując jak typ struct
jest podobne do typu całkowitego.
Natomiast kod pisaliśmy obowiązuje C,
to nie jest bardzo przydatne,
i brzęk da nam ostrzeżenie.
Pamiętasz, jak i jego elemencie są podobne?
Cóż, w zasadzie tylko, że
int,
które nie bardzo pomocna jest wiersz.
Więc faktycznie zadeklarować zmienną tego typu
poprzez nadanie mu nazwy przed średnikiem.
Zadzwonimy zmiennej student.
Teraz mamy zadeklarowane zmienną studenta
z typem określonym przez struktury.
Jak dostaniemy się do zmiennych wewnątrz struktury?
Technicznie, nazwy tych zmiennych
są członkami.
Aby uzyskać dostęp do żadnego konkretnego elementu w strukturze studentów
dołączeniu kropkę do nazwy zmiennej,
po którym następuje nazwa członka chcesz.
Więc tutaj, tylko w 2 ważnych możliwości
są student.age
i student.name.
I możemy zrobić coś takiego
student.age = 12
i student.name = student.
I co teraz, czy chcemy, aby wykonać drugie studenta?
Można by pomyśleć, aby skopiować i wkleić te linie
i zmienić ucznia do ucznia 2 lub coś,
i że będzie działać,
ale technicznie, student i student 2
nie są tego samego typu.
Patrz, nie można przypisać ich do siebie.
To dlatego, że, jak dotąd,
Twój struct był anonimowy.
Musimy dać mu nazwę.
Aby to zrobić, możemy wstawić nazwę struct
po struktury tekstu.
student,
następnie definicji.
Nadal możemy natychmiast zadeklarować zmienną typu
struct student, tak jak to robiliśmy wcześniej.
Nazwijmy to S1
Dając struct nazwę,
możemy teraz używać studenta struct
niemal dokładnie taki sam sposób będziemy używać int.
Więc możemy zadeklarować zmienną studenta struct typu
jak
struct Student S2.
Jak tablice, kodowanym dostarcza składnię inicjalizacji skrótu
Można więc powiedzieć, struct Student S2
taniej
lewy nawias klamrowy 3, S2.
Tutaj S2.age będzie 3
i S2.name będzie wskazywać na S2.
Pomyśl o wszystkich rzeczach, które możesz zrobić z typu int
i większość z nich można zrobić z typem studenta struktury.
Możemy użyć studenta struct jako typ parametru funkcji.
Możemy użyć studenta struct wewnątrz nowej struktury.
Możemy mieć wskaźnik do studenta struktury.
Możemy zrobić rozmiar studenta struktury.
Student jest typu struct
jak int to typ.
Możemy również przypisać S1 do S2
ponieważ oba są tego samego typu, to możemy
S1 = S2.
Co się dzieje, jeśli nie zrobimy
S1.age = 10?
Czy S2 zmiany w ogóle?
Znowu myślę o elemencie prostu jak zwykłe liczby całkowite.
Jeśli przypisujemy jakąś int x pewnym Y INT,
jak x = y
a następnie zmień X,
jak w X + +
Y nie zmienia w ogóle?
Y o nie zmienia, a więc nie ma wyżej S2.
S2.age jeszcze 3.
Jednak pamiętać, że podczas przypisywania jeden struct do innej,
wszystkie wskaźniki nadal wskazują na to samo,
ponieważ były one tylko kopiowane.
Jeśli nie chcesz, aby wskaźniki się dzielić,
musisz ręcznie z tym poradzić,
być może malicking jeden blok pamięci na jeden ze wskaźników wskazać
i kopiowania danych na.
To może być irytujące napisać studenta struct wszędzie.
Korzystanie z def typu, możemy zrobić
Typ def
struct
a my nazywamy to student.
Teraz możemy używać wszędzie studenta
że używałem studenta struct.
To def typie anonimowy struct
i nazywa to student.
Ale jeśli będziemy mieć także identyfikator studenta
obok struktury tekstu, jak w typedef struct studenta,
możemy użyć zarówno ucznia struct i student zamiennie teraz.
Oni nawet nie muszą mieć taką samą nazwę.
Możemy wpisać studenta struct def do Boba
a następnie struct studenta i Boba
byłoby wymienne typów.
Niezależnie od typu def,
musimy identyfikator obok struct
jeśli definicja tej struktury
jest rekurencyjna.
Na przykład,
Typ def struct node
i zostanie ona zdefiniowana jako int val
i będzie miał wskaźnik, który wskazuje na inny węzeł struktury.,
jak w węźle struct * następnym.
I będziemy nazywać węzeł.
Struktura ta jest rekurencyjna,
ponieważ definicja węzła struct zawiera w sobie
wskaźnik do węzła struktury.
Zauważ, że mamy do powiedzenia struct node * next
wewnątrz definicji węzła struct
od def typu jeszcze się nie zakończyło, aby umożliwić nam uprościć
do zaledwie węzeł * next.
Dowiesz się więcej o strukturach podobnych do tego
w kontaktach z powiązanych list i drzew.
Co o elemencie w funkcji?
Jest to również w pełni uzasadniona.
Mogliśmy
void func
która przyjmuje jako argument,
Student s
i czy coś z tego ucznia.
A następnie możemy przekazać ją jako struct studentów tak.
Func S1 z przed.
Struct zachowuje
dokładnie jak to, gdy całkowita przekazywane do funkcji.
Func otrzymuje kopię S1
i tak nie można modyfikować S1;
raczej tylko kopia, która jest przechowywana w S.
Jeśli chcesz, aby funkcja mogła modyfikować S1,
func będzie musiał podjąć * studenta S,
i będziesz musiał przejść S1 według adresu, tak.
Student * S, funk i S1.
Jest jeszcze jeden powód, aby przejść przez adres.
Co jeśli nasza struktura zawierała 100 pól?
Za każdym razem, mijamy studentowi func,
nasz program musi skopiować wszystkie te 100 pól w argument func jest,
nawet jeśli nie używa większość z nich.
Więc nawet jeśli funkcja nie planuje na modyfikację studenta
jeśli może być jeszcze wartościowe przejść przez adres.
Dobra, co jeśli chcemy utworzyć wskaźnik do struktury?
Moglibyśmy zrobić coś
Student * S
równa malloc
rozmiar studenta.
Zauważ, że rozmiar nadal działa tutaj.
Więc jak mamy teraz dostęp do Wiek
bloku, który wskazuje na S?
Możesz najpierw pomyśleć zrobić
* S.age = 4,
ale nie dość pracy.
Ponieważ bardzo to być interpretowane jako
S.age * w nawiasach = 4,
który nie będzie nawet skompilować,
ponieważ S nie jest strukturą, a raczej wskaźnik do struktury,
i tak kropka nie będzie tutaj.
Moglibyśmy zrobić
(* S). Wiek = 4
ale nawiasy można dostać denerwujące i mylące.
Na szczęście, mamy specjalny operator strzałki
, który wygląda mniej więcej tak
S-> wiek = 4.
Te 2 sposoby odwoływania wiek
są równoważne
i tak naprawdę nie potrzebować operator strzałki
ale sprawia, że ​​wszystko wygląda ładniej.
Ponieważ S jest wskaźnikiem do pewnego bloku pamięci, który zawiera struct,
można myśleć o S> wieku następująco strzałkę wskaźnika
i chwyć członek wiek.
Więc dlaczego mielibyśmy kiedykolwiek użyć przypisać struktury?
Jest to z pewnością możliwe, aby uciec z zaledwie liczb całkowitych prymitywnych
znaki, wskaźniki i podobne
że jesteśmy przyzwyczajeni;
zamiast przed S1 i S2
mogliśmy mieć age1, age2, nazwa1 i nazwa2
wszystkie na osobnych zmiennych.
To jest w porządku, tylko z 2 studentów
ale co jeśli mamy 10 z nich?
A co, jeśli zamiast tylko 2 pola,
struct student 100 pól?
GPA, kursy, kolor włosów, płeć, i tak dalej.
Zamiast tylko 10 elemencie, musimy 1.000 oddzielnych zmiennych.
Warto również funkcję
że bierze to struct z 100 pól z jej jedynym argumentem
i wypisuje wszystkie pola.
Jeśli nie korzystaliśmy struct,
za każdym razem wywołujemy tę funkcję,
musimy przekazać na wszystkich 100 zmiennych,
i jeśli mamy 100 zmiennych dla studenta 1,
i 100 zmiennych dla ucznia 2,
Musimy być pewni, że nie przypadkowo przekazać niektóre zmienne z ucznia 1
i niektóre zmienne z uczniem 2.
Nie da się tego błędu z struct,
ponieważ wszystkie 100 zmiennych zawarte są w jednym pakiecie.
Wystarczy kilka końcowych uwag:
Jeśli zrozumiałeś wszystko do tego punktu, to wspaniale.
Reszta filmu jest tylko dla kompletności boską.
Ponieważ kodowanym może posiadać jakikolwiek wskaźnik,
mogą również posiadać wskaźników funkcji.
Jeśli jesteś zaznajomiony z programowania obiektowego,
zapewnia to sposób na wykorzystanie struktury do programu w stylu obiektu zorientowanych.
Więcej informacji na temat wskaźników funkcji w innym czasie.
Ponadto, czasami możesz mieć 2 przypisać struktury
których definicje zależne od siebie.
Na przykład,
mogliśmy struct,
która jest zdefiniowana jako
wskaźnik na struct B,
struct B * X,
i teraz możemy mieć B struct
który jest zdefiniowany jako wskaźnik
do struct,
struct * Y.
Ale nie będzie to skompilować,
od B struct nie istnieje w chwili struct jest skompilowany.
A jeśli zamienić struct i struct B,
Potem po prostu zostać z tym samym problemem;
tym razem z struct nie istniejące.
Aby rozwiązać ten problem, możemy napisać
struct B;
przed definicją struct A.
Nazywa się to do przodu deklarację.
To właśnie pozwala kompilator wie, że
struct B jest ważny typ, który będzie w pełni zdefiniowana później lub w innym miejscu.
Nazywam się Rob Bowden, a to CS50.
[CS50.TV]