[Powered by Google Translate] [Setmana 5] [David J. Malan - Harvard University] [Aquesta és CS50. - CS50.TV] Això és CS50, la Setmana 5. Avui en dia, i aquesta setmana, presentem una mica del món de la ciència forense en el context del butlletí de problemes 4. Avui serà una lliçó abreujada perquè hi ha un esdeveniment especial a aquí després. Així que anem a fer una ullada i es burlen tant dels estudiants com per als pares d'avui dia amb algunes de les coses que estan en l'horitzó. Entre ells, a partir de dilluns, tindrà una mica més dels seus companys de classe. EDX, Harvard i la nova iniciativa en línia del MIT OpenCourseWare i per més, està posant en marxa al campus de Harvard, dilluns, el que significa venir dilluns tindrà, a partir de l'últim recompte, 86.000 companys de classe addicionals que estarà seguint al llarg de amb xerrades CS50 i les seccions i els tutorials i els conjunts de problemes. I com a part d'això, es convertiran en membres de la classe inaugural del CS50 i CS50x ara. Com a part d'això ara, s'adonen que hi haurà alguns Upsides també. Per preparar-se per això, per l'enorme quantitat d'estudiants, només cal dir que tot i que comptem amb 108 TFS i CAS, no és exactament el millor estudiant-mestre una vegada que arribem a 80.000 dels estudiants. No anem a qualificar problema per a molts jocs de forma manual, que hagin introduït aquesta setmana en el conjunt de problemes serà CS50 Check, que serà una utilitat de línia d'ordres en l'aparell que obtindrà una vegada que el actualitzeu a finals d'aquest cap de setmana. Vostè serà capaç d'executar una ordre, check50, en el seu propi conjunt de processadors, i obtindrà informació instantània sobre si el seu programa és correcte o incorrecte d'acord amb les especificacions de disseny diferents que ens han brindat. Més sobre això en l'especificació de problemes. Els companys de classe CS50x va a utilitzar això també. Butlletí de problemes 4 té a veure amb la medicina forense, i aquest conjunt de processadors va ser inspirat realment per algunes coses de la vida real de manera que quan jo estava a la universitat em van internar per un temps amb l'oficina del fiscal del Comtat de Middlesex el districte està fent la feina forense amb el seu investigador forense plom. El que això equival a, com crec que he esmentat un parell de setmanes passat, és la policia estatal de comunicació o altres persones poguessin entrar, ells deixen les coses com discs durs i CD i els disquets i similars, i llavors l'objectiu de l'oficina forense era determinar si hi va haver o no evidència d'algun tipus. Aquesta va ser la Unitat d'Investigacions Especials, així que era delictes de coll blanc. Era una mica més preocupant dels delictes, qualsevol cosa que implica algun tipus de mitjans de comunicació digitals. Resulta que no és que molta gent escriu un correu electrònic dient: "Jo ho vaig fer". Així que molt sovint, aquestes recerques forenses no es va presentar tot el que molt de fruit; però de vegades la gent anava a escriure aquests correus electrònics. Així que de vegades, els esforços van ser recompensats. Però per dur a aquest conjunt de processadors forense, anem a introduir en pset4 una mica de gràfics. És probable que prendre aquestes coses per fet - JPEG, GIF i similars - en aquests dies. Però si vostè realment pensa d'ell, una imatge, igual que la cara de Rob, pot modelar com una seqüència de punts o píxels. En el cas de la cara de Rob, hi ha tot tipus de colors, i comencem a veure els punts individuals, coneguts com píxels, una vegada que comencem per apropar la imatge Però si simplifiquem el món una mica i dir que això aquí és Rob en blanc i negre, per representar en blanc i negre, només pot utilitzar binari. I si utilitzarem binari, 1 o 0, podem expressar aquesta mateixa imatge de cara somrient de Rob amb aquest patró de bits. 11000011 representa el blanc, blanc, negre, negre, negre, negre, blanc, blanc. I el que no és un gran salt després de començar a parlar sobre fotografies a tot color, coses que t'agradaria veure a Facebook o prendre amb una càmera digital. Però, certament, quan es tracta de colors, necessita més bits. I molt comú en el món de les fotografies és utilitzar no 1-bit color, ja que això suggereix, però de 24-bit color, on realment obtenir milions de colors. Així com en el cas quan el zoom a l'ull de Rob, que era qualsevol nombre de milions de possibilitats diferents colors. Així que anem a introduir en aquest Butlletí de problemes 4, així com en el tutorial, que serà avui a les 3:30 en lloc de les habituals a causa de 2:30 conferència de divendres aquí. Però el vídeo estarà en línia com de costum matí. També vaig a presentar a un altre format d'arxiu. Això està deliberadament destinada a semblar intimidatori al principi, però això és només part de la documentació per a una estructura C. Resulta que Microsoft fa anys va ajudar a popularitzar aquest format anomenat el format d'arxiu de mapa de bits, bmp, i això va ser un super format simple, colorit gràfic d'arxius que s'ha utilitzat des de fa força temps i de vegades encara per als papers pintats d'escriptori. Si vostè pensa de nou a Windows XP i els turons i el cel blau, que era en general una imatge de mapa de bits bmp o. Els mapes de bits són divertits per a nosaltres perquè tenen una mica més de complexitat. No és tan simple com aquesta xarxa de 0s i 1s. En el seu lloc, tenen coses com una capçalera al començament d'un arxiu. En altres paraules, dins d'un arxiu. Bmp és un munt de 0s i 1s, però hi ha alguna cosa addicional 0s i 1s en aquest país. I resulta que el que probablement ha donat per fet durant anys - formats d'arxiu com. doc o. xls o. mp3, mp4,. siguin quins siguin els formats d'arxiu que vostè està familiaritzat amb - què significa ser fins i tot un format d'arxiu, perquè al cap ia la fi tots aquests arxius que utilitzem té només 0s i 1s. I potser els 0s i 1s representen ABC a través d'ASCII o similars, però al final del dia, encara és només 0s i 1s. Així que els humans només de tant en tant decideixen inventar un nou format d'arxiu on estandarditzar el que els patrons de bits realment signifiquen. I en aquest cas aquí, amics els que va dissenyar el format de fitxer de mapa de bits va dir que en el primer byte en un arxiu de mapa de bits, com es denota per 0 Offset allà, que serà una mica crípticament anomenat bfType variable anomenada, que només representa el tipus de fitxer de mapa de bits, el tipus de fitxer de mapa de bits és la següent. Es pot inferir potser des de la segona fila que compensat 2, número 2 byte, té un patró de 0 i 1 que representa què? La mida d'alguna cosa. I continua des d'allà. Així que, en conjunt Problema 4, se li va travessar algunes d'aquestes coses. No arribarem a preocupar per tots ells. Però noti que comença a posar-se interessant voltant byte 54: rgbtBlue, Verd i Vermell. Si alguna vegada has escoltat la sigla RGB - vermell, verd, blau - es tracta d'una referència a aquesta perquè resulta que es pot pintar tots els colors de l'arc de Sant Martí amb una combinació de vermell, blau i verd. I de fet, els pares a l'habitació pot recordar alguns dels primers projectors. En aquests dies, vostè acaba de veure una llum brillant que surt d'una lent, però de tornada al dia en què va tenir la lent de color vermell, la lent blava i verd de la lent, i junts dirigida a una pantalla i formen un quadre de colors. I molt sovint, les escoles intermèdies i secundàries que tenen aquests lents molt lleugerament decantat, de manera que eren una mena de veure imatges dobles o triples. Però aquesta era la idea. Tenies llum vermella, verda i blava que pinta un quadre. I aquest mateix principi s'utilitza en els ordinadors. Així que un dels reptes a continuació, perquè en el Problema 4 seran unes quantes coses. Un d'ells és per redimensionar una imatge, per prendre en un patró de 0s i 1s, esbrinar què trossos de 0s i 1s representen el que en una estructura d'aquest tipus, i després trobar la manera de reproduir els píxels - els vermells, els blaus, els verds - dins, així que quan una imatge es veu com aquest principi, pot semblar que aquesta vegada després d'això. Entre els altres reptes que també serà que se li va lliurar una imatge forense d'un arxiu real d'una càmera digital. I en aquesta cambra, fa molt de temps, eren un munt de fotos. El problema és que accidentalment esborrats o tenia la imatge danyada d'alguna manera. Les coses dolentes succeeixen amb càmeres digitals. I pel que ràpidament copiat tots els de 0s i 1s d'aquesta carta per a tu, salvat a tots en un sol arxiu gran, i després els anem a lliurar a vostè en problemes n º 4 de manera que vostè pot escriure un programa en C amb el de recuperar tots aquests arxius JPEG, idealment. I resulta que els arxius JPEG, encara que són una mena format d'arxiu complex - són molt més complexes que aquesta cara somrient aquí - resulta que cada JPEG comença amb els mateixos patrons de 0s i 1s. Així, utilitzant, en definitiva, un bucle while o un cicle for o similar, pot iterar sobre tots els 0s i 1s en aquesta imatge forense, i cada vegada que veus el patró especial que està definit en l'especificació del conjunt de problemes, es pot assumir aquí és, amb una probabilitat molt alta, l'inici d'un JPEG. I tan aviat com vostè troba el mateix patró determinat nombre de bytes o KiB o megabytes més tard, es pot assumir que aquí hi ha una segona JPEG, la foto que vaig prendre després de la primera. Permetin-me deixar de llegir aquest arxiu en primer lloc, començar a escriure aquest nou, i la sortida del seu programa per pset4 hi haurà fins a 50 imatges JPEG. I si no són 50 imatges JPEG, té una mica d'un bucle. Si vostè té un nombre infinit d'imatges JPEG, té un bucle infinit. Així que això també serà un cas bastant comú. Així que això és el que està en l'horitzó. Concurs 0 a les nostres esquenes, per compte del meu correu electrònic que sempre hi ha persones que són al mateix temps feliç, espècie de punt mort, trist i al voltant qüestionari temps 0. I si us plau acostar-se a mi, el cap TF Zamyla, el seu propi TF, o una de les entitats emissores de certificats que vostè sàpiga si li agradaria discutir com anaven les coses. Així que per impressionar als pares aquí a l'habitació, el que és la biblioteca CS50? [Rialles] Bona feina. Quina és la biblioteca CS50? Si. >> [Estudiant] És un conjunt prescrit de codi [inaudible] Bé, bé. És un conjunt prescrit de codi que va escriure el personal, proporcionem a vostè, que proporciona part de la funcionalitat comuna, coses com fer-me una cadena, porta-me'n 1 int - totes les funcions que s'enumeren aquí. A partir d'ara, comencem a prendre realment aquestes rodes d'entrenament apagat. Anem a començar a portar una cadena de vostè, recordo que era un sinònim per al tipus de dades real? >> [Diversos estudiants] Char *. * Char. Per als pares, que probablement va ser [fa so de bufada]. Això és bo. * Char començarem a veure a la pantalla amb més raó ara traiem cadena del nostre vocabulari, almenys quan es tracta de realment escriure codi. De la mateixa manera, deixarem d'utilitzar algunes d'aquestes funcions tant ja que els nostres programes es posaran més sofisticat. En lloc d'escriure programes de seure allà amb un missatge parpellejant, esperant que l'usuari escrigui alguna cosa endins, vostè rebrà les aportacions d'altres llocs. Per exemple, vostè els rebi d'una sèrie de bits en el disc dur local. En el seu lloc, vaig a aconseguir en el futur d'una connexió de xarxa, un lloc web en algun lloc. Així que anem a pelar aquesta capa, per primera vegada i tiri cap amunt del Dispositiu CS50 i l'arxiu anomenat cs50.h, que ha estat inclòs # durant setmanes, però anem a veure realment el que hi ha dins d'això. La part superior de l'arxiu en blau és només un munt de comentaris: informació sobre la garantia i llicència. Aquesta és una espècie de paradigma comú en el programari perquè una gran quantitat de programari en aquests dies és el que s'anomena codi obert, el que significa que algú ha escrit el codi i ho va fer lliurement disponible no només per executar i utilitzar, sinó per realment llegir i modificar i integrar en el seu propi treball. Així que això és el que vostè ha estat utilitzant programari de codi obert, encara que d'una manera molt petita. Si em desplaço cap avall més enllà dels comentaris, però, començarem a veure algunes coses més familiars. Avís a la part superior aquí que l'arxiu cs50.h inclou una gran quantitat d'arxius de capçalera. La majoria d'ells, no hem vist abans, però un és familiar. Quin d'aquests hem vist, encara que breument, fins ara? >> [Estudiant] Biblioteca estàndard. Sí, la biblioteca estàndard. stdlib.h té malloc. Quan vam començar a parlar sobre l'assignació de memòria dinàmica, que anem a tornar a la setmana següent, així, que va començar a incloure aquest arxiu. Resulta que bool i veritat i la falsedat en realitat no existeix en C per se si no va acompanyat l'arxiu aquí. Hem estat durant setmanes fins i tot stdbool.h de manera que vostè pot utilitzar la noció d'una. bool, vertader o fals Sense això, vostè hauria d'ordenar d'fingir i utilitzar un int i només arbitràriament assumir que 0 és fals i 1 és veritable. Si ens desplacem cap avall encara més, aquí és la nostra definició d'una cadena. Resulta que, com hem dit abans, que aquesta estrella és on en realitat no importa. Vostè pot fins i tot tenir espai al seu voltant. Tenim aquest semestre ha estat promovent com això per deixar clar que l'estrella té a veure amb el tipus, però s'adonen tan comú, sinó una mica més comú, és posar allà, però funcionalment és el mateix. Però ara, si llegim més avall, anem a fer una ullada a getInt perquè hem utilitzat que potser primer abans de tot aquest semestre. Aquí està getInt. Això és el que? >> [Estudiant] Un prototip. >> Això és només un prototip. Sovint, hem posat prototips a la part superior del nostre. Arxius c, però també es pot posar en prototips arxius de capçalera, arxius. h, com aquest d'aquí de manera que en escriure algunes de les funcions que voleu que altres persones puguin utilitzar, que és exactament el cas de la biblioteca CS50, no només posar en pràctica les seves funcions en una mena cs50.c, també posar els prototips no en la part superior d'aquest arxiu, però a la part superior d'un arxiu de capçalera. Després que l'arxiu de capçalera és el que els amics i col · legues incloure amb # include en el seu propi codi. Així que tot aquest temps que has estat incloent tots aquests prototips, eficaçment a la part superior del seu arxiu, però a través d'aquest mecanisme # include, que essencialment còpia i enganxa aquest arxiu en el seu compte. Aquí hi ha alguna documentació molt detallada. Hem pràcticament per fet que getInt rep un int, però resulta que hi ha alguns casos de cantonada. Què passa si l'usuari escriu un nombre que és massa gran, un trilió, que no pot cabre dins d'un int? Quin és el comportament esperat? L'ideal és predictible. Així que en aquest cas, si un llegeix la lletra petita, que realment va a veure que si la línia no pot ser llegit, aquest INT_MAX devolucions. Mai hem parlat d'això, però sobre la base de la seva capitalització, el que és probable que sigui? [Estudiant] Constant. >> És una constant. És una constant especial que probablement està declarat en un dels arxius de capçalera que és més alt en l'arxiu, i INT_MAX és probablement una mena uns 2 milions de dòlars, La idea és que, perquè hem d'indicar d'alguna manera que alguna cosa va sortir malament, nosaltres, sí, tenim 4 milions de números a la nostra disposició: -2 milions de dòlars en fins a 2 milions de dòlars, més o menys. Bé, el que és comú en la programació és de robar un d'aquests números, 0 tal vegada, potser 2 milions de dòlars, potser -2000000000, perquè passi una de les seves possibles valors perquè pugui comprometre amb el món que si alguna cosa surt malament, jo em tornaré aquest valor gran super. Però vostè no desitja que l'usuari escrigui alguna cosa críptic com 234 ..., un nombre molt gran. El generalitzar en canvi, com una constant. Així que en realitat, si s'estaven anal en les últimes setmanes, cada vegada que es diu getInt, vostè ha d'haver estat revisant amb una condició, si ho va fer el tipus d'usuari en INT_MAX, o, més específicament, va fer INT_MAX getint retorn, perquè si ho fes, que en realitat vol dir que no ho escrigui. Quelcom ha fallat en aquest cas. Així que això és el que es coneix generalment com un valor sentinella, que només significa especial. Passem ara a l'arxiu. C. L'arxiu de C ha existit en l'aparell durant algun temps. I de fet, l'aparell ha de pre-compilats per a vostè en aquesta cosa que es diu codi objecte, però això no li importa a vostè on està perquè el sistema sap en aquest cas on és: l'aparell. Anem ara a desplaçar-se cap avall i veure com getInt getInt ha estat treballant tot aquest temps. Aquí tenim comentaris similars d'abans. Permetin-me fer un zoom sobre només la part del codi. I el que tenim per getInt és la següent. No es necessita entrada. Es torna un int, mentre que (veritat), així que tenim un bucle infinit deliberada, però se suposa que sortirem d'això d'alguna manera o tornar des d'aquest. Anem a veure com funciona això. Sembla que estem fent servir GetString en aquesta primera línia dins del bucle, 166. Això ara és una bona pràctica perquè en quines circumstàncies podria tornar GetString la paraula clau NULL especial? >> [Estudiant] Si alguna cosa surt malament. Si alguna cosa surt malament. I què podria sortir malament quan es diu alguna cosa així com GetString? Si. >> [Estudiant] malloc no imposar els INT. Si. Potser malloc falla. En algun lloc sota de la capella com crida malloc GetString, que assigna la memòria, que permet a la botiga d'informàtica a tots els personatges que l'usuari escriu en el teclat. I suposem que l'usuari tenia un munt de temps lliure i va escriure més, per exemple, de 2 milions de caràcters, més caràcters que l'equip encara té RAM. GetString ha de ser capaç d'indicar que, si s'escau. Fins i tot si es tracta d'un cas super, super cantonada poc comú, ha de ser d'alguna manera capaç de manejar això, i així GetString, si ens vam tornar i llegir la seva documentació, ho fa en NULL fet de retorn. Així que ara si GetString falla en tornar NULL, getInt fallarà en tornar INT_MAX així com un sentinella. Aquests són només convencions humanes. L'única manera de saber que aquest és el cas és llegir la documentació. Anem a desplaçar-se cap avall perquè el int és realment aconseguit. Si desplaceu-vos cap avall una mica més lluny, en la línia 170, que té un comentari sobre aquestes línies. Declarem en un int 172, n, i char a, c, i llavors aquesta nova funció, que alguns de vosaltres heu ensopegat abans, sscanf. Això significa scanf cadena. En altres paraules, dóna'm una cadena i el vaig a buscar els fragments d'informació d'interès. Què significa això? Suposem que jo escriure, literalment, 123 en el teclat i després prem Enter. Quin és el tipus de dades de 123 quan són retornats per GetString? >> [Estudiant] String. Òbviament és una cadena, no? Tinc una cadena. Així que 123 és realment, entre cometes, 123 amb el 0 \ al final de la mateixa. Això no és un int. Això no és un nombre. Sembla un nombre, però no és en realitat. Llavors, què getInt he de fer? S'ha d'explorar aquesta cadena d'esquerra a dreta - 123 \ 0 - i d'alguna manera convertir un enter real. Vostè podria trobar la manera de fer això. Si penses en pset2, vostè probablement té una mica còmode amb César o Vigenère, així que vostè pot iterar sobre una seqüència, pot convertir caràcters a sencers. Però diables, és un munt de treball. Per què no cridar a una funció com sscanf que fa això per a vostè? Així sscanf espera un argument - en aquest cas anomenat línia, que és una cadena. A continuació, especifiqui entre cometes, molt similar a printf, el que s'espera veure en aquesta cadena. I el que estic dient aquí és que espero veure un nombre decimal i pot ser un personatge. I anem a veure per què aquest és el cas en un moment. I resulta que aquesta notació és ara una reminiscència de coses que vam començar a parlar de poc més d'una setmana. Quin és & N i & c fent per nosaltres aquí? >> [Estudiant] Direcció de n i la direcció de c. Si. M'està donant la direcció de n i la direcció de c. Per què és tan important? Vostès saben que amb funcions en C, sempre es pot tornar un valor o cap valor en absolut. Vostè pot tornar un int, cadena, un flotador, char a, el que sigui, o pot tornar buit, però només es pot tornar una cosa al màxim. Però aquí volem sscanf per a mi tornar potser un enter, un nombre decimal, i també a. char, i vaig a explicar per què el char en un moment Que efectivament vol tornar a sscanf dues coses, però això no és possible en C. Podeu evitar que en aprovar en dues direccions perquè quan et lliuren una funció de dues direccions, el que pot ser que la funció de fer amb ells? >> [Estudiant] Escriure a aquestes adreces. Es pot escriure en aquestes direccions. Vostè pot utilitzar l'operació estrella i anar-hi, a cadascuna d'aquestes direccions. És una espècie d'aquest mecanisme de la porta del darrere però molt comú per canviar els valors de les variables més d'un sol lloc - en aquest cas, dues. Ara noti que estic comprovant == 1 i després tornar n si això és així, de fet, s'avaluen com true. Llavors, què està passant? Tècnicament, tot el que realment volem que succeeixi en getInt és això. Volem analitzar, per dir-ho així, volem llegir la cadena - entre cometes 123 - i si sembla que hi ha un nombre allà, el que estem dient sscanf fer és indicar un nombre - 123 - en aquesta variable n per a mi. Llavors, per què llavors tinc realment això així? Quin és el paper de sscanf dient que també pot ser que aconsegueixi un personatge aquí? [Resposta dels estudiants inaudible] >> Un punt decimal en realitat podria funcionar. Anem a celebrar que va pensar per un moment. Què més? [Estudiant] Pot ser NULL. >> Bona idea. Podria ser el caràcter nul. En realitat no és en aquest cas. Si. >> [Estudiant] ASCII. ASCII. O deixa que em generalitzar encara més. El% c no és només per a la comprovació d'errors. No volem que hi hagi un caràcter després del número, però el que això em permet fer és el següent. Resulta que sscanf, a més d'emmagatzemar els valors de N i C en aquest exemple aquí, el que també fa és que retorna el nombre de variables de posar els valors cm Així que si només escriu en l'any 123, només el% d va a coincidir, i només s'emmagatzema n amb un valor com 123, i res es posa al c. C segueix sent un valor escombraries, per dir-ho - escombraries, ja que mai s'ha inicialitzat a un valor. Així que en aquest cas, sscanf retorna 1 perquè poblada 1 dels punters, en aquest cas gran, tinc un int de manera que alliberar la línia per alliberar la memòria GetString que realment assignat, i després torno n, else if T'has preguntat on Reintenta declaració que ve, que ve d'aquí. Així que si, per contra, de tipus I en 123foo - només alguns seqüència aleatòria de text - sscanf veurà el nombre, nombre, nombre, f, i que posarà el 123 en n, sinó que posarà a la f c i després tornar 2. Així que tenim, simplement usant la definició bàsica de la conducta sscanf, una manera molt simple - així, complex a primera vista, però al final de la dia mecanisme força simple - de dir que hi ha un enter i si ho és, que l'únic que he trobat? I l'espai en blanc aquí és deliberada. Si llegeix la documentació de sscanf, li diu que si s'inclou una peça d'espais en blanc al principi o al final, sscanf també permetrà que l'usuari, per qualsevol raó, 123 per colpejar la barra d'espai i que serà legítim. No va a cridar que l'usuari només perquè prem la barra d'espai al principi o al final, que és només una mica més fàcil d'utilitzar. Qualsevol pregunta llavors sobre getInt? Si. >> [Estudiant] Què passa si vostè acaba de posar en un char? Bona pregunta. Què passa si vostè acaba d'escriure en un char com f i premeu Enter sense escriure 123? Què et sembla el comportament d'aquesta línia de codi seria llavors? [Resposta dels estudiants inaudible] Sí, i sscanf pot cobrir això també, perquè en aquest cas, no va a omplir n o c. Va a tornar en lloc 0, en aquest cas estic també posar aquest escenari pel fet que el valor esperat que vull és 1. Només vull una cosa i només una part del utilitzador. Bona pregunta. Altres? Està bé. Millor no anar a través de totes les funcions d'aquí, però la que sembla potser d'interès restant és GetString perquè resulta que GetFloat, getInt, GetDouble GetLongLong tot punt gran part de la seva funcionalitat a GetString. Així que donem una ullada a la manera com es porta a terme aquí. Aquest sembla una mica complex, però utilitza els mateixos fonaments que comencem a parlar de la setmana passada. En GetString, que pren cap argument com pel buit fins aquí i retorna una cadena, que pel que sembla estic declarant una cadena anomenada buffer. Realment no sé el que serà utilitzat per encara, però ja veurem. Sembla que la capacitat per defecte és 0. No estic segur d'on va això, no sé el que n s'utilitzarà per, però, però ara s'està posant una mica més interessant. En la línia 243, que declara un int, c. Aquesta és una espècie d'un detall tonto. Un char és de 8 bits, i 8 bits pot emmagatzemar quants valors diferents? >> [Estudiant] 256. >> 256. El problema és que si vols tenir 256 caràcters diferents ASCII, els quals hi si vostè pensa de nou - i això no és una cosa per memoritzar. Però si penses en aquesta taula ASCII gran que vam tenir setmanes enrere, existien en aquest cas, 128 o 256 caràcters ASCII. Utilitzem tots els patrons de fins 0s i 1s. Això és un problema si vostè vol ser capaç de detectar un error perquè si vostè ja està utilitzant 256 valors per als seus personatges, que en realitat no planificar el futur perquè ara no hi ha manera de dir: aquest no és un caràcter de fiar, aquest és un missatge erroni. Així que el que el món fa és que s'utilitza el valor més gran que ve, una mena int, de manera que vostè té un nombre boig de bits, 32 per 4 bilions de possibles valors de manera que només ha de acaben usant essencialment 257 de ells, 1 dels quals té un significat especial com un error. Així que anem a veure com funciona això. En la línia 246, que tinc aquest bucle while gran que està trucant fgetc, f significat arxiu, de manera getc, a continuació, stdin. Resulta que això és només la forma més precisa de dir-ho llegir l'entrada des del teclat. Teclat estàndard mitjà d'entrada, la sortida estàndard significa pantalla, i l'error estàndard, que veurem en pset4, significa que la pantalla però una part especial de la pantalla perquè no es confonen amb la producció real que pretén imprimir. Però més sobre això en el futur. Així fgetc només significa llegir un caràcter del teclat i emmagatzemar-on? Guardi'l al c. I a continuació, comprovar - així que estic fent servir algunes conjuncions booleanes aquí - comprovar que no és igual a - \ n, de manera que l'usuari ha premi Enter, volem deixar en aquest moment, final del bucle - i també volem comprovar la constant EOF especial, que si sap o endevina, què significa? >> [Estudiant] Final de l'arxiu. >> Fi de l'arxiu. Això és una mica absurd perquè si estic escrivint en el teclat, no hi ha realment cap arxiu involucrats en això, però això és només una espècie del terme genèric utilitzat per a referir- que només ve dels dits de l'humà. EOF - final de l'arxiu. Com acotació al marge, si mai t'has colpejat Control D en el seu teclat, no és que vostè hauria encara - vostè ha colpejat Control C - Control D envia aquesta constant especial anomenada EOF. Així que ara només ens queda una mica d'assignació de memòria dinàmica. Així que si (n + 1> capacitat). Ara vaig a explicar núm. N és només quants bytes es troben actualment en el buffer, la cadena que s'està construint en l'actualitat per part de l'usuari. Si vostè té més personatges en la memòria intermèdia del que té la capacitat de la memòria intermèdia, intuïtivament el que hem de fer llavors és assignar més capacitat. Així que vaig a passar fregant algunes de les operacions aritmètiques aquí i centrar-se només en aquesta funció aquí. Saps el que és malloc o almenys generalment familiar. Endevina el que realloc fa. >> [Estudiant] Afegeix la memòria. No és prou l'addició de memòria. Es reassignació la memòria de la següent manera. Si encara hi ha espai a l'extrem de la corda perquè duri més que la memòria del que originalment li dóna, llavors vostè aconseguirà que la memòria addicional. Així que vostè pot seguir posant els personatges de la cadena de tornada a esquena amb esquena amb esquena. Però si aquest no és el cas, ja que va esperar massa temps i es va deixar caure alguna cosa a l'atzar va quedar en la memòria hi ha però no hi ha més memòria per aquí, això està bé. Realloc farà tot el treball pesat per a vostè, moure la cadena ha llegit fins ara d'aquí, el va deixar allà, i després li donen la pista una mica més en aquest punt. Així que amb un gest de la mà, deixa dir que el que està fent GetString s'està començant amb un buffer petit, potser un sol caràcter, i si l'usuari escriu en dos personatges, GetString acaba trucant realloc i diu: un personatge no era suficient, dóna'm dos personatges. Llavors, si vostè llegeix a través de la lògica del circuit, que dirà l'usuari va escriure en 3 caràcters; dóna'm ara no 2, però 4 personatges, llavors dóna'm 8, llavors dóna'm 16 i 32. El fet que estic doblant la capacitat cada vegada significa que el buffer no creixerà a poc a poc, va creixent super ràpid. I el que podria ser l'avantatge d'això? Per què estic doblant la mida de la memòria intermèdia encara que l'usuari només pot ser que necessiti un personatge extra del teclat? [Resposta dels estudiants inaudible] >> Què és això? >> [Estudiant] No ha de créixer amb tanta freqüència. Exactament. No ha de créixer amb tanta freqüència. I això és només una mica de te de cobertura seves apostes aquí, La idea és que vostè no desitja trucar realloc molt, ja que tendeix a ser lenta. Cada vegada que li demana al sistema operatiu per a la memòria, com aviat veurem en un futur conjunt de problemes, tendeix a portar el seu temps. Així que minimitza la quantitat de temps, fins i tot si vostè està perdent una mica d'espai, tendeix a ser una bona cosa. Però si llegim a través de la part final del GetString aquí - i una altra la comprensió de cada línia aquí no és tan important avui en dia - adonar que finalment crida a malloc nou i s'assigna exactament tants bytes com necessita per a la cadena i després llença a les escombraries trucant gratis la memòria intermèdia excessivament gran si de fet he doblat diverses vegades. Així que en resum, així és com GetString ha estat treballant tot aquest temps. Tot el que fa és llegir un caràcter alhora una i altra vegada i una altra, i cada vegada que necessita una mica de memòria addicional, li demana al sistema operatiu perquè trucant realloc. Alguna pregunta? Està bé. Un atac. Ara que entenem punters o almenys estan cada vegada més familiaritzats amb els punters, anem a considerar com el món sencer comença a esfondrar- si no arribes a defensar contra els usuaris contradictori, persones que estan tractant de tallar en el seu sistema, persones que estan tractant de robar seu programari eludint un codi de registre que en cas contrari podria haver d'escriure polz Fes un cop d'ull a aquest exemple aquí, que és només el codi C que té una funció principal a la part inferior que crida a una funció foo. I què és el que passa a foo? [Estudiant] Un sol argument. >> [Malan] Un sol argument. Així que argv [1], el que significa la primera paraula que l'usuari escriu en la línia d'ordres després a.out o el que s'anomena el programa. Així foo a la part superior porta en un char *. Però char * és què? >> [Estudiant] Una cadena. [Malan] Una cadena, així que no hi ha res de nou aquí. Aquesta cadena és arbitràriament ser anomenat bar. En aquesta línia aquí, char c [12], en una mena de semi-Anglès tècnic, el que està fent aquesta línia? [Estudiant] Matriu de - Array de >>? >> [Estudiant] Caràcters. Caràcters. >> Dóna'm una matriu de 12 caràcters. Així que podríem anomenar això un buffer. És tècnicament anomenat c, però un amortidor en la programació només significa un munt d'espai que vostè pot posar algunes coses polz A continuació, finalment, memcpy no hem usat abans, però que és fàcil endevinar el que fa. Còpia de la memòria. Què fer? Aparentment còpia bar, la seva entrada, al c, però només fins a la longitud de la barra. Però hi ha un error aquí. >> [Estudiant] Es necessita el caràcter sizeof. >> Okay. Tècnicament, hauríem de fer strlen (bar) * sizeof (char)). Això és correcte. Però en el pitjor dels casos aquí, anem a suposar que això és - Bé. Llavors hi ha dos errors. Així sizeof (char)); Anem a fer això una mica més. Així que ara que encara hi ha un error, que és el que? >> [Resposta dels estudiants inaudible] Comproveu què? >> [Estudiant] Comprovar valor NULL. En general, s'ha de comprovar si NULL perquè passen coses dolentes quan el punter és NULL, ja que podria acabar anant allà, i no sempre es va a NULL per eliminació de referències amb l'operador estrella. Així que això és bo. I què més farem? Lògicament, hi ha una falla aquí també. [Estudiant] Comprovar si argc és> = a 2. Per tal de comprovar si argc és> = 2. Bé, hi ha tres errors en aquest programa. Estem comprovant si l'usuari realment escriure en res a argv [1]. Bé. Quin és l'error tercera? Si. >> [Estudiant] C pot no ser prou gran. Bé. Ens registrem un escenari. Hem comprovat implícitament no copiar més memòria de la que s'excedeixi la longitud de la barra. Així que si la cadena que l'usuari va escriure en és de 10 caràcters de longitud, això es va limitar a dir copiar 10 caràcters. I això està bé. Però què passa si l'usuari va escriure en una paraula en l'indicador com una paraula de 20 caràcters? Això és a dir còpia 20 caràcters de barra en què? C, també conegut com el nostre buffer, el que significa que acabes d'escriure dades a 8 llocs byte que vostè no és propietari, i no els tenen en el sentit que mai se'ls assignen. Així que això és el que es coneix generalment com l'atac de desbordament de memòria intermèdia o atac saturació de la memòria intermèdia. I és un atac en el sentit que si l'usuari o el programa que està trucant a la seva funció està fent maliciosament, el que realment passa a continuació en realitat podria ser molt dolent. Així que anem a fer una ullada a aquesta foto aquí. Aquest quadre representa la pila de memòria. Recordeu que cada vegada que es crida a una funció rep aquest petit marc a la pila i després un altre i després un altre i un altre. I fins ara, tenim només una mica abstret aquests en forma de rectangles ja sigui en el tauler oa la pantalla aquí. Però si ens centrem en un d'aquests rectangles, quan es crida a una funció foo, resulta que hi ha més a l'interior de la pila que s'emmarquen en aquest rectangle que amb prou feines x i i i a i b, com ho vam fer parlant de swap. Resulta que hi ha alguns detalls de menor nivell, entre els quals remet. Així que resulta quan principal diu foo, el principal ha d'informar foo quina és la direcció principal està en la memòria de l'ordinador perquè en cas contrari, tan aviat com foo es fa executar, com en aquest cas aquí, una vegada que arribi a aquest claudàtor tancat al final del foo, Com dimonis es foo saber on és el control del programa se suposa que ha d'anar? Resulta que la resposta a aquesta pregunta està en aquest rectangle vermell aquí. Això representa un punter, i li toca a l'ordinador per emmagatzemar temporalment a la pila de trucada de la direcció principal, de manera que tan aviat com foo es fa executar, l'equip sap on i quina línia principal per tornar. Punter salvat Frame fa de manera similar a aquesta. Bar Char * aquí representa què? Ara bé, aquest segment blau aquí és el marc de foo. Què és el bar? Bar és només l'argument de la funció foo. Així que ara estem de tornada en una mena de quadre familiar. Hi ha més coses i més distraccions en la pantalla, però aquest segment de color blau clar només és el que hem estat dibuixant a la pissarra per a alguna cosa com swap. Aquest és el marc per foo. I l'única cosa en què ara mateix és el bar, que és aquest paràmetre. Però el que més hauria d'estar a la pila d'acord amb aquest codi aquí? [Estudiant] char c [12]. >> [Malan] char c [12]. També cal veure 12 quadres de memòria assignada a una variable anomenada c, i de fet hem de a la pantalla. La part superior hi ha c [0], i llavors l'autor d'aquest diagrama no es va molestar a dibuixar totes les places, però en realitat hi ha 12 hi perquè si ens fixem en la part inferior dreta, c [11] si s'enumeren des de 0 és el byte tal 12. Però aquí està el problema. En quina direcció es c creixent? Ordenar de dalt a baix si comença a la part superior i creix fins al fons. No es veu com ens va deixar la pista molt aquí en absolut. Hem classe de nosaltres mateixos pintat en una cantonada, i que c [11] és just contra bar, que està just en contra punter guardat, que és just en contra del remet. No hi ha més lloc. Quina és la implicació llavors si fiques la pota i està llegint 20 bytes en un buffer de 12 bytes? On són aquests 8 bytes addicionals anirà? >> [Estudiant] Inside - Dins de tota la resta, alguns dels quals és súper important. I el més important, potencialment, és el quadre vermell allà, Direcció de Retorn, perquè suposo que vostè ja sigui accidental o de contradicció sobreescriure aquests 4 bytes, que la direcció del punter, no només amb les escombraries però amb un nombre que passa a representar una adreça real a la memòria. Quina és la implicació, lògicament? >> [Estudiant] Funció que tornarà a un lloc diferent. Exactament. Quan torna foo i èxits que claudàtor, el programa es procedirà no per tornar al menú principal, tornarà al que la direcció està en aquesta caixa vermella. En el cas del registre de programari eludir, I si l'adreça que està sent retornat a és la funció que normalment s'anomena després d'haver pagat pel programari i introdueix el teu codi de registre? Et pots enganyar a l'ordinador en no anar aquí, però en comptes de pujar aquí. O si ets realment intel · ligent, un adversari realment pot escriure en el teclat, per exemple, no és una paraula real, els personatges no 20, però suposo que ell o ella actualment els tipus d' alguns personatges que representen codi. I no serà el codi C, en realitat seran els personatges que representen el codi binari de màquina, 0s i 1s. Però suposem que ets prou intel · ligent com per fer això, per fer alguna manera en l'indicatiu GetString una cosa que és essencialment codi compilat, i els últims 4 bytes sobreescriure aquest remitent. I quina direcció vol que l'entrada de fer-ho? S'emmagatzema realment en aquest rectangle vermell la direcció del primer byte de la memòria intermèdia. Així que cal ser molt intel · ligent, i això és un munt de prova i error per a la gent dolenta per aquí, però si vostè pot esbrinar què tan gran és aquest tampó de manera que els últims bytes de l'entrada li proporcionarà al programa passar a ser equivalent a la direcció de l'inici del seu buffer, que pot fer això. Si diem hola i normalment 0 \, això és el que acaba en la memòria intermèdia. Però si ets més intel · ligent i omplim aquest memòria intermèdia amb el que genèricament anomenarem codi d'atac - AAA, atac, atac, atac - que és només una cosa que fa una cosa dolenta, Què passa si ets realment intel · ligent, és possible fer això. En el quadre vermell aquí és una seqüència de nombres - 80, C0, 35, 08. Recordeu que que coincideix amb el nombre que està aquí dalt. Està en ordre invers, però més d'això en un altre moment. Tingueu en compte que aquesta direcció de retorn s'hagin modificat per igualar la direcció d'aquí, no l'adreça de la principal. Així que si el dolent de la pel · lícula és súper intel · ligent, ell o ella va a incloure en aquest codi d'atac una mena eliminar tots els arxius de l'usuari o copiar les contrasenyes o crear un compte d'usuari que pot accedir a - res en absolut. I aquest és el perill i el poder de la C. Com que té accés a la memòria a través de punters i per tant es pot escriure el que vulgui en la memòria d'un ordinador, vostè pot fer que un equip fer el que vulguis simplement per haver-ho saltar dins del seu propi espai de memòria. I així fins al dia d'avui tants programes i llocs web internacionals de tants que estan en perill es redueixen a les persones que prenen avantatge d'això. I això pot semblar un sofisticat atac super, però no sempre comença d'aquesta manera. La realitat és que el que la gent dolenta sol fer és, si es tracta d'un programa en una línia d'ordres o un programa d'interfície gràfica d'usuari o una pàgina web, que acaba de començar a proporcionar una tonteria. Vostè escriu en una paraula molt gran en el camp de cerca i prémer Retorn, i esperar a veure si el lloc web s'estavella o esperar a veure si el programa es manifesta algun missatge d'error perquè si tens sort com el dolent de la pel · lícula i oferiments entrada boig que bloqueja el programa, el que significa que el programador no va preveure el seu mal comportament, el que significa que probablement pot amb bastant esforç, el judici suficient i error, trobar la manera de lliurar un atac més precís. Així que una part tan important de la seguretat no és només evitar aquests atacs en conjunt però la seva detecció i, de fet mirant logs i veure el que la gent boja entrades teclejades al seu lloc web, quins termes de recerca i la gent escriu a la seva pàgina web amb l'esperança d'algun desbordament buffer. I tot això es redueix al bàsic senzilles del que és una matriu i què significa per assignar i utilitzar la memòria. Relacionat a continuació, que també és aquesta. Anem a fer una ullada a l'interior d'un disc dur nou. Vostè recordarà d'una o dues setmanes enrere, que en arrossegar arxius a la paperera de reciclatge o pot d'escombraries, Què passa? >> [Estudiant] Res. >> Absolutament res, oi? Finalment, si s'executa sense espai en disc, Windows o Mac OS començarà a eliminar arxius per vostè. Però si arrossega alguna cosa aquí, això no és del tot segur. Tota la seva company de quart o d'un amic o membre de la família ha de fer és doble clic i, voila, hi ha tots els arxius incomplets que van intentar esborrar. La majoria de nosaltres si més no saber que vostè ha de fer clic dret o control Premeu i buidar les escombraries o alguna cosa així. Però fins i tot llavors, que no acaba de fer el truc perquè el que passa quan es té un arxiu en el disc dur que representa algun document de Word o algun JPEG, el que representa el disc dur, i diguem que aquesta estella aquí representa aquest arxiu, i es compon d'un munt de 0s i 1s. Què passa quan vostè no només arrossegar el fitxer a la paperera o paperera de reciclatge però també buidar? Una espècie de res. No hi ha absolutament res ara. Ara només és res perquè una mica d'alguna cosa que passa en la forma d'aquesta taula. Així que hi ha una mena de base de dades o taula dins de la memòria d'un ordinador que essencialment té una columna per als noms de fitxers i una columna per als arxius 'ubicació, on això podria ser la ubicació 123, un nombre a l'atzar. Així que podríem tenir quelcom x.jpeg i la ubicació 123. Què passa llavors quan realment buidar la paperera? Que se'n vagin. Però el que no desapareix és el 0s i 1s. Quina és llavors la connexió a pset4? Bé, amb pset4, només perquè hem esborrat accidentalment la targeta Compact Flash que tenia totes les fotos o simplement perquè la mala sort es va corrompre no vol dir que el 0 i 1 no estan encara allà. Potser alguns d'ells s'han perdut perquè alguna cosa es corromp en el sentit que alguns 0s i 1s 1s convertir es va convertir en 0s. Les coses dolentes poden succeir a causa de programari defectuós o maquinari defectuós. Però molts d'aquests bits, potser fins i tot el 100% d'ells, encara hi són. És que l'ordinador o la càmera no sap on va començar JPEG1 i on JPEG2 començar. Però si, el programador, saber amb una mica de sentit comú en aquests JPEGs són o com es veuen perquè pugui analitzar el 0 i 1 i diuen JPEG, JPEG, vostè pot escriure un programa amb essencialment un bucle for o while que es recupera cada un d'aquests arxius. Així que la lliçó és, doncs, per començar a esborrar els arxius de forma segura si vols evitar això del tot. Sí [Estudiant] Com és que diu en el seu ordinador que té més memòria que abans? Tenir més memòria que abans - >> [estudiant] Més memòria disponible. Oh. Bona pregunta. Llavors, per què després de buidar les escombraries té el seu ordinador li dirà que té més espai lliure que abans? En poques paraules, perquè està mentint. Més tècnicament, vostè té més espai perquè ara vostè ha dit pots posar altres coses en aquest arxiu una vegada va ser. Però això no vol dir que els bits desapareixeran, i això no vol dir que els bits estan sent canviats per a tots 0s, per exemple, per a la seva protecció. Així que per contra, si bé esborrar arxius o destruir físicament el dispositiu, que és realment l'única manera de vegades al voltant d'això. Així que per què no ens anem en aquesta nota semi-por, i ens veiem el dilluns. [Aplaudiment] [CS50.TV]