1 00:00:00,000 --> 00:00:06,030 >> [MUSIK SPELA] 2 00:00:06,030 --> 00:00:08,390 >> DOUG Lloyd: pekare, här är vi. 3 00:00:08,390 --> 00:00:11,080 Detta är förmodligen kommer att vara den svåraste ämne 4 00:00:11,080 --> 00:00:12,840 att vi talar om i CS50. 5 00:00:12,840 --> 00:00:15,060 Och om du har läst något om pekare 6 00:00:15,060 --> 00:00:19,080 innan du kan vara lite hotfull att gå in den här videon. 7 00:00:19,080 --> 00:00:21,260 Det är sant pekarna tillåter dig möjlighet 8 00:00:21,260 --> 00:00:23,740 till kanske skruva upp ganska dåligt när du är 9 00:00:23,740 --> 00:00:27,450 arbeta med variabler, och data, och orsakar programmet att krascha. 10 00:00:27,450 --> 00:00:30,490 Men de är faktiskt riktigt bra och de tillåter oss ett riktigt bra sätt 11 00:00:30,490 --> 00:00:33,340 att passera data fram och tillbaka mellan funktioner, 12 00:00:33,340 --> 00:00:35,490 att vi annars inte kan göra. 13 00:00:35,490 --> 00:00:37,750 >> Och så vad vi verkligen vill göra här är tåg 14 00:00:37,750 --> 00:00:41,060 att du har bra pekar disciplin, så att du kan använda pekare på ett effektivt sätt 15 00:00:41,060 --> 00:00:43,850 att göra dina program så mycket bättre. 16 00:00:43,850 --> 00:00:48,220 Som jag sa pekare ge oss ett annat sätt att överföra data mellan funktioner. 17 00:00:48,220 --> 00:00:50,270 Nu om du minns från en tidigare video, när 18 00:00:50,270 --> 00:00:53,720 Vi pratade om variabel omfattning, nämnde jag 19 00:00:53,720 --> 00:01:00,610 att all data som vi passerar mellan funktioner i C passeras av värde. 20 00:01:00,610 --> 00:01:03,070 Och jag kanske inte har använt den term, vad jag menade det 21 00:01:03,070 --> 00:01:07,170 var att vi passerar kopior av data. 22 00:01:07,170 --> 00:01:12,252 När vi passerar en variabel till en funktion, vi faktiskt inte passera variabeln 23 00:01:12,252 --> 00:01:13,210 till funktionen, eller hur? 24 00:01:13,210 --> 00:01:17,670 Vi passerar en kopia av att data till funktionen. 25 00:01:17,670 --> 00:01:20,760 Funktionen gör vad den kommer och den beräknar ett visst värde, 26 00:01:20,760 --> 00:01:23,180 och kanske vi använder det värdet när det ger den tillbaka. 27 00:01:23,180 --> 00:01:26,700 >> Det fanns ett undantag till denna regel att passera i värde, 28 00:01:26,700 --> 00:01:31,210 och vi ska återkomma till vad det är lite längre fram i den här videon. 29 00:01:31,210 --> 00:01:34,880 Om vi ​​använder pekare istället att använda variabler, 30 00:01:34,880 --> 00:01:38,180 eller i stället för att använda variablerna själva eller kopior av variablerna, 31 00:01:38,180 --> 00:01:43,790 Vi kan nu passera variabler runt mellan fungerar på ett annat sätt. 32 00:01:43,790 --> 00:01:46,550 Detta innebär att om vi gör en förändring i en funktion, 33 00:01:46,550 --> 00:01:49,827 ändringen faktiskt kommer att ta effekt i en annan funktion. 34 00:01:49,827 --> 00:01:52,160 Återigen, detta är något som Vi kunde inte göra tidigare, 35 00:01:52,160 --> 00:01:56,979 och om du någonsin har försökt att byta värdet av de två variabler i en funktion, 36 00:01:56,979 --> 00:01:59,270 du har märkt detta problem slags smygande upp, eller hur? 37 00:01:59,270 --> 00:02:04,340 >> Om vi ​​vill byta X och Y och vi skicka dem till en funktion som kallas swap, 38 00:02:04,340 --> 00:02:08,680 insidan av funktionen byta variabler gör bytesvärden. 39 00:02:08,680 --> 00:02:12,600 Man blir två, två blir en, men vi egentligen inte 40 00:02:12,600 --> 00:02:16,890 ändra något i den ursprungliga funktionen i den som ringer. 41 00:02:16,890 --> 00:02:19,550 Eftersom vi inte kan, vi är bara arbeta med kopior av dem. 42 00:02:19,550 --> 00:02:24,760 Med pekare men vi kan faktiskt passera X och Y till en funktion. 43 00:02:24,760 --> 00:02:26,960 Denna funktion kan göra något med dem. 44 00:02:26,960 --> 00:02:29,250 Och dessa variabler värden kan faktiskt förändras. 45 00:02:29,250 --> 00:02:33,710 Så det är ganska en förändring i vår förmåga att arbeta med data. 46 00:02:33,710 --> 00:02:36,100 >> Innan vi dyker in pekare, jag tycker det är värt 47 00:02:36,100 --> 00:02:38,580 tar några minuter till gå tillbaka till grunderna här. 48 00:02:38,580 --> 00:02:41,000 Och ta en titt på hur datorminnesarbeten 49 00:02:41,000 --> 00:02:45,340 eftersom dessa två ämnen kommer att faktiskt vara ganska varandra. 50 00:02:45,340 --> 00:02:48,480 Som ni säkert vet, på din dator 51 00:02:48,480 --> 00:02:51,310 du har en hårddisk eller kanske en solid state drive, 52 00:02:51,310 --> 00:02:54,430 någon form av fillagring plats. 53 00:02:54,430 --> 00:02:57,950 Det är oftast någonstans i trakten av 250 gigabyte 54 00:02:57,950 --> 00:02:59,810 till kanske ett par terabyte nu. 55 00:02:59,810 --> 00:03:02,270 Och det är där alla dina filer i slutändan lever, 56 00:03:02,270 --> 00:03:04,870 även när datorn är avstängd off, kan du slå på den igen 57 00:03:04,870 --> 00:03:09,190 och du hittar dina filer finns igen när du startar om datorn. 58 00:03:09,190 --> 00:03:14,820 Men hårddiskar, som en hårddisk, en hårddisk eller en SSD-enhet, en SSD, 59 00:03:14,820 --> 00:03:16,050 är bara lagringsutrymme. 60 00:03:16,050 --> 00:03:20,400 >> Vi kan faktiskt inte göra något med de data som finns i hårddisken, 61 00:03:20,400 --> 00:03:22,080 eller i en SSD-enhet. 62 00:03:22,080 --> 00:03:24,950 För att verkligen förändra uppgifter eller flytta runt, 63 00:03:24,950 --> 00:03:28,800 Vi måste flytta den till RAM, random access memory. 64 00:03:28,800 --> 00:03:31,170 Nu RAM, har du en hel del mindre i din dator. 65 00:03:31,170 --> 00:03:34,185 Du kan ha någonstans i trakten av 512 megabyte 66 00:03:34,185 --> 00:03:38,850 Om du har en äldre dator, till kanske två, fyra, åtta, 16, 67 00:03:38,850 --> 00:03:41,820 kanske till och med lite mer gigabyte RAM. 68 00:03:41,820 --> 00:03:46,390 Så det är mycket mindre, men det är där alla flyktiga data existerar. 69 00:03:46,390 --> 00:03:48,270 Det är där vi kan förändra saker. 70 00:03:48,270 --> 00:03:53,350 Men när vi vänder vår datorn, all data i RAM-minnet förstörs. 71 00:03:53,350 --> 00:03:57,150 >> Så det är därför vi måste ha hårddisk för mer permanent placering av den, 72 00:03:57,150 --> 00:03:59,720 så att den exists- det skulle vara riktigt illa om varje gång vi 73 00:03:59,720 --> 00:04:03,310 visade vår datorn, varje fil i vårt system utplånades. 74 00:04:03,310 --> 00:04:05,600 Så arbetar vi inne i RAM. 75 00:04:05,600 --> 00:04:09,210 Och varje gång vi pratar om minne, ganska mycket, i CS50, 76 00:04:09,210 --> 00:04:15,080 vi pratar om RAM, inte hårddisken. 77 00:04:15,080 --> 00:04:18,657 >> Så när vi flytta saker i minnet, den tar upp ett visst utrymme. 78 00:04:18,657 --> 00:04:20,740 Alla de datatyper som Vi har arbetat med 79 00:04:20,740 --> 00:04:23,480 ta upp olika mängder utrymme i RAM. 80 00:04:23,480 --> 00:04:27,600 Så varje gång du skapar ett heltal variabel, fyra byte minne 81 00:04:27,600 --> 00:04:30,750 avsätts i RAM-minnet så att du kan arbeta med det heltal. 82 00:04:30,750 --> 00:04:34,260 Du kan förklara heltal ändra det, tilldela den 83 00:04:34,260 --> 00:04:36,700 till ett värde 10 ökas med en, så vidare och så vidare. 84 00:04:36,700 --> 00:04:39,440 Allt som måste ske i RAM, och du får fyra byte 85 00:04:39,440 --> 00:04:42,550 att arbeta med för varje heltal som du skapar. 86 00:04:42,550 --> 00:04:45,410 >> Varje tecken du skapa får ett byte. 87 00:04:45,410 --> 00:04:48,160 Det är bara hur mycket utrymme är behövs för att lagra ett tecken. 88 00:04:48,160 --> 00:04:51,310 Varje flottör, en verklig nummer, får fyra byte 89 00:04:51,310 --> 00:04:53,390 om det inte är en dubbel precision flyttal 90 00:04:53,390 --> 00:04:56,510 nummer, vilket gör att du kan har mer exakta eller fler siffror 91 00:04:56,510 --> 00:04:59,300 efter decimalkommat utan att förlora precision, 92 00:04:59,300 --> 00:05:01,820 som tar upp åtta byte minne. 93 00:05:01,820 --> 00:05:06,730 Långa longs, riktigt stora heltal, även ta upp åtta byte minne. 94 00:05:06,730 --> 00:05:09,000 Hur många byte minne gör strängar ta upp? 95 00:05:09,000 --> 00:05:12,990 Nåväl låt oss sätta ett stift i den frågan för nu, men vi ska återkomma till det. 96 00:05:12,990 --> 00:05:17,350 >> Så tillbaka till denna idé om minnet som en stor matris av bytestora celler. 97 00:05:17,350 --> 00:05:20,871 Det är verkligen allt det är, det är bara en enorm mängd celler, 98 00:05:20,871 --> 00:05:23,370 precis som alla andra array som du är bekant med och se, 99 00:05:23,370 --> 00:05:26,430 utom varje element är en byte bred. 100 00:05:26,430 --> 00:05:30,030 Och precis som en array, varje element har en adress. 101 00:05:30,030 --> 00:05:32,120 Varje element i en matris har ett index, och vi 102 00:05:32,120 --> 00:05:36,302 kan använda detta index för att göra s.k. direktåtkomst på matrisen. 103 00:05:36,302 --> 00:05:38,510 Vi behöver inte börja på början av arrayen, 104 00:05:38,510 --> 00:05:40,569 iterera igenom varje enda element därav, 105 00:05:40,569 --> 00:05:41,860 att hitta vad vi letar efter. 106 00:05:41,860 --> 00:05:45,790 Vi kan bara säga, jag vill komma till 15 element eller 100-elementet. 107 00:05:45,790 --> 00:05:49,930 Och du kan bara passera i det numret och få det värde du letar efter. 108 00:05:49,930 --> 00:05:54,460 >> På samma sätt varje plats i minnet har en adress. 109 00:05:54,460 --> 00:05:57,320 Så ditt minne kanske se ut så här. 110 00:05:57,320 --> 00:06:01,420 Här är en mycket liten del av minne, är detta 20 byte minne. 111 00:06:01,420 --> 00:06:04,060 De första 20 byte eftersom min behandlar det på botten 112 00:06:04,060 --> 00:06:08,890 är 0, 1, 2, 3, och så på ända upp till 19. 113 00:06:08,890 --> 00:06:13,190 Och när jag deklarerar variabler och när jag börjar arbeta med dem, 114 00:06:13,190 --> 00:06:15,470 systemet kommer att ställa avsätta lite utrymme för mig 115 00:06:15,470 --> 00:06:17,595 i detta minne för att fungera med mina variabler. 116 00:06:17,595 --> 00:06:21,610 Så jag kan säga, röding c lika kapital H. Och vad kommer att hända? 117 00:06:21,610 --> 00:06:23,880 Väl systemet kommer att avsatts för mig ett byte. 118 00:06:23,880 --> 00:06:27,870 I det här fallet valde byte nummer fyra, byte vid adress fyra, 119 00:06:27,870 --> 00:06:31,310 och det kommer att lagra brev huvudstad H där för mig. 120 00:06:31,310 --> 00:06:34,350 Om jag sedan säga int hastighet gräns är lika med 65, det är 121 00:06:34,350 --> 00:06:36,806 kommer att avsätta fyra byte minne för mig. 122 00:06:36,806 --> 00:06:39,180 Och det kommer att behandla de fyra byte som en enda enhet 123 00:06:39,180 --> 00:06:41,305 eftersom det vi jobbar med är ett heltal här. 124 00:06:41,305 --> 00:06:44,350 Och det kommer att lagra 65 i det. 125 00:06:44,350 --> 00:06:47,000 >> Nu redan Jag är typ av berättar en bit av en lögn, 126 00:06:47,000 --> 00:06:50,150 rätt, eftersom vi vet att datorer fungerar i binär. 127 00:06:50,150 --> 00:06:53,100 De förstår inte nödvändigtvis vad en kapital H är 128 00:06:53,100 --> 00:06:57,110 eller vad en 65 är, de bara förstår binära, nollor och ettor. 129 00:06:57,110 --> 00:06:59,000 Och så faktiskt vad vi lagrar där 130 00:06:59,000 --> 00:07:03,450 är inte bokstaven H och antalet 65, utan snarare de binära representation 131 00:07:03,450 --> 00:07:06,980 därav, som ser lite ungefär så här. 132 00:07:06,980 --> 00:07:10,360 Och särskilt när det gäller ramen för heltalsvariabel 133 00:07:10,360 --> 00:07:13,559 det kommer inte att bara spotta i, det kommer inte att behandla det som en fyra 134 00:07:13,559 --> 00:07:15,350 byte bit nödvändigtvis, det är faktiskt går 135 00:07:15,350 --> 00:07:19,570 att behandla det som fyra en byte bitar, som kan se ut så här. 136 00:07:19,570 --> 00:07:22,424 Och även detta är inte helt sant heller, 137 00:07:22,424 --> 00:07:24,840 på grund av något som kallas en endian, som vi inte 138 00:07:24,840 --> 00:07:26,965 gå in på nu, men Om du är nyfiken, 139 00:07:26,965 --> 00:07:29,030 du kan läsa på lite och stora endian. 140 00:07:29,030 --> 00:07:31,640 Men för den skull detta argument, till förmån för den här videon, 141 00:07:31,640 --> 00:07:34,860 låt oss bara anta att är, i Faktum är hur antalet 65 skulle 142 00:07:34,860 --> 00:07:36,970 vara representerade i minne på varje system, 143 00:07:36,970 --> 00:07:38,850 även om det inte helt sant. 144 00:07:38,850 --> 00:07:41,700 >> Men låt oss faktiskt bara få bli av med alla binära helt, 145 00:07:41,700 --> 00:07:44,460 och bara tänka på som H och 65, är det mycket lättare 146 00:07:44,460 --> 00:07:47,900 att tänka på det som att som en människa. 147 00:07:47,900 --> 00:07:51,420 Okej, så det verkar också kanske en lite slumpmässigt att I've- mitt system 148 00:07:51,420 --> 00:07:55,130 gav mig inte byte 5, 6, 7, och 8 för att lagra heltal. 149 00:07:55,130 --> 00:07:58,580 Det finns en anledning till det också, som vi kommer inte att komma in just nu, men räcker 150 00:07:58,580 --> 00:08:00,496 det vill säga att vad dator gör här 151 00:08:00,496 --> 00:08:02,810 är förmodligen ett bra drag på sin sida. 152 00:08:02,810 --> 00:08:06,020 Att inte ge mig minne som är nödvändigtvis rygg mot rygg. 153 00:08:06,020 --> 00:08:10,490 Även om det kommer att göra det nu om jag vill få en annan sträng, 154 00:08:10,490 --> 00:08:13,080 kallas efternamn, och jag vill att sätta Lloyd där. 155 00:08:13,080 --> 00:08:18,360 Jag kommer att behöva passa en karaktär, varje bokstav i det är 156 00:08:18,360 --> 00:08:21,330 kommer att kräva en karaktär, ett byte av minnet. 157 00:08:21,330 --> 00:08:26,230 Så om jag kunde sätta Lloyd i min samling så här jag är ganska bra att gå, eller hur? 158 00:08:26,230 --> 00:08:28,870 Vad saknas? 159 00:08:28,870 --> 00:08:31,840 >> Kom ihåg att varje sträng vi arbetar med i C avslutas med omvänt snedstreck noll, 160 00:08:31,840 --> 00:08:33,339 och vi kan inte utesluta att här heller. 161 00:08:33,339 --> 00:08:36,090 Vi måste avsätta en byte minne för att hålla det så vi 162 00:08:36,090 --> 00:08:39,130 vet när vår sträng är avslutad. 163 00:08:39,130 --> 00:08:41,049 Så återigen detta arrangemang av hur saker och ting 164 00:08:41,049 --> 00:08:42,799 visas i minnes styrka vara lite slumpmässigt, 165 00:08:42,799 --> 00:08:44,870 men det är faktiskt hur de flesta system är utformade. 166 00:08:44,870 --> 00:08:48,330 Att rada upp dem på multiplar av fyra skäl igen 167 00:08:48,330 --> 00:08:50,080 att vi inte behöver komma in just nu. 168 00:08:50,080 --> 00:08:53,060 Men detta, så är det tillräckligt att säga att efter dessa tre rader kod, 169 00:08:53,060 --> 00:08:54,810 detta är vad minne kan se ut. 170 00:08:54,810 --> 00:08:58,930 Om jag behöver minnesplatser 4, 8 och 12 för att hålla mina uppgifter, 171 00:08:58,930 --> 00:09:01,100 Detta är vad mitt minne kan se ut. 172 00:09:01,100 --> 00:09:04,062 >> Och bara vara särskilt pedantisk här, när 173 00:09:04,062 --> 00:09:06,020 Vi pratar om minne adresser vi vanligtvis 174 00:09:06,020 --> 00:09:08,390 göra det med hexadecimala beteckningar. 175 00:09:08,390 --> 00:09:12,030 Så varför gör vi inte konvertera alla dessa från decimal till hexadecimal notation 176 00:09:12,030 --> 00:09:15,010 bara för att det är i allmänhet hur vi hänvisar till minnet. 177 00:09:15,010 --> 00:09:17,880 Så istället för att vara 0 till 19, vad vi har är noll 178 00:09:17,880 --> 00:09:20,340 x noll till noll x1 tre. 179 00:09:20,340 --> 00:09:23,790 De är 20 byte minne som vi har eller vi tittar på i den här bilden 180 00:09:23,790 --> 00:09:25,540 precis här. 181 00:09:25,540 --> 00:09:29,310 >> Så allt detta sagt, låt oss steg bort från minnet för en sekund 182 00:09:29,310 --> 00:09:30,490 och tillbaka till pekare. 183 00:09:30,490 --> 00:09:32,420 Här är den viktigaste sak att komma ihåg 184 00:09:32,420 --> 00:09:34,070 när vi börjar arbeta med pekare. 185 00:09:34,070 --> 00:09:36,314 En pekare är ingenting mer än en adress. 186 00:09:36,314 --> 00:09:38,230 Jag ska säga det igen eftersom Det är så viktigt, 187 00:09:38,230 --> 00:09:42,730 en pekare är ingenting mer än en adress. 188 00:09:42,730 --> 00:09:47,760 Pointers är adresser till platser i minnet där variabler bor. 189 00:09:47,760 --> 00:09:52,590 Att veta att det blir förhoppningsvis en lite lättare att arbeta med dem. 190 00:09:52,590 --> 00:09:54,550 En annan sak som jag gillar göra är att ha sortera 191 00:09:54,550 --> 00:09:58,510 av diagram visuellt representerar vad som är händer med olika rader kod. 192 00:09:58,510 --> 00:10:00,660 Och vi kommer att göra detta ett par gånger i pekare, 193 00:10:00,660 --> 00:10:03,354 och när vi talar om dynamisk minnesallokering samt. 194 00:10:03,354 --> 00:10:06,020 Eftersom jag tror att dessa diagram kan vara särskilt praktiskt. 195 00:10:06,020 --> 00:10:09,540 >> Så om jag säger till exempel int k i min kod, vad som händer? 196 00:10:09,540 --> 00:10:12,524 Tja vad som i grund och botten händer är Jag får minne som reserverats för mig, 197 00:10:12,524 --> 00:10:14,690 men jag inte ens gillar att tänker på det så jag 198 00:10:14,690 --> 00:10:16,300 gillar att tänka på det som en låda. 199 00:10:16,300 --> 00:10:20,090 Jag har en låda och det är färgade grön eftersom jag 200 00:10:20,090 --> 00:10:21,750 kan sätta heltal i gröna rutor. 201 00:10:21,750 --> 00:10:23,666 Om det var ett tecken jag kan ha en blå låda. 202 00:10:23,666 --> 00:10:27,290 Men jag säger alltid, om jag skapar en låda som rymmer heltal 203 00:10:27,290 --> 00:10:28,950 att rutan färgas grönt. 204 00:10:28,950 --> 00:10:33,020 Och jag tar en märkpenna och jag skriver k på sidan av den. 205 00:10:33,020 --> 00:10:37,590 Så jag har en låda som kallas k, i vilket jag kan sätta heltal. 206 00:10:37,590 --> 00:10:41,070 Så när jag säger int k, det är vad som händer i mitt huvud. 207 00:10:41,070 --> 00:10:43,140 Om jag säger k är lika med fem, vad gör jag? 208 00:10:43,140 --> 00:10:45,110 Tja, jag sätter fem i rutan till höger. 209 00:10:45,110 --> 00:10:48,670 Detta är ganska enkelt, om Jag säger int k, skapa en ruta som kallas k. 210 00:10:48,670 --> 00:10:52,040 Om jag säger k lika med 5, sätta fem i rutan. 211 00:10:52,040 --> 00:10:53,865 Förhoppningsvis det är inte för mycket av ett språng. 212 00:10:53,865 --> 00:10:55,990 Här är där det går en lite intressant ändå. 213 00:10:55,990 --> 00:11:02,590 Om jag säger int * pk, bra även om jag inte vet vad detta med nödvändighet innebär, 214 00:11:02,590 --> 00:11:06,150 Det är helt klart fått något att göra med ett heltal. 215 00:11:06,150 --> 00:11:08,211 Så jag kommer att färga rutan grön-ish, 216 00:11:08,211 --> 00:11:10,210 Jag vet att det har något att göra med ett heltal, 217 00:11:10,210 --> 00:11:13,400 men det är inte ett heltal själv, eftersom det är en int stjärna. 218 00:11:13,400 --> 00:11:15,390 Det finns något lite annorlunda om det. 219 00:11:15,390 --> 00:11:17,620 Så ett heltal är inblandad, men annars är det 220 00:11:17,620 --> 00:11:19,830 inte avviker alltför mycket från vad vi pratade om. 221 00:11:19,830 --> 00:11:24,240 Det är en låda, dess fått en etikett, Det bär en etikett pk, 222 00:11:24,240 --> 00:11:27,280 och det är kapabel innehav int stjärnor, oavsett de är. 223 00:11:27,280 --> 00:11:29,894 De har något att göra med heltal, tydligt. 224 00:11:29,894 --> 00:11:31,060 Här är den sista raden men. 225 00:11:31,060 --> 00:11:37,650 Om jag säger pk = & k, whoa, vad som just hände, eller hur? 226 00:11:37,650 --> 00:11:41,820 Så detta slumptal, till synes slumpmässig nummer, får kastas i rutan där. 227 00:11:41,820 --> 00:11:44,930 Allt som är, är pk blir adressen för k. 228 00:11:44,930 --> 00:11:52,867 Så jag fastnar där k bor i minnet, dess adress, adressen till dess byte. 229 00:11:52,867 --> 00:11:55,200 Allt jag gör är att jag säger detta värde är vad jag kommer 230 00:11:55,200 --> 00:11:59,430 att sätta in i min låda som kallas pk. 231 00:11:59,430 --> 00:12:02,080 Och eftersom dessa saker är pekare, och eftersom ser 232 00:12:02,080 --> 00:12:04,955 på en sträng som noll x åtta noll c sju fyra åtta 233 00:12:04,955 --> 00:12:07,790 två noll är förmodligen inte mycket meningsfullt. 234 00:12:07,790 --> 00:12:12,390 När vi i allmänhet visualisera pekare, vi faktiskt göra det så pekare. 235 00:12:12,390 --> 00:12:17,000 Pk ger oss den information vi måste hitta k i minnet. 236 00:12:17,000 --> 00:12:19,120 Så i princip pk har en pil i den. 237 00:12:19,120 --> 00:12:21,670 Och om vi går längden av den pil, föreställa 238 00:12:21,670 --> 00:12:25,280 det är något du kan gå på, om vi promenera utmed längden av pilen, 239 00:12:25,280 --> 00:12:29,490 vid den yttersta spetsen av den pil, vi kommer att finna den plats i minnet 240 00:12:29,490 --> 00:12:31,390 där k bor. 241 00:12:31,390 --> 00:12:34,360 Och det är verkligen viktigt eftersom när vi vet var k bor, 242 00:12:34,360 --> 00:12:37,870 vi kan börja arbeta med data insidan av den minnesplatsen. 243 00:12:37,870 --> 00:12:40,780 Även om vi får ett pyttelitet bit framför oss nu. 244 00:12:40,780 --> 00:12:42,240 >> Så vad är en pekare? 245 00:12:42,240 --> 00:12:45,590 En pekare är en datapost vars värdet är en minnesadress. 246 00:12:45,590 --> 00:12:49,740 Det var att noll x åtta noll grejer pågår, det var en minnesadress. 247 00:12:49,740 --> 00:12:52,060 Det var en plats i minnet. 248 00:12:52,060 --> 00:12:55,080 Och vilken typ av en pekare beskriver den typ 249 00:12:55,080 --> 00:12:56,930 data du hittar på den minnesadressen. 250 00:12:56,930 --> 00:12:58,810 Så det är int stjärnigt del rätt. 251 00:12:58,810 --> 00:13:03,690 Om jag följer det pilen, är det kommer att leda mig till en plats. 252 00:13:03,690 --> 00:13:06,980 Och den platsen, vad jag hittar det i mitt exempel, 253 00:13:06,980 --> 00:13:08,240 är en grön färgad ruta. 254 00:13:08,240 --> 00:13:12,650 Det är ett heltal, det är vad jag hittar du om jag går till den adressen. 255 00:13:12,650 --> 00:13:14,830 Datatyp en pekaren beskriver vad 256 00:13:14,830 --> 00:13:17,936 hittar du på den minnesadress. 257 00:13:17,936 --> 00:13:19,560 Så här är riktigt cool sak dock. 258 00:13:19,560 --> 00:13:25,090 Pointers tillåter oss att passera variabler mellan funktioner. 259 00:13:25,090 --> 00:13:28,520 Och faktiskt skicka variabler och inte passera kopior av dem. 260 00:13:28,520 --> 00:13:32,879 För om vi vet exakt var i minnet för att hitta en variabel, 261 00:13:32,879 --> 00:13:35,670 Vi behöver inte göra en kopia av Det kan vi bara gå till den platsen 262 00:13:35,670 --> 00:13:37,844 och arbeta med den variabeln. 263 00:13:37,844 --> 00:13:40,260 Så i huvudsak pekare sort av att göra en datormiljö 264 00:13:40,260 --> 00:13:42,360 mycket mer som den verkliga världen, rätt. 265 00:13:42,360 --> 00:13:44,640 >> Så här är en analogi. 266 00:13:44,640 --> 00:13:48,080 Låt oss säga att jag har en anteckningsbok, rätt, och det är full av anteckningar. 267 00:13:48,080 --> 00:13:50,230 Och jag skulle vilja att ni uppdatera den. 268 00:13:50,230 --> 00:13:53,960 Du är en funktion som uppdateringar anteckningar, rätt. 269 00:13:53,960 --> 00:13:56,390 På det sätt som vi har varit arbetar så långt, vad 270 00:13:56,390 --> 00:14:02,370 händer är att du kommer att ta min bärbara dator, du kommer att gå till kopieringsbutik, 271 00:14:02,370 --> 00:14:06,410 du kommer att göra en Xerox kopia av varje sida av den bärbara datorn. 272 00:14:06,410 --> 00:14:09,790 Du lämnar min bärbara dator tillbaka på mitt skrivbord när du är klar, 273 00:14:09,790 --> 00:14:14,600 du ska gå och stryka saker i mitt anteckningsbok som är inaktuella eller fel, 274 00:14:14,600 --> 00:14:19,280 och sedan kommer du att passera tillbaka till mig stapeln av Xerox sidor 275 00:14:19,280 --> 00:14:22,850 som är en kopia av min bärbara dator med de ändringar som du har gjort i den. 276 00:14:22,850 --> 00:14:27,040 Och på den punkten, är det upp till mig som anropsfunktionen, som den som ringer, 277 00:14:27,040 --> 00:14:30,582 besluta att ta dina anteckningar och integrera dem tillbaka i min bärbara dator. 278 00:14:30,582 --> 00:14:32,540 Så det finns en mängd åtgärder involverade här, rätt. 279 00:14:32,540 --> 00:14:34,850 Liksom skulle det inte vara bättre Om jag bara säga, hej, kan du 280 00:14:34,850 --> 00:14:38,370 uppdatera min bärbara dator för mig, lämna dig min bärbara dator, 281 00:14:38,370 --> 00:14:40,440 och du tar saker och bokstavligen stryka dem 282 00:14:40,440 --> 00:14:42,810 och uppdatera mina anteckningar i min anteckningsbok. 283 00:14:42,810 --> 00:14:45,140 Och sedan ge mig min bärbara dator tillbaka. 284 00:14:45,140 --> 00:14:47,320 Det är typ av vad pekare tillåter oss att göra, 285 00:14:47,320 --> 00:14:51,320 de gör denna miljö mycket mer som hur vi fungerar i verkligheten. 286 00:14:51,320 --> 00:14:54,640 >> Okej, så det är vad en pekare är, låt oss tala 287 00:14:54,640 --> 00:14:58,040 om hur pekare fungerar i C, och hur vi kan börja arbeta med dem. 288 00:14:58,040 --> 00:15:02,550 Så det finns en mycket enkel pekare i C kallas nollpekaren. 289 00:15:02,550 --> 00:15:04,830 Noll pekaren pekar på någonting. 290 00:15:04,830 --> 00:15:08,310 Det verkar sannolikt som det är faktiskt inte en mycket bra sak, 291 00:15:08,310 --> 00:15:10,500 men vi får se en Lite senare på det faktum 292 00:15:10,500 --> 00:15:15,410 att denna nollpekare existerar faktiskt riktigt kan komma till hands. 293 00:15:15,410 --> 00:15:19,090 Och när du skapar en pekare, och du inte ställa in dess värde immediately- 294 00:15:19,090 --> 00:15:21,060 ett exempel på inställning dess värde omedelbart 295 00:15:21,060 --> 00:15:25,401 kommer att vara ett par glider tillbaka där jag sa pk lika & k, 296 00:15:25,401 --> 00:15:28,740 pk får k adress, som Vi får se vad det betyder, 297 00:15:28,740 --> 00:15:32,990 vi får se hur man kan koda det shortly- om vi inte ställa in dess värde till något 298 00:15:32,990 --> 00:15:35,380 meningsfull omedelbart, Du bör alltid 299 00:15:35,380 --> 00:15:37,480 ställa in pekaren pekar på noll. 300 00:15:37,480 --> 00:15:40,260 Du bör ställa in den att peka på någonting. 301 00:15:40,260 --> 00:15:43,614 >> Det är mycket annorlunda än bara lämnar det värde som det är 302 00:15:43,614 --> 00:15:45,530 och sedan förklara en pekare och bara om man antar 303 00:15:45,530 --> 00:15:48,042 Det är noll eftersom det är sällan sant. 304 00:15:48,042 --> 00:15:50,000 Så du ska alltid ställa värdet på en pekare 305 00:15:50,000 --> 00:15:55,690 till null om du inte anger dess värde till något meningsfullt omedelbart. 306 00:15:55,690 --> 00:15:59,090 Du kan kontrollera om en pekare värde är null använda likhetsoperatorn 307 00:15:59,090 --> 00:16:05,450 (==), Precis som du jämför alla heltal värden eller tecken värden med (==) 308 00:16:05,450 --> 00:16:06,320 också. 309 00:16:06,320 --> 00:16:10,994 Det är en speciell sorts konstant värde som du kan använda för att testa. 310 00:16:10,994 --> 00:16:13,160 Så det var en mycket enkel pekare, nollpekaren. 311 00:16:13,160 --> 00:16:15,320 Ett annat sätt att skapa en pekare är att extrahera 312 00:16:15,320 --> 00:16:18,240 adressen till en variabel du redan har skapat, 313 00:16:18,240 --> 00:16:22,330 och du gör det genom att använda & operatör adress extraktion. 314 00:16:22,330 --> 00:16:26,720 Som vi redan har sett tidigare i första diagrammet exemplet jag visade. 315 00:16:26,720 --> 00:16:31,450 Så om x är en variabel som vi har redan skapat av typen heltal, 316 00:16:31,450 --> 00:16:35,110 då och X är en pekare till ett heltal. 317 00:16:35,110 --> 00:16:39,810 & x är- minns, och kommer att extrahera adress sak på höger sida. 318 00:16:39,810 --> 00:16:45,350 Och eftersom en pekare är bara en adress, än & x är en pekare till ett heltal 319 00:16:45,350 --> 00:16:48,560 vars värde är där minnet x liv. 320 00:16:48,560 --> 00:16:50,460 Det är x adress. 321 00:16:50,460 --> 00:16:53,296 Så & x är adressen för x. 322 00:16:53,296 --> 00:16:55,670 Låt oss ta detta ett steg vidare och ansluta till något 323 00:16:55,670 --> 00:16:58,380 Jag hänvisade till i en tidigare video. 324 00:16:58,380 --> 00:17:06,730 Om arr är en rad dubbel, då & arr hakparentes jag är en pekare 325 00:17:06,730 --> 00:17:08,109 till en dubbel. 326 00:17:08,109 --> 00:17:08,970 OK. 327 00:17:08,970 --> 00:17:12,160 arr hakparentes i, om arr är en rad dubbel, 328 00:17:12,160 --> 00:17:19,069 sedan arr hakparentes i är den i: te elementet i nämnda matris, 329 00:17:19,069 --> 00:17:29,270 och & arr hakparentes jag är där i minne den i: te elementet i arr existerar. 330 00:17:29,270 --> 00:17:31,790 >> Så vad är innebörden här? 331 00:17:31,790 --> 00:17:34,570 Ett matriser namn, innebörden av hela denna sak, 332 00:17:34,570 --> 00:17:39,290 är att en array heter faktiskt själv en pekare. 333 00:17:39,290 --> 00:17:41,170 Du har jobbat med pekare längs 334 00:17:41,170 --> 00:17:45,290 varje gång du har använt en array. 335 00:17:45,290 --> 00:17:49,090 Kom ihåg från exemplet Rörlig omfattning, 336 00:17:49,090 --> 00:17:53,420 i slutet av videon jag presentera ett exempel där vi har en funktion 337 00:17:53,420 --> 00:17:56,890 kallas set int och funktion kallad set array. 338 00:17:56,890 --> 00:18:00,490 Och din utmaning att bestämma med eller utan, eller vad 339 00:18:00,490 --> 00:18:03,220 värden som vi skrivs ut slutet av funktionen, 340 00:18:03,220 --> 00:18:05,960 vid slutet av huvudprogrammet. 341 00:18:05,960 --> 00:18:08,740 >> Om du minns från det exemplet eller om du har sett videon, 342 00:18:08,740 --> 00:18:13,080 du vet att när er-samtalet till set int gör effektivt ingenting. 343 00:18:13,080 --> 00:18:16,390 Men uppmaningen att ställa array gör. 344 00:18:16,390 --> 00:18:19,280 Och jag slags slätade över varför som var fallet vid den tidpunkten. 345 00:18:19,280 --> 00:18:22,363 Jag sa bara, ja det är en matris, är det speciell, du vet, det finns en anledning. 346 00:18:22,363 --> 00:18:25,020 Anledningen är att en arrays Namnet är egentligen bara en pekare, 347 00:18:25,020 --> 00:18:28,740 och det finns denna speciella klammer syntax som 348 00:18:28,740 --> 00:18:30,510 göra det mycket trevligare att arbeta med. 349 00:18:30,510 --> 00:18:34,410 Och de gör idén om en pekaren mycket mindre hotfull, 350 00:18:34,410 --> 00:18:36,800 och det är därför de är sortera av presenteras på detta sätt. 351 00:18:36,800 --> 00:18:38,600 Men egentligen arrayer är bara pekare. 352 00:18:38,600 --> 00:18:41,580 Och det är därför när vi gjort en ändring till arrayen, 353 00:18:41,580 --> 00:18:44,880 när vi passerade en array som en parameter till en funktion eller som ett argument 354 00:18:44,880 --> 00:18:50,110 till en funktion, innehållet i arrayen faktiskt ändras i både den uppringda 355 00:18:50,110 --> 00:18:51,160 och den som ringer. 356 00:18:51,160 --> 00:18:55,846 Som för alla andra typer av variabel vi såg var inte fallet. 357 00:18:55,846 --> 00:18:58,970 Så det är bara något att ha i tänka på när du arbetar med pekare, 358 00:18:58,970 --> 00:19:01,610 är att namnet på en matris faktiskt en pekare 359 00:19:01,610 --> 00:19:04,750 till det första elementet i den arrayen. 360 00:19:04,750 --> 00:19:08,930 >> OK så nu har vi alla dessa fakta, låt oss fortsätta, höger. 361 00:19:08,930 --> 00:19:11,370 Varför vi bryr oss om där något bor. 362 00:19:11,370 --> 00:19:14,120 Väl som jag sa, det är ganska bra att veta var något bor 363 00:19:14,120 --> 00:19:17,240 så att du kan åka dit och ändra det. 364 00:19:17,240 --> 00:19:19,390 Arbeta med det och faktiskt har det som du 365 00:19:19,390 --> 00:19:23,710 vill göra med den variabeln börjar gälla, och inte träda i kraft på någon kopia av den. 366 00:19:23,710 --> 00:19:26,150 Detta kallas Namnåtergång. 367 00:19:26,150 --> 00:19:28,690 Vi går till referens- och vi ändra värdet där. 368 00:19:28,690 --> 00:19:32,660 Så om vi har en pekare och det kallas pc, och det pekar på ett tecken, 369 00:19:32,660 --> 00:19:40,610 då kan vi säga * pc och * pc är namnet på vad vi hittar om vi går 370 00:19:40,610 --> 00:19:42,910 till den adress som st. 371 00:19:42,910 --> 00:19:47,860 Vad vi kommer att finna att det finns en karaktär och * pc är hur vi hänvisar till data på den 372 00:19:47,860 --> 00:19:48,880 plats. 373 00:19:48,880 --> 00:19:54,150 Så vi kunde säga något i stil * PC = D eller nåt sånt, 374 00:19:54,150 --> 00:19:59,280 och det betyder att allt var på minnesadress pc, 375 00:19:59,280 --> 00:20:07,040 oavsett karaktär var tidigare Det är nu D, om vi säger * pc = D. 376 00:20:07,040 --> 00:20:10,090 >> Så här går vi igen med några konstiga C grejer, rätt. 377 00:20:10,090 --> 00:20:14,560 Så vi har sett * tidigare som på något sätt en del av datatyp, 378 00:20:14,560 --> 00:20:17,160 och nu är det som används i ett något annorlunda sammanhang 379 00:20:17,160 --> 00:20:19,605 tillgång till uppgifterna på en plats. 380 00:20:19,605 --> 00:20:22,480 Jag vet att det är lite förvirrande och det är faktiskt en del av denna helhet 381 00:20:22,480 --> 00:20:25,740 liknande, varför pekare har denna mytologi omkring dem som så komplicerat, 382 00:20:25,740 --> 00:20:28,250 är typ av en syntax problem, ärligt. 383 00:20:28,250 --> 00:20:31,810 Men * används i båda sammanhangen, både som en del av typnamnet, 384 00:20:31,810 --> 00:20:34,100 och vi kommer att se en liten senare något annat också. 385 00:20:34,100 --> 00:20:36,490 Och just nu är det dereference operatör. 386 00:20:36,490 --> 00:20:38,760 Så det går till referens, Det ger tillgång till uppgifter 387 00:20:38,760 --> 00:20:43,000 vid läget för pekaren, och gör att du kan manipulera den efter behag. 388 00:20:43,000 --> 00:20:45,900 >> Nu är mycket lik besöker din granne, höger. 389 00:20:45,900 --> 00:20:48,710 Om du vet vad du granne bor, du är 390 00:20:48,710 --> 00:20:50,730 inte umgås med din granne. 391 00:20:50,730 --> 00:20:53,510 Du vet att du råkar vet var de bor, 392 00:20:53,510 --> 00:20:56,870 men det betyder inte att man genom på grund av att ha den kunskap 393 00:20:56,870 --> 00:20:59,170 du interagerar med dem. 394 00:20:59,170 --> 00:21:01,920 Om du vill interagera med dem, du måste gå till deras hus, 395 00:21:01,920 --> 00:21:03,760 du måste gå till där de bor. 396 00:21:03,760 --> 00:21:07,440 Och när du gör det, då kan du interagera 397 00:21:07,440 --> 00:21:09,420 med dem precis som du skulle vilja. 398 00:21:09,420 --> 00:21:12,730 Och på samma sätt med variabler, du måste gå till deras adress 399 00:21:12,730 --> 00:21:15,320 Om du vill interagera dem, du kan inte bara vet adressen. 400 00:21:15,320 --> 00:21:21,495 Och hur du går till den adress är att använda *, den dereference operatören. 401 00:21:21,495 --> 00:21:23,620 Vad tror du händer om vi försöker och dereference 402 00:21:23,620 --> 00:21:25,260 en pekare vars värde är noll? 403 00:21:25,260 --> 00:21:28,470 Minns att noll pekaren pekar på någonting. 404 00:21:28,470 --> 00:21:34,110 Så om du försöker och dereference ingenting eller gå till en adress ingenting, 405 00:21:34,110 --> 00:21:36,800 vad tror du händer? 406 00:21:36,800 --> 00:21:39,630 Tja, om du gissade segmente fel, skulle du vara rätt. 407 00:21:39,630 --> 00:21:41,390 Om du försöker och dereference en null-pekare, 408 00:21:41,390 --> 00:21:43,140 du drabbas av en segmente fel. Men vänta, 409 00:21:43,140 --> 00:21:45,820 gjorde jag inte berätta för dig, att Om du inte kommer 410 00:21:45,820 --> 00:21:49,220 att ställa in värdet på din pekaren till något meningsfullt, 411 00:21:49,220 --> 00:21:51,000 bör du ställa till null? 412 00:21:51,000 --> 00:21:55,290 Jag gjorde och faktiskt segmente fel är lite av en gott uppförande. 413 00:21:55,290 --> 00:21:58,680 >> Har du någonsin deklarerat en variabel och inte tilldelas dess värde omedelbart? 414 00:21:58,680 --> 00:22:02,680 Så du bara säga int x; du inte faktiskt tilldela den till något 415 00:22:02,680 --> 00:22:05,340 och sedan senare i din kod, du skriver ut värdet på x, 416 00:22:05,340 --> 00:22:07,650 har fortfarande inte tilldelat den till någonting. 417 00:22:07,650 --> 00:22:10,370 Ofta får du noll, men ibland 418 00:22:10,370 --> 00:22:15,000 kan få några slumptal, och har du ingen aning om varifrån den kom. 419 00:22:15,000 --> 00:22:16,750 På samma sätt kan saker hända med pekare. 420 00:22:16,750 --> 00:22:20,110 När du deklarerar en pekare int * pk t.ex. 421 00:22:20,110 --> 00:22:23,490 och du inte tilldela den till ett värde, du får fyra byte för minnet. 422 00:22:23,490 --> 00:22:25,950 Oavsett fyra byte minne systemet kan 423 00:22:25,950 --> 00:22:28,970 finna att ha några meningsfullt värde. 424 00:22:28,970 --> 00:22:31,760 Och det kan ha varit något som redan finns att 425 00:22:31,760 --> 00:22:34,190 behövs inte längre av en annan funktion, så att du bara har 426 00:22:34,190 --> 00:22:35,900 de data var där. 427 00:22:35,900 --> 00:22:40,570 >> Vad händer om du försökte göra dereference någon adress som du don't- fanns 428 00:22:40,570 --> 00:22:43,410 redan bytes och information där, det är nu i pekaren. 429 00:22:43,410 --> 00:22:47,470 Om du försöker avreferera att pekaren, du kanske jävlas med en del av minnet 430 00:22:47,470 --> 00:22:49,390 att du inte hade för avsikt bråka med det hela. 431 00:22:49,390 --> 00:22:51,639 Och i själva verket du kan göra något riktigt förödande, 432 00:22:51,639 --> 00:22:54,880 som bryta ett annat program, eller bryta en annan funktion, 433 00:22:54,880 --> 00:22:58,289 eller göra något skadligt att du hade inte för avsikt att göra alls. 434 00:22:58,289 --> 00:23:00,080 Och så det är därför det är faktiskt en bra idé 435 00:23:00,080 --> 00:23:04,030 att ställa in pekare till null om du inte ställa dem till något meningsfullt. 436 00:23:04,030 --> 00:23:06,760 Det är förmodligen bättre på slutet av dagen för ditt program 437 00:23:06,760 --> 00:23:09,840 att krascha då för att det ska göra Något som skruvar upp 438 00:23:09,840 --> 00:23:12,400 ett annat program eller en annan funktion. 439 00:23:12,400 --> 00:23:15,207 Detta beteende är förmodligen ännu mindre perfekt än bara kraschar. 440 00:23:15,207 --> 00:23:17,040 Och så det är därför det är faktiskt en god vana 441 00:23:17,040 --> 00:23:20,920 att komma in för att ställa in pekare till null om du inte ställer in dem 442 00:23:20,920 --> 00:23:24,540 till ett meningsfullt värde omedelbart, ett värde som du känner 443 00:23:24,540 --> 00:23:27,260 och att du kan säkert den dereference. 444 00:23:27,260 --> 00:23:32,240 >> Så låt oss komma tillbaka nu och ta en titt på den övergripande syntaxen av situationen. 445 00:23:32,240 --> 00:23:37,400 Om jag säger int * p ;, vad har jag just gjort? 446 00:23:37,400 --> 00:23:38,530 Vad jag har gjort är detta. 447 00:23:38,530 --> 00:23:43,290 Jag vet värdet av p är en adress eftersom alla pekare är bara 448 00:23:43,290 --> 00:23:44,660 adresser. 449 00:23:44,660 --> 00:23:47,750 Jag kan dereference p med hjälp av * operatören. 450 00:23:47,750 --> 00:23:51,250 I detta sammanhang här, åtmin top minns * är en del av den typ. 451 00:23:51,250 --> 00:23:53,510 Int * är datatypen. 452 00:23:53,510 --> 00:23:56,150 Men jag kan dereference p med hjälp av * operatör, 453 00:23:56,150 --> 00:24:01,897 och om jag gör det, om jag går till den adressen, Vad hittar jag på denna adress? 454 00:24:01,897 --> 00:24:02,855 Jag kommer att hitta ett heltal. 455 00:24:02,855 --> 00:24:05,910 Så int * p är i grund och botten säger, är en adress sid. 456 00:24:05,910 --> 00:24:09,500 Jag kan dereference p och om Jag gör det kommer jag att hitta ett heltal 457 00:24:09,500 --> 00:24:11,920 vid denna minnesplats. 458 00:24:11,920 --> 00:24:14,260 >> OK så jag sade att det var en annan irriterande sak med stjärnor 459 00:24:14,260 --> 00:24:17,060 och här är där det irriterande sak med stjärnor är. 460 00:24:17,060 --> 00:24:21,640 Har du någonsin försökt att förklara flera variabler av samma typ 461 00:24:21,640 --> 00:24:24,409 på samma kodrad? 462 00:24:24,409 --> 00:24:27,700 Så för en andra, låtsas att linjen, koden jag har faktiskt där i grönt 463 00:24:27,700 --> 00:24:29,366 är inte där och det säger bara int x, y, z ;. 464 00:24:29,366 --> 00:24:31,634 465 00:24:31,634 --> 00:24:34,550 Vad det skulle göra är faktiskt skapa tre heltalsvariabler för dig, 466 00:24:34,550 --> 00:24:36,930 en kallade x, som kallas y, och en som heter z. 467 00:24:36,930 --> 00:24:41,510 Det är ett sätt att göra det utan behöva dela på tre linjer. 468 00:24:41,510 --> 00:24:43,890 >> Här är där stjärnorna får irriterande igen men 469 00:24:43,890 --> 00:24:49,200 eftersom * är faktiskt en del av både typ namn och delvis 470 00:24:49,200 --> 00:24:50,320 av variabelnamnet. 471 00:24:50,320 --> 00:24:56,430 Och så om jag säger int * px, py, pz, vad jag faktiskt får är en pekare till ett heltal 472 00:24:56,430 --> 00:25:01,650 kallas px och två heltal, py och pz. 473 00:25:01,650 --> 00:25:04,950 Och det är förmodligen inte vad vi vill, det är inte bra. 474 00:25:04,950 --> 00:25:09,290 >> Så om jag vill skapa flera pekare på samma rad, av samma typ, 475 00:25:09,290 --> 00:25:12,140 och stjärnor, vad jag faktiskt behöver göra är att säga int * pa, * pb, * pc. 476 00:25:12,140 --> 00:25:17,330 477 00:25:17,330 --> 00:25:20,300 Nu har just sagt att och nu talar om detta, 478 00:25:20,300 --> 00:25:22,170 du förmodligen aldrig kommer att göra detta. 479 00:25:22,170 --> 00:25:25,170 Och det är förmodligen en bra sak ärligt, eftersom du kanske av misstag 480 00:25:25,170 --> 00:25:26,544 utelämna en stjärna, nåt sånt. 481 00:25:26,544 --> 00:25:29,290 Det är nog bäst att kanske förklara pekare på enskilda linjer, 482 00:25:29,290 --> 00:25:31,373 men det är bara en annan av dessa irriterande syntax 483 00:25:31,373 --> 00:25:35,310 saker med stjärnor som gör pekare så svårt att arbeta med. 484 00:25:35,310 --> 00:25:39,480 Eftersom det är just detta syntaktiskt mess du har att arbeta igenom. 485 00:25:39,480 --> 00:25:41,600 Med praktiken gör verkligen bli en andra natur. 486 00:25:41,600 --> 00:25:45,410 Jag fortfarande gör misstag med det fortfarande efter programmering i 10 år, 487 00:25:45,410 --> 00:25:49,630 så bli inte upprörd om något händer till dig, är det ganska vanligt ärligt. 488 00:25:49,630 --> 00:25:52,850 Det är verkligen slags en brist i syntaxen. 489 00:25:52,850 --> 00:25:54,900 >> OK så jag slags lovat att vi skulle återkomma 490 00:25:54,900 --> 00:25:59,370 begreppet hur stor är en sträng. 491 00:25:59,370 --> 00:26:02,750 Tja, om jag sa att en sträng, vi har verkligen slags 492 00:26:02,750 --> 00:26:04,140 ljugit för dig hela tiden. 493 00:26:04,140 --> 00:26:06,181 Det finns ingen datatyp som kallas sträng, och faktum är att jag 494 00:26:06,181 --> 00:26:09,730 nämnde detta i en av våra tidigaste videor på datatyper, 495 00:26:09,730 --> 00:26:13,820 strängen var en datatyp som skapades för dig i CS50.h. 496 00:26:13,820 --> 00:26:17,050 Du måste #include CS50.h för att kunna använda den. 497 00:26:17,050 --> 00:26:19,250 >> Tja sträng är egentligen bara ett alias för något 498 00:26:19,250 --> 00:26:23,600 kallas char *, en pekare till ett tecken. 499 00:26:23,600 --> 00:26:26,010 Väl pekare, återkallelse, är bara adresser. 500 00:26:26,010 --> 00:26:28,780 Så vad är storleken i byte i en sträng? 501 00:26:28,780 --> 00:26:29,796 Jo det är fyra eller åtta. 502 00:26:29,796 --> 00:26:32,170 Och anledningen till att jag säger fyra eller åtta är eftersom det faktiskt 503 00:26:32,170 --> 00:26:36,730 beror på systemet, Om du använder CS50 ide, är char * storleken på en röding 504 00:26:36,730 --> 00:26:39,340 * Är åtta, det är en 64-bitars system. 505 00:26:39,340 --> 00:26:43,850 Varje adress i minnet är 64 bitar långt. 506 00:26:43,850 --> 00:26:48,270 Om du använder CS50 apparaten eller använda 32-bitars maskin, 507 00:26:48,270 --> 00:26:51,640 och du har hört det uttrycket 32-bitars maskin, vad är en 32-bitars maskin? 508 00:26:51,640 --> 00:26:56,090 Jo det bara innebär att varje adress i minnet är 32 bitar lång. 509 00:26:56,090 --> 00:26:59,140 Och så 32 bitar är fyra byte. 510 00:26:59,140 --> 00:27:02,710 Så en char * är fyra eller åtta byte beroende på ditt system. 511 00:27:02,710 --> 00:27:06,100 Och faktiskt alla datatyper, och en pekare till alla uppgifter 512 00:27:06,100 --> 00:27:12,030 skriver, eftersom alla pekare är bara adresser, är fyra eller åtta byte. 513 00:27:12,030 --> 00:27:14,030 Så låt oss återkomma till detta diagram och låt oss sluta 514 00:27:14,030 --> 00:27:18,130 den här videon med lite övning här. 515 00:27:18,130 --> 00:27:21,600 Så här är diagrammet vi slutade med i början av videon. 516 00:27:21,600 --> 00:27:23,110 Så vad händer nu om jag säger * pk = 35? 517 00:27:23,110 --> 00:27:26,370 518 00:27:26,370 --> 00:27:30,530 Så vad betyder det när jag säger, * pk = 35? 519 00:27:30,530 --> 00:27:32,420 Ta en andra. 520 00:27:32,420 --> 00:27:34,990 * pk. 521 00:27:34,990 --> 00:27:39,890 I sammanhanget här, * är dereference operatör. 522 00:27:39,890 --> 00:27:42,110 Så när dereference operatör används, 523 00:27:42,110 --> 00:27:48,520 vi gå till adressen pekade på genom pk, och vi ändrar vad vi hittar. 524 00:27:48,520 --> 00:27:55,270 Så * pk = 35 på ett effektivt sätt gör detta till bilden. 525 00:27:55,270 --> 00:27:58,110 Så det är i princip syntaktiskt identisk med att ha nämnda k = 35. 526 00:27:58,110 --> 00:28:00,740 527 00:28:00,740 --> 00:28:01,930 >> En till. 528 00:28:01,930 --> 00:28:05,510 Om jag säger int m, jag skapar en ny variabel som kallas m. 529 00:28:05,510 --> 00:28:08,260 En ny ruta, är det en grön ruta, eftersom det kommer att hålla ett tal, 530 00:28:08,260 --> 00:28:09,840 och det är märkt m. 531 00:28:09,840 --> 00:28:14,960 Om jag säger m = 4, ställde jag en heltal i den rutan. 532 00:28:14,960 --> 00:28:20,290 Om säga pk = & m, hur detta diagram förändring? 533 00:28:20,290 --> 00:28:28,760 Pk = & m, gör du ihåg vad & Operatör gör eller kallas? 534 00:28:28,760 --> 00:28:34,430 Kom ihåg att & vissa variabelnamn är adressen till ett variabelnamn. 535 00:28:34,430 --> 00:28:38,740 Så vad vi säger är pk får adress m. 536 00:28:38,740 --> 00:28:42,010 Och så effektivt vad händer diagrammet är att pk inte längre poäng 537 00:28:42,010 --> 00:28:46,420 k, men pekar på m. 538 00:28:46,420 --> 00:28:48,470 >> Igen pekare är mycket knepigt att arbeta med 539 00:28:48,470 --> 00:28:50,620 och de tar en hel del praxis, men eftersom 540 00:28:50,620 --> 00:28:54,150 deras förmåga att låta dig för att skicka data mellan funktioner 541 00:28:54,150 --> 00:28:56,945 och faktiskt har de ändringarna träder i kraft, 542 00:28:56,945 --> 00:28:58,820 få huvudet runt är verkligen viktigt. 543 00:28:58,820 --> 00:29:02,590 Det är förmodligen den mest komplicerade ämne vi diskuterar i CS50, 544 00:29:02,590 --> 00:29:05,910 men det värde som du får från att använda pekare 545 00:29:05,910 --> 00:29:09,200 långt uppväger de komplikationer som kommer från att lära sig dem. 546 00:29:09,200 --> 00:29:12,690 Så jag önskar er det bästa av lycka lära sig om pekare. 547 00:29:12,690 --> 00:29:15,760 Jag är Doug Lloyd, är detta CS50. 548 00:29:15,760 --> 00:29:17,447