[Powered by Google Translate] Låt oss tala om arrayer.
Så varför skulle vi någonsin vill använda arrayer?
Nåväl låt oss säga att du har ett program som behöver lagra 5 student-ID.
Det kan tyckas rimligt att ha 5 olika variabler.
Av skäl som vi kommer att se i lite, börjar vi räkna från 0.
Variablerna kommer vi att ha kommer att vara int id0, int ID1, och så vidare.
Någon logik vi vill utföra på en student-ID måste kopieras och klistras
för varje av dessa student-ID.
Om vi ​​vill kontrollera vilka elever råkar vara i CS50,
vi måste först kontrollera om id0 representerar studenten i kursen.
Sen att göra samma sak för nästa student, behöver vi för att kopiera och klistra in koden för ID0
och ersätta alla förekomster av ID0 med ID1 och så vidare för ID2, 3 och 4.
>> Så fort du hör att vi måste kopiera och klistra in,
bör du börja tänka att det finns en bättre lösning.
Nu vad händer om du inser att du inte behöver 5 student-ID utan 7?
Du måste gå tillbaka till din källkod och lägga i en ID5, en ID6,
och kopiera och klistra in logiken för att kontrollera om de ID tillhör klassen för dessa 2 nya ID.
Det finns inget förbinder alla dessa ID ihop, och så det finns inget sätt att be
programmet för att göra detta för ID 0 till 6.
Ja nu du inser att du har 100 student-ID.
Det börjar verka mindre än idealisk att behöva separat deklarera alla dessa ID,
och kopiera och klistra in någon logik för de nya ID.
Men kanske är vi fast beslutna, och vi gör det för alla 100 elever.
Men om du inte vet hur många elever det egentligen är?
Det är bara några n studenter och ditt program måste fråga användaren vad det n.
Uh oh. Detta kommer inte att fungera mycket bra.
Ditt program fungerar bara för någon konstant antal elever.
>> Lösa alla dessa problem är skönheten i matriser.
Så vad är en matris?
I vissa programmeringsspråk en array typ skulle kunna göra lite mer,
men här kommer vi att fokusera på den grundläggande matrisen datastrukturen precis som du ser det i C.
En array är bara en stor block av minne. Det var allt.
När vi säger att vi har en mängd 10 heltal, det betyder bara att vi har lite blocket
minne som är tillräckligt stor för att hålla 10 separata heltal.
Förutsatt att ett heltal är 4 byte, innebär detta att en grupp av 10 heltal
är ett sammanhängande block av 40 byte i minnet.
Även när du använder flerdimensionella arrayer, som vi inte kommer att gå in på här,
det är fortfarande bara en stor block av minne.
Den flerdimensionella notation är bara en bekvämlighet.
Om du har en 3 av 3 flerdimensionell array av heltal,
då ditt program kommer egentligen bara behandla detta som en stor block 36 byte.
Det totala antalet heltal är 3 gånger 3, och varje heltal tar upp 4 bytes.
>> Låt oss ta en titt på ett grundläggande exempel.
Vi kan här se 2 olika sätt att förklara matriser.
Vi måste kommentera 1 av dem för programmet att sammanställa
eftersom vi förklarar x två gånger.
Vi tar en titt på några av skillnaderna mellan dessa 2 typer av deklarationer i lite.
Båda dessa linjer förklarar en rad storlek N,
där vi har definierar # N som 10.
Vi kunde lika gärna ha bett användaren för ett positivt heltal
och används som heltal som antalet element i vår array.
Liksom vårt exempel studentlegitimation tidigare är denna typ av som att förklara 10 helt separat
imaginära variabler, x0, x1, x2, och så vidare upp till xn-1.
Ignorera de linjer där vi förklarar arrayen, märker hakparenteserna intakta
inuti för slingor.
När vi skriver något i stil med X [3], som jag ska bara läsa som x konsol 3,
du kan tänka på det som ber om det imaginära x3.
Tillkännagivande än med en array av storlek N, innebär detta att antalet insidan av konsolerna,
som vi kommer att kalla index kan vara allt från 0 till N-1,
vilket är totalt N index.
>> Att tänka på hur det faktiskt fungerar
ihåg att matrisen är en stor minnesblock.
Förutsatt att ett heltal är 4 byte, är hela gruppen X en 40 byte block av minne.
Så x0 hänvisar till de allra första 4 byte i blocket.
X [1] avser de kommande 4 byte och så vidare.
Detta innebär att starten av x är alla program någonsin behöver hålla reda på.
Om du vill använda x [400], programmet vet att det här är likvärdigt
till bara 1.600 byte efter starten av X.
Var fick vi 1.600 byte från? Det är bara 400 gånger 4 byte per heltal.
>> Innan vi går vidare, det är mycket viktigt att inse att i C
det finns ingen kontroll av det index som vi använder i arrayen.
Vår stora block är bara 10 heltal lång, men ingenting kommer skrika på oss om vi skriver x [20]
eller X [-5].
Indexet inte ens vara ett nummer.
Det kan vara någon godtycklig uttryck.
I programmet använder vi variabeln i från for-slingan till index i arrayen.
Detta är ett mycket vanligt mönster, looping från i = 0 till längden av uppsättningen,
och sedan använda i som indexet för arrayen.
På detta sätt kan du effektivt loop över hela matrisen,
och du kan antingen tilldela varje plats i matrisen eller använda den för något beräkning.
>> I den första for-slingan börjar jag vid 0,
och så kommer det att tilldela 0 plats i arrayen, värdet 0 gånger 2.
Då jag steg, och vi tilldelar den första platsen i arrayen värdet 1 gånger 2.
Då jag steg igen och så vidare tills vi tilldelar till läge N-1 i gruppen
värdet N-1 gånger 2.
Så vi har skapat en array med de första 10 jämna nummer.
Kanske jämnar skulle ha varit lite bättre namn på variabeln än x,
men som skulle ha gett bort saker.
Den andra for-slingan sedan bara skriver de värden som vi redan har lagrats på insidan av matrisen.
>> Låt oss försöka köra programmet med båda typerna av array deklarationer
och ta en titt på utgången av programmet.
Såvitt vi kan se, beter sig programmet på samma sätt för båda typerna av deklarationer.
Låt oss också ta en titt på vad som händer om vi ändrar den första slingan att inte stanna vid N
utan snarare säga 10.000.
Långt bortom slutet av arrayen.
Oops. Kanske du har sett det här förut.
En segmenteringsfel betyder ditt program har kraschat.
Du börjar se dessa när du trycker på områden minne du ska inte röra.
Här är vi rör vid 10.000 platser bortom början av x,
som uppenbarligen en plats i minnet att vi inte bör röra.
Så de flesta av oss förmodligen inte skulle misstag sätta 10.000 i stället för N,
men vad händer om vi gör något mer subtilt som att säga skriva mindre än eller lika med N
i for-slingan tillstånd i motsats till mindre än N.
Kom ihåg att en matris endast har index från 0 till N-1,
vilket innebär att index N är bortom änden av arrayen.
Programmet kanske inte krascha i detta fall, men det är fortfarande ett fel.
I själva verket är detta fel så vanligt att den har sitt eget namn,
en av av 1 fel.
>> Det var allt för grunderna.
Så vad är de stora skillnaderna mellan de 2 olika typer av array deklarationer?
En skillnad är där de stora block av minne går.
I den första deklaration som jag ringer fästet-array typ,
även om detta är ingalunda en konventionell namn,
det går på stacken.
Medan det i den andra, som jag ringer pekaren-array typ, kommer det att gå på högen.
Detta innebär att när funktionen returnerar, kommer konsolen arrayen automatiskt deallokeras,
medan du måste explicitily ringa gratis på pekaren array
eller annat du har en minnesläcka.
Dessutom är fästet matrisen faktiskt inte en variabel.
Detta är viktigt. Det är bara en symbol.
Du kan se det som en konstant som kompilatorn väljer åt dig.
Det innebär att vi inte kan göra något liknande X + + med fäste typ,
men detta är helt giltigt med pekaren typ.
>> Pekaren typ är en variabel.
För pekaren typ, har vi 2 separata minnesblock.
Variabeln x själv lagras i stacken och är bara en enda pekare,
men den stora block av minnet lagras på stacken.
Variabeln x på stacken lagrar bara adressen
av den stora minnesblock på högen.
En konsekvens av detta är med storleken på operatören.
Om du ber om storleken på fästet array, kommer det att ge dig storleken på stora block av minne,
ungefär 40 byte,
men om du frågar efter storleken på pekaren typ array
det kommer att ge dig storleken på variabeln x själv, som på apparaten är sannolikt bara 4 byte.
Använda pekaren-array typ, är det omöjligt att direkt begära
storleken på stora block av minne.
Detta är vanligtvis inte mycket av en begränsning eftersom vi mycket sällan vill storleken
av den stora block av minne, och vi kan oftast räkna det om vi behöver det.
>> Slutligen sker fästet array för att förse oss med en genväg för att initiera en array.
Låt oss se hur vi skulle kunna skriva de första 10 jämna heltal med hjälp av genvägen initilization.
Med pekaren array, det finns inte ett sätt att göra en genväg som denna.
Detta är bara en introduktion till vad du kan göra med arrayer.
De dyker upp i nästan varje program du skriver.
Förhoppningsvis kan du nu se en bättre sätt att göra den studerande ID exemplet
från början av videon.
>> Mitt namn är Rob Bowden, och detta är CS50.