[Powered by Google Translate] Anem a parlar de les estructures.
Les estructures ens proporcionen una forma d'agrupar un munt de variables juntes
en un paquet agradable.
És probablement més fàcil per veure un exemple immediat,
per això diem estructura,
després obrir clau,
i en aquesta estructura, tindrem una edat int,
un nom char *,
i això és tot.
Pot semblar estrany amb un punt i coma després d'una clau,
però és de fet necessari, amb les estructures.
Qualsevol tipus vàlid pot anar dins de la definició d'estructura.
Aquí, hem utilitzat un int i un char *,
però també es pot utilitzar una matriu, de, diguem, 100 elements
o fins i tot en una altra estructura.
Quan vostè està utilitzant estructures en C,
està creant nous tipus
d'una col · lecció d'altres tipus.
Aquí, estem fent un nou tipus
d'un sencer i un char *.
Com veurem més endavant, una estructura tipus
està en un munt de maneres equivalents de qualsevol altre tipus que estem acostumats.
En general, estaré comparant com un tipus struct
és similar a un tipus sencer.
Mentre que el codi que va escriure és vàlida C,
no és molt útil,
clang i ens donarà una advertència.
Recorda com les seves estructures i són similars?
Bé, bàsicament, va dir
int,
que no és una línia molt útil.
Així que en realitat declarar una variable d'aquest tipus
donant-li un nom abans del punt i coma.
Anomenarem a l'estudiant variable.
Ara hem declarat una variable anomenada estudiants
amb el tipus de proposta per l'estructura.
Com podem arribar a les variables dins de l'estructura?
Tècnicament, els noms d'aquestes variables
són membres.
Per accedir a qualsevol membre particular d'una estructura estudiant,
s'afegeix un punt al nom de la variable,
seguit del nom de l'element que voleu.
Així que aquí, les úniques dues possibilitats vàlides
són student.age
i student.name.
I podem fer alguna cosa com
student.age = 12
i student.name = estudiant.
Ara el que si volíem fer un estudiant de segon?
Es podria pensar que copiar i enganxar aquestes línies
i canviar un estudiant a 2 o alguna cosa així,
i que funcionarà,
però tècnicament, estudiant i estudiant 2
no tenen el mateix tipus.
Vegi, vostè no serà capaç d'assignar l'un a l'altre.
Això és degut al fet que, fins ara,
seva estructura ha estat anònim.
Hem de donar-li un nom.
Per fer això, introduïu el nom de l'estructura
després de la paraula struct.
estudiant,
seguit per la definició.
Encara podem immediatament declarar una variable de tipus
struct estudiant, com ho vam fer abans.
L'anomenarem S1
En donar a l'estructura d'un nom,
ara podem utilitzar estudiant struct
en gairebé la mateixa manera que faria servir int.
Per tant, es pot declarar una variable de tipus struct estudiant,
com
struct estudiant S2.
Igual que les matrius, estructures proporcionen una sintaxi d'inicialització d'accés directe,
pel que podem dir, estructura estudiant S2
és igual a
clau d'obertura 3, S2.
Aquí, S2.age és 3,
i S2.name apuntarà a S2.
Penseu en totes les coses que pots fer amb un tipus int
i la majoria d'ells es pot fer amb un tipus struct estudiant.
Es pot utilitzar un estudiant struct com un tipus d'un paràmetre de funció.
Podem utilitzar struct estudiant dins d'una estructura nova.
Podem tenir un punter a una struct estudiant.
Podem fer grandària de l'estudiant estructura.
Estudiant struct és un tipus
igual que int és un tipus.
També podem assignar S1 a S2
ja que tots dos són del mateix tipus, de manera que podem fer
S1 = S2.
Què passa si no fem
S1.age = 10?
Canvia S2 en absolut?
Un cop més, pensar en les estructures només com sencers normals.
Si assignem una mica de X int a int I alguns,
com X = I
i canviï X,
com a X + +,
I no canvia en absolut?
I aquí no canvia, de manera que tampoc S2 dalt.
S2.age és encara 3.
Fixeu-vos, que quan s'assigna una estructura a una altra,
tots els punters encara apunten a la mateixa cosa,
des que es va acabar de copiar.
Si no desitja que els punters a ser compartida,
hauràs de manejar manualment que,
potser per malicking un bloc de memòria per a un dels punters per apuntar a
i copiar les dades de nou.
Pot ser molest haver d'escriure struct estudiant a tot arreu.
L'ús d'un tipus de definició, podem fer
tipus def
struct
i ho anomenarem estudiant.
Ara, podem utilitzar qualsevol estudiant
que hem utilitzat per a ús dels estudiants estructura.
Aquesta definició és un tipus struct anònim
i ho crida estudiant.
Però si anem a mantenir l'identificador d'estudiant
al costat de la paraula struct, com en l'estudiant typedef struct,
podríem utilitzar tant l'estudiant i l'estudiant struct indistintament ara.
Ni tan sols ha de tenir el mateix nom.
Podríem escriure def estudiant struct per Bob
i després struct estudiant i Bob
Seria tipus intercanviables.
Independentment de la definició de tipus,
necessitem el següent identificador a struct
Si la definició de l'estructura
és recursiva.
Per exemple,
def tipus struct node
i es defineix com un int val
i comptarà amb un punter que apunta a un altre node struct.,
com a struct node * següent.
I llavors l'anomenarem node.
Aquesta estructura és recursiva,
ja que la definició de struct node conté en el seu interior
un punter a un node d'estructura.
Recordeu que hem de dir struct node * següent
dins de la definició de l'estructura de node,
ja que la definició de tipus no ha acabat encara que ens permeti simplificar aquest
a només * següent node.
Vostè aprendrà més sobre les estructures similars a aquest
quan es tracta de les llistes enllaçades i arbres.
Què passa amb les estructures en una funció?
Això també és perfectament vàlid.
Podríem tenir
anul · lar la funció
que pren com a argument,
estudiant s
i fa alguna cosa amb aquest estudiant.
I després podem passar com struct estudiant com a tal.
Func de S1 d'abans.
L'estructura es comporta
exactament com un nombre enter quan es passa a una funció.
Func rep una còpia de S1
i per tant no pot modificar S1;
més aviat, només la còpia que s'emmagatzema en S.
Si desitja que la funció per poder modificar S1,
funció haurà de prendre una estudiant * S,
i que haurà de passar per direcció S1, així.
Estudiant * S, funcions i S1.
Hi ha una altra raó per passar per direcció aquí.
I si la nostra estructura contenia 100 camps?
Cada vegada que passa un estudiant de funcionar,
nostre programa ha de copiar tots els 100 camps en funció de S argument,
encara que no s'utilitza la gran majoria d'ells.
Així que encara que func no planeja modificar l'estudiant,
si encara pot ser de gran valor per passar per la direcció.
Bé, què passa si volem crear un punter a una estructura?
Podríem fer alguna cosa com
estudiant * S
és igual a malloc
grandària dels alumnes.
Tingueu en compte que la mida d'encara treballa aquí.
Llavors, com podem ara tenir accés al membre edat
del bloc que els punts S per?
En primer lloc, pot ser que pensi que fer
* S.age = 4,
però això no funcionarà bastant.
Atès que això realment s'interpretarà com
* S.age entre parèntesis = 4,
que fins i tot no compilar,
ja que S no és una estructura o millor dit un punter a una estructura,
de manera que el punt no funcionarà aquí.
Podríem fer
(* S). = 4 anys
però els parèntesis pot ser molest i confús.
Afortunadament, comptem amb un operador de fletxa especial
que es veu alguna cosa com
S-> edat = 4.
Aquestes dues formes de fer referència a l'edat
són equivalents
i que realment no necessita sempre l'operador de fletxa,
però fa que les coses es veuen més boniques.
Com que S és un indicador a una bloc de memòria que conté l'estructura,
es pot pensar en l'edat S> com seguir la fletxa del cursor
i agafar el membre de l'edat.
Llavors, per què ens utilitzen estructures?
És definitivament possible allunyar amb només els nombres enters primitius,
caràcters, punters i similars
que estem acostumats;
en lloc de S1 i S2 abans,
que podria haver tingut edad1, edat2, Nom1, nombre2 i
tot en les variables independents.
Això està molt bé, amb només 2 estudiants,
però el que si tinguéssim 10 d'ells?
I si en lloc de només els camps 2,
l'estructura estudiant comptava amb 100 camps?
GPA, cursos, color de cabell, el sexe, etc.
En lloc de només 10 estructures, necessitem 1.000 variables separades.
A més, consideri una funció
que pren aquesta estructura amb 100 camps amb el seu únic argument
i imprimeix tots els camps.
Si no fem servir una estructura,
cada vegada que anomenem a aquesta funció,
hem de passar als 100 variables,
i si tenim 100 variables per a l'estudiant 1,
i 100 variables per a l'estudiant 2,
hem d'estar segurs que no accidentalment es passa d'algunes variables d'un estudiant
i algunes variables de l'estudiant 2.
És impossible cometre el mateix error amb una estructura,
ja que totes les variables de 100 estan continguts en un únic paquet.
Només un parell de notes finals:
Si vostè ha entès tot fins aquest punt, molt bé.
La resta del vídeo és només pel bé de la integritat ".
Com que les estructures poden contenir qualsevol tipus de punter,
també poden contenir punters a funcions.
Si està familiaritzat amb la programació orientada a objectes,
això proporciona una manera d'utilitzar les estructures de programa en un estil orientat a objectes.
Més informació sobre els punters de funció en un altre moment.
També, de vegades vostè pot tenir dues estructures
les definicions depenen un de l'altre.
Per exemple,
podríem tenir struct A,
que es defineix com
un punter a una struct B,
struct B * X,
i ara podem tenir una estructura B
que es defineix com un punter
a una estructura A,
struct A * I.
Però això no va a construir
ja que B struct no existeix en el moment en què struct A està sent compilat.
I si canviem struct struct A i B,
llavors ens quedaríem amb el mateix problema;
aquesta vegada, amb un struct inexistent.
Per solucionar això, podem escriure
struct B;
abans de la definició de l'estructura A.
Això s'anomena una declaració cap endavant.
Això només deixa que el compilador sap que
struct B és un tipus vàlid que estarà totalment definit més endavant o en un altre lloc.
El meu nom és Rob Bowden, i això és CS50.
[CS50.TV]