Tip:
Highlight text to annotate it
X
>> DAVID MALAN: Okej, välkommen tillbaka.
Detta är CS50.
Detta är början på vecka sju.
Så det har varit ett tag, så jag tänkte att vi skulle ta en virvlande tur av var vi
slutade och där vi är nu på väg.
>> Så denna sak här kan ha orsakade viss ångest i början.
Men förhoppningsvis, du börjar anpassa sig till vad det betecknar här -
stjärna som representerar en pekare, som är precis vad, i mer lekmannaspråk?
Så det är en adress.
>> Så det är adressen till något i minnet.
Och vi började skära ner lagren ett par veckor sedan, saker gillar
GetString och andra sådana funktioner hela denna tid har återvänt
adresser saker i minnet, såsom adress för det första tecknet i
viss sekvens.
>> Så vi introducerade också Valgrind, vilket du börjar att använda för detta problem
ställa, i synnerhet för nästa Problemet satt liksom.
Och Valgrind gör vad för oss?
Den kontrollerar för minnesläckor, och det kontrollerar också för missbruk av minnet.
>> Det kan, med viss sannolikhet, upptäcka om din kod kommer att beröra minne
att det borde helt enkelt inte.
Så inte nödvändigtvis en läcka, men om du går utöver gränserna för vissa
array, och du kör faktiskt valgrind och framkalla detta beteende medan
Valgrind körs i ditt program är kör inne i den, får du
meddelanden som detta - "ogiltigt skriver om storlek 4, "där, minns ett par
veckor innebar sedan att jag hade av misstag gillar på en int för långt
utanför gränserna för en array.
Och så storlek 4 betyder här storleken av just int.
>> Så ta trygghet i det faktum att valgrind s produktion, formatet för den,
är bara avskyvärda.
Det är verkligen svårt att se igenom röran för den intressanta informationen.
Så vad vi har gjort här är bara utdrag några av de par mer
intressanta linjer.
Men inser att 80% av valgrind s produktionen kommer att vara lite av en
distraktion.
>> Bara leta efter mönster som dessa - ogiltig rätt, ogiltig läsa, 40 byte
och några antal block är definitivt förlorade, sökord som.
Och vad kommer du förhoppningsvis se en viss typ av spår av vilken funktion
misstag är faktiskt i.
I det här fallet, i vilken linje min kod var felet tydligen?
>> 26 i en fil som kallas memory.c, som var exemplet vi spelade med
vid den tidpunkten.
Så det är nog inte i malloc.
Det var nog i min kod istället.
Så vi får se detta igen och igen innan lång.
>> Så scanf, kom detta upp i en par blanketter hittills.
Vi såg sscanf kortfattat.
Det var något som ett antal du dök in i din
förberedelserna för frågesport.
Och scanf är faktiskt vad CS50 Biblioteket har använt under
huva för ganska länge för att få input från användaren.
>> Till exempel, om jag flyttar över till CS50 apparaten här, låt mig öppna upp en
exempel idag som heter scanf-0.c Och det är super enkelt.
Det är bara några få rader kod.
Men det visar verkligen hur getInt har arbetat hela denna tid.
>> I detta program här, i linje 16 , Märker att jag deklarera en int.
Så inga pekare, inget magiskt där, bara en int.
Sedan i linje 17, meddelar jag användaren för ett antal, tack.
Sedan i slutet av 18, jag använder scanf här.
Och jag specificerade, ungefär som printf, att jag väntar citat
unquote procent i.
>> Så procent i, naturligtvis, betecknar en int.
Men märker vad den andra argument till scanf är.
Hur skulle du beskriva den andra argument efter kommatecknet?
Vad är det?
>> Det är den adress x.
Så detta är användbart eftersom genom att tillhandahålla scanf med adressen till x, vad
att ge den funktionen att göra?
Inte bara åka dit, men också göra det?
>> Gör en ändring till den.
Eftersom du kan åka dit, det är typ av som en karta till en plats i minnet.
Och så länge du ger scanf, eller någon funktion med en sådan karta, som
Funktionen kan åka dit, och inte bara titta på värdet, men det kan också
ändra detta värde, vilket är användbart om syftet i livet med scanf är att
skanna inmatning från användaren, särskilt från tangentbordet.
Och f betecknar formaterade, precis som printf, betecknar f ett formaterat
sträng som du vill skriva ut.
>> Så kort sagt, denna linje 18 bara säger, försöker läsa ett int från användarens
tangentbord och förvara den inne i x, vid oavsett adress x råkar leva på.
Och sedan slutligen, linje 19 bara säger, tack för int, i det här fallet.
>> Så låt mig gå vidare och göra det.
Så gör scanf 0.
Låt mig gå vidare och zooma in
Jag ska gå och köra med prickar slash scanf 0.
Number, snälla?
50.
Tack för 50.
Så det är ganska enkelt.
>> Nu vad gör inte?
Det gör inte en hel *** av felkontroll.
Till exempel, om jag inte samarbetar, och jag skriver inte på ett nummer, men
istället skriver jag något som "hej" det är bara slags märkligt.
Och så en av de saker de CS50 Biblioteket har gjort för oss för några
tiden är att reprompting och reprompting.
>> Den retry frasen minns var i cs50.c, och det är anledningen till att getInt i
den CS50 biblioteket är faktiskt en hel gäng rader lång, eftersom vi är
kontroll för dumma saker som denna.
Har användaren inte ge oss, i själva verket, en int?
Har han eller hon ge oss något som en alfabetisk bokstav?
Om så, vill vi att upptäcka det och skrika på dem.
>> Men det blir mer intressant i nästa exempel.
Om jag går till scanf-1 c, är vad en sak som ändras radikalt i
nästa exempel?
Jag använder char *, naturligtvis, istället för int.
>> Så det här är intressant, eftersom char *, minns, är egentligen bara
Samma sak som sträng.
Så det känns som det kanske detta är en super enkel implementering av GetString.
Men jag har skalat tillbaka lagret av CS50 biblioteket, så jag är
kallar denna char * nu.
Så låt oss se var, om någonstans, vi går fel.
>> Linje 17 -
Jag säger det igen, ge mig något, i detta fall en sträng.
Och sedan i nästa rad, kallar jag scanf, igen, ge det ett format kod,
men denna gång procent s.
Och så den här gången, jag är ge den buffert.
>> Nu märker, jag inte använder et-tecknet.
Men varför är det förmodligen OK här?
För vad är bufferten redan?
Det är redan en pekare.
Det är redan en adress.
>> Och låt oss detta ord "förvirra," låt mig bara kalla det s, till exempel för
enkelhet.
Men jag har kallat den buffert eftersom allmänhet, i programmering, om du har en
bit av minnet, som en sträng egentligen bara är, kan man kalla det en buffert.
Det är en plats att lagra information.
>> Liknar saker som YouTube, då de är buffring, så att säga, att
bara betyder det att ladda ner bitar från Internet och lagra dem i en
lokal array, en lokal del av minnet så att du kan titta på det senare utan
det hoppar eller hänger på du under uppspelning.
>> Så det finns ett problem här men, eftersom jag säger scanf, förvänta sig en
strängen från användaren.
Här är adressen till en bit av minnet.
Sätt den strängen där.
Varför är det bundet ge oss problem, men?
>> Vad är det?
Får jag komma den del av minnet?
Du vet, jag vet inte.
Eftersom har buffert initierats till någonting?
Inte riktigt.
Och så det är vad vi har ringt ett skräp värde, vilket
är inte ett formellt ord.
Det betyder bara att vi har ingen aning om vad bitar är inne på de fyra byte som
Jag har tilldelats som buffert.
>> Jag har inte kallat malloc.
Jag har definitivt inte kallas GetString.
Så vem vet vad som faktiskt insidan av buffert?
Och ändå säger scanf blint, dit och ange vad användaren skrivit.
>> Så vad är sannolikt att orsaka i vår kod, om vi kör det?
Förmodligen en segfault.
Kanske inte, men förmodligen en segfault.
Och jag säger kanske inte eftersom det ibland du gör, ibland
du får inte en segfault.
Ibland får man bara tur, men det ändå kommer att vara
en bugg i vårt program.
>> Så låt mig gå vidare och sammanställa detta.
Jag kommer att göra det enligt den gamla skolan.
Så klang dash 0, scanf-1, scanf-1.c, Enter.
Oops, för gammal skola.
Låt oss se.
Vart tog jag vägen?
Åh, char * buffert.
Åh, tack -
Spara, OK -
mycket gamla skolan.
Okej, det har varit ett tag.
>> Så jag har bara sparat filen efter vilket gör att tillfälliga
ändra en stund sedan.
Och nu har jag sammanställt det manuellt med Clang.
Och nu ska jag gå vidare och kör scanf-1, Enter.
String vänligen.
Jag ska skriva in "hej."
>> Och nu, här där, uppriktigt sagt, printf kan är lite irriterande.
Det är faktiskt inte kommer att segfault i detta fall.
Printf är lite speciell eftersom det är så super vanligt att
huvudsak printf gör oss en tjänst och inse,
det är inte en giltig pekare.
Låt mig ta det på mig att bara skriva ut anges i parentes null, även
men det är inte nödvändigtvis vad vi själva förväntat.
>> Så vi kan inte riktigt lätt framkalla en segfault med detta, men tydligt detta
är inte det beteende som jag ville.
Så vad är den enkla lösningen?
Tja, i scanf-2, låt mig föreslå att stället för att faktiskt bara allokera en
char *, låt mig vara lite smartare om detta, och låt mig allokera buffert
som en sekvens av 16 tecken.
>> Så jag kan göra detta på ett par olika sätt.
Jag skulle absolut använda malloc.
Men jag kan gå tillbaka till vecka två när Jag behövde bara en ***
tecken.
Det är bara en array.
Så låt mig i stället omdefiniera buffert att vara en matris med 16 tecken.
>> Och nu, när jag passerar buffert -
och detta är något vi inte prata om i vecka två -
men du kan behandla en array som även om det är en adress.
Tekniskt, som vi har sett, de är lite annorlunda.
Men scanf inget emot om du klarar det namnet på en matris, eftersom det
Klang kommer att göra för oss är i huvudsak behandla namnet på den matris som
adressen för den bit av 16 byte.
>> Så det här är bättre.
Detta innebär nu att jag kan förhoppningsvis gör följande.
Låt mig zooma ut för ett ögonblick och gör att scanf-2, sammanställs OK.
Nu låt mig göra fick slash scanf-2.
String vänligen. "Hej." Och det verkade fungera den här gången.
>> Men kan någon föreslå ett scenario där det kanske inte fortfarande fungerar?
Yeah?
Något längre än 16 tecken.
Och faktiskt, kan vi vara lite mer exakt.
Något längre än 15 tecken, eftersom vi verkligen behöver för att hålla i minnet
att vi behöver att backslash noll implicit i slutet av strängen,
vilket är en åt sidan scanf kommer typiskt ta hand om för oss.
>> Så låt mig göra något liknande -
Ibland kan vi bara lämna det så.
OK, så vi har nu inducerad vår segmentering fel.
Varför?
Eftersom jag skrev till mer än 15 tecken, och så vi har faktiskt
rörd minne som jag faktiskt bör inte ha.
>> Så vad är egentligen lösningen här?
Tja, vad händer om vi behöver en längre sträng?
Tja, gör vi det kanske 32 bytes.
Tja, tänk om det inte är länge nog?
Vad sägs om 64 byte?
Tänk om det inte är länge nog?
Vad sägs om 128 eller 200 byte?
Vad är egentligen lösningen här i allmänna fallet, om vi inte vet i
förhand vad användaren kommer att skriva?
>> Det är bara typ av en stor smärta i röven, att vara ärlig, vilket är anledningen till den
CS50 biblioteket har några dussin rader kod som kollektivt genomföra
GetString sträng på ett sätt som vi inte måste veta i förväg vad
Användaren kommer att skriva.
I synnerhet om man ser tillbaka på cs50.c från två veckor sedan, kommer du att se
att GetString gör faktiskt inte använda scanf på detta sätt.
Snarare, läser den ett tecken åt gången.
>> Eftersom den ena fina läser ett tecken är att vi kan
garantera oss att alltid ha minst en röding.
Jag kan bara förklara en röding, och sedan ta dessa verkligt baby steg till strax
Läs ett tecken in på en tiden från tangentbordet.
Och sedan, vad du ser GetString gör är varje gång det tar ***,
säga, 16 byte minne, använder den malloc, eller en kusin därav, att
allokera mer minne, kopierar den gamla minnet i den nya, och sedan krypa
tillsammans, att få ett tecken i tiden, och när det tar *** i det
bit av minnet, kastar bort det, grabs en större bit av minnet, kopierar gamla
till nya, och upprepar.
Och det är verkligen en smärta att faktiskt genomföra något så enkelt som
få input från en användare.
>> Så du kan använda scanf.
Du kan använda andra liknande funktioner.
Och en hel del läroböcker och nätet exempel gör, men de är alla
sårbara för problem som detta.
Och slutligen, få en segfault är typ av irriterande.
Det är inte bra för användaren.
>> Men i värsta fall, vad gör det lägger grunden din
kod vid risk?
Något slags angrepp, potentiellt.
Vi pratade om en sådan attack - överfyllda bunten.
Men i allmänhet, om du får spilla en buffert, som vi gjorde en
par veckor sedan, med bara skriva mer än "hej" på stacken, du
kan faktiskt ta över, potentiellt, en dator, eller åtminstone komma på data som
tillhör inte dig.
>> Så kort sagt, det är därför vi har dessa stödhjul.
Men nu börjar vi att ta bort dem, eftersom våra program inte längre behöver,
nödvändigtvis, inmatning från användaren.
Men i fallet med problem som sex, din inmatning kommer från en enorm
ordlistefilen med 150 några udda tusen ord.
>> Så du inte behöver oroa dig användarens godtyckliga indata.
Vi kommer att ge dig några antaganden om den filen.
Eventuella frågor om pekare eller scanf eller användarens input i allmänhet?
>> Okej, så en snabb *** och sedan på en släpande ämne från två veckor sedan.
Och det var denna föreställning om en struct.
Inte att - denna föreställning om en struct, vilket var vad?
Vad gjorde struct göra för oss?
>> Define -
ledsen?
Definiera en variabel typ.
Så sortera om.
Vi är faktiskt kombinera två ämnen.
Så med typedef, minns att vi kan deklarera en typ av vår egen, som en
synonym, liksom sträng för char *.
Men med hjälp av typedef och struct, kan vi skapa verkligt egna datastrukturer.
>> Till exempel, om jag går tillbaka in i gedit här för bara ett ögonblick, och jag går vidare
och göra något liknande, låt mig sparar detta som, låt oss säga, structs.c
tillfälligt, jag ska bara att gå vidare och inkludera
standardio.h, int main tomrum.
Och sedan i här, antar att jag vill ha att skriva ett program som lagrar
flera studenter från flera hus, till exempel.
Så det är som en registrarial databas av något slag.
>> Så om jag behöver namnet en student, jag kanske göra något liknande char * namn,
och jag ska göra något liknande -
faktiskt, låt oss använda CS50 biblioteket för bara en stund för att göra detta till en
lite enklare, så att vi kan låna de dussintals rader kod.
Och låt oss bara hålla det enkelt.
Vi ska hålla det sträng, och nu getString.
>> Så jag hävdar nu att jag har sparat namnet av någon elev, och hus
vissa studerande, helt enkelt med hjälp av variabler som vi gjorde, och i vecka ett.
Men antar att jag nu vill stödja flera studenter.
Okej, så min instinkt är att göra string namn2, blir GetString, sträng
house2 blir GetString.
Och då vår tredje elev, låt oss göra NAME3 GetString.
>> Okej, så det är förhoppningsvis slående dig som ett slags dum,
eftersom denna process är egentligen aldrig kommer att sluta, och det kommer bara att
gör min kod ser värre och värre och värre.
Men vi löste det också i vecka två.
Vad var vår relativt ren lösning när vi hade flera variabler av
samma datatyp som alla är relaterade, men Vi ville inte att denna fruktansvärda röran
av liknande namn variabler?
Vad gjorde vi i stället?
>> Så jag tror att jag hörde ett par ställen.
Vi hade en matris.
Om du vill ha flera instanser av något, varför inte vi rengöra alla
upp och bara säga, ge mig array kallas namn?
>> Och för nu, låt oss hårt kod 3.
Och sedan ge mig en annan array kallas hus, och låt mig för
nu hårt kod 3.
Och jag har massivt städas upp förstöra som jag nyss skapat.
Nu har jag fortfarande svårt kodad 3, men även 3 kunde dynamiskt komma från
användare eller argv, eller liknande.
Så detta är redan renare.
>> Men vad är irriterande med detta är att Nu är även ett namn på något sätt
fundamentalt kopplad till en students hus -
det är en elev som jag verkligen vill representera -
Jag har nu två arrayer som är parallella i den meningen att de är de
samma storlek och namn konsol 0 förmodligen kartor till hus konsol 0,
och namn på konsolen 1 kartor till hus bracket 1.
Med andra ord, den studerande bor i det huset, och att andra studerande
bor i det andra huset.
Men visst kan detta vara gjort ännu renare.
>> Tja, det kan i själva verket.
Och låt mig gå vidare och öppna upp structs.h, och du kommer
se denna idé här.
Lägg märke till att jag har använt typedef, som ni hänvisade till för en stund sedan att förklara vår
egen datatyp.
Men jag använder också denna andra sökord kallas struct som ger mig en ny
datastruktur.
>> Och denna datastruktur jag hävdar går att ha två saker inuti
det - en sträng som heter namn, och en sträng som kallas hus.
Och namnet jag ska ge till denna datastruktur kommer
att kallas student.
Jag skulle kunna kalla det vad jag vill, men detta göra semantiskt
meningsfullt för mig i mitt sinne.
>> Så nu, om jag öppnar upp en bättre version av det program jag började skriva
det, låt mig rulla till toppen.
Och det finns några fler rader kod här, men låt mig fokusera för
det ögonblick på en.
Jag har förklarat en konstant kallade studenter och hårdkodade 3 för nu.
Men nu, märker hur ren min kod börjar komma.
>> I linje 22, förklarar jag samling av studenter.
Och märker att studenten är tydligen nu en datatyp.
Eftersom på toppen av denna fil, märker Jag har bland annat varit sidhuvudfilen
att jag drog upp nyss.
Och att header-fil helt enkelt hade denna definition av en elev.
>> Så nu har jag skapat min egna uppgifter typ att författarna C år
sedan inte tänka på i förväg.
Men inga problem.
Jag kan göra det själv.
Så detta är en array kallas studenter, vars samtliga medlemmar
är en student struktur.
Och jag vill ha tre av dem i arrayen.
>> Och nu, vad gör resten av detta program göra?
Jag behövde något lite godtyckligt.
Så från nätet 24 och framåt, Jag iterera från 0 till 3.
Jag frågar då användaren för studentens namn.
Och då jag använder getString som förut.
Då frågar jag för elevens huset, och jag använder getString som tidigare.
>> Men varsel - något nytt bit syntax -
Jag kan fortfarande index till det i: te studerande, men hur får jag på de specifika uppgifter
fält inne i struct?
Tja, vad är uppenbarligen ny bit av syntax?
Det är bara pricken operatören.
>> Vi har inte riktigt sett det här förut.
Du har sett det i pset fem om du har dök redan med bitmap-filer.
Men pricken betyder precis innanför detta struct eller flera fält, ger prick
namn, eller ge mig dot hus.
Det innebär att gå in i struct och få dessa särskilda områden.
>> Vad gör resten av det här programmet?
Det är inte så sexigt.
Observera att jag iterera från 0 till 3 igen, och jag skapar helt enkelt en engelsk
fras som så och så är i en sådan och ett sådant hus, passerar i prick namn från
den i: te student och deras huset också.
>> Och sedan sist, nu ska vi börja för att få *** om detta, nu när vi är
bekant med vad malloc och andra funktioner har varit
gör hela tiden.
Varför måste jag befria både namn och hus, även om jag
inte ringa malloc?
>> GetString gjorde.
Och det var den smutsiga lilla hemlighet för flera veckor, men GetString har
läckt minne hela placera hela terminen hittills.
Och Valgrand kommer slutligen avslöja detta för oss.
>> Men det är inte en stor sak, eftersom jag vet att jag kan helt enkelt frigöra namnet
och huset, men tekniskt sett, att vara super, super säker, ska jag vara
gör vissa felkontroll här.
Vilka är dina instinkter säger dig?
Vad bör jag kontrollera om innan jag gratis Vad är en
string, aka som en char *?
>> Jag borde verkligen kontrollera om eleverna fäste i prick namn inte
lika null.
Sedan ska det vara OK att gå vidare och gratis som pekare, och samma eller det andra
en också.
Om eleverna fäste i dot hus är inte lika med noll, detta nu kommer att skydda
mot hörnet fall där GetString returnerar något som null.
Och vi såg en stund sedan, printf kommer skydda oss här uppe genom att bara säga
null, vilket går att se konstigt.
Men åtminstone det inte kommer segfault, som vi har sett.
>> Nåväl, låt mig göra en sak här. structs-0 är lite av en dum program
eftersom jag in alla dessa data, och sedan det förlorat när programmet avslutas.
Men låt mig gå vidare och göra det.
Låt mig göra terminalen fönstret lite större.
Låt mig göra structs-1, vilket är en ny version av detta.
>> Jag kommer in i en liten bit.
Och låt mig nu kör prick snedstreck structs-1.
Studentens namn -
David Mather, låt oss göra Rob Kirkland, låt oss göra Lauren Leverett.
Vad är intressant nu är varsel -
och jag vet att bara detta eftersom Jag skrev programmet -
det finns en fil nu på min nuvarande katalog som heter students.csv.
Några av er kanske har sett dessa i den verkliga världen.
>> Vad är en CSV-fil?
Kommaavgränsade värden.
Det är ungefär som en fattig mans version av en Excel-fil.
Det är en tabell med rader och kolumner som du kan öppna i ett program som Excel,
eller siffror på en Mac.
>> Och om jag öppnar den här filen här på gedit, varsel - och siffrorna är inte där.
Det är bara gedit berätta mig radnummer.
Tillkännagivande om den första raden i detta filen är David och Mather.
Nästa rad är Rob kommatecken Kirkland.
Och den tredje raden är Lauren kommatecken Leverett.
>> Så vad har jag skapat?
Jag har nu skrivit ett C-program som effektivt kan generera kalkylblad
som kan öppnas i en program som Excel.
Inte så övertygande en datamängd, men om du har mycket större bitar av
data som du verkligen vill manipulera och göra grafer av och
liknande, är detta kanske en sätt att skapa dessa uppgifter.
Dessutom CSVs är faktiskt super gemensamma bara för lagring av enkel data -
Yahoo Finance, till exempel, om du får aktiekurser via deras så kallade
API, gratis tjänst som låter dig få aktuell up-to-the-date lager
offerter för företagen, de ge tillbaka data i
super enkel CSV-format.
>> Så hur har vi det?
Väl att märka, de flesta av programmets nästan samma.
Men märker här nere, snarare än utskrift eleverna ute på linje 35
framåt, hävdar jag att jag sparar den studenter till disk, så sparar en fil.
>> Så märker jag att förklara en FIL * -
nu, är denna typ av en anomali i C. Av någon anledning är FILE versaler,
vilket är inte som de flesta andra datatyper i C. Men detta är en inbyggd
datatyp, FILE *.
Och jag förklara en pekare till en fil, är hur du kan tänka på det.
>> fopen betyder öppen fil.
Vilken fil vill du öppna?
Jag vill öppna en fil som jag kommer godtyckligt ringa students.csv.
Jag skulle kalla det vad jag vill.
>> Och sedan ta en gissning.
Vad innebär det andra argumentet till fopen betyda förmodligen?
Höger, w för write, kunde vara r för läsning.
Det finns en för append om du vill lägga till rader och inte
skriva över det hela.
>> Men jag vill bara skapa den här filen en gång, så jag ska använda citat unquote w.
Och jag vet att det bara från att ha läst dokumentationen, eller man-sidan.
Om filen inte är null - med andra ord, Om något gick fel där -
låt mig iterera över studenter från 0 till 3.
>> Och nu märker att det är något någonsin så något annorlunda
kring linjen 41 här.
Det är inte printf.
Det är fprintf för filen printf.
Så det kommer att skriva till fil.
Vilken fil?
Den vars pekare du anger som det första argumentet.
>> Då kan vi ange ett format sträng.
Då kan vi ange vilken sträng som vi vill plug in för den första procent s, och
sedan en annan variabel eller den andra procent s.
Då kan vi avsluta ärendet med fclose.
Än jag frigöra minne som förut, men Jag ska gå tillbaka in och lägga
vissa kontroller för null.
>> Och det är det.
fopen, fprintf ger fclose mig förmåga att skapa textfiler.
Nu ser du i problem set fem, som innebär bilder, ska du använda
binära filer i stället.
Men i grunden är idén densamma, även om de funktioner du
se är lite annorlunda.
>> Så virvlande tur, men du kommer att få alltför bekant med fil I/O--
ingång och utgång - med pset fem.
Och några frågor om första grunderna här?
Yeah?
>> Vad händer om du försöker att frigöra ett null-värde?
Jag tror, om inte gratis har blivit en lite mer användarvänliga, kan du
potentiellt segfault.
Förbi det null är dåligt eftersom jag inte tro gratis stör att kontrollera dig,
eftersom det skulle kunna vara ett slöseri tid för den att göra sig till
alla i världen.
Bra fråga, men.
>> Okej, så denna typ av får oss till ett intressant ämne.
Temat för problemet set fem är kriminalteknik.
Åtminstone det är en del av problemet set.
Forensics hänvisar i allmänhet till återvinning av information som kan eller
kanske inte har tagits bort avsiktligt.
Och så jag trodde jag skulle ge dig en snabb smakprov på vad som verkligen händer alla
denna gång under huven på din dator.
>> Till exempel, om du har insidan av din bärbara eller stationära dator en
hårddisk, det är antingen en mekanisk enhet som faktiskt snurrar -
det finns cirkulära saker som kallas Platters som helt ser ut som vad jag
bara hade upp på skärmen här, men detta är allt gamla skolan.
Detta är en tre-och en halv tum hårddisk.
Och tre och en halv inches hänvisar i med den saken när du installerar det
i en dator.
>> Många av er i era laptops nu har solid-state-enheter eller SSD,
som inte har några rörliga delar.
De är mer som RAM och mindre som Dessa mekaniska anordningar.
Men idéerna är fortfarande samma, säkerligen de rör
att problemet satt fem.
>> Och om du tycker om nu en hårddisk föreställer att vara en cirkel, som
Jag ska göra som det här.
När du skapar en fil på din dator, oavsett om det är en SSD, eller i
detta fall, en äldre skola hårddisk, den filen innefattar flera bitar.
Låt oss säga att det är det här 0 och 1, en hel *** av 0 och 1.
Så detta är hela min hårddisk.
Detta är uppenbarligen en ganska stor fil.
Och det använder upp 0s och 1s vid den del av den fysiska diskens.
>> Nå, vad är det fysiska delen?
Jo, visar det sig att på en hårddisk, åtminstone av denna typ, det finns
dessa små små magnetiska partiklar.
Och de har i huvudsak norr och sydpoler till dem, så att om du
vända ett av dessa magnetiska partiklar detta sätt kan man säga att det är
som representerar en 1.
Och om det är upp och ner söderut till norr, kan man säga att det är
representerar en 0.
>> Så i den verkliga fysiska världen, är det hur man kan representera något i
binära tillståndet av 0 och en 1.
Så det är allt en fil.
Det finns en hel drös med magnetisk partiklar som är deras på detta sätt eller
detta sätt, vilket skapar mönster av 0 och 1.
>> Men det visar sig när du sparar en fil, viss information sparas separat.
Så det här är ett litet bord, en katalog, så att säga.
Och jag ska kalla denna kolumn namn, och Jag ringer denna kolumn plats.
>> Och jag ska säga, antar detta är mitt CV.
Min resume.doc lagras vid plats, låt oss säga 123.
Jag går alltid för det numret.
Men det räcker att säga att precis som i RAM, kan du ta en hårddisk
det är en gigabyte eller 200 gigabyte eller en terabyte, och du kan
antal alla byte.
Du kan numrera alla bitar av 8 bitar.
>> Så vi säger att detta är plats 123.
Så här katalogen insidan av mitt operativsystem Systemet kommer ihåg att min
CV är på plats 123.
Men det blir intressant när du raderar en fil.
>> Så till exempel -
och tack och lov, har de flesta av världens fångas på detta - vad händer när
du drar en fil till din Mac OS Papperskorgen eller din Windows Papperskorgen?
Vad är syftet med att göra det?
Det är självklart att bli av med filen, men vad gör handlingen att dra och
släppa in papperskorgen eller din Recycle Bin göra på en dator?
>> Absolut ingenting, egentligen.
Det är precis som en mapp.
Det är en särskild mapp, för att vara säker.
Men tar inte bort det faktiskt filen?
>> Tja, nej, eftersom vissa av er förmodligen ha varit som, åh fan, det gjorde du inte
menar att göra det.
Så du dubbelklicka på Papperskorgen eller Papperskorgen.
Du har petade runt och du har återhämtat filen bara genom att dra den
av där.
Så klart, det är inte nödvändigtvis radera det.
>> OK, du är smartare än så.
Du vet att bara dra den till Papperskorgen eller Papperskorgen betyder inte
du tömma papperskorgen.
Så du gå upp till menyn, och du säger Töm papperskorgen eller Töm papperskorgen.
Vad händer då?
>> Ja, så det tas bort mer så.
Men allt som händer är detta.
Datorn glömmer där resume.doc var.
>> Men vad har inte förändrats tydligen på bilden?
Bitarna är 0 och 1 som jag hävdar är på platsen för några fysiska aspekten av
hårdvaran.
De är fortfarande där.
Det är bara att datorn har glömt vad de är.
>> Så det är i huvudsak befriade filens bitar så att de kan återanvändas.
Men inte förrän du skapar fler filer, och fler filer och mer filer
probabilistiskt, de 0s och 1s, dessa magnetiska partiklar, får återanvändas,
upp eller med rätt sida upp, för andra filer, 0 och 1.
>> Så du har detta tidsfönster.
Och det är inte för förutsägbar längd, egentligen.
Det beror på storleken på din hårddisk kör och hur många filer du har och
hur snabbt du göra nya.
Men det är det här fönstret för tid under som att filen är fortfarande helt
ersättningsgilla.
>> Så om du använder någonsin program som McAfee eller Norton att försöka återvinna
uppgifter, är allt de gör försöker återvinna denna så kallade katalogen
räkna ut var filen fanns.
Och ibland Norton och kommer att säga, filen är 93% återvinningsbart.
Tja, vad betyder det?
Det betyder bara att någon annan fil tillfällighet slutade med, säg,
dessa bitar ur din ursprungliga filen.
>> Så vad är egentligen inblandade att återskapa data?
Tja, om du inte har något som Norton förinstallerat på datorn,
det bästa du kan ibland göra är att titta på hela hårddisken söker
mönster av bitar.
Och ett av de teman som problem set fem är att du kommer att söka
motsvarande en hårddisk, en rättsmedicinsk bilden av ett compact flash-kort från en
digitalkamera, söka efter 0s och 1s som normalt, med hög
sannolikhet, företräda start av en JPEG-bild.
>> Och ni kan återställa dessa bilder genom antar, om jag ser detta mönster av
bitar på rättsmedicinska bilden, med hög sannolikhet, som markerar
början av en JPEG.
Och om jag ser samma mönster igen, som markerar förmodligen starten av
annat JPEG, och en annan JPEG, och annat JPEG.
Och detta är typiskt hur Data Recovery fungerar.
Vad är trevligt om JPEG är trots filformatet i sig är något
komplex, i början av varje sådan filen är faktiskt ganska identifierbar
och enkel, som ni kommer att se, om du har inte redan.
>> Så låt oss ta en närmare *** under huven till exakt vad som har varit
pågår, och vad dessa 0s och 1s är, för att ge dig lite mer av en
sammanhanget för denna utmaning.
>> [VIDEO SPELA]
>> -Om din dator lagrar mest av dess permanenta uppgifter.
För att göra detta, reser data från RAM tillsammans med programvara signaler som talar
hårddisken hur man lagrar dessa data.
De hårda drivkretsar översätta dessa signaler till spänning
fluktuationer.
Dessa, i sin tur, kontrollera hårddiskens rörliga delar, några av de få
rörliga delar kvar i modern dator.
>> Några av de signaler styr en motor som snurrar metall-belagda skivorna.
Dina uppgifter lagras i själva verket på dessa fat.
Andra signaler flytta läs / skriv huvuden att läsa eller
skriva data på skivorna.
Denna maskin så precisa att en människa håret kunde inte ens passera mellan
huvuden och snurrande skivorna.
Ändå fungerar det på fantastiska hastigheter.
>> [END VIDEOAVSPELNING]
>> DAVID MALAN: Zooma in lite djupare nu på vad som är
faktiskt på dessa fat.
>> [VIDEO SPELA]
>> -Låt oss titta på vad vi just såg i slow motion.
När en kort puls av el är skickas till läs / skrivhuvudet, om flips
på en liten elektromagnetisk för en bråkdel av en sekund.
Magneten skapar ett fält, vilket ändrar polaritet av en liten, liten
del av metallpartiklar som päls varje tallrik yta.
>> Ett mönster serie av dessa små, laddade-up områden på disken
representerar en enda bit av data i det binära talet
system som används av datorer.
Nu, om ström sänds ett sätt genom läs / skriv huvudet, området
är polariserat i en riktning.
Om ström sänds i motsatt riktning, den
polarisering är omvänd.
>> Hur du får data från hårddisken?
Bara vända processen.
Så det är partiklarna på disken att få strömmen i
läs / skrivhuvudet rör sig.
Sätt ihop miljontals dessa magnetiserade segment, och
du har en fil.
>> Nu, bitar av en enda fil kan vara utspridda över ett enhetens
skivorna, ungefär som röran av papper på skrivbordet.
Så en särskild extra fil håller koll av där allt är.
Önskar du inte att du hade nåt sånt?
>> [END VIDEOAVSPELNING]
>> DAVID MALAN: OK, förmodligen inte.
Så hur många av er killar växte upp med dessa?
OK, så det är färre och färre händer varje år.
Men jag är glad att du är minst bekant med dem, eftersom detta och vår egen
bok demo, tyvärr, dör en mycket långsam död här i förtrolighet.
>> Men detta är vad jag, åtminstone, tillbaka i gymnasiet, använde användning för säkerhetskopior.
Och det var fantastiskt, eftersom du kunde lagra 1.4 megabyte på
denna speciella skivan.
Och detta var den höga tätheten versionen, såsom indikeras av HD, som har
menande före dagens HD-videor.
>> Standard densiteten var 800 kilobyte.
Och innan det fanns 400-kilobyte diskar.
Och innan dess fanns det 5 och 1/4 tums disketter, som var riktigt diskett,
och lite bredare och högre än dessa saker här.
Men du kan faktiskt se den så kallade floppy aspekt av dessa diskar.
>> Och funktionellt, är de faktiskt ganska lik hårddiskar på
minst denna typ.
Återigen, SSDs i nyare datorer fungerar lite annorlunda.
Men om du flyttar den lilla metall flik, Du kan faktiskt se en liten kaka,
eller tallrik.
>> Det är inte metall som den här.
Detta är faktiskt lite billigare plastmaterial.
Och du kan typ av vicka.
Och du har trully bara torkas av vissa antalet bitar eller magnetiska partiklar
från denna skiva.
>> Så tack och lov, det finns inget på det.
Om den saken är i vägen - och täcker dina ögon och de av din granne -
du kan bara typ av drag här Hela skidan iväg så där.
Men det finns en liten fjäder, så att medveten om det med dina ögon.
Så nu har du verkligen en diskett.
>> Och vad är anmärkningsvärt om detta är att i så mycket som detta är en
småskalig representation av en större hårddisk, dessa saker är super,
super enkelt.
Om du nyper botten med det, nu när att metall sak är avstängd, och skal
dem öppna, är allt som finns två stycken filt och den så kallade diskett
med en bit metall på insidan.
>> Och där går hälften av min diskens innehåll.
Det går en annan halva av dem.
Men det är allt som snurrar inuti av datorn i förr.
>> Och återigen, att sätta detta i perspektiv, hur stort är det mesta av din
hårddiskar dessa dagar?
500 gigabyte, en terabyte, kanske i en stationär dator, 2 terabyte, 3
terabyte, 4 terabyte, eller hur?
Detta är en megabyte, ge eller ta, som inte ens kan passa en typisk MP3
längre dessa dagar, eller några liknande musikfil.
>> Så en liten souvenir för dig idag, och också att hjälpa kontextualisera vad
Vi kommer att ta för givet nu i problem som fem.
Så de är din att behålla.
Så låt mig övergång till där blir spendera nästa pset liksom.
Så vi har nu satt den här sidan för - åh, ett par meddelanden snabbt.
>> Denna fredag, om du vill gå CS50 för lunch, gå till det vanliga stället,
cs50.net/rsvp.
Och slutprojekt -
så per kursplanen, har vi lagt upp slutprojekt specifikationen redan.
Inse att det inte betyder det beror särskilt snart.
Det har publicerats, egentligen, bara för att få ni tänker på det.
Och faktiskt, en super betydande procentandel av er kommer att ta itu med
slutarbeten på material som vi har inte ens fått i klassen,
men kommer så tidigt som nästa vecka.
>> Observera dock att den spec kräver några olika komponenter i
slutprojekt.
Den första, i ett par veckor, är en pre-förslag, en ganska casual e-post till
din TF för att berätta för honom eller vad du är tänka på för ditt projekt, med
inget åtagande.
Förslaget kommer att vara din engagemang, ordstäv, här, är detta vad
Jag skulle vilja göra för mitt projekt.
Vad tycker du?
För stor?
För liten?
Är det hanterbart?
Och du ser spec för mer information.
>> Par veckor efter det är statusen Rapporten, som är en liknande
tillfällig e-post till din TF att säga precis hur långt efter du är i din sista
projektets genomförande, följt av den CS50 Hackathon som alla
är inbjudna, vilket kommer att vara en händelse från 20:00 på en kväll till 07:00
AM nästa morgon.
Pizza, som jag kanske har nämnt i veckan noll, vara til serveras vid 9:00,
Kinesisk mat på 1:00 AM.
Och om du fortfarande vaken klockan 5:00, Vi tar dig till IHOP för frukost.
>> Så Hackathon är en av de mer minnesvärda upplevelser i klassen.
Då genomförandet beror, och då den kulminerande CS50 Fair.
Mer information om alla dessa under de kommande veckorna.
>> Men låt oss gå tillbaka till något old school -
igen, en array.
Så en array var trevligt, eftersom det löser problem som vi såg bara en
stund sedan med studerande strukturer få en lite ur kontroll om vi
vill ha eleven en, student två, Studenten tre, student dot dot dot,
några godtyckligt antal studenter.
>> Så arrayer, för några veckor sedan, svepte in och löste alla våra problem med inte
att veta i förväg hur många saker av något slag som vi kanske vill.
Och vi har sett att structs kan hjälpa oss ytterligare organisera vår kod och hålla
begreppsmässigt likartade variabler, t.ex. en namn och ett hus, tillsammans, så att vi
kan behandla dem som en enhet, insida av vilka det finns mindre bitar.
>> Men arrayer har vissa nackdelar.
Vilka är några av de nackdelar vi har stött
med arrayer hittills?
Vad är det?
Fast storlek - så även om du kanske kunna allokera minne för ett
array, när du vet hur många studenter du har, hur många tecken du har
från användaren, när du har tilldelats arrayen, har du typ av målade
själv i ett hörn.
>> Eftersom du inte kan infoga nya element i mitten av en array.
Du kan inte sätta in fler element vid slutet av en array.
Verkligen, du måste ta till att skapa en helt ny array, som vi har diskuterat,
kopiera det gamla till det nya.
Och återigen, är att huvudvärken som GetString erbjudanden med för dig.
>> Men återigen, kan du inte ens sätta något i mitten av uppsättningen
Om räntan inte är helt fylld.
Till exempel, om denna array här av storlek sex har bara fem saker i den,
Tja, kan du bara please något på änden.
Men vad händer om du vill infoga något in i mitten av den
array, även om det kan ha fem av sex saker i den?
>> Nå, vad vi gör när vi hade alla av våra frivilliga på scenen i
veckor tidigare?
Om vi ville sätta någon här, antingen dessa människor hur man flyttar detta
sätt, eller dessa människor hur man flyttar detta sätt, och det blev dyrt.
Vid förflyttningen av människor inne i en array hamnade lägga upp och kostnadsberäkning
oss tid, alltså mycket av vår n kvadrat rinnande tider som insättning sortera, för
Exempelvis, i värsta fall.
Så arrayer är bra, men du måste vet i förväg hur stor du vill ha dem.
>> Så OK, här är en lösning.
Om jag inte vet i förväg hur många elever jag kan ha, och jag vet en gång
Jag bestämmer, men jag fastnade med att många studenter, varför gör inte jag bara alltid
fördela dubbelt så mycket utrymme så jag tror jag behöver?
Är det inte en rimlig lösning?
>> Realistiskt, jag tror inte att vi är kommer att behöva mer än 50 platser
i en matris för en medelstor klass, så låt oss bara runda upp.
Jag ska göra 100 slots i min samling, precis så att vi kan definitivt få
Antalet elever jag förväntar vara i någon medelstor klass.
Så varför inte bara runda upp och fördela mer minne, typiskt, för en samling
än du tror att du ens behöver?
Vad är det här enkla stift till den idén?
>> Du är bara slöseri med minne.
Bokstavligen varje program du skriver sedan är kanske använder dubbelt så mycket minne som
du behöver faktiskt.
Och det bara inte känns som en särskilt elegant lösning.
Dessutom minskar det bara sannolikheten för ett problem.
Om du råkar ha en populär kurs en termin och du har 101
studenter, är programmet fortfarande grunden inför samma fråga.
>> Så tack och lov, det finns en lösning på denna annons alla våra problem i form
av datastrukturer som mer komplex än de som
vi har sett hittills.
Detta, hävdar jag, är en länkad lista.
Detta är en lista med tal -
9, 17, 22, 26, och 34 -
som har länkats samman genom av vad jag har ritat som pilar.
>> Med andra ord, om jag ville representera en matris, kunde jag göra
ungefär så här.
Och jag ska sätta detta på overhead på bara ett ögonblick.
Jag kunde göra -
hej, okej.
Stand by.
Ny dator här, klart -
okej.
>> Så om jag har dessa siffror i rad -
9, 17, 22, 26, 24 -
inte nödvändigtvis i skala.
Okej, så här är min samling -
oh my god.
Okej, så här är min samling.
Herregud.
>> [SKRATT]
>> DAVID MALAN: Pretend.
Det är för mycket ansträngning för att gå tillbaka och fixa det, så det -
26.
Så vi har denna samling av 9, 17, 22, 26, och 34.
För de av er kan se pinsamt misstag jag gjorde precis,
det är det.
>> Så jag hävdar att detta är en mycket effektiv lösning.
Jag har tilldelats lika många ints som Jag behöver - ett, två, tre,
fyra, fem eller sex -
och jag har sedan lagrat numren insidan av denna matris.
Men anta, då vill jag att infoga ett värde som nummer 8?
Tja, inte var det går?
Anta att jag vill infoga ett antal som 20.
Tja, inte var det går?
Någonstans där i mitten, eller antalet 35 måste gå
någonstans i slutet.
Men jag är allt ut i rymden.
>> Och så detta är en grundläggande utmaning av matriser det betyder är lösningen.
Jag hävdade en stund sedan, getString löser detta problem.
Om du vill infoga en sjätte nummer in i denna matris, vilka är åtminstone en
lösning du kan falla tillbaka på för säker, precis som vi gör med GetString?
Vad är det?
>> Tja, göra det större är lättare sagt än gjort.
Vi kan inte nödvändigtvis göra arrayen större, men vad kan vi göra?
Gör en ny array som är större, av storlek 6, eller kanske storlek 10, om vi vill
att få ett försprång på saker, och sedan kopiera den gamla arrayen i den nya, och sedan
frigöra den gamla matrisen.
>> Men vad är det gångtid nu i den processen?
Det är stort O n, eftersom kopiering kommer att kosta dig några enheter
tid, så inte så perfekt om vi måste allokera en ny array, som kommer
att konsumera dubbelt så mycket minnet tillfälligt.
Kopiera gammalt till nytt -
Jag menar, det är bara en huvudvärk, som är, återigen, varför vi skrev
GetString för dig.
>> Så vad kan vi göra i stället?
Tja, tänk om vår datastruktur faktiskt har luckor i det?
Antag att jag slappna av mitt mål att ha sammanhängande bitar av minnet, där 9
är rätt bredvid 17, vilket är precis intill 22, och så vidare.
>> Och antar att 9 kan vara över här i RAM och 17 kan vara över här i RAM,
och 22 kan vara över här i RAM.
Med andra ord, jag behöver inte dem även tillbaka till tillbaka längre.
Jag måste bara något trä en nål genom alla dessa siffror, eller varje
av dessa noder, som vi kallar rektanglar som jag har ritat dem,
ihåg hur man får till den sista sådan nod från det första.
>> Så vad är programmering konstruktion Vi har sett ganska nyligen som jag
kan genomföra denna tråd, eller dras här, som jag kan
genomföra dessa pilar?
Så pekare, eller hur?
Om jag inte allokera bara en int, men en nod - och genom
nod, menar jag bara behållare.
Och visuellt, menar jag en rektangel.
Så en nod behöver tydligen att innehålla två värden -
int själv, och sedan, underförstådda som genom den nedre halvan av rektangeln,
tillräckligt med utrymme för en int.
>> Så bara tänka framåt här, hur stor är denna nod, detta
container i fråga?
Hur många bytes för int?
Förmodligen 4, om det är samma som vanligt.
Och sedan hur många bytes för pekaren?
4.
Så här containern, eller denna nod, är kommer att vara en 8-byte struktur.
Åh, och det är ett lyckligt sammanträffande att Vi introducerade just denna föreställning om
en struct, eller en C-struktur.
>> Så jag hävdar att jag vill ta ett steg mot detta mer sofistikerade
Genomförandet av en lista med tal, en länkad lista med siffror, måste jag göra en
lite mer tänkande fram och förklarar inte bara en int, men en struct
att jag ringer, konventionellt här, nod.
Vi kan kalla det vad vi vill ha, men nod kommer att vara tematiskt i en hel
av de saker vi börja titta på nu.
>> Insidan av den noden är en int n.
Och sedan denna syntax, lite konstig vid första anblicken -
struct node * nästa.
Väl bildmässigt, vad är det?
Det är den nedre halvan av rektangeln som vi såg
bara en stund sedan.
>> Men varför säger jag struct node * i motsats till bara nod *?
För om det pekaren pekar på en annan nod, det är bara
adressen för en nod.
Det är i linje med vad vi har diskuteras om pekare hittills.
Men varför, om jag hävdar denna struktur är kallas nod, måste jag säga struct
nod inne här?
>> Exakt.
Det blir liksom en dum verklighet C. Den typedef, så att säga, har inte
hänt ännu.
C är SUPER bokstavlig.
Den läser din kod topp till botten, vänster till höger.
Och tills den träffar den semikolon på bottom line, gissa vad som inte
existera som en datatyp?
Node, citationstecken unquote nod.
>> Men på grund av den mer utförliga förklaring jag gjorde på första raden -
typedef struct node -
eftersom det kom först, innan klammerparenteser, som är ungefär som
pre-utbilda klang som du vet vad, ge mig en struct
kallas struct node.
Ärligt talat, jag gillar inte kalla saker struct node, struct node alla
hela min kod.
Men jag ska bara använda den en gång, strax innanför, så att jag kan effektivt
skapa ett slags cirkulär referens, inte en pekare till mig själv per se, men en
pekare till en annan av identisk typ.
>> Så visar det sig att på en datastruktur så här, det finns ett fåtal
verksamheter som kan vara av intresse för oss.
Vi kanske vill infoga in i en lista som denna.
Vi kanske vill ta bort från en lista som denna.
Vi kanske vill söka i listan för en värde, eller mer generellt, travers.
Och travers är bara ett finare sätt att säger start till vänster och flytta alla
vägen till höger.
>> Och varsel, även med denna något mer sofistikerade datastruktur, låt
jag föreslår att vi kan låna några av idéer de senaste två veckorna och
implementera en funktion som kallas söka så här.
Det kommer att returnera sant eller falskt, vilket indikerar, ja eller
nej, n är i listan.
Dess andra argumentet är en pekare till själva listan, så en
pekare till en nod.
>> Allt jag ska gör sedan är deklarera en temporär variabel.
Vi kallar det ptr av konvention, för pekaren.
Och jag tilldelar det lika med början av listan.
>> Och nu märker while-slingan.
Så länge pekaren är inte lika till null, jag ska kolla.
Är Pilpekaren n lika med n som antogs i?
Och vänta en minut - ny bit syntax.
Vad är pil helt plötsligt?
Yeah?
>> Exakt.
Så medan några minuter sedan, använde vi dot notation för att komma åt något
inne i en struct, om variabeln du har inte den struct
själv, men en pekare till en struct, tack och lov, en bit av syntax som
äntligen gör intuitiv känsla.
Pilen betyder att följa pekaren, som våra pilar betyder vanligen
bildmässigt, och gå på datafält inuti.
Så pil är samma sak som prick, men du använda det när du har en pekare.
>> Så bara för att sammanfatta då, om n fältet insidan av struct kallas pekaren
lika lika n, return true.
Annars denna linje här - pekare lika pekare nästa.
Så vad detta gör, varsel, är om jag är för närvarande pekar på struct
innehållande 9, och 9 är inte antalet Jag letar efter - antar jag letar
för n är lika med 50 -
Jag kommer att uppdatera min tillfälliga pekare att inte peka på denna nod
längre, men pekaren pilen bredvid, vilket kommer att sätta mig upp hit.
>> Nu insåg jag är en virvelvind introduktion.
På onsdag ska vi faktiskt göra detta med vissa människor och med lite mer
kod i en långsammare takt.
Men inse, gör vi nu våra data strukturer mer komplex så att vår
algoritmer kan få mer effektiva, vilket kommer att vara nödvändiga för
pset sex, när vi laddar in, igen, de 150.000 ord, men måste göra det
effektivt, och helst skapa en program som körs för våra användare inte
linjär, inte i n kvadrat, men i konstant tid, i den ideala.
>> Vi ses på onsdag.
>> Speak: Vid nästa CS50, David glömmer sin basfallet.
>> DAVID MALAN: Och det är hur du skickar textmeddelanden med C. Vad -
>> [Blandat TEXTMEDDELANDE Meddelandeljud]