[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]