[Powered by Google Translate] Poďme hovoriť o structs.
Štruktúry nám poskytujú spôsob, ako skupina veľa premenných spolu
do peknej balenia.
Je to asi najjednoduchší vidieť príklad hneď,
tak hovoríme struct,
potom ľavú zloženú zátvorkou,
a v tomto struct, budeme mať int veku,
char * name,
a to je všetko.
Môže sa to zdať divné bodkočiarkou po ortézy kučeravé,
ale je to v skutočnosti nevyhnutné s structs.
Ľubovoľný platný typ môže ísť do struct definície.
Tu sme použili int a char *,
ale môžete tiež použiť pole, povedzme, 100 prvkov
alebo aj iný struct.
Ak používate structs v C,
ste vytvorenie nových typov
z kolekcie iných typov.
Tu, robíme nový typ
z integer a char *.
Ako uvidíme neskôr, struct typu
je v mnohých ohľadoch rovnocenné so akýmkoľvek iným typom ste zvyknutí.
Obvykle, budem porovnávať, ako struct typ
je podobný celočíselného typu.
Kým kód sme písali je platný C,
to nie je moc užitočné,
a rinčanie sa nám varovanie.
Spomeňte si, ako structs a IDS sú podobné?
No, my sme v podstate len povedal,
int,
ktorá nie je veľmi užitočné línie.
Takže poďme skutočne deklarovať premennú tohto typu
tým, že mu meno pred bodkočiarkou.
Zavoláme premenné študenta.
Teraz sme deklaroval premennú zvanú študenta
s typom danej struct.
Ako sa dostaneme do premennej vnútri struct?
Technicky, mená pre tieto premenné
sú členmi.
Pre prístup k akejkoľvek konkrétnej člena v študentskom struct,
pridáte bodku na názov premennej,
po ktorej nasleduje meno člena, ktorý chcete.
Takže tu, len 2 platné možnosti
sú student.age
a student.name.
A čo môžeme urobiť niečo ako
student.age = 12
a student.name = študent.
Tak čo keby sme chceli, aby sa druhý študenta?
Možno si myslíte, skopírovať a vložiť tieto riadky
a zmeniť študenta k študentovi 2 alebo tak niečo,
a že bude fungovať,
ale technicky, študent a študent 2
nemajú rovnaký typ.
Pozri, nebude môcť priradiť ich k sebe.
To je preto, že tak ďaleko,
Vaša struct bol anonymný.
Musíme dať mu meno.
K tomu, že sme vložte názov struct
za slovo struct.
študent,
nasleduje definícia.
Stále môžeme okamžite deklarovať premennú typu
struct študenta, rovnako ako sme to urobili predtým.
Hovorme tomu S1
Tým, že struct meno,
môžeme teraz používať struct študenta
takmer presne rovnakým spôsobom by sme použiť int.
Takže môžeme deklarovať premennú typu struct študenta,
ako
struct Študent S2.
Rovnako ako polia, structs poskytujú miestne inicializačné syntax,
takže môžeme povedať, že struct Student S2
rovná
ľavá zložená zátvorka 3, S2.
Tu bude S2.age byť 3,
a S2.name bude ukazovať na S2.
Spomeňte si na všetky veci, ktoré môžete urobiť s typu int
a väčšina z nich si môžete robiť s typom struct študenta.
Môžeme použiť struct študenta ako pre typ parametra funkcie.
Môžeme použiť struct študenta vnútri nového struct.
Môžeme mať ukazovateľ na struct študenta.
Môžeme to urobiť veľkosť struct študenta.
Struct študent je typ
rovnako ako int je typ.
Môžeme tiež priradiť S1 na S2
pretože obaja sú rovnakého typu, takže môžeme urobiť
S1 = S2.
Čo sa stane, keď budeme robiť
S1.age = 10?
Má S2 zmenu vôbec?
Opäť, myslím, že z structs len ako bežné celých čísel.
Ak priradíme nejakú int x do určitej int Y,
ako X = Y
a potom zmeniť X,
ako v X + +,
sa Y zmeniť vôbec?
Y nemení tu, a tak nie je ani S2 vyššie.
S2.age je stále 3.
Ale všimnite si, že pri priraďovaní jedna struct do druhého,
všetky ukazovatele stále poukazujú na rovnakú vec,
pretože oni boli práve skopírovali.
Ak nechcete, aby ukazovatele na zdieľanie,
budete musieť ručne spracovať, že
snáď malicking jeden blok pamäte pre jeden z ukazovateľov poukázať na
a kopírovanie dát cez.
To by mohlo byť nepríjemné musieť napísať struct študenta všade.
Použitie typu def, môžeme urobiť
Typ def
struct
a budeme hovoriť študent.
Teraz môžeme použiť študenta všade
že sme používali struct študenta.
Tento typ def je anonymný struct
a nazýva to študent.
Ale ak budeme mať aj naďalej študentské identifikátor
vedľa slova struct, rovnako ako v typedef struct študenta,
by sme mohli použiť aj struct študent a študent zameniteľne teraz.
Oni nemajú ani mať rovnaký názov.
Mohli by sme napísať def struct študenta k Bobovi
a potom struct študenta a Bob
by byť zameniteľné typy.
Bez ohľadu na typ def,
musíme identifikátor vedľa struct
ak definícia struct
je rekurzívny.
Napríklad,
Typ def struct node
a to je definovaný ako int val
a to bude mať ukazovateľ, ktorý ukazuje na iný struct uzol.,
ako v struct uzol * ďalšie.
A potom budeme hovoriť, že uzol.
Táto štruktúra je rekurzívny,
pretože definície struct uzol v sebe obsahuje
ukazovateľ na struct uzol.
Všimnite si, že musíme povedať, struct uzol * ďalšie
vnútri definície struct uzol,
pretože typ def ešte neskončila, ktoré nám umožní zjednodušiť tým,
len na uzle * ďalšie.
Dozviete sa viac o structs podobných tomuto
pri rokovaní s lineárnymi zoznamy a stromy.
Čo structs vo funkcii?
To je tiež dokonale platí.
Mohli by sme mať
void func
ktorá berie ako argument,
Študent s
a niečo s tým študentom.
A potom môžeme odovzdať ako študent struct ako tak.
Func S1 pred rokom.
Struct chová
presne tak, ako by celé číslo, ak funkciu odovzdané.
Func dostane kópiu S1
a tak nemožno zmeniť S1;
skôr len kópia toho, že sú uložené v S.
Ak chcete, aby funkcia, ktorá umožňuje upraviť S1,
func bude musieť vziať študentskú * S,
a budete musieť prejsť S1 podľa adresy, tak ako.
Študent * S, funkcie a S1.
Tam je ďalší dôvod, prečo sa potom podľa adresy tu.
Čo keď sa naše struct obsiahnuté 100 polí?
Zakaždým míňame študenta func,
náš program musí kopírovať všetky tie 100 polí do argumentu S FUNC je,
aj keď nikdy používa drvivá väčšina z nich.
Takže aj keď funkcia nemá v pláne na úpravu študenta,
ak môže ešte byť cenným okolo adresu.
Dobre, čo keď chceme vytvoriť ukazovateľ na struct?
Mohli by sme urobiť niečo ako
Študent * S
rovná malloc
veľkosť študenta.
Všimnite si, že veľkosť stále funguje tu.
Tak ako sme sa už máte prístup k veku člena
bloku, ktorý S body?
Môžete najprv myslieť robiť
* S.age = 4,
ale to nie je úplne fungovať.
Vzhľadom k tomu, to bude naozaj potrebné vykladať v tom
* S.age v zátvorke = 4,
ktoré sa ani zostavovať,
pretože S nie je struct alebo skôr ukazovateľ na struct,
a tak dot tu nebude fungovať.
Mohli by sme urobiť
(* S). Vek = 4
ale zátvorky môže dostať nepríjemné a mätúce.
Našťastie, máme špeciálne šípky operátora
ktorý vyzerá niečo ako
S-> age = 4.
Tieto 2 spôsoby odkazovanie veku
sú rovnocenné
a nemáme naozaj niekedy potrebovať šípky prevádzkovateľa,
ale to robí veci krajšie.
Vzhľadom k tomu, S je ukazovateľ na nejakú blok pamäti, ktorý obsahuje struct,
si môžete myslieť S> veku, sledovať ukazovateľ šípku
a uchopiť vekové člena.
Tak prečo by sme mali vždy používať structs?
Je to určite možné sa dostať preč len s primitívnymi celých čísel,
znaky, ukazovatele a podobné výrobky
že sme zvyknutí;
miesto S1 a S2 skôr,
mohli sme age1, age2, name1 a NAME2
všetko na samostatných premenných.
To je v poriadku, len sa 2 študentov,
ale čo keď sme mali 10 z nich?
A čo keď namiesto toho, aby len 2 polia,
Študent struct mala 100 polí?
GPA, kurzy, farba vlasov, pohlavia, a tak ďalej.
Namiesto iba 10 structs, musíme 1.000 samostatné premenné.
Zvážte funkciu
že berie túto struct s 100 polí s jediným argumentom
a vytlačí všetky polia.
Ak by sme nemali používať struct,
zakaždým hovoríme, že funkcia,
musíme prejsť na všetkých 100 premenných,
a ak máme 100 premenných pre študentov 1,
a 100 premenných pre študentov 2,
musíme byť istí, že nemáte náhodou odovzdať niektoré premenné od študenta 1
a niektoré premenné od študenta 2.
Je nemožné, aby sa tu chybu s struct,
od všetkých 100 premenné sú obsiahnuté v jednom obale.
Len pár záverečných poznámok:
Ak ste všetko pochopil až do tohto bodu, veľký.
Zvyšok videa je len pre úplnosť.
Vzhľadom k tomu, structs môže mať akýkoľvek typ ukazovatele,
môžu tiež držať ukazovateľov funkcií.
Ak ste oboznámení s objektovo orientovaného programovania,
to poskytuje spôsob, ako využiť structs na programe v objektovo orientované štýle.
Viac informácií o funkčných ukazovateľov v inej dobe.
Tiež, niekedy môžete mať 2 structs
ktorých definície sú závislé na seba.
Napríklad,
by sme mohli mať struct,
, Ktorý je definovaný ako
ukazovateľ na struct B,
struct B * X,
a teraz môžeme mať struct B
, Ktorá je definovaná ako ukazovateľ
na struct,
struct * Y.
Ale to nebude zostavovať,
od struct B neexistuje v čase, keď struct je zostavený.
A ak vymeníme struct a struct B,
potom by sme byť jednoducho odišiel s rovnakým problémom;
tentoraz s struct neexistujúce.
Ak chcete vyriešiť tento problém, môžeme písať
struct B;
pred definíciu struct A.
Toto sa nazýva vpred vyhlásenie.
To len nechá kompilátor vedieť, že
struct B je platný typ, ktorý sa bude úplne definované neskôr alebo inde.
Moje meno je Rob Bowden, a to je CS50.
[CS50.TV]