[Powered by Google Translate] [Payo]
[Rob Bowden] [Harvard University]
[Ito ay CS50] [CS50.TV]
>> Natin makipag-usap tungkol sa mga payo.
Hanggang ngayon, laging kami lang tinutukoy sa mga bagay sa memory tahasang sa pamamagitan ng pangalan.
Namin ang sinabi n int = 42; at pagkatapos kapag gusto naming gamitin ang variable n,
namin lamang tumawag ito sa pamamagitan ng pangalan namin ibinigay ito sa pamamagitan ng pagsusulat ng isang bagay tulad ng n * 2.
Ngunit variable na dapat nakatira sa isang lugar sa memorya.
Kapag nais mong gamitin ang halaga na ay kasalukuyang naka-imbak sa loob n,
o i-update ang halaga na n ay may hawak,
ang iyong programa ay kailangang malaman kung saan sa memory upang tumingin para sa n.
Saan sa memory ng variable buhay ay tinatawag na ang address nito.
Ito ay tulad ng isang address ng bahay.
Maaari kong makahanap ng bahay ng isang tao hangga't alam ko ang kanilang home address,
at isang computer program ay maaaring makahanap ng isang variable hangga't alam nito memory address.
Anong mga payo magbigay ay isang paraan ng direktang pagharap sa mga address na ito ng memorya.
>> Isang maraming ng kapangyarihan sa C ay mula sa pagiging magagawang upang manipulahin ang memory tulad nito.
Ngunit may dakilang kapangyarihan pagdating mahusay na responsibilidad.
Pointer ay maaaring gamitin dangerously sapat na ng maraming mga wika ng programming
itago ang kabuuan ng mga payo.
Kaya, kung bakit ang C bigyan kami ng payo pagkatapos?
Tulad ng alam mo, argumento sa isang function C
palaging kinopya sa mga parameter ng function na.
Kaya, ang pagtawag ng isang bagay tulad makipagpalitan sa ilang mga variable x at y
hindi maaaring Interchange ang mga halaga ng x at y sa pagtawag sa function na,
kahit na maaaring maging madaling-magamit na.
Bilang makikita namin makita mamaya, muling pagsusulat makipagpalitan sa tumagal ng mga payo sa lokasyon na nangangailangan na swapped
ay nagbibigay-daan sa ito upang makaapekto sa variable nito tumatawag.
>> Lakad natin sa pamamagitan ng ganap na tapat Halimbawa ng kung ano ang payo ay maaaring gawin.
Sabihin nating mayroon kaming int n = 4; at int * pointer_to_n = & n.
Whoa! Isang bit ng bagong syntax upang masakop ang.
Una, sabihin bigyang-kahulugan ang mga ito at n.
Tandaan na ang lahat sa memory ang ilang address.
Ampersand ay tinatawag na ang "address ng" operator.
Kaya, & n ay tumutukoy sa address sa memorya kung saan n ay naka-imbak.
Ngayon, kami ay pag-iimbak sa address na ito sa isang bagong variable, pointer_to_n.
Ano ang uri ng mga bagong variable na ito?
Asterisk ay isang bahagi ng uri ng variable,
at kami na basahin ang mga uri ng int *.
Int * ay nangangahulugan na pointer_to_n ay isang variable na nag-iimbak ng address ng isang integer.
Alam namin na & n ay isang int * dahil n ay isang integer, at kami ay paglalaan ng address ng n.
Int * ay isang halimbawa ng isang uri ng pointer.
Sa lalong madaling simulan mo ang nakakakita ng mga asterisk sa uri,
alam mo na ikaw ay pagharap sa mga payo.
Lamang tulad ng maaari naming ipinapahayag sa isang variable ng int x at magpasinda y,
maaari naming sabihin int * z at magpasinda * w.
Int * at magpasinda * bago lang na uri para sa amin upang gamitin.
Ang lokasyon ng * pumunta saanman bago ang pangalan ng variable.
Kaya, ang parehong int * pointer_to_n - na may * na susunod sa int, mayroon kaming dito -
at int * pointer_to_n gamit ang * sa tabi pointer_to_n wasto.
Ngunit dito, makikita ko bang ilagay ang * sa tabi ng int.
Hindi mahalaga kung saan gusto mo, maging pare-pareho lamang.
>> Natin gumuhit ng diagram para sa.
Muna namin ang variable n, na makikita namin gumuhit bilang isang maliit na kahon ng memorya.
Para sa halimbawang ito, sabihin natin na ang kahon na ito ay matatagpuan sa address 100.
Loob ng ang kahon na ito, kami ay ang pag-iimbak ang halaga 4.
Ngayon, mayroon kaming isang bagong variable, pointer_to_n.
Ito ay may sarili nitong box sa memorya,
na gagamitin namin sabihin sa address 200.
Loob ng ang kahon na ito, kami ay itinatago ang address ng n,
kung saan bago namin sinabi ay 100.
Madalas sa diagram, makikita mo ito ipinapakita bilang isang literal na arrow
umaalis sa pointer_to_n box na tumuturo sa box na nag-iimbak n.
Ngayon, kung ano ang maaari naming aktwal na gawin sa pointer_to_n?
Well, kung sinasabi namin ang isang bagay tulad ng * pointer_to_n = 8, ito ay isang ibang paggamit para sa asterisk
na ganap na nakahiwalay mula sa paggamit ng asterisk sa deklarasyon ng variable
ng isang uri ng pointer.
Dito, ang asterisk ay tinatawag na dereference operator.
Sa aming diagram, ano * pointer_to_n = 8 paraan,
pumunta sa ang kahon na naglalaman pointer_to_n, sundin ang mga arrow,
at pagkatapos ay italaga sa ang kahon sa dulo ng arrow ang halaga 8.
Nangangahulugan ito na matapos ang linyang ito, kung sinusubukan naming gamitin n ito ang halaga 8.
'Pointer' Ang salita ay ginagamit sa maraming mga iba't ibang konteksto.
Dito, susubukan naming maging pare-pareho.
Isang pointer uri ay isang bagay tulad ng int *.
Sa video na ito, ang isang pointer ay ay lamang ginagamit sa ibig sabihin ng isang halaga sa isang uri ng pointer,
tulad pointer_to_n na may * uri int.
Kahit saan ginamit namin lamang sabihin ng n, maaari namin ngayon sa halip sabihin * pointer_to_n,
at ang lahat ay gagana lamang pati na rin.
>> Lakad natin sa pamamagitan ng isa pang simpleng halimbawa.
Sabihin nating mayroon kaming int n = 14; int * pointer = &n; n + +, at (* pointer) + +.
Ang unang linya ay lumilikha ng isang bagong kahon sa memory na may label n.
Oras na ito, hindi namin label ang kahon na may isang tahasang address, ngunit pa rin ito ay may isa.
Sa loob ng kahon sa, kami ay itinatago ang bilang 14.
Ang susunod na linya ay lumilikha ng isang pangalawang kahon na may label pointer.
At sa loob ng kahon na ito, kami ay pag-iimbak ng isang pointer sa kahon na may label n.
Kaya, sabihin gumuhit ang arrow mula sa pointer sa n.
Ngayon, n + + palugit ang halaga sa kahon na may label na n,
kaya namin pumunta 14-15.
Panghuli, (* pointer) + + napupunta sa kahon na may label ng pointer,
dereferences halaga sa kahon, na nangangahulugan na sundin ang mga arrow sa kung saan ito POINTS,
at palugit ang halaga na nakaimbak doon, kaya kami 15-16.
At na ito.
N ngayon iniimbak ang numero 16 matapos dalawang beses na incremented -
sabay-sabay nang direkta sa pamamagitan ng paggamit ng ang mga variable na n pangalan, at ang iba pa sa pamamagitan ng pointer_to_n.
>> Mabilis na pagsusulit. Ano sa tingin ninyo ang ibig sabihin nito kung sinusubukan kong sabihin na ang isang bagay tulad && n?
Well, ipaalam sa muling isulat ito bilang & (& n) na accomplishes ang parehong bagay.
Ang (& n) nagbabalik ang address ng variable n sa memory.
Ngunit pagkatapos pagkatapos panlabas ampersand ay sinusubukan upang ibalik ang address ng address.
Iyon ay tulad ng sinusubukang gawin & 2.
Hindi ito magkaroon ng kahulugan upang makuha ang address ng ilan lang bilang
dahil hindi ito naka-imbak sa memorya.
Paggamit ng dalawang ampersand sa isang hilera ay hindi kailanman ang karapatan na ideya.
Ngunit ngayon, ano ang ibig sabihin kung sinusubukan kong sabihin na ang int ** double_pointer = & pointer?
Ngayon, ako ang paglikha ng isang bagong kahon na may label na double_pointer,
at sa loob ng kahon na ako sa pag-iimbak ng address ng pointer,
na nangangahulugan ko gumuhit ng isang arrow mula sa double_pointer kahon sa kahon ng pointer.
Pansinin ang uri ng double_pointer, isang int **.
N ay isang integer, pointer na naka-imbak na ang address ng n, at kaya may * uri int.
Ngayon, nag-iimbak ng double_pointer ang address ng pointer, kaya ito ay may uri int **.
>> Kaya, kung ano ang sa tingin namin Nangangahulugan itong -
** Double_pointer = 23?
Pansinin na ako ngayon dereferencing dalawang beses.
Sundin lang ang mga box-at-arrow diagram na namin ang set up.
Una, pumunta kami sa kahon na may label na double_pointer.
Ang unang * ibig sabihin sundin ang mga arrow sa isang beses.
Ngayon, hindi namin sa kahon na may label na pointer.
Ang ikalawang bituin na sundin ang mga arrow muli,
at ngayon hindi namin sa kahon na may label na n, at namin itakda ang halaga ng ang kahon na ito sa 23.
Pansinin na ang dereference at address ng 'operator mga inverses ng isa't isa.
Ito ay nagbibigay-daan sa akin upang gawin ang isang bagay tulad ng * & * & n = 42.
Habang ito gumagana, hindi mo dapat gawin ang isang bagay tulad nito sa kasanayan.
Ano kami aktwal na ginagawa dito?
Ang unang ampersand grabs ang address ng variable n.
Pagkatapos, mayroon kaming dereference operator, na nangangahulugan na namin ay pagpunta sa address na iyon sa memorya,
kaya hindi namin pabalik sa n.
Ngayon, grab namin ang mga address ng n muli at agad dereference,
kaya hindi namin pabalik sa n at tindahan 42.
Kaya, ang bawat pares ng * & lang magkakansela out.
>> May ay isang espesyal na pointer na tinatawag na ang null pointer.
Ito ay isang pointer na hindi namin dapat dereference.
Tulad pointer ay mahalaga sapagkat ito ay nagbibigay sa amin ng isang paraan upang makilala sa pagitan ng
isang pointer na dapat at hindi dapat dereferenced.
Kung sinubukan mong mag-dereference null pointer,
karaniwang iyong programa ay pag-crash ng may isang segmentation fault,
kung saan maaaring nakakita ka bago.
Kaya, sabihin nating mayroon kaming ang code int * x = null; * x = 4.
Sa halimbawang ito, maaaring mukhang halata na namin ang paggawa ng isang bagay masamang,
ngunit tandaan na null maaaring talagang maging isang halaga na ibinalik mula sa isang tawag sa isang function
tulad ng malloc, kung malloc hindi maglaan ang memory na hiniling ng user.
Para sa kadahilanang ito, kung sa halip namin itakda ang halaga ng x mula sa isang tawag sa malloc,
sa int * x = malloc (sizeof (int)), pagkatapos ay dapat namin laging tahasang suriin
upang makita kung null ay ibinalik.
Kung (x == null); / / uhoh! return; pa ang maaari naming magpatuloy at sabihin * x = 4.
>> Kaya, muli, kung bakit dapat namin gamitin ang mga payo?
Tingnan natin sa isang halimbawa ng isang programa na kung saan kailangan naming gamitin ang mga payo -
isang simpleng makipagpalitan ng function na.
Ipagpalagay natin na mayroon akong dalawang integer, int x = 4, at int y = 15;
at gusto kong magsulat ng isang function na tinatawag na makipagpalitan na maaari kong gamitin tulad ng sa gayon: makipagpalitan ng (x, y).
Matapos ang linyang ito, ang mga halaga sa loob ng variable x ay dapat na 15,
at ang halaga sa loob variable y dapat na 4.
Ang mga halaga sa loob ng x at y ay swapped.
Walang mga payo, maaari naming subukan ang isang bagay tulad ng walang bisa makipagpalitan (int a, int b);
int tmp = b; b = isang; a = tmp.
Ngunit, huwag mong mapansin ang problema na ito?
Tandaan na ang halaga na naka-imbak sa variable lamang ng isang kopya ng ang halaga ng x,
at ang halaga sa b kinopya mula sa y.
Anumang pagbabago na ginawa sa isang at b ay hindi makikita sa x at y.
Kaya, habang ang halaga ng isang at b ay tama swapped,
x at y na hindi nagbago sa lahat.
Ngayon, sabihin baguhin ang makipagpalitan ng function na upang na ang argumento
mga payo sa mga variable na ito ay dapat swap, i kaya:
makipagpalitan ng void (int * a, int * b); int tmp = * b; * b = * a; * a = tmp.
Tandaan na ang swaps argumento ngayon payo,
at kaya kailangan namin upang pumasa ang address ng x at y sa tawag sa swap, i kaya:
swap (& x, at y).
Ito ngayon tama swaps ang mga halaga ng x at y.
>> Natin gumuhit ng kahon-at-arrow diagram upang makita kung bakit ito gumagana.
Magsisimula kami sa aming dalawang mga kahon sa memory, x at y.
Sa loob ng box para sa x ay ang bilang 4, at sa loob ng box para sa y mayroon kaming 15.
Ngayon, sa loob ng pagtawag sa function na makipagpalitan ng, mayroon kaming dalawang mas maraming mga kahon
para sa argumento at b;
ng mga puntos sa ang kahon para sa x, at b puntos sa box para sa y.
Ang isang bagong kahon ay nilikha para sa variable na tmp,
at sa loob nito imbak ng namin ang resulta ng dereferencing b,
na nangangahulugan na 'sundin ang mga arrow mula sa kahon na may label na b.'
Kaya, iniimbak namin ang 15 sa loob ng tmp.
Pagkatapos, sundin namin ang arrow sa b at mag-store dito ang resulta ng dereferencing ng,
na ang halaga 4.
Panghuli, sundin namin ang mga arrow sa at tindahan kung ano ang kasalukuyang loob ng tmp, na 15.
Pansinin na ang mga kahon na may label na x at y tama swapped halaga.
>> Sa sandaling aming matuto nang higit pa tungkol sa malloc at dynamic memory pamamahala,
makikita namin makita na wala kaming pagpipilian ngunit upang gamitin ang mga payo.
Naglalakad sa pamamagitan ng kahon-at-arrow diagram para sa anumang programa
ay maaaring makatulong sa iyo na malaman kung ano ang programa ay talagang ginagawa.
>> Ang pangalan ko ay Rob Bowden, at ito ay CS50.
[CS50.TV]
>> Ito ay isang ibang paggamit para sa asterisk - bleah, mapoot ko ang salitang iyon.
Kahit saan ginamit namin lamang sabihin ng n, maaari naming ngayon sabihin pointer_to_n - walang Hindi mai ka - * pointer_to_n.