[Powered by Google Translate] Pojďme mluvit o structs.
Struktury nám poskytují způsob, jak skupina spoustu proměnných spolu
do pěkné balení.
Je to asi nejjednodušší vidět příklad hned,
tak říkáme struct,
pak levou složenou závorkou,
a v tomto struct, budeme mít int věku,
char * name,
a to je vše.
Může se to zdát divné středníkem po ortézy kudrnaté,
ale je to ve skutečnosti nezbytné s structs.
Libovolný platný typ může jít do struct definice.
Zde jsme použili int a char *,
ale můžete také použít pole, řekněme, 100 prvků
nebo i jiný struct.
Pokud používáte structs v C,
jste vytvoření nových typů
z kolekce jiných typů.
Zde, děláme nový typ
z integer a char *.
Jak uvidíme později, struct typu
je v mnoha ohledech rovnocenné s jakýmkoli jiným typem jste zvyklí.
Obvykle, budu srovnávat, jak struct typ
je podobný celočíselného typu.
Zatímco kód jsme psali je platný C,
to není moc užitečné,
a řinčení se nám varování.
Vzpomeňte si, jak structs a ITS jsou podobné?
No, my jsme v podstatě jen řekl,
int,
která není velmi užitečné linie.
Takže pojďme skutečně deklarovat proměnnou tohoto typu
tím, že mu jméno před středníkem.
Zavoláme proměnné studenta.
Nyní jsme deklaroval proměnnou zvanou studenta
s typem dané struct.
Jak se dostaneme do proměnné uvnitř struct?
Technicky, jména pro tyto proměnné
jsou členy.
Pro přístup k jakékoliv konkrétní člena v studentském struct,
přidáte tečku na název proměnné,
po níž následuje jméno člena, který chcete.
Takže tady, jen 2 platné možnosti
jsou student.age
a student.name.
A co můžeme udělat něco jako
student.age = 12
a student.name = student.
Tak co kdyby jsme chtěli, aby se druhý studenta?
Možná si myslíte, zkopírovat a vložit tyto řádky
a změnit studenta ke studentovi 2 nebo tak něco,
a že bude fungovat,
ale technicky, student a student 2
nemají stejný typ.
Viz, nebude moci přiřadit je k sobě.
To je proto, že tak daleko,
Vaše struct byl anonymní.
Musíme dát mu jméno.
K tomu, že jsme vložte název struct
za slovo struct.
student,
následuje definice.
Stále můžeme okamžitě deklarovat proměnnou typu
struct studenta, stejně jako jsme to udělali předtím.
Říkejme tomu S1
Tím, že struct jméno,
můžeme nyní používat struct studenta
téměř přesně stejným způsobem bychom použít int.
Takže můžeme deklarovat proměnnou typu struct studenta,
jako
struct Student S2.
Stejně jako pole, structs poskytují místní inicializační syntaxi,
takže můžeme říci, že struct Student S2
rovná
levá složená závorka 3, S2.
Zde bude S2.age být 3,
a S2.name bude ukazovat na S2.
Vzpomeňte si na všechny věci, které můžete udělat s typu int
a většina z nich si můžete dělat s typem struct studenta.
Můžeme použít struct studenta jako pro typ parametru funkce.
Můžeme použít struct studenta uvnitř nového struct.
Můžeme mít ukazatel na struct studenta.
Můžeme to udělat velikost struct studenta.
Struct student je typ
stejně jako int je typ.
Můžeme také přiřadit S1 až S2
protože oba jsou stejného typu, takže můžeme udělat
S1 = S2.
Co se stane, když budeme dělat
S1.age = 10?
Má S2 změnu vůbec?
Opět, myslím, že z structs jen jako běžné celých čísel.
Pokud přiřadíme nějakou int x do určité int Y,
jako X = Y
a pak změnit X,
jako v X + +,
se Y změnit vůbec?
Y nemění zde, a tak není ani S2 výše.
S2.age je stále 3.
Ale všimněte si, že při přiřazování jedna struct do druhého,
všechny ukazatele stále poukazují na stejnou věc,
protože oni byli právě zkopírovali.
Pokud nechcete, aby ukazatele na sdílení,
budete muset ručně zpracovat, že
snad malicking jeden blok paměti pro jeden z ukazatelů poukázat na
a kopírování dat přes.
To by mohlo být nepříjemné muset napsat struct studenta všude.
Použití typu def, můžeme udělat
Typ def
struct
a budeme říkat student.
Nyní můžeme použít studenta všude
že jsme používali struct studenta.
Tento typ def je anonymní struct
a nazývá to student.
Ale pokud budeme mít i nadále studentské identifikátor
vedle slova struct, stejně jako v typedef struct studenta,
bychom mohli použít i struct student a student zaměnitelně nyní.
Oni nemají ani mít stejný název.
Mohli bychom napsat def struct studenta k Bobovi
a pak struct studenta a Bob
by být zaměnitelné typy.
Bez ohledu na typ def,
musíme identifikátor vedle struct
pokud definice struct
je rekurzivní.
Například,
Typ def struct node
a to je definován jako int val
a to bude mít ukazatel, který ukazuje na jiný struct uzel.,
jako v struct uzel * další.
A pak budeme říkat, že uzel.
Tato struktura je rekurzivní,
protože definice struct uzel v sobě obsahuje
ukazatel na struct uzel.
Všimněte si, že musíme říci, struct uzel * další
uvnitř definice struct uzel,
protože typ def ještě neskončila, které nám umožní zjednodušit tím,
jen na uzlu * další.
Dozvíte se více o structs podobných tomuto
při jednání s lineárními seznamy a stromy.
Co structs ve funkci?
To je také dokonale platí.
Mohli bychom mít
void func
která bere jako argument,
Student s
a něco s tím studentem.
A pak můžeme předat jako student struct jako tak.
Func S1 před rokem.
Struct chová
přesně tak, jak by celé číslo, pokud funkci předány.
Func obdrží kopii S1
a tak nelze změnit S1;
spíše jen kopie toho, že jsou uloženy v S.
Pokud chcete, aby funkce, která umožňuje upravit S1,
func bude muset vzít studentskou * S,
a budete muset projít S1 podle adresy, tak jako.
Student * S, funkce a S1.
Tam je další důvod, proč se pak podle adresy zde.
Co když se naše struct obsaženy 100 polí?
Pokaždé míjíme studenta func,
náš program musí kopírovat všechny ty 100 polí do argumentu S FUNC je,
i když nikdy používá drtivá většina z nich.
Takže i když funkce nemá v plánu na úpravu studenta,
pokud může ještě být cenným kolem adresu.
Dobře, co když chceme vytvořit ukazatel na struct?
Mohli bychom udělat něco jako
Student * S
rovná malloc
velikost studenta.
Všimněte si, že velikost stále funguje tady.
Tak jak jsme se již máte přístup k věku člena
bloku, který S body?
Můžete nejprve myslet na to
* S.age = 4,
ale to není úplně fungovat.
Vzhledem k tomu, to bude opravdu být vykládán v tom
* S.age v závorce = 4,
které se ani sestavovat,
protože S není struct nebo spíše ukazatel na struct,
a tak dot zde nebude fungovat.
Mohli bychom udělat
(* S). Věk = 4
ale závorky může dostat nepříjemné a matoucí.
Naštěstí, máme speciální šipky operátora
který vypadá něco jako
S-> age = 4.
Tyto 2 způsoby odkazování věku
jsou rovnocenné
a nemáme opravdu někdy potřebovat šipky provozovatele,
ale to dělá věci hezčí.
Vzhledem k tomu, S je ukazatel na nějakou blok paměti, která obsahuje struct,
si můžete myslet S> věku, sledovat ukazatel šipku
a uchopit věkové člena.
Tak proč bychom měli vždy používat structs?
Je to určitě možné se dostat pryč jen s primitivními celých čísel,
znaky, ukazatele a podobné výrobky
že jsme zvyklí;
místo S1 a S2 dříve,
mohli jsme age1, age2, name1 a NAME2
vše na samostatných proměnných.
To je v pořádku, jen se 2 studenty,
ale co když jsme měli 10 z nich?
A co když místo toho, aby pouze 2 pole,
Student struct měla 100 polí?
GPA, kurzy, barva vlasů, pohlaví, a tak dále.
Namísto pouhých 10 structs, musíme 1.000 samostatné proměnné.
Zvažte také funkci
že bere tuto struct s 100 polí s jediným argumentem
a vytiskne všechna pole.
Pokud bychom neměli používat struct,
pokaždé říkáme, že funkce,
musíme projít na všech 100 proměnných,
a máme-li 100 proměnných pro studenty 1,
a 100 proměnných pro studenty 2,
musíme být jisti, že nemáte náhodou předat některé proměnné od studenta 1
a některé proměnné od studenta 2.
Je nemožné, aby se tu chybu s struct,
od všech 100 proměnné jsou obsaženy v jednom obalu.
Jen pár závěrečných poznámek:
Pokud jste všechno pochopil až do tohoto bodu, velký.
Zbytek videa je jen pro úplnost.
Vzhledem k tomu, structs může mít jakýkoli typ ukazatele,
mohou také držet ukazatelů funkcí.
Pokud jste obeznámeni s objektově orientovaného programování,
to poskytuje způsob, jak využít structs na programu v objektově orientované stylu.
Více informací o funkčních ukazatelů v jiné době.
Také, někdy můžete mít 2 structs
jejichž definice jsou závislé na sebe.
Například,
bychom mohli mít struct,
, který je definován jako
ukazatel na struct B,
struct B * X,
a teď můžeme mít struct B
, která je definována jako ukazatel
na struct,
struct * Y.
Ale to nebude sestavovat,
od struct B neexistuje v době, kdy struct je sestaven.
A pokud vyměníme struct a struct B,
pak bychom být prostě odešel se stejným problémem;
tentokrát s struct neexistující.
Chcete-li vyřešit tento problém, můžeme psát
struct B;
před definici struct A.
Toto se nazývá vpřed prohlášení.
To jen nechá kompilátor vědět, že
struct B je platný typ, který se bude plně definovány později nebo jinde.
Mé jméno je Rob Bowden, a to je CS50.
[CS50.TV]