[Powered by Google Translate] [Setmana 4, continuació] [David J. Malan - Harvard University] [Aquesta és CS50. - CS50.TV] Això és CS50, i aquest és el cap de setmana 4. Així que una bona notícia i una mala notícia. No conferència el dilluns, cap problema fixat la setmana. [Estudiants victorejant] No t'agradarà a on va això. Però tenim aquest lloc el proper dimecres, i també hi ha un programa d'estudis per la conferència divendres divendres perquè puguem mantenir el rumb. Però tot serà filmat, com de costum, pel que no es preocupés. I pel que fa quiz 0 ho que farem a finals de la setmana es publiqui cs50.net pàgina d'inici del curs una explicació de quin tipus d'expectatives que vostè ha de tenir quan es tracta de la primera prova. En general, serà d'opció múltiple, vertader-fals, resposta curta, talla els problemes de codificació. No va a esperar per posar en pràctica l'equivalent d'un problema que vostè veuria en un conjunt de processadors, per a això disposa d'un ordinador i un depurador i similars, però hi haurà petits problemes de codificació. I, en efecte, la millor guia per tenir una idea del que CS50 concursos són com és anar a cs50.net, aneu al enllaç de concursos, i es pot veure en els últims anys per valor de concursos. Només es donen compte que el pla d'estudis no sempre ha estat igual al llarg dels anys. De vegades s'afegeix, de vegades, restar, així que si veus algun tema en un d'aquests vells concursos que vostè no té idea del que està parlant, o és que el cobreixi o que no ho cobreixi. Però en la forma d'opinions, aquest diumenge, dilluns i dimarts així com un curs de tota la sessió de revisió en la nit - hora i lloc que s'anunciarà a la pàgina principal del curs - que tots tinguin l'oportunitat de revisar amb companys docents del curs el material per a aquest any, tant en la secció i com una classe completa, i els que es filmarà com sempre també. Està bé. Així que sense més preàmbuls, un comentari sobre passa / no passa i add / drop. És possible que hagi vist els meus notes ahir a la nit, i això és només una mica de tranquil · litat addicional que si vostè està entre els menys còmodes en particular o en algun punt intermedi i et sents una mica endins sobre el seu cap, adonar-se que és de fet bastant normal, i no hi ha una estructura de suport suficient en el lloc, un dels quals les hores d'oficina tenien la intenció de millorar encara més per l'última nit de correu electrònic, i adonar-se també que una opció com apte / no apte per a una classe com aquesta realment s'entén com un mecanisme per prendre la vora d'un curs com aquest, de manera que de nou si vostè està gastant aquests 10, 15, 20 hores tractant d'obtenir algun conjunt de processadors per treballar i vostè sap que vostè és el 90-95% del camí però no es pot trobar algun bug maleït, en un passa / no passa model que és una espècie de bé. La idea és que amb aquest mecanisme es pot anar focus en els seus conjunts de processadors altres o dormir o el que sigui que vulgui enfocar. Així que adonar-se que vostè té fins dimarts - tècnicament el cinquè dilluns, però és un dia de festa, de manera que el dimarts - per canviar de passa / no passa al revés graduades o viceversa. I si vostè està realment en el precipici i estan pensant a abandonar del tot, si us plau m'agafa després de la conferència o mándenme una nota. Ens encantaria que almenys xerrada abans de dir adéu. Està bé. Així que vam començar a prendre les rodes d'entrenament fos l'última vegada. En particular, ens centrem en cadena. La cadena és una cosa que es va declarar a la biblioteca CS50, específicament en aquest arxiu anomenat cs50.h que començarem a veure aquesta setmana i la propera. Però la cadena és en realitat una simplificació d'alguna cosa que és una mica més arcanely descrit com char *. Xerrada estem familiaritzats. És només un caràcter únic. Però a partir de dilluns * denota què? >> [Estudiant] Punter. Un punter. I el que és un punter? >> [Estudiant] Una adreça. És com una adreça, un lloc en la memòria. Què és una adreça o ubicació o la memòria? Un cop més, tots nosaltres tenim ordinadors portàtils amb un giga o 2 gigues de RAM més probable és que en aquests dies, i això vol dir que tens un bilió o 2 mil milions de bytes per valor de memòria. I no importa el que físicament s'assembla, però tingues fe que vostè pot comptar tots els bytes individuals que dona el seu ordinador portàtil - aquest és el byte 0, es tracta d'un byte, aquest és el byte 2000000000 - i això és exactament el que fa un ordinador. En assignar espai per a un sol caràcter, per exemple, és obvi que ha de viure en algun lloc de la memòria de l'ordinador, i potser és en el byte nombre 12345, i que en algun lloc aquí a la memòria del seu ordinador. I a continuació, la direcció d'aquest caràcter és 12345. Ara, en la setmana 0 i ara fins ara, no hem atès on en les coses de memòria s'emmagatzemen ja que en general utilitzen símbols, variables i matrius per aconseguir realment a les nostres dades. Però a partir de dilluns i tot el dia d'avui més, vostè està ara tindrà totes les capacitats més expressius amb els programes d'escriptura per manipular realment la memòria d'un ordinador però li sembli, tant per a fins bons i dolents, errors és un resultat molt comú en aquest punt en l'aprenentatge d'aquesta matèria. Però, què és el que realment significa ser un char *? Seguirem endavant cap enrere - i tornarem a Binky com va prometre avui. Anem a un exemple simple aquí. Deixa desar aquest fitxer compare.c, i em van deixar d'aconseguir una mica de codi de plantilla aquí així com stdio.h, permetin-me donar-me inclouen cs50.h. Vaig a acostar-hi. Permetin-me començar a escriure int main, main (void), i ara vull fer alguna cosa com això: printf ("Dóna'm una cadena:") i després vaig a utilitzar la cadena s es GetString per obtenir una cadena per part de l'usuari, i després em vaig a preguntar a l'usuari de l'altra. ("Dóna'm una altra cadena:") i vaig a preguntar per GetString per aconseguir això. Vaig a trucar a t t perquè ve després de s i s és un bonic nom per a una cadena si és bastant genèric. Així GetString, i ara només vull fer una comprovació de validesa i jo vaig a dir if (s == t), llavors jo vaig a dir-li a l'usuari printf ("Vostè escriu el mateix \ n"); més que vaig a imprimir alguna cosa com ("que ha escrit alguna cosa diferent! \ n") o qualsevol que sigui la sentència serà. Així que alguna cosa com això. Llavors, com de costum, vaig a tornar 0, la qual cosa només significava que res dolent ha passat, i seguiré endavant i compilar i executar aquest programa. Però el dilluns ens trobem amb aquest programa, i de fet se'ls va dir que no es HOLA hola i adéu no és un adéu. El comportament que vam veure va ser una mica més d'aquesta manera. Deixa anar al meu directori de les fonts, zoom aquí, i compararem fan. Compilat bé. Deixa córrer comparar. Dóna'm una cadena: HOLA. Dóna'm una altra cadena: HOLA. Ha escrit alguna cosa diferent! Bé, vaig a tractar d'alguna cosa més simple com 50, 50. Ha escrit alguna cosa diferent! hi, hi. Així que, clarament, alguna cosa està passant aquí. Però quina era l'explicació de per què? Pel que sembla, la línia 12 és completament disfuncional. Quin és el problema fonamental aquí? Si. >> [Estudiant] Es comparen les adreces. Sí, exactament. De fet, és la comparació de les adreces en el qual HOLA HOLA i s'emmagatzemen. No és comparar les cartes HOLA una i altra vegada, perquè el que realment va passar, tot aquest temps que hem estat usant GetString - Aquesta pissarra és de nou la memòria del nostre ordinador, i diguem que jo anomeno GetString després de declarar una variable s. Què fa la meva memòria sembla? Anem a dir que arbitràriament es són aquestes. És un quadrat. I gairebé tot el temps que he dibuixat un tros de la memòria a la pantalla si és de 32 bits que he estat dibuixant quadres com aquest perquè de fet en l'aparell, un punter, una adreça, és de 32 bits. És el mateix que un int. Això pot variar basat en el sistema informàtic. Aquells de vostès que són vagament familiaritzat amb el fet que el teu Mac o PC és de 64 bits, que en realitat vol dir que l'equip està utilitzant punters de 64 bits, Adreces de 64-bit, i entre els upsides que els equips RAM pot tenir molt més que abans. Llarga història curta, de tornada al dia en què els ordinadors només utilitzen 32 bits per representar adreces, el major nombre de bytes que pot representar en aquest cas era el que si vostè té 32 bits? Així que 4 mil milions, a la dreta, ja que 2 dels 32 és de 4 milions de dòlars. Aquest número ha estat recurrent al curs. Així que si vostè només té 32 bits, el nombre més alt que es pot comptar fins és aproximadament 4 mil milions. Però això era una limitació fonamental dels ordinadors fins fa uns anys perquè si només es pot comptar tan alt com 4 mil milions, no importa si vostè compra 8 gigabytes de RAM i fins a 5 gigabytes de RAM; no es pot comptar tan alt, de manera que era inútil. Només es podia accedir als primers 3 o 4 gigabytes de memòria del seu ordinador. Això és menys d'un problema ara, i vostè pot comprar MacBook Pro i Dells amb 8 gigabytes de RAM o fins i tot més en aquests dies. Però si simplement assignar en aquest programa un punter, un punter anomenat s, que podria tenir aquest aspecte a la pantalla perquè en realitat hem de pelar aquesta capa. Segueixo dient cadena, però a partir de dilluns, la cadena és realment char *, la direcció d'algun personatge. Així que anem a prendre aquesta roda d'entrenament tot i que seguirem utilitzant GetString per ara. Així que he declarat s, i això és una porció de la memòria, 32 bits. Què hi ha aquí a la memòria per defecte? >> [Resposta dels estudiants inaudible] Què és això? >> [Estudiant] escombraries. >> Escombraries. Exactament. Si el programador no posar un valor en una variable, que sap el que és? De vegades es té sort i és 0, que és una espècie d'un valor agradable, net defecte, però com vam veure dilluns, de vegades és una completa tonteria, un nombre molt gran positiu o negatiu que ve d'on? Si. >> [Estudiant] La funció anterior. Sí >>. Sovint, la funció que he anomenat abans perquè recordin, com es diu a funcions de la memòria, que ocupen cada vegada més espai de baix a dalt, i tan bon punt la funció retorna, que la memòria es reutilitzen pel tipus del costat que es diu, qui està utilitzant el mateix segment de la memòria. I si tens escombraries esquerra hi ha, els valors anteriors, podríem confondre s com tenir algun valor, quan en realitat no hem posat res allà. Així que la nostra RAM en aquest punt es veu així. Ara, al costat dret de la línia 7 que anomenem GetString, que hem estat fent durant setmanes ara, però el que realment GetString fent? GetString escrit per membres CS50 és una mica intel · ligent en què tan aviat com l'usuari inicia premen tecles i parada Intro, GetString s'adona de com les pulsacions de tecles molts van fer el hit d'usuari, nombre de caràcters que he de assignarà memòria RAM. I on RAM que ve, qui sap? Està en algun lloc de 2 gigabytes del seu ordinador o el que sigui de la memòria. Però anem a suposar que l'equip va trobar espai per a la paraula HOLA aquí. La paraula que vaig escriure va ser H-E-L-L-O. I si traiem això com una seqüència de caràcters, podríem dir així. Però he de fer una cosa més. El que pertany al final de qualsevol cadena en C? El caràcter nul, el que s'escriu com \ 0. És tècnicament el nombre 0, però la barra invertida fa tot més clar que això és literalment el número 0, el nombre enter 0; no ho és, per exemple, entre cometes 0 que podria escriure en el teclat. Així que això és HELLO. I què podem dir avui que una funció com GetString en realitat està tornant totes aquestes setmanes? No està tornant una cadena de per si, ja que en realitat no tenen significat perquè les cadenes no existeixen. Són una espècie d'una fabricació a la biblioteca CS50. El que és realment una cadena, més tècnicament? >> [Estudiant] És el primer caràcter. Exactament. És, senzillament, la direcció del primer caràcter que l'usuari va escriure polz Així que si la meva paraula HOLA acaba en 123 el nombre de bytes i després en el byte número 124, 125, 126, i així successivament, si només el meu número de bytes en un màxim de 0, el que realment està tornant GetString és, literalment, el número 123. Així que el que es posa en s és el nombre 123, no la lletra H, no la paraula HOLA, senzillament, la direcció en la que puc trobar la primera lletra de HELLO. Però això no sembla ser suficient. Et vaig demanar una cadena, no un personatge. Llavors, com sap l'ordinador o quin tipus d'AIXÒ vénen juntament amb la H? Quin és el tipus d'acord que tenim? Si. [Estudiant] Se segueix dient si mateix per trobar alguns personatges més. >> Exactament. Hi ha una convenció persona-ordinador de manera que quan es tracta de cadenes, també coneguda ara com estrelles char, simplement has de saber on al final de cada cadena a la vida és realment només iterar sobre ella amb un bucle for, un bucle while, el que sigui, perquè quan trobi el final de la cadena ara es pot inferir d'això, oh, tota la paraula era HELLO. Aquells de vostès que tenen experiència prèvia en programació pot saber en Java vostè pot trucar. longitud i en altres idiomes es pot trucar a la longitud o similar. Això és perquè en una gran quantitat d'idiomes, sobretot coses que es diuen llenguatges orientats a objectes, la longitud d'alguna cosa és de tipus encapsulat dins de la peça de dades en si, molt semblant a nosaltres, els ID i noms encapsulats i cases a l'interior d'un estudiant dilluns. No obstant això, C és el nivell molt més baix. No hi ha objectes o classes, si has escoltat aquests termes abans. Tot el que tens és realment adreces de memòria. Així que això és una espècie de la manera tradicional de representar les estructures de dades interessants. Té un valor d'inici com la direcció del primer caràcter i després només una convenció arbitrària que tothom està d'acord en seguir. Llavors, com s'implementa longitud de la cadena, el que proposem? Strlen, strlen, que alguns de vosaltres heu usat un parell de vegades. És bastant simple, oi? És com dues línies de codi. És més o menys un llaç per d'algun tipus, potser amb una variable local addicional. Però strlen només ha de donar un punter i després començar a buscar \ 0. I tan bon punt el troba, pot tornar el nombre total de passos que ha pres en aquesta cadena. Així que podem inferir d'això el que passa a continuació. Suposem llavors declaro t com ho he fet en la línia 10. Aquest és un valor escombraries. Qui sap al principi? Però en el costat dret de la línia de 10 Vaig a trucar a GetString nou. Qui sap on acaba això? Anem a dir arbitràriament que el sistema operatiu s'ha trobat lloc per a ell fins aquí. Passa que escriure casualment H-E-L-L-O de nou, i pel que podem anomenar el mateix tipus d'imatge. Però el fet que he redibuixat aquesta imatge és deliberada perquè és una. diferent HOLA que aquest Així que aquí aquesta podria ser la ubicació 456, és a dir 457, i així successivament. Així que el que es posa en el signe d'interrogació que una vegada va ser? En aquest cas 456. Estem rebent aquests nombres arbitràriament perquè realment a partir d'avui no anem a tenir cura molt sobre quina és la direcció d'alguna cosa és. Tot el que importa és que podem esbrinar la direcció d'alguna dada com HELLO. Així que en realitat el que la majoria de la gent fa en ciències de la computació quan es parla de les adreces de memòria i parlant de punters en concret, en lloc de preocupar esbrinant 123 - a qui li importa on aquest material és en realitat, només sabem que és en alguna direcció numèrica - simplifiquem el món i dir que s està apuntant a aquest personatge i t s'assenyala a aquest caràcter. I el fet que és una fletxa és absolutament intencional perquè, literalment, ara s està apuntant a H i T està assenyalant en l'altre H perquè al final del dia, no importa el que la direcció és, però sí importa que tinguem la capacitat d'expressar aquesta direcció amb alguna peça de codi. Realment no hem manipulat aquestes adreces encara així que anem a veure on podem intervenir i ordenar de fer les coses amb punters, però de moment en la línia 12 literalment quins valors estem comparant d'acord amb aquesta història en la línia 12? El que estem dient és 123 igual igual a 456? I això no és definitivament el cas. I fins i tot conceptualment, aquest punter és definitivament no és el mateix que aquest perquè GetString trucat dues vegades, i GetString no tracta de ser super intel · ligent, no es tracta de donar-te compte, oh, que va escriure HOLA fa 5 minuts; et vaig a donar el mateix punter com que et vaig donar abans, només reserva un espai de memòria cada vegada que en diuen. Llavors, com podem solucionar aquest problema? Si un nivell més alt que vull comparar les cadenes Hola i hola - No m'importen els punters - Com puc contestar la pregunta, Per què l'usuari escrigui la mateixa cosa? El que es necessita aquí? Si. [Estudiant] Utilitzeu una funció. >> Puc utilitzar una funció fora de la caixa. Puc utilitzar una funció anomenada strcmp, s-t-r-c-m-p, només la versió abreujada de dir comparació de cadenes. I si entrem en, per exemple, comparar 2, que és un dels fullets de avui, Faig exactament això. Vaig guardar tota la resta constant de la línia 1 fins al 26 o així, i ara compte d'aquesta part ha canviat una mica. Anem a passar per alt la línia 28 per un moment i centrar-se només en aquest cas. Què ens diuen avui que str comparació fa? Es maneja el procés de prendre 2 punters, S i T en aquest cas, tipus de pràcticament posant el dit en aquestes 2 cartes, i el que ha de fer és una mena de bucle while o bucle for, i diu que aquests són els mateixos? Si és així, es mou els dits o els punters cap endavant. Són els mateixos, aquests el mateix, ells, el mateix aquests mateix, aquests mateix? I ooh, estic al final de la cadena, tant en s i t. No he trobat cap contradicció. Sí, aquestes cadenes són iguals. I què str comparar devolució si dues cadenes són iguals, pel que sembla? Zero. Així que 0 és bo en aquest cas perquè si torna -1 o +1, que vol dir que es li passa a venir abans o després de t alfabèticament t. I per què hauria de ser útil disposar d'una funció que li indica quina cadena va abans o després que en un diccionari? [Estudiant] Recerques. >> Recerca i ordenació. Així que vostè pot fer coses com a recerca binària o tipus bombolla o fusionar espècie on vostè ha de comparar les coses. Fins ara hem espècie de tallar algunes cantonades i només va parlar de classificació en el context dels nombres, perquè és agradable i fàcil de parlar, però que sens dubte pot comparar cadenes, poma i plàtan, perquè si la poma és conegut per venir abans de plàtan, de manera similar, Pot moure les cadenes al voltant de la memòria igual que va fer amb Rob espècie de barreja en el vídeo i ho vam fer aquí a l'escenari amb una mena de selecció, ordenació per inserció, i una mena de bombolla. Llavors, on més podem prendre això? Anem a provar això. Anem a ordenar d'oblidar aquesta lliçó per un moment i provi i copiar 1.c a fer el següent. En la línia 21 que estic dient alguna cosa d'impressió, llavors jo estic fent una cadena de l'usuari, llavors jo estic comprovant això. Realment no hem entrat en aquest costum encara, però ara farem això. Anem a pelar en realitat aquesta capa. Això és realment char *. Aquest tipus és realment char *. Llavors, què significa estar comprovant si s == NULL? Resulta que quan es crida a una funció com GetString o més generalment només demana un ordinador per donar-li una mica de memòria, alguna cosa podria sortir malament. Vostè podria estar boig i demanar a l'ordinador per un terabyte de memòria demanant milers de milions de bytes de memòria que simplement no existeixen en l'equip, però les funcions GetString i altres necessiten alguna forma de cridar a vostè si has demanat massa. I la forma en GetString fa això és si vostè ha demanat més memòria integrat en l'equip, encara que això probabilitat super, super baix perquè cap de nosaltres va a escriure un bilió de caràcters i després premeu Enter, però baixa probabilitat tot i que pot ser, jo encara desitja comprovar per si de cas, i el valor especial que torna GetString, resposta, i altres funcions si alguna cosa ha anat malament és NULL en majúscules. I quina és NULL? NULL que passa de representar un punter. És l'adreça de memòria 0. El món arbitràriament decidir que, si es tracta de la memòria del meu ordinador - saps què? - anem a robar a 1 byte de memòria cada equip, i aquesta és la posició 0. Anem a donar-li un sobrenom NULL, i anem a prometre que en realitat mai posar les dades reals no perquè simplement arbitràriament necessita un valor especial, 0, NULL aka, perquè puguem cridar als usuaris si alguna cosa surt malament. En cas contrari vostè pot no saber què dir 0 posar alguna cosa aquí o vol dir alguna cosa va sortir malament? Hem d'estar d'acord tot el que no significa res NULL va ser retornat, sense direcció real va ser retornat. Ara, aquí estic adoptant la meva convenció humana de tornada d'un principal si alguna cosa surt malament. Això es deu a la convenció principal de retorn és tornar 0 si bé, 1 o algun altre valor si és dolenta. Però GetString i qualsevol altra funció que s'ocupa dels rendiments de memòria NULL si alguna cosa surt malament. Bé. Així que, lamentablement, la línia 27, super simple que sigui, no pot copiar completament la cadena. Per què? Podem veure això com segueix. Estic reclamant en la línia 27 es fa una còpia de s i dir que és t. Així que no estic preguntant a l'usuari per 2 cadenes en aquesta ocasió, només estic dient que el valor en s s'ha de posar en t també. Així que ara només per demostrar com trencada és a dir, en la línia 29 en endavant què estic fent? En primer lloc estic comprovant si la longitud de t és més gran que 0. Hi ha una mica de corda allà. L'usuari escriu alguna cosa polz Quina és la línia 32 fa, pel que sembla? [Resposta dels estudiants inaudible] Dret. >> Es pot inferir de la mateixa espècie a partir del que he dit que està fent. Però, tècnicament, el que s'està fent? t [0] representa què? [Estudiant] El caràcter zero. >> [Malan] El caràcter zero. O, més semblants als humans, el primer caràcter en t, sigui el que sigui, H potser en aquest cas. I ToUpper fa el que diu. S'aprofita el caràcter zero de tones i el canvia. Així que això significa prendre el caràcter zero de t, el converteixen en majúscules, i posar de nou en aquest mateix lloc. Així que si jo escrigui hello en minúscules, això ha de canviar la h minúscula a majúscula H. Però el problema és que a les línies 35 i 36, el que faré és imprimir per a nosaltres s i t. I quin és el teu pressentiment? Què és el que realment va a veure si he escrit en hola en minúscules? Què quedarà imprès? >> [Resposta dels estudiants inaudible] >> Què és això? [Estudiant] Big H i la resta petites. >> La gran H i la resta petit perquè, s o t? [Estudiant] Les dues coses. Ambdós >>. Exactament. Així que anem a veure el que està passant aquí. Deixin-me seguir endavant i compilar això. Això és copy1, així que copia1. Està bé. Zoom in Déjame seguir endavant i executar copy1, Intro, Dir una cosa: hola en minúscules. Es capitalitza la còpia, però pel que sembla capitalitzen l'original i, perquè el que ara passa en aquesta història? En la línia 27 que en realitat no sembla estar copiant la cadena, però tot i que podria haver esperat intuïtivament que aquest sigui el cas, si vostè pensa sobre aquesta foto, el que realment he fet? La meitat de la imatge és el mateix. Així que anem a retrocedir en el temps perquè t encara no existeix en la història. S pot existir en la història, però anem a minúscules hola aquest moment. Així que anem a arreglar el que en realitat escrit polz En aquest cas aquí tenim h-i-l-l-o. Anem a dibuixar com una seqüència de caràcters, vaig posar les línies de separació aquí i la meva 0 \. Així que aquí és on som tan bon punt la línia 1 a la 24-ish, més o menys, s'han executat. Aquesta és la foto de la meva memòria. Quan arribo a la línia 27, que passa? Igual que abans, apareix un punter, el que vaig a dibuixar com aquesta plaça. Es diu t. I quin és el seu valor per defecte? Qui sap? Alguns valors d'escombraries. Així que em vaig abstracte que fos com un signe d'interrogació. I tan bon punt la part dreta de la línia 27 s'executa, el que em posa dins de t? El mateix que hi ha a s. Així que si per un moment retirar aquesta abstracció de la fletxa i diem, oh, aquesta és l'adreça de memòria de càrrega 123, quan dius t aconsegueix s, punt i coma, que està literalment posant 123 aquí. Ara si que tipus de simplificar el nostre món de nou amb els quadres, el que ha fet en realitat s'acaba d'afegir una altra fletxa en el seu món que està assenyalant de t a la cadena exactament el mateix. Per això, quan en la línia 31 i 32 que van realment sobre el canvi de t [0], el que és t [0] pel que sembla sinònim d'ara? s [0] Així que això és tot el que està passant. I encara que aquest tipus de se sent una mica baix nivell i arcà i aquest tipus de se sent com potser intuïtivament això hauria d'haver només funcionava - He fet còpies de coses abans i ha funcionat - si vostè realment pensa sobre el que realment és una cadena, és un char *. Bé, què és això? És l'adreça d'algun personatge. Llavors, potser té més sentit que quan es tracta de fer alguna cosa súper aparentment simple com això, tot el que estem fent és copiar una adreça de memòria. No està fent res amb la pròpia cadena. Així que encara que no té idea de com es podria resoldre aquest problema en el codi, alt nivell, conceptualment, què és el que hem de fer perquè ta còpia fidel de s, pel que sembla? Si. >> [Estudiant] Donaria una nova ubicació? >> Exactament. Hem de donar a t un lloc completament nou. Hem de crear d'alguna manera un món on tenim un espai de memòria, que només per raons de claredat vaig a trucar a sota d'aquest, però no ha de ser-hi. Però ha de ser de la mateixa mida, així que vaig a dibuixar aquestes línies verticals en el mateix lloc. Està molt bé si això és tot escombraries inicialment. Qui sap què hi era? Però el pas 1 es va a haver de donar-me tanta memòria com que necessito per adaptar-se a una còpia de hola, a continuació, trobar la manera de copiar el h aquí, el correu aquí, el l aquí i així successivament. Però això ja ho deu semblar una mica obvi, encara que alguns dels detalls són encara abstracte. Per copiar aquesta cadena en aquest, és només un bucle for o while o alguna cosa amb el que t'has convertit en el més familiar. Així que anem a provar això. Déjame entrar copy2.c. En copy2.c tenim gairebé el mateix programa, a excepció de la línia 27. S'assembla una mica complex, però si es descomponen a poc a poc, el costat esquerre és el mateix. Char * t crea aquesta cosa a la memòria, encara que amb un signe d'interrogació perquè no tenim ni idea del que hi ha per defecte. A la part dreta estem ara la introducció d'una nova funció malloc,, per assignar memòria, dóna'm la memòria, i pel que sembla es quants arguments, quantes coses entre parèntesis? Vaig sentir murmuris d'1 i 2, però és només 1. No hi ha una coma, el que significa que només hi ha una cosa dins dels parèntesis. Tot i que hi ha altres parèntesis, voldria destacar el que hi ha dins dels parèntesis més externs, i és aquesta expressió: (Strlen (s) + 1) * sizeof (char). Així que si realment pensar en això, això diu dóna'm la longitud de s. Per què sóc, però, afegir 1 a la longitud? >> [Resposta dels estudiants inaudible] Exactament. Necessitem espai per a aquest tipus de la cua, el sisè personatge que no té cap significat Anglès però té un significat especial programàtic. Així que necessitem un + 1 per això perquè strlen Retorna l'expectativa humana de longitud, hola o 5, no li dóna el caràcter nul addicional. Així que afegir manualment aquest amb + 1. I després d'això, de mida * (char), no hem vist això abans. Això no és tècnicament una funció. És una paraula clau especial que només et diu el que la mida és d'un altre tipus de dades en un ordinador perquè en realitat, alguns de nosaltres tenim equips de 32 bits. Tinc un ordinador bastant antic al país, i que només utilitza 32 bits per representar els punters. I si ho feia mida d'un tipus de dades, pot ser de 32 bits. Però si estic fent servir el meu ordinador nova fantasia, que podria tornar un valor de 64 bits una mena direcció. Així que en aquest cas, només per estar segur super, no anem a codificar alguna cosa com - així, quin és la mida d'un char d'acord amb el que hem dit fins ara? Hem pràcticament em va dir verbalment que es tracta d'un byte, i això és bastant cert en tots els àmbits. Però, de nou, els supòsits tendeixen a ser dolent. Condueixen a programari defectuós si les persones fan servir el seu programari de maneres que no pensava. Així que anem a abstreure aquesta lluny i més just dir genèricament Necessito això molts trossos de la memòria i cada tros de memòria hauria de ser equivalent a la mida d'un caràcter, que de fet és igual a 1 en aquest cas, però és una forma més genèrica d'escriure. Així que si la paraula és hola, quants bytes es malloc aparentment assignar a saludar? [Estudiant] Sis. >> Six. Exactament com molts ja que tenim signes d'interrogació a la pantalla. I després prendre una conjectura ara es basa en la comprensió de GetString Què malloc probablement torni? >> [Estudiant] Una adreça. Una adreça de què? Pel primer fragment de memòria. No tenim idea del que és allà perquè alguna altra funció podria haver estat utilitzant aquesta memòria prèviament. Però malloc, com GetString, torna la direcció del primer byte de la memòria que s'ha reservat per a vostè. No obstant això, el que no fa és omplir l'espai en blanc amb un caràcter nul barra invertida perquè resulta que vostè pot utilitzar malloc per assignar qualsevol cosa: sencers, cadenes, matrius, flotadors, estructures estudiantils. Podeu utilitzar malloc totalment genèrica. No li importa ni ha de saber el que l'assignació de memòria per. Així que seria presumptuós per malloc posar un 0 \ al final de cada tros de memòria que t'està donant perquè \ 0 cosa és només una convenció per les cadenes. No s'usa per sencers, no s'utilitza per als flotadors, no s'utilitza per als estudiants. I així el Gotcha amb malloc és que la càrrega és totalment de vostè al programador per recordar la quantitat de bytes que assignen i no utilitzar mai un bucle for o un bucle while i anar més enllà del límit de la quantitat de memòria que han donat. En altres paraules, tan bon punt s'assigna memòria, no es pot demanar al sistema operatiu, oh, per cert, què tan gran d'un tros de memòria va ser això? És totalment de vostè per recordar si vostè necessita aquest valor. Així que anem a veure com procedeixo a utilitzar aquesta memòria. En la línia 28 i 29 per què estic fent això? Només has de comprovar el seny total. Només en cas que alguna cosa anava malament, demano una cosa increïble quantitat de memòria o tinc tantes coses que s'executa en l'equip que simplement no hi ha prou memòria, una cosa així, jo almenys desitja comprovar nul · la. En realitat, la majoria de les computadores li donarà la il · lusió que tots els programes Podeu utilitzar la totalitat de la memòria RAM, però tot i així, si l'usuari escriu en una corda llarga boig potser perquè ets un noi dolent i en realitat estan tractant de bloquejar el programa o truc-hi, desitja comprovar almenys el valor de retorn de malloc i si és igual a null. I si ho fa, anem a deixar de fumar en aquest moment perquè no sé què fer en aquest cas. Com puc copiar la cadena? Hi ha algunes maneres de fer això. Hi ha str copiar funcions en C, però és molt senzill per a nosaltres fer això la manera antiga. En primer lloc anem a esbrinar quina és la longitud de s és. Jo podria haver posat això en el bucle, però en lloc d'això només cal posar aquí per més claredat. Així núm ara emmagatzema la longitud de l'original, que aparentment és 5. Després, en el meu bucle per iterar des que estic en 0 fins an, i en cada iteració estic posant s [i] dins de la [i]. Així que això és el que implicava amb els meus dos dits apuntant a les cordes abans. Com aquest bucle for itera així, jo estaré copiant ha aquí, i en aquí, jo en aquí perquè aquest és s, aquest és t. I finalment, en la línia 35 per què estic fent això? He de assegurar-me que estic acabant la cadena t. I ho va fer d'aquesta manera a ser súper explícit. Però proposar a algú, si pogués, una forma diferent de fer això. Jo realment no necessita la línia 35. Hi ha una altra manera de fer això. Si. >> [Resposta dels estudiants inaudible] >> Digues-ho fort. [Estudiant] Menor o igual a. >> Exactament. Podríem dir inferior o igual a n, que en general ha estat mal perquè gairebé sempre quan vam pujar a un igual al que estem explicant anem un pas massa lluny. Però recordeu, la quantitat de bytes que s'assignen? Es van assignar de strlen s, de manera que 5 + 1 per a un total de 6. Així que en aquest cas podríem fer alguna cosa com això pel que estem copiant no només la salutació sinó també el 0 \ al final. Alternativament, podríem utilitzar una funció anomenada str còpia, strcpy, però que no seria divertit gairebé com a molt. Però això és tot el que fa per sota de la caputxa. A continuació, finalment, fem el mateix que abans. Jo t capitalitzar i després em diuen que l'original estan presents i la còpia és així. Així que anem a tractar ara. Déjame aquí. Fer copy2. Anem a ampliar i executar copy2. Vaig a escriure hola en minúscules, i de fet tinc minúscules hola que l'original però el capital Hola per a la còpia. Però no he acabat encara. He de fer una última cosa aquí. 46 i 47 està clarament com alliberar memòria, però què significa això realment? Què estic fent, creus que, trucant a la línia 46 i la línia 47? Quin efecte té això? Si. [Resposta dels estudiants inaudible] >> Exactament. Vostè s'acaba d'indicar al sistema operatiu, hey, gràcies per aquest record. Ara pot utilitzar per a una altra persona. I aquí hi ha un exemple perfecte dels valors d'escombraries. Acabo d'utilitzar aquesta memòria per escriure la paraula hola en 2 llocs, aquí, aquí, aquí i aquí. Així que aquest és h-i-l-l-o-\ 0. Però llavors truqui a la línia 46 i la línia 47, i ja saps el que passa allà en termes de la imatge? En realitat, esperar, aquesta imatge és l'antiga. Una vegada que la còpia sigui, aquest home està apuntant aquí, així que anem a treure els números i només abstreure com les nostres fletxes de nou. Què passa en aquest quadre quan dic lliure? [Resposta dels estudiants inaudible] >> Ni tan sols. Si dic gratis a s i t - una mena de pregunta capciosa - aquest panorama no canvia en absolut perquè trucant i trucant s t li diu al sistema operatiu, hey, vostè pot utilitzar aquesta memòria de nou, però això no canvia aquest valor nul o algun caràcter especial, no canvia això, no canvia el h o i el o la l o l o el o ja sigui en el lloc per a qualsevol altra cosa. Quant a la imatge, tan aviat com es digui canvis lliures, res. I aquí està l'origen dels valors de fem perquè si després més endavant en aquest programa acabar amb un sistema operatiu per obtenir més memòria amb malloc o GetString o alguna cosa per l'estil i el sistema operatiu diu, clar, tinc 12 bytes de memòria només alliberats, utilitzar aquests, què seràs lliurat? Vostè serà lliurat un tros de memòria que normalment es basaria amb signes d'interrogació, però quins són els signes d'interrogació? Que estiguin h-i-l-l-o, h-i-l-l-o. Aquests són els nostres valors nous d'escombraries tan aviat com alliberar aquesta memòria. Hi ha una implicació món real aquí també. Això succeeix a veure amb la RAM, però els equips en realitat fan el mateix amb el disc. Parlarem d'això en particular amb un conjunt de problemes futurs que se centra en la medicina forense. Però el que realment succeeix si té algun arxiu financera sensible a l'escriptori o alguna vaga JPEG i l'arrossega en les seves escombraries, el que passa quan l'arrossega a les escombraries o la paperera de reciclatge? Sabia el que estava parlant. [Rialles] Què passa quan s'ha arrossegat aquests documents a la paperera de reciclatge o pot d'escombraries? [Resposta dels estudiants inaudible] Bé, així que vés amb compte. Què passa quan vostè fa això? La resposta curta és no, oi? Expedient incomplet o sensible encara hi assegut en algun lloc del seu disc dur. La majoria de nosaltres almenys hem après per les males que cal buidar les escombraries o la paperera de reciclatge per eliminar realment els arxius. I, en efecte, en fer clic o clic amb el botó de control en el pot d'escombraries o seleccioneu Fitxer, Buidar paperera o el que sigui i que en realitat buidar la paperera o paperera de reciclatge, el que realment succeeix llavors amb aquesta imatge? Més res. Així que res succeeix realment en el disc. I si només temporalment divagar i escriure - I'Ll només ha d'utilitzar la part de darrere d'això. Així que ara la història està canviant de RAM, que és on hi ha programes mentre està en funcionament, el disc, que és on s'emmagatzemen a llarg termini fins i tot quan se'n va la llum, per ara - i tornarem a això en el futur - anem a pretendre que això representa l'interior del disc dur del seu ordinador perquè en el seu dia el que solia ser discos circulars, igual que els disquets. Així que si vostè té una mica de sensibilitat arxiu d'Excel, pot trigar fins aquest tros de memòria en el disc del seu ordinador, i estic dibuixant 1s i 0s mateix arbitrari. En arrossegar l'arxiu de la mateixa manera que al seu pot de brossa o la paperera de reciclatge, literalment no passa res, ja que Apple i Microsoft acaba de decidir la paperera i paperera de reciclatge és en realitat un marcador de posició temporal. Potser, finalment, el sistema operatiu es buidar per a vostè, però en general, no fa res, almenys fins que estiguis realment poc espai. No obstant això, quan es va a les escombraries buida o buida la paperera de reciclatge, De la mateixa manera, no passa res a aquesta imatge. Tot el que succeeix està en un altre lloc en l'equip, hi ha una mena de taula. És una mena de full de trucs poc que diu que, diguem, resume.doc, de manera que el seu full de vida en un arxiu de Microsoft Word solia viure en el lloc 123 en el disc dur, no en la memòria i no en la memòria RAM, però en el seu disc dur, i les seves vides incompletes JPEG amb 456, i l'arxiu d'Excel viu en 789 o on sigui. En eliminar arxius en realitat buidar les escombraries o la paperera de reciclatge, aquesta imatge no canvia. La 0s i 1s al seu disc dur no van enlloc. Però aquesta taula, aquesta base de dades poc de sort, si canvia. En eliminar el seu full de vida, és com si l'arxiu s'elimina d'alguna manera, però tot l'equip no s'oblidi que el que viu en el seu disc dur. El 0 i 1 que componen el seu full de vida o de qualsevol d'aquests arxius es troben encara intactes. Així que si vostè ho va fer accidentalment, encara hi ha una probabilitat diferent de zero que vostè pot recuperar les seves dades utilitzant Norton Utilities o algun programari comercial el propòsit en la vida és trobar 0s i 1s que han quedat orfes a causa del tipus, oblidat aquí, però va sortir d'aquí, perquè pugui recuperar les dades. O els investigadors forenses amb la policia o l'FBI en realitat tindria un disc dur i realment buscar patrons de 0s i 1s que s'assemblen a imatges JPEG, s'assemblen als arxius d'Excel, i recuperar d'aquesta manera, encara que l'equip s'ha oblidat d'ells allà. Així que l'única manera de realment eliminar les dades, com veurem en el futur, és fregar o netejar l'arxiu o disc dur - Realment no es pot eliminar el 0 i 1 perquè si no començaria amb una unitat de disc dur gigabyte i que acabaria amb un disc dur megabyte si constantment es esborrar, literalment, 0s i 1s. Llavors, què faria vostè si realment volia cobrir les seves pistes i el problema fonamental és que encara hi ha 0s i 1s al disc? Veig algú que físicament gesticulant trencaria el dispositiu. Això va a funcionar. [Rialles] Però si això és una cosa d'una solució cara, el que seria més raonable? Si. >> [Estudiant] Sobreescriure ells. >> Sobreescriure'ls amb què? >> [Estudiant] Altres dades. Altres dades. Vostè pot sobreescriure el disc amb 0s o 1s o 0s tots, tots 1s. I això és precisament el que alguns dels programes fa. Vostè pot comprar el programari o fins i tot aconseguir el programari lliure, i fins i tot integrada en Mac OS en aquests dies, si més no en Windows, és la capacitat d'esborrar de forma segura. En realitat, si vostè vol tot jonrones avui si tens un Mac i fer això, si tens algunes coses al seu pot de brossa, pot fer-ho Secure Empty Trash, que fa exactament això. En lloc d'esborrar arxius només aquí, no esborra l'aquí 0s i 1s, més aviat, només canvia tots ells, per exemple, a 0s i punt, punt, punt. Així que un dels conjunts de processadors futurs en realitat serà recuperar intencionalment dades - fotografies que hem pres de les persones, llocs i coses al campus perquè anem a fer una imatge forense de la targeta de memòria d'una càmera digital, que és la idea mateixa - i que haurà de ser desafiats a trobar realment els patrons que representen imatges JPEG al disc dur, igual que l'ex estudiant el correu electrònic que vaig llegir fa unes setmanes va fer per recuperar fotografies de la seva germana. Per què no ens prenem un descans de 5 minuts aquí, i anem a reagrupar amb més memòria. Així que aquí és on les coses es posen una mica al · lucinant, però aquest és un pas molt potent cap a la comprensió d'aquest encara més. Aquí hi ha un programa anomenat pointers.c. És un codi d'exemple d'avui. Recordeu que en les primeres línies, 19 a 22, tot el que estem fent és com GetString i tornar una adreça, emmagatzemant-la en s. A partir de llavors per pset fins i tot 3 si vols però pset 4 i en on vostè pot començar a prendre aquestes rodes d'entrenament fora de tu mateix, no hi ha cap raó per pretendre que les cadenes de deixat d'existir. És certament correcte començar dient char *. Com acotació al marge, en referències en línia i en els llibres que sovint pot veure l'estrella costat de la variable. Vostè podria fins i tot veure els espais al voltant dels dos costats de la mateixa. Tots aquests són funcionalment correcte. Per ara, però, anem a estandarditzar aquest mètode per fer super clar char * que és com dir punter a caràcter. Aquest és el tipus de dades. I a continuació, el nom de la variable s és en aquest cas. Per això hem aconseguit una corda i l'hem anomenat s. I llavors aquí adonar que estic fent en realitat una mica d'engany. Això s'anomena aritmètica de punters, que és una mena de súper simple. Només vol dir sumar i restar nombres als punters. Però això realment funciona. Aquest programa aparentment imprimeix la cadena es 1 caràcter per línia de tal manera que el resultat final - Només així podem fer malbé a on va això, fer suggeriments, executeu punters, deixa zoom in Ara em deixa escriure alguna cosa com HOLA i el tipus Intro i imprimeix un caràcter per línia. Fins fa un segon, haguéssim fet això amb notació de claudàtors. Tindríem un bucle for i que faríem printf de s [i] i ens agradaria fer això una i altra vegada i una altra amb un n barra invertida al final de cada línia. Però aquest programa és diferent. Aquest programa s'utilitza, literalment, l'aritmètica. Llavors, què està passant aquí? En primer lloc, abans que aquest llaç encara s'executa, el que, per ser clars, és realment s? S és? >> [Estudiant] Una adreça. >> Una adreça. I és la direcció de, en el cas de hola, el primer caràcter de la paraula, que és h. Així que s és, en aquest exemple particular, la direcció de h. Llavors, què significa això per fer s + i? Bé, i comença en 0 en aquest bucle for. Hem fet moltes vegades. Em pujarà a la longitud de la cadena, pel que sembla. Així que en la primera iteració d'aquest bucle, i és evidentment 0. Així que aquesta expressió està dient s + i - més aviat, es +0, això és, òbviament, només s. Llavors, què és * s aquí? Ara estem utilitzant l'estrella d'una manera lleugerament diferent. Deixa anar per davant i desfer-se de t perquè hem acabat parlant de t i còpies de s. Ara només vull explicar una història que involucra s. I així, en aquest moment, després de tipus string, el nostre món es veu absolutament com ho feia abans amb només s emmagatzemar la direcció de hi de manera més general que s'assenyala en la cadena hola. Si ara faig una línia com * (s + i), anem a provar això. Així * (s + i). Permetin-me simplificar això perquè això és 0, de manera que aquest és * (s +0). Bé, espera un minut. Simplificar encara més. Això és * (s). Bé, ara els parèntesis són una espècie d'estúpid, així que ara farem * s. Així, en la primera iteració d'aquest bucle, que la línia que està ressaltat, 26, és més o menys equivalent a la impressió d'això. Quin és el tipus de dades * s? En aquest context, perquè l'estrella passa a ser gairebé el mateix s, però més específicament, perquè ja no estem declarant s, no estem creant una variable més, no hi ha cap menció de char * en la línia 26, no hi ha esment de la cadena de paraules clau, només estem utilitzant una variable anomenada s, Resulta que ara l'estrella té una mica diferent i, sens dubte, confonent el significat. * S aquí significa anar a l'adreça de s i imprimir el que està allà. Així que es aquí, s * és - una cosa així com Serps i Escales, segueixi la fletxa - aquí. Així que això és * s. Així que el que s'imprimeix en la primera iteració d'aquest bucle en la línia 26? Puc imprimir% c, que és el marcador de posició per a un caràcter, llavors un \ n per a una nova línia. * (S + i), on i és 0 és precisament això. Llavors, què puc fer carbó en lloc de c%? H. En la següent iteració del bucle - és probable que pugui veure on va això - la següent iteració i és òbviament 1, de manera que aquest mitjà es +1, i ara em cal el parèntesi perquè ara l'estrella ha de dir anar a l'adreça de memòria s +1. Quin és s? Anem a retrocedir en el temps i dir això ara arrow realitat no se'ns està fent cap favor. Que és més específicament dir que aquest és l'emmagatzematge de la sèrie 123 ja que l'inici d'aquesta cadena hola, aquesta és l'adreça 123, és a dir 124, i així successivament. Així que en la segona iteració quan dic s +1, que és com dir que un 123, també conegut com 124, així que el que s'imprimeix caràcters en la segona iteració? I en direcció de memòria 124. Entonces + més, 125, 126, 127, i per sort aquest bucle s'atura abans d'arribar aquí perquè estic fent servir strlen per assegurar-se que no compta massa alt. De manera que també ho és. De nou, això és com si haguéssim fet fa una setmana. Deixa que ho escrigui en la línia de sota tot i que no volem fer dues coses. Això és idèntic a aquest ara. Així que, encara que s és una cadena, com ho hem estat trucant durant setmanes, s és realment un char *. Així que si volem ser súper anal, és molt adequat per escriure el caràcter específic en la posició i-èsima usant aquestes adreces numèriques i d'aquest operador estrella, però, francament, això és simplement molt més net. Així que això no és dolent. No hi ha raó per deixar de fer la línia 27 aquí, però el 26 és funcionalment el mateix, i és funcionalment el mateix exactament per les raons que hem estat discutint fins ara. I finalment, 29 és només una bona pràctica. Trucar gratis de s significa que ara vostè està donant de nou la memòria que li va donar GetString perquè, de nou, com he esmentat dilluns, GetString per setmana ha estat la introducció d'un error en el codi. El seu codi de setmana ha tingut pèrdues de memòria pel que vostè ha estat preguntant GetString per a la memòria, però mai he estat donant volta. I això va ser triat deliberadament per nosaltres pedagògicament perquè és simplement massa com per pensar en el principi. Però ara necessitem més simetria. Si li demana a l'equip per a la memòria, com és el cas de GetString, com és el cas aparentment per malloc, Ara deu pset 4 en endavant també alliberar la memòria tal. Tingueu en compte que això és diferent de dir n int. No és necessari per alliberar això perquè vostè no va cridar a GetString i vostè no va cridar a malloc. I fins i tot si vostè diu getInt ja que finalment veurà, GetInt no assigna memòria per a vostè, perquè en realitat es pot passar al voltant dels nombres enters i flota i caràcters exactament de la manera que hem estat fent durant setmanes. Cordes, però, són especials perquè en realitat són la concatenació de caràcters múltiples. Així que són només diferents de caràcters i carrosses i sencers i similars. Però tornarem a això en poc temps. Qualsevol pregunta després en aquest inici de punters? Si. [Pregunta estudiant inaudible] Ah, molt bona pregunta. Una de les poques coses en realitat C fa per tu, el que és convenient, s'adona que per a tu el que la mida és del tipus de dades i després fa aquest tipus de multiplicació per a vostè. Això és irrellevant en el cas dels caràcters, ja que gairebé sempre és un char és un byte, així que això funciona. Però pel bé de la discussió, si en realitat estaven imprimint els nombres enters i que estava tractant d'imprimir una mica de s valor que s'apunta a un nombre enter, De la mateixa manera que no hauria de fer + 4 * i només perquè un int és de 4 bytes. L'aritmètica de punters significa que C i el compilador fer tot el que càlculs per vostè. Tot el que has de tenir en compte és el compte en una mena de sentit humà. Si. [Estudiant] Quan apareixen una cadena dins d'un bucle for, has de alliberar més tard? Bona pregunta. Si es declara una cadena dins el bucle for, és necessari per alliberar més tard? Només cal per alliberar la memòria que es pot assignar a GetString o amb malloc. Així que si vostè acaba de dir alguna cosa com - m'ho dius a mi posar claus ara el que tot el codi està relacionat. Si va fer alguna cosa, encara que buggily, com aquest, char * t = s, vostè no necessita t t lliures perquè no incloïa cap menció de malloc o GetString. Si per contra et va fer això, GetString, llavors sí, vostè hauria de t lliures. I de fet, l'única oportunitat de fer-ho és ara dins d'aquest bucle, per a la mateixa edició d'abast que hem discutit en el passat. En cas contrari, estaria l'assignació de memòria, assignació de memòria, assignació de memòria, i al final del programa, perquè estàs fora d'aquest circuit, t no existeix, però mai es va dir que el sistema operatiu que no era necessari que la memòria més. I en poc temps, per pset 4 o 5 et equiparà amb un programa anomenat Valgrind, que és similar en esperit al BGF ja que té una mena interfície arcà, però el seu propòsit en la vida és ajudar. I Valgrind és un programa que en el futur busqui seus programes a la recerca de fuites de memòria, ja sigui per GetString o malloc, que començarem a utilitzar amb més raó ara que deixi d'utilitzar la biblioteca CS50 tant. Per fi ara tenim una mena de vocabulari i el tipus de model mental en la teoria amb els de resoldre aquest programa trencada. Així que en aquest programa trencada o intercanvi treballa dins de swap, però en realitat mai va funcionar en la principal causa principal passava a x i i, recordem, i els que van ser passats per a valors, per així dir-ho. Les còpies d'ells van ser donats a canviar. Al final de l'intercanvi, a i b s'havia fet intercanviat, però, és clar, x i i, com vam veure el dilluns, no ho havia estat. Així que proposo en verd aquí que aquesta és en realitat la solució aquí. I, de fet, anem a moure els meus estrelles per estar d'acord encara que, de nou, funcionalment això no importa. En les properes setmanes explicarem quan i per què és important. Així, en verd ara és una solució. Francament, sembla molt més desordenat perquè tinc totes aquestes estrelles. Permetin-me assenyalar una cosa. La línia superior aquí on diu int * a * b i int fonamentalment fent el mateix que sempre ha fet. Es declara dos arguments o paràmetres a canviar, el primer dels quals és un punter int trucada, el segon dels quals és un punter int anomenat b. L'únic que hi ha de nou en aquest punt és el fet que hi ha una estrella allà. Què significa això? A no és un int, b no és un int. Una és la direcció d'un sencer i b és la direcció d'un int diferent. Aquí baix, aquí és on em admit C torna confús. Ara estem utilitzant una estrella, però té un significat diferent en aquest context. Perquè no estem declarant punters com som aquí, aquí estem dereferencing coses. Així que, tècnicament, l'estrella en aquest context de la primera línia, segona i tercera dins de swap és l'operador d'indirecció, la qual cosa significa anar-hi. Així que com el meu dit seguia la fletxa en h, * Als mitjans anar a aquesta direcció i em trobareu, el int que hi és. * B mitjans anar a l'adreça i em passa el que hi ha. Així que anem a tornar a dibuixar la imatge de dilluns ara usant una pila de marcs, el fons de la qual serà principal, el superior dels quals serà swap, perquè el nostre món es veu, igual que dilluns, així. Heus aquí un tros de memòria que principal s'utilitzarà. Recordeu de dilluns que el programa només tenia 2 variables, un anomenat X i una crida i, i jo havia posat els números 1 i 2 hi ha. Ara, quan jo dic canviar com ho vaig fer el dilluns, anteriorment quan he utilitzat la versió vermella d'aquest programa, que té aquest aspecte, Tinc dos paràmetres, a i b, i el que escrivim aquí i aquí? Només 1 i 2, literalment còpies de x i i. Avui podem canviar això. Avui en comptes de passar a enters a i b que passarem en dues direccions. Les adreces de succeir perquè apunti a INT, però aquestes adreces no són ells mateixos intercepcions. Són adreces. És com una adreça postal. Així que ara hem de acaba de donar-me una mica més de detall a la pantalla. Aquesta és la memòria del meu ordinador, ja que ha estat tot el dia. Ara necessitem una mica de arbitrari esquema de numeració. Així que anem a dir, per casualitat, que aquesta és l'adreça de memòria de 123, 124. Diguem que aquest és de 125, és a dir 126, i així successivament, però això és totalment arbitrària. Només necessitem un esquema de numeració en la meva memòria. Així que ara quan realment passa en x i y, no vaig a passar en X i Y; Vaig a passar a l'adreça postal, per dir-ho, de x i de y de manera que el que s'emmagatzema aquí i aquí no és 1 i 2, però si pots veure el meu petit text, el que es passa per aquí i aquí? [Resposta dels estudiants inaudible] >> Exactament. 123 es va posar aquí i 124 es va posar aquí. Ara, perquè jo l'estrella d'aquesta forma primera línia aquí a la part superior, meu programa només sap que 123 i 124, encara que són òbviament sencers que qualsevol humà podria notar, ells han de ser interpretats com adreces, adreces numèriques. No són en si mateixos sencers, que són les adreces, i això és perquè m'he posat explícitament les estrelles allà. Així que ara en la meva línia de primera, segona i tercera de codi real el que passa aquí? Anem a dibuixar la resta de la imatge. Tmp és igual que ho va ser el dilluns. Res especial a tmp. És a uns locals de 32 bits variable, i dins d'aquest parer estic emmagatzemant el valor de * a. Ara, si m'acaba de dir tmp = a, el que em va posar aquí? >> [Estudiant] 123. 123. Però això no és el que estic fent. Estic dient tmp = * a. Significa estrella anar-hi. Així que aquí hi ha una, 123. Com puc anar? Imagina com si hi hagués una fletxa. Bé, aquí està, 1. Així que el que s'emmagatzema en tmp, pel que sembla? A només 1. En altres paraules, tmp és * a *, un mitjà de anar a l'adreça que es troba actualment en una, que aparentment és 123. Bé, aquí estem en la posició 123, veig el número 1, així que em vaig a posar el número 1 hi. Ara, què és el que faig en la línia 2, * a * = b? Aquest és una mica més complicat perquè ara el que és un? És 123. Així que * a és on? Just on estava abans. Així que anar-hi. Bé. Ara, finalment, i, finalment, es començarà a tenir sentit, és d'esperar, * B significa que el que està en b? 124. Així que he d'anar allà, que és 2. Llavors, què em poso a on? 2 entra aquí perquè va a * b * a. Així que vaig a fer això. I ja es pot veure, potser, que estem molt més a prop a la solució d'aquest problema estúpid, simple correctament per primera vegada perquè ara encara ens queda un record del que era x, tenim 2 còpies, sens dubte, de i, però ara diu que la línia 3 * b. Així que aquí està b. B * significa anar-hi. I on és la ubicació 124? És pel que sembla aquí. Llavors, què poso aquí? Òbviament, tmp. Així que ara faig això. Així que tinc una aquí i 2 aquí. I ara, què passa amb tot això, el 123, el 124, i l'1? Així que retorns de swap, aquesta memòria és tan bona com perdut perquè així que retorns d'intercanvi, el sistema operatiu és lliure d'utilitzar la memòria de nou en el futur. Només la memòria principal a la part inferior d'aquesta pila de trucada s'enganxa al voltant. I així, per fi tenim ara una versió de treball. Déjame entrar swap.c i observeu el següent. A la part superior del programa que he canviat el meu prototip per ser int * a * b i int. Així que l'únic que vaig canviar per anar de vermell, que era dolent, al verd, la qual cosa és bo, se li vaig afegir aquestes estrelles d'avui. Però aquí baix, en si mateix canviar vaig haver copiar, enganxar el que era just a la diapositiva. Tinc aquí un estel, l'estrella aquí - que coincideix amb el prototip - i llavors totes aquestes coses ara tenen estrelles excepte tmp perquè l'ús d'una variable temporal, no hi ha res de nou allà. Només necessito d'emmagatzematge temporal per a un int. Així que no necessitem un estel allà. Només necessitem l'estrella perquè puguem travessar aquest tipus de límit arbitrari entre aquests dos marcs en la memòria del meu ordinador. Però una última cosa ha de canviar, i que podria haver albirat ja. Quina altra línia és òbviament diferent ara? >> [Els estudiants] i x. Sí, així que 25 és l'última línia de codi que necessita canviar perquè això funcioni. Fa una setmana i fins dilluns de la línia 25 es veia així, intercanviï x i i, i aquesta es va trencar perquè si dius swap (x, i) li està donant còpies de x i y per intercanviar, llavors està fent el seu, però mai en realitat està canviant xiy si mateix. Així que encara que vostè mai ha vist abans a aquest personatge amb el símbol d'unió en el codi, acaba de prendre una conjectura. Què significa el símbol d'unió fan, pel que sembla? [Estudiant] neu la. >> Pren la direcció. De manera que el signe està dient dóna'm la direcció de x. Qui sap on és? Li passa a ser 123. No m'importa. Només dóna'm la direcció de x. & I significa dóna'm la direcció de i. I en aquest punt la història és perfectament coherent amb la imatge que va dibuixar fa un moment. Així que vaig a admetre punters, sens dubte per a mi quan vaig començar a aprendre això, van ser sens dubte una de les coses més difícils d'embolicar el meu cap al voltant. Però dese compte, sobretot perquè seguim jugant amb aquest tipus de coses, si ho desglossem a aquesta classe de súper simple intel · lectualment interessants problemes de moure només els números més, la resposta a una gran confusió amb els punters realment es poden derivar d'aquestes mecàniques molt bàsiques. Aquí està la direcció. Veu allà amb l'estrella. O al revés, això és un símbol d'unió. Esbrinar quina és l'adreça que realment és. Està bé. On és tot això de memòria ve? Hem elaborat aquesta imatge un parell de vegades, i em segueixen prometent que anem a tornar-hi, però aquí és la representació de la memòria de l'equip que és una mica més marcat que el nostre pissarra aquí està. El segment de text a la part superior representa el que fa al seu programa? [Resposta dels estudiants inaudible] >> Com? Digues-ho de nou. [Estudiant] El programa actual. >> El programa en si. Així que el Clang 0 i 1 que ha compilat després d'escriure codi C i que després ends i la generació de 0s i 1s fins aconseguir amagat allà a la memòria perquè quan es fa doble clic en una icona en el teu Mac o PC o executar una ordre com mario en el seu sistema, la seva 0s i 1s de disc es carreguen a la memòria perquè l'ordinador pugui manipular i executar amb més rapidesa. Així dades inicialitzats i dades sense inicialitzar, no parlarem molt d'ells, però això són només les variables globals. Establir variables globals significa que va donar a valors; sense inicialitzar variables globals significa que vostè encara no donen valors a. Llavors hi ha aquestes variables d'entorn que estic totalment d'ona va la mà menys, però hi són i que emmagatzema coses com el seu nom d'usuari i un altre tipus d'informació de nivell inferior. Però els més sucosos trossos de la disposició de la seva memòria és aquesta cosa anomenada la pila i el heap. La pila de nou, perquè quedi clar, és la memòria que s'utilitza cada vegada que es diu a funcions, sempre que hi ha variables locals i sempre que hi hagi paràmetres que es passen al voltant. Tot això passa a la pila. El munt no hem parlat, però prendre una conjectura que utilitza la pila. Només una part diferent de la memòria. Li passa a ser dibuixat aquí a la part superior, però això és una convenció pictòrica arbitrària. Qui està pel que sembla s'utilitza la memòria del munt per setmanes? És tècnicament però indirectament. >> [Estudiant] GetString. GetString i malloc. Així que aquí està la diferència fonamental. Saps per les últimes setmanes que si necessites memòria, només declarar una variable. Si vostè necessita molta memòria, declarar una matriu de dret dins de la seva funció. Però el problema que hem mantingut enfrontem és si declara les variables locals dins de funcions, tan bon punt la funció retorna, el que passa amb la memòria i les variables d'aquests? Només espècie que ja no és teu, no? Simplement desapareix una espècie de vista conceptual. Segueix sent físicament allà, òbviament, però ja no és el seu dret d'ús. Això és òbviament problemàtic si vols escriure funcions en la vida que en realitat assignar memòria i no tornar immediatament. Cas en qüestió: GetString propòsit en la vida és no tenir idea per endavant el gran d'una cadena que vaig a escriure en el teclat, sinó que ha de ser capaç d'assignar memòria per contenir David o hola o un assaig sencer que l'usuari podria haver escrit polz Així GetString ha estat usant malloc. Malloc per tant no ha d'utilitzar la pila; sinó que està fent servir aquesta cosa anomenada el munt. No hi ha res diferent a la memòria. No és més ràpid o més lent o alguna cosa per l'estil. És només físicament en un lloc diferent. Però la regla és que la memòria que està assignada a la pila Mai serà pres de vosaltres, fins que es diu - prendre una conjectura - lliure. Per contra, qualsevol memòria de demanar a la pila amb només declarar una matriu o declarar una variable com la que hem estat fent durant setmanes, que, per defecte acaba a la pila. I que funciona molt bé 90% del temps, però en aquestes ocasions més rares en la qual voleu assignar la memòria i mantenir al seu voltant, llavors vostè necessita utilitzar una funció com malloc. O hem utilitzat una funció com GetString, que al seu torn utilitza malloc. Anem a veure on podria trencar cap avall i després fer una ullada a Binky. Tornarem a que en el futur. Aquí hi ha un programa super senzill que en les primeres 2 línies fa què? En Anglès, què aquestes primeres 2 línies de codi realitzen dins de la principal? [Resposta dels estudiants inaudible] Amb cura. No em dóna la direcció de x o i. [Estudiant] Proporciona punters a sencers. Bé >>. Dóna'm 2 punteres a sencers. En altres paraules, em donen 2 trossos de memòria que guardo dibuix avui, tot i que l'ha esborrat ara, com quadrats. Dóna'm dos trossos de memòria, una trucada x, que es diu i - abans em deien s i t - i quin és el tipus d'aquest tros de memòria? Es va a emmagatzemar una adreça. * És de tipus int. Així que la direcció d'un int amb el temps va a viure en x, la direcció d'un int amb el temps va a viure en i, però en un principi, el que hi ha dins de x i y? Qui sap? Valors d'escombraries. No té res a veure amb punters. Si no hem posat una mica allà, qui sap el que està realment allà? Ara, x. Què passa aquí? Això és legítima perquè ara x un punter. És un * int. Així que això significa que puc posar en la direcció x d'algun tros de memòria. Què malloc tornar? Perfecte, retorna les adreces, la direcció del primer byte d'un tros sencer de memòria. Quants bytes s'està assignant pel que sembla, per exemple, en l'aparell? Quina és la mida d'un int? 4. Si penses en la setmana 1, no és super important recordar sempre que, però en aquest cas, és útil saber, 4 bytes. Així que aquesta és l'assignació en el munt de 4 bytes i es torna la direcció de la primera que em arbitràriament. Ara, què està fent x? A * x = 42 està fent què? Si en aquest punt de la història que tenim x, que té aquest aspecte amb un valor escombraries, això és ara i amb un valor escombraries, ara en la línia 3 que he assignat 4 bytes. Aquest quadre essencialment són aquestes. O més específicament, si aquesta és la direcció arbitrària 123, això és el que la nostra història ara sembla. * X = 42 ara què significa? Això vol dir anar a la direcció 123 i posar el número 42 hi. No cal dibuixar aquestes línies perquè no estem fent cadenes. Hi hauria d'haver escrit així, i només per causa de la manifestació, 42 com un tipus int ocupa molt espai, 4 bytes. Així que això és el que ha passat allà, però hi ha un problema ara. * I = 13. ¿Què passarà aquí? El problema és i * en el nostre món simplificat només significa anar a la direcció en i. Què hi ha a i? És cert valor escombraries. Així que anem a suposar que aquest valor és 5551212 escombraries, una mica de boig. * Significa que I s'abordaran 5551212. Això és així per aquí. No hi ha, per exemple. Així obté 13 * i mig que estic tractant de dibuixar 13 aquí. No existeix. He superat el segment de la pissarra. Què obtinc? Aquest missatge críptic error de segmentació perquè estic tractant de posar en la memòria un valor com 13 en un lloc que no existeix. La resta del programa pot funcionar bé, però fins a aquest moment no ho fa. Així que anem a tractar d'explicar aquesta història. Tornarem al fet que una vegada que hem parlat hexagonal. Tornem a això i concloure amb aquesta cosa anomenada Binky, que recordo és un professor de Stanford que se senti a casa jugant amb plastilina, per explicar la història de exactament el mateix programa. És només al voltant de 3 minuts de durada. Aquí tenim Binky. [Parlant masculí al vídeo] Hey Binky, desperta. És temps per a la diversió punter. [Binky] Què és això? Aprendre sobre els punters? Oh, que bé! [Parlant masculí] Bé, per començar, crec que necessitarem un parell de punters. [Binky] Bé. Aquest codi assigna 2 punteres que poden apuntar a sencers. [Parlant masculí] Bé. Bé, veig que els dos punters, però no semblen estar apuntant a res. [Binky] Això és correcte. Inicialment, els punters no apunten a res. Les coses que apunten són anomenats pointees i configurar és un pas separat. [Parlant masculí] Oh, és clar, és clar. Ja ho sabia. Els pointees estan separats. Er, així que com assignar un pointee? [Binky] Bé. Aquest codi assigna un nombre enter pointee nou, i aquesta part es presenten x perquè apunti a ell. [Parlant masculí] Hey, això es veu millor. Així que faci alguna cosa. >> [Binky] Bé. Vaig a eliminar la referència al punter x per emmagatzemar el número 42 en el seu pointee. Per aquest truc que vaig a necessitar la meva vareta màgica de la cancel · lació de referència. [Parlant masculí] La teva vareta màgica de l'eliminació de referències? Això és genial. [Binky] Això és el que el codi sembla. Vaig a establir el nombre i la ... [Apareixent de so] [Parlant masculí] Hey mira, aquí va. Així que fer una desreferencia de x segueix la fletxa per accedir al seu pointee, en aquest cas per emmagatzemar 42 a allà. Hey, tracta d'usar-lo per emmagatzemar el número 13 a través de l'altre punter, i. [Binky] Bé. Vaig a repassar aquí per obtenir ii el número 13 estableix i després prendre la vara d'eliminació de referències i només ... [Buzz] Whoa! [Parlant masculí] Oh bé, això no va funcionar. Diguem, Binky, no crec dereferencing i és una bona idea perquè la creació de la pointee és un pas separat i no crec que alguna vegada ho va fer. [Binky] Hmm, bon punt. [Parlant masculí] Yeah. Ens van assignar el punter i però mai posar perquè apunti a un pointee. [Binky] Hmm, molt observador. [Parlant masculí] Hey, et veus molt bé allà, Binky. Pots arreglar perquè i apunta a la pointee mateix que x? >> [Binky] Clar. Vaig a utilitzar el meu vareta màgica de l'assignació de punter. [Parlant masculí] És que serà un problema com abans? [Binky] No, això no toca les pointees. Només canvia un punter per assenyalar a la mateixa cosa que una altra. [Apareixent de so] [Parlant masculí] Oh, ja veig. Ara i apunta al mateix lloc que x. Així que esperar. Ara i és fix. Té un pointee. Així que vostè pot provar la vareta d'eliminació de referències tornar a enviar els més de 13 anys. [Binky] Uh, està bé. Heus aquí. [Apareixent de so] [Parlant masculí] Hey, mira això. Ara eliminació de referències a obres i. I pel fet que els punters que estan compartint un pointee, ambdós veuen el 13. [Binky] Sí, compartir. El que sigui. Així que anem a canviar de lloc ara? [Parlant masculí] Oh, mira, estem fora de temps. >> [Binky] Però - [Parlant masculí] Només recorda les 3 regles de punter. El número 1, l'estructura bàsica és que vostè té un punter i apunta a un pointee. Però el punter i pointee estan separats, i l'error comú és la creació d'un punter però us oblideu de donar-li un pointee. Número 2, desreferencia punter comença al punter i segueix el seu ratolí a sobre per accedir al seu pointee. Com tots sabem, això només funciona si hi ha un pointee, quin tipus de torni a la regla número 1. Número 3, assignació de punter pren un punter i el canvia perquè apunti a la pointee mateix com un altre punter. Així que després de la cessió, els 2 punters que apunten a la pointee mateix. De vegades això es diu compartir. I això és tot el que hi ha en realitat. Bye-bye ara. Això és Binky. Això és CS50. Ens veiem la setmana que ve. [Aplaudiment] [CS50.TV]