[Powered by Google Translate] [Semajno 4]
[Davido J. Malan] [Universitato Harvard]
[Jen CS50.] [CS50.TV]
>> Bone, ĉi tiu estas CS50, kaj ĉi tiu estas la komenco de la semajno 4,
kaj ĉi tiu estas unu el la plej malrapida ebla ordigo algoritmoj.
Kiu trovis ĝin, ke ni nur rigardis tie?
Tio estis bobelo varo, por granda O (n ^ 2) + sumo,
kaj ja ni ne estas la solaj en ĉi tiu mondo al ŝajnas scii
kio bobelo varo estas aŭ ĝia rula tempo.
Efektive, tiu estis intervjuo kun Eric Schmidt de Google
kaj eksa senatano Barack Obama ĵus antaŭ kelkaj jaroj.
>> Nun, Senatano, vi estas ĉi tie en Google,
kaj mi ŝatas pensi pri la prezidanteco kiel laboron intervjuo.
Nun, estas malfacile akiri laboron kiel prezidanto, kaj vi tuj tra la rigorecoj nun.
Estas ankaŭ malfacile akiri laboron en Google.
Ni havas demandojn, kaj ni petas niajn kandidatoj demandoj,
kaj ĉi tiu estas de Larry Schwimmer.
You guys pensas mi kidding? Estas ĉi tie.
Kio estas la plej efika maniero por ordigi miliono 32-bita entjeroj?
[Ridado]
Nu-
Mi pardonpetas. >> Ne, ne, ne, ne.
Mi kredas ke la bobelo speco estus la malĝustan vojon al iri.
>> Venu, kiu rakontis al li tion?
Pasintsemajne memori ni prenis ripozon de kodo, almenaŭ por unu tago,
kaj komencis enfokusigante iu pli alta nivelo ideoj kaj problemo solvanta pli ĝenerale
en la kunteksto de serĉado kaj ordigi,
kaj ni enkondukis iu kiun ni ne abofetear ĉi nomon sur pasintsemajne,
sed asimptota skribmaniero, la Granda a, la Granda Omega,
kaj kelkfoje la Big Theta skribmaniero, kaj tiuj estis simple manieroj
de priskribanta la rula tempo de algoritmoj,
kiom da tempo ĝi prenas por algoritmo por kuri.
>> Kaj vi povas memori ke vi parolis pri la rula tempo en terminoj de la grandeco
de la enigo, kiu ni ĝenerale nomas n, kion ajn la problemo povas esti,
kie n estas la nombro de homoj en la ĉambron,
la nombro de paĝoj en telefono libro, kaj ni komencis skribi aferojn
kiel O (n ^ 2) aŭ O (n) aŭ O (n log n),
kaj eĉ kiam la math ne sufiĉe ellabori tiel perfekte
kaj estis n ² - n / 2 aŭ io simila
ni anstataŭ simple forĵeti kelkajn el la suba ordo terminoj,
kaj la motivado estas ke ni vere volas
speco de objektiva maniero de taksi
la agado de programoj aŭ la rendimenton de algoritmoj
ke je la fino de la tago havas nenion por fari, ekzemple,
kun la rapido de via komputilo hodiaŭ.
>> Ekzemple, se vi apliki bobelo varo,
aŭ vi apliki kunfandi varo aŭ selektado speco en la hodiaŭa komputilo,
a 2 GHz komputilo, kaj vi kuros ĝin,
kaj ĝi portas iun numeron de duaj, venontjare tie estas 3 GHz
aŭ 4 GHz komputilo, kaj vi povus tiam aserti ke "Wow, mia algoritmo
nun estas duoble rapida, "kiam fakte tio evidente ne estas la kazo.
Estas nur la aparataro alvenis rapida, sed via komputilo
ne, kaj tiel ni vere volas forĵeti aĵojn kiel
obloj de 2 aŭ obloj de 3, kiam temas pri priskribanta
kiel rapide aŭ kiel malrapida algoritmo estas kaj vere nur enfokusigi
sur n aŭ iu faktoro gxiajn
iuj potenco gxiaj kiel en la kazo de la varoj de la lasta semajno.
Kaj memoru ke kun la helpo de merge speco
ni povis fari tion multe pli bone ol bobelo varo kaj selektado speco
kaj eĉ inserción varon.
>> Ni deiris al n logo n, kaj denove,
memori, ke log n ĝenerale aludas al iu kiu kreskas
pli malrapide tiam n, do n logo n tiel multe estis bona
ĉar estis malpli ol n ².
Sed por atingi n log n kun merge speco
kio estis la baza ĝermo de ideo, ke ni devis utiligi
ke ni ankaŭ leveraged reen en semajno 0?
Kiel ni pritrakti la ordiga problemo lerte kun merge speco?
Kio estis la ŝlosilo sagaceco, eble?
Iu ajn.
Konsentite, ni preni retropaŝon.
Ekverku kunfandi varo en viaj propraj vortoj.
Kiel ĝi funkcias?
Konsentite, ni remi reen al semajno 0.
Konsentite, yeah.
[Inaudible-studento]
Okay, bona, do ni dividas la tabelo de nombroj en 2 pecojn.
Ni ordo ĉiu de tiuj pecoj, kaj poste ni kunfandis ilin,
kaj ni vidis ĉi tiun ideon antaŭ de prenante problemo kiu estas tiu granda
kaj batante ĝin en problemo kiu estas tio granda aŭ ĉi granda.
>> Memori la telefono libro ekzemplo.
Memori la mem-kalkula algoritmo de semajnoj,
tiel kunfandi varo estis resumita de ĉi _pseudocode_ tie.
Kiam vi donita n eroj, la unua estis prudento kontroli.
Se n <2 tiam ne faras ion ajn
ĉar se n <2 tiam n estas evidente 0 aŭ 1,
kaj kio se ĝi estas ĉu 0 aŭ 1 estas nenio por ordigi.
Vi faris.
Via listo estas jam bagatele ordo.
Sed alie se vi havas 2 aŭ pli elementoj antaŭeniri kaj dividi ilin
en 2 duonoj, maldekstra kaj dekstra.
Ordigi ĉiu el tiuj duonoj, kaj poste kunfandi la ordo duonoj.
Sed la problemo estas, ke je la unua vido tio sentas kiel ni punting.
Ĉi tiu estas cirkla difino en ke se mi petis vin ordigi tiujn n eroj
kaj vi diras al mi "Bone, bone, ni ordigi tiujn n / 2 kaj tiuj n / 2 elementoj,"
tiam mia sekva demando tuj estos "Belaj, kiel vi ordigi la n / 2 eroj?"
>> Sed pro la strukturo de tiu programo,
ĉar estas ĉi tiu bazo kazo, por tiel diri,
ĉi tiu speciala kazo kiu diras se n estas <iu fiksita valoro kiel 2 reveno tuj.
Ne respondas kun tiu sama cirkulero respondo.
Ĉi tiu procezo, ĉi ciclicidad eventuale fini.
Se mi demandas vin "Ordigi tiuj n eroj," kaj vi diras, "Belaj, ordigi tiujn n / 2,"
tiam vi diros, "Belaj, varo tiuj n / 4, n / 8, n/16,"
eventuale vi dividu per sufiĉe granda nombro
ke vi havos nur 1 ero maldekstren, je kiu punkto oni povas diri,
"Jen, jen ordo sola ero."
Tiam la brilo de ĉi tiu algoritmo ĝis tie estas derivi de la fakto
ke iam vi havas ĉiujn tiujn individue ordo lertaj,
ĉiuj kiuj estas de amplekso 1, kiu ŝajnas esti senutilaj,
iam vi komencas kunfandi ilin kaj kunfandi ilin
vi konstruos fine kiel Rob faris en la video oni fine ordo listo.
>> Sed tiu ideo etendas multe pli tie ordigado.
Estas ĉi tiu ideo enigita en tiu programo konata kiel rekursio,
la ideo laŭ kiu vi estas programo,
kaj solvi iun problemon vi nomas vin,
aŭ metitaj en la kunteksto de programlingvoj vi estas funkcio,
kaj por solvi problemon, vi la funkcio vokas vin
denove kaj denove kaj denove, sed al vi la funkcio
ne povas nomi vin malfinie multaj fojoj.
Eventuale vi devas fundo eksteren, por tiel diri,
kaj havas iom malmola kodita bazo kondiĉo kiu diras
en ĉi tiu punkto halti nomante mem tiel ke la tuta procezo
fine ĝi fakte ĉesas.
Kion tio vere signifas, por recurse?
>> Ni vidu, se ni povas fari simplan, bagatela ekzemplo kun, ekzemple,
3 personoj kun mi ĉi tien sur la scenejo, se iu estas komforta.
1, venu supren, 2 kaj 3.
Se vi 3 volas veni tien.
Se vi volas stari tuj apud mi cxi tie en linio, supozu ke la problemo je mano
estas tre bagatele grafo la nombro de homoj kiuj estas tie.
Sed sincere, mi estas laca de ĉiuj tiuj rakonti ekzemploj.
Tiu tuj prenos iom da tempo, 1, 2, kaj pentras, punkto, ĝi pentras.
Ĝi tuj prenu eterne.
Mi preferas ke nur liberigas tiun problemon aro kun la helpo de-kio estas via nomo?
Sara. >> Sara, tute certe.
Kelly. >> Kelly kaj?
>> Willy. >> Willy, Sara, Kelly, kaj Willy.
Ĝuste nun mi demandis la demando de iu
kiom da homoj sur tiu etapo, kaj mi ne havas ideon.
Tio estas vere longa listo, kaj tiel anstataŭ mi faros ĉi tiu lertaĵo.
Mi tuj demandos la persono apud mi faru la plejparto de la laboro,
kaj unu fojon ŝi estas farita faras la plimulton de la laboro
Mi tuj faros la malplej kvanto de laboro ebla kaj justa aldoni 1
al kiom ŝi respondo estas, do jen ni iru.
Min oni petis kiom da homoj estas en la scenejo.
Kiom da homoj estas en la scenejo de la maldekstra de vi?
Maldekstre de mi? >> Konsentite, sed ne trompi.
Tio estas bona, tio estas ĝusta, sed se ni volas daŭrigi ĉi logiko
ni supozu, ke vi simile volas liberigas tiun problemon al la maldekstra de vi,
tial anstataŭ respondo rekte antaŭeniri kaj simple pasigi la cervo.
Ho, kiom da homoj estas maldekstre de mi?
Kiom da homoj estas por la maldekstra?
1.
[Ridado]
Okay, do 0, tia kiu nun Willy faris
estas vi revenis vian respondon tiu direkto dirante 0.
Nun, kio devus fari? >> 1.
Okay, do vi estas la 1, do vi diras, "Bone, mi iros por aldoni 1
al kiom Willy la grafo estis, "do 1 + 0.
Vi estas nun 1 tial via respondo al la rajto estas nun-
1. >> Kaj mia estus 2.
Bona, do vi prenis la antaŭan respondon de 1,
aldono de la minimuma kvanto de laboro vi volas fari, kiu estas +1.
Vi nun havas 2, kaj vi tiam transdonos al mi, kiu valoro?
3, mi volas diri, sorry, 2.
Bona.
>> Nu, ni devis 0 al la maldekstra.
Tiam ni havis 1, kaj tiam ni aldonas 2,
kaj nun vi transdonis al mi la nombro 2,
kaj tiel Mi dirante bone, +1, 3.
Estas ja 3 personoj starantaj apud mi en ĉi tiu stadio,
tiel ni povus esti evidente faris tion tre lineare,
tre en la evidenta maniero, sed kion ni vere faru?
Ni prenis problemon de amplekso 3 komence.
Ni tiam rompis ĝin al problemo de amplekso 2,
tiam problemo de amplekso 1, kaj tiam fine la bazo kazo
Estis vere, ho, tie estas neniu tie,
je kiu punkto Willy revenis efektive malmola-kodita respondon kelkajn fojojn,
kaj la dua estis tiam bobelis supren, bobelis supren, bobelis supren,
kaj poste per aldono en ĉi tiu aldona 1
ni implementado tiu baza ideo de rekursio.
>> Nun, en tiu kazo ĝi ne vere solvi problemon
neniu pli efike poste ni vidis ĝis nun.
Sed pensi pri la algoritmoj ni faris en la scenejo ĝis nun.
Ni havis 8 pecoj de papero en la chalkboard,
en video kiam Estu serĉis la numero 7, kaj kion li vere faras?
Nu, li ne faris ian ajn dividu kaj regu.
Li ne faris ian ajn rekursio.
Prefere li nur faris tion lineara algoritmo.
Sed kiam ni enkondukis la ideon de ordo numerojn sur la scenejo vivi pasintsemajne
tiam ni havis ĉi instinkto de iri al la mezo,
je kiu punkto ni havis pli malgrandan liston de grandeco 4 aŭ alia listo de grandeco 4,
kaj poste ni havis la ĝusta sama problemo, do ni ripetas, ripetis, ripetita.
Alivorte, ni recursed.
Grandan dankon al niaj 3 volontuloj tie por pruvante rekursio kun ni.
>> Ni vidu se ni ne povas fari ĉi nun iom pli konkreta,
solvanta problemon kiu ni denove povis fari belan facile,
sed ni uzos ĝin kiel ŝtupo al efektivigo de ĉi tiu baza ideo.
Se mi volas komputi la sumado de faskon da nombroj,
ekzemple, se vi pasas en la numero 3,
Mi volas doni al vi la valoro de sigmo 3,
do la sumo de 3 + 2 + 1 + 0.
Mi volas reiri la respondo 6,
do ni havos apliki ĉi sigma funkcio, ĉi sumada funkcio
ke, denove, prenas en enigo, kaj poste redonas la sumado
de tiu numero la tuta vojo malsupren al 0.
Ni povus fari tion sufiĉe simple, ĉu ne?
Ni povus fari tion kun ia looping strukturo,
do lasu min antaŭeniri kaj akiri ĉi komencis.
>> Inkluzivi stdio.h.
Lasu min preni min en ĉefaj por labori kun ĉi tien.
Ni savu tion kiel sigma.c.
Tiam mi tuj iros tien, kaj mi tuj deklaru int n,
kaj mi faros la sekvajn dum la uzanto ne kunlabori.
Dum la uzanto ne donis al mi pozitiva nombro
lasu min iri antaŭen kaj instigas ilin por n = GetInt,
kaj mi donos al ili iom da instrukcioj pri kion fari,
tiel printf ("Pozitiva entjero bonvolu").
Nur iu relative simpla kiel tiu por ke per la tempo ni batis linio 14
ni nun havas pozitiva entjero supozeble en n.
>> Nun ni faru ion kun tio.
Lasu min kaj komputi la sumado, do int sumo = sigmo (n).
Sigma estas nur sumado, do mi simple skribas ĝin en la amatoro vojo.
Ni simple nomas ĝin sigma tie.
Tio estas la sumo, kaj nun mi iros al presi la rezulton,
printf ("La sumo estas% d, \ n", sumo).
Kaj poste mi revenos 0 por bona mezuro.
Ni faris ĉion ĉi programo postulas krom la interesa parto,
kiu estas reale efektivigi la sigmo funkcio.
>> Lasu min iri cxi tie al la fundo, kaj lasu min deklari funkcio sigma.
Oni alvenis al variablo kiu estas de tipo entjero,
kaj kion datumtipo mi volas reveni supozeble de sigmo?
Int, ĉar mi volas ke ĝi kongruas miaj atendoj on line 15.
En ĉi tie lasu min antaŭeniri kaj realigi tiun
en bela simpla maniero.
>> Ni iru antaŭen kaj diru int sumo = 0,
kaj nun mi tuj iros havas iom por buklo tie
ke tuj diri ion kiel tion,
por (_int_ i = 0; mi <= nombro; i + +) sumo + = i.
Kaj poste mi tuj revenos sumo.
Mi povus esti realigita ĉi en ajna nombro de manieroj.
Mi povus esti uzita dum ciklo.
Mi povus esti saltis uzanta la sumo variablo se mi vere volis,
sed en fino, ni nur havas funkcion, ke se mi ne goof deklaras sumo estas 0.
Tiam iterates de 0 sur supren tra la numeron,
kaj sur ĉiu ripeto aldonas, ke la aktuala valoro al sumo kaj poste revenas sumo.
>> Nun, estas malpeza optimumigo tie.
Tio estas probable malŝparis paŝo, sed tiel estu. Ke estas bone por la momento.
Ni estas almenaŭ esti ĝisfunda kaj irante 0 tuta vojo plu supren.
Ne tre forta kaj bela simpla,
sed ĝi rezultas ke kun la sigmo funkcion havas la saman ŝancon
kiel ni faris ĉi tie sur la scenejo.
En la scenejo ni simple rakontitaj kiom da homoj estis apud mi,
sed anstataŭ se ni volis havi la numeron 3 + 2 + 1
malsupren al 0 ni povis simile liberigas al funkcio
ke mi anstataŭ priskribi kiel rekursie.
Jen ni do rapida prudento kontroli kaj certigi mi ne goof.
>> Mi scias ke estas almenaŭ unu aĵo en tiu programo, kiun mi ne faru malbonon.
Kiam mi batis eniri mi povos akiri ia kriante ĉe mi?
Kion mi devas kriis je proksimume?
Jes, mi forgesis la prototipo, do mi uzas funkcio nomita sigma on line 15,
sed ne deklaris ĝis linio 22, do mi pli bona proactivamente iru tien
kaj deklari prototipo, kaj mi diros int sigmo (int nombro), kaj tio estas ĝi.
Ĝi estas implementado malsupre.
>> Aŭ alia maniero mi povus solvi tiun,
Mi povis movi la funkcio tie supre, kio ne estas malbona,
sed almenaŭ kiam via programoj komencos akiri longan, sincere,
Mi kredas ke estas iu valoro en havante ĉiam ĉefa supre
por ke vi en la leganto povas malfermi la dosieron kaj tiam tuj vidos
kion la programo faras sen devi serĉi tra ĝi
serĉas ke ĉefa funkcio.
Ni iru al mia fina fenestro tie, provu fari sigma fari sigma,
kaj mi ŝraŭbita tien ankaŭ.
Implica deklaro de funkcio GetInt signifas Mi forgesis fari kion ajn?
[Inaudible-studento]
Bona, do ŝajne komuna eraro, do ni metis ĉi tien,
cs50.h, kaj nun ni reiros al mia fina fenestro.
>> Mi certe la ekrano, kaj mi rerun fari sigmo.
Ŝajnas esti kompilita. Permesu al mi kuri sigmo.
Mi tajpas en la numero 3, kaj mi ne atingas 6, tiel ne estas rigora ĉeko,
sed almenaŭ ŝajnas esti laboranta ĉe la unua rigardo, sed nun ni ŝiri ĝin aparte,
kaj ni efektive utiligi la ideon de rekursio, denove,
en tre simpla kunteksto por ke post kelkaj semajnoj 'tempo
kiam ni komencos esplori amatoro datumstrukturoj ol arrays
ni havas alian ilon en la ilaron kun kiuj
manipuli tiujn datumstrukturoj kiel ni vidos.
Ĉi tiu estas la ripeta alproksimiĝo, la buklo bazita alproksimiĝon.
>> Lasu min anstataŭ nun faras tion.
Lasu min anstataŭ diri ke la sumado de numero
malsupren al 0 estas vere la sama afero kiel
numeron + sigmo (numero - 1).
Alivorte, samkiel en la scenejo mi punted al ĉiu el la popolo apud mi,
kaj ili laŭvice observis punting ĝis ni fine fundo tra Willy,
kiu devis reveni malmola-kodita respondon kiel 0.
Jen nun ni simile punting al sigmo
la sama funkcio kiel origine nomis, sed la ŝlosilo _insight_ tie
estas ke ni ne nomante sigma idente.
Ni ne pasante en n.
Ni klare pasante en numero - 1,
tiel iomete pli malgranda problemo, iomete pli malgranda problemo.
>> Bedaŭrinde, tiu ne estas sufiĉe solvo ankoraux, kaj antaŭ ni ripari
kio povus esti saltante kiel evidenta en iu el vi
lasu min iri antaŭen kaj rerun fari.
Ŝajnas al kompili okay.
Lasu min rerun sigma kun 6.
Whoops, lasu min rerun sigma kun 6.
Ni vidis tiun antaŭe, kvankam hazarde lasta fojo ankaŭ.
Kial mi akiri ĉi críptico segmentación kulpo? Yeah.
[Inaudible-studento]
Ne bazo kazo, kaj pli specife, kion probable okazis?
Tio estas simptomo de tio, kion konduto?
Diru ĝin iom pli laŭta.
[Inaudible-studento]
Estas senfina ciklo efike, kaj la problemo kun malfinia maŝojn
kiam engaĝi rekursio en ĉi tiu kazo, funkcio kiu nomas sin,
kio okazas ĉiufoje vi nomas funkcio?
Nu, pensu reen al kiel ni planis la memoro en komputilo.
Ni diris, ke tie estas tio eron de memoro nomis la pilo tio ĉe la fundo,
kaj ĉiufoje vi nomas funkcio iom pli memoro gets metis
en ĉi tiu tiel nomata pilo enhavis tiun funkcion de loka variabloj aŭ parametroj,
do se sigma nomas sigma alvokoj sigma nomas sigmo
flamo sigma kie faras ĉi rakonto fino?
>> Nu, finfine overruns la tuta kvanto
de memoro, ke vi havas disponebla por via komputilo.
Vi invadita la segmento kiu vi supozis resti interne,
kaj vi ricevos tiun segmentación kulpo, kerno verŝis,
kaj kion kerno verŝis signifas estas ke mi nun havas dosieron nomatan kerno
kiu estas dosiero enhavanta nuloj kaj
ke vere en la estonteco estos diagnostically utila.
Se ĝi ne estas evidenta al vi kie estas via eraro estas
vi povas reale fari iom de jura analizo, por tiel diri,
en ĉi tiu kerno dump dosiero, kiu, denove, estas nur aro faskon da nuloj kaj
kiu esence reprezentas la staton de via programo en memoro
la momento frakasis tiamaniere.
>> La riparas tie estas ke ni ne povas simple blinde reveni sigma,
la nombro + sigma de iomete pli malgranda problemo.
Ni bezonas havi ian bazon kazo ĉi tie,
kaj kion faru la bazo kazo probable estus?
[Inaudible-studento]
Konsentite, tiel longe kiel la nombro estas pozitiva ni vere revenos ĉi,
aŭ meti alian vojon, se nombro estas, diri, <= al 0
vi scias kion, mi iros antaŭen kaj reveni 0,
multe kiel Willy faris, kaj alie, mi tuj iros antaŭen
kaj revenu ĉi, do ĝi ne estas tiom da mallongaj
ol la ripeta versio kiu ni ekfrapis unua uzante por ciklo,
sed rimarkas ke estas ĉi tia eleganteco al ĝi.
Anstataŭ reveni iu nombro kaj realigante ĉio ĉi math
kaj aldonante aĵoj kun lokaj variabloj
vi anstataŭ diri "Konsentite, se ĉi tiu estas super facila problemo,
kiel la nombro estas <0, lasu min tuj revenos 0. "
>> Ni ne tedi apogas negativaj nombroj,
do mi tuj forte kodo la valoro de 0.
Sed alie, por apliki tiun ideon de sumanta
ĉiuj el tiuj numeroj kune vi povas efektive fari malgrandan mordo
eksteren de la problemo, multe kiel ni faris ĉi tie sur scenejo,
tiam liberigas la resto de la problemo al la sekvanta persono,
sed en ĉi tiu kazo la sekvanta persono estas vi mem.
Ĝi estas idente nomata funkcio.
Nur pasi ĝin pli malgranda kaj pli malgrandaj kaj pli malgrandaj problemo ĉiu tempo,
kaj eĉ se ni ne havas sufiĉe formaligita aĵojn en kodo tie
ĉi tiu estas precize kio okazas en semajno 0 kun la telefono libro.
Tio estas ekzakte kio okazas en pasintaj semajnoj kun Sean
kaj estis kun niaj manifestacioj de serĉanta por nombroj.
Oni prenas problemo kaj dividante ĝin denove kaj denove.
>> Alivorte, ne estas maniero nun traduki
ĉi reala mondo konstruas, tiun altan nivelon konstruo
de dividi kaj venki kaj farante ion ĉiam denove
en kodo, do ĉi tiu estas io ni vidos denove la tempo.
Nun, kiel flanken, se vi estas nova al rekursio vi devus almenaŭ kompreni nun
kial tiu estas amuza.
Mi tuj iros al google.com,
kaj mi tuj serĉi iujn konsilojn kaj lertaĵoj de rekursio, eniru.
Diru al la persono apud vi, se ili ne ridas gxuste nun.
Ĉu vi volas diri rekursio?
Ĉu vi volas diri-ha, tie ni iru.
Okay, nun tio estas la resto de ĉiuj.
Iom Easter egg enigita ie tie en Google.
Kiel flanken, unu el la ligiloj ni surmetis la kurso de afiŝinto
hodiaŭ estas nur tiun kradon de diversaj ordigado algoritmoj,
iuj de kiuj ni rigardis lasta semajno, sed kio estas bela pri tiu videbligo
kiel vi provas kovri vian menson ĉirkaŭ diversaj aferoj rilataj al algoritmoj
scias, ke vi povas tre facile nun starti kun malsamaj tipoj de enigoj.
La enigoj ĉiuj renversis, La enigoj plejparte ordo, la enigoj hazarda ks.
Kiel vi klopodos, denove, distingi tion en via menso
rimarkas ke ĉi tiu URL en la paso de afiŝinto sur Prelegoj paĝo
povus helpi al vi kialon por iu el tiuj.
>> Hodiaŭ ni finfine atingos solvi tiun problemon de kelka tempo reen,
kio estis tiu ĉi interŝanĝo funkcio simple ne funkcias,
kaj kio estis la fundamenta problemo kun ĉi tiu funkcio interŝanĝa,
la celo de kiu estis, denove, por interŝanĝi valoron tie kaj tie
tia, ke ĉi tio okazas?
Ĉi tio ne vere funkcias. Kial?
Yeah.
[Inaudible-studento]
Precize, la ekspliko por ĉi bugginess
simple estis ĉar kiam vi nomas funkcioj en C
kaj tiuj funkcioj preni argumentoj, kiel a kaj b tie,
vi pasas en kopioj de kiom valoron vi havigante al tiu funkcio.
Vi ne estas havigi la originalaj valoroj sin,
do ni vidis tion en la kunteksto de buggyc,
buggy3.c, kiu aspektis iom io tiamaniere.
>> Memori, ke ni havis x kaj y inicializado al 1 kaj 2 respektive.
Ni tiam presitaj el kio ili estis.
Mi tiam asertis, ke mi estis interŝanĝi ilin nomante swap de x, y.
Sed la problemo estis, ke la interŝanĝante laboris,
sed nur en la medio de la interŝanĝa funkcii mem.
Tuj kiam ni batis linio 40 tiuj interŝanĝis valoroj
estis ĵetitaj for, do nenio
en la originala funkcio ĉefa estis vere ŝanĝis tute ne,
do se vi opinias tiutempe pri kio ĉi aspektas kiel en terminoj de nia memoro
se ĉi tiu maldekstra flanko de la tabulo reprezentas-
kaj mi faros mian plejeblon por ĉiuj por vidi ĉi-se ĉi maldekstra flanko de la tabulo
reprezentas, diru vian RAM, kaj la pilo tuj kreskas sur tiun vojon,
kaj ni nomas funkcio kiel ĉefa, kaj ĉefa havas 2 lokaj variabloj, x kaj y,
ni priskribas tiujn kiel x tie, kaj ni priskribas tiujn kiel y tie,
kaj ni metis en la valoroj de 1 kaj 2, do ĉi tie estas ĉefa,
kaj kiam ĉefa nomas la interŝanĝa funkcio la mastruma sistemo
donas la interŝanĝa funkcio propran swath de memoro pri la pilo,
lia propra kadro sur la pilo, por tiel diri.
Ĝi ankaŭ allocates 32 bitoj por tiuj ints.
Ĝi okazas nomi ilin a kaj b, sed tio estas tute arbitra.
Ĝi povus ilin vokis ajn ĝi volas, sed kio okazas kiam ĉefa
alvokoj interŝanĝa estas prenas ĉi 1, metas kopion tie, metas kopion tie.
>> Estas 1 aliaj lokaj variablo en interŝanĝa, kvankam, nomita kio? >> Tmp.
Tmp, do mi donos al mi alian 32 bitoj tie,
kaj kion mi faras en ĉi tiu funkcio?
Mi diris int tmp ricevas, tial havas 1, do mi faris tion kiam ni lastaj ludis kun ĉi tiu ekzemplo.
Tiam ricevas b, do b estas 2, do nun ĉi iĝas 2,
kaj nun b gets temp, do temp estas 1,
tial nun b igas ĉi.
Tio estas granda. Ĝi funkciis.
Sed tiam kiam la funkcio redonas
interŝanĝa la memoro efektive malaperas tiel ke ĝi povas esti reuzata
de iu alia funkcio en la estonteco, kaj ĉefa estas evidente tute senŝanĝe.
Ni bezonas metodo fundamente solvi ĉi tiun problemon,
kaj hodiaŭ ni fine havas vojon por tion fari per
ni povas enkonduki iun nomita puntero.
Rezultas, ke ni povas solvi ĉi tiun problemon
ne per paŝo en kopioj de x kaj y
sed anstataŭ per pasante en kio, ĉu vi opinias, al la interŝanĝa funkcio?
Yeah, kio pri la adreso?
Ni ne vere parolis pri adresoj en multa detalo,
sed se tiu pizarrón reprezentas mia komputilo memoro
ni povus certe komencos numeri la bajtoj en mia memoro RAM
kaj diru ĉi estas bajto # 1, ĉi tiu estas bajto # 2, # 3 bajto,
bajto # 4, bajto # ... 2 miliardoj se mi havas 2 gigabajtoj de RAM,
do ni povus certe venos kun iu ajna kalkulado skemo
por ĉiuj individuaj bajtoj en mia komputilo memoro.
>> Kio se anstataŭ kiam mi vokas interŝanĝa
anstataŭ pasu en kopioj de x kaj y
kial ne mi anstataŭ pasi en la sidejo de x ĉi tie,
la adreso de y tie, esence la poŝta adreso
de x kaj y ĉar tiam interŝanĝi, se li informis
de la adreso en memoro de x kaj y,
tiam interŝanĝi, se ni trejnis lin iom,
li povus potenciale forpelos al tiu adreso, por tiel diri,
x, kaj ŝanĝi la nombron tie, tiam forpelos al la adreso de y,
ŝanĝi la nombron tie, eĉ dum ne vere atingi kopioj de tiuj valoroj mem,
do eĉ se ni parolis pri tiu kiel ĉefa memoro
kaj ĉi tiu estas interŝanĝa la memoro la potencaj kaj la danĝera parto de C
estas ke neniu funkcio povas tuŝi memoro ie ajn en la komputilo,
kaj ĉi tiu estas potenca en kiu vi povas fari tre kapricaj aĵoj kun komputilaj programoj en C.
Tiu estas danĝera ĉar vi povas ankaŭ ŝraŭbo supren tre facile.
Fakte, unu el la plej komunaj formoj por programoj tiuj tagoj por esti ekspluatita
ankoraŭ estas por programisto ne rimarki
ke li aŭ ŝi estas permesante datumoj
esti skribitaj en loko en memoro kiu ne estis intencita.
>> Ekzemple, li aŭ ŝi deklaras tabelo de amplekso 10
sed tiam hazarde provas meti 11 bitokoj en tiun tabelo de memoro,
kaj vi komencos tuŝi partoj de memoro kiu ne plu estas valida.
Nur por contextual tio, kelkaj el vi sciu, ke
programaro ofte vin avertas por seria nombroj aŭ registriĝo klavoj,
Photoshop kaj Word kaj programoj kiel ĉi tio.
Ekzistas fendetoj, kiel kelkaj el vi scias, online, kie vi povas kuri iomete programo,
kaj voila, ne pli peto por seria numero.
Kiel ĝi estas laborante?
En multaj kazoj ĉi tiuj aferoj estas simple trovi en la komputiloj
teksto segmentoj en la komputilo reala nuloj kaj
kie estas tiu funkcio, kie la seria numero petas,
kaj vi anstatauxigas tiu spaco, aŭ dum la programo kuras
vi povas elŝeligi kie la ŝlosilo estas vere stokita
uzante iun nomita erarserĉilo, kaj vi povas fendi programaro kiu vojo.
Tio ne estas diri, ke ĉi tiu estas nia celo por la venonta paro de tagoj,
sed ĝi havas tre reala mondo ramificaciones.
Tiu okazas impliki ŝtelo de la programaro,
sed estas ankaŭ kompromison de tutaj maŝinoj.
>> Fakte, kiam retejoj tiuj tagoj estas ekspluatita
kaj kompromitita kaj datumoj estas filtritaj kaj pasvortoj estas ŝtelitaj
tion tre ofte rilatas al malriĉaj mastrumado de onia memoro,
aŭ, en la kazo de datumbazoj, fiasko anticipi
adversarial enigo, do pli en kiuj en la semajnoj por veni,
sed por nun nur sneak antaŭmontro de la varo de damaĝo, kiun vi povas fari
por ne sufiĉe kompreni kiel aferoj funkcias sub la kapuĉo.
Ni iru pri kompreni kial ĉi estas rompita
kun ilo kiu igos pli kaj pli utila
kiel niaj programoj akiri pli kompleksa.
Tiel malproksime kiam vi havis cimon en via programo
kiel vi iradis, elpurigante ĝin?
Kion viaj teknikoj estis tiel malproksime, ĉu instruis per via TF
aŭ nur memlernanto?
[Studenta] printf.
Printf, do printf estas probable estis via amiko en kiu, se vi volas vidi
kio okazas ene de via programo
vi simple metas printf tie, printf tie, printf tie.
Tiam vi kuros, kaj vi ricevos tutan faskon da aĵoj sur la ekrano
ke vi povas uzi por tiam dedukti kio reale iras malĝustan en via programo.
>> Printf emas esti tre potenca afero,
sed estas tre manlibro procezo.
Vi devas enmeti printf tie, printf tie,
kaj se vi metas ĝin interne de ciklo vi povus ricevi 100 linioj
de eliro, ke vi tiam devas kribri tra.
Ne tre uzantamika aŭ interaga mekanismo por elpurigi programoj,
sed dankeme ekzistas alternativoj.
Jen programo, ekzemple, nomita GDB, la GNU sencimigilo,
kiu estas iom arcano en kiel vi uzas ĝin.
Ĝi estas iom kompleksa, sed sincere,
tio estas unu el tiuj aĵoj kie se vi metas en ĉi tiun semajnon kaj apud
la ekstra horo por kompreni iun kiel GDB
ĝin savos vin probable dekojn da horoj en la longa,
do kun tio, mi donos al vi teaser de kiel tion funkcias.
>> Mi estas en mia fina fenestro.
Lasu min kaj kompili tiun programon, buggy3.
Estas jam ĝis nun.
Lasu min ruli ĝin samkiel ni faris dum dorso, kaj ja, ĝi estas rompita.
Sed kial estas tio? Eble mi ŝraŭbita ĝis la interŝanĝa funkcio.
Eble estas a kaj b. Mi ne sufiĉe movi ilin ĉirkaŭ ĝuste.
Lasu min kaj faros.
Anstataŭ nur kuri buggy3 lasu min anstataŭ kuri ĉi programo GDB,
kaj mi tuj rakontos ĝin kuri buggy3,
kaj mi tuj inkludas komandlinio argumento,-tui,
kaj ni metos tion en estonteco problemoj ĉe spec memorigi.
Kaj nun tiu nigra-blanka interfaco pusxis supren ke, denove,
estas iom blindiga unue ĉar tie estas ĉiuj ĉi
garantio informojn cxi tie, sed almenaŭ estas iu familiara.
En la pinto de la fenestro estas mia reala kodo,
kaj se mi rulumu supren tie lasu min rulumi la plejsupro de mia dosiero,
kaj ja, ekzistas buggy3.c, kaj anonco en la fundo de tiu fenestro
Mi havas ĉi GDB prompto.
>> Ĉi tiu ne estas la sama kiel mia normala John Harvard prompto.
Tio ĉi estas prompto ke tuj permesos ke mi kontroli GDB.
GDB estas erarserĉilo.
Al erarserĉilo estas programo kiu ebligas trairu
ekzekuto de via programo linio por linio por linio,
la vojo faras ion vi volas al la programo,
eĉ nomante funkcioj, aŭ rigardi, pli grave,
ĉe diversaj variablo de valoroj.
Ni faru tion.
Mi tuj iros antaŭen kaj tajpu en afiŝo en GDB la prompto,
tiom rimarkos malsupre maldekstre de la ekrano mi tajpis kuri,
kaj mi batis eniros, kaj kion tiu faras?
Ĝi laŭvorte kuris mia programo, sed mi ne vere vidas multe iru tien
ĉar mi ne vere diris la erarserĉilo
paŭzi en aparta momento en tempo.
Nur tajpi run kuras la programo.
Mi ne vere vidas nenion. Mi ne povas manipuli ĝin.
>> Anstataŭ lasu min fari tion.
En ĉi GDB prompto lasu min anstataŭ tajpi paŭzo, eniru.
Tio ne estas kion mi celis tajpi.
Ni anstataŭ tajpi ripozon ĉefa.
Alivorte, mi volas establi iu nomita Haltpunkto,
kiu estas _aptly_ nomis ĉar ĝi rompos aŭ paŭzo
ekzekuto de via programo en tiu aparta loko.
Artikolo estas la nomo de mia funkcio.
Rimarku ke GDB estas sufiĉe inteligenta.
Ĝi supozis, ke ĉefa okazas komenci malglate ĉe linio 18
de buggy3.c, kaj poste rimarkis tie en supre maldekstre
b + estas tuj apud linio 18.
Tio memorigis min ke mi aperigos Haltpunkto ĉe linio 18.
Ĉi-foje kiam mi tajpas kuras, mi tuj kuras mia programo
supren ĝis batas ke Haltpunkto,
tial la programo faros paŭzon por mi en linio 18.
Ĉi tie ni iros, kuri.
Nenio ŝajnas esti okazinta, sed avizo je fundo forlasis
komencante programo, buggy3, Haltpunkto 1 en ĉefa ĉe buggy3.c linio 18.
Kion mi povas fari nun?
>> Rimarku mi povas ektajpu aĵojn kiel presita,
ne printf, presita x, kaj nun jen stranga.
La $ 1 estas nur vidindaĵo, kiel ni vidos
ĉiufoje kiam vi presas ion vi acxetas novan $ valoro.
Tio estas tiel ke vi povas raporti al antaŭaj valoroj ĉiaokaze,
sed por nun kion print diras al mi estas ke la valoro de x je ĉi tiu punkto en la historio
estas ŝajne 134514032.
Kio? Kien ke eĉ venis?
[Inaudible-studento]
Ja, tio estas, kion ni nomas rubo valoron, kaj ni ne parolis pri tiu ankoraux,
sed la kialo ke vi pravalorizi variabloj
Estas evidente ke ili havas iun valoron, kiun vi volas ilin havi.
Sed la kaptaĵo estas memori, ke vi povas deklari variablojn
kiel mi faris antaŭ momento en mia sigma Ekzemplo
sen efektive donante ilin valoro.
Memori kion mi faris super tie en sigmo.
Mi deklaris n, sed kion valoro ĉu mi donu ĝin?
Neniu, ĉar mi sciis, ke en la venontaj linioj
GetInt okupus de la problemo de meti valoron ene de n.
>> Sed en ĉi tiu punkto en la historio de linio 11
kaj linio 12 kaj linio 13 kaj linio 14
laŭlonge de tiuj pluraj linioj, kio estas la valoro de n?
En C vi simple ne scias.
Estas ĝenerale iu rubo valoron, iuj tute hazarda nombro
ke tio lasis sur esence de iu antaŭa funkcio
estinte kuras, por ke via programo kuras
memori, ke funkcio atingas funkcio, funkcio, funkcio.
Ĉiuj ĉi tiuj kadroj get surmetis memoro, kaj tiam tiuj funkcioj reveno,
kaj kiel mi sugestis per la Eraser lia memoro estas eventuale reutilizado.
Nu, ĝuste tiel okazas ke ĉi variablo x en tiu programo
ŝajnas esti enhavis iujn rubo valoro kiel 134514032
de iu antaŭa funkcio, ne tia mi skribis.
Ĝi povus esti iu kiu venas efike kun la mastruma sistemo,
iu funkcio sub la kapuĉo.
>> Konsentite, ke estas bone, sed ni nun antaŭi al la sekvanta linio.
Se mi tajpas "proksima" en mia GDB prompto kaj mi batis eniros,
rimarki, ke la reliefigante movas malsupren al linio 19,
sed la logika implikacio estas tiu linio 18
nun finita ekzekuti, do se mi denove tajpi "print x"
Mi devus nun vidas 1, kaj fakte, mi faras.
Denove, la $ stuff estas maniero de GDB memorante vin
kion la historio de gravuraĵoj estas ke vi faris.
Nun lasu min antaŭeniri kaj presi y, kaj vere, y estas iu freneza valoro tiel,
sed neniu granda interkonsento ĉar en linio 19 ni estas sur atribui ĝin
la valoro 2, do lasu min tajpi "proksima" denove.
Kaj nun ni estas en la printf linio.
Lasu min fari print x.
Lasu min fari print y. Sincere, mi ricevas iom laca de presi ĉi.
Lasu min anstataŭ tajpi "display x" kaj "ekrano y,"
kaj nun ĉiufoje mi tajpu la komandon en la estonteco
Mi estos memoras kio estas x kaj y, kio estas x kaj y, kio estas x kaj y.
>> Mi povas ankaŭ, kiel flanken, tajpu "info lokaj".
Informoj estas speciala komando.
Lokaj signifas ĝi montras al mi la lokaj variabloj.
Ĉiaokaze mi forgesas aŭ ĉi estas freneza, komplika funkcio
ke mi aŭ iu alia skribis info lokaj diros al vi
kio estas ĉiuj lokaj variabloj ene ĉi tiu loka funkcio
ke vi zorgas pri se vi volas poke ĉirkaŭe.
Nun, printf estas por ekzekuti, tiel ke mi iru antaŭen kaj nur tajpu "sekva".
Ĉar ni estas en ĉi tiu medio ni ne reale vidi ĝin
ekzekuti cxi tie, sed rimarkas ĝin Fariĝas iom disŝiritaj tie.
Sed rimarki ĝi estas supera la ekrano tie,
do ĝi ne estas perfekta programo tie, sed tio estas bone, ĉar mi povas ĉiam poke ĉirkaŭ
uzante print se mi volas.
>> Lasu min tajpi sekva denove, kaj nun jen la interesa parto.
Je ĉi tiu punkto en la historio y estas 2, kaj x estas 1,
kiel sugestis tie, kaj denove,
la kialo ĉi estas aŭtomate montri nun estas ĉar mi uzis la komando
display x kaj y ekrano, do la momento mi tajpas sekva
en teorio x kaj y fariĝu svopitaj.
Nun, ni jam scias ke tio ne tuj estos la kazo,
sed ni vidos en momento kiel ni povas plonĝi profunda eltrovi kial tio estas vera.
Tuj poste, kaj bedaŭrinde, y estas ankoraŭ 2 kaj x estas ankoraŭ 1, kaj mi povas konfirmi tiel.
Print x, presita kaj.
Ja, ne interŝanĝante fakte okazis, do ni komencu la aferon.
Klare interŝanĝa estas rompita.
Ni anstataŭ tajpi "kuri" denove.
Lasu min diri jes, mi volas rekomenci ĝin de la komenco, eniru.
>> Nun mi revenas ĉe linio 18.
Nun rimarki x kaj y estas rubo valoroj denove.
Tuj poste, proksima, sekva, apud.
Se I get bored mi povas ankaŭ simple tajpu n por alia.
Vi povas mallongigi ĝin al la plej mallonga ebla vico de signoj.
Swap nun rompita.
Ni pikita en, tial anstataŭ tajpi proksima,
Nun mi tajpi paŝo por ke mi tretante ene de ĉi tiu funkcio
por ke mi povas marŝi tra ĝi, do mi batis paŝo kaj tiam eniri.
Rimarku ke la reliefigante saltas malsupren suba en mia programo por linio 36.
Nun kio estas la loka variabloj?
Informoj lokaj.
Nenio nur ankoraŭ ĉar ni ne alvenis al tiu linio,
do ni iru antaŭen kaj diri "poste."
Nun ni ŝajnas havi tmp, presita tmp.
Garbage valoro, ĉu ne? Mi kredas tiel.
Kion pri presi, presita b, 1 kaj 2?
En momento, kiam mi tajpas sekva denove
tmp tuj alpreni valoron de 1, espereble,
ĉar tmp tuj estos atribuitaj la valoro de.
>> Nun ni ne presi, presita b,
sed nun presi tmp, kaj estas ja 1.
Lasu min fari. Lasu min fari.
Mi finis la interŝanĝa funkcio.
Mi ankoraŭ ene de ĝi en linio 40, do lasu min presi,
print b, kaj Mi ne zorgas kion tmp estas.
Ĝi aspektas kiel interŝanĝa estas korekta, kiam temas pri interŝanĝi a kaj b.
Sed se mi nun tajpas sekva, mi saltas reen al linio 25,
kaj sendube, se mi tajpu x kaj y print
ili estas ankoraŭ sen ŝanĝoj, do ni ne riparis la problemon.
Sed diagnostically nun eble kun ĉi GDB programo
ni almenaŭ alveninta unu paŝon pli al kompreno
kio okazas erara sen devi portilo nia kodo per meto de printf tie,
printf tie, printf tie kaj tiam kurante ĝin denove kaj denove
provi elkompreni kio okazas erara.
>> Mi tuj iros antaŭen kaj quit el tiu aro kun quit.
Ĝi tuj poste diras, "Quit ĉiuokaze?" Jes.
Nun mi estas ree en mia normala prompto, kaj mi faris uzante GDB.
Kiel flanken, vi ne bezonas por uzi ĉi-tui flago.
Fakte, se vi preterlasas ke vi ricevas esence la fundo de la duono de la ekrano.
Se mi tiam tajpas ripozon ĉefa kaj poste ekzekuti
Mi povas ankoraŭ kuri mia programo, sed kion ĝi faros pli laŭvorte
nur montri al mi la nunan linion unuope.
The-tui, teksta uzantinterfaco,
nur montras al vi pli de la programo samtempe, kio estas verŝajne iom koncepte pli facila.
Sed ja, mi povas nur fari poste, proksima, apud,
kaj mi tuj vidos unu linio samtempe, kaj se mi vere volas vidi kio okazas
Mi povas tajpi listo kaj vidi tutan faskon da apudaj linioj.
>> Jen video kiun ni petis, ke vi rigardas al problemo aroj 3
en kiu Nate kovras iujn de la intricacies de GDB,
kaj ĉi tiu estas unu el tiuj aĵoj, honeste, kie iuj ne-bagatela procento de vi
neniam tuŝi GDB, kaj ke estos malbona
ĉar laŭvorte vi finos pasi pli da tempo poste ĉi semestro
persekutante malsupren erarojn tiam vi estus se vi metas en tiu duonhoro / horo
ĉi tiu semajno kaj apud lernado akiri komforta kun GDB.
Printf estis via amiko.
GDB devus nun esti via amiko.
>> Demandojn sur GDB?
Kaj jen rapida listo de iuj el la plej potenca kaj utila ordonojn.
Yeah. >> Cxu vi povas presi ĉeno?
Ĉu vi povas presi ĉeno? Tute ne.
Ĝi ne devas esti nur entjeroj.
Se variablo s estas ĉeno nur tajpu print s.
Ĝi montros al vi kion tiu ĉeno variablo estas.
[Inaudible-studento]
Ĝi donos al vi la adreson kaj la kordo mem.
Ĝi montros al vi ambaŭ.
Kaj unu lasta afero, nur ĉar tiuj estas bone scii ankaŭ.
Retrospuro kaj kadron, lasu min mergi en ĉi tiu lasta fojo,
sama ekzakta programo kun GDB.
Lasu min antaŭeniri kaj rompi la teksta uzantinterfaco versio,
rompi ĉefa.
Lasu min kaj kuras denove. Jen mi estas.
Nun lasu min iri sekva, apud, apud, apud, apud, paŝo, eniru.
>> Kaj nun supozas ke mi estas nun en interŝanĝa intence, sed mi ŝatas "Malbenita, kio estis la valoro de x?"
Mi ne povas fari x plu.
Mi ne povas fari y ĉar ili ne estas en la medio.
Ili estas ne en kunteksto, sed ne estas problemo.
Mi povas tajpi retrospuro.
Tio montras al mi ĉiujn funkciojn kiuj ekzekutis ĝis ĉi tiu punkto en la tempo.
Rimarku ke la unu sur la fundo, ĉefa, regiono kun ĉefa
esti sur la fundo de nia bildo tie.
La fakto ke interŝanĝa estas super ĝi regiono kun interŝanĝa tretante en memoro tie,
kaj se mi volas reiri al ĉefa provizore mi povas diri "kadro."
Kio numeron? Artikolo estas kadro # 1.
Mi tuj iros antaŭen kaj diru "kadro 1."
>> Nun mi estas denove en ĉefa, kaj mi povas printi x, kaj mi povas printi y,
sed mi ne povas presi aŭ b.
Sed mi povas, se mi diras, "Bone, atendu momenton. Kie estis la interŝanĝa?"
Lasu min kaj diru "kadro 0."
Nun mi estas reen, kie mi volas esti, kaj kiel flanken,
ekzistas aliaj komandoj ankaŭ, kiel se vi vere atingi truita tajpante sekva, apud, apud, tuj poste,
vi povas ĝenerale diri tion kiel "proksimaj 10", kaj kiu havos paŝo tra la proksimaj 10 linioj.
Vi ankaŭ povas skribi "daŭrigi" kiam vi vere get sata tretante tra ĝi.
Daŭrigu kuros via programo sen interrompo ĝis batas alian Haltpunkto,
cxu en ciklo aŭ malsupreniri en via programo.
>> En ĉi tiu kazo ni daŭrigis ĝis la fino, kaj la programo eliris kutime.
Tio ĉi estas ornama metodo, malsupera procezo.
Nur via programo eliris kutime.
Pli sur kiuj en la video kaj en elpurigante kunsidoj veni.
Tio estis tre.
Ni prenu nian 5-minuta paŭzo tie, kaj ni revenos kun structs kaj dosieroj.
>> Se vi plonĝis en ĉi tiu semajno pset jam
vi scias, ke ni uzas en la dissendo kodo,
la fontkodo kiun ni ofertas al vi kiel deirpunkto, iuj novaj teknikoj.
En aparta, ni enkondukis tiun novan ŝlosilvorton nomis struct, por strukturo,
tiel ke ni povas krei akomoditan variabloj de varoj.
Ni ankaŭ enkondukis la nocion de dosiero I / O, dosiero enigo kaj eligo,
kaj ĉi tiu estas por ke ni povu konservi la staton
de via Scramble estraro al dosiero en disko
por ke la instruado uloj kaj mi povas kompreni
kio okazas ene de via programo sen devi permane tuŝi
dekoj da ludoj de Scramble.
Ni povas fari ĉi pli automatedly.
>> Tiu ideo de struct solvas sufiĉe konvinkaj problemo.
Supozu ke ni volas apliki iun programon
ke iel subtenas spuro de informoj pri studentoj,
kaj studentoj havu, ekzemple, oni ID, nomo
kaj domo en loko kiel Harvard, do ĉi tiuj estas 3 pecoj de informo
ni volas konservi ĉirkaŭe, do lasu min antaŭeniri kaj komenci skribi iom programo tie,
inkluzivas stdio.h.
Lasu min fari inkluzivas cs50.h.
Kaj tiam komencos mia ĉefa funkcio.
Mi ne tedos kun ajna komandlinio argumentoj,
kaj tie mi volas havi studento, do mi tuj diros
studento havas nomon, do mi tuj diros "string nomo."
Tiam mi intencis diri studento ankaŭ havas ID, do int id,
kaj studento havas domon, do mi ankaŭ intencas diri "string domo."
Tiam mi mendos tiuj iom pli pure kiel ĉi tio.
Okay, nun mi havas 3 variabloj, per kiu ĝi reprezentas studento, do "studento".
>> Kaj nun mi volas popoli tiuj valoroj, do lasu min antaŭeniri kaj diru ion kiel
"Id = 123."
Nomo tuj akiri Davido.
Diru domo tuj akiri Mather,
kaj tiam Mi faros ion arbitre kiel printf ("% s,
kies ID estas% d, vivas en% s.
Kaj nun, kion mi volas ŝtopi ĉi tien, unu post la alia?
Nomo, id, domo; reveno 0.
Konsentite, se mi ne ŝraŭbita supren ie tie
Mi kredas ke ni havas sufiĉe bona programo kiu stokas unu lernanto.
Kompreneble, ĉi tio ne estas ĉio, kion interesa. Kio se mi volas havi 2 studentoj?
Tio ne estas granda interkonsento. Mi povas apogi 2 personoj.
Lasu min kaj reliefigi tion kaj iru malsupren tie,
kaj mi povas diri "id = 456" por iu kiel Rob kiu vivas en Kirkland.
>> Konsentite, atendi, sed mi ne povas nomi tiujn la saman aferon,
kaj ĝi aspektas kiel mi tuj devos kopii ĉi,
do lasu min diri, ke ĉi tiuj estos David variabloj,
kaj lasu min akiri iuj kopioj de tiuj por Rob.
Ni vokos tiuj Rob la sed tion oni ne tuj funkcias nun
ĉar mi-atendi, ni ŝanĝas min id1, name1 kaj house1.
Rob estos 2, 2.
Mi devas ŝanĝi ĉi tie, tie, tie, tie, tie, tie ĉi.
Atendu, kio pri Tommy? Ni faru ĉi denove.
Evidente se vi ankoraŭ pensas, ke estas bona maniero por tion fari, ne,
tiel kopii / alglui malbona.
Sed ni solvis ĉi antaŭ unu semajno.
>> Kio estis nia solvo, kiam ni volis havi plurajn aperojn de la sama datumtipo?
[Studentoj] An tabelo.
Tabelo, do lasu min provas purigi ĉi supre.
Lasu min fari iujn ĉambron por mi mem ĉe la supro, kaj lasu min anstataŭ fari ĉi tie.
Ni vokos tiuj homoj, kaj anstataŭe mi intencis diri "int IDS,"
kaj mi tuj apogos 3 el ni nun.
Mi intencis diri "string nomoj," kaj mi apogas 3 de ni,
kaj tiam mi iros diri "string domoj," kaj mi tuj apogos 3 de ni.
Nun en ĉi tie anstataŭ Davido atingi sian proprajn lokajn variablojn
ni povas forigi tiuj.
Kiu sentas bone, ke ni purigi ĉi supre.
Mi povas do diri Davido tuj estos [0] kaj nomoj [0]
kaj domoj [0].
Kaj poste Rob ni povas simile ŝpari en ĉi.
Ni metis tiun cxi tie, do li tuj arbitre esti IDS [1].
Li tuj estos nomoj [1],
kaj poste persiste, domoj [1].
>> Ankoraŭ iom teda, kaj nun mi devas kompreni ĉi tion,
do ni diru "nomoj [0], id [0], domoj [0],
kaj ni pluralize ĉi.
IDS, IDS, IDS.
Kaj denove, mi faras, tiel denove, mi jam recurriendo kopii / alglui denove,
tiel malakordo estas tie estas alia solvo ĉi tie.
Mi povas probable purigi ĉi supren plu kun buklo aŭ io simila,
tial en fino, ĝi estas iom pli bona sed ankoraŭ sentas
Mi recurriendo kopii / alglui, sed eĉ tio, mi asertas,
ne estas vere fundamente dekstre solvo ĉar
kion se iam ni decidas vi scias kion?
Ni vere devus esti stokante retadresoj al David kaj Rob
kaj ĉiuj aliaj en ĉi tiu programo.
Ni devas ankaŭ stoki telefonnumerojn.
Ni devas ankaŭ stoki kriz kontakto nombroj.
Ni havas ĉiujn tiujn pecojn de datumoj kiuj ni volas konservi,
tiel kiel vi irados tra fari tion?
>> Vi rakontos alian tabelo supre, kaj tiam vi permane aldoni
retadreson [0], retadreso [1]
al David kaj Rob kaj tiel plu.
Sed estas vere nur supozo suba ĉi dezajno
ke mi uzas la honoron sistemo por scii ke
[I] en ĉiu de la pluraj tabeloj
nur tiel okazas por raporti al la sama persono,
tiel [0] en IDS estas numero 123,
kaj mi tuj supozi ke nomoj [0]
estas la sama persono nomo kaj domoj [0]
estas la sama persono domo kaj tiel plu por ĉiuj el la diversaj tabeloj, ke mi krei.
Sed rimarki ke mankas fundamenta ligo
inter tiuj 3 pecoj de informo, id, nomo kaj domo,
kvankam la ento ni provas modelo en tiu programo ne estas tabeloj.
Arrays estas nur tiun programita maniero fari tion.
Kion ni vere volas modela en nia programo estas persono
kiel Davido, persono kiel Rob ene de kiuj
aŭ encapsulando estas nomo kaj ID kaj domo.
>> Ĉu ni povas iel esprimi ĉi tiun ideon de encapsulación
per persono havas ID, nomo kaj domo
kaj ne recurrir por vere ĉi hack per kiu ni ĵus
konfidi ke krampo ion
rilatas al la sama homa ento en ĉiu el tiuj pafas tabeloj?
Ni povas vere fari tion.
Lasu min iri super ĉefa nuntempe, kaj lasu min krei mian propran datumtipo
cxar vere la unuan fojon.
Ni uzis tiun teknikon en Scramble,
sed tie mi tuj iros antaŭen kaj krei datumtipo,
kaj vi scias kion, mi iros nomi ĝin studento aŭ persono,
kaj mi tuj uzos typedef por difini tipo.
Mi intencis diri, ke ĉi tiu estas strukturo,
kaj tiam ĉi tiu strukturo tuj estos de tipo studento, ni diros,
kvankam ĝi estas iom datita nun por mi.
Ni diras "int id."
Ni diras "string nomo."
Tiam ni diras "string domo,"
tial nun por la fino de tiuj malmultaj linioj de kodo
Mi ĵus instruis clang ke ekzistas
datumtipo krom ints, krom kordoj, krom duobloj, krom flosas.
>> De ĉi tiu momento en tempo linio 11, estas nun nova datumtipo nomata studentoj,
kaj nun mi povas deklari studento variablo ie ajn mi volas,
do lasu min rulumi malsupren tie al la homo.
Nun mi povas forigi tion, kaj mi povas reiri malsupren al David tie,
kaj al David mi povas vere diri, ke David,
ni povas laŭvorte enoficigi la variablo post mi,
tuj estos de tipo studento.
Tio povas aspekti iom stranga, sed ĉi tio ne estas tiom malsimila
anonci ion kiel int aŭ ĉeno aŭ kaleŝego.
Simple tiel okazas esti nomata studenta nun,
kaj se mi volas meti ion ene de ĉi tiu strukturo
Mi nun devas uzi novan pecon de sintakso, sed estas bela simpla,
david.id = 123, david.name = "Davido" en ĉefurbo D,
kaj david.house = "Mather,"
kaj nun mi povas forigi ĉi tiujn aferojn tie.
Rimarku ni nun rediseñado nia programo en vere tre bona maniero
en tiu nun nia programo reflektas la reala mondo.
>> Jen reala mondo nocio de persono aŭ lernanto.
Jen ni havas nun C versio de persono aŭ pli specife studento.
Ene de tiu persono estas tiuj gravaj karakterizaĵoj,
IRU, nomo kaj domo, do Rob esence igas la samon ĉi tie,
tiel studento ŝteli, kaj nun rob.id = 456,
rob.name = "Rob."
La fakto ke la variablo estas nomita Rob estas speco de sensignifa.
Ni povis esti nomis x aŭ y aŭ z.
Ni nur nomis ĝin Rob esti semantike konsekvenca,
sed vere la nomo estas ene de tiu kampo mem,
do nun mi havas ĉi.
Ĉi tro ne sentas kiel la pli bona dezajno en tiu mi forte kodita Davido.
Mi forte kodita Rob.
Kaj mi ankoraŭ devas recurrir al iu kopio kaj gluu ĉiufoje mi volas novan variabloj.
Cetere, mi devas ŝajne doni al ĉiu el ĉi tiuj variabloj nomon,
kvankam mi multe preferas priskribi ĉi tiuj variabloj
pli genéricamente kiel lernantoj.
>> Nun ni povas kunfandi la ideoj kiuj estis laborante bone por ni
kaj anstataŭ diri, "Vi scias kion, donu al mi variablo nomita studentoj,
kaj ni havas ĝin esti de amplekso 3, "do nun mi povas rafini ĉi plui,
forigi la permane deklaris David
kaj mi povas anstataŭe diri ion kiel studentoj [0] tie.
Mi povas do diri studentoj [0] ĉi tie,
studentoj [0] ĉi tie, kaj tiel plu, kaj mi povas iri ĉirkaŭ
kaj purigi ke ĉe Rob.
Mi povus ankaŭ iri nun eble aldonante buklo
kaj uzante GetString kaj GetInt al reale preni tiujn valorojn de la uzanto.
Mi povis iri aldonante konstanta ĉar ĉi tio estas ĝenerale malbona praktiko
al malmola kodo iuj arbitraj numeron kiel 3 dekstra tie
kaj tiam simple memoru, ke vi devus meti ne pli ol 3 studentoj en ĝi.
Estus probable pli bone uzi # difini sur la supro de mia dosiero
kaj faktoro kiu, do ja, lasu min antaŭeniri kaj ĝeneraligi tion.
>> Lasu min malfermi ekzemplo jen inter hodiaŭa
ekzemploj anticipe, structs1.
Tio estas pli kompleta programo kiu uzas # difini ĉi tien
kaj diras, ke ni tuj havas 3 studentoj defaŭlte.
Jen Mi deklarante klaso valoro de studentoj,
tial klasĉambro de studentoj, kaj nun mi uzas buklo
nur por fari la kodon iom pli eleganta, popoli la klaso
kun la uzanto enigo, do persisti de mi = 0 sur supren al studentoj, kiuj estas 3.
Kaj tiam mi instigas la uzanton en tiu ĉi versio
kio estas la studenta ID, kaj mi alvenas gxin per GetInt.
Kio estas la studenta nomo, kaj tiam I get it kun GetString.
Kio estas la studenta domo? I get it kun GetString.
Kaj poste ĉe la malsupro tie Mi nur decidis ŝanĝi
kiom mi presi tiujn el kaj al reale uzi buklo,
kaj kiu mi estas presi?
Laŭ la komento mi presi iun en Mather,
kaj tio estas tiel Rob kaj Tommy ks-reale Tommy en Mather.
Tommy kaj Davido estus presita en ĉi tiu kazo, sed kiel estas ĉi laborante?
Ni ne vidis ĉi tiun funkcion antaŭe, sed preni guess pri kio ĉi faras.
Komparas kordoj.
>> Ĝi estas iom ne-evidenta kiel komparas kordoj ĉar ĝi rezultas
se ĝi redonas 0 kiu signifas la kordoj estas egalaj.
Se ĝi redonas -1 kiu signifu venas alfabete antaux la alia,
kaj se li revenas +1 kiu signifas la alia vorto venas alfabete
antaŭ la alia, kaj vi povas rigardi en linio aŭ la viro paĝo
vidi precize kien estas kio, sed ĉiuj ĉi nun faras estas ĝi estas jene
se la [i]. domo estas egala al "Mather"
tiam iru antaŭen kaj presi tiel kaj tiel estas en Mather.
Sed jen io ne vidis antaŭe, kaj ni revenos al ĉi tio.
Mi ne memoras iam devi fari tion en iu ajn el miaj programoj.
Libera estas ŝajne raportante al memoro, liberigante memoro,
sed kion memoro mi ŝajne liberigante en ĉi buklo en la fundo de tiu programo?
Ĝi aspektas kiel mi liberigante la nomo de persono
kaj persono domo, sed kial estas tio?
>> Ĝi rezultas ĉiuj tiuj semajnoj ke vi estis uzante GetString
ni ia estis enkonduki cimon en ĉiun el viaj programoj.
GetString per dezajno allocates memoro por ke ĝi povas reveni al vi ŝnuron,
kiel Davido, aŭ Rob, kaj vi povos tiam faru kion vi volas
kun tiu ĉeno en via programo ĉar ni rezervis la memoro pri vi.
La problemo estas tiel tempo ĉiufoje vi nomas GetString
ni, la aŭtoroj de GetString, estis petante la mastruma sistemo
doni al ni iom da RAM por ĉi linio.
Donu al ni iom da RAM por ĉi sekva linio.
Donu al ni kelkajn pli RAM por ĉi sekva linio.
Kion vi, la programisto, neniam faras
, donas al ni, ke memoro reen,
tial por tiuj pluraj semajnoj ĉiuj programoj vi skribis
havis kio nomiĝas memoro salton per ili plu uzi
pli kaj pli memoro ĉiufoje vi nomas GetString, kaj tio estas fajna.
Ni intence fari tion en la unuaj semajnoj ĉar ĝi ne estas tiu interesa
devos maltrankviligi kie la kordo venas de.
Ĉiuj vi volas estas la vorto Rob reveni kiam la uzanto tajpas ĝin in
>> Sed movi antaŭen ni nun devas starti atingi pli kompleksa alproksimigas ĉi.
Ajn ni rezervi memoron ni pli bone eventuale transdoni ĝin.
Alie en la reala mondo sur vian Mac aŭ PC vi havu tempo al tempo spertis
simptomoj kie via komputilo estas muelantaj detenis eventuale
aŭ la malsaĝaj ŝpinita strando pilko estas nur okupante la komputilo
tutan atenton kaj vi ne povas fari tion.
Tio povas klarigi por ajna nombro da eraroj, sed inter tiuj eblaj eraroj
estas aferoj nomis memoro filtras per iu, kiu skribis, ke peco de programaro
vi uzas ne memoris al libera memoro
ke li aŭ ŝi demandis la mastruma sistemo por,
ne uzante GetString, ĉar tio estas CS50 afero, sed uzante similajn funkciojn
kiuj petos la mastruma sistemo por memoro.
Se vi aŭ ŝraŭbo supren kaj neniam vere reveni tiu memoro
simptomo de tiu eblas ke programo malrapido kaj bremsas kaj paŭzo
se vi ne memoras nomi libera.
>> Ni revenos al kiam kaj kial vi nomas libera,
sed ni iru antaŭen nur por bona mezuro kaj provu kurante tiu aparta programo.
Ĉi nomis structs1, eniru.
Lasu min kaj kuras structs1, 123, Davido Mather,
456, Rob Kirkland, 789,
Tommy Mather, kaj ni vidu David en Mather, Tommy en Mather.
Tiu estas nur iom prudento ĉeko ke la programo funkcias.
Nun, bedaŭrinde, tiu programo estas iom frustra en tiu
Mi ne ĉiuj kiuj laboras, mi tajpis en 9 malsamaj kordoj, batis eniros,
Oni raportis al kiu estis en Mather, tamen evidente mi sciis kiu estis en Mather jam ĉar mi tajpis ĝin.
Estus almenaŭ agrabla se tiu programo estas pli kiel datumbazo
kaj ĝi efektive memoras kion mi tajpis en
do mi ne plu devas enigo tiuj studento diskoj.
Eble estas kiel registrarial sistemo.
>> Ni povas fari ĉi tion uzante tiun teknikon konata kiel dosiero I / O, dosiero enigo kaj eligo,
tre ĝenerala maniero diri ajn vi volas legi aŭ skribi dosierojn dosieroj
vi povas fari tion per iu aro de funkcioj.
Lasu min kaj malfermu tiun ekzemplon structs2.c,
kiu estas preskaŭ identaj, sed ni vidu kion nun faras.
Sur la supro de la dosiero mi deklaras klaso de studentoj.
Mi tiam popoli la klaso kun la uzanto enigo,
do tiuj linioj de kodo estas ĝuste kiel antaŭe.
Tiam se mi rulumu malsupren tie mi presi ĉiu, kiu estas en Mather arbitre kiel antaŭe,
sed ĉi tiu estas interesa nova trajto.
Tiuj linioj de kodo estas nova, kaj ili enkondukas ion ĉi tie,
DOSIERO, ĉiuj ĉapoj, kaj ĝi havas * en ĉi tie ankaŭ.
Lasu min movi ĉi tien, al * super tie ankaŭ.
>> Ĉi tiu funkcio ne vidis antaŭe, fopen,
sed signifas dosiero malfermita, do ni skim tra ĉi tiuj,
kaj ĉi tiu estas io ni revenos al en estonteco psets,
sed ĉi tiu linio tie esence malfermas dosieron nomatan datumbazo,
kaj specife malfermas ĝin en tia maniero, ke ĝi povas fari kion ĝi?
[Inaudible-studento]
Bone, do "w" nur signifas ĝi estas diras la mastruma sistemo
malfermu tiun dosieron en tia maniero, ke mi povas skribi al ĝi.
Mi ne volas legi ĝin. Mi ne volas nur rigardi ĝin.
Mi volas ŝanĝi ĝin kaj aldoni stuff potenciale al ĝi,
kaj la dosiero estas tuj nomos datumbazo.
Tio povus nomi ion.
Tio povus esti database.txt. Tio povus esti. Db.
Tio povus esti vorto kiel foo, sed mi arbitre elektis nomi la dosieron datumbazo.
Tio estas iom prudento ĉeko ke ni revenos al tre detale kun la tempo,
se fp, por dosiero pointer, ne egala NULL tio signifas ĉio estas bone.
>> Longan rakonton, funkcioj kiel fopen kelkfoje maltrafi.
Eble la dosiero ne ekzistas. Eble vi estas el disko spaco.
Eble vi ne havas permeson por tiu dosierujo,
do se fopen revenas nula io malbona okazis.
Male, se fopen ne revenas nula ĉiuj estas bone
kaj mi povas komenci skribi al ĉi tiu dosiero.
Jen nova artifiko.
Tio estas por buklo ke tio ripetanta super ĉiu el miaj studentoj,
kaj ĉi aspektas tiel simila al kio ni faris antaŭe,
sed ĉi tiu funkcio estas unua de printf nomis fprintf por dosiero printf,
kaj rimarki ke estas malsamaj en nur 2 manieroj.
Unu, ĝi komenciĝas per f anstataŭ p,
sed tiam lia unua argumento estas ŝajne kio?
[Studentoj] Dosiero. >> Estas dosiero.
Tion nomis fp, kiun ni devos eventuale tease aparte kio dosieron puntero estas,
sed por nun fp simple reprezentas la dosiero kiun mi malfermis,
tiel fprintf tie dirante presi ĉi uzanto ID al la dosiero, ne al la ekrano.
Presi la uzanto nomon al la dosiero, ne al la ekrano,
la domo por la dosiero, ne al la ekrano, kaj poste malsupren tie, evidente,
fermi la dosieron, kaj tiam ĉi tie liberan la memoro.
>> La sola diferenco inter ĉi tiu versio 2 kaj versio 1
estas la enkonduko de fopen kaj ĉi DOSIERO kun *
kaj tiu nocio de fprintf, do ni vidu kion la fina rezulto estas.
Lasu min iri al mia fina fenestro.
Mi kuros structs2, eniru.
Aspektas kiel ĉiuj estas bone. Ni rerun structs2.
123, Davido Mather, 456, Rob Kirkland,
789, Tommy Mather, eniru.
Aspektas kiel ĝi kondutis la sama, sed se mi nun faru ls
rimarki kion dosiero estas en ĉi tie inter ĉiuj miaj kodo, datumbazo,
do ni malfermos ke, gedit de datumbazo, kaj rigardu tion.
Ĝi ne estas la sexy de dosiero formatoj.
Vere estas unu peco de datumoj linio por linio por linio,
sed tiuj el vi kiuj uzas Excel aŭ CSV-dosieroj, apartigita de komoj valoroj,
Mi povus certe uzis fprintf al anstataŭ eble fari ion kiel tiu
por ke mi povus vere krei la ekvivalento de Excel dosieron
per disigi aĵojn kun komoj, ne nur novaj linioj.
>> En ĉi tiu kazo se mi anstataŭe uzas komojn anstataŭ novaj linioj
Mi povis laŭvorte malfermu tiun datumbazon dosiero en Excel se mi anstataŭ faris aspekti ĉi.
Mallonge, nun ke ni havas la povon por skribi al dosieroj
ni povas nun starti persistante datumoj, tenante ĝin ĉirkaŭ sur disko
por ke ni povu konservi informon ĉirkaŭe denove kaj denove.
Rimarki kelkajn aliajn aferojn, kiuj estas nun iom pli familiara.
Sur la supro de ĉi tiu dosiero C ni havas typedef
ĉar ni volis krei datumtipo kiu reprezentas vorton,
tial ĉi tiu tipo estas nomitaj vorto, kaj ene de tiu strukturo
ĝi estas iom amatoro nun.
Kial vorto konsistas el ŝajne tabelo?
Kio estas vorto simple intuicie?
>> Ĝi estas aro de karakteroj.
Ĝi estas vico de signoj malantaŭo al malantaŭo al malantaŭo.
LITEROJ en ĉiuj kaskedoj hazarde estas ni arbitre diras la maksimuma longo
de iu vorto en la vortaro ke ni uzas por Scramble.
Kial mi havas +1?
La nula karaktero.
Memori, kiam ni faris la Bananagrams Ekzemple ni bezonis specialan valoron
fine de la vorto por konservi trako
de kie vortoj fakte finiĝis, kaj kiel la problemo aro specifo diras
tie ni renkontas donita vorto bulea valoro,
flagon, por tiel diri, vera aŭ malvera.
Ĉu vi trovis tiun vorton jam, ĉar ni rimarkas
ni vere bezonas metodo memorante ne nur kia vorto estas en Scramble
sed ĉu vi, la homo, trovis ĝin
tiel ke se vi faros trovi la vorton "la" oni povas ne nur tajpi la, eniru, la, eniru, la, eniri
kaj akiri 3 punktoj, 3 punktoj, 3 punktoj, 3 punktoj.
Ni volas povi vortlisto tiun vorton per opcio oni bool
al vera se vi jam trovis ĝin, do jen kial ni
encapsuladas ĝin en tiu strukturo.
>> Nun, cxi tie en Scramble tie estas tio alia struct nomis vortaro.
Ausente tie estas la vorto typedef ĉar en tiu kazo
ni bezonis encapsular la ideo de vortaro,
kaj vortaron enhavas tuta amaso de vortoj,
kiel implicita de ĉi tabelo, kaj kiel multaj el tiuj vortoj estas tie?
Nu, kio ajn tio variablo nomas grandecon diras.
Sed ni nur bezonas unu vortaron.
Ni ne bezonas datumtipo nomata vortaro.
Ni nur bezonas unu el ili, do rezultas en C
ke se vi ne diras typedef, vi simple diru struct, tiam ene la frizita krampoj
vi metis vian variabloj, tiam vi metu la nomon.
Ĉi tiu estas deklari unu variablo nomis vortaro
kiu similas ĉi.
Kontraste, tiuj linioj estas krei reuzebla datumstrukturo nomata vorto
ke vi povas krei plurajn kopiojn de, ĝuste kiel ni kreis
multnombraj ekzempleroj de studentoj.
>> Kion tio finfine permesas al ni fari?
Lasu min iri returne en, ni diru, pli simpla ekzemplo de simpla tempoj,
kaj lasu min malfermi, diru, compare1.c.
La problemo tie en mano estas vere senŝeligi reen
la mantelo de kordo kaj komenci despegando tiuj trejnado radoj
ĉar ĝi rezultas ke ĉeno tiel tempo
Estas kiel ni promesis en semajno 1 vere nur alnomo,
sinonimo de la CS50 biblioteko por iu kiu aspektas iom pli kripta,
char *, kaj ni vidis tiun stelon antaŭe.
Ni vidis ĝin en la kunteksto de dosieroj.
>> Ni nun vidas kial ni estis kaŝante tiun detalon dum iom da tempo nun.
Jen dosiero nomata compare1.c,
kaj ĝi ŝajne demandas al la uzanto por 2 kordoj, s kaj t,
kaj tiam provas kompari tiujn ŝnurojn por egaleco en linio 26,
kaj se ili estas egalaj diras, "Vi tajpis la saman,"
kaj se ili ne estas egalaj diras, "Vi tajpis malsamaj aferoj."
Lasu min kaj kuras ĉi tiu programo.
Lasu min iri al mia fonto dosierujo, faru compare1. Kompilis okay.
Mi kuros compare1.
Mi zomi, eniru.
Diru ion. SALUTON.
Mi diros ion alian fojon. SALUTON.
Mi certe ne tajpi malsamaj aĵoj.
>> Lasu min provi tion denove. Bye Bye.
Certe ne malsama, do kio okazas ĉi tie?
Nu, kio estas vere esti komparitaj en linio 26?
[Inaudible-studento]
Jes, do rezultas ke ĉenon, datumtipo, estas speco de blanka mensogo.
Kordo estas char *, sed kio estas char *?
A char *, kiel ili diras, estas puntero,
kaj puntero estas efektive adreson,
sumo situo en memoro, kaj se vi hazarde havas tajpita en vorto kiel SALUTON,
memori de pasintaj diskutoj de kordoj
ĉi tiu estas kiel la vorto SALUTON.
Memoru ke vorto kiel SALUTON povas esti prezentita
tiel tablo de karakteroj kiel tiu
kaj poste kun speciala karaktero fine vokis la nula karaktero,
kiel la \ signifas.
Kio estas fakte kordoj?
Rimarku ke ĉi tio estas multnombraj pecoj de memoro,
kaj fakte, la fino de ĝi nur konas unu fojon vi rigardas tra la tuta ĉeno
serĉante la specialaj nula karaktero.
Sed se tiu estas peco de memoro de mia komputilo memoro,
ni arbitre diri ke ĉi tiu ĉeno just got bonŝanca,
kaj got metita en la komenco de mia komputilo RAM.
Ĉi tiu estas bajto 0, 1, 2, 3, 4, 5, 6 ...
>> Kiam mi diras ion kiel GetString kaj mi faras string s = GetString
kio vere esti revenis?
Por ĉi tiuj lastaj semajnoj, kio vere esti stokita en s
Ne ĉi kordoj per, sed en tiu kazo kio esti stokita estas
la nombro 0 ĉar kion GetString reale faras
estas ne fizike revenas ĉenon.
Tio ne eĉ vere fari koncepta senco.
Kion ĝi faras reveno estas nombro.
Tiu numero estas la adreso de SALUTON en memoro,
kaj ŝnuro s tiam, se ni senŝeligi reen ĉi tavolo, kordoj ne vere ekzistas.
Tio estas nur simpligo en la CS50 biblioteko.
>> Tiu vere estas io nomata char *.
Char havas sencon ĉar kio estas vorto, kiel SALUTON?
Nu, estas serio de signoj, serio de karakteroj.
Char * signifas la adreson de karaktero,
do kion tio signifas reveni ĉeno?
Bela, simpla maniero de reveni ĉeno
estas anstataŭ provi elkompreni kiel mi revenu al 5 aŭ 6 malsamaj bitokoj
lasu min reveni al la adreso de kiu bitoko?
La unua.
En aliaj vortoj, mi donos al vi la adreson de karaktero en memoro.
Tion char * reprezentas, la adreso de unu sola signo en memoro.
Voku ke variablo s.
Vendejo en s tiu aparta adreso, kiun mi arbitre diris estas 0,
nur por konservi aferojn simplajn, sed fakte ĝi estas ĝenerale pli grandan numeron.
>> Atendu minuton.
Se vi nur donas al mi la adreson de la unua signo, kiel mi scias, kion la adreso estas
de la dua karaktero, la tria, la kvara kaj la kvina?
[Inaudible-studento]
Vi nur scias kie la fino de la linio estas pere de ĉi tiu oportuna lertaĵo,
do kiam vi uzas iun kiel printf, kion printf laŭvorte prenas kiel ĝia argumento,
memori, ke ni uzu ĉi% s lokokupilo, kaj tiam vi pasos en
la variablo ke tio stokante ĉenon.
Kion vi vere pasante estas la adreso de la unua signo de tiu linio.
Printf tiam uzas por buklo aŭ dum buklo sur ricevi tiun adreson,
ekzemple, 0, do lasu min fari tion nun,
printf ("% s \ n" j);
Kiam mi vokas printf ("% s \ n" j); kion mi vere havigante printf kun
estas la adreso de la unua signo en s, kiu en ĉi tiu kazo estas arbitraj H.
>> Kiel printf scias kion ekzakte montri sur la ekrano?
La persono kiu implementado printf implementó dum buklo aŭ por buklo
kiu diras tiu ĉi karaktero egali la specialaj nula karaktero?
Se ne, presi ĝin. Kion pri ĉi tiu?
Se ne presi ĝin, presas ĝin, presas ĝin, presas ĝin.
Ho, ĉi tiu estas speciala. Ĉesu impreso kaj reveni al la uzanto.
Kaj tio estas laŭvorte ĉiuj ke tio estis okazas sub la kapuĉo,
kaj tio estas multe digesti en la unua tago de klaso,
sed por nun estas vere la konstruaĵo bloko de kompreno ĉio
ke tio daŭras interne de nia komputilo memoro,
kaj finfine ni tease ĉi aparte kun iom helpo
de unu el niaj amikoj en Stanford.
>> Profesoro Nick Parlante Stanford faris tion mirinda video sekvenco
el ĉiaj malsamaj lingvoj kiuj enkondukis
tiu malgranda Claymation karaktero Binky.
La voĉo vi pri aŭdi en nur kelkaj dua sneak antaŭmontro
estas tiu de Stanford instruisto, kaj vi ricevas
nur 5 aŭ 6 duaj de ĉi tiu momento,
sed ĉi tiu estas la noto, sur kiu ni konkludi hodiaŭ
kaj komencos la merkredoj.
Mi donas al vi Pointer Fun kun Binky, la antaŭmontro.
[♪ ♪ Muziko] [Profesoro Parlante] Hey, Binky.
Veki. Estas tempo por puntero amuzo.
[Binky] Kio estas tio? Lernu pri punteros?
Ho, Goody!
>> Ni vidos vin merkredon.
[CS50.TV]