[Powered by Google Translate] Ni parolos pri structs. Structs provizi nin per maniero kolekti aron da variabloj kune en bela pako. Verŝajne plej facile por vidi ekzemplon al la momento, do ni diru struct, poste malfermante frizita streĉa, kaj en ĉi struct, ni havas int aĝo, a char * nomon, kaj tio estas ĝi. Ĝi povas ŝajni stranga kun punktokomo post frizita streĉa, sed estas fakte necesa kun structs. Neniu valida tipo povas iri en la struct difino. Tie, ni uzis int kaj char *, sed vi povus ankaŭ uzi tabelo, de diru, 100 elementoj aŭ eĉ alian struct. Kiam vi uzas structs en C, vi kreas novan tipoj el kolekto de aliaj tipoj. Tie, ni farante novan tipon el entjera kaj char *. Kiel ni vidos poste, struct tipo estas en tereno de manieroj ekvivalenta al ajna alia tipo vi kutimi. Kutime, mi povas kompari kiel struct tipo estas simila al entjero tipo. Dum la kodo oni skribis validas C, ĝi ne estas tre utila, kaj clang donos al ni averton. Memoru, kiamaniere structs kaj lia estas similaj? Nu, ni esence nur diris int, kiu ne estas tre helpema linio. Do ni vere deklaras variablon de tiu tipo donante al ĝi nomon antaux la punktokomo. Ni vokos la variablo studento. Nun ni deklaris variablo nomita studento kun la tipo donita per la struct. Kiel ni atingos la variabloj ene la struct? Teknike, la nomoj por tiuj variabloj estas membroj. Por aliri ajna aparta membro en studenta struct, vi aldonas punkton al la variablo nomo, sekvata de la nomo de la membro vi volas. Do jen, la nur 2 validajn ebloj estas student.age kaj student.name. Kaj ni povas fari ion kiel student.age = 12 kaj student.name = lernanto. Nun kio se ni volis fari duan studento? Vi povus pensi kopii kaj alglui ĉi tiujn liniojn kaj ŝanĝi lernanto studento 2 aŭ ion, kaj kiu funkcios, sed teknike, lernanto kaj lernantino 2 ne havas la sama tipo. Vidu, vi ne povos atribui ilin al unu la alian. Ĉi tio estas ĉar, ĝis nun, vian struct estis anonima. Ni devas doni nomon. Por fari tion, ni enmetas la nomon de la struct post la vorto struct. studento, sekvata de la difino. Ni povas ankoraŭ tuj deklari variablon de tipo struct studento, kiel ni faris antaŭe. Ni nomas ĝin S1 Por doni la struct nomon, ni povas nun uzi struct studento en preskaŭ la ĝusta sama maniero ni uzus int. Do ni povas deklari variablon de tipo struct studento, kiel struct studento S2. Kiel arrays, structs ofertas ŝparvojo inicialización sintakso, do ni povas diri, struct studento S2 egalas maldekstra frizita streĉa 3, S2. Ĉi tie, S2.age estos 3, kaj S2.name notos al S2. Pensu pri ĉiuj aĵoj vi povas fari kun int tipo kaj la plimulto de ili vi povas fari kun struct studento tipo. Ni povas uzi struct studento kiel tipo de funkcio parametro. Ni povas uzi struct studento ene de nova struct. Ni povas havi puntero al struct studento. Ni povas fari grandeco de struct studento. Struct studento estas tipo samkiel int estas tipo. Ni povas ankaŭ asigni S1 al S2 ekde ambaŭ estas de la sama tipo, do ni povas fari S1 = S2. Kio okazas se ni faros S1.age = 10? Ĉu S2 ŝanĝo ajn? Denove, pensu pri la structs same regula entjeroj. Se ni atribui iun int X al iuj int Y, kiel X = Y kaj poste ŝanĝi X, kiel en X + +, tio Y ŝanĝi ajn? Y ne ŝanĝas tie, do ne faras S2 supre. S2.age estas ankoraŭ 3. Sed rimarku ke kiam atribui unu struct al alia, ĉiuj punteros ankoraŭ indikas la saman aferon, pro tio ke estis nur kopiis. Se vi ne volas ke la punteros esti dividitaj, vi devas permane manipuli ke, eble por malicking unu bloko de memoro por unu el la indikoj atentigi al kaj kopii la datumoj super. Ĝi povus esti ĝena havi skribi struct studento ĉie. Uzanta tipo def, ni povas fari tipo def struct kaj ni nomas ĝin studento. Nun, ni povas uzi studento ĉie ke ni kutimis uzi struct studento. Ĉi tiu tipo def estas anonima struct kaj nomas ĝin studento. Sed se ni ankaŭ subteni la lernanto ensalutilo apud la vorto struct, kiel en typedef struct studento, ni povus uzi ambaŭ struct lernanto kaj studento interŝanĝebla nun. Ili eĉ ne devas havi la sama nomo. Ni povis tajpi def struct studento al Bob kaj tiam struct studento kaj Bob estus interŝanĝebla tipoj. Sendepende de la tipo def, ni bezonas la identigilo apud struct se la difino de la struct estas rekursie. Ekzemple, tipo def struct nodo kaj estos difinita kiel int val kaj ĝi havos puntero kiu notas al alia struct nodo., kiel en struct nodo * proksima. Kaj tiam ni nomas ĝin nodo. Ĉi struct estas rekursie, ekde la difino de struct nodo enhavas en ĝi puntero al struct nodo. Rimarku ke ni devas diri struct nodo * sekva ene de la difino de la struct nodo, ekde la tipo def ne finis ankoraŭ ni permesos simpligi ĉi justaj nodo * proksima. Vi lernos pli pri structs simila al tiu kiam kontraktanta kun ligitaj lertaj kaj arboj. Kio pri structs en funkcio? Ĉi tiu estas ankaŭ perfekte valida. Ni povis esti neniigas func kiu prenas kiel argumento, studento j kaj ĝi faras ion kun tiu studento. Kaj tiam ni povas pasi ĝin kiel studento struct kiel tia. Func de S1 de antaŭ. La struct kondutas precize kiel entjero estus kiam pasis al funkcio. Func ricevas kopion de S1 kaj pro tio ne povas modifi S1; pli ĝuste, nur la kopion de ĝi ke tio stokitaj en S. Se vi volas ke la funkcio por povi modifi S1, func bezonos preni studento * S, kaj vi devos pasi S1 de adreso, kiel tia. Studenta * S, func & S1. Estas alia kialo por preterpasi per adreso tie. Kio se nia struct enhavis 100 kampoj? Ĉiu unuopa momento ni pasis studento al func, nia programo bezonas kopii ĉiujn el tiuj 100 kampoj enen func la argumento S, eĉ se ĝi neniam uzas la vasta plimulto de ili. Do eĉ se func ne intencas modifante la studento, se povas ankoraŭ esti valora por pasi de adreso. Konsentite, kio se ni volas krei puntero al struct? Ni povus fari ion kiel studento * S egalas malloc grandeco de studento. Rimarku ke grandeco de ankoraŭ laboras tie. Nu do kiel ni nun aliri la aĝo membro de la bloko ke S punktoj al? Vi eble unue pensas fari * S.age = 4, sed ĉi tio ne tute funkcias. Ekde ĉi tiu estos efektive esti interpretita kiel * S.age en krampoj = 4, kiu eĉ ne kompili, ekde S estas ne struct aŭ pli ĝuste puntero al struct, kaj tiel la punkto ne funkcios ĉi tie. Ni povus fari (* S). Aĝo = 4 sed la krampoj povas akiri tedas kaj konfuza. Feliĉe, ni havas specialan sago operatoro kiu similas iun kiel S-> aĝo = 4. Tiuj 2 manieroj de referenco aĝo estas ekvivalento kaj ni ne vere iam bezonas la sago operatoro, sed ĝi faras tion aspektas pli bela. Ekde S estas puntero al iu bloko de memoro kiu enhavas la struct, vi povas pensi de S> aĝo kiel sekvi la puntero sago kaj kroĉi la evo membro. Do kial ni cxiam uzas structs? Estas definitive eblas foriri kun nur la komenca entjeroj, signoj, punteros kaj similaj ke ni uzis por; anstataŭ S1 kaj S2 antaŭ, ni povis havi age1, age2, name1, kaj name2 ĉiuj al apartaj variabloj. Ĉi tio estas tre bone kun nur 2 lernantoj, sed kio se ni havis 10 el ili? Kaj kio se anstataŭ nur 2 kampoj, la lernanto struct havis 100 kampoj? GPA, kursoj, haro koloro, sekso, kaj tiel plu. Anstataŭ nur 10 structs, ni bezonas 1.000 apartaj variabloj. Ankaŭ, konsideri funkcion kiu portas tiun struct kun 100 kampoj kun lia sola argumento kaj presas ĉiujn kampojn. Se ni ne uzas struct, ĉiun solan fojon ni nomas tiun funkcion, ni bezonas por pasi tute 100 variabloj, kaj se ni havas 100 variabloj por studento 1, kaj 100 variabloj por studento 2, ni bezonas esti certa ne hazarde pasi iuj variabloj de studento 1 kaj iuj variabloj de studento 2. Estas neeble fari tiun eraron kun struct, ĉar ĉiuj 100 variabloj estas enhavita en sola pako. Nur kelkaj fina notoj: Se vi komprenis cxion ĝis ĉi tiu punkto, granda. La resto de la video estas nur por kompleteco mem. Ĉar structs povas teni ajna tipo de pointer, ili povas ankaŭ teni funkcio punteros. Se vi estas familiara kun objektema programado, ĉi havigas maniero uzi structs plani en objektema stilo. Pli sur funkcio punteros alifoje. Ankaŭ, foje oni povas havi 2 structs kies difinoj dependas de unu alia. Ekzemple, ni povus havi struct A, kiu estas difinita kiel puntero al struct B, struct B * X, kaj nun ni povas havi struct B kiu estas difinita kiel puntero al struct A, struct A * Y. Sed ĉi tio ne kompili, ekde struct B ne ekzistas en la momento ke struct A estas kompilitaj. Kaj se ni interŝanĝi struct A kaj struct B, tiam ni havus nur resti kun la sama problemo; ĉi tiun fojon, kun struct A ne ekzistanta. Por solvi tion ĉi, ni povas skribi struct B; antaŭ la difino de struct A. Tiu nomiĝas antaŭen deklaro. Tiu simple lasas la tradukilo scias, ke struct B estas valida tipo kiu estos plene difinita poste aŭ aliloke. Mia nomo estas Rob Bowden, kaj ĉi tiu estas CS50. [CS50.TV]