[Powered by Google Translate] Să vorbim despre tablouri.
Deci, de ce ne-ar dori vreodată să utilizați tablouri?
Ei bine, hai să presupunem că aveți un program de care are nevoie pentru a stoca 5 ID-uri studențești.
Ar putea părea rezonabil să aibă 5 variabile separate.
Din motive vom vedea într-un pic, vom începe numărarea de la 0.
Variabilele vom avea vor fi id0 int, int ID1, și așa mai departe.
Orice logica dorim pentru a efectua pe un ID de student va trebui să fie copiate și lipite
pentru fiecare dintre aceste ID-uri studențești.
Dacă vrem să verificați care elevii se întâmplă să fie în CS50,
vom trebui mai întâi pentru a verifica dacă id0 reprezintă student în curs.
Apoi să facă același lucru pentru elev următoare, vom avea nevoie să copiați și să inserați codul pentru id0
și să înlocuiască toate aparițiile de id0 cu ID1 și așa mai departe pentru ID2, 3, și 4.
>> De îndată ce veți auzi de care avem nevoie pentru a copia și lipi,
ar trebui să începi să te gândești că nu există o soluție mai bună.
Acum, ce se întâmplă dacă vă dați seama că nu aveți nevoie de ID-uri de 5 studenți, ci mai degrabă 7?
Ai nevoie pentru a merge înapoi în codul sursă și se adaugă într-o id5, o ID6,
și să copiați și să lipiți logica pentru a verifica dacă ID-urile aparțin clasei de aceste 2 ID-uri noi.
Nu este nimic conectarea toate aceste ID-uri împreună, și astfel nu există nici o modalitate de a pune
program pentru a face acest lucru pentru ID-urile de la 0 la 6.
Ei bine, acum iti dai seama ca ai 100 de ID-uri de studenți.
A început să pară mai puțin de ideal dacă doriți să trebuie să declare separat fiecare dintre aceste ID-uri,
și să copiați și lipiți orice logică pentru aceste ID-uri noi.
Dar poate suntem hotărâți, și o facem pentru toți 100 de elevi.
Dar ce se întâmplă dacă nu știi câți elevi există, de fapt sunt?
Există doar unii studenți n și programul dumneavoastră trebuie să solicite utilizatorului ce n este.
Uh oh. Acest lucru nu este de gând să lucreze foarte bine.
Programul tău funcționează numai pentru un numar constant de studenți.
>> Rezolvarea tuturor acestor probleme este frumusetea de matrice.
Deci, ce este o matrice?
În unele limbaje de programare un tip de matrice ar putea fi capabil să facă un pic mai mult,
dar aici ne vom concentra pe structura de bază de date matrice așa cum veți vedea în C.
O matrice este doar un bloc mare de memorie. Asta e tot.
Atunci când spunem că nu avem un tablou de 10 intregi, ca doar înseamnă că avem ceva bloc
de memorie, care este suficient de mare pentru a deține 10 numere întregi separate.
Presupunând că un număr întreg este de 4 octeți, aceasta înseamnă că o serie de 10 numere întregi
este un bloc continuu de 40 de octeți în memorie.
Chiar și atunci când utilizați tablouri multidimensionale, pe care nu vom merge in pentru a aici,
este încă doar un bloc mare de memorie.
Notația multidimensională este doar o comoditate.
Dacă aveți un 3 de 3 matrice multidimensional al întregi,
atunci programul va trata într-adevăr la fel ca pe un bloc mare de 36 de octeți.
Numărul total de numere întregi este de 3 ori 3, și fiecare număr întreg durează până la 4 octeți.
>> Să aruncăm o privire la un exemplu de bază.
Putem vedea aici 2 moduri diferite de declarare a tablourilor.
Va trebui să comenteze 1 din ele afară pentru a compila programul
deoarece ne pronunțăm x de două ori.
Vom arunca o privire la unele dintre diferențele dintre aceste 2 tipuri de declarații într-un pic.
Ambele aceste linii declară o serie de N dimensiune,
în cazul în care ne-am # define N, 10.
Am putea la fel de ușor au cerut utilizator pentru un întreg pozitiv
și utilizate ca întreg și o serie de elemente din gama noastră.
Vrei exemplul nostru ID-ul de student înainte, acest lucru este un fel de declarare complet separat de 10
variabile imaginare, x0, x1, x2, și așa mai departe până la xN-1.
Ignorarea liniile pe care le declara matrice, observați parantezele pătrate intacte
în interiorul pentru bucle.
Când ne-am scrie ceva de genul x [3], pe care voi citi la fel de suport x 3,
vă puteți gândi la ea ca cere imaginar x3.
Aviz decât cu o serie de dimensiune N, acest lucru înseamnă că numărul interiorul paranteze,
pe care vom numi indicele, poate fi orice, de la 0 la N-1,
care este un total de indici N.
>> Să se gândească la modul în care acest fapt de lucrări
amintiți-vă că matrice este un bloc mare de memorie.
Presupunând că un număr întreg este de 4 octeți, x întregului set este un bloc de memorie 40 octet.
Deci x0 se referă la primele 4 bytes de bloc.
X [1] se referă la următoarele 4 octeți și așa mai departe.
Acest lucru înseamnă că la începutul lui x este tot programul vreodată nevoie pentru a ține evidența.
Dacă doriți să utilizați x [400], apoi programul știe că acest lucru este echivalent
la doar 1,600 octeți de la începutul lui x.
De unde vom lua 1600 octeți de la? E doar de 400 de ori 4 bytes pe întreg.
>> Înainte de a trece mai departe, este foarte important să realizăm că, în C
nu există nici punerea în aplicare a indicelui pe care le folosim în matrice.
Blocul nostru de mare este la numai 10 numere întregi lung, dar nimic nu va țipa la noi, dacă vom scrie x [20]
sau chiar x [-5].
Indicele nu are nici măcar să fie un număr.
Acesta poate fi orice expresie arbitrară.
În programul pe care îl utiliza i variabila de bucla pentru a indexa în matrice.
Acesta este un model foarte comun, looping de la i = 0 la lungimea de matrice,
și apoi i folosind ca index pentru matrice.
În acest fel vă în mod eficient bucla pentru întreaga rețea,
și aveți posibilitatea să atribuiți fie la fața locului, în fiecare matrice sau să-l utilizați pentru unele calcul.
>> În prima bucla de, am începe de la 0,
și așa se va atribui la fața locului 0 în matrice, valoarea 0 ori 2.
Apoi am incremente, și am atribui primul loc în matrice valorii de 1 ori 2.
Apoi m-am trepte din nou și așa mai departe, până vom atribui în poziția N-1 în matrice
valoarea N-1 ori 2.
Deci, am creat un tablou cu primele 10 numere chiar.
Poate că ar fi fost echilibreaza un pic mai bine pentru nume variabila decât x,
dar care ar fi dat la o parte lucrurile.
A doua pentru bucla, apoi imprimă doar valorile pe care le-am deja stocate în interiorul tabloului.
>> Să încercați să executați programul cu ambele tipuri de declarații de matrice
și să ia o privire la ieșirea din program.
În ceea ce putem vedea, programul se comporta la fel pentru ambele tipuri de declarații.
Să aruncăm o privire la, de asemenea, ce se întâmplă dacă vom schimba bucla primul să nu se oprească la N
ci spune mai degrabă 10.000.
Dincolo de sfârșitul matrice.
Hopa. Poate că ați văzut asta înainte.
O eroare de segmentare înseamnă programul dumneavoastră prăbușit.
Ai începe să vedeți aceste atunci când atingeți zonele de memorie pe care nu ar trebui să fie tangente.
Aici ne ating 10,000 de locuri, dincolo de începutul lui x,
care, evident, este un loc în memorie nu trebuie să ne atingă.
Deci, cele mai multe dintre noi, probabil, nu ar pune accidental 10000 în loc de N,
dar ce se întâmplă dacă facem ceva mai subtil ca spun de scriere mai mică sau egală cu N
în stare de buclă pentru ca spre deosebire de mai puțin de N.
Amintiți-vă că o matrice are doar indici de la 0 la N-1,
ceea ce înseamnă că indicele N este dincolo de sfârșitul matrice.
Programul nu s-ar putea prăbuși în acest caz, dar este încă o eroare.
De fapt, această eroare este atât de comună că are nume propriu,
un off de 1 eroare.
>> Asta e. pentru elementele de bază.
Deci, ce sunt diferențele majore între cele 2 tipuri de declarații de matrice?
O diferență este în cazul în care bloc mare de memorie merge.
În prima declarație, pe care-l sun pe tipul de suport-matrice,
deși acest lucru nu este deloc un nume convențional,
se va merge pe stivă.
Întrucât, în al doilea, pe care le voi numi de tip pointer-matrice, se va merge pe movila.
Acest lucru înseamnă că, atunci când se întoarce funcția, matricea suportul va fi automat dealocate,
întrucât, trebuie să apelați în mod explicit gratuit de pe matrice indicatorul
sau altceva aveți o scurgere de memorie.
În plus, suportul matrice nu este de fapt o variabilă.
Acest lucru este important. E doar un simbol.
Vă puteți gândi la ea ca la o constantă că compilatorul alege pentru tine.
Acest lucru înseamnă că nu putem face ceva de genul x + + cu tipul de suport,
deși acest lucru este perfect valabil cu tipul pointer.
>> Tipul de pointer este o variabilă.
Pentru tip pointer, avem 2 blocuri separate de memorie.
Variabila x în sine este stocată în stivă și este doar un indicator unic,
dar bloc mare de memorie sunt stocate pe heap.
Variabila x pe stiva stochează doar adresa
de bloc mare de memorie pe heap.
O implicație a acestui fapt este cu dimensiunea de operator.
Dacă vă întrebați pentru dimensiunea de matrice suport, acesta va da dimensiunea de bloc mare de memorie,
ceva de genul 40 octeți,
dar dacă vă întreb pentru dimensiunea de tip pointer de matrice,
acesta va da dimensiunea variabila x în sine, care, pe aparatul este probabil doar 4 octeți.
Utilizarea de tip pointer-matrice, este imposibil de a solicita în mod direct de
dimensiunea de bloc mare de memorie.
Acest lucru nu este, de obicei, de mult o restricție, deoarece am foarte rar doresc dimensiunea
din bloc mare de memorie, și putem calcula, de obicei, aceasta în cazul în care avem nevoie de ea.
>> În cele din urmă, matrice suportul se întâmplă pentru a ne oferi o comandă rapidă pentru inițializarea unei matrice.
Să vedem cum am putea scrie primele 10 numere întregi, chiar folosind initilization de comenzi rapide.
Cu gama indicatorul, nu există o modalitate de a face o comandă rapidă de genul asta.
Aceasta este doar o introducere la ceea ce puteți face cu tablouri.
Ele arată în aproape fiecare program pe care il scrie.
Sperăm că puteți vedea acum o modalitate mai bună de a face un exemplu carduri de student
de la începutul videoclipului.
>> Numele meu este Rob Bowden, iar acest lucru este CS50.