>> [Redarea muzicii]
>> David J. MALAN: În regulă.
>> [Râsete]
>> Bine ai venit înapoi.
Aceasta este CS50.
Iar acest final de săptămână cinci.
Și până acum, ne-am cam fost luați de la sine că există
există acest compilator, zăngănit, pe care le-am fost invocat prin intermediul acestui
alt instrument numit face că într-un fel convertește magic codul sursă
în cod obiect, de zerouri și cele care computerele dvs. CPU, Central
unitate de procesare, de fapt înțelege.
Dar se pare că există un număr care este întâmplă sub capotă, în
între intrare și ieșire.
>> Și aș vrea să propun ca am trup că într-un pic mai în detaliu în
aceste patru etape, au ceva numit pre-procesare, ceva
numit compilare, pe care le-am văzut, ceva numit asamblare, și
ceva numit de legătură.
Deci, până în prezent, în unele dintre noastre programe, am avut ascuțite include.
Mai recent am avut ceva ascuțit definește pentru constante.
Deci, se dovedește că acele lucruri pe care sunt precedate de simbolul hash sau
simbolul lira sunt pre-procesor directive.
Asta e doar un mod fantezist de a spune că e o linie de cod care este de fapt
convertit în altceva înainte calculator chiar să încerce să convertească dvs.
Programul de la zero si unu.
>> De exemplu, ascuțit include standardul I / O. H, destul de mult înseamnă doar du-te
înainte, apuca conținutul fișierelor stdio.h și lipiți-le acolo.
Deci, nu zero si unu la acel moment încă.
Este într-adevăr doar o schimbare.
Și că a făcut în așa-numitul etapa de pre-procesare, atunci când
rula de fapt zăngănit sau specific A face în cele mai multe cazuri.
Deci, tot acest lucru sa întâmplat Primul mod automat până acum.
>> Apoi vine etapa de compilare.
Dar am fost simplificat compilare.
Elaborarea unui program înseamnă cu adevărat să ia-o de la ceva de genul C,
codul sursă ne-am scris, în jos la ceva numit de asamblare.
Limbaj de asamblare este un nivel mai mic limbaj care, din fericire, nu vom
are ocazia de mult la scriu acest semestru.
Dar este la cel mai scăzut nivel din sensul că începe literalmente scris
adăuga și scade si se multiplica și încărcați de memorie și de a salva de memorie,
instrucțiuni foarte de bază pe care un calculator, sub capota,
de fapt înțelege.
>> În cele din urmă, asamblare reușește să limbi la zero și cele pe care le-am fost
descriind până acum.
Și într-adevăr în cele din urmă, există așa-numitul care leagă fază, pe care le vom
a se vedea într-o clipă, care combină zerouri dvs. și cei cu zero și
cele ale altor oameni înainte de le-ați creat.
>> Deci, să ia în considerare acest program super-simplu.
Acesta a fost de la Săptămâna 1.
Pur și simplu a declarat, Hello World, de pe ecran.
Am alergat prin acest zăngănit.
Sau am alergat-o prin Asigurați- care a fugit zăngănit.
Și scoase la momentul în care unele zero si unu.
Dar se pare că nu există o etapă intermediară.
Dacă mă duc pe aici - oops, nu Vreau să-l văd încă.
Dacă merg aici la aparat meu și am deschide hello.c, aici
este că același program.
Și ceea ce am de gând să fac în terminalul meu Fereastra aici este am de gând să
rula răsune mai degrabă decât a face, care automatizează toate cele patru
aceste măsuri pentru noi.
Și am de gând să fac să răsune-S și apoi hello.c și apoi introduceți.
>> Și primesc o promptă clipește din nou, ceea ce este bine.
Și acum într-o fereastră ușor mai mare, Am de gând să deschidă gedit aici.
Și am de gând să deschidă un fișier care, se dovedeste, este numit hello.s acest
conține că limbaj de asamblare Am menționat mai devreme.
Și aceasta este ceea ce se numește Adunarea limba, nivel relativ scăzut
instrucțiunile care procesorul Intel sau orice ar fi care este în interiorul
înțelege.
MOV și este pentru a muta. apel este pentru apel, o funcție de nivel foarte scăzut.
Sub este de scădere.
>> Deci, atunci când aveți un anumit procesor interior a computerului, ceea ce face
distincte, comparativ cu alte procesoare de pe de piață, este ceea ce instrucțiuni se
înțelege și de multe ori cât de eficient este, cât de repede este la executarea unor
din aceste instrucțiuni.
Acum, pentru mai mult pe acest lucru, puteți lua următor CS61 toamna la facultate.
Dar aici avem, de exemplu, câteva identificatori care ar putea arata familiar.
hello.c este numele programului.
>> . Text -
nu e mult de interes acolo chiar acum, amintesc că textul
segment, ca de luni, este în cazul în memorie programul de fapt sfârșește.
Așa că, cel puțin vag familiar acolo.
Aici, desigur, este o mențiune funcției nostru principal.
Defilare în jos, acestea se referă la lucruri numitele registre, bucăți foarte mici de
memorie în interiorul procesorului real.
Și dacă derulați în jos chiar în plus, văd un fel
mențiune indirectă a ASCII.
Și acolo, într-adevăr, este că șir, Bună ziua, virgulă, lumea.
>> Deci, pe scurt, acest lucru a fost întâmplă pentru tine, în mod automat,
sub capota tot acest timp.
Și ce sa întâmplat într-adevăr este o dată ați alerga răsune, sau prin
Face, vei primi în primul rând, din codul sursă,
așa-numita limbaj de asamblare.
Apoi răsune este transformarea acestei asamblare Limba până la zero si unu.
Și aceasta este diapozitiv pe care am început discuția noastră în Săptămâna 0 la -
și apoi Săptămâna 1 pe.
Și apoi în final, aceste zerouri și cele sunt combinate cu zero si unu
din acele biblioteci care le-am luat pentru a acordat ca standard I / O sau
Șir Biblioteca sau chiar CS50 biblioteca.
>> Deci, pentru a picta acest tablou mai mult vizual, avem hello.c.
Și, desigur, folosește printf funcționează să spun, salut lume.
Pas compilatie este nevoie de până la că fișierul am văzut doar hello.s, chiar
însă care este de obicei șterse în mod automat pentru tine.
Dar asta e codul de asamblare în etapa de mijloc.
Și atunci când vom asambla asamblare limba, ca să spunem așa, atunci te
obține cele zero si unu.
Deci, ne-am mărit în mod eficient de azi pe ceea ce ne-am luat de la sine,
înseamnă a merge codul sursă față de codul obiect.
>> Dar în cele din urmă, acum că aceeași imagine - haideți să-l împinge pe la
în partea stângă.
Și rețineți că în partea de sus acolo Am menționat stdio.h.
Acesta este un fișier pe care l-am inclus în aproape toate
programe pe care le-am scris.
Și asta e fișierului al cărui conținut Ia copia lipit,
în mod eficient varful codul.
Dar se pare că, pe un calculator Sistemul de undeva, există probabil un
fișier stdio.c că cineva a scris ani Acum că pune în aplicare toate
Funcțiile care au fost declarate în stdio.h.
>> Acum, în realitate nu este, probabil, pe Mac sau PC-ul sau chiar în
CS50 aparat este un cod C crud.
Cineva deja compilat și inclus . O fișier de cod obiect sau. O
dosar, care se referă la o bibliotecă partajată care a fost pre-instalate și
pre-compilate pentru tine.
Dar să presupunem că într-adevăr există pe stdio.c nostru de calculator în paralel
cu zăngănit.
Codul dvs. a fost compilat și asamblate.
Cod stdio.c 's este compilat și asamblate, astfel încât această ultimul
pas, aici jos, trebuie să cumva link-ul, ca să spunem așa, zerouri dvs. și cei
cu zero si unu sale într-un singur program simplu, care în cele din urmă este
numit doar Buna ziua.
>> Deci, asta e tot de magie care este sa întâmplat până acum.
Și va continua să ia aceste procese pentru a acordat, dar dau seama
există o mulțime de detalii picante merge pe dedesubt acolo.
Și aceasta este ceea ce face dvs. calculator cu procesor Intel interior
în special distinct.
>> Astfel, pe această notă, dacă doriți să alaturi de noi pentru masa de prânz vinerea aceasta, se duc
la locul cs50.net/rsvp obișnuit, 13:15 vineri.
Și acum câteva anunțuri.
Deci, avem o veste bună.
Și avem niște vești proaste.
Începe cu o veste bună aici.
>> [Geme]
>> Bine.
Ei bine, este punct de vedere tehnic o vacanță, astfel încât nu este atât de mult un cadou de la noi.
Dar apoi vestea proastă desigur.
>> [Geme]
>> Mi-am petrecut o mulțime de timp pe aceste animații.
>> [Râsete]
>> Va exista o sesiune comentariu aceasta vine luni.
Acesta va fi la ora 05:30.
Noi vă va aminti de toate aceste detalii prin e-mail pe cursul de
site-ul în doar câteva zile de timp.
Acesta va fi filmat și pus la dispoziția la scurt timp după aceea.
Deci, dacă nu puteți face că luni slot de noapte, nu vă faceți griji.
Secțiunile în această săptămână vine va fi, de asemenea, se concentreze pe analiza de test.
În cazul în care secțiune este de luni, care este într-adevăr vacanță universitate, vom
îndeplinesc în continuare în secțiunea.
Dacă pur și simplu nu se poate face ca secțiune pentru că ai de gând
departe, asta e bine.
Participa la o zi de duminică sau marți secțiune sau ton, în secțiunea lui Jason, care este
disponibil on-line.
>> Deci, mai multe vești proaste.
Deci, în conformitate cu programa, avem prelegere vinerea viitoare.
Dar vestea bună -
în mod clar, am petrecut prea mult timp pe aceasta.
>> [Râsete]
>> Vom anula lângă cursurile de vineri.
Astfel că va fi un cadou pentru noi, astfel încât să poate avea într-adevăr un răgaz frumos în
între această săptămână și două de săptămâni, prin urmare.
Deci, nu prelegeri săptămâna viitoare, doar o mică test mic, pentru care ar trebui să fie
ce în ce mai entuziasmat.
>> Așa că haideți să ne îndreptăm acum atenția asupra ceva care este într-adevăr mai mult vizual
și mai interesant și pentru a seta scena pentru ceea ce va fi la orizont
în doar câteva săptămâni de timp.
Dupa primul test, vom transforma concentra de seturi problema noastră la un alt
problemă specifică domeniului, acela al criminalistica sau de securitate în general.
>> De fapt, tradiția cu această problemă Setul este pentru mine una din
predare colegi sau AC a mers pe jos peste campus luarea unor fotografii ale
oameni evidente identificabile, dar nu, locuri sau lucruri, atunci in fiecare an am
reuși cumva să ștergeți accidental sau la deteriorarea cardului digital media
care este în interiorul din camera noastră.
Dar nu e mare lucru.
Eu pot merge mai departe și conectați că în calculatorul meu.
Eu pot face o imagine medico-legale de ea, așa de a vorbi, prin copierea zerouri și
Cei de pe acea cartelă de memorie, dacă de un card SD sau card compact flash sau
indiferent ca esti familiarizat cu.
Și atunci putem preda asta.
>> Și astfel provocarea înainte, printre altele, lucruri pentru tine, va fi de a scrie
Cod C, care recupereaza o grămadă de JPEG pentru mine și a arătat vor fi
acei oameni, locuri sau lucruri.
Și vom vorbi de asemenea, în această problemă stabilit și în zilele următoare, despre
grafica mai general.
Noi le-am folosit, un curs, pentru izbucni.
Dar ai un fel de luate pentru a acordat există aceste noțiuni la nivel înalt
de dreptunghiuri și ovale.
Dar sub capota există pixeli.
Și a trebuit să înceapă gândesc la ele.
Sau va pentru p-set 4 trebuie să se gândească despre decalajul dintre cărămizi, cum
repede te mingea se deplasează pe ecranului pentru izbucni.
Deci, nu există această noțiune a puncte de pe ecran care este
intrat deja în joc.
>> Acum, ceea ce vezi, însă, este ceea ce te pe un ecran de computer.
Dacă ați privit vreodată ceva bun sau TV rău, șansele sunt destul de mult
trata publicul ca technophobes care nu prea
știu prea multe despre calcul.
Și astfel este foarte ușor pentru poliție detectiv să spun, nu-i asa
curat asta pentru mine?
Sau spori, nu?
Spori este ca și cum cuvântul Buzz în cele mai multe orice spectacol legate de crima.
Iar realitatea este, dacă luați o foarte imagine neclara a unui suspect face
ceva rău, nu puteți doar spori ea.
Nu se poate mări la infinit.
Nu se poate vedea în licărire a cuiva ochi care a comis că
special, a criminalității, în ciuda Prevalența acestui la TV.
>> Și astfel, cu care să motiveze care problema viitoare set cu o privire la
unele spectacole cu care s-ar putea să fie familiarizat.
>> [Redare video]
>> -OK.
Acum, sa trecem o privire bine la tine.
>> L-Stai.
Rulați-o înapoi.
>> -Stai un minut.
La dreapta.
>> -Acolo.
Freeze asta.
>> Screen-complet.
>> -OK.
Freeze asta.
>> Strângeți-up pe care, da?
>> Vector-in pe tipul ăla de roata din spate.
>> -Zoom in chiar aici, pe acest loc.
>> -Cu echipamentul potrivit, ca imagini poate fi extinsă și ascuțit.
>> -Ce-i asta?
>> -Este un program de îmbunătățire.
>> -Poți clar că la orice?
>> -Nu stiu.
Să-l consolideze.
>> -Consolidarea secțiunea A-6.
>> -Am îmbunătățit detaliu și -
>> -Cred că e de ajuns pentru a spori.
Eliberați-l la ecranul meu.
>> -Consolidarea reflecție în ochii ei.
>> -Să facem acest lucru prin Caracteristici superioare video.
>> -Edgar, poți îmbunătăți acest lucru?
>> -Stai.
>> -Am lucrat la această reflecție.
>> -Cineva reflecție a lui.
>> -Reflecție.
>> -E o reflexie din fața omului.
>> -Reflecție.
>> -E o reflexie.
>> -Mări oglinda.
>> -Puteți vedea o reflecție.
>> -Poți să consolideze imaginea de aici?
>> -Poți să-l spori chiar aici?
>> -Poți să-l consolideze?
>> -Putem îmbunătăți acest lucru?
>> -Poți să-l consolideze?
>> -Stai o secundă, voi spori.
>> -Zoom in pe ușă.
>> -X10.
>> -Zoom.
>> [Râsete]
>> Mutați-inch
>> -Stai, oprește-te.
>> Oprește-te.
>> L-pauză.
>> -Rotiți cu 75 de grade în jurul vertical te rog.
>> [Râsete]
>> Oprește-te, și înapoi la partea despre usa din nou.
>> -Ai o imagine potențiator care poate bitmap?
>> -Poate putem folosi Pradeep Sen metoda de a vedea în ferestre.
>> -Acest software este stare de arta.
>> -Valoarea icoana este oprit.
>> -Cu dreptul de asociere de algoritmi.
>> -A luat algoritmi de iluminare la nivelul următor și le pot folosi pentru a
spori această fotografie.
>> -Lock pe mări și z-axa.
>> -Enhance.
>> -Îngheț și de a spori.
>> [END redare video]
>> David J. MALAN: Set de problemă, astfel 5 este ceea ce ne așteaptă acolo.
Deci, vom avea în curând o mai bună înțelegere de când și de ce puteți
și a noastră nu poate spori în acest fel.
Dar, mai întâi, să se întoarcă atenția noastră la unele dintre pietrele de temelie vom
trebuie să fie în măsură să spună povestea.
>> Astfel amintesc că am desenat această imagine pe Luni și un pic de săptămâna trecută.
Și aceasta descrie aspectul de lucruri în memoria computerului atunci când
care rulează un alt program.
Segmentul Tech până sus, rechemare, se referă la zerourile reale și cele
care compun programul dumneavoastră.
Există, de mai jos, care, ceva inițializat sau date neinițializate, care de obicei
se referă la lucruri cum ar fi constante sau siruri de caractere sau variabile globale care au
fost declarate în prealabil.
Există grămadă, dar vom veni înapoi la faptul că într-un pic.
>> Și apoi există stiva.
Mai mult ca un teanc de tăvi în cafenea, acest lucru este în cazul în care memoria devine
stratificat și stratificat ori de câte ori faci ceea ce într-un program?
Care este utilizarea stiva pentru?
>> Da?
>> Call of funcției.
De fiecare dată când a apela o funcție, e acordată așchie de memorie pentru ușurința
variabile locale sau parametrii săi.
Și pictural, vom vedea că, cu fiecare Funcția succesive numit, atunci când o
apeluri B apeluri C apeluri D, ele te stratificat pe stiva.
Și în fiecare dintre aceste felii de Memoria este în esență un scop unic
pentru această funcție, care, desigur, este problematic dacă vrei să dai
la o funcție la alta O bucată de date pe care îl doriți
pentru a evolua sau schimba.
>> Deci, ce a fost soluția noastră pentru a permite O funcție reprezentată de unul stivă
cadrul pentru modificarea memoriei interior de un alt cadru stivă?
Cum cei doi vorbesc cu una de alta?
Astfel de mod de indicii sau adrese, care, din nou, doar în cazul în care descrie în
memorie, prin intermediul unui anumit numărul de muscatura, special
Valoarea poate fi găsit.
Deci, amintesc ultima dată prea am continuat povestea și se uită la un
destul program de buggy.
Și acest program este buggy pentru câteva motive, dar cel mai îngrijorătoare este
pentru că nu reușește să verificați ce?
>> Da, nu reușește să verificați de intrare.
Îmi pare rău?
>> Daca este mai mult de 12 caractere.
Deci, foarte inteligent, atunci când se solicită memcopy, care, așa cum sugerează și numele, doar
copii de memorie de la al doilea argument în primul argument.
Al treilea argument, foarte inteligent, este verificate pentru a vă asigura că nu
copia mai mult, în acest caz, lungimea de bar, numărul de caractere,
în destinație, care este aceasta matrice C. Dar problema este că ceea ce
dacă C în sine nu este suficient de mare să se ocupe de asta?
Te duci pentru a copia numărul de bytes că ați fost dat.
Dar ce au de fapt mai mult bytes decât aveți spațiu pentru?
>> Ei bine, acest program foarte prostește doar orbește purcede să ia orice e
având în vedere, salut backslash 0 este mare în cazul în care șirul este scurt
destul de, cum ar fi de cinci caractere.
Dar dacă e de fapt 12 caractere sau 1.200 de caractere, am văzut ultima oară
ca esti doar de gând să complet suprascrie memorie
nu-ți aparține.
Și cel mai rău caz, dacă vă suprascrie că Partea roșu acolo că am numit
reveni adresa -
aceasta este doar în cazul în care computerul în mod automat, pentru tine, în spatele
scene, inveleste departe o valoare pe 32 de biți, care amintește-l la ce adresă ar trebui
se întoarcă atunci când foo, această altă funcție, se face executare.
Este un miez de pâine de felul la care se întoarce.
Dacă vă suprascrie care, potențial, dacă tu ești tipul rău, poate ar putea
ar putea prelua computerul cuiva.
Și veți mai sigur prăbuși l în cele mai multe cazuri.
>> Acum, această problemă a fost doar exacerbată așa cum am început să vorbim despre memorie
management general.
Și malloc, pentru alocarea de memorie, este un Funcția pe care le putem folosi pentru a aloca
de memorie atunci când nu știm în avans pe care am putea avea nevoie de ceva.
Deci, de exemplu, dacă mă duc înapoi a aparatului aici.
Și am deschis de la ultima hello2.c timp, amintesc acest program de aici, care a analizat
ceva ca aceasta, doar trei linii -
Spuneți-vă numele, apoi numele șir, pe stânga, egal getstring.
Și apoi l-am imprimați, numele utilizatorului.
>> Deci asta a fost un program foarte simplu.
Pentru a fi clar, lasă-mă să merg mai departe și să salut-2.
Am de gând să fac dot slash salut-2.
Spuneți-vă numele -
David.
Enter.
Bună David.
Se pare că funcționează bine.
Dar ce se întâmplă cu adevărat pe sub capota aici?
În primul rând haideți să coaja înapoi câteva straturi.
String este doar un sinonim ne-am a dat seama pentru ce?
Stele char.
Deci, haideți să-l un pic mai Arcane dar mai corect punct de vedere tehnic că această
este o stea char, ceea ce înseamnă că numele, da, este o variabilă.
Dar ceea ce magazine nume este adresa de un caracter, care se simte un pic ciudat
pentru că mă întorc un șir.
Primesc inapoi multiple caractere nu un char.
>> Dar, desigur, ai nevoie doar de prima adresa lui Char să-și amintească unde
șir întreg se datorează faptului că de ce?
Cum iti dai seama unde la sfârșitul anului șirul este cunoașterea început?
Zero backslash.
Deci, cu aceste două indicii îți dai seama înainte de începutul și sfârșitul
orice șir sunt, atât timp cât acestea sunt corespunzător format cu care nul
terminator, care la zero backslash.
>> Dar acest lucru este de asteptare getstring.
Și se pare că getstring în tot acest timp a fost un fel de
inseala pentru noi.
A făcut acest lucru, pentru a fi sigur, obținerea unui șir de la utilizator.
Dar unde-i că memoria au venit de la?
Dacă ne întoarcem la imaginea de aici și se aplică definiția de la doar o
în urmă clipă, că stiva este cazul Memoria merge atunci când funcțiile sunt numite,
prin care logica, atunci când apelați getstring, și apoi am tastați
D-O-V-I-D Se precizează, dacă este D-A-V-I-D backslash zero, stocate, bazată pe
Povestea ne-am ne-a spus acum?
>> S-ar părea să fie în stiva, nu?
Atunci când apelați obține șir veți obține o felie de memorie pe stiva.
Deci, este evident motivul pentru care D-A-V-I-D este stocat backslash la zero
acolo în stivă.
Dar stai un minut, getstring revine că șir, ca să spunem așa, ceea ce înseamnă
e tava de la cantina este luat de pe stivă.
Și am spus data trecută că de îndată ce un returnează funcția, și vă voi lua ca
tavă, ca să spunem așa, de pe stiva, ceea ce puteți asuma despre resturile de
că memoria?
Am un fel de ele redesenat ca semne de întrebare deoarece ele devin în mod eficient
Valorile necunoscute.
Ele pot fi refolosite atunci când unele Funcția următoare este numit.
>> Cu alte cuvinte, dacă se întâmplă să fie stocarea -
Voi desena o imagine rapidă aici a stivei.
Dacă se întâmplă să fie de desen în partea de jos din segmentul meu de memorie, și vom spune
că acesta este locul de memorie ocupate de principal și poate arg c și
arg V și orice altceva în program, atunci când getstring este numit,
probabil getstring devine o bucată de memorie aici.
Apoi D-A-V-I-D cumva ajunge în această funcție.
Și am de gând să simplificăm.
Dar să presupunem că ei D-A-V-I-D backslash zero.
Deci, acest lucru de multe biți sunt utilizate în cadru pentru getstring.
>> Dar, de îndată ce se întoarce getstring, am a spus ultima oară că această memorie peste
aici totul devine - woops! -
totul devine șterse în mod eficient.
Și ne putem gândi la asta acum ca întrebare semne că cine știe
ce va deveni din ce memorie.
Într-adevăr, eu numesc foarte des funcții altele decât getstring.
Și, de îndată ce eu numesc un alt Funcția de getstring, poate nu în
acest program special, ne-am uitat la, dar pentru alte, cu siguranță o altă
Funcția s-ar putea sfârși prin a fi dat acest loc viitoare în stivă.
>> Deci, nu se poate ca magazinele getstring D-A-V-I-D de pe stiva pentru că mi-ar
pierde imediat acces la ea.
Dar noi știm că ele getstring returnează numai ce?
Nu este revenirea la ma șase caractere.
Ceea ce este cu adevărat revenirea a putem concluziona ultima dată?
Adresa primului.
Deci într-un fel, când ai sunat getstring, este alocarea unui segment de memorie pentru
șir că utilizatorii de tip și adresa apoi se întorc din el.
Și se pare că atunci când doriți să funcționeze de a aloca memorie în acest
cale și a reveni la persoana care a sunat că funcția, adresa
ca segment de memorie, vă absolut nu se poate pune în stivă la
partea de jos, pentru ca funcțional este doar de gând să nu devină a ta foarte
rapid, astfel încât să puteți ghici, probabil, în cazul în care Probabil suntem de gând să-l arunce
în schimb, așa-numitul grămadă.
>> Deci, între partea de jos a memoriei dumneavoastră structura și partea de sus a memoriei dumneavoastră
layout-ul sunt o grămadă de segmente.
Unul este stiva, și dreapta de mai sus este grămadă.
Și grămadă este doar o bucată diferit de memorie care nu este utilizată pentru funcțiile de
atunci când acestea sunt numite.
Este folosit pentru memoria pe termen lung, atunci când vrei o funcție pentru a apuca unele
memorie și să fie capabil să stea pe ea fără a pierde controlul asupra acesteia.
>> Acum, ai putea, probabil, imediat vedea că acest lucru nu este
neapărat un design perfect.
Ca programul de memorie alocată pe stiva, sau ca te sun mai mult și
mai multe funcții, sau ca tine aloca memorie pe heap cu malloc off ca
getstring este de a face, ceea ce în mod clar pare a fi o problemă inevitabilă?
>> Dreapta.
Cum ar fi faptul că aceste săgeți sunt orientate unul spre altul
nu este de bun augur.
Și într-adevăr, am putea prăbuși foarte repede un program în orice număr de moduri.
De fapt, cred că am putea avea făcut acest lucru accidental o dată.
Sau, dacă nu, să o facem în mod deliberat acum.
Lasă-mă să merg mai departe și scrie foarte repede un program numit dontdothis.c.
Și acum voi merge în aici și nu ascuțite includ stdio.h.
Să declare funcția de foo are nici un argument, care este
notat de asemenea de gol.
>> Și singurul lucru foo este de gând să faceți este să apel foo, care, probabil, nu este
mai deștept ideea, dar așa să fie.
Ent principal nule.
Acum, singurul lucru principal se va să faceți este să sunați foo, de asemenea.
Și doar pentru lovituri, am de gând să merg mai departe aici și spune printf "Bună ziua de la
foo. "
>> OK.
Deci, dacă nu am face orice greșeli, Face dontdothis punct slash.
Și să o facem într-o fereastră mai mare -
dot slash, dontdothis.
Haide.
Uh oh.
Aparent, puteți face acest lucru.
La naiba.
OK.
Așteaptă.
Stand by.
Am -
Noi l-am folosi cu face.
>> [Sighs]
>> Știu, dar cred că doar șterse care.
Uh, da.
La naiba.
Rezolva acest Rob.
Ce?
Este foarte simplu.
Da, ne-am întors de optimizare off.
OK, stau la revedere.
Acum mă simt mai bine.
OK.
Bine.
>> Așa că haideți să recompilați acest lucru -
Asigurați-vă dontdothis.
S-ar putea avea pentru a redenumi acest lucru dothis.c într-o clipă.
Acolo mergem.
Mulțumesc.
OK.
Deci, faptul că am fost de imprimare ceva a fost de fapt doar
încetinirea procesului prin care ar fi ajuns la acel punct.
OK.
Pfiu!
>> Deci, ce se întâmplă de fapt pe?
Motivul pentru care există, la fel cum o parte, este fac nimic în termeni de intrare și
ieșire tinde să fie mai lent, deoarece Trebuie să scrie caractere pentru a
ecran, are pentru a defila.
Deci, pe scurt, a avut de fapt am sa întâmplat atât de nerăbdător, am avea
văzut acest rezultat final, de asemenea.
Acum, că am plimbare de imprimare-up-uri, vom vedea imediat.
Deci, de ce se întâmplă asta.
Ei bine, explicația simplă, desigur, este că foo, probabil, nu ar trebui
fi de asteptare sine.
>> Acum, în termeni generali, aceasta este recursivă.
Și ne-am gândit de câteva săptămâni în urmă recursiv este bun.
Recursivitatea este în acest fel magic de te exprima foarte succint.
Și pur și simplu funcționează.
Dar există o caracteristică cheie a tuturor programele recursive care am vorbit
despre și se uită la până acum, care a fost că au avut ce?
Un caz de bază, care a fost un greu codificate cazul în care a spus, în anumite situații
nu suna foo, care este în mod clar nu este cazul aici.
>> Deci, ce se întâmplă cu adevărat în ceea ce privește această imagine?
Ei bine, atunci când principalul numește foo, se devine o felie de memorie.
Când foo numește foo, acesta devine o felie de memorie.
Când foo numește foo, acesta devine o felie.
Ea devine o felie.
Deoarece foo nu se întoarce.
Noi nu suntem ștergerea unul dintre cei cadre din stivă.
Deci, suntem suflare prin grămadă, nu pentru a menționa cine știe ce altceva, și
vom depăși limitele noastre așa-numita segment de memorie.
Eroare merge segmentare false.
>> Deci, soluția este în mod evident, nu face asta.
Dar implicația mai mare este că, da, există absolut unele limite,
chiar dacă nu este bine definit, cu privire la modul multe funcții, puteți apela la un
Programul, de câte ori o funcție se poate apela.
Deci, chiar dacă am făcut predica recursivitate ca acest lucru ar putea magic o
câteva săptămâni în urmă pentru sigma funcția, și când vom obține date
structuri și CS50, veți vedea alte aplicații pentru ea, nu e
neapărat cel mai bun lucru.
Pentru că dacă o funcție în sine numește, apeluri în sine, chiar dacă există o bază
caz, dacă nu a lovit acest caz de bază pentru 1.000 de apeluri sau 10.000 de apeluri, prin
atunci este posibil să fi rămas fără cameră pe așa-zisa ta stivă și a lovit
alte segmente de memorie.
Deci, acesta este de asemenea un design de compromis între eleganță și între
robustețea special dvs. punere în aplicare.
>> Deci, există un alt dezavantaj sau un alt prins la ceea ce am
făcut până acum.
Când am sunat getstring -
lasă-mă să mă întorc la salut-2.
Observați că am sunat getstring, care se întoarce o adresă.
Și am pretind astăzi că adresa este din morman.
Și acum am imprimarea șir la acea adresa.
Dar nu am numit vizavi de getstring.
Noi nu am avut de a calll o funcție ca ungetstring, în cazul în care mâna înapoi
că memoria.
Dar sincer am, probabil, ar fi fost.
Pentru că dacă ne tot întreabă pe calculator pentru memorie, cu titlu de cineva ca
getstring dar nu-l dau înapoi, cu siguranță care este de asemenea obligat să ducă la
problemele prin care am alerga afară de memorie.
>> Și, de fapt, ne putem uita la aceste probleme cu nou instrument a cărui utilizare
este un pic criptic de tip.
Dar lasă-mă să merg mai departe și stropiți-l pe ecran în doar o clipă.
Am de gând să merg mai departe și a alerga Valgrind cu parametrul a carui prima comanda
Argumentul linie este numele din care programul de salut-2.
Și, din păcate, este de ieșire este atroce
complex pentru nici un motiv bun.
Deci, vom vedea tot ce mizerie.
David este un stat numele meu.
Deci asta e programul de fapt de funcționare.
Și acum avem această ieșire.
>> Deci Valgrind este similară în spirit de GDB.
Nu este un program de depanare în sine.
Dar este un verificator de memorie.
Este un program care va rula dvs. programa și să vă spun dacă ați întrebat o
calculator de memorie și nu-l predat înapoi, astfel ceea ce înseamnă că aveți
o scurgere de memorie.
Și pierderi de memorie tind să fie rău.
Și tu este utilizatorii de calculatoare au probabil simțit acest lucru, dacă aveți un
Mac sau un PC.
Ați folosit vreodata computerul pentru timp și nu repornită în mai multe
zile, sau tocmai ai primit o mulțime de programele care rulează, și nimic
încetinește la o oprire măcinare, sau cel puțin este foarte enervant de a utiliza, deoarece
tot ceea ce tocmai a fost foarte lent.
>> Acum, că poate fi orice număr de motive.
Ar putea fi o buclă infinită, un bug în Codul cuiva, sau, mai simplu, ea
ar putea însemna că utilizați mai mult memorie, sau încercarea de a, decât dvs.
calculator de fapt are.
Și poate că e un bug într-un program de că tot întreabă de memorie.
Browsere de ani, au fost cunoscute pentru acest lucru, cere pentru mai mult și mai mult memorie
dar nu-l predarea înapoi.
Cu siguranță, dacă aveți doar un finit cantitatea de memorie, nu poți cere
infinit de multe ori pentru unele dintre care memorie.
>> Și astfel ceea ce vedeți aici, chiar dacă din nou ieșire Valgrind este
inutil de complexă a privi la în primul rând, aceasta este partea interesantă.
Heap -
în utilizare la ieșire.
Deci, aici este cantitatea de memorie a fost în uz în grămadă, la
timp programul meu a ieșit -
aparent șase octeți într-un bloc.
Așa că am de gând să val mâinile mele la ceea ce un bloc este.
Gândiți-vă de ea este doar o bucată, o mai cuvânt tehnic pentru bucată.
Dar șase bytes -
care sunt cele șase octeți care erau încă în uz?
>> Exact.
D-O-V-I-D backslash la zero, cinci litere Numele plus nul Terminator.
Deci, acest program de Valgrind observat că am a cerut timp de șase bytes, se pare, de
mod de getstring, dar nu le-a dat înapoi.
Și, de fapt, aceasta ar putea să nu fie atât de evident, în cazul în care programul meu nu este de trei
linii, dar este de 300 de linii.
Deci, putem da de fapt, o altă comandă argument linie de Valgrind la
face mai detaliată.
Este un pic enervant să-și amintească.
Dar dacă fac -
să vedem.
Leak -
A fost scurgeri -
chiar nu-mi amintesc ceea ce este oprit manual.
>> - Scurgeri de verificare egal plin.
Da, mulțumesc.
- Scurgeri de verificare egal plin.
Enter.
Același program se execută.
Tastați în David din nou.
Acum, văd un pic mai în detaliu.
Dar sub rezumat grămadă, care este identic cu patru - ah,
aceasta este un fel de frumos.
Acum Valgrind este, de fapt în căutarea un pic mai greu în codul meu.
Și se spune că, aparent, malloc la linie -
am micșora.
La linie -
nu vedem ce linie este.
Dar malloc este primul vinovat.
Există un blog în malloc.
>> În regulă?
OK, nu.
Dreapta?
Am sunat getstring.
getstring pare că apelurile malloc.
Deci, ceea ce este aparent linie de cod de vina pentru a avea
alocate această memorie?
Să presupunem că cine a scris malloc a fost în jurul suficient de mult timp că este
nu este vina lor.
Deci, este, probabil, a mea.
getstring în cs50.c - pentru ca este o depună undeva pe computer -
în linie 286 pare a fi vinovat.
Acum, să presupunem că CS50 a fost în jurul valorii de cantitate decenta de timp, astfel încât
noi suntem infailibili.
Și deci nu este, probabil, în getstring că bug-ul se afla, ci mai degrabă în
linie de salut-2.c 18.
>> Deci, haideți să aruncăm o privire la ceea ce a fost ca linia 18.
Oh.
Într-un fel această linie nu este neapărat buggy, în sine, dar acesta este motivul
spatele scurgere de memorie.
Deci super-pur și simplu, ceea ce ar fi intuitiv fi soluția aici?
Dacă cerem de memorie, nu au fost niciodată dându-i înapoi, și care pare a fi o
problema, deoarece a lungul timpului computerul meu s-ar putea alerga afară de memorie, s-ar putea încetini
jos, lucruri rele s-ar putea întâmpla, de asemenea, ceea ce este o solutie simpla intuitiv?
Dă-l înapoi.
>> Cum te elibera acea memorie?
Ei bine, din fericire este destul de simplu a spus numele gratuit.
Și n-am mai făcut asta înainte.
Dar vă puteți gândi în esență, de fără ca opusul malloc.
gratuit este opusul alocarea de memorie.
Deci, acum lasă-mă să recompilați asta.
Face salut-2.
Lasă-mă să-l rulați din nou. salut-2 David.
Deci, se pare să funcționeze în exact în același mod.
Dar dacă mă întorc la Valgrind și re-rula că aceeași comandă pe nou-mea
compilat programul, dactilografiere în numele meu ca înainte -
frumos.
Sumar Heap -
în utilizare la ieșire -
octeți zero în blocuri zero.
Și acest lucru este foarte frumos, toate blocuri grămadă au fost eliberați.
Nu sunt posibile scurgeri.
>> Deci, venind, nu cu un set Problema 4, dar cu Set Problema 5, criminalistica
și mai departe, și aceasta va deveni o măsură de corectitudinea dvs.
Programul, indiferent dacă sau nu aveți sau nu au pierderi de memorie.
Dar din fericire, nu numai că puteți raționa prin ei intuitiv, care
este, fără îndoială, ușor pentru programe mici dar mai greu pentru programe mari,
Valgrind, pentru aceste programe mari, vă poate ajuta să identificați
problemă deosebită.
>> Dar există o altă problemă care ar putea apărea.
Lasă-mă să deschid acest fișier aici, care este, din nou, un exemplu oarecum simplu.
Dar să ne concentrăm pe ceea ce acest program nu.
Aceasta se numește memory.c.
Vom posta acest astăzi, mai târziu, în zip de cod sursă de astăzi.
Și observa că am o funcție numită f care nu ia argumente și
returneaza nimic.
În linia 20, eu sunt aparent declararea pointer la un int și numindu-l x.
Sunt atribuirea este revenirea Valoarea de malloc.
Și ca să fie clar, cât de multe bytes sunt Probabil că mă întorc de la malloc
în această situație?
>> Probabil 40.
De unde ai scos asta?
Ei bine, dacă vă amintiți că un int este de multe ori 4 bytes, cel puțin acesta este în
Aparatul, de 10 ori 4 este, evident, 40.
Deci, malloc se intoarce o adresa de o bucată de memorie și stocare care
abordeze în cele din urmă în x.
Astfel încât să fie clar, ceea ce atunci se întâmplă?
Ei bine, lasă-mă să comutați înapoi pentru imaginea noastră aici.
Permiteți-mi să nu trage doar partea de jos a mea memoria calculatorului, lasă-mă să merg mai departe și
trage tot dreptunghi care reprezinta toate de RAM meu.
>> Vom spune că stiva este pe partea de jos.
Și există un segment de text în datele neinițializate.
Dar eu sunt doar de gând să celor abstract alte lucruri pe departe la fel de dot, dot dot.
Mă voi referi la această ca grămadă în partea de sus.
Și apoi în partea de jos a acestui tablou, să reprezinte principala, am de gând
să-i dea o memorie felii pe stivă.
Pentru f, am de gând să-i dea o felie de memorie pe stiva.
Acum, am să consulte mea codul sursă din nou.
Care sunt variabilele locale de principal?
Aparent nimic, astfel încât felie este eficient gol sau nu chiar la fel de mare
așa cum l-am desenat.
Dar, în f, am o variabilă locală, care se numește x.
Așa că am de gând să merg mai departe și să f o bucată de memorie, numindu-l x.
>> Și acum malloc de 10 ori 4, Deci malloc 40, unde e
memorie vine de la?
Noi nu am desenat o imagine înainte ca aceasta.
Dar să presupunem că este eficient vine de aici, așa unul,
doi, trei, patru, cinci.
Și acum am nevoie de 40 dintre acestea.
Așa că voi face doar punct, punct, punct care să sugereze că există chiar mai mult memorie
întorc din zona de lucru.
Acum, ceea ce este adresa?
Să alegem arbitrar nostru abordeze ca întotdeauna -
Ox123, chiar dacă este probabil că va să fie ceva complet diferit.
Asta e adresa primului octet din de memorie pe care am cer malloc pentru.
>> Deci, în linie scurt, o dată 20 execută, ceea ce este literalmente
stocate în interiorul de x aici?
Ox123.
Și Ox este neinteresant.
Aceasta înseamnă doar aici este o număr hexazecimal.
Dar ceea ce este esențial este că ceea ce am magazin în x, care este o variabilă locală.
Dar tipul de date, din nou, este o adresă de un int.
Ei bine, am de gând pentru a stoca Ox123.
Dar, din nou, în cazul în care este un pic prea complicat inutil, dacă am defila
înapoi, putem abstract această distanță destul de rezonabil și să spun doar că x este o
pointer la acea bucată de memorie.
>> OK.
Acum, întrebarea la mână este următoarea -
linia 21, se pare, este buggy.
De ce?
>> Îmi pare rău?
Ea nu are -
spune că o dată mai mult.
Ei bine, nu gratuit.
Deci, asta e de-a doua, dar.
Deci, există un alt dar special la linia 21.
>> Exact.
Această simplă linie de cod este doar o buffer overflow, o depășire tampon.
Un tampon înseamnă doar o bucată de memorie.
Dar că segment de memorie este de dimensiune 10, 10 numere întregi, ceea ce înseamnă că dacă
index în ea folosind zahăr sintactic de notație matrice, pătrat
paranteze, aveți acces la x suport 0 x suport 1 x,
Suport punct, punct, punct.
x suport 9 este cel mai mare.
Deci, dacă am face x suport 10, în cazul în care Sunt de fapt merge în memorie?
>> Ei bine, dacă am 10 Int -
să atragă de fapt, toate de astea aici.
Astfel că a fost primul cinci.
Iată celelalte cinci int.
Deci x suport 0 este aici. x suport 1 este aici. x suport 9 este aici. x suport
10 este aici, ceea ce înseamnă că spun, în linia 21, calculatorul pentru a pune
Numărul unde?
Numărul 0 unde?
Ei bine, e 0, da.
Ci doar faptul că 0 său este un fel de coincidență.
Acesta ar putea fi numărul 50, pentru toate ne pasă.
Dar noi încercăm să-l pună la x suport 10, care este în cazul în care acest lucru
semn de întrebare este tras, care nu este un lucru bun.
Acest program ar putea foarte bine prăbuși ca un rezultat.
>> Acum, să mergem mai departe și să vedem dacă acest lucru este, într-adevăr, ceea ce se întâmplă.
Face de memorie, deoarece fișierul se numește memory.c.
Să mergem mai departe și a alerga memoria program.
Așa că am avut noroc, de fapt, se pare.
Am avut noroc.
Dar să vedem dacă vom rula acum Valgrind.
La prima vedere, programul meu s-ar putea par a fi perfect corect.
Dar permiteți-mi să ruleze Valgrind cu - Scurgeri de verificare egal plin de pe memorie.
>> Iar acum, când am rula acest -
interesant.
Invalid scrie de dimensiune 4 la Linia 21 de memory.c.
Linia 21 de memory.c este care unul?
Oh, interesant.
Dar așteptați.
Dimensiunea 4, ceea ce este ca referindu-se la?
Eu doar am o scrie, dar este de dimensiune 4.
De ce este 4?
Este pentru că este un int, care este, din nou, patru bytes.
Deci, Valgrind găsit un bug care am, uite la codul meu, nu.
Și poate TF ta ar fi sau nu ar fi.
Ce Dar Valgrind pentru sigur constatat că am făcut o greșeală acolo, chiar
deși am avut noroc, iar computerul a decis, nu-i așa, nu am de gând să se prăbușească
doar pentru că ai atins un octet, o valoare Int de memorie care nu
de fapt propriu.
>> Ei bine, ce altceva este buggy aici.
Adresa -
aceasta este o adresă în căutarea nebun în hexazecimal.
Asta înseamnă că undeva în grămadă este octeți zero, după un bloc de dimensiune 40
este alocat.
Lasă-mă să micșorați aici și vezi dacă acest lucru este un pic mai util.
Interesant.
40 bytes sunt cu siguranta pierdut în evidență pierdere 1 din 1.
Din nou, mai multe cuvinte decât este util aici.
Dar bazate pe liniile evidențiate, unde ar trebui să se concentreze, probabil mea
atenție pentru un alt bug?
Se pare ca o linie de 20 de memory.c.
>> Deci, dacă ne întoarcem la linia 20, care este unul care ați identificat mai devreme.
Și nu este neapărat buggy.
Dar am această inversat efectele sale.
Deci, cum pot corecta cel puțin una dintre aceste greșeli?
Ce aș putea face după linia 21?
Am putea face fără a x, deci este pentru a da înapoi ca memoria.
Și cum pot rezolva această problemă?
Eu ar trebui să meargă cu siguranta nu mai departe decât 0.
Deci, lasă-mă să încerc și re-rula acest lucru.
Ne pare rău, du-te cu siguranta nu mai departe decât 9.
Face memorie.
Lasă-mă să reluare Valgrind într-o fereastră mai mare.
Și acum uite.
Frumos.
Toate blocurile grămadă fost eliberați.
Nu sunt posibile scurgeri.
Și deasupra aici, nu e nici o mențiune mai mult de drept invalid.
>> Doar pentru a obține lacomi, și hai să vedea dacă o altă demonstrație
nu merge așa cum este prevăzut -
Eu am noroc acum o clipă.
Și faptul că aceasta este 0 este probabil inutil înșelătoare.
Hai să facem doar 50, o oarecum arbitrară număr, face memorie punct memorie slash -
încă avea noroc.
Nimic nu crashing.
Să presupunem că am face ceva cu adevărat prostesc, iar eu fac 100.
Permiteți-mi refac memoria, dot memorie slash -
am din nou noroc.
Ce zici de 1.000 de?
int dincolo de, aproximativ, unde ar trebui să fiu?
Face memorie -
la naiba.
>> [Râsete]
>> OK.
Să nu mai mizerie în jurul valorii.
Reluare de memorie.
Acolo mergem.
Bine.
Deci, se pare că tu indicele 100.000 int dincolo de cazul în care ar fi fost în
memorie, se întâmplă lucruri rele.
Astfel încât aceasta nu este în mod evident o regulă tare, repede.
Am fost un fel de a folosi proces și eroare pentru a ajunge acolo.
Dar acest lucru se datorează faptului că, pe scurt, memoria computerului este, de asemenea, divizat
în aceste lucruri numite segmente.
Și, uneori, computerul de fapt, a dat un pic mai mult memorie
decât vă întreb pentru.
Dar, pentru eficiență, este mai ușor să obține mai mult de memorie, dar vă spun doar
că vei primi o parte din ea.
>> Și dacă ai noroc, uneori, prin urmare, s-ar putea fi capabil de a atinge
memorie care nu-ți aparține.
Nu ai nici o garanție că ceea ce valoare ai pus acolo va rămâne acolo, pentru că
calculatorul încă crede că nu este a ta, dar nu este neapărat va
a lovit un alt segment de memorie în calculator și induce o greșeală ca
asta aici.
Bine.
Orice întrebări, atunci pe memorie?
>> Bine.
Să aruncăm o privire aici, apoi, la ceva ce ne-am luat pentru
acordată de ceva timp, care este în acest fișier numit cs50.h.
Deci, acesta este un fișier.
Acestea sunt doar o grămadă de comentarii sus.
Și este posibil să fi uitat la acest lucru în cazul în care ai bagat în jurul pe aparat.
Dar se pare că tot timpul, când am folosit pentru a folosi ca un șir
sinonim, mijloacele prin care a declarat că a fost sinonim cu acest
cuvinte cheie typedef, pentru definirea de tip.
Și suntem în esență spune, face string un sinonim pentru stele char.
Că mijloacele prin care stivă a creat aceste roți de formare cunoscut sub numele de
șir.
>> Acum, aici e doar un prototip pentru getchar.
S-ar putea l-am văzut mai înainte, dar asta e într-adevăr ceea ce face. getchar
ia nici un argument, returnează un char.
getdouble ia nici un argument, returnează o dublă.
getfloat nevoie de nici un argument, se întoarce un float, și așa mai departe.
getint este aici. getlonglong este aici.
Și getstring este aici.
Și asta e tot.
Această linie violet este un alt preprocesor Directiva din cauza
hashtag de la începutul ei.
>> Bine.
Deci, acum lasă-mă să merg în cs50.c.
Și nu vom vorbi prea mult pe acest lucru.
Dar pentru a vă oferi o idee de ceea ce este fost întâmplă toate astea
timp, lasă-mă să merg la -
hai sa facem getchar.
Deci, getchar este cea mai mare parte comentarii.
Dar se pare ca aceasta.
Deci, aceasta este funcția propriu-zisă getchar că am fost
ia pentru a acordat exista.
Și, chiar dacă nu ne-am folosi aceasta care de multe ori, dacă vreodată, este cel puțin
relativ simplu.
Deci, este în valoare de a lua o privire rapidă la aici.
>> Deci, getchar are o bucla infinita, în mod deliberat atât de aparent.
Apoi cheamă - și acest lucru este un fel de reutilizarea frumos de cod ne-am scris.
Acesta solicită getstring.
Pentru că ceea ce face înseamnă a obține un caracter?
Ei bine, ai putea încerca la fel de bine pentru a obține o întreaga linie de text din partea utilizatorului și
apoi uita-te la un de aceste caractere.
În linia 60, aici e un pic bit de un control bun-simț.
Dacă getstring întors nul, Să nu continua.
Ceva a mers prost.
>> Acum, acest lucru este oarecum enervant, dar convențional în C. char max, probabil,
reprezintă ceea ce tocmai bazat pe numele său?
Este o constantă.
E ca și cum valoarea numerică a Cea mai mare char puteți reprezenta cu
unul musca, care este, probabil, numărul 255, care este cel mai mare număr de tine
reprezintă opt biți, pornind de la zero.
Deci, am folosi acest, în această funcție, atunci când scris acest cod, numai pentru că
în cazul în care ceva nu merge bine în getchar, dar scopul său în viață este de a returna o
char, trebuie să fie cumva capabil să semnaleze utilizatorul care
ceva a mers prost.
Nu ne putem intoarce null.
Se pare că nul este un pointer.
Și din nou, getchar are pentru a reveni un char.
>> Deci convenție, în cazul în care ceva nu merge greșit, este tu, programator, sau în
acest caz, eu cu biblioteca, am avut o doar decide în mod arbitrar, în cazul în care
ceva nu merge bine, am de gând să returneaza numarul 255, care este cu adevărat
înseamnă că nu se poate, utilizatorul nu poate introduce caracterul reprezentat de
numărul 255 pentru că am avut o fura ca un așa-numita valoare santinelă la
reprezintă o problemă.
Acum se dovedește că personajul 255 nu este ceva ce se poate introduce pe
tastatură, asa ca nu e mare lucru.
Utilizatorul nu observă că Am furat acest personaj.
Dar dacă ați vedea vreodată în paginile de om pe o sistem informatic unii referire la un
toate capacele constant ca asta, care spune, în cazul unor erori această putere constantă
fi returnate, asta e tot un om a făcut cu ani în urmă a fost arbitrar a decis să
returna această valoare deosebită și numesc o constantă în cazul în care
ceva nu merge bine.
>> Acum, magia se intampla aici.
În primul rând, am declarat în linie 67 două personaje, C1 și C2.
Și apoi în linie 68, nu există de fapt o linie de cod care este o reminiscență a
prietenul nostru printf, având în vedere că are la suta Cs în ghilimele.
Dar observați ce se întâmplă aici. sscanf înseamnă scanare string -
înseamnă scana o formatat șir, sscanf Ergo.
Ce înseamnă asta?
Aceasta înseamnă că trece la sscanf un șir.
Și linia este indiferent utilizatorul tastează inch
Tu treci la sscanf un șir format ca aceasta spune că scanf care sunt
Speri utilizatorul a tastat inch
Apoi trece-in adresele de două bucăți de memorie, în acest caz,
pentru că am doi substituenți.
Așa că am de gând să-i dea adresa C1 și C2 adresa.
>> Și amintesc că vă dau o funcție Adresa de unele variabile, ceea ce este
implicația?
Ce se poate face, care funcționează ca un rezultat de a da o adresă a unui
variabilă, spre deosebire de variabila în sine?
Se poate schimba, nu?
Dacă ați avut cineva o hartă a unui fizic adresa, ei pot merge acolo și de a face
ceea ce isi doresc de la acea adresa.
Aceeași idee aici.
Dacă trecem la sscanf, adresa de doi bucăți de memorie, chiar și aceste mici
bucăți mici de memorie, C1 și C2, dar ne spun că adresa lor,
sscanf se poate schimba.
>> Deci, scopul sscanf în viață, dacă citim pagina de om, este de a citi ceea ce
utilizatorul tastat în, speranță pentru ca utilizatorul tastat într-un caracter și poate
un alt personaj, și indiferent de utilizator tastat, primul caracter se
aici, al doilea caracter merge aici.
Acum, ca o paranteza, aceasta, și v-ar știu numai aceasta din documentația,
faptul că am pus un spatiu gol acolo înseamnă doar că nu-mi pasă dacă
utilizatorul lovește bara de spațiu câteva ori înainte de el sau ea are o
caracter, am de gând să ignore orice spațiu alb.
Așa că, eu știu de la documentația.
>> Faptul că există o a doua% c urmat de spațiu alb este de fapt
deliberat.
Vreau să fie capabil să detecteze dacă utilizatorul greșit sau nu au cooperat.
Deci, eu sunt în speranța că singurul utilizator tastat într-un singur caracter, de aceea sper
care sscanf este doar de gând să se întoarcă valoarea 1, deoarece, din nou, în cazul în care am citit
documentația, scopul sscanf în viață este de a reveni la numărul de
variabile care au fost completate cu intrare de utilizator.
>> Am trecut în două variabile adrese, C1 și C2.
Sper, totuși, că doar unul dintre le este ucis pentru că dacă sscanf
se întoarce 2, ceea ce este probabil implicarea logic?
Că utilizatorul nu da-mi un personaj ca i-am spus sau ea.
Probabil au tastat la cel puțin două caractere.
Deci, dacă am loc nu am avut de-a doua % C, am avut una, care
sincer ar fi mai intuitiv abordare, cred ca o prima vedere,
nu sunteți de gând să fie în măsură să detecteze În cazul în care utilizatorul a fost oferindu-vă mai mult
intrare decât ai vrut de fapt.
Deci, aceasta este o formă implicită de verificarea erorilor.
>> Dar observați ce fac aici.
După ce am Sunt sigur că utilizatorul mi-a dat un caracter, am elibera linia, face
opusă getstring, care la rândul său utilizează malloc, și apoi mă voi întoarce
C1, personajul pe care am sperat utilizator oferit si numai cu conditia.
Deci, un rapid zărit numai, dar întrebări cu privire la getchar?
Vom reveni la unii dintre ceilalți.
>> Ei bine, lasă-mă să merg mai departe și de a face acest lucru - Presupun că acum, doar pentru a motiva nostru
discuție într-o săptămână, plus timp, acest este un fișier numit structs.h.
Și din nou, acest lucru este doar un gust de ceva ce se află în fața.
Dar observați că o mulțime în acest sens este comentarii.
Deci, permiteți-mi să subliniez doar Partea interesanta pentru acum.
typedef -
există din nou același cuvânt cheie.
typedef le folosim pentru a declara șir ca un tip de date special.
Puteți folosi typedef pentru a crea nou tipuri de date care nu existau atunci când
C a fost inventat.
De exemplu, int vine cu C. char vine cu C. dublu vine cu C. Dar
nu exista nici o noțiune de un student.
Și totuși, ar fi destul de util pentru a fi capabil să scrie un program care stochează
într-o variabilă, număr de identificare unui student, numele lor, și casa lor.
Cu alte cuvinte, trei piese de date, cum ar fi un int și un
șir și un alt șir.
>> Cu typedef, ceea ce e destul de puternic despre acest lucru și sturct cuvinte cheie pentru
structura, tu, programator în 2013, se poate defini de fapt, propriul
tipuri de date care nu existau ani în urmă, dar care se potrivesc scopuri.
Și atât de aici, în liniile 13 și 19, ne declara un nou tip de date, cum ar fi
un int, dar numindu-l elev.
Iar în interiorul acestei variabile se va fi trei lucruri - un int, un șir,
și un șir.
Deci, vă puteți gândi la ceea ce este cu adevărat sa întâmplat aici, chiar dacă aceasta este o
bit de o simplificare pentru ziua de azi, un student este, în esență va
pentru a arata ca aceasta.
Sa mergi la a fi o bucată de memorie cu o identitate, un nume
teren, și un teren casă.
Și vom putea folosi aceste bucăți de memorie și accesați-le, după cum urmează.
>> Dacă mă duc în struct0.c, aici este o relativ lung, dar ca urmare a unei
model, de cod care folosește acest nou truc.
Deci, în primul rând, permiteți-mi să vă atrag atenția de interesante piese de sus.
Sharp definește elevii 3, declară un constante numite studenți și atribuie
ea arbitrar numărul 3, doar așa că am trei elevi care utilizează
acest program pentru acum.
Aici vine principal.
Și de notificare, cum declar o serie de studenți?
Ei bine, am folosi doar aceeași sintaxă.
Studentul Cuvântul este, evident, nou.
Dar studenți, clasa, elevii suport.
>> Deci, din păcate, există o mulțime de reutilizare a termenilor aici.
Acesta este doar un număr.
Deci, acest lucru este ca și cum spune trei.
Class este exact ceea ce vreau pentru a apela variabila.
Am putea numi studenți.
Dar clasă, aceasta nu este o clasă într-un Orientată Obiect fel Java de drum.
E doar o clasă de elevi.
Și tipul de date de fiecare element în care matrice este elev.
Deci, acest lucru este un pic diferit și de a spune ceva
ca aceasta, e doar -
Eu spun da-mi trei elevi și apela clasa matrice.
>> Bine.
Acum, aici e un patru buclă.
Acest tip familiar - itera de la zero până la trei.
Și aici e noua piesa de sintaxă.
Programul mă va solicita, uman, pentru a da un elev
ID, care este un int.
Și aici e sintaxa cu care puteți stoca ceva în câmpul ID de la
Clasa de locație suport I. Deci, aceasta sintaxa nu este nouă.
Acest lucru înseamnă doar da-mi de-a opta elev în clasa.
Dar acest simbol este nou.
Până acum, ne-am nu pot fi folosite punct, cel puțin în codul ca aceasta.
Acest lucru înseamnă du-te la struct cunoscut sub numele de un elev și a pus ceva acolo.
De asemenea, în această linie viitoare, 31, du-te înainte și pune orice tipuri de utilizatori
pentru un nume aici, și ceea ce fac ei pentru o casă, același lucru, mergeți mai departe și
pune-l in. casă.
>> Deci, ce are acest program în cele din urmă face?
Puteti vedea un pic teaser acolo.
Lasă-mă să merg mai departe și fac structs 0 dot slash struct 0, ID-ul studentului 1,
spune David Mather, student ID 2.
Rob Kirkland, student ID 3.
Lauren Leverit -
și singurul lucru pe care acest program a făcut, care este doar complet arbitrar, este
Am vrut să fac ceva cu aceste date, Acum, că am ne-a învățat cum să
folosi structs, doar am avut această buclă în plus aici.
Am repeta peste serie de studenți.
Am folosit noastră, prieten, probabil, acum familiar, string comparație, stircomp la
Verificarea este casa a 8-a elevului egală cu Mather?
Și dacă este așa, doar imprima ceva arbitrar ca, da, este.
Dar, din nou, doar să-mi dea oportunități la utilizarea și reutilizarea și
reutilizarea acest nou punct notație.
>> Deci cui îi pasă, nu?
Vine cu un program de elev este oarecum arbitrară, dar se pare
că putem face lucruri utile cu aceasta, de exemplu, după cum urmează.
Aceasta este o struct mult mai complicată în C. Are o duzină sau mai multe domenii,
oarecum criptic pe nume.
Dar, dacă ați auzit vreodată de o grafică format de fișier numit bitmap, BMP, ea
se dovedește că formatul de fișier de tip bitmap destul de mult pare că acest lucru.
Este un pic stupid fata zambitoare.
Este o imagine mică pe care le-am mărit pe destul de mare, așa că am putut vedea fiecare
din puncte individuale sau pixeli.
Acum, se pare că ne poate reprezenta un punct negru cu, să zicem, numărul 0.
Și un punct alb cu numărul 1.
>> Deci, cu alte cuvinte, dacă doriți să atragă un Smiley Face și a salva ca imagine într-un
calculator, este suficient pentru a stoca zerouri și cele care arata ca aceasta, în cazul în care,
din nou, sunt cele alb și zerouri sunt negre.
Și împreună, dacă aveți în mod eficient o încinge de unu și zero, aveți un
grila de pixeli, și dacă ați pune le, aveți un drăguț
mic fata zambitoare.
Acum, formatul de fișier bitmap, BMP, este în mod eficient ca sub capota,
dar cu mai mulți pixeli sot pe care le poate reprezenta de fapt culorile.
>> Dar atunci când aveți mai sofisticate formate de fișiere, cum ar fi BMP și JPEG și GIF
cu care s-ar putea să fie familiarizat, cele fișiere de obicei nu numai pe disc
au zerouri și cele de pixeli, dar ei au unele metadate, precum și -
meta, în sensul că nu este într-adevăr Datele dar este util de a avea.
Deci, aceste domenii sunt aici implică, și vom vedea acest lucru în mai multe detalii în P-set
5, că înainte de zerouri și cele care reprezintă pixelii dintr-o imagine,
există o grămadă de metadate cum ar fi dimensiunea imaginii și
lățimea imaginii.
Și observa eu ​​sunt jumulire pe unele lucruri arbitrare aici -
lățime și înălțime.
Numărul de biți și alte câteva lucruri.
Deci, există unele metadate într-un fișier.
>> Ci prin intelegerea modului sunt prevăzute fișiere în acest fel, aveți posibilitatea de fapt,
apoi manipula imagini, recupera imagini de disc, redimensiona imagini.
Dar nu poți neapărat spori ele.
Am nevoie de o fotografie.
Așa că m-am dus înapoi la RJ aici, care te-a văzut pe ecran destul de ceva timp în urmă.
Și dacă am deschide Keynote aici, acest lucru este ce se întâmplă dacă încercați să mări și
spori RJ.
El nu din ce in ce mai bine cu adevărat.
Acum Keynote este un fel de interferență o pic, doar pentru luciu peste
Faptul că RJ nu se deosebit de îmbunătățită atunci când zoom inch
Și dacă o fac în acest fel, vezi pătrate?
Da, puteți vedea cu siguranta pătrate pe un proiector.
>> Asta e ceea ce obții atunci când a spori.
Dar în înțelegerea modului în RJ nostru sau Smiley Face este implementat ne va permite
de fapt scrie cod care manipulează aceste lucruri.
Și am crezut că voi ajunge la această notă, cu 55 secunde de un spori, care este,
Eu îndrăznesc, spun destul de înșelătoare.
>> [Redare video]
>> -Minte.
Despre ce, nu știu.
>> -Deci, ce știm?
>> -Asta la 9:15 Ray Santoya a fost la ATM.
>> -Deci, întrebarea este de ce făcea la 09:16?
>> -Impuscaturi nouă milimetri la ceva.
Poate că el a văzut pe lunetist.
>> -Sau a fost de lucru cu el.
>> -Așteaptă.
Du-te înapoi unul.
>> -Ce vrei sa vezi?
>> -Adu fața în sus, ecran complet.
>> -Lui ochelari.
>> -E o reflexie.
>> -Asta e echipa de baseball Neuvitas.
Asta e logo-ul lor.
>> -Și vorbește cu oricine e va purta sacoul.
>> [END redare video]
>> David J. MALAN: Aceasta va fi stabilit Problema 5.
Vă vom vedea săptămâna viitoare.
>> SPEAKER BĂRBAȚI: La CS50 următoare.
>> [Greierii ciripind]
>> [Redarea muzicii]