1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] Låt oss tala om arrayer. 2 00:00:09,360 --> 00:00:12,780 Så varför skulle vi någonsin vill använda arrayer? 3 00:00:12,780 --> 00:00:17,210 Nåväl låt oss säga att du har ett program som behöver lagra 5 student-ID. 4 00:00:17,210 --> 00:00:21,270 Det kan tyckas rimligt att ha 5 olika variabler. 5 00:00:21,270 --> 00:00:24,240 Av skäl som vi kommer att se i lite, börjar vi räkna från 0. 6 00:00:24,240 --> 00:00:30,700 Variablerna kommer vi att ha kommer att vara int id0, int ID1, och så vidare. 7 00:00:30,700 --> 00:00:34,870 Någon logik vi vill utföra på en student-ID måste kopieras och klistras 8 00:00:34,870 --> 00:00:36,870 för varje av dessa student-ID. 9 00:00:36,870 --> 00:00:39,710 Om vi ​​vill kontrollera vilka elever råkar vara i CS50, 10 00:00:39,710 --> 00:00:43,910 vi måste först kontrollera om id0 representerar studenten i kursen. 11 00:00:43,910 --> 00:00:48,070 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 12 00:00:48,070 --> 00:00:54,430 och ersätta alla förekomster av ID0 med ID1 och så vidare för ID2, 3 och 4. 13 00:00:54,430 --> 00:00:57,560 >> Så fort du hör att vi måste kopiera och klistra in, 14 00:00:57,560 --> 00:01:00,440 bör du börja tänka att det finns en bättre lösning. 15 00:01:00,440 --> 00:01:05,360 Nu vad händer om du inser att du inte behöver 5 student-ID utan 7? 16 00:01:05,360 --> 00:01:09,570 Du måste gå tillbaka till din källkod och lägga i en ID5, en ID6, 17 00:01:09,570 --> 00:01:14,260 och kopiera och klistra in logiken för att kontrollera om de ID tillhör klassen för dessa 2 nya ID. 18 00:01:14,260 --> 00:01:19,600 Det finns inget förbinder alla dessa ID ihop, och så det finns inget sätt att be 19 00:01:19,600 --> 00:01:22,040 programmet för att göra detta för ID 0 till 6. 20 00:01:22,040 --> 00:01:26,120 Ja nu du inser att du har 100 student-ID. 21 00:01:26,120 --> 00:01:30,770 Det börjar verka mindre än idealisk att behöva separat deklarera alla dessa ID, 22 00:01:30,770 --> 00:01:33,760 och kopiera och klistra in någon logik för de nya ID. 23 00:01:33,760 --> 00:01:38,380 Men kanske är vi fast beslutna, och vi gör det för alla 100 elever. 24 00:01:38,380 --> 00:01:42,240 Men om du inte vet hur många elever det egentligen är? 25 00:01:42,240 --> 00:01:47,320 Det är bara några n studenter och ditt program måste fråga användaren vad det n. 26 00:01:47,320 --> 00:01:50,250 Uh oh. Detta kommer inte att fungera mycket bra. 27 00:01:50,250 --> 00:01:53,820 Ditt program fungerar bara för någon konstant antal elever. 28 00:01:53,820 --> 00:01:57,520 >> Lösa alla dessa problem är skönheten i matriser. 29 00:01:57,520 --> 00:01:59,930 Så vad är en matris? 30 00:01:59,930 --> 00:02:04,480 I vissa programmeringsspråk en array typ skulle kunna göra lite mer, 31 00:02:04,480 --> 00:02:09,960 men här kommer vi att fokusera på den grundläggande matrisen datastrukturen precis som du ser det i C. 32 00:02:09,960 --> 00:02:14,030 En array är bara en stor block av minne. Det var allt. 33 00:02:14,030 --> 00:02:17,770 När vi säger att vi har en mängd 10 heltal, det betyder bara att vi har lite blocket 34 00:02:17,770 --> 00:02:20,740 minne som är tillräckligt stor för att hålla 10 separata heltal. 35 00:02:29,930 --> 00:02:33,410 Förutsatt att ett heltal är 4 byte, innebär detta att en grupp av 10 heltal 36 00:02:33,410 --> 00:02:37,180 är ett sammanhängande block av 40 byte i minnet. 37 00:02:42,660 --> 00:02:46,280 Även när du använder flerdimensionella arrayer, som vi inte kommer att gå in på här, 38 00:02:46,280 --> 00:02:49,200 det är fortfarande bara en stor block av minne. 39 00:02:49,200 --> 00:02:51,840 Den flerdimensionella notation är bara en bekvämlighet. 40 00:02:51,840 --> 00:02:55,640 Om du har en 3 av 3 flerdimensionell array av heltal, 41 00:02:55,640 --> 00:03:00,650 då ditt program kommer egentligen bara behandla detta som en stor block 36 byte. 42 00:03:00,650 --> 00:03:05,460 Det totala antalet heltal är 3 gånger 3, och varje heltal tar upp 4 bytes. 43 00:03:05,460 --> 00:03:07,750 >> Låt oss ta en titt på ett grundläggande exempel. 44 00:03:07,750 --> 00:03:10,660 Vi kan här se 2 olika sätt att förklara matriser. 45 00:03:15,660 --> 00:03:18,580 Vi måste kommentera 1 av dem för programmet att sammanställa 46 00:03:18,580 --> 00:03:20,900 eftersom vi förklarar x två gånger. 47 00:03:20,900 --> 00:03:25,140 Vi tar en titt på några av skillnaderna mellan dessa 2 typer av deklarationer i lite. 48 00:03:25,140 --> 00:03:28,560 Båda dessa linjer förklarar en rad storlek N, 49 00:03:28,560 --> 00:03:30,740 där vi har definierar # N som 10. 50 00:03:30,740 --> 00:03:34,460 Vi kunde lika gärna ha bett användaren för ett positivt heltal 51 00:03:34,460 --> 00:03:37,250 och används som heltal som antalet element i vår array. 52 00:03:37,250 --> 00:03:41,960 Liksom vårt exempel studentlegitimation tidigare är denna typ av som att förklara 10 helt separat 53 00:03:41,960 --> 00:03:49,000 imaginära variabler, x0, x1, x2, och så vidare upp till xn-1. 54 00:03:57,270 --> 00:04:00,840 Ignorera de linjer där vi förklarar arrayen, märker hakparenteserna intakta 55 00:04:00,840 --> 00:04:02,090 inuti för slingor. 56 00:04:02,090 --> 00:04:09,660 När vi skriver något i stil med X [3], som jag ska bara läsa som x konsol 3, 57 00:04:09,660 --> 00:04:13,090 du kan tänka på det som ber om det imaginära x3. 58 00:04:13,090 --> 00:04:17,519 Tillkännagivande än med en array av storlek N, innebär detta att antalet insidan av konsolerna, 59 00:04:17,519 --> 00:04:22,630 som vi kommer att kalla index kan vara allt från 0 till N-1, 60 00:04:22,630 --> 00:04:25,660 vilket är totalt N index. 61 00:04:25,660 --> 00:04:28,260 >> Att tänka på hur det faktiskt fungerar 62 00:04:28,260 --> 00:04:31,260 ihåg att matrisen är en stor minnesblock. 63 00:04:31,260 --> 00:04:37,460 Förutsatt att ett heltal är 4 byte, är hela gruppen X en 40 byte block av minne. 64 00:04:37,460 --> 00:04:41,360 Så x0 hänvisar till de allra första 4 byte i blocket. 65 00:04:45,810 --> 00:04:49,230 X [1] avser de kommande 4 byte och så vidare. 66 00:04:49,230 --> 00:04:53,760 Detta innebär att starten av x är alla program någonsin behöver hålla reda på. 67 00:04:55,660 --> 00:04:59,840 Om du vill använda x [400], programmet vet att det här är likvärdigt 68 00:04:59,840 --> 00:05:03,460 till bara 1.600 byte efter starten av X. 69 00:05:03,460 --> 00:05:08,780 Var fick vi 1.600 byte från? Det är bara 400 gånger 4 byte per heltal. 70 00:05:08,780 --> 00:05:13,170 >> Innan vi går vidare, det är mycket viktigt att inse att i C 71 00:05:13,170 --> 00:05:17,080 det finns ingen kontroll av det index som vi använder i arrayen. 72 00:05:17,080 --> 00:05:23,180 Vår stora block är bara 10 heltal lång, men ingenting kommer skrika på oss om vi skriver x [20] 73 00:05:23,180 --> 00:05:26,060 eller X [-5]. 74 00:05:26,060 --> 00:05:28,240 Indexet inte ens vara ett nummer. 75 00:05:28,240 --> 00:05:30,630 Det kan vara någon godtycklig uttryck. 76 00:05:30,630 --> 00:05:34,800 I programmet använder vi variabeln i från for-slingan till index i arrayen. 77 00:05:34,800 --> 00:05:40,340 Detta är ett mycket vanligt mönster, looping från i = 0 till längden av uppsättningen, 78 00:05:40,340 --> 00:05:43,350 och sedan använda i som indexet för arrayen. 79 00:05:43,350 --> 00:05:46,160 På detta sätt kan du effektivt loop över hela matrisen, 80 00:05:46,160 --> 00:05:50,600 och du kan antingen tilldela varje plats i matrisen eller använda den för något beräkning. 81 00:05:50,600 --> 00:05:53,920 >> I den första for-slingan börjar jag vid 0, 82 00:05:53,920 --> 00:05:58,680 och så kommer det att tilldela 0 plats i arrayen, värdet 0 gånger 2. 83 00:05:58,680 --> 00:06:04,370 Då jag steg, och vi tilldelar den första platsen i arrayen värdet 1 gånger 2. 84 00:06:04,370 --> 00:06:10,170 Då jag steg igen och så vidare tills vi tilldelar till läge N-1 i gruppen 85 00:06:10,170 --> 00:06:13,370 värdet N-1 gånger 2. 86 00:06:13,370 --> 00:06:17,810 Så vi har skapat en array med de första 10 jämna nummer. 87 00:06:17,810 --> 00:06:21,970 Kanske jämnar skulle ha varit lite bättre namn på variabeln än x, 88 00:06:21,970 --> 00:06:24,760 men som skulle ha gett bort saker. 89 00:06:24,760 --> 00:06:30,210 Den andra for-slingan sedan bara skriver de värden som vi redan har lagrats på insidan av matrisen. 90 00:06:30,210 --> 00:06:33,600 >> Låt oss försöka köra programmet med båda typerna av array deklarationer 91 00:06:33,600 --> 00:06:36,330 och ta en titt på utgången av programmet. 92 00:06:51,450 --> 00:06:57,020 Såvitt vi kan se, beter sig programmet på samma sätt för båda typerna av deklarationer. 93 00:06:57,020 --> 00:07:02,230 Låt oss också ta en titt på vad som händer om vi ändrar den första slingan att inte stanna vid N 94 00:07:02,230 --> 00:07:05,040 utan snarare säga 10.000. 95 00:07:05,040 --> 00:07:07,430 Långt bortom slutet av arrayen. 96 00:07:14,700 --> 00:07:17,210 Oops. Kanske du har sett det här förut. 97 00:07:17,210 --> 00:07:20,440 En segmenteringsfel betyder ditt program har kraschat. 98 00:07:20,440 --> 00:07:24,430 Du börjar se dessa när du trycker på områden minne du ska inte röra. 99 00:07:24,430 --> 00:07:27,870 Här är vi rör vid 10.000 platser bortom början av x, 100 00:07:27,870 --> 00:07:31,920 som uppenbarligen en plats i minnet att vi inte bör röra. 101 00:07:31,920 --> 00:07:37,690 Så de flesta av oss förmodligen inte skulle misstag sätta 10.000 i stället för N, 102 00:07:37,690 --> 00:07:42,930 men vad händer om vi gör något mer subtilt som att säga skriva mindre än eller lika med N 103 00:07:42,930 --> 00:07:46,830 i for-slingan tillstånd i motsats till mindre än N. 104 00:07:46,830 --> 00:07:50,100 Kom ihåg att en matris endast har index från 0 till N-1, 105 00:07:50,100 --> 00:07:54,510 vilket innebär att index N är bortom änden av arrayen. 106 00:07:54,510 --> 00:07:58,050 Programmet kanske inte krascha i detta fall, men det är fortfarande ett fel. 107 00:07:58,050 --> 00:08:01,950 I själva verket är detta fel så vanligt att den har sitt eget namn, 108 00:08:01,950 --> 00:08:03,970 en av av 1 fel. 109 00:08:03,970 --> 00:08:05,970 >> Det var allt för grunderna. 110 00:08:05,970 --> 00:08:09,960 Så vad är de stora skillnaderna mellan de 2 olika typer av array deklarationer? 111 00:08:09,960 --> 00:08:13,960 En skillnad är där de stora block av minne går. 112 00:08:13,960 --> 00:08:17,660 I den första deklaration som jag ringer fästet-array typ, 113 00:08:17,660 --> 00:08:20,300 även om detta är ingalunda en konventionell namn, 114 00:08:20,300 --> 00:08:22,480 det går på stacken. 115 00:08:22,480 --> 00:08:27,450 Medan det i den andra, som jag ringer pekaren-array typ, kommer det att gå på högen. 116 00:08:27,450 --> 00:08:32,480 Detta innebär att när funktionen returnerar, kommer konsolen arrayen automatiskt deallokeras, 117 00:08:32,480 --> 00:08:36,419 medan du måste explicitily ringa gratis på pekaren array 118 00:08:36,419 --> 00:08:38,010 eller annat du har en minnesläcka. 119 00:08:38,010 --> 00:08:42,750 Dessutom är fästet matrisen faktiskt inte en variabel. 120 00:08:42,750 --> 00:08:45,490 Detta är viktigt. Det är bara en symbol. 121 00:08:45,490 --> 00:08:49,160 Du kan se det som en konstant som kompilatorn väljer åt dig. 122 00:08:49,160 --> 00:08:52,970 Det innebär att vi inte kan göra något liknande X + + med fäste typ, 123 00:08:52,970 --> 00:08:56,240 men detta är helt giltigt med pekaren typ. 124 00:08:56,240 --> 00:08:58,270 >> Pekaren typ är en variabel. 125 00:08:58,270 --> 00:09:01,510 För pekaren typ, har vi 2 separata minnesblock. 126 00:09:01,510 --> 00:09:06,060 Variabeln x själv lagras i stacken och är bara en enda pekare, 127 00:09:06,060 --> 00:09:08,620 men den stora block av minnet lagras på stacken. 128 00:09:08,620 --> 00:09:11,010 Variabeln x på stacken lagrar bara adressen 129 00:09:11,010 --> 00:09:14,010 av den stora minnesblock på högen. 130 00:09:14,010 --> 00:09:17,370 En konsekvens av detta är med storleken på operatören. 131 00:09:17,370 --> 00:09:22,480 Om du ber om storleken på fästet array, kommer det att ge dig storleken på stora block av minne, 132 00:09:22,480 --> 00:09:24,620 ungefär 40 byte, 133 00:09:24,620 --> 00:09:26,920 men om du frågar efter storleken på pekaren typ array 134 00:09:26,920 --> 00:09:32,740 det kommer att ge dig storleken på variabeln x själv, som på apparaten är sannolikt bara 4 byte. 135 00:09:32,740 --> 00:09:36,530 Använda pekaren-array typ, är det omöjligt att direkt begära 136 00:09:36,530 --> 00:09:38,530 storleken på stora block av minne. 137 00:09:38,530 --> 00:09:42,530 Detta är vanligtvis inte mycket av en begränsning eftersom vi mycket sällan vill storleken 138 00:09:42,530 --> 00:09:46,980 av den stora block av minne, och vi kan oftast räkna det om vi behöver det. 139 00:09:46,980 --> 00:09:51,490 >> Slutligen sker fästet array för att förse oss med en genväg för att initiera en array. 140 00:09:51,490 --> 00:09:56,130 Låt oss se hur vi skulle kunna skriva de första 10 jämna heltal med hjälp av genvägen initilization. 141 00:10:11,220 --> 00:10:14,470 Med pekaren array, det finns inte ett sätt att göra en genväg som denna. 142 00:10:14,470 --> 00:10:18,120 Detta är bara en introduktion till vad du kan göra med arrayer. 143 00:10:18,120 --> 00:10:20,990 De dyker upp i nästan varje program du skriver. 144 00:10:20,990 --> 00:10:24,390 Förhoppningsvis kan du nu se en bättre sätt att göra den studerande ID exemplet 145 00:10:24,390 --> 00:10:26,710 från början av videon. 146 00:10:26,710 --> 00:10:29,960 >> Mitt namn är Rob Bowden, och detta är CS50.