DAVID Malan: Molt bé, benvingut. Aquesta és CS50. Aquest és el començament de la setena setmana. Així que ha estat un temps, així que vam pensar que seria millor prendre un viatge llampec d'on som deixem i que ara estem passant. Així que aquesta cosa pugui tenir causat certa angoixa al principi. Però és d'esperar, que està començant a aclimatar-se a el que això denota aquí - estrella que representa un punter, que és just el que, en termes més senzills? Així que és una adreça. Així que és la direcció de alguna cosa a la memòria. I vam començar a pelar les capes Fa un parell de setmanes, les coses com GetString i altres funcions tot aquest temps han estat tornant adreces de les coses en la memòria, com el direcció del primer caràcter alguna seqüència. Així també vam introduir valgrind, que vostè començarà a utilitzar per a aquest problema establir, en particular per a la propera problema configurat així. I valgrind fa el que per a nosaltres? Comprova si hi ha fuites de memòria, i També comprova que hi ha abús de la memòria. Es pot, amb certa probabilitat, detectar si el codi es tocarà de memòria que simplement no hauria. Així que no és necessàriament una fugida, però si anar més enllà de les fronteres d'alguns matriu, i en realitat s'executa valgrind i induir a que el comportament, mentre que valgrind s'està executant en el seu programa és s'executa dins de la mateixa, obtindrà missatges com això - "no vàlid escriuen d' mida de 4 ", que, recordem un parell de Fa setmanes significava que havia accidentalment com en un int massa més enllà dels límits d'una matriu. I el que la mida 4 significa aquí la mida que int en particular. Així que pren consol en el fet que de sortida de valgrind, el format de la mateixa, és simplement atroç. És molt difícil veure a través del desordre per la informació interessant. Així que el que hem fet aquí és només fragment alguns dels parells de més línies interessants. Però adonar-se que el 80% de valgrind de sortida serà una mica d'un distracció. Només has de buscar patrons com aquests - invàlida dret, nul llegir 40 bytes i un nombre de blocs són definitivament perduts, paraules clau així. I què et esperem veure algun tipus de rastre del que funcionarà el error és en realitat polz En aquest cas aquí, en quina línia de el meu codi era aparentment l'error? 26 en un arxiu anomenat memory.c, que era l'exemple que estàvem jugant amb en el moment. Així que no és probable que en malloc. Probablement va ser en el meu codi al seu lloc. Així que anem a veure això de nou i de nou en poc temps. Així scanf, això va ocórrer en un parell de formes fins ara. Ens vam veure breument sscanf. Va ser una cosa un nombre de que es va capbussar en si els preparatius per al concurs. I scanf és en realitat el que el CS50 biblioteca ha estat utilitzant per sota de la campana des de fa força temps per tal per obtenir l'entrada de l'usuari. Per exemple, si em mut a la CS50 aparell aquí, deixa obrir una exemple, avui dia això es diu scanf-0.C I és super simple. És només unes poques línies de codi. Però demostra realment com getInt ha estat treballant tot aquest temps. En aquest programa aquí, a la línia 16 , Observi que em declaro 1 int. Així que no hi punters, res màgic allà, només un int. Després, en la línia 17, que inciten la usuari un nombre, per favor. Després a finals de 18, jo ús scanf aquí. I he especificat, una mena printf, que estic esperant cita Unquote cent i. Així cent i, per descomptat, denota un int. Però noti el que el segon argument per scanf és. Com descriuria el segon argument després de la coma? Què és això? És l'adreça de x. Així que això és útil ja que en proporcionar scanf amb la direcció de x, el que fa que faculten a aquesta funció a fer? No només ha d'anar-hi, però també fer què? Realitzar un canvi en ell. Com que vostè pot anar-hi, és una espècie de com un mapa a una ubicació en la memòria. I mentre vostè proporciona scanf o qualsevol funció amb un mapa a tal, que funció pot anar-hi, i no només mirar el valor, però també pot canviar aquest valor, la qual cosa és útil si el propòsit de la vida d'scanf és escanejar l'entrada de l'usuari, en concret des del teclat. I el f denota format, igual que printf, el f denota un format cadena que voleu imprimir. Així que en resum, la línia 18 simplement diu: tractar de llegir un int de l'usuari del teclat i guardar dins de x, en qualsevol que sigui la direcció x passa a viure en. I després, finalment, la línia 19 només diu, gràcies pel int, en aquest cas. Així que permetin-me anar endavant i fer això. Així que scanf 0. Deixin-me seguir endavant i fer més gran Vaig a córrer amb aquest punts frega scanf 0. Número, per favor? 50. Gràcies pel 50. Així que és bastant simple. Ara, què és el que no fa? No està fent un munt de comprovació d'errors. Per exemple, si jo no coopero, i jo no escric en un nombre, però vegada que escric alguna cosa així com "hola" això és una mica estrany. I el que una de les coses que l'CS50 biblioteca ha estat fent per nosaltres durant algun temps és que reprompting i reprompting. La retirada del mercat frase reintent estava en cs50.c, i aquesta és la raó per la qual en getInt la biblioteca CS50 és en realitat un conjunt manat de llargues cues, perquè estem comprovació de coses estúpides com aquesta. ¿No li dóna a l'usuari nosaltres, de fet, 01:00 int? ¿Ell o ella ens dóna alguna cosa com una lletra de l'alfabet? Si és així, volem detectar això i cridar. Però les coses es posen més interessants en el següent exemple. Si vaig a scanf-1.c, quina és la El que ha canviat fonamentalment en el següent exemple? Estic utilitzant char *, per descomptat, en lloc de int. Així que això és interessant, perquè char *, recordar, és en realitat la el mateix que la cadena. Així que se sent com potser això és un super implementació simple de GetString. Però he desprendre la capa de la biblioteca CS50, així que estic anomenar aquest char * ara. Així que anem a veure que, si en qualsevol lloc, ens equivoquem. Línia 17 - Una altra vegada dic, si us plau, dóna'm alguna cosa, en aquest cas, una cadena. I després, en la següent línia, que jo anomeno scanf, de nou, donant-li un codi de format, però aquesta vegada per cent s. I aquesta vegada, estic donant-li tampó. Ara noto, no estic fent servir la i comercial. Però per què és que, probablement, bé aquí? Perquè el que està memòria intermèdia ja? Ja és un punter. Ja és una adreça. I anem a la paraula "confondre", em va deixar simplement dir-s, per exemple, per simplicitat. Però jo he anomenat esmorteir perquè en en general, en la programació, si vostè té un part de la memòria, que una cadena molt just és, pot trucar a un buffer. És un lloc per emmagatzemar informació. Igual que en coses com YouTube, quan que estan tampó, per així dir-ho, que simplement vol dir que la descàrrega els bits de Internet i el seu emmagatzematge en un matriu local, una part local de la memòria per que es pot veure més endavant sense que salta o penjat a que durant la reproducció. Així que hi ha un problema aquí, però, perquè jo ho dic scanf, l'espera una cadena de l'usuari. Aquí està la direcció del un tros de memòria. Ficar aquesta cadena no. Per què és que la envoltant donar ens problemes, però? Què és això? Puc accedir a que parteix de la memòria? Vostè sap, jo ho sé. A causa que s'ha inicialitzat tampó a alguna cosa? En realitat no. I el que és el que hem estat trucant un valor d'escombraries, el que no és una paraula formal. Simplement vol dir que no tenim idea del que els bits es troben dins dels quatre bytes que els He assignat com a tampó. No he trucat a malloc. He definitivament no vaig trucar GetString. Llavors, ¿qui sap el que és en realitat dins de tampó? I no obstant això, diu scanf cegues, anar-hi i posar el que l'usuari escriu. Llavors, és probable que causi en el nostre codi si ho executem? Probablement sigui una violació de segment. Potser no, però probablement una violació de segment. I dic potser no, perquè a vegades ho fa, de vegades, no rep una violació de segment. A vegades només tenir sort, però que és, però, serà un error en el programa. Així que permetin seguir endavant i compilar això. Vaig a fer-ho de la manera de la vella escola. Així Clang tauler 0, scanf-1, scanf-1.c, Enter. Vaja, l'escola és massa vell. Anem a veure. Què vaig fer? Oh, char buffer *. Oh, gràcies - Deseu, OK - molt vella escola. Bé, ha estat un temps. Així que he acabo de salvar l'arxiu després d' fent que la temporal canviar fa un moment. I ara que he compilat manualment amb Clang. I ara em vaig a anar per davant i executar scanf-1, Enter. Cadena favor. Vaig a escriure "hola". I ara, aquí és on, francament, printf s'és una mica molest. No és en realitat va a segfault en aquest cas. Printf és una mica especial perquè és tan super d'ús comú que essencialment printf està fent Fes-nos un favor i adonar-se, això no és un punter vàlid. Déjame a mi mateix que acaba d'imprimir en parèntesi nul, fins i tot encara que no és necessàriament el que nosaltres esperàvem. Així que no podem induir molt fàcilment un segfault amb això, però és clar que no és el comportament que jo volia. Llavors, quina és la solució simple? Doncs bé, en scanf-2, permetin-me proposar que en lloc de en realitat només l'assignació d'una char *, deixa de ser una mica més intel · ligent sobre això, i em deixa assignar la memòria intermèdia com una seqüència de 16 caràcters. Així que puc fer això en un parell de maneres. Podria absolutament utilitzar malloc. Però puc tornar a la setmana dos quan Només necessitava un munt de personatges. Això és només una matriu. Així que permetin-me lloc redefinir memòria intermèdia en ser una matriu de 16 caràcters. I ara, quan pas de memòria intermèdia a - i això és una cosa que no ens parlar en dues setmanes - però es pot tractar a una matriu com encara que és una direcció. Tècnicament, com hem vist, són una mica diferent. Però scanf no li importarà si se li passa el nom d'una matriu, ja que el que Clang farà per nosaltres és essencialment tractar el nom de la matriu com la direcció de la part de 16 bytes. Així que això és millor. Això vol dir que ara que puc esperar feu el següent. Permetin-me Allunyar per un moment i fer fer scanf-2, compilat a OK. Ara m'ho dius fer aconseguir slash scanf-2. Cadena favor. "Hola." I semblava funcionar aquesta vegada. Però algú pot proposar un escenari en el qual no pot seguir funcionant? Sí? Una mica més de 16 caràcters. I, de fet, podem estar una mica més precisa. Una mica més llavors 15 caràcters, perquè realment hem de tenir en compte que és necessari que la barra invertida zero implícitament en l'extrem de la cadena, que és un a part scanf se solen tenir cura de nosaltres. Així que permetin-me fer una cosa així - A vegades podem simplement deixar-ho així. Acceptar, pel que hem va induir ara la decisió de segmentació. Per què? Com he escrit en més de 15 caràcters, pel que hem fet memòria tocat que en realitat No hauria d'haver fet. Llavors, què és realment la solució a aquest problema? Bé, i si necessitem una cadena més llarga? Bé, potser ho deixem 32 bytes. Bé, i si això no és suficient? Què hi ha de 64 bytes? I si això no és suficient? Què hi ha de 128 o 200 bytes? El que realment és la solució a aquest problema en el cas general, si no sabem en avançar en el que està passant a l'usuari que escrigui? És només una mena de gran dolor al cul, per ser sincer, de manera que la CS50 biblioteca compta amb una dotzena de línies de codi que implementen col · lectivament GetString cadena d'una manera que no ho fem cal saber per endavant el que el usuari va a escriure. En particular, si un mira cap enrere en cs50.c des de fa dues setmanes, vostè veurà que GetString fa realitat No utilitzeu scanf d'aquesta manera. Més aviat, es llegeix un caràcter alhora. Perquè l'única cosa bona de la lectura d'un personatge és el que podem ens garanteix que sempre tenir almenys un car. Només es pot declarar una xerrada i, a continuació, prendre aquests passos veritablement nadó a llegir un caràcter en l'1 moment des del teclat. I llavors, el que veuràs GetString Com és que cada vegada que es queda sense, dir, 16 bytes de memòria, s'utilitza malloc, o un cosí d'aquests, a assignar més memòria, còpia l'antiga memòria en la nova, i després arrossegar- junt, aconseguint un caràcter alhora, i quan es queda sense que part de la memòria, el tira, joc un tros més gran de la memòria, còpies antigues en noves i repeteix. I és realment un mal de realitat implementar una cosa tan simple com obtenir informació d'un usuari. Així que vostè pot utilitzar scanf. Podeu utilitzar altres funcions similars. I un munt de llibres de text i en línia exemples fan, però tots són vulnerables a problemes com aquest. I en última instància, aconseguir una violació de segment és una mica molest. No és bo per a l'usuari. Però en el pitjor dels casos, el que fa és fonamental posar el seu codi en risc d'? Algun tipus d'atac, el que podria. Parlem d'un d'aquests atacs - Desbordament de la pila. Però en general, si se li permet desbordament de memòria intermèdia, com ho va fer un Fa unes setmanes, amb només escriure més que "hola" a la pila, tampoc pot fer-se càrrec, en potència, un equip, o almenys arribar a les dades que no li pertany a vostè. Així que en resum, és per això que tenim les rodes d'entrenament. Però ara, comencem a treure-se'ls, com els nostres programes ja no necessiten, necessàriament, l'entrada de l'usuari. Però en el cas del problema plantejat 06:00, seva aportació provindrà d'una gran arxiu de diccionari amb 150 alguns imparells mil paraules. Així que vostè no haurà de preocupar per arbitrària d'entrada de l'usuari. Li donarem alguns supòsits sobre aquest arxiu. Teniu alguna pregunta respecte punters o scanf o l'entrada de l'usuari en general? Bé, de manera que un ràpid cop d'ull a continuació, en un tema s'arrossega des de fa dues setmanes. I aquesta va ser la idea d'una estructura. No és que - aquesta noció de estructura, que era el que? Què li struct fer per nosaltres? Definir - ho sento? Definir un tipus variable. Així que en certa manera. De fet, estem combinant dos temes. Així que amb typedef, recordem que podem declarar un tipus de la nostra, com un sinònim, com a cadena de char *. Però l'ús d'typedef struct i, podem crear veritablement les nostres pròpies estructures de dades. Per exemple, si vaig de nou en gedit aquí només per un moment, i segueixo endavant i fer una cosa així, vaig a salvar això com, diguem, structs.c temporalment, només vaig seguir endavant i incloure standardio.h, void main int. I després aquí, suposo que vull per escriure un programa que emmagatzema diversos estudiants de múltiples cases, per exemple. Així que és com un registrarial base de dades d'algun tipus. Així que si necessito el nom d'un estudiant, podria fer alguna cosa com caràcters Nom * i vaig a fer una cosa així - En realitat, farem servir la biblioteca CS50 per només un moment per fer d'aquest un mica més simple, pel que pot demanar prestat aquestes desenes de línies de codi. I anem a mantenir simple. El mantindrem cadena, i ara GetString. Així que pretenc ara que he emmagatzemat el nom d'algun estudiant, i la casa de algun estudiant, el simple ús de les variables com ho vam fer, i en la primera setmana. Però suposo que ara vull donar suport diversos estudiants. Molt bé, així que els meus instints tenen a veure string nom2, es GetString, string house2 es GetString. I el nostre tercer estudiant, farem name3 GetString. Molt bé, així que això és d'esperar sorprenent vostè com una mica estúpid, perquè aquest procés és realment mai va a acabar, i només va a fer el meu codi es vegi pitjor i pitjor i pitjor. Però vam resoldre això també en la segona setmana. Quina era la nostra solució relativament net quan vam tenir múltiples variables de l' mateix tipus de dades que estan relacionats, però que no volíem aquest embolic atroç de les variables de nom similar ¿ Què hem fet en el seu lloc? Així que crec que he sentit alguns llocs. Vam tenir una matriu. Per diverses còpies de alguna cosa, per què no netegem tot això i simplement dir, dóna'm array anomenat noms? I per ara, anem a codificar 3. I llavors dóna'm una altra matriu anomenat cases, i em va deixar per Codi dura ara 3. I jo he netejat massivament la embolic que acabo de crear. Ara, he encara fortament codificats 3, però encara el 3 podria venir dinàmica de la usuari, o argv, o similars. Així que això ja està més net. Però el que és molest d'això és que Ara, tot i que el nom és d'alguna manera fonamentalment vinculats a la casa d'un estudiant - és un estudiant que realment vol representar - Ara tinc dos arrays paral · lels en el sentit que són el mateixa mida i noms suport 0 presumiblement mapes a cases suport 0, i els noms del suport 1 mapes a les cases de suport 1. En altres paraules, que l'estudiant viu a aquesta casa, i que un altre estudiant que viu en una altra casa. Però segur que això podria ser fet encara més netament. Bé, pot, de fet. I m'ho dius a mi seguir endavant i obrir fins structs.h, i vostè veure aquesta idea aquí. Tingueu en compte que he fet servir typedef, com lusió fa un moment per declarar la nostra tipus de dades pròpia. Però també estic fent servir aquesta altra paraula clau anomenada struct el que em dóna una nova estructura de dades. I aquesta estructura de dades afirmo va de tenir dues coses a l'interior de és - una cadena anomenada nom, i una cadena anomenada casa. I el nom que vaig a donar a aquesta estructura de dades es va que es dirà estudiant. Podria dir-el que vulgui, però això semànticament fer sentit per a mi en la meva ment. Així que ara, si obro una versió millorada del programa que vaig començar a escriure allà, deixa desplaçar fins a la part superior. I hi ha alguna cosa més línies de codi aquí, però vull centrar-me en el moment en un. He declarat una constant crida als estudiants i codificat 3 per ara. Però ara, observi el net el meu codi comença a aconseguir. En la línia 22, declaro selecció dels estudiants. I noti que l'alumne és aparentment ara és un tipus de dades. A causa que en la part superior d'aquest arxiu, notarà He inclòs l'arxiu de capçalera que vaig arribar fa un moment. I aquest fitxer de capçalera simplement havia aquesta definició d'un estudiant. Així que ara, he creat els meus propis dades personalitzades tipus que els autors de C any Fa no pensar per endavant. Però no hi ha problema. Puc fer-ho jo mateix. Així que aquesta és una matriu anomenada alumnes, cada un dels membres és una estructura estudiant. I vull tres dels en la matriu. I ara, què fa el resta d'aquest programa fer? Jo necessitava una cosa una mica arbitrària. Així que de línia 24 en endavant, Una iteració de 0 a 3. Llavors els pregunto a l'usuari el nom de l'estudiant. I llavors jo ús GetString com abans. Llavors li pregunto a la casa de l'estudiant, i utilitzo GetString com abans. Però noti - Lleugerament nova tros de sintaxi - Encara puc índex per l'i-èsim estudiant, però com puc obtenir les dades específiques camp a l'interior de l'estructura? Bé, el que és aparentment el nova peça de la sintaxi? És només l'operador punt. No hem realment vist això abans. Vostè ho ha vist en el conjunt de processadors cinc si vostè té bussejat en ja amb els arxius de mapa de bits. Però el punt només significa dins d'aquest estructura o diversos camps, donen punts nom, o em dóna house punt. Això significa anar dins de l'estructura i obtenir els camps particulars. Què fa la resta d'aquest programa ho faci? No tot és tan sexy. Tingueu en compte que una iteració de 0 a 3 més, i jo simplement crear una Anglès frase com això i allò altre és de tal una casa per exemple, passant el nom del punt de l'i-èsim alumne i la seva casa també. I finalment, ara anem a començar a obtenir anal sobre això, ara que estem familiaritzat amb el que malloc i d'altres funcions han estat fent tot aquest temps. Per què he d'alliberar tant el nom i de la casa, tot i que no trucar a malloc? GetString va fer. I aquest va ser el petit i brut secret de diverses setmanes, però GetString té es perd memòria a tot el col · locar tot el semestre fins al moment. I finalment Valgrand revelar això a nosaltres. Però no és una gran cosa, perquè sé que simplement puc alliberar el nom i la casa, encara que tècnicament, a ser súper, súper segur, hauria de ser fent un repàs de les faltes aquí. Quins són els teus instints et diuen? Quina hauria de ser la comprovació de abans que jo Què és un cordes, també conegut com el qual un char *? Realment ha de comprovar si els alumnes Suport nom i punt no igual nul. Llavors estarà bé per seguir endavant i lliure aquest punter, i la mateixa o una altra un així. Si els estudiants bracket casa i punt no és igual a null, això ara va a protegir contra el cas de la cantonada en què GetString torna alguna cosa així com nul. I vam veure fa un moment, es printf protegir aquí amb només dir null, el que va a semblar estrany. Però almenys no violació de segment, com hem vist. Bé, deixa fer una cosa aquí. estructures-0 és una mena de programa estúpid perquè entro totes aquestes dades i, a continuació, es perd un cop acabi el programa. Però m'ho dius anar endavant i fer això. Vull deixar el terminal finestra una mica més gran. Permetin-me fer estructures-1, que és una nova versió d'aquest. Vaig a apropar una una mica. I ara m'ho dius córrer dot reduir les estructures-1. Nom de l'estudiant - David Mather, farem Rob Kirkland, farem Lauren Leverett. L'interessant ara és avís - i només jo sé perquè Vaig escriure el programa - hi ha un arxiu ara en el meu actual directori anomenat students.csv. Alguns de vosaltres heu vist aquests en el món real. Què és un arxiu CSV? Valors separats per comes. És com un home pobre versió d'un arxiu d'Excel. És una taula de files i columnes que pot obrir en un programa com Excel, o números en un Mac I si obro l'arxiu aquí a gedit, avís - i els números no hi són. Això és només gedit dient em números de línia. Recordeu que en la primera línia d'aquesta arxiu és David and Mather. La següent línia és Rob comes Kirkland. I la tercera línia és Lauren coma Leverett. Llavors, què he creat? Ara que he escrit un programa en C que efectivament pot generar fulls de càlcul que es pot obrir en un programa com Excel. No tot el que obligar a un conjunt de dades, però si té trossos molt grans de dades que en realitat es vol manipular i fer gràfiques i de les com, això és potser un manera de crear aquestes dades. D'altra banda, CSV són realment súper comú només per emmagatzemar dades simples - Yahoo Finance, per exemple, si obté cotitzacions de borsa a través de la seva trucada API, el servei gratuït que li permet poseu-vos al dia proveir-se a la data les cotitzacions de les empreses, que donar les dades de nou en el súper format CSV simple. Llavors, com ho fem? Ben comunicat, la major part d'aquest programa de gairebé la mateixa. Però noti aquí baix, en lloc d'imprimir els estudiants de fora, en la línia 35 en endavant, em diuen que m'estic estalviant el estudiants en el disc, així que guardar un arxiu. Llavors noto que estic declarant un FILE * - Ara, això és una espècie d'anomalia en C. Per alguna raó, FILE és tot en majúscules, que no és com la majoria d'altres tipus de dades de C. Però això és un predefinit tipus de dades, FILE *. I estic declarant un punter a un arxiu, és com es pot pensar en això. fopen significa obrir l'arxiu. Què fitxer que voleu obrir? Vull obrir un arxiu que jo vull arbitràriament truqui students.csv. Podria trucar a que qualsevol cosa que jo vulgui. I després prendre una conjectura. Què fa el segon argument a fopen probablement vol dir? Dreta, w per escriptura, podria ser r per a lectura. Hi ha una per append si voleu afegir files i no sobreescriure tot. Però jo només vull crear aquest arxiu una vegada, així que faré servir cita unquote w. I sé que només per haver llegit la documentació, o de la pàgina del manual. Si l'arxiu no és nul - en altres paraules, si res va sortir malament allà - m'ho dius recórrer en iteració els alumnes de 0 a 3. I ara noten que hi ha alguna cosa lleugerament diferent sobre la línia 41 aquí. No és printf. És fprintf d'arxiu printf. Així que va a escriure a l'arxiu. Què arxiu? Aquell el punter s'especifica com a primer argument. A continuació s'especifica una cadena de format. A continuació especifiquem quina cadena que volem connecti per primera cent s, i a continuació, una altra variable o la segona per cent s. Després tanquem l'arxiu amb fclose. Del que alliberar la memòria com abans, encara He tornar i afegir algunes comprovacions per null. I això és tot. fopen, fprintf, fclose em dóna la capacitat de crear arxius de text. Ara, vostè veurà en conjunt de problemes 5, que consisteix en imatges, es va a utilitzar arxius binaris en lloc. Però fonamentalment, la idea és la mateixa, tot i que les funcions que comptaràs veure són una mica diferents. Així gira llampec, però vostè rebrà molt familiaritzat amb l'arxiu I/O-- entrada i sortida - amb el conjunt de processadors 05:00. I qualsevol pregunta sobre l' fonaments inicials aquí? Sí? Què passa si vostè tracta d'alliberar un valor nul? Crec que, a menys lliure ha aconseguit un poc més fàcil d'usar, es pot potencial violació de segment. Passar nul · la és dolent perquè no ho faig creure sense la molèstia de comprovar per tu, perquè podria ser potencialment una pèrdua de temps perquè ho faci per si mateix tots en el món. Bona pregunta, però. Bé, pel que aquest tipus de es nosaltres un tema interessant. El tema del butlletí de problemes 05:00 és forense. Almenys aquesta és una part del conjunt de problemes. Forense es refereix generalment a la la recuperació de la informació que pot o No pot haver estat esborrat deliberadament. I així que vaig pensar que li donaria una ràpida mostra del que realment està passant tot aquesta vegada per sota de la capó del seu ordinador. Per exemple, si vostè té dins del seu portàtil o l'ordinador d'escriptori a disc dur, o és un mecànic dispositiu que gira realitat - hi ha coses circulars anomenats plats que es veuen força com el que només tenia a la pantalla aquí, encara aquesta és l'escola cada vegada més vella. Aquesta és una de tres i mitja polzades unitat de disc dur. I 3:30 polzades es refereix de amb la de la cosa quan l'instal en un ordinador. Molts de vostès en els seus ordinadors portàtils ara que les unitats d'estat sòlid, o SSD, que no tenen parts mòbils. Són més com RAM i menys com aquests dispositius mecànics. Però les idees continuen sent les mateixes, sens dubte pel que fa al problema d'establir 05:00. I si ho penses ara d'un disc dur representa ser un cercle, el qual Vaig a dibuixar com això aquí. Quan es crea un arxiu en l'equip, si es tracta d'un SSD, o en aquest cas, una escola de disc dur més gran, arxiu que comprèn múltiples bits. Diguem que és 0 i 1, un munt de 0s i 1s. Així que aquest és el meu disc dur sencer. Aparentment és un arxiu bastant gran. I s'està utilitzant el 0 i 1 en aquest porció de la font física. Bé, el que és la part física? Bé, resulta que en un disc dur, almenys d'aquest tipus, hi ha aquestes petites partícules magnètiques petites. I ells tenen essencialment nord i pols sud a ells, de manera que si al seu torn una d'aquestes partícules magnètiques d'aquesta manera, es podria dir que es tracta d' que representa l'1. I si és a l'inrevés sud a nord, es podria dir que es tracta d' que representa un 0. Així que en el món físic real, això és com es pot representar alguna cosa en estat binari de 0 i 1. Així que això és tot un arxiu és. Hi ha un munt de magnètica partícules que són d'aquesta manera o el seu d'aquesta manera, la creació de patrons de 0 i 1. Però resulta que quan es guarda un arxiu, alguna informació es guarda per separat. Així que aquesta és una petita taula, un directori, per dir-ho. I vaig a trucar a aquest nom de columna i Vaig a trucar a aquesta ubicació de la columna. I jo vaig a dir, suposem aquesta és la meva full de vida. El meu resume.doc s'emmagatzema en ubicació, diguem 123. Sempre vaig per aquest nombre. Però cal dir que igual que en la memòria RAM, es pot prendre una unitat de disc dur Això és un gigabyte o 200 gigabytes o d'un terabyte, i es pot nombre de tots els bytes. Pot numerar totes trossos de 8 bits. Així que anem a dir que aquest és la ubicació 123. Així que aquest directori a de la meva intervenció sistema recorda que el meu full de vida és en la ubicació 123. Però es posa interessant quan s'elimina un arxiu. Així, per exemple - i per sort, la major part del món té atrapat en això - el que passa quan arrossega un arxiu al teu Mac OS Trash o la Paperera de reciclatge de Windows? Quin és el propòsit de fer això? És obvi que és desfer-l'arxiu, però el que fa l'acte d'arrossegar i caure en la paperera o, si Recycle Bin fer en un ordinador? Absolutament res, de veritat. És com una carpeta. És una carpeta especial, per estar segur. Però realment esborrar l'arxiu? Bé, no, perquè alguns de vostès probablement han estat, oh maleïda sigui, no ho va fer vaig voler fer això. Així es fa doble clic al Trash o Paperera de reciclatge. Vostè ha furgar i que s'hagi recuperat l'arxiu simplement arrossegant d'aquí. Així que, clarament, no és necessàriament eliminar-lo. Bé, ets més intel · ligent que això. Vostè sap que només arrossegant-la a la Trash o Paperera de reciclatge no significa estàs buidar la paperera. Així que anar fins al menú, i vostè diu Buidar paperera o paperera de reciclatge buida. Llavors, què passa? Sí, per la qual cosa s'elimina més. Però tot el que passa és això. L'ordinador s'oblida que resume.doc era. Però el que no ha canviat de parer a la foto? Els bits del 0 i 1 que reclamo són en el lloc d'algun aspecte físic del el maquinari. Encara hi són. És només que l'equip té oblidat del que són. Pel que és essencialment alliberat del fitxer bits de manera que puguin ser reutilitzats. Però no és fins que es creu més arxius, i més arxius i més arxius probabilísticament, els 0s i 1s, les partícules magnètiques, es reutilitzen, banda a l'alça oa la dreta, si altres arxius, 0s i 1s. Pel que té aquesta finestra de temps. I no és d'predictible longitud, de veritat. Depèn de la mida del seu disc unitat i la quantitat d'arxius que té i la rapidesa amb què fer-ne de noves. Però hi ha aquesta finestra de temps durant el que aquest arxiu és encara perfectament recuperable. Així que si alguna vegada utilitza programes com McAfee o Norton per intentar recuperar dades, l'únic que estan fent és intentar recuperar la trucada directori per esbrinar on l'arxiu va ser. I a vegades Norton i dirà: arxiu és el 93% de reemborsament. Bé, què significa això? Això significa simplement que algú altre arxiu casualment va acabar usant, per exemple, aquests bits fora del seu arxiu original. Així que el que realment està involucrada en la recuperació de les dades? Bé, si vostè no té alguna cosa com Norton pre-instal lat al seu ordinador, el millor de vegades es pot fer és mirar en tot el disc dur a la recerca d' els patrons de bits. I un dels temes del conjunt de problemes 05:00 és que va a buscar el equivalent a un disc dur, un forense imatge d'una targeta Compact Flash d'un càmera digital, la recerca de la 0s i 1s que normalment, amb alta probabilitat, representar la l'inici d'una imatge JPEG. I vostès poden recuperar aquestes imatges per assumint, si veig a aquest patró de bits a la imatge forense, amb alta probabilitat, que marca l'inici d'un JPEG. I si veig el mateix patró altra vegada, que probablement marca l'inici de la altra JPEG, i un altre JPEG, JPEG i un altre. I això és en general la forma recuperació de dades funciona. El millor dels arxius JPEG és tot i que el mateix format de fitxer és una cosa complex, el començament de cada un d'aquests arxiu és en realitat bastant identificable i simple, com es veurà, si no tens ja. Així que anem a fer una ullada més de prop per sota la campana quant a exactament el que ha estat passant, i el que aquests 0s i 1s són, per donar-li una mica més d'un context per a aquest desafiament particular. [REPRODUIR VIDEO] -Quan el PC emmagatzema la majoria de les seves dades permanents. Per a això, les dades viatgen des de la RAM juntament amb els senyals de programari que li diuen el disc dur de la forma d'emmagatzemar les dades. Els circuits de disc dur es tradueixen aquests senyals en tensió fluctuacions. Aquests, al seu torn, controlen la unitat de disc peces en moviment, alguns dels pocs parts mòbils que queden al ordinador moderna. Algunes de les senyals de control d'un motor que fa girar discos de metall recoberts. Les seves dades s'emmagatzemen en realitat en aquests discos. Altres senyals es mouen de lectura / escriptura caps de lectura o escriure dades als discs. Aquest mecanisme tan precís que un ésser humà pèl ni tan sols podia passar entre el caps i plats giratoris. No obstant això, tot funciona a velocitats fenomenals. [FI REPRODUCCIÓ DE VÍDEO] DAVID Malan: Zoom en una petita més ara en el que és en realitat en els plats. [REPRODUIR VIDEO] -Fem una ullada al que acabem de va veure en càmera lenta. Quan un breu pols d'electricitat és enviat al capdavant de lectura / escriptura, si volteja en una petita electromagnètica per una fracció d'un segon. L'imam crea un camp, el qual canvia la polaritat d'un petit, petit part de les partícules de metall que abric de cada superfície del disc. Una sèrie de patrons d'aquests petits, àrees de càrrega-per amunt en el disc representa un sol bit d' les dades en el nombre binari sistema utilitzat per les computadores. Ara bé, si s'envia el corrent d'una manera a través de la lectura / escriptura del cap, la zona és polaritzada en una direcció. Si el corrent s'envia al direcció oposada, la polarització s'inverteix. Com obtenir les dades des del disc dur? Simplement revertir el procés. Així que les partícules en el disc que aconsegueix el corrent en el lectura / escriptura cap mòbil. Poseu a milions d'aquests segments magnetitzats, i vostè té un arxiu. Ara, les peces d'un sol arxiu pot estar dispersos per tota una unitat de plats, una mena el desordre de papers en el seu escriptori. Així que un arxiu sigui especial seguiment d'on està tot. No t'agradaria tenir una cosa així? [FI REPRODUCCIÓ DE VÍDEO] DAVID Malan: OK, probablement no. Llavors, quants de vostès Vaig créixer amb ells? Acceptar, pel que és cada vegada menys mans cada any. Però m'alegro que estigui almenys familiaritzats amb ells, perquè això i la nostra pròpia Demo del llibre, per desgràcia, s'estan morint molt retardar la mort aquí de familiaritat. Però això és el que, almenys, de nou en l'escola secundària, l'ús s'utilitza per a còpies de seguretat. I va ser increïble, perquè podria emmagatzemar en 1,4 megabytes aquest disc en particular. I aquesta va ser la versió d'alta densitat, com s'indica per l'HD, que té és a dir, abans de vídeos d'alta definició d'avui en dia. La densitat estàndard va ser de 800 kilobytes. I abans d'això, havia Discos de 400 kilobytes. I abans d'això, hi havia 5 i 1/4 discos polzades, que eren veritablement flexible, i una mica més ample i més alt que aquestes coses aquí. Però en realitat es pot veure l'anomenada aspecte disquet d'aquests discos. I funcionalment, en realitat són molt similars als discs durs de l' menys d'aquest tipus. Un cop més, els SSD en els equips més nous treballar una mica diferent. Però si trasllada la llengüeta de metall petita, en realitat es pot veure una mica de galeta, o safates. No és de metall com aquest. Aquest és en realitat alguns més barats material plàstic. I vostè pot tipus de maniobra és. I has vaig apuntar només esborrat alguns nombre de bits o partícules magnètiques des d'aquest disc. Així que gràcies a Déu, no hi ha res en ell. Si això està en el camí - i cobrir els seus ulls i els del seu veí - vostè pot simplement llençar d'aquest tipus de conjunt de beina així. Però hi ha una mica de primavera, així que vés conscient que amb els ulls. Així que ara vostè té realment un disquet. I el que és notable sobre aquest és que en tant com aquest és un representació a petita escala d'un major disc dur, aquestes coses són super, super simple. Si es pessiga la part inferior de la mateixa, ja que aquesta cosa de metall està apagat, i la closca obrir-los, tot el que hi ha és dues peces de feltre i l'anomenada disquet amb una peça de metall a l'interior. I aquí va la meitat de el contingut del meu disc. Aquí va un altre mitjà d'ells. Però això és tot el que gira a l'interior del seu equip en antany. I a més, a posar això en perspectiva, el gran que és la major part de la seva discs durs d'avui en dia? 500 gigabytes, un terabyte potser en un ordinador d'escriptori, 2 terabytes, 3 terabytes, 4 terabytes, oi? Es tracta d'un megabyte, més o menys, que ni tan sols poden adaptar a una típica MP3 anymore aquests dies, o alguns arxiu de música similar. Així que un petit record per a tu avui, i també per ajudar a contextualitzar el anem a prendre per fet ara en el problema d'establir 05:00. Així que aquests són teus per sempre. Així que em va passar a on serà passar al següent conjunt de processadors també. Així que hem creat ara aquesta pàgina de - oh, un parell d'anuncis de forma ràpida. Aquest divendres, si vol unir-se a CS50 per dinar, anar al lloc de costum, cs50.net/rsvp. I el projecte final - pel que el pla d'estudis, hem publicat la especificacions del projecte definitiu ja. Adonar-se que això no vol dir que és degut sobretot aviat. Ha publicat, en realitat, només per obtenir vostès pensar-hi. I, en efecte, un super significativa percentatge dels que s'afronta projectes fi de carrera en el material que ni tan sols han arribat a la classe, però serà tan aviat com la setmana que ve. Noteu, però, que l'especificació exigeix uns pocs components diferents de la projecte final. El primer, en unes poques setmanes, és una pre-proposta, un correu electrònic bastant informal per el TF per dir o què ets pensant per al seu projecte, amb sense compromís. La proposta serà la seva particular, compromís, dient aquí, això és el que M'agradaria fer per al meu projecte. Què pensa vostè? Massa gran? Massa petit? És manejable? I veuen l'especificació per a més detalls. Un parell de setmanes després que l'estat informe, que és una forma similar email informal al teu TF dir el molt per darrere es troba en la seva última aplicació del projecte, seguit per el CS50 Hackathon a la qual tots és convidat, que serà un esdeveniment de 20:00 una nit fins les 7:00 Am del matí següent. Pizza, com jo ho he dit a la setmana zero, ho vagi a servir a les 9:00 PM, Menjar xinès a les 1:00 h. I si vostè encara està despert a les 5:00 PM, el portarem a IHOP per esmorzar. Així que la Hackathon és un dels més experiències memorables a la classe. A continuació, l'aplicació es deu, i llavors el clímax CS50 Fair. Més detalls sobre totes aquestes en les properes setmanes. Però tornem a alguna cosa vella escola - de nou, una matriu. Així que una sèrie estava molt bé, ja que resol problemes com vam veure només una fa actualment amb les estructures estudiantils posant una mica fora de control si vull tenir un estudiant, estudiant 2, 3 estudiants, estudiant dot dot dot, un nombre arbitrari dels estudiants. Així arrays, fa unes setmanes, es va abalançar a i resolt tots els nostres problemes de no sabent per endavant la quantitat de coses d'algun tipus que podríem desitjar. I hem vist que les estructures poden ajudar organitzar millor el nostre codi i mantenir les variables conceptualment similars, com un nom i una casa, junts, pel que es tracten com un sol entitat, a l'interior dels quals hi ha peces més petites. Però matrius tenen alguns desavantatges. Quines són algunes de les desavantatges ens hem trobat amb les matrius fins al moment? Què és això? Mida fix - pel que tot i que podria ser capaç d'assignar memòria per a una matriu, un cop heu escoltat el nombre d'estudiants vostè té, quants caràcters té per part de l'usuari, un cop ha assignat la matriu, has classe de pintades a tu mateix en una cantonada. Perquè no es pot inserir nous elements al centre d'una matriu. No es pot inserir més elements al final d'una matriu. Realment, cal recórrer a la creació d'un conjunt completament nou, com hem comentat, la còpia de l'antiga a la nova. I de nou, que és el mal de cap que GetString ofertes per tu. Però, de nou, ni tan sols es pot inserir alguna cosa al centre de la matriu si la taxa no s'omple completament. Per exemple, si aquesta matriu aquí de mida sis només té cinc coses en ella, així, vostè podria virar alguna cosa a l'extrem. Però el que si desitja inserir una cosa en el medi de la conjunt, tot i que podria tenir cinc dels sis que hi ha en ell? Bé, què podem fer quan teníem tot dels nostres voluntaris en l'escenari en setmana passat? Si volguéssim posar a algú aquí, ja sigui aquestes persones com moure aquest manera, o aquesta gent com moure aquest manera, i que es va convertir car. El desplaçament de persones a l'interior d'un array acabar sumant i costos nosaltres temps, per tant, gran part del nostre n quadrat temps de funcionament com l'ordenació per inserció, per exemple, en el pitjor dels casos. Així les matrius són grans, però cal sap per endavant la mida que voleu. Així que bé, aquí està la solució. Si no sé per endavant quantes estudiants que puguin tenir, i sé que un cop Jo decideixo, però, m'he de quedar amb aquesta molts estudiants, per què no ho faig jo sempre assignar el doble d'espai com podria pensar que necessito? ¿No és una solució raonable? Sent realistes, no crec que estem va a necessitar més de 50 ranures en un arranjament per una classe de grandària mitjana, així que anem a la tornada de dalt. Faré 100 slots en el meu matriu, només perquè puguem aconseguir definitivament la nombre d'estudiants que espero estar en alguna mena de grandària mitjana. Així que per què no reunir i assignar més memòria, en general, per a una matriu del que pensa que fins i tot podria necessitar? Què és aquest simple retrocés a aquesta idea? Estàs perdent la memòria. Literalment, cada programa s'escriu a continuació, és potser l'ús del doble de memòria que que realment necessita. I això simplement no se sent com un particularment elegant solució. D'altra banda, només es disminueix la probabilitat que un problema. Si li passa que té un curs molt popular un semestre i té 101 els estudiants, el programa segueix sent s'enfronta fonamentalment el mateix problema. Així que per sort, hi ha una solució per a Aquest anunci de tots els nostres problemes en forma d'estructures de dades que estan més complexos que els que hem vist fins al moment. Això, afirmo, és una llista enllaçada. Aquesta és una llista dels números - 9, 17, 22, 26, i 34 - que han estat units entre si per mitjà del que he dibuixat com fletxes. En altres paraules, si jo volia representar una matriu, que podria fer alguna cosa com això. I vaig a posar això al cap en un moment. Que podia fer - hola, molt bé. En espera. Equip nou aquí, és clar - Està bé. Així que si tinc aquests números en ordre de batalla - 9, 17, 22, 26, 24 - no necessàriament a escala. Molt bé, així que aquí està la meva sèrie - oh el meu déu. Molt bé, així que aquí està la meva matriu. Oh, Déu meu. [El] DAVID Malan: Pretend. És massa esforç per tornar i arreglar això, de manera que - 26. Així que tenim aquest conjunt de 9, 17, 22, 26, i 34. Per a aquells de vostès pot veure el vergonyós error que acaba de fer, aquí està. Per això afirmo que es tracta d'una solució molt eficient. He assignar tants punts com Necessito - un, dos, tres, quatre, cinc, o sis - i després m'he emmagatzemat els números dins d'aquesta gamma. Però suposem que, aleshores, vull inserir un valor com el número 8? Bé, on va? Suposem que vull inserir un nombre com 20. Bé, on va? En algun lloc en el medi, o el nombre 35 ha d'anar en algun lloc a l'extrem. Però m'he quedat sense espai. I així, aquest és un repte fonamental de matrius que no són la solució. Vaig afirmar fa un moment, GetString resol aquest problema. Per inserir un sisè nombre en aquesta matriu, el que és com a mínim un solució que vostè pot recórrer amb certesa, igual que fem amb GetString? Què és això? Bé, fer-lo més gran es més fàcil de dir que de fer. No podem necessàriament que la matriu més gran, però què podem fer? Fer una nova matriu que és més gran, de la mida d' 6, o potser de la mida 10, si volem per avançar-se a les coses i, a continuació, copiar l'antiga matriu a la nova, i després alliberar la vella matriu. Però quin és el temps d'execució ara d'aquest procés? És gran O de n, a causa que la còpia costarà algunes unitats de temps, així que no és tan ideal si hem de assignar una nova gamma, que va per consumir dues vegades com a molt memòria temporalment. Copieu vell en nou - Vull dir, és només un mal de cap, que és, de nou, per què escrivim GetString per a vostè. Llavors, què podríem fer en el seu lloc? Bé, i si la nostra estructura de dades en realitat té llacunes en ella? Suposem que em relaxo meu objectiu de tenir blocs contigus de memòria, en la seva 9 està just al costat de 17, que és just al costat de 22, i així successivament. I suposem que el 9 pot ser aquí a RAM, i 17 poden estar aquí a la memòria RAM, i 22 poden estar aquí a la RAM. En altres paraules, jo no els necessito fins i tot Esquena amb esquena més. Només he de enfilar una agulla d'alguna manera a través de cada un d'aquests números, o cada un d'aquests nodes, ja que anem a cridar l' rectangles com jo els he dibuixat, a recordar com arribar a l'última tals node de la primera. Llavors, quina és la construcció de programació que hem vist fa poc amb la qual pot implementar aquest fil, o dibuixat aquí, amb la qual puc aplicar aquestes fletxes? Punters així, oi? Si no assigna només una int, però un node - i per node, em refereixo a contenidor. I visualment, em refereixo a un rectangle. Així aparentment necessita un node per contenir dos valors - el mateix int, i després, com es dedueix de la meitat inferior del rectangle, espai suficient per a un int. Així que pensant en el futur aquí, el gran que és aquest node, això contenidor de què es tracti? Quants bytes per al int? Presumiblement 4, si és la mateixa, com de costum. I llavors quants bytes per al punter? 4. Així que aquest contenidor o aquest node, és serà una estructura de 8 bytes. Ah, i això és una feliç coincidència que que acaba de presentar aquesta idea de una estructura o una estructura de C. Per això afirmo que vull donar un pas cap a aquest més sofisticat aplicació d'una llista de nombres, un llista enllaçada de nombres, he de fer una poc més de pensament en la davantera i declarar no només un int, però una estructura que vaig a trucar, convencionalment aquí, el node. Podríem dir qualsevol cosa que vulguem, però node serà temàtics en un munt de les coses que vam començar veient ara. A l'interior d'aquest node és un n int. I després aquesta sintaxi, una mica estrany a primera vista - struct node * següent. Bé il · lustrat, què és això? Aquesta és la part inferior de el rectangle que vam veure fa un moment. Però per què estic dient struct node * en lloc de només node *? Perquè si aquest punter apunta en un altre node, és només la direcció d'un node. Això és coherent amb el que hem discutit sobre els punters fins al moment. Però per què, si puc reclamar aquesta estructura és anomenat node, he de dir struct node dins d'aquesta llista? Exactament. És una espècie d'una realitat estúpida C. La definició de tipus, per així dir-ho, no té succeït encara. C és molt literal. Es llegeix el codi a la part superior baix, d'esquerra a dreta. I fins que arribi a aquest punt i coma a la línia de fons, suposo que el que no existir com un tipus de dades? Node, el node entre cometes. Però a causa de la més detallat declaració que vaig fer a la primera línia - node typedef struct - ja que va ser primer, abans de la claus, això és una cosa així com pre-educar Clang això, saber què, dóna'm una estructura anomenat node d'estructura. Francament, no m'agraden les coses de trucades struct node, struct node tot a través del meu codi. Però jo només vaig a utilitzar una vegada, just a l'interior, perquè jo pugui efectivament crear una mena de referència circular, no un punter a mi mateix per se, sinó un punter a un altre de un tipus idèntic. Per tant, resulta que en una estructura de dades així, hi ha uns quants operacions que podrien ser d'interès per a nosaltres. Potser voleu inserir en una llista com aquesta. Potser voleu suprimir a partir d'una llista com aquesta. Pot ser que vulgueu cercar a la llista de valor, o més en general, transversal. I travessa és només una forma elegant de dient començament a l'esquerra i seguir tot el camí a la dreta. I fixin-se, fins i tot amb aquest una mica més estructura de dades sofisticada, deixi em proposo que puguem demanar prestat una mica de les idees de les últimes dues setmanes i implementar una funció anomenada buscar així. Es va a tornar true o falsa, el que indica, si o no, n és a la llista. El seu segon argument és un punter a la llista en si pel que un punter a un node. Tot el que faré és declarar a continuació una variable temporal. L'anomenarem ptr per convenció, per al punter. I jo assigno igual a la principi de la llista. I ara observeu el bucle while. Mentre punter no és igual en nul, vaig a comprovar. És punter de fletxa n igual a n el que es va aprovar? I esperar un minut - nou tros de sintaxi. Què és la fletxa, de sobte? Sí? Exactament. Així que mentre que fa uns minuts, es va utilitzar la notació de punts per accedir a alguna cosa a l'interior d'un l'estructura, si la variable que tenen no és l'estructura si mateix, sinó un punter a una estructura, per sort, un tros de sintaxi finalment té sentit intuïtiu. La fletxa significa seguir el punter, com les nostres fletxes normalment signifiquen gràficament, i anar a camp de dades a l'interior. Així fletxa és la mateixa cosa que punt, però utilitzar quan es té un punter. Així que per recapitular a continuació, si el camp n interior de l'estructura anomenada punter igual a igual a n, torni realitat. En cas contrari, aquesta línia aquí - punter és igual a punter següent. Llavors, què està fent això, avís, és si Actualment estic apuntant a l'estructura que conté 9, i 9 no és el nombre Busco - Suposo que estic buscant per n és igual a 50 - Vaig a actualitzar el meu punter temporal al no assenyalar en aquest node més, però punter de fletxa del costat, que em posarà aquí. Ara, em vaig adonar és un remolí la introducció. Dimecres farem realitat aquest amb alguns éssers humans i amb una mica més codi a un ritme més lent. Però adonar-se, ara estem fent els nostres dades estructures més complexes perquè el nostre algoritmes pot obtenir més eficient, el que serà necessari per PSET 6, quan carreguem en, de nou, els 150.000 paraules, però ho ha de fer eficient, i l'ideal és crear un programa que té una durada de nostres usuaris no lineal, no en n quadrat, però en constant de temps, en l'ideal. Ens veiem dimecres. ALTAVEU: En la següent CS50, David oblida el seu cas base. DAVID Malan: I aquesta és la forma d'enviar missatges de text amb C. El que el - [MISSATGE DE TEXT DIVERSOS NOTIFICACIÓ DE SONS]