[Powered by Google Translate] Lad os tale om struct.
Structs giver os en måde at gruppere en flok variabler sammen
ind i en dejlig pakke.
Det er nok nemmest at se et eksempel med det samme,
så siger vi struct,
derefter åbne klammeparentes,
og i denne struct, vil vi have en int alder,
en char * navn,
og det er det.
Det kan synes mærkeligt med et semikolon efter en klammeparentes,
men det er faktisk nødvendigt med struct.
Enhver gyldig type kan gå i struct definition.
Her har vi brugt en int og en char *,
men du kan også bruge en array, af sige, 100 elementer
eller endda en anden struct.
Når du bruger struct i C,
du opretter nye typer
ud af en samling af andre typer.
Her gør vi en ny type
ud af et helt tal og et char *.
Som vi skal se senere, et struct type,
er på mange måder svarer til nogen anden type du er vant til.
Normalt vil jeg være at sammenligne, hvordan en struct type,
svarer til et helt tal type.
Mens den kode, vi skrev, er gyldig C,
det er ikke meget nyttigt,
og klang vil give os en advarsel.
Husk, hvordan struct og dens ligner?
Nå, vi dybest set bare sagt
int,
som ikke er en meget nyttig linje.
Så lad os faktisk erklære en variabel af denne type
ved at give det et navn, før semikolon.
Vi ringer til variable studerende.
Nu har vi erklæret en variabel kaldet elev
med den type, som afgives af struct.
Hvordan kommer vi til de variabler inde i struct?
Teknisk set navne for disse variabler
er medlemmer.
For at få adgang nogen særlig element i en student struct,
du tilføje en prik til den variable navn,
efterfulgt af navnet på det medlem, du ønsker.
Så her, kun 2 gyldige muligheder
er student.age
og student.name.
Og vi kan gøre noget lignende
student.age = 12
og student.name = studerende.
Hvad nu hvis vi ønskede at lave en anden elev?
Du tror måske at kopiere og indsætte disse linjer
og ændre elev til elev 2 eller noget,
og der vil arbejde,
men teknisk, studerende og studerende 2
har ikke samme type.
Se, vil du ikke være i stand til at tildele dem til hinanden.
Dette skyldes indtil nu,
Deres struct har været anonyme.
Vi er nødt til at give det et navn.
For at gøre det, vi indsætte navnet på den struct
efter ordet struct.
studerende,
efterfulgt af definitionen.
Vi kan stadig omgående erklære en variabel af typen
struct studerende, ligesom vi gjorde før.
Vi kalder det S1
Ved at give struct et navn,
Vi kan nu bruge struct student
i næsten nøjagtig samme måde, som vi ville bruge int.
Så vi kan erklære en variabel af typen struct student,
ligesom
struct studerende S2.
Ligesom arrays, giver struct en genvej initialisering syntaks,
så vi kan sige, struct student S2
lig
venstre klammeparentes 3, S2.
Her vil S2.age være 3,
og S2.name vil pege på S2.
Tænk på alle de ting, du kan gøre med en int type,
og de fleste af dem kan du gøre med en struct student type.
Vi kan bruge en struct student som en form for en funktion parameter.
Vi kan anvende struct student indersiden af ​​en ny struct.
Vi kan have en pointer til en struct studerende.
Vi kan gøre størrelsen af ​​struct studerende.
Struct studerende er en type
ligesom int er en type.
Vi kan også tildele S1 til S2
idet begge dele er af samme type, så vi kan gøre
S1 = S2.
Hvad sker der, hvis vi gør
S1.age = 10?
Er S2 ændring overhovedet?
Igen, tænk på de struct bare som almindelige heltal.
Hvis vi tildele noget int X til nogle int Y,
ligesom X = Y
og derefter ændre X,
som i X + +,
gør Y ændre på alle?
Y ikke ændrer sig her, og det heller ikke S2 ​​ovenfor.
S2.age stadig 3.
Men bemærk, at når de tildeler en struct til en anden,
alle henvisninger stadig peger på den samme ting,
da de bare blev kopieret.
Hvis du ikke ønsker, at pointere, der skal deles,
du bliver nødt til manuelt at håndtere det,
måske ved malicking en blok af hukommelse til en af ​​pegepinde til at pege på
og kopiering af data over.
Det kan være irriterende at skulle skrive struct studerende overalt.
Ved hjælp af en type, def, kan vi gøre
typen def
struct
og vi vil kalde det elev.
Nu kan vi bruge studerende overalt
at vi plejede at bruge struct studerende.
Denne type def er en anonym struct
og kalder det elev.
Men hvis vi også holde den studerende identifikator
siden af ​​ordet struct, som i typedef struct studerende,
vi kunne bruge både struct studerende og studerende i flæng nu.
De behøver ikke engang at have samme navn.
Vi kunne skrive def struct studerende til Bob
og derefter struct studerende og Bob
ville være udskiftelige typer.
Uanset typen def,
vi har brug for identifikator siden struct
Hvis definitionen af ​​struct
er rekursiv.
For eksempel,
typen def struct node
og den vil blive defineret som en int val
og det vil have en pointer, der peger på en anden struct node.,
som i struct node * næste.
Og så vil vi kalde det node.
Denne struct er rekursiv,
da definitionen af ​​struct node indeholder i sig
en pointer til en struct node.
Bemærk, at vi har at sige struct node * næste
indersiden af ​​definitionen af ​​struct node,
Da type def ikke er færdig endnu at tillade os at forenkle denne
til lige node * næste.
Du vil lære mere om struct svarende til dette
når det drejer sig hægtede lister og træer.
Hvad med struct i en funktion?
Dette er også fuldt ud gyldig.
Vi kunne have
ugyldig funk
som tager som et argument,
studerendes
og gør noget med, at studerende.
Og så kan vi give det som studerende struct som så.
Func af S1 fra før.
Den struct opfører
præcis som et heltal vil, når i en funktion.
Func modtager en kopi af S1
og kan derfor ikke ændre S1;
snarere, kun den kopi af det, der er lagret i S.
Hvis du vil have den funktion at være i stand til at ændre S1,
funk bliver nødt til at tage en studerende * S,
og du bliver nødt til at passere S1 efter adresse, som så.
Student * S, funk & S1.
Der er en anden grund til at passere efter adresse her.
Hvad hvis vores struct indeholdt 100 felter?
Hver eneste gang vi passerer en elev til funk,
vores program skal kopiere alle disse 100 felter i funk argument S,
Selv om det aldrig anvender det store flertal af disse.
Så selv om funk har ikke planer om at ændre den studerende,
hvis kan stadig være værdifuldt at passere efter adresse.
Okay, hvad nu hvis vi ønsker at skabe en pointer til en struct?
Vi kunne gøre noget lignende
studerende * S
lig malloc
størrelse studerende.
Bemærk, at størrelsen af ​​stadig arbejder her.
Så hvordan kan vi nu få adgang til alder medlem
af blokken, at S peger på?
Du kan først tænker at gøre
* S.age = 4,
men det vil ikke helt fungere.
Da dette virkelig vil blive tolket som
* S.age i parenteser = 4,
som ikke engang kompileres,
da S ikke er en struct eller snarere en pointer til en struct,
og så prik vil ikke arbejde her.
Vi kunne gøre
(* S). Alder = 4
men parenteserne kan få irriterende og forvirrende.
Heldigvis har vi en særlig pil operatør
som ser ud som
S-> alder = 4.
Disse 2 måder referencing alder
svarer
og vi har ikke rigtig nogensinde har brug pilen operatør,
men det gør tingene ser pænere.
Da S er en pointer til nogle blok af hukommelse, der indeholder struct,
du kan tænke på S> alder som følge Markørpilen
og få fat i den alder medlem.
Så hvorfor skulle vi nogensinde Benyt strukturer?
Det er absolut muligt at slippe af sted med kun de primitive heltal,
chars, pegepinde og lignende
at vi er vant til;
i stedet for S1 og S2 før,
vi kunne have haft age1, age2, navn1, og NAME2
alle på forskellige variabler.
Det er fint med kun 2 studerende,
men hvad nu hvis vi havde 10 af dem?
Og hvad hvis der i stedet for kun 2 felter,
den studerende struct havde 100 felter?
GPA, kurser, hårfarve, køn og så videre.
I stedet for blot 10 struct har vi brug for 1.000 separate variabler.
Også overveje en funktion
der tager at struct med 100 felter med sit eneste argument
og udskriver alle felter.
Hvis vi ikke bruge en struct,
hver eneste gang vi kalder denne funktion,
vi er nødt til at passere på alle 100 variabler,
og hvis vi har 100 variabler til studerende 1,
og 100 variabler til studerende 2,
vi nødt til at være sikker på, at vi ikke ved et uheld passere nogle variabler fra studerende 1
og nogle variable fra studerende 2.
Det er umuligt at lave den fejl med en struct,
eftersom alle 100 variabler er indeholdt i en enkelt pakke.
Blot et par sidste bemærkninger:
Hvis du har forstået alt op til dette punkt, stor.
Resten af ​​videoen er bare for fuldstændighedens skyld.
Fordi struct kan holde enhver form for pointer,
de kan også holde funktionspointere.
Hvis du er fortrolig med objektorienteret programmering,
Dette tilvejebringer en måde at bruge struct at programmere i et objektorienteret stil.
Mere om funktionspointere på et andet tidspunkt.
Også, nogle gange kan du have 2 struct
hvis definitioner afhængige af hinanden.
For eksempel,
vi kunne have struct A,
der er defineret som
en pointer til en struct B,
struct B * X,
og nu kan vi få en struct B
der er defineret som en pegepind
til en struct A,
struct A * Y.
Men dette vil ikke kompilere,
da struct B ikke eksisterer på det tidspunkt, struct A bliver kompileret.
Og hvis vi bytter struct A og struct B,
så ville vi bare stå tilbage med det samme problem;
denne gang, med konstruere A ikke eksisterende.
For at løse dette, kan vi skrive
struct B;
før definitionen af ​​struct A.
Dette kaldes en forreste erklæring.
Dette blot lader compileren vide, at
struct B er en gyldig type, som vil blive fuldt ud defineret senere, eller andetsteds.
Mit navn er Rob Bowden, og dette er CS50.
[CS50.TV]