[Powered by Google Translate] Le të flasim për structs.
Structs na japin një mënyrë për të grupit të një bandë e variablave bashku
në një paketë të bukur.
Kjo është ndoshta më e lehtë për të parë një shembull të drejtë larg,
kështu që ne themi struct,
pastaj hapjen mbajtëse kaçurrel,
dhe në këtë struct, ne do të kemi një moshë int,
një emër char *,
dhe kjo është ajo.
Kjo mund të duket i çuditshëm me një pikëpresje pas një mbajtëse kaçurrel,
por kjo është në fakt e domosdoshme me structs.
Çdo lloj vlefshme mund të shkojë brenda përkufizimit struct.
Këtu, ne kemi përdorur një int dhe një char *,
por ju mund të përdorë gjithashtu edhe një grup, të themi, 100 elemente
apo edhe një tjetër struct.
Kur ju jeni duke përdorur structs në C,
ju jeni duke krijuar lloje të reja
nga një koleksion të llojeve të tjera.
Këtu, ne jemi duke bërë një lloj të ri
nga një numër i plotë dhe një * char.
Siç do të shohim më vonë, një lloj struct
është në shumë mënyra ekuivalente me çdo lloj tjetër ju jeni duke përdorur për të.
Zakonisht, unë do të krahasuar si një lloj struct
është i ngjashëm me një lloj numër i plotë.
Ndërsa kodi kemi shkruar është C vlefshme,
kjo nuk është shumë e dobishme,
Dhe tingëllimë do të na japë një paralajmërim.
Mos harroni se sa structs saj dhe janë të ngjashme?
E pra, ne thelb vetëm tha
int,
e cila nuk është një linjë shumë e dobishme.
Pra, le të vërtetë të deklarojë një ndryshore e atij lloji
duke i dhënë asaj një emër para pikëpresje.
Ne do të thërrasë nxënësin ndryshueshme.
Tani ne kemi deklaruar një student ndryshueshme quajtur
me llojin e dhënë nga struct.
Si mund të marrim të variablave brenda struct?
Teknikisht, emrat për këto variabla
janë anëtarë.
Për të hyrë në ndonjë anëtar të veçantë në një struct studentëve,
ju append një dot me emrin e ndryshueshme,
pasuar me emrin e anëtarit që ju dëshironi.
Pra këtu, vetëm 2 mundësi të vlefshme
janë student.age
dhe student.name.
Dhe ne mund të bëjmë diçka si
student.age = 12
dhe student.name = studentëve.
Tani çfarë nëse ne të kërkuar për të bërë një student të dytë?
Ju mund të mendoni për të kopjoni dhe ngjisni këto rreshta
dhe të ndryshojë nxënësi të studentit 2 apo diçka,
dhe që do të punojnë,
por teknikisht, student dhe nxënës 2
nuk kanë të njëjtin lloj.
Shih, ju nuk do të jetë në gjendje të caktojë ata me njëri-tjetrin.
Kjo është për shkak se, deri më tani,
struct juaj ka qenë anonim.
Ne kemi nevojë për të dhënë atë një emër.
Për ta bërë këtë, ne kemi futur emrin e struct
pas fjalës struct.
student,
ndjekur nga përkufizimi.
Ne ende mund të deklarojë menjëherë një ndryshore të tipit
struct student, si ne e bëri më parë.
Ne do të thërrasë atë S1
Duke i dhënë struct një emër,
Ne tani mund të përdorni nxënësit struct
pothuajse në të njëjtën mënyrë të saktë, ne do të përdorim int.
Kështu që ne mund të deklarojë një ndryshore të tipit struct nxënës,
si
struct studenti S2.
Ashtu si vargjeve, structs sigurojë një sintaksë initialization shkurtore,
kështu që ne mund të themi, struct studenti S2
barabartë
majtë kaçurrel shtrëngoj 3, S2.
Këtu, S2.age do të jetë 3,
S2.name dhe do të tregojë për S2.
Mendoj se të gjitha gjërat që ju mund të bëni me një lloj int
dhe shumica e tyre ju mund të bëni me një lloj studentëve struct.
Ne mund të përdorim një student struct si një lloj i një parametër funksion.
Ne mund të përdorim nxënësit struct brenda një struct ri.
Ne mund të kemi një tregues për një student struct.
Ne mund të bëjmë madhësinë e studentit struct.
Struct studenti është një lloj
ashtu si int është një lloj.
Ne gjithashtu mund të caktojë S1 S2 në
pasi që të dyja janë të llojit të njëjtë, kështu që ne mund të bëjmë
S1 S2 =.
Çfarë ndodh nëse ne bëjmë
S1.age = 10?
A S2 ndryshim në të gjitha?
Përsëri, mendoj se e structs ashtu si integers rregullta.
Nëse ne të caktojë një X në një farë int int Y,
si x = Y
dhe pastaj të ndryshojë X,
si në X + +,
nuk Y ndryshojë në të gjitha?
Y nuk ka ndryshuar këtu, dhe kështu nuk e bën S2 sipër.
S2.age është ende 3.
Por vini re se kur caktimin e një struct në një tjetër,
të gjitha pointers ende tregojnë të njëjtën gjë,
pasi ata janë kopjuar vetëm.
Nëse ju nuk dëshironi që pointers të ndahet,
ju do të duhet të dorë të trajtuar atë,
ndoshta nga malicking një bllok të memories për njërit prej pointers tek pikës tek
dhe kopjimit të dhënave gjatë.
Ajo mund të jetë i bezdisshëm që të ketë për të shkruar studenti struct kudo.
Duke përdorur një lloj def, ne mund të bëjmë
Lloji def
struct
dhe ne do të thërrasë atë student.
Tani, ne mund të përdorim nxënësin kudo
që kemi përdorur për të përdorur nxënës struct.
Ky është një lloj def struct anonim
dhe e quan atë studenti.
Por në qoftë se ne gjithashtu të mbajtur identifikues studentore
ardhshëm të fjalës struct, si në student i typedef struct,
ne mund të përdorim si nxënës dhe student struct interchangeably tani.
Ata as nuk duhet të ketë të njëjtin emër.
Ne mund të shkruani studenti def struct për Bob
dhe pastaj struct nxënësin dhe Bob
do të jetë lloje këmbyeshëm.
Pavarësisht nga lloji def,
ne kemi nevojë identifikues tjetër për struct
në qoftë se përkufizimi i struct
është gjithkund rekursive.
Për shembull,
Lloji def struct nyje
dhe kjo do të definohet si një val int
dhe kjo do të ketë një tregues që pikë në një tjetër nyje struct.,
si në nyje struct * ardhshme.
Dhe pastaj ne do të thërrasë atë nyje.
Kjo struct është recursive,
pasi përcaktimi i nyjeve struct përmban brenda saj
një akrep te nje nyje struct.
Vini re se ne duhet të them struct * nyja e ardhshme
brenda përkufizimit të nyjen struct,
pasi def lloji nuk ka përfunduar ende për të na lejojë për të lehtësuar këtë
në vetëm * nyjeve ardhshëm.
Ju do të mësoni më shumë rreth structs të ngjashme me këtë
kur kanë të bëjnë me listat e lidhura dhe pemëve.
Po në lidhje me structs në një funksion?
Kjo është gjithashtu e përkryer e vlefshme.
Ne mund të kemi
pavlefshme funk
e cila merr si argument,
Studenti s
dhe bën diçka me atë student.
Dhe atëherë ne mund të kalojë atë si struct studentëve si të tillë.
Funksion të S1 para.
The struct sillet
tamam si një numër të plotë, kur do të kaloi në një funksion.
Funksion merr një kopje të S1
dhe kështu nuk mund të modifikoni S1;
në vend, vetëm kopja e tij që është ruajtur në S.
Nëse ju doni funksion të jetë në gjendje të modifikojë S1,
funk do të duhet të marrë një * studentëve S,
dhe ju do të duhet të kalojnë S1 me adresë, si të tillë.
Student * S, funk dhe S1.
Ka një tjetër arsye për të kaluar nga adresa këtu.
Çfarë ndodh nëse struct ynë përmban 100 fusha?
Çdo herë të vetme që ne të kalojë një student të funk,
Programi ynë duhet të kopje të të gjitha këtyre fushave në 100 S funk-së argumentit,
edhe në qoftë se ajo kurrë nuk përdor shumicën e tyre.
Pra, edhe në qoftë se funk nuk ka në plan të modifikuar student,
nëse ende mund të jenë të vlefshme për të kaluar nga adresë.
Mirë, çfarë nëse ne duam të krijojmë një tregues për një struct?
Ne mund të bëjmë diçka si
studenti * S
barabartë me malloc
Madhësia e studentit.
Vini re se dimensioni i ende punon këtu.
Pra, si nuk kemi tani qasje anëtarin moshës
e bllokut që pikë për S?
Ju mund të mendoni për të bërë para
* S.age = 4,
por kjo nuk do të mjaft të punojnë.
Pasi kjo do të vërtetë të interpretohet si
* Në kllapa S.age = 4,
e cila nuk do të hartojë,
pasi S nuk është një struct ose më tepër një akrep tek një struct,
dhe kështu nuk do të funksionojë dot këtu.
Ne mund të bëjmë
(* S). Mosha = 4
por kllapat mund të merrni bezdisshëm dhe konfuze.
Fatmirësisht, ne kemi një operator të veçantë shigjetë
që duket diçka si
S-> mosha = 4.
Këto 2 mënyra për të referuar moshës
janë ekuivalente
dhe ne nuk të vërtetë kurrë nevojë për operatorin shigjetë,
por kjo i bën gjërat duken nicer.
Që S është një tregues për një bllok të memories që përmban struct,
ju mund të mendoni S> moshës si më poshtë arrow akrep
dhe kapje anëtarin moshës.
Pra, pse duhet të përdorin kurrë structs?
Është padyshim e mundur për të marrë larg me vetëm integers primitive,
chars, pointers dhe si
se ne jemi përdorur për të;
në vend të S1 dhe S2 para,
ne mund të kemi pasur age1, age2, name1 dhe name2
të gjitha në variablat të ndara.
Kjo është e mirë me vetëm 2 nxënës,
por çka nëse kishim 10 prej tyre?
Dhe çka nëse në vend të vetëm 2 fusha,
struct studenti kishte 100 fusha?
GPA, kurse, ngjyra e flokëve, gjinore, dhe kështu me radhë.
Në vend të vetëm 10 structs, ne kemi nevojë për 1.000 variablave të veçanta.
Gjithashtu, e konsiderojnë një funksion
that merr se struct me 100 fusha me argumentin e saj vetëm
dhe printime nga të gjitha fushat.
Nëse ne nuk e përdorim një struct,
çdo herë të vetme që ne e quajmë atë funksion,
ne kemi nevojë për të kaluar në të gjitha variablave 100,
dhe në qoftë se ne kemi 100 nxënës variablave për 1,
dhe 100 variablave për nxënës, 2
ne duhet të jetë i sigurt që ne nuk aksidentalisht kalojnë disa variabla studenti nga 1
dhe disa variabla studenti nga 2.
Është e pamundur për ta bërë këtë gabim me një struct,
pasi të gjitha 100 variablat janë të përfshira në një paketë të vetme.
Vetëm disa shënime fundit:
Nëse e keni kuptuar gjithçka deri në këtë pikë, e madhe.
Pjesa tjetër e video është vetëm për hir të plotësisë '.
Sepse structs mund të mbajë çdo lloj akrep,
ata gjithashtu mund të mbajë pointers funksion.
Nëse ju jeni të njohur me programimin e orientuar nga objekti,
kjo siguron një mënyrë për të përdorur structs të programit në një stil orientuar nga objekti.
Më shumë pointers funksion në një tjetër kohë.
Gjithashtu, ndonjëherë ju mund të keni 2 structs
përkufizime të cilëve varen nga njëra-tjetra.
Për shembull,
ne mund të kemi struct A,
cila është përcaktuar si
një akrep tek një B struct,
struct B * X,
dhe tani ne mund të kemi një struct B
cila është përcaktuar si një pointer
Një në një struct,
struct A * Y.
Por kjo nuk do të hartojë,
pasi struct B nuk ekziston në kohën që struct A është duke u hartuar.
Dhe nëse ne swap struct A dhe B struct,
atëherë ne vetëm do të lihet me të njëjtin problem;
këtë herë, me struct A nuk ekzistues.
Për të zgjidhur këtë, ne mund të shkruajmë
struct B;
para përcaktimit të struct A.
Kjo është quajtur një deklaratë përpara.
Kjo vetëm lejon përpiluesit e di se
struct B është një lloj i vlefshëm që do të përcaktohen plotësisht më vonë, ose diku tjetër.
Emri im është Rob Bowden, dhe kjo është CS50.
[CS50.TV]