1 00:00:07,360 --> 00:00:09,360 [Powered by Google Translate] La oss snakke om arrays. 2 00:00:09,360 --> 00:00:12,780 Så hvorfor skulle vi ønske å bruke arrays? 3 00:00:12,780 --> 00:00:17,210 Vel la oss si du har et program som trenger å lagre 5 student IDer. 4 00:00:17,210 --> 00:00:21,270 Det kan virke rimelig å ha 5 separate variabler. 5 00:00:21,270 --> 00:00:24,240 Av grunner vi vil se i en bit, vil vi begynne å telle fra 0. 6 00:00:24,240 --> 00:00:30,700 Variablene vi vil ha vil bli int ID0, int ID1, og så videre. 7 00:00:30,700 --> 00:00:34,870 Noen logikk vi ønsker å utføre på en student-ID må kopieres og limes 8 00:00:34,870 --> 00:00:36,870 for hver av disse student-ID. 9 00:00:36,870 --> 00:00:39,710 Hvis vi ønsker å sjekke hvilke studenter måtte være i CS50, 10 00:00:39,710 --> 00:00:43,910 Vi må først sjekke om ID0 representerer student i kurset. 11 00:00:43,910 --> 00:00:48,070 Så for å gjøre det samme for neste student, må vi kopiere og lime inn koden for ID0 12 00:00:48,070 --> 00:00:54,430 og erstatte alle forekomster av 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 trenger å kopiere og lime inn, 14 00:00:57,560 --> 00:01:00,440 du bør begynne å tenke på at det er en bedre løsning. 15 00:01:00,440 --> 00:01:05,360 Hva nå hvis du innser at du ikke trenger 5 studenter IDer men heller 7? 16 00:01:05,360 --> 00:01:09,570 Du trenger å gå tilbake til kildekoden og legge i en ID5, en id6, 17 00:01:09,570 --> 00:01:14,260 og kopiere og lime inn logikk for å sjekke om de IDer tilhører klassen for disse to nye IDer. 18 00:01:14,260 --> 00:01:19,600 Det er ingenting å koble alle disse IDene sammen, og så er det ingen måte å spørre 19 00:01:19,600 --> 00:01:22,040 programmet å gjøre dette for IDer 0 til 6. 20 00:01:22,040 --> 00:01:26,120 Vel nå innser at du har 100 studenter IDer. 21 00:01:26,120 --> 00:01:30,770 Det begynner å virke mindre enn ideelle til å trenge å separat erklære hver av disse IDene, 22 00:01:30,770 --> 00:01:33,760 og kopiere og lime inn noen logikk for de nye ID-er. 23 00:01:33,760 --> 00:01:38,380 Men kanskje vi er fast bestemt på, og vi gjør det for alle 100 studenter. 24 00:01:38,380 --> 00:01:42,240 Men hva hvis du ikke vet hvor mange elever det faktisk er? 25 00:01:42,240 --> 00:01:47,320 Det er bare noen n studenter og programmet har å spørre brukeren hva som n er. 26 00:01:47,320 --> 00:01:50,250 Uh oh. Dette er ikke til å fungere veldig bra. 27 00:01:50,250 --> 00:01:53,820 Programmet fungerer bare for noen konstant antall studenter. 28 00:01:53,820 --> 00:01:57,520 >> Løse alle disse problemene er skjønnheten i arrays. 29 00:01:57,520 --> 00:01:59,930 Så hva er en matrise? 30 00:01:59,930 --> 00:02:04,480 I noen programmeringsspråk en rekke typer kan være i stand til å gjøre litt mer, 31 00:02:04,480 --> 00:02:09,960 men her vil vi fokusere på grunnleggende matrise datastrukturen akkurat som du vil se den i C. 32 00:02:09,960 --> 00:02:14,030 En matrise er bare en stor blokk med minne. Det var det. 33 00:02:14,030 --> 00:02:17,770 Når vi sier vi har en rekke 10 heltall, det betyr bare at vi har noen blokk 34 00:02:17,770 --> 00:02:20,740 minne som er stor nok til å romme 10 separate heltall. 35 00:02:29,930 --> 00:02:33,410 Forutsatt at et heltall er 4 byte, betyr dette at en rekke av 10 heltall 36 00:02:33,410 --> 00:02:37,180 er en sammenhengende blokk på 40 byte i minnet. 37 00:02:42,660 --> 00:02:46,280 Selv når du bruker flerdimensjonale arrays, som vi ikke vil gå inn på her, 38 00:02:46,280 --> 00:02:49,200 det er fortsatt bare en stor blokk med minne. 39 00:02:49,200 --> 00:02:51,840 Flerdimensjonale notasjon er bare et hjelpemiddel. 40 00:02:51,840 --> 00:02:55,640 Hvis du har en 3 x 3 flerdimensjonal array av heltall, 41 00:02:55,640 --> 00:03:00,650 da programmet vil egentlig bare behandle dette som en stor blokk med 36 byte. 42 00:03:00,650 --> 00:03:05,460 Det totale antall av heltall er 3 ganger 3, og hver heltall tar opp 4 byte. 43 00:03:05,460 --> 00:03:07,750 >> La oss ta en titt på en grunnleggende eksempel. 44 00:03:07,750 --> 00:03:10,660 Vi ser her to forskjellige måter erklære arrays. 45 00:03:15,660 --> 00:03:18,580 Vi må kommentere en av dem ut for programmet å kompilere 46 00:03:18,580 --> 00:03:20,900 siden vi erklærer x to ganger. 47 00:03:20,900 --> 00:03:25,140 Vi vil ta en titt på noen av forskjellene mellom disse to typene erklæringer i litt. 48 00:03:25,140 --> 00:03:28,560 Begge disse linjene erklære en rekke 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 like gjerne ha spurt brukeren om et positivt heltall 51 00:03:34,460 --> 00:03:37,250 og brukes som heltall som en rekke elementer i matrisen vår. 52 00:03:37,250 --> 00:03:41,960 Liker vår student-ID eksempel før, er dette typen som erklære 10 helt separat 53 00:03:41,960 --> 00:03:49,000 imaginære variabler; x0, x1, x2, og så videre opp til xN-1. 54 00:03:57,270 --> 00:04:00,840 Ignorerer linjer der vi erklærer tabellen, merker klammeparentesene intakt 55 00:04:00,840 --> 00:04:02,090 inne i for sløyfer. 56 00:04:02,090 --> 00:04:09,660 Når vi skriver noe sånt x [3], som jeg vil bare lese som x brakett 3, 57 00:04:09,660 --> 00:04:13,090 du kan tenke på det som å be om den imaginære x3. 58 00:04:13,090 --> 00:04:17,519 Merke enn med en matrise av størrelse N, betyr dette at antall innsiden av vinkelen, 59 00:04:17,519 --> 00:04:22,630 som vi kaller indeksen, kan være alt fra 0 til N-1, 60 00:04:22,630 --> 00:04:25,660 som er en total av N indeksene. 61 00:04:25,660 --> 00:04:28,260 >> Å tenke på hvordan dette faktisk fungerer 62 00:04:28,260 --> 00:04:31,260 husk at matrisen er en stor blokk med minne. 63 00:04:31,260 --> 00:04:37,460 Forutsatt at et heltall er 4 bytes, er hele matrisen X en 40 byte minneblokk. 64 00:04:37,460 --> 00:04:41,360 Så x0 refererer til de aller første 4 byte av blokken. 65 00:04:45,810 --> 00:04:49,230 X [1] viser til de neste 4 byte og så videre. 66 00:04:49,230 --> 00:04:53,760 Dette betyr at inngangen av x er alle program noensinne behov for å holde styr på. 67 00:04:55,660 --> 00:04:59,840 Hvis du ønsker å bruke x [400], og programmet vet at dette tilsvarer 68 00:04:59,840 --> 00:05:03,460 til bare 1600 byte etter starten av x. 69 00:05:03,460 --> 00:05:08,780 Hvor fikk vi får 1600 bytes fra? Det er bare 400 ganger 4 bytes per tall. 70 00:05:08,780 --> 00:05:13,170 >> Før du går videre, er det svært viktig å innse at i C 71 00:05:13,170 --> 00:05:17,080 Det er ingen håndhevelse av indeksen som vi bruker i tabellen. 72 00:05:17,080 --> 00:05:23,180 Vår store blokken er bare 10 heltall lang, men ingenting vil kjefte på oss hvis 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 Indeksen har ikke engang å være ett nummer. 75 00:05:28,240 --> 00:05:30,630 Det kan være en hvilken som helst vilkårlig uttrykk. 76 00:05:30,630 --> 00:05:34,800 I programmet bruker vi variabelen i fra for loop å indeksere inn i matrisen. 77 00:05:34,800 --> 00:05:40,340 Dette er en svært vanlig mønster looping fra i = 0 til lengden av tabellen, 78 00:05:40,340 --> 00:05:43,350 og deretter bruke jeg som indeksen for tabellen. 79 00:05:43,350 --> 00:05:46,160 På denne måten du effektivt sløyfe over hele array, 80 00:05:46,160 --> 00:05:50,600 og du kan enten tildele hver plass i matrisen eller bruke det til noen beregning. 81 00:05:50,600 --> 00:05:53,920 >> I den første for-løkken, starter jeg ved 0, 82 00:05:53,920 --> 00:05:58,680 og slik vil det tilordne til 0 plass i tabellen, verdien 0 ganger 2. 83 00:05:58,680 --> 00:06:04,370 Så jeg trinn, og vi tilordne det første stedet i matrisen verdien 1 ganger 2. 84 00:06:04,370 --> 00:06:10,170 Så jeg trinn igjen og så videre inntil vi gir posisjonere N-1 i rekken 85 00:06:10,170 --> 00:06:13,370 verdien N-1 ganger 2. 86 00:06:13,370 --> 00:06:17,810 Derfor har vi laget en matrise med de første 10 partall. 87 00:06:17,810 --> 00:06:21,970 Kanskje jevner ville ha vært litt bedre navn på variabelen enn x, 88 00:06:21,970 --> 00:06:24,760 men som ville ha gitt ting unna. 89 00:06:24,760 --> 00:06:30,210 Den andre for loop så skriver bare de verdiene som vi allerede har lagret inne i matrisen. 90 00:06:30,210 --> 00:06:33,600 >> La oss prøve å kjøre programmet med begge typer rekke erklæringer 91 00:06:33,600 --> 00:06:36,330 og ta en titt på utgangen av programmet. 92 00:06:51,450 --> 00:06:57,020 Så vidt vi kan se, oppfører programmet på samme måte for begge typer erklæringer. 93 00:06:57,020 --> 00:07:02,230 La oss også ta en titt på hva som skjer hvis vi endrer den første loop til ikke stoppe på N 94 00:07:02,230 --> 00:07:05,040 men heller si 10.000. 95 00:07:05,040 --> 00:07:07,430 Langt utover slutten av tabellen. 96 00:07:14,700 --> 00:07:17,210 Oops. Kanskje du har sett dette før. 97 00:07:17,210 --> 00:07:20,440 En segmentering feil betyr at programmet har krasjet. 98 00:07:20,440 --> 00:07:24,430 Du begynner å se disse når du trykker på områder av minnet du ikke bør berøre. 99 00:07:24,430 --> 00:07:27,870 Her er vi rørende 10000 steder utenfor inngangen til x, 100 00:07:27,870 --> 00:07:31,920 som er åpenbart et sted i minnet vi ikke bør berøre. 101 00:07:31,920 --> 00:07:37,690 Så de fleste av oss sannsynligvis ikke ville ved et uhell sette 10000 i stedet for N, 102 00:07:37,690 --> 00:07:42,930 men hva hvis vi gjør noe mer subtil som sier write mindre enn eller lik N 103 00:07:42,930 --> 00:07:46,830 i for loop tilstand i motsetning til mindre enn N. 104 00:07:46,830 --> 00:07:50,100 Husk at en matrise bare har indekser fra 0 til n-1, 105 00:07:50,100 --> 00:07:54,510 noe som betyr at indeks N er utover slutten av tabellen. 106 00:07:54,510 --> 00:07:58,050 Programmet er kanskje ikke krasje i dette tilfellet, men det er fortsatt en feil. 107 00:07:58,050 --> 00:08:01,950 Faktisk er denne feilen så vanlig at det har det egne navn, 108 00:08:01,950 --> 00:08:03,970 en av ved en feil. 109 00:08:03,970 --> 00:08:05,970 >> Det er det for det grunnleggende. 110 00:08:05,970 --> 00:08:09,960 Så hva er de største forskjellene mellom de to typene rekke erklæringer? 111 00:08:09,960 --> 00:08:13,960 En forskjell er der den store blokken av minnet går. 112 00:08:13,960 --> 00:08:17,660 I den første erklæringen, som jeg vil kalle braketten-array type, 113 00:08:17,660 --> 00:08:20,300 selv om dette er på ingen måte en konvensjonell navn, 114 00:08:20,300 --> 00:08:22,480 det vil gå på stakken. 115 00:08:22,480 --> 00:08:27,450 Mens i andre, som jeg vil kalle pekeren-array type, vil det gå på haugen. 116 00:08:27,450 --> 00:08:32,480 Dette betyr at når funksjonen returnerer vil braketten matrisen automatisk deallocated, 117 00:08:32,480 --> 00:08:36,419 mens som du må eksplisitt ringe gratis på pekeren rekke 118 00:08:36,419 --> 00:08:38,010 eller annet du har en minnelekkasje. 119 00:08:38,010 --> 00:08:42,750 I tillegg, er braketten matrisen faktisk ikke en variabel. 120 00:08:42,750 --> 00:08:45,490 Dette er viktig. Det er bare et symbol. 121 00:08:45,490 --> 00:08:49,160 Du kan tenke på det som en konstant som kompilatoren velger for deg. 122 00:08:49,160 --> 00:08:52,970 Dette betyr at vi ikke kan gjøre noe sånt x + + med braketten type, 123 00:08:52,970 --> 00:08:56,240 men dette er helt gyldig med pekeren type. 124 00:08:56,240 --> 00:08:58,270 >> Pekeren typen er en variabel. 125 00:08:58,270 --> 00:09:01,510 For pekeren type, har vi 2 separate blokker av minnet. 126 00:09:01,510 --> 00:09:06,060 Variabelen X selv er lagret i stakken og er bare en enkelt peker, 127 00:09:06,060 --> 00:09:08,620 men den store blokken av minnet er lagret på haugen. 128 00:09:08,620 --> 00:09:11,010 Variabelen x på stakken lagrer bare adressen 129 00:09:11,010 --> 00:09:14,010 av den store blokken av minnet på haugen. 130 00:09:14,010 --> 00:09:17,370 En implikasjon av denne er med størrelsen av operatør. 131 00:09:17,370 --> 00:09:22,480 Hvis du ber om størrelsen på braketten array, vil det gi deg størrelsen på den store blokken av minne, 132 00:09:22,480 --> 00:09:24,620 noe sånt som 40 byte, 133 00:09:24,620 --> 00:09:26,920 men hvis du ber om størrelsen på pekeren type array, 134 00:09:26,920 --> 00:09:32,740 det vil gi deg størrelsen på variabelen x selv, som på apparatet er sannsynlig bare 4 bytes. 135 00:09:32,740 --> 00:09:36,530 Ved hjelp av pekeren-array type, er det umulig å direkte spørre om 136 00:09:36,530 --> 00:09:38,530 størrelsen av den store minneblokk. 137 00:09:38,530 --> 00:09:42,530 Dette er vanligvis ikke mye av en begrensning siden vi svært sjelden ønsker størrelsen 138 00:09:42,530 --> 00:09:46,980 av den store blokken av minnet, og vi kan vanligvis regne det hvis vi trenger det. 139 00:09:46,980 --> 00:09:51,490 >> Endelig skjer braketten rekke å gi oss en snarvei for initialisering en matrise. 140 00:09:51,490 --> 00:09:56,130 La oss se hvordan vi kan skrive de første 10 selv heltall ved hjelp av snarveien initilization. 141 00:10:11,220 --> 00:10:14,470 Med pekeren array, det er ikke en måte å gjøre en snarvei som dette. 142 00:10:14,470 --> 00:10:18,120 Dette er bare en introduksjon til hva du kan gjøre med arrays. 143 00:10:18,120 --> 00:10:20,990 De dukker opp i nesten hvert program du skriver. 144 00:10:20,990 --> 00:10:24,390 Forhåpentligvis kan du nå se en bedre måte å gjøre studenten IDer eksempel 145 00:10:24,390 --> 00:10:26,710 fra begynnelsen av videoen. 146 00:10:26,710 --> 00:10:29,960 >> Mitt navn er Rob Bowden, og dette er CS50.