[Powered by Google Translate] Laten we praten over structs.
Structs bieden ons een manier om een ​​bos van variabelen te groeperen
in een mooi pakket.
Het is waarschijnlijk het beste om een ​​voorbeeld te zien meteen,
dus we zeggen struct,
vervolgens te openen accolade,
en in deze struct, zullen we een int leeftijd,
een char * naam,
en dat is het.
Het kan raar lijken met een puntkomma na een accolade,
maar het is in feite nodig met structs.
Ieder geldig type kan gaan binnen de struct definitie.
Hier hebben we gebruik gemaakt van een int en een char *,
maar je kunt ook gebruik maken van een array, van zeg, 100 elementen
of zelfs een andere struct.
Wanneer u gebruik maakt van structs in C,
je bent het creëren van nieuwe typen
uit een verzameling van andere soorten.
Hier maken we een nieuw type
uit een geheel getal en een char *.
Zoals we later zullen zien, een struct type
is in veel opzichten gelijk aan een ander type dat u gewend bent.
Meestal zal ik vergelijken hoe een struct-type
is vergelijkbaar met een integer type.
Terwijl de code die we schreven is geldig C,
het is niet erg handig,
en Clang zal ons een waarschuwing.
Weet je nog hoe structs en zijn vergelijkbaar zijn?
Nou ja, we in principe net gezegd
int,
dat is niet een zeer nuttig lijn.
Dus laten we in feite een variabele van dat type te verklaren
door het geven van een naam voor de puntkomma.
We bellen de variabele student.
Nu hebben we uitgeroepen tot een variabele genaamd student
met het type door de struct.
Hoe komen we aan de variabelen in de struct?
Technisch namen voor deze variabelen
zijn leden.
Om een ​​bepaald lid in een studentenhuis struct te openen,
U voegt een punt om de variabele naam,
gevolgd door de naam van het lid dat u wilt.
Dus hier, de enige 2 geldige mogelijkheden
zijn student.age
en student.name.
En we kunnen zoiets doen
student.age = 12
en student.name = student.
Nu, wat als we wilden een tweede studente?
Je zou kunnen denken om te kopiëren en plakken deze lijnen
en verander student tot student 2 of iets,
en dat zal werken,
maar technisch, student en student 2
niet hetzelfde type.
Zie, zult u niet in staat zijn om ze toe te wijzen aan elkaar.
Dit is omdat tot nu toe
je struct is anoniem.
We moeten het een naam geven.
Om dat te doen, voegen we de naam van de struct
achter het woord struct.
student,
gevolgd door de definitie.
We kunnen nog steeds meteen verklaren een variabele van het type
struct student, zoals we eerder hebben gedaan.
We noemen het S1
Door het geven van de struct een naam,
We kunnen nu gebruik maken van struct student
in bijna exact dezelfde manier waarop we zouden gebruiken int.
Dus we kunnen verklaren een variabele van het type struct student,
zoals
struct student S2.
Net als arrays, structs vormen een snelkoppeling initialisatie syntax,
zodat we kunnen zeggen, struct student S2
is gelijk aan
linker accolade 3, S2.
Hier wordt S2.age 3 is,
en S2.name zal wijzen op S2.
Denk aan alle dingen die je kunt doen met een int-type
en de meeste van hen die je kunt doen met een struct student type.
We kunnen gebruik maken van een struct student als een soort van een functie parameter.
We kunnen gebruik maken struct student binnenkant van een nieuwe struct.
We kunnen een pointer naar een struct student.
We kunnen doen grootte van struct student.
Struct student is een type
net als int is een type.
We kunnen ook S1 toewijzen aan S2
aangezien beide van hetzelfde type, dus kunnen we
S1 = S2.
Wat gebeurt er als we dat doen
S1.age = 10?
Heeft S2 verandering op alle?
Nogmaals, denk aan de structs net als gewone integers.
Als we wijzen sommige int X om wat int Y,
als X = Y
en wijzig X,
zoals in X + +,
doet Y veranderen helemaal?
Y hier niet veranderen, en dus ook niet S2 hierboven.
S2.age is nog steeds 3.
Maar merk op dat bij het toewijzen struct een ander,
alle van de wijzers nog steeds naar dezelfde zaak,
omdat ze werden gewoon gekopieerd.
Als u niet wilt dat de pointers te delen,
moet u handmatig verwerken dat,
misschien door malicking een geheugenblok voor een van de wijzers wijzen naar
en het kopiëren van data over.
Het is misschien vervelend om struct student overal schrijven.
Met behulp van een soort def, kunnen we doen
soort def
struct
en we noemen het student.
Nu kunnen we overal gebruiken student
die we hebben gebruikt om struct student te gebruiken.
Dit type def is een anonieme struct
en noemt het student.
Maar als we houden ook van de student-id
naast het woord struct, zoals in typedef struct student,
we kunnen gebruiken zowel struct student en student door elkaar nu.
Ze hebben niet eens dezelfde naam te hebben.
We konden typen def struct student Bob
en dan struct student en Bob
zou verwisselbare types.
Ongeacht het type def,
moeten we de identifier naast struct
Als de definitie van de struct
is recursief.
Bijvoorbeeld
soort def struct knoop
en wordt gedefinieerd als een int val
en het zal een pointer die wijst naar een andere struct knoop.,
zoals in struct knoop * volgende.
En dan zullen we noemen het knooppunt.
Dit struct is recursief,
aangezien de definitie van struct knoop bevat in zich
een pointer naar een struct node.
Merk op dat we te zeggen hebben struct knoop * volgende
binnenkant van de definitie van de struct knooppunt
omdat het type def is nog niet klaar om ons in staat om dit te vereenvoudigen
gewoon knooppunt * volgende.
Je leert meer over structs vergelijkbaar met deze
bij de behandeling met gelinkte lijsten en bomen.
Hoe zit het met structs in een functie?
Dit is ook perfect geldig.
We konden
vervallen functies
waarbij rekening wordt als een argument,
student s
en doet iets met die student.
En dan kunnen we gaan het als student struct zoals zo.
Func van S1 van voor.
De struct gedraagt
precies als integer zou doorgeeft aan een functie.
Func ontvangt een kopie van S1
en kan dus niet wijzigen S1;
plaats, alleen het exemplaar van het dat is opgeslagen in S.
Als u wilt dat de functie om te kunnen S1 te wijzigen,
functie moet een student * S te nemen,
en je moet S1 voorbij adres, zoals zo.
Student * S, functie & S1.
Er is nog een reden om hier te gaan op adres.
Wat als onze struct 100 velden bevatten?
Elke keer als we een student door te geven aan functies,
ons programma om al die 100 velden te kopiëren naar argument func S,
zelfs indien gebruikt nooit de meeste van hen.
Dus zelfs als functie is niet van plan over het wijzigen van de student,
Als u nog steeds waardevol te passeren op adres.
Oke, wat als we willen een pointer te creëren naar een struct?
We kunnen iets doen als
student * S
is gelijk aan malloc
grootte van de student.
Merk op dat de grootte van de nog steeds werkt hier.
Dus hoe kunnen we nu toegang tot de leeftijd lid
van het blok dat S verwijst naar?
Je zou eerst denken te doen
* S.age = 4,
maar dit zal niet helemaal werken.
Aangezien dit zal echt worden geïnterpreteerd als
* S.age haakjes = 4,
die niet eens compileren,
aangezien S is geen struct of liever een pointer naar een struct,
en dus de stip zal hier niet werken.
We konden doen
(* S). Leeftijd = 4
maar de haakjes kan vervelend en verwarrend.
Gelukkig hebben we een speciale pijl operator
dat ziet er ongeveer als
S-> age = 4.
Deze 2 manieren van verwijzen naar leeftijd
gelijkwaardig
en we niet echt ooit nodig de pijl exploitant,
maar het maakt het wat mooier.
Aangezien S is een pointer naar een aantal blok van het geheugen dat de struct bevat,
kunt u denken aan S> leeftijd als volgt u de aanwijzer
en pak de leeftijd lid.
Dus waarom zouden we ooit gebruiken structs?
Het is zeker mogelijk om weg te komen met slechts de primitieve gehele getallen,
tekens, pointers en dergelijke
dat we gewend zijn;
plaats van S1 en S2 voor,
we hadden kunnen gebruiken age1, age2, naam1 en naam2
Alle op verschillende variabelen.
Dit is prima met slechts 2 studenten,
maar wat als we 10 van hen hadden?
En wat als plaats van slechts 2 velden,
de student struct had 100 velden?
GPA, cursussen, haarkleur, geslacht, enzovoort.
In plaats van slechts 10 structs, moeten we 1.000 afzonderlijke variabelen.
Overweeg ook een functie
dat neemt die struct met 100 velden met enige argument
en drukt alle velden in.
Als we geen gebruik van een struct,
elke keer roepen we die functie,
moeten we over op alle 100 variabelen,
en als we 100 variabelen voor student 1,
en 100 variabelen voor student 2,
moeten we er zeker van zijn dat we niet per ongeluk een aantal variabelen gaan van student 1
en een aantal variabelen van student 2.
Het is onmogelijk om die fout te maken met een struct,
omdat alle 100 variabelen zijn opgenomen in een enkel pakket.
Gewoon een paar laatste opmerkingen:
Als je hebt alles begrepen tot op dit punt, geweldig.
De rest van de video slechts Volledigheidshalve.
Omdat structs kan elk type pointer te houden,
ze kunnen ook hold functie pointers.
Als u bekend bent met object georiënteerd programmeren,
Dit biedt een manier om structs gebruiken bij het programmeren in een object georiënteerde stijl.
Meer over functie pointers op een ander tijdstip.
Ook, soms moet u wellicht twee structs
waarvan de definitie van elkaar afhankelijk.
Bijvoorbeeld
we zouden kunnen hebben struct A,
gedefinieerd als
een pointer naar een struct B,
struct B * X,
en nu kunnen we een struct B
gedefinieerd als een pointer
een struct A,
struct A * Y.
Maar dit zal niet compileren,
sinds struct B niet bestaat op het moment dat struct A wordt samengesteld.
En als we ruilen struct A en struct B,
dan zouden we gewoon blijven zitten met hetzelfde probleem;
dit keer, struct met A niet bestaande.
Om dit op te lossen, kunnen we schrijven
struct B;
voor de definitie van struct A.
Dit heet een voorwaartse declaratie.
Dit laat weet alleen de compiler dat
struct B is een geldig type dat volledig zal worden later of elders gedefinieerd.
Mijn naam is Rob Bowden, en dit is CS50.
[CS50.TV]