1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] Lad os tale om arrays. 2 00:00:09,360 --> 00:00:12,780 Så hvorfor skulle vi nogensinde ønsker at bruge arrays? 3 00:00:12,780 --> 00:00:17,210 Jamen så lad os sige du har et program, der skal til at gemme 5 studerende id'er. 4 00:00:17,210 --> 00:00:21,270 Det kan virke rimeligt at have 5 separate variabler. 5 00:00:21,270 --> 00:00:24,240 Af grunde, vi vil se i en smule, vil vi begynde at tælle fra 0. 6 00:00:24,240 --> 00:00:30,700 De variable vi vil have, vil være int ID0, int ID1, og så videre. 7 00:00:30,700 --> 00:00:34,870 Enhver logik vi ønsker at udføre på et studiekort skal kopieres og indsættes 8 00:00:34,870 --> 00:00:36,870 for hver af disse studerende id'er. 9 00:00:36,870 --> 00:00:39,710 Hvis vi ønsker at se, hvilke studerende tilfældigvis i CS50, 10 00:00:39,710 --> 00:00:43,910 vi først nødt til at kontrollere, om ID0 repræsenterer den studerende i kurset. 11 00:00:43,910 --> 00:00:48,070 Så for at gøre det samme for den næste elev, vil vi nødt til at kopiere og indsætte koden for ID0 12 00:00:48,070 --> 00:00:54,430 og erstatte alle forekomster af ID0 med ID1 og så videre for ID2, 3 og 4. 13 00:00:54,430 --> 00:00:57,560 >> Så snart du hører, at vi er nødt til at kopiere og indsætte, 14 00:00:57,560 --> 00:01:00,440 bør du begynde at tænke, at der er en bedre løsning. 15 00:01:00,440 --> 00:01:05,360 Hvad nu hvis du indser, at du ikke behøver 5 studerende id'er, men snarere 7? 16 00:01:05,360 --> 00:01:09,570 Du er nødt til at gå tilbage i din kilde kode og tilføje i en ID5, en ID6, 17 00:01:09,570 --> 00:01:14,260 og kopiere og indsætte den logik for kontrol, hvis de ID'er tilhører klassen for disse 2 nye ID'er. 18 00:01:14,260 --> 00:01:19,600 Der er intet der forbinder alle disse ID'er sammen, og så der er ingen måde at spørge 19 00:01:19,600 --> 00:01:22,040 programmet for at gøre dette for ID'er 0 til 6. 20 00:01:22,040 --> 00:01:26,120 Nå nu har du indser du har 100 studerende id'er. 21 00:01:26,120 --> 00:01:30,770 Det er begyndt at synes mindre end ideel til brug for at særskilt erklære hver af disse ID'er, 22 00:01:30,770 --> 00:01:33,760 og kopiere og indsætte nogen logik for disse nye ID'er. 23 00:01:33,760 --> 00:01:38,380 Men måske er vi bestemt, og vi gør det for alle 100 elever. 24 00:01:38,380 --> 00:01:42,240 Men hvad nu, hvis du ikke ved, hvor mange studerende der rent faktisk er? 25 00:01:42,240 --> 00:01:47,320 Der er bare nogle n studerende og dit program har at spørge brugeren, hvad der n er. 26 00:01:47,320 --> 00:01:50,250 Uh oh. Dette kommer ikke til at arbejde meget godt. 27 00:01:50,250 --> 00:01:53,820 Dit program virker kun for nogle konstant antal studerende. 28 00:01:53,820 --> 00:01:57,520 >> Løsning alle disse problemer er skønheden i arrays. 29 00:01:57,520 --> 00:01:59,930 Så hvad er et array? 30 00:01:59,930 --> 00:02:04,480 I nogle programmeringssprog et array type, kan være i stand til at gøre en smule mere, 31 00:02:04,480 --> 00:02:09,960 men her vil vi fokusere på den grundlæggende opstilling datastruktur lige som du vil se det i C. 32 00:02:09,960 --> 00:02:14,030 Et array er bare en stor blok af hukommelse. Det er det. 33 00:02:14,030 --> 00:02:17,770 Når vi siger, at vi har en vifte af 10 heltal, der bare betyder, at vi har nogle blok 34 00:02:17,770 --> 00:02:20,740 hukommelse, der er stor nok til at rumme 10 separate heltal. 35 00:02:29,930 --> 00:02:33,410 Antages det, at et helt tal er fire bytes, betyder dette, at et array af 10 heltal 36 00:02:33,410 --> 00:02:37,180 er en kontinuerlig blok på 40 bytes i hukommelsen. 37 00:02:42,660 --> 00:02:46,280 Selv når du bruger flerdimensionelle arrays, som vi ikke vil gå ind på her, 38 00:02:46,280 --> 00:02:49,200 det er stadig bare en stor blok af hukommelse. 39 00:02:49,200 --> 00:02:51,840 Den flerdimensionale notation er bare en bekvemmelighed. 40 00:02:51,840 --> 00:02:55,640 Hvis du har en 3 gange 3 multidimensional array af heltal, 41 00:02:55,640 --> 00:03:00,650 så dit program vil egentlig bare betragte dette som en stor blok af 36 bytes. 42 00:03:00,650 --> 00:03:05,460 Det samlede antal heltal er 3 gange 3, og hvert heltal optager 4 byte. 43 00:03:05,460 --> 00:03:07,750 >> Lad os tage et kig på et grundlæggende eksempel. 44 00:03:07,750 --> 00:03:10,660 Vi kan se her 2 forskellige måder at erklære arrays. 45 00:03:15,660 --> 00:03:18,580 Vi bliver nødt til at kommentere 1 af dem ud for programmet at indsamle 46 00:03:18,580 --> 00:03:20,900 da vi erklærer x to gange. 47 00:03:20,900 --> 00:03:25,140 Vi tager et kig på nogle af forskellene mellem disse 2 typer af erklæringer i en smule. 48 00:03:25,140 --> 00:03:28,560 Begge disse linjer erklærer en vifte af størrelse N, 49 00:03:28,560 --> 00:03:30,740 hvor vi har # define N som 10. 50 00:03:30,740 --> 00:03:34,460 Vi kunne lige så godt have bedt brugeren om et positivt heltal 51 00:03:34,460 --> 00:03:37,250 og brugte den heltal som en række elementer i vores array. 52 00:03:37,250 --> 00:03:41,960 Ligesom vores studiekort eksempel før, det er lidt ligesom at erklære 10 helt adskilt 53 00:03:41,960 --> 00:03:49,000 imaginære variabler, x0, x1, x2, og så videre op til xn-1. 54 00:03:57,270 --> 00:04:00,840 Ignorerer de strækninger, hvor vi erklærer array, bemærker de firkantede parenteser intakt 55 00:04:00,840 --> 00:04:02,090 inde i for-løkker. 56 00:04:02,090 --> 00:04:09,660 Når vi skriver noget i retning af x [3], som jeg bare læses som x konsol 3, 57 00:04:09,660 --> 00:04:13,090 du kan tænke på det som beder om det imaginære x3. 58 00:04:13,090 --> 00:04:17,519 Bemærker end med et array af størrelsen N, betyder dette, at antallet indersiden af ​​konsollerne, 59 00:04:17,519 --> 00:04:22,630 som vi vil kalde indekset, kan være alt fra 0 til N-1, 60 00:04:22,630 --> 00:04:25,660 som er i alt N indeks. 61 00:04:25,660 --> 00:04:28,260 >> At tænke over, hvordan dette rent faktisk virker 62 00:04:28,260 --> 00:04:31,260 huske, at opstillingen er en stor blok af hukommelse. 63 00:04:31,260 --> 00:04:37,460 Antages det, at et helt tal er fire bytes, hele array'et x er en 40 byte blok af hukommelse. 64 00:04:37,460 --> 00:04:41,360 Så x0 refererer til de første 4 bytes af blokken. 65 00:04:45,810 --> 00:04:49,230 X [1] henviser til de næste 4 bytes og så videre. 66 00:04:49,230 --> 00:04:53,760 Dette betyder, at starten på x er så program nogensinde skal holde styr på. 67 00:04:55,660 --> 00:04:59,840 Hvis du ønsker at bruge x [400], så programmet ved, at det er ækvivalent 68 00:04:59,840 --> 00:05:03,460 til kun 1.600 bytes efter starten af ​​x. 69 00:05:03,460 --> 00:05:08,780 Hvor vi får 1.600 bytes fra? Det er blot 400 gange 4 bytes per heltal. 70 00:05:08,780 --> 00:05:13,170 >> Før vi går videre, er det meget vigtigt at indse, at i C 71 00:05:13,170 --> 00:05:17,080 Der er ingen håndhævelse af indekset, som vi bruger i array. 72 00:05:17,080 --> 00:05:23,180 Vores store blok er kun 10 heltal lang, men intet vil yell på os, hvis vi skriver x [20] 73 00:05:23,180 --> 00:05:26,060 eller endog x [-5]. 74 00:05:26,060 --> 00:05:28,240 Indekset har ikke engang at være et tal. 75 00:05:28,240 --> 00:05:30,630 Det kan være enhver vilkårlig ekspression. 76 00:05:30,630 --> 00:05:34,800 I programmet bruger vi variablen i fra for-løkken til indeks i array. 77 00:05:34,800 --> 00:05:40,340 Dette er en meget almindelig mønster, looping fra i = 0 til længde af arrayet, 78 00:05:40,340 --> 00:05:43,350 og derefter bruge i som indekset for opstillingen. 79 00:05:43,350 --> 00:05:46,160 På denne måde kan du faktisk loop over hele systemet, 80 00:05:46,160 --> 00:05:50,600 og du kan enten tildele hver plet i rækken, eller bruge det til noget beregning. 81 00:05:50,600 --> 00:05:53,920 >> I den første for-løkke, starter jeg på 0, 82 00:05:53,920 --> 00:05:58,680 og så det vil tildele 0 plet i arrayet, værdien 0 gange 2. 83 00:05:58,680 --> 00:06:04,370 Så jeg intervaller, og vi tildele det første sted i arrayet værdien 1 gange 2. 84 00:06:04,370 --> 00:06:10,170 Så jeg intervaller igen og så videre indtil vi tildeler at positionere N-1 i array 85 00:06:10,170 --> 00:06:13,370 værdien N-1 gange 2. 86 00:06:13,370 --> 00:06:17,810 Så vi har oprettet et array med de første 10 lige numre. 87 00:06:17,810 --> 00:06:21,970 Måske udligner ville have været en smule bedre navn for variablen end x, 88 00:06:21,970 --> 00:06:24,760 men det ville have givet ting væk. 89 00:06:24,760 --> 00:06:30,210 Den anden for-løkke så bare udskriver de værdier, som vi allerede har gemt inde i array. 90 00:06:30,210 --> 00:06:33,600 >> Lad os prøve at køre programmet med begge typer array-erklæringer 91 00:06:33,600 --> 00:06:36,330 og tage et kig på outputtet af programmet. 92 00:06:51,450 --> 00:06:57,020 Så vidt vi kan se, at programmet opfører sig på samme måde for begge typer erklæringer. 93 00:06:57,020 --> 00:07:02,230 Lad os også tage et kig på, hvad der sker, hvis vi ændre det første sløjfe til ikke stoppe ved N 94 00:07:02,230 --> 00:07:05,040 men snarere sige 10.000. 95 00:07:05,040 --> 00:07:07,430 Langt ud over enden af ​​arrayet. 96 00:07:14,700 --> 00:07:17,210 Ups. Måske har du set det før. 97 00:07:17,210 --> 00:07:20,440 En segmentering fejl betyder, at din program er gået ned. 98 00:07:20,440 --> 00:07:24,430 Du begynder at se disse, når du trykker på områder med hukommelse, bør du ikke røre. 99 00:07:24,430 --> 00:07:27,870 Her er vi rører 10.000 pladser ud over starten af ​​x, 100 00:07:27,870 --> 00:07:31,920 som åbenbart er et sted i hukommelsen, vi skal ikke røre. 101 00:07:31,920 --> 00:07:37,690 Så de fleste af os nok ikke utilsigtet sætte 10.000 i stedet for N, 102 00:07:37,690 --> 00:07:42,930 men hvad nu hvis vi gør noget mere subtile lignende sige skrive mindre end eller lig med N 103 00:07:42,930 --> 00:07:46,830 i for-løkken tilstand i modsætning til mindre end N. 104 00:07:46,830 --> 00:07:50,100 Husk, at en matrix kun har indekser fra 0 til N-1, 105 00:07:50,100 --> 00:07:54,510 hvilket betyder, at indeks N er ud over enden af ​​matrixen. 106 00:07:54,510 --> 00:07:58,050 Programmet kan ikke gå ned i denne sag, men det er stadig en fejl. 107 00:07:58,050 --> 00:08:01,950 I virkeligheden er denne fejl så almindeligt, at det har det eget navn, 108 00:08:01,950 --> 00:08:03,970 en off med 1 fejl. 109 00:08:03,970 --> 00:08:05,970 >> Det er det for det grundlæggende. 110 00:08:05,970 --> 00:08:09,960 Så hvad er de store forskelle mellem de 2 typer af array-erklæringer? 111 00:08:09,960 --> 00:08:13,960 En forskel er, hvor den store blok af hukommelse går. 112 00:08:13,960 --> 00:08:17,660 I den første erklæring, jeg som ringer til beslaget-array-type, 113 00:08:17,660 --> 00:08:20,300 men dette er på ingen måde en konventionel betegnelse, 114 00:08:20,300 --> 00:08:22,480 den kan komme på stakken. 115 00:08:22,480 --> 00:08:27,450 Hvorimod i det andet, som jeg vil kalde markøren-array-typen, vil det gå på heapen. 116 00:08:27,450 --> 00:08:32,480 Det betyder, at når funktionen returnerer, vil konsollen arrayet automatisk blive deallokeret, 117 00:08:32,480 --> 00:08:36,419 hvorimod som du explicitily skal ringe gratis på pointer arrayet 118 00:08:36,419 --> 00:08:38,010 eller andet, du har en hukommelsesfejl. 119 00:08:38,010 --> 00:08:42,750 Derudover konsollen arrayet er faktisk ikke en variabel. 120 00:08:42,750 --> 00:08:45,490 Dette er vigtigt. Det er bare et symbol. 121 00:08:45,490 --> 00:08:49,160 Du kan tænke på det som en konstant at compileren vælger for dig. 122 00:08:49,160 --> 00:08:52,970 Det betyder, at vi ikke kan gøre noget som x + + med beslaget type, 123 00:08:52,970 --> 00:08:56,240 selvom det er fuldt på højde med markøren type. 124 00:08:56,240 --> 00:08:58,270 >> Markøren type er en variabel. 125 00:08:58,270 --> 00:09:01,510 For henvisningstype har vi 2 separate blokke af hukommelsen. 126 00:09:01,510 --> 00:09:06,060 Variablen x selv er lagret i stakken og er blot en enkelt pointerjustering, 127 00:09:06,060 --> 00:09:08,620 men den store blok af hukommelse er lagret på heapen. 128 00:09:08,620 --> 00:09:11,010 Den variable x på stakken bare gemmer adressen 129 00:09:11,010 --> 00:09:14,010 af den store blok af hukommelse på heapen. 130 00:09:14,010 --> 00:09:17,370 En implikation af dette er med størrelsen af ​​operatøren. 131 00:09:17,370 --> 00:09:22,480 Hvis du beder om størrelsen af ​​konsollen array, vil det give dig størrelsen af ​​den store blok af hukommelse, 132 00:09:22,480 --> 00:09:24,620 noget lignende 40 bytes, 133 00:09:24,620 --> 00:09:26,920 men hvis du beder om størrelsen af ​​pointer type array, 134 00:09:26,920 --> 00:09:32,740 det vil give dig størrelsen af ​​den variable x selv, som om apparatet er sandsynligvis kun 4 bytes. 135 00:09:32,740 --> 00:09:36,530 Brug markøren array type, er det umuligt at direkte bede om 136 00:09:36,530 --> 00:09:38,530 størrelsen af ​​den store blok af hukommelse. 137 00:09:38,530 --> 00:09:42,530 Dette er normalt ikke meget af en begrænsning, da vi meget sjældent vil have den størrelse 138 00:09:42,530 --> 00:09:46,980 af den store blok af hukommelse, og vi kan som regel beregne det, hvis vi har brug for det. 139 00:09:46,980 --> 00:09:51,490 >> Endelig konsollen arrayet sker for at give os en genvej til initialisering et array. 140 00:09:51,490 --> 00:09:56,130 Lad os se, hvordan vi kunne skrive de første 10 lige heltal ved hjælp af genvejen initilization. 141 00:10:11,220 --> 00:10:14,470 Med markøren array, er der ikke en måde at gøre en genvej som denne. 142 00:10:14,470 --> 00:10:18,120 Dette er blot en introduktion til, hvad du kan gøre med arrays. 143 00:10:18,120 --> 00:10:20,990 De dukker op i næsten alle program, du skriver. 144 00:10:20,990 --> 00:10:24,390 Forhåbentlig kan du nu se en bedre måde at gøre den studerende id'er eksempel 145 00:10:24,390 --> 00:10:26,710 fra begyndelsen af ​​video. 146 00:10:26,710 --> 00:10:29,960 >> Mit navn er Rob Bowden, og dette er CS50.