>> [Speel van musiek]
>> DOUG LLOYD: Pointers, hier is ons.
Dit is waarskynlik gaan om wees die moeilikste onderwerp
dat ons praat oor in CS50.
En as jy gelees het niks oor pointers
voordat jy 'n bietjie kan wees intimiderend gaan in hierdie video.
Dit is waar die wysers moenie toelaat dat jy die vermoë
miskien skroef redelik sleg wanneer jy
werk met veranderlikes, en data, en veroorsaak dat jou program te crash.
Maar hulle is eintlik baie handig en hulle het ons 'n baie goeie manier toelaat
om data terug te slaag en weer tussen funksies,
dat ons anders is nie in staat om te doen.
>> En ja, wat ons regtig hier wil doen, is die trein
jy goeie wyser dissipline, so dat jy verwysings effektief kan gebruik
om jou programme wat baie beter te maak.
Soos ek gesê het wenke gee ons 'n ander manier om data tussen funksies te slaag.
Nou as jy onthou uit 'n vroeëre video, wanneer
ons praat oor veranderlike omvang, ek genoem
dat al die data wat ons slaag tussen funksies in C word geslaag deur waarde.
En ek kan nie gebruik dat termyn, wat ek daar bedoel
was dat ons verby afskrifte van data.
As ons verby 'n veranderlike om 'n funksie, ons is nie eintlik verby die veranderlike
om die funksie, reg?
Ons verby 'n afskrif van dat data om die funksie.
Die funksie doen wat dit sal en dit bereken bietjie waarde,
en miskien gebruik ons ​​wat waarde wanneer dit gee dit terug.
>> Daar was 'n uitsondering op hierdie reël van verbygaande volgens waarde
en ons sal terug na wat wat kom is 'n bietjie later in hierdie video.
As ons gebruik wenke plaas van die gebruik van veranderlikes,
of in plaas van die gebruik van die veranderlikes hulself of afskrifte van die veranderlikes,
kan ons nou verby die veranderlikes rondom tussen funksies in 'n ander manier.
Dit beteken dat as ons 'n verandering in een funksie,
dat verandering sal eintlik neem bewerkstellig in 'n ander funksie.
Weereens, dit is iets wat ons kon nie voorheen doen nie,
en as jy al ooit probeer om die ruil waarde van twee veranderlikes in 'n funksie,
jy hierdie probleem het opgemerk soort van bekruip, reg?
>> As ons wil X en Y, en ons ruil slaag hulle om 'n funksie genoem ruil,
binnekant van die funksie ruil die veranderlikes te doen ruil waardes.
Een word twee, twee word een nie, maar ons doen nie eintlik
niks verander in die oorspronklike funksie in die oproeper.
Omdat ons nie kan nie, ons is net werk met afskrifte van hulle.
Met wysers al is, ons kan eintlik slaag X en Y om 'n funksie.
Daardie funksie kan doen iets met hulle.
En dié veranderlikes waardes eintlik kan verander.
So dit is nogal 'n verandering in ons vermoë om te werk met data.
>> Voordat ons duik in wysers, ek dink dit is die moeite werd
neem 'n paar minute om gaan terug na die basiese dinge hier.
En het 'n blik op hoe rekenaar geheue werke
omdat dié twee vakke gaan om werklik redelik interafhanklik.
Soos u waarskynlik weet, op jou rekenaar stelsel
jy het 'n hardeskyf of miskien 'n vaste toestand ry,
'n soort van lêer stoor plek.
Dit is gewoonlik iewers in die omgewing van 250 GB
om dalk 'n paar van terabyte nou.
En dit is waar al jou lêers uiteindelik lewe,
selfs wanneer jou rekenaar toegesluit af, kan jy dit weer op
en jy sal vind jou lêers is daar weer wanneer jy jou stelsel herlaai.
Maar skyfaandrywers, soos 'n hardeskyf, 'n HDD, of 'n vaste toestand ry, 'n SSD,
is net stoorplek.
>> Ons kan nie eintlik enigiets doen met die data wat in die hardeskyf,
of in 'n vaste toestand ry.
Ten einde te eintlik verander data of skuif dit rond,
ons het om dit te skuif na RAM, ewetoeganklike geheue.
Nou RAM, jy het 'n baie minder in jou rekenaar.
Jy kan iewers in die het omgewing van 512 megagrepe
As jy 'n ouer rekenaar, om miskien twee, vier, agt, 16,
moontlik selfs 'n bietjie meer GB RAM.
So dit is baie kleiner, maar dit is waar al die vlugtige data bestaan.
Dit is waar ons dinge kan verander.
Maar toe ons draai ons rekenaar af, al die data in die geheue is vernietig.
>> So dit is hoekom ons nodig het om te hardeskyf het vir die meer permanente plek daarvan,
sodat dit exists- dit sou regtig sleg as elke keer as ons
draai ons rekenaar af, elke lêer in ons stelsel is uitgewis.
So werk ons ​​binnekant van RAM.
En elke keer as ons praat oor geheue, pretty much in CS50,
ons praat oor RAM, nie hardeskyf.
>> So wanneer ons dinge beweeg in die geheue, dit neem om 'n sekere bedrag van die ruimte.
Al die data tipes wat Ons het gewerk met
neem verskillende bedrae van ruimte in RAM.
So elke keer as jy 'n heelgetal te skep veranderlike, vier grepe van die geheue
tersyde gestel in RAM sodat jy kan werk met wat heelgetal.
Jy kan die heelgetal te verklaar, dit verander, gee dit
om 'n waarde 10 geïnkrementeer een, so aan en so aan.
Al wat moet gebeur in RAM, en jy kry vier grepe
om te werk met elke heelgetal wat jy skep.
>> Elke karakter wat jy skep kry een byte.
Dit is net hoeveel ruimte is wat nodig is om 'n karakter te stoor.
Elke vlot, 'n ware nommer, kry vier grepe
tensy dit 'n dubbele presisie swaai punt
nommer, wat jou toelaat om meer akkurate of meer syfers
na die desimale punt sonder verlies presisie,
wat neem agt grepe van die geheue.
Lang verlang, baie groot heelgetalle, neem ook agt grepe van die geheue.
Hoeveel grepe van die geheue moenie snare neem?
Wel, laat ons sit 'n pen in die vraag vir nou, maar ons sal terug te kom.
>> So terug na die idee van geheue as 'n groot verskeidenheid van byte-grootte selle.
Dit is regtig al wat dit is, dit is net 'n groot verskeidenheid van selle,
net soos enige ander skikking wat jy ken en te sien,
behalwe elke element is een byte breed.
En net soos 'n skikking, elke element het 'n adres.
Elke element van 'n skikking het 'n indeks, en ons
kan die indeks gebruik om te doen sogenaamde ewetoeganklike op die skikking.
Ons hoef nie te begin by die begin van die skikking,
Itereer deur elke enkele element daarvan,
om uit te vind wat ons soek.
Ons kan net sê, ek wil die te kry 15 element of die 100 element.
En jy kan net slaag in dat die getal en kry die waarde wat jy op soek is na.
>> Net so elke plek in die geheue het 'n adres.
So jou geheue krag lyk so.
Hier is 'n baie klein deel van geheue, dit is 20 grepe van die geheue.
Die eerste 20 grepe omdat my spreek daar aan die onderkant
is 0, 1, 2, 3, en so op al die pad tot 19.
En toe Ek verklaar veranderlikes en toe ek begin om te werk met hulle,
die stelsel gaan stel opsy ruimte vir my
in die geheue te werk met my veranderlikes.
So ek kan sê, char c gelyk kapitaal H. En wat gaan gebeur?
Wel, die stelsel gaan opsygesit vir my 'n byte.
In hierdie geval is dit gekies byte nommer vier, die greep by adres vier
en dit gaan na die winkel brief kapitaal H daar vir my.
As ek dan sê int spoed limiet gelyk 65, dit is
gaan ter syde te stel vier grepe van die geheue vir my.
En dit gaan om daardie behandel vier grepe as 'n eenheid
want wat ons werk met 'n heelgetal is hier.
En dit gaan om te slaan 65 daar.
>> Nou al ek is soort van jy vertel 'n bietjie van 'n leuen,
reg, want ons weet dat rekenaars te werk in binêre.
Hulle verstaan ​​nie noodwendig wat 'n kapitale H is
of wat 'n 65 is, maar hulle verstaan ​​binêre, nulle en ene.
En so eintlik wat ons stoor in daar
is nie die letter H en die nommer 65, maar eerder die binêre voorstelling
daarvan, wat lyk bietjie iets soos hierdie.
En in die besonder in die konteks van die heelgetal veranderlike,
dit gaan nie net spoeg dit in, dit is nie van plan om dit te hanteer as een vier
byte stuk noodwendig, dit is eintlik gaan
om dit te hanteer as vier een byte stukke, wat iets soos hierdie kan kyk.
En selfs dit is nie heeltemal waar nie,
as gevolg van iets genoem 'n endianness, wat ons nie
gaan kry in nou nie, maar as jy nuuskierig oor is,
jy kan lees bietjie en 'n groot endianness.
Maar ter wille van die argument, ter wille van die video,
laat ons net aanvaar dat is, in Trouens, hoe die getal 65 sou
in verteenwoordig geheue op elke stelsel,
maar dit is nie heeltemal waar nie.
>> Maar laat ons eintlik net kry ontslae te raak van al binêre geheel,
en net te dink oor as H en 65, is dit 'n baie makliker
na te dink oor dit soos dat as 'n mens.
Alle reg, sodat dit lyk ook miskien 'n bietjie random dat I've- my stelsel
het nie gee my grepe 5, 6, 7, en 8 aan die heelgetal te stoor.
Daar is 'n rede vir wat, ook, wat Ons sal nie in die oomblik, maar volstaan
om te sê dat wat die rekenaar hier
is waarskynlik 'n goeie skuif op sy deel.
Om nie gee my geheue wat noodwendig rug aan rug.
Hoewel dit gaan dit nou doen as ek wil 'n ander string te kry,
genoem van, en ek wil Lloyd daar sit.
Ek gaan nodig om een ​​te pas karakter, elke letter van wat
gaan een nodig karakter, een greep van die geheue.
So as ek Lloyd in my array kan sit soos hierdie Ek is redelik goed om te gaan, reg?
Wat ontbreek?
>> Onthou dat elke string ons werk in C eindig met backslash nul,
en ons kan nie hier uitlaat wat, hetsy.
Ons moet opsy een byte stel geheue om so ons hou dat
weet wanneer ons string geëindig het.
So weer hierdie reëling van die manier waarop dinge
verskyn in die geheue krag 'n bietjie random,
maar dit is eintlik hoe die meeste stelsels is ontwerp.
Om hulle in lyn op veelvoude vier, vir redes weer
dat ons nie nodig het om te kry in nou.
Maar dit, so dit voldoende om te sê dat na hierdie drie reëls van die kode,
dit is wat die geheue kan lyk.
As ek nodig geheue plekke 4, 8 en 12 tot my data te hou,
dit is wat my geheue kan lyk.
>> En net besonder wees pedanties hier toe
ons praat oor die geheue adresse ons gewoonlik
doen deur die hexadecimale notasie.
So waarom nie ons sit al hierdie uit desimale notasie te heksadesimale
net omdat dit is oor die algemeen hoe ons verwys na die geheue.
So in plaas van 0 tot 19, wat ons het, is nul
x zero deur nul x1 drie.
Dit is die 20 grepe van die geheue dat ons het of ons kyk na in hierdie beeld
net hier.
>> So al wat gesê word, laat stap weg van die geheue vir 'n tweede
en terug na wenke.
Hier is die belangrikste ding om te onthou
soos ons begin werk met wysers.
A wyser is niks meer as 'n adres.
Ek sal dit weer sê, want dit is wat belangrik is,
'n wyser is niks meer as 'n adres.
Pointers is adresse aan plekke in die geheue waar veranderlikes lewe.
Wetende dat dit hopelik 'n bietjie makliker om te werk met hulle.
Nog 'n ding wat ek graag om te doen is om soort te hê
diagramme visueel verteenwoordig wat is gebeur met verskeie reëls van die kode.
En ons sal dit 'n paar te doen keer in wysers,
en wanneer ons praat oor dinamiese geheuetoekenning as well.
Want ek dink dat hierdie diagramme kan veral nuttig.
>> So as ek sê byvoorbeeld int k in my kode, wat gebeur?
Wel, wat is basies gebeur is Ek kry geheue opsy gesit vir my,
maar ek het nie eens wil dink oor dit so, ek
wil om te dink oor dit soos 'n boks.
Ek het 'n boks en dit is gekleurde groen, want ek
kan heelgetalle in 'n groen bokse.
As dit is 'n karakter wat ek dalk 'n blou boks.
Maar Ek sê altyd, as ek skep 'n boks wat heelgetalle kan hou
dat boks is groen gekleur.
En ek neem 'n permanente merker en ek skryf k aan die kant van dit.
So ek het 'n boks genoem k, waarin ek heelgetalle kan sit.
So as ek sê int k, dit is wat gebeur in my kop.
As ek sê k gelyk vyf wat doen ek?
Wel, ek is om vyf in die boks, reg.
Dit is redelik eenvoudig, as Ek sê int k, skep 'n boks genoem k.
As ek sê k gelyk 5, opgestel: vyf in die boks.
Hopelik is dit nie te veel van 'n sprong.
Hier is waar dinge gaan 'n bietjie interessante al is.
As ek sê int * PK, goed, selfs as ek dit nie doen nie weet wat dit beteken nie noodwendig,
dit is duidelik het iets te doen het met 'n heelgetal.
So ek gaan inkleur hierdie boks groen-ish,
Ek weet dit het iets te doen het met 'n heelgetal,
maar dit is nie 'n heelgetal self, want dit is 'n int ster.
Daar is iets effens verskillende daaroor.
So betrokke 'n heelgetal se maar andersins is dit
nie veel verskillend van wat ons praat.
Dit is 'n boks, sy het 'n etiket, dit dra 'n etiket PK,
en dit is in staat om van hou int sterre, wat ook al dit is.
Hulle het iets te doen met heelgetalle, duidelik.
Hier is die laaste linie al is.
As ek sê PK = & k, whoa, wat nou net gebeur het, reg?
So hierdie ewekansige getal, skynbaar ewekansige nommer, kry gegooi word in die boks.
Alle dit is, is pk kry die adres van k.
So ek vas waar k woon in die geheue, sy toespraak het die adres van sy grepe.
Al wat ek doen is ek sê wat waarde is wat ek gaan
binnekant van my boks genoem PK om te sit.
En omdat hierdie dinge wysers, en omdat soek
op 'n string soos nul x agt nul c sewe vier agt
twee nul is waarskynlik nie baie betekenisvol.
Wanneer ons in die algemeen te visualiseer wysers, ons eintlik so doen soos wenke.
PK gee ons die inligting ons nodig het om te vind k in die geheue.
So basies PK het 'n pyl in.
En as ons loop die lengte van daardie pyl, dink
dit is iets wat jy kan loop, as ons loop langs die lengte van die pyl,
Op die heel punt van daardie pyl, ons sal die plek in die geheue vind
waar k woon.
En dit is werklik belangrik want as ons weet waar k woon,
ons kan begin om te werk met die data binnekant van die geheue plek.
Hoewel ons kry 'n Teeny bietjie voor onsself vir nou.
>> So, wat is 'n wyser?
A wyser is 'n data-item wie waarde is 'n geheue adres.
Dit was dit nul x agt nul dinge aangaan, dit was 'n geheue adres.
Dit was 'n plek in die geheue.
En die tipe van 'n wyser beskryf die soort
van data wat jy kry by dat die geheue adres.
So is daar die int ster deel reg.
As ek volg dat die pyl, dit is gaan my lei tot 'n plek.
En dat die plek, wat ek daar sal vind in my voorbeeld,
is 'n groen gekleurde boks.
Dit is 'n heelgetal is, dit is wat ek sal vind as ek gaan na daardie adres.
Die data tipe van 'n wyser beskryf wat
jy sal vind op daardie geheue adres.
So hier is die regtig cool ding al is.
Pointers ons toelaat om te slaag veranderlikes tussen funksies.
En eintlik slaag veranderlikes en nie afskrifte van hulle slaag.
Want as ons weet presies waar in die geheue van 'n veranderlike te vind,
Ons het nie nodig om 'n kopie van maak dit kan ons net gaan na die plek
en werk met daardie veranderlike.
So in wese pointers soort maak van 'n rekenaar omgewing
'n baie meer soos die werklike wêreld, reg.
>> So hier is 'n analogie.
Kom ons sê dat ek 'n notebook, reg, en dit is vol notas.
En ek wil hê jy moet dit verander.
Jy is 'n funksie wat updates notas, reg.
Op die pad het ons nie dusver werk, wat
gebeur is dat jy sal my notebook te neem, jy sal gaan na die kopie winkel,
jy sal 'n kopie van Xerox maak elke bladsy van die notaboek.
Jy sal my notebook terug te verlaat op my lessenaar wanneer jy klaar is,
jy gaan kruis uit dinge in my notebook wat is uit datum of verkeerd,
en dan sal jy weer slaag om vir my die stapel van Xerox bladsye
dit is 'n replika van my notaboek met die veranderinge wat jy gemaak het om dit te.
En op daardie punt, is dit vir my as die roeping funksie, soos die oproeper,
om te besluit om jou notas te neem en integreer dit weer terug in my notaboek.
So is daar 'n klomp van stappe hier betrokke is, reg.
Soos sou dit nie beter wees as ek net sê, hey, jy kan
werk my notebook vir my hand wat jy my notebook,
en jy dinge te neem en hulle letterlik kruis uit
en werk my notas in my notaboek.
En dan gee my notebook rug.
Dit is soort van wat wysers ons toelaat om te doen,
hulle maak hierdie omgewing 'n baie meer soos hoe ons in werklikheid funksioneer.
>> Alle reg, sodat dit is wat 'n wyser is, laat ons praat
oor hoe wysers werk in C en hoe kan ons begin om met hulle te werk.
So daar is 'n baie eenvoudige wyser in C genoem null pointer.
Die nul wyser punte niks.
Dit is waarskynlik lyk soos dit is eintlik nie 'n baie nuttige ding,
maar soos ons sal sien 'n bietjie later, die feit
dat dit null pointer bestaan eintlik werklik kan handig te pas kom.
En wanneer jy 'n wyser skep, en jy nie die waarde daarvan onmiddellik ontruim- stel
'n voorbeeld van die opstel onmiddellik sy waarde
sal 'n paar skyfies terug waar ek gesê PK gelyk & k,
pk kry posadres k, soos ons sal sien wat dit beteken,
ons sal sien hoe om kode wat shortly- as ons nie sy waarde om iets te stel
onmiddellik betekenisvolle, Jy moet altyd
stel jou muis om te wys op null.
Jy moet sit dit om te verwys na niks.
>> Dit is baie anders as net verlaat die waarde soos dit is
en dan waarby 'n wyser en net die veronderstelling
dit is null want dit is selde waar.
So jy moet altyd gestel die waarde van 'n wyser
om null as jy nie die waarde daarvan te stel om iets betekenisvol onmiddellik.
Jy kan kyk of waarde wat 'n wyser se is van nul deur die operateur gelykheid
(==), Net soos jy vergelyk enige heelgetal waardes of karakter waardes behulp (==)
ook.
Dit is 'n spesiale soort van konstante waarde wat jy kan gebruik om te toets.
So dit was 'n baie eenvoudige wyser, die nul wyser.
Nog 'n manier om te skep 'n wyser is om te onttrek
die adres van 'n veranderlike jy reeds gemaak het,
en jy doen dit met behulp van die & operateur adres onttrekking.
Wat ons reeds voorheen gesien in die eerste diagram voorbeeld wat ek het.
So as x is 'n veranderlike wat ons het reeds geskep tipe integer,
dan & x is 'n verwysing na 'n heelgetal.
& x is- onthou & gaan onttrek die adres van die ding aan die regterkant.
En omdat 'n wyser is net 'n adres, as & x is 'n verwysing na 'n heelgetal
waarvan die waarde is waar in die geheue x lewens.
Dit is adres x se.
So & x is die adres van x.
Kom ons neem 'n stap hierdie verder en verbind om iets
Ek verwys na 'n vorige video.
As arr is 'n verskeidenheid van die dubbelspel, dan & arr vierkante bracket i is 'n wyser
om 'n dubbele.
OK.
skik vierkante bracket Ek, as arr is 'n verskeidenheid van die dubbelspel,
dan skik vierkante bracket i is die i-de element van daardie skikking,
en & skik vierkante bracket i is waar in geheue van die i-de element van arr bestaan.
>> So, wat is die implikasie hier?
'N skikkings naam, is die implikasie van hierdie hele ding,
is dat die naam 'n skikking is eintlik self 'n wyser.
Jy het gewerk met wysers al langs
elke keer dat jy 'n verskeidenheid gebruik het.
Onthou uit die voorbeeld op veranderlike omvang,
naby die einde van die video wat ek aanbied 'n voorbeeld waar ons het 'n funksie
genoem stel en 'n int funksie genoem stel skikking.
En jou uitdaging om te bepaal of nie, of wat die
waardes wat ons gedruk die einde van die funksie,
aan die einde van die hoofprogram.
>> As jy onthou van daardie voorbeeld of as jy die video gekyk het,
jy weet dat wanneer die oproep om jou- stel int effektief doen niks.
Maar die oproep om 'n skikking nie.
En ek soort van glansende oor waarom dit was die geval by die tyd.
Ek het net gesê, goed dit is 'n skikking, dit is spesiale, jy weet, daar is 'n rede.
Die rede hiervoor is dat 'n skikking se naam is regtig net 'n wyser,
en daar is hierdie spesiale sintaksis bracket vierkant wat
maak dinge 'n baie lekkerder om mee te werk.
En hulle maak die idee van 'n aanwijzer 'n baie minder intimiderend,
en dit is hoekom hulle is soort van wat in daardie manier.
Maar regtig skikkings is net wenke.
En dit is hoekom wanneer ons 'n verandering aan die skikking,
wanneer ons verby 'n verskeidenheid as 'n parameter om 'n funksie of as 'n argument
om 'n funksie, die inhoud van die skikking in beide die callee eintlik verander
en in die oproeper.
Wat vir elke ander soort veranderlike wat ons gesien het, was nie die geval nie.
So dit is net iets om in te hou gedagte wanneer jy werk met wysers,
is dat die naam van 'n verskeidenheid eintlik 'n wyser
om die eerste element van daardie skikking.
>> OK so nou het ons al hierdie feite, laat ons gaan hou, reg.
Hoekom moet ons omgee waar iets woon.
Wel soos ek gesê het, dit is redelik nuttig om te weet waar iets woon
sodat jy kan gaan en dit verander.
Werk met dit en eintlik die ding wat jy
wil doen om daardie veranderlike in werking tree, en nie in werking op 'n paar afskrif daarvan.
Dit is die sogenaamde dereferencing.
Ons gaan na die verwysing en ons die waarde te verander is daar.
So as ons 'n wyser en dit genoem rekenaar, en dit dui op 'n karakter,
dan kan ons sê * rekenaar en * PC is die naam van wat ons sal vind as ons gaan
na die adres rekenaar.
Wat ons sal daar vind, is 'n karakter en * PC is hoe ons verwys na die data op daardie
plek.
Sodat ons kan sê iets soos * PC = D of iets soos dit,
en dit beteken dat alles wat was op geheue adres rekenaar,
watter karakter was voorheen daar is nou D, as ons sê * PC = D.
>> So hier gaan ons weer met sommige weird C goed, reg.
So het ons voorheen gesien * as een of ander manier deel van die tipe data,
en nou is dit wat gebruik word in 'n effens ander konteks
om toegang tot die data op 'n plek.
Ek weet dit is 'n bietjie verwarrend en dit is eintlik deel van hierdie hele
soos, hoekom pointers hierdie mitologie rondom hulle as so kompleks,
is 'n soort van 'n syntax probleem eerlik.
Maar * word gebruik in beide kontekste, sowel as deel van die tik naam,
en ons sal sien 'n bietjie later iets anders ook.
En nou is die dereference operateur.
So dit gaan na die verwysing, dit toegang tot die data
op die ligging van die wyser, en kan jy dit manipuleer wil.
>> Nou is dit baie soortgelyk aan besoek jou naaste, reg.
As jy weet wat jou naaste woon, is jy
nie uithang met jou naaste.
Jy weet jy toevallig weet waar hulle woon,
maar dit beteken nie dat deur hoofde van 'dat kennis
jy interaksie met hulle.
As jy wil om te kommunikeer met hulle, jy het om te gaan na hul huis,
jy het om te gaan na waar hulle woon.
En as jy dit doen, dan kan jy interaksie
met hulle net soos jy graag wil hê om.
En insgelyks met veranderlikes, wat jy nodig het om te gaan na hul adres
as jy wil hê hulle interaksie, jy kan nie net weet wat die adres.
En die manier waarop jy na die adres om te gebruik *, die dereference operateur.
Wat dink jy gebeur As ons probeer dereference
'n wyser waarvan die waarde is van nul?
Onthou dat die nul wyser wys niks.
So as jy probeer en dereference niks of gaan na 'n adres niks
wat dink jy gebeur?
Wel, as jy geraai segmentering fout, sou jy reg wees.
As jy probeer en dereference 'n null pointer,
jy aan 'n segmentering fout. Maar wag,
het ek nie sê vir julle, As jy nie gaan
om jou waarde van jou stel wyser na iets sinvol,
jy moet stel om null?
Ek het en eintlik die segmentering skuld is 'n soort van 'n goeie gedrag.
>> Het jy al ooit 'n veranderlike en verklaar die waarde nie onmiddellik opgedra?
Sodat jy net int x sê; jy doen nie dit eintlik wys enigiets
en dan later in jou kode, jy druk die waarde van x,
met nog nie opgedra dit tot niks.
Dikwels jy kry nul, maar soms jy
kan kry 'n paar random nommer, en jy het geen idee waar dit vandaan kom.
Net so kan dinge gebeur met wysers.
Wanneer jy 'n wyser te verklaar int * PK byvoorbeeld
en jy dit nie te wys aan 'n waarde, jy vier grepe vir die geheue.
Wat ook al vier grepe van geheue Die stelsel kan
vind dat 'n betekenisvolle waarde het.
En daar kon gewees het iets wat reeds daar dat
is nie meer nodig is deur 'n ander funksie, so jy moet net
watter data daar was.
>> Wat gebeur as jy probeer om te doen dereference sommige adres wat u don't- daar was
reeds grepe en inligting in daar, dis nou in jou wyser.
As jy probeer en dereference dat pointer, jy dalk geknoei met 'n paar geheue
dat jy nie van plan om te mors met dit alles.
En in die feit dat jy kan doen iets wat regtig verwoestende,
soos breek 'n ander program, of breek 'n ander funksie,
of iets kwaadwillige doen jy het nie van plan om op alles te doen.
En so dit is waarom dit is eintlik 'n goeie idee
om jou wenke te stel om null as jy hulle nie ingestel om iets betekenisvol.
Dit is waarskynlik beter by die einde van die dag vir jou program
om te crash dan vir dit om te doen iets wat skroewe
'n ander program of 'n ander funksie.
Dit gedrag is waarskynlik selfs minder ideale as net gekraak.
En so dit is waarom dit is eintlik 'n goeie gewoonte
om in jou pointers stel om null as jy dit nie stel
om 'n betekenisvolle waarde onmiddellik, 'n waarde dat jy weet
en dat jy veilig kan die dereference.
>> So laat kom nou terug en neem 'n blik by die algehele sintaksis van die situasie.
As ek sê int * p ;, wat het ek nou net gedoen?
Wat ek gedoen het, is dit.
Ek weet dat die waarde van p is 'n adres want al pointers is net
adresse.
Ek kan dereference p die gebruik van die * operateur.
In hierdie konteks hier, op die heel top onthou die * is deel van die tipe.
Int * is die tipe data.
Maar ek kan dereference p die gebruik van die * operateur,
en as ek dit doen, as ek gaan na daardie adres, wat sal ek vind by daardie adres?
Ek sal 'n heelgetal te vind.
So int * p is basies sê, p is 'n adres.
Ek kan dereference p en as Ek doen, sal ek 'n heelgetal te vind
op daardie geheue plek.
>> OK, so ek het gesê daar was 'n ander irriterende ding met sterre
en hier is waar dat irriterende ding met sterre is.
Het jy al ooit probeer om te verklaar verskeie veranderlikes van dieselfde soort
op dieselfde lyn van die kode?
So vir 'n tweede, voorgee dat die lyn, die kode Ek het eintlik daar in die groen
is nie daar nie en dit net sê int x, y, z ;.
Wat sou doen is eintlik skep drie heelgetal veranderlikes vir jou,
een wat geroep is x, een wat geroep is y, en een wat geroep z.
Dit is 'n manier om dit te doen sonder om te verdeel op drie lyne.
>> Hier is waar sterre kry irriterende weer al is,
omdat die * is eintlik deel van beide die naam en deel tipe
van die veranderlike naam.
En so as ek sê int * px, py, PZ, wat ek eintlik kry is 'n verwysing na 'n heelgetal
genoem px en twee heelgetalle, py en PZ.
En dit is waarskynlik nie wat ons wil hê, is dit nie goed nie.
>> So as ek wil om veelvuldige verwysings te skep op dieselfde lyn, van dieselfde soort,
en die sterre, wat ek werklik nodig om te doen is om te sê int * pa, * pb, * rekenaar.
Nou net gesê dat hy en nou vertel julle dit,
jy sal waarskynlik nooit dit doen.
En dit is waarskynlik 'n goeie ding eerlik, omdat jy dalk per ongeluk
laat 'n ster, iets soos dit.
Dit is waarskynlik die beste om miskien verklaar wenke oor individuele lyne,
maar dit is net 'n ander een van daardie irriterende sintaksis
dinge met sterre wat wysers so moeilik om mee te werk.
Want dit is net die sintaktiese gemors wat jy het om deur te werk.
Met die praktyk is dit nie regtig tweede natuur geword.
Ek foute maak steeds met dit steeds ná ontwikkeling vir 10 jaar,
so moenie ontsteld wees as daar iets gebeur vir julle, dit is redelik algemeen eerlik.
Dit is regtig soort 'n fout van die sintaksis.
>> OK, so ek soort van belowe dat ons sal weer
die konsep van hoe groot is 'n string.
Wel, as ek jou vertel dat 'n string, het ons regtig soort
jok vir julle die hele tyd.
Daar is geen tipe data genoem string, en in werklikheid Ek
het dit al in een van ons vroegste video's op tipes data,
dat string was 'n tipe data wat is geskep vir jou in CS50.h.
Jy het om te include CS50.h om dit te gebruik.
>> Wel string is regtig net 'n alias vir iets
genoem die char *, 'n wyser na 'n karakter.
Wel wysers, onthou, is net aanspreek.
So, wat is die grootte in grepe van 'n string?
Wel dit is vier of agt.
En die rede waarom ek sê vier of agt, is omdat dit eintlik
hang af van die stelsel, As jy ' CS50 ide, char * is die grootte van 'n kar
* Is agt, dit is 'n 64-bis-stelsel.
Elke adres in die geheue is 64 stukkies lank.
As jy CS50 toestel of die gebruik van enige 32-bit masjien,
en jy het die term 32-bit gehoor masjien, wat is 'n 32-bit masjien?
Wel dit beteken net dat elke adres in die geheue is 32 stukkies lank.
En so 32 stukkies vier grepe.
So 'n char * is vier of agt grepe afhangende op jou stelsel.
En inderdaad enige data tipes, en 'n verwysing na enige data
tik, aangesien alle aanduidings is net adresse, vier of agt grepe.
So laat heroorweeg hierdie diagram en laat ons die gevolgtrekking
hierdie video met 'n bietjie oefening hier.
So hier is die diagram ons opgehou het met aan die begin van die video.
So wat gebeur nou as ek sê * PK = 35?
So wat beteken dit as ek sê, * PK = 35?
Neem 'n tweede.
* PK.
In konteks hier, * is dereference operateur.
So wanneer die dereference operateur gebruik word,
ons gaan na die adres daarop om deur PK, en ons verander wat ons vind.
So * PK = 35 effektief doen dit om die prentjie.
So dit is basies sintakties identies aan dat hy gesê k = 35.
>> Nog een.
As ek sê int m, Ek skep 'n nuwe veranderlike genoem m.
N nuwe boks, dit is 'n groen boks omdat dit gaan om 'n heelgetal te hou,
en dit is gemerk m.
As ek sê m = 4, sit ek 'n heelgetal in daardie boks.
As sê PK = & m, hoe hierdie diagram verandering?
PK = & m, het jy onthou wat die & Operateur doen of genoem word?
Onthou dat sommige & veranderlike naam is die adres van 'n veranderlike naam.
So wat ons sê is pk kry die adres van m.
En so effektief wat gebeur die diagram is wat nie meer punte PK
om k, maar punte te m.
>> Weereens wenke is baie moeilik om te werk met
en hulle neem 'n baie praktyk nie, maar omdat
van hul vermoë om jou te laat om data tussen funksies slaag
en eintlik diegene veranderinge in werking tree,
kry jou kop rond is baie belangrik.
Dit is waarskynlik die mees ingewikkelde onderwerp bespreek in CS50,
maar die waarde wat u kry van die gebruik wenke
veel groter as die komplikasies wat kom uit leer hulle.
So ek wens jou die beste van Sterkte leer oor wenke.
Ek is Doug Lloyd, dit is CS50.