[Powered by Google Translate] [Review] [Quiz 0] [Lexi Ross, Tommy MacWilliam, Lluc Freitas, Joseph Ong] [Harvard University] [Aquesta és CS50.] [CS50.TV] Ei, tothom. Benvinguts a la sessió de revisió per Quiz 0, que se celebra aquest dimecres. El que farem aquesta nit, estic amb 3 altres FF, i junts anirem a través d'una revisió del que hem fet en el curs fins ara. No serà 100% complet, però ha de donar una idea millor del que ja té i pel que encara ha d'estudiar abans de dimecres. I no dubteu a aixecar la mà amb preguntes com anem al llarg, però tingui en compte que també tindrem una mica de temps al final- si aconseguim a través d'uns minuts de sobres per fer preguntes generals, així que tingues-ho en ment, així que anem a començar des del principi amb la Setmana 0. [Concurs 0 Review!] [Part 0] [Lexi Ross] Però abans de fer això parlarem de la logística de la prova. [Logística] [Concurs tindrà lloc el dimecres 10/10 en lloc de la conferència] [(Veure http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf per més detalls)] És el dimecres, 10 d'octubre. Això és avui, i si vas a aquesta URL aquí que també és accessible des CS50.net-aquí 's un enllaç a ella- pot veure informació sobre on anar sobre la base de seu cognom o afiliació escolar, així com es parla exactament el que la prova inclourà i els tipus de preguntes que vostè va a obtenir. Tingueu en compte que vostè també tindrà l'oportunitat de revisar el qüestionari a la secció, pel que els seus TFS ha d'anar sobre alguns problemes de la pràctica, i aquesta és una altra bona oportunitat per veure d'on vostè encara ha d'estudiar per l'examen. Anem a començar des del principi amb bytes 'n' Bits. Recordeu que un bit és un 0 o un 1, i un byte és una col · lecció de 8 d'aquests bits. Fem una ullada a aquesta col · lecció de bits aquí. Hem de ser capaços d'esbrinar quants bits hi. On s'explica que hi ha només 8 d'ells, vuit 0 o 1 unitats. I ja que hi ha 8 bits, això és 1 byte, i anem a convertir hexadecimal. Hexadecimal és base 16, i és bastant fàcil de convertir en un nombre binari, que és el que és, a un nombre en hexadecimal. Tot el que fem és mirar en grups de 4, i convertir-los al dígit hexadecimal corresponent. Comencem amb el grup de més a la dreta de 4, així que 0011. Això serà un 1 i un 2, de manera que en conjunt fa 3. I després veurem l'altre bloc de 4. 1101. Això serà un 1, un 4 i un 8. Al costat això serà de 13, el que fa D. I recordarem que en hexadecimal no ens limitem a anar del 0 al 9. Anem 0 a F, de manera que després de 9, 10 correspon a A, 11 a B, etc, on F és 15. Aquí 13 és una D, pel que per convertir decimal tot el que fem és en realitat tractar cada posició com una potència de 2. Aquesta és una de 1, un 2, zero 4s, 8s zero, un 16, etcètera, i és una mica difícil de calcular al cap, però si anem a la següent diapositiva podem veure la resposta a això. Essencialment anem a l'altre costat de la dreta de nou a l'esquerra, i estem multiplicant cada dígit per la corresponent potència de 2. I recorda, per hexadecimal que denoten aquestes xifres amb 0x al principi així que no ho confongui amb un nombre decimal. Continuant, aquesta és una taula ASCII, i el que utilitzi ASCII per és mapejar de caràcters a valors numèrics. Recordeu que en el conjunt de processadors criptografia hem fet un ús extensiu de la taula ASCII per tal d'utilitzar diversos mètodes de criptografia, el Cèsar i el xifrat de Vigenère, per convertir lletres diferents en una cadena d'acord amb la clau proporcionada per l'usuari. Anem a veure una mica de matemàtiques ASCII. Quant a 'P' + 1, en format de caràcters que seria Q, i recorda que '5 '≠ 5. I com podríem convertir entre aquestes 2 formes? No és en realitat massa dura. Per tal d'obtenir 5 restem '0 ' perquè hi ha 5 llocs entre el 0 i el '5 '. Per tal d'anar cap a l'altre que només ha d'afegir el 0, pel que és una mena d'aritmètica regular. Només recordeu que quan alguna cosa té cometes al voltant d'ell que és un personatge i per tant correspon a un valor en la taula ASCII. Entrant en temes més generals d'informàtica. Ens assabentem del que un algorisme és i com s'utilitza la programació per implementar algorismes. Alguns exemples d'algorismes són alguna cosa realment simple, com comprovar si un nombre és parell o senar. Per als que es recorden de nosaltres mod el nombre per 2 i comprovar si el resultat és 0. Si és així, és encara. Si no és així, és estrany. I això és un exemple d'un algorisme molt bàsic. Una mica d'una major participació és la recerca binària, que anem a repassar més tard a la sessió de revisió. I la programació és el terme que fem servir per prendre un algorisme i la conversió a codificar l'ordinador pot llegir. 2 exemples de programació Scratch, que és el que vam fer a la setmana 0. Tot i que en realitat no s'escriu el codi és una forma d'implementar aquest algorisme, que és la impressió dels números 1-10, i aquí fem el mateix en el llenguatge de programació C. Aquests són funcionalment equivalents, acaba d'escriure en diferents idiomes o de sintaxi. Després ens assabentem sobre les expressions booleanes, i un booleà és un valor que és vertader o fals, i aquí moltes vegades booleana anar dins de les condicions, així que si (x ≤ 5), bo, ia establir x = 5, de manera que l'estat es va a avaluar en true. I si és veritable, tot el codi està per sota de la condició serà avaluat per l'ordinador, de manera que cadena s'ha d'imprimir la sortida estàndard, i la condició de terme es refereix a tot el que està dins dels parèntesis de la instrucció if. Recordeu que tots els operadors. Recorda que és && i | | quan estem tractant de combinar 2 o més condicions, == No = per comprovar si dues coses són iguals. Recordeu que és = per a l'assignació mentre == és un operador booleà. ≤, ≥ i després la final 2 són fàcils d'entendre. Una revisió general de la lògica booleana aquí. I booleana són també importants en bucles, que anem a repassar ara. Vam aprendre unes 3 tipus de bucles des de començament CS50, for, while i do temps. I és important saber que mentre per a la majoria dels propòsits de fet podem utilitzar qualsevol tipus de bucle en general hi ha certs tipus de propòsits o patrons comuns en la programació que específicament trucar a un d'aquests bucles fer que el. més eficient o elegant per codificar d'aquesta manera Anem a repassar el que cada un d'aquests bucles se sol utilitzar per més freqüència. En un bucle for en general, ja sé quantes vegades volem repetir. Això és el que posem en la condició. Per, i = 0, i <10, per exemple. Ja sabem que volem fer alguna cosa 10 vegades. Ara, per un bucle while, en general, no necessàriament sé quantes vegades volem que el bucle s'executi. Però sí sabem algun tipus de condició que volem que sempre és veritable o sempre falsa. Per exemple, mentre que s'estableix. Diguem que és una variable booleana. Si bé és cert que volem que el codi per avaluar, així que una mica més extensible, una mica més general que un bucle for, però per a qualsevol bucle també es pot convertir en un bucle while. Finalment, fer bucles while, que poden ser els més difícils de comprendre immediatament, s'utilitza sovint quan volem avaluar el primer codi abans de la primera vegada que comprovi l'estat. Un cas d'ús comú que un cicle do while és quan es vol aconseguir l'entrada de l'usuari, i vostè sap que vostè vol preguntar a l'usuari per a l'entrada d'almenys una vegada, però si no et donen una bona entrada immediatament vol seguir preguntant fins que et donen la bona entrada. Aquest és l'ús més comú d'un bucle Do While, i donem una ullada a l'estructura real d'aquests bucles. En general sempre tendeixen a seguir aquests patrons. En el bucle per l'interior té 3 components: inicialització, en general alguna cosa com int i = 0 on i és el comptador, condició, on volem dir per executar aquest bucle, sempre que aquesta situació encara es manté, com i <10, i, finalment, l'actualització, que és com incrementem la variable de comptador en cada punt en el bucle. Una cosa comuna veure només hi ha i + +, el que significa incrementar ia 1 cada vegada. També es podria fer alguna cosa com i + = 2, el que significa afegir 2 a i cada vegada que vagi a través del bucle. I a continuació, el fer això només es refereix a qualsevol codi que realment s'executa com a part del bucle. I per un bucle while, aquesta vegada en realitat tenim la inicialització fora del bucle, així per exemple, diguem que estem tractant de fer el mateix tipus de bucle, com acabo de descriure. Diríem int i = 0 abans del bucle comença. Llavors podríem dir que mentre i <10 fer això, de manera que el mateix bloc de codi com abans, i aquesta vegada la part d'actualització del codi, per exemple, i + +, en realitat va dins del bucle. I finalment, per fer una estona, és similar al bucle while, però hem de recordar que el codi s'avaluarà una vegada abans que la condició es comprova, per la qual cosa té molt més sentit si ens fixem en ella per tal de dalt a baix. En una, do while avalua el codi, fins i tot abans de veure la condició mentre mentre que un bucle while, comprova en primer lloc. Les declaracions i variables. Quan volem crear una nova variable que primer vol inicialitzar. Per exemple, la barra int inicialitza la variable bar, però no li dóna un valor, llavors quin és el valor de la barra ara? No ho sé. Podria ser un valor escombraries que estava prèviament emmagatzemat en la memòria allà, i no volem utilitzar aquesta variable fins que realment li donen un valor, així ho declarem aquí. Després inicialitzem a ser 42. Ara, per descomptat, sabem que això es pot fer en una sola línia, bar int = 42. Però per ser clars els múltiples passos que s'estan produint, la declaració i inicialització estan succeint aquí per separat. Això passa en un sol pas, i el següent, int = bar baz + 1, aquesta declaració de baix, que baz increments, de manera que al final d'aquest bloc de codi si haguéssim de imprimir el valor de baz seria 44 perquè declarar i inicialitzar a ser d'1 bar>, i després l'incrementa un cop més amb el + +. Repassem breument aquesta bonica, però és bo tenir un general comprensió del que les discussions i els esdeveniments són. Principalment ens va fer això en Scratch, així que vostè pot pensar en temes com diverses seqüències de codi executant a la vegada. En realitat, és probable que no s'està executant a la vegada, sinó una mena de forma abstracta, podem pensar-hi d'aquesta manera. En Scratch, per exemple, vam tenir els sprites múltiples. Es podria executar codi diferent a la vegada. Un podia caminar mentre que l'altre està dient alguna cosa en una part diferent de la pantalla. Els esdeveniments són una altra manera de separar la lògica entre els diferents elements del seu codi, i en Scratch hem estat capaços de simular els esdeveniments utilitzant la difusió, i que en realitat és quan rebut, no quan sento, però en essència es tracta d'una forma de transmetre informació d'un sprite a un altre. Per exemple, és possible que vulgueu transmetre més de joc, i quan un altre follet rep més de joc, que respon d'una manera determinada. És un model important per entendre la programació. Només per passar la Setmana bàsic 0, el que hem anat fins ara, donem una ullada a aquest programa C simple. El text pot ser una mica més petita d'aquí, però vaig a anar-hi molt ràpid. Estem incloent dos arxius de capçalera a la part superior cs50.h i stdio.h. Estem llavors definir un límit constant cridat a ser 100. Estem llavors la implementació de la nostra funció principal. Com que no utilitza arguments de línia d'ordres aquí hem de posar buit com els arguments a favor principal. Veiem int dalt principal. Aquest és el tipus de retorn, per tant, tornar 0 a la part inferior. I estem fent servir la funció de biblioteca CS50 aconseguir int sol · licitar a l'usuari dades, i la emmagatzemem en aquesta variable x, de manera que declarem x dalt, i el inicialitza amb x = getInt. A continuació, comprovar per veure si l'usuari ens va donar bona entrada. Si es tracta d'LIMIT ≥ volem tornar un codi d'error d'1 i mostrarà un missatge d'error. I, finalment, si l'usuari ens ha donat bons aportacions anem a quadrar el nombre i imprimir el resultat. Només per assegurar-se que tots els afectats casa es pot veure les etiquetes de diferents parts del codi aquí. Esmentar arxius constants de capçalera. Oh, int x. Assegureu-vos recordar que és una variable local. Això contrasta d'una variable global, el que anem a parlar de una mica més endavant en la sessió de revisió, i estem cridant a la funció de biblioteca printf, així que si no havia inclòs l'arxiu de capçalera stdio.h no seria capaç de cridar a printf. I crec que la fletxa que es va tallar aquí està apuntant a la d% que és una cadena de format de printf. Diu imprimir aquesta variable com un nombre d%. I que és la Setmana de 0. Ara Lucas va a continuar. Hey, nois. El meu nom és Lluc. Sóc un estudiant de segon any a la millor casa al campus, Mather, i vaig a parlar una mica sobre la Setmana 1 i 2,1. [Setmana 1 i 2,1!] [Lluc Freitas] Com Lexi estava dient, quan vam començar a traduir el codi des de zero en C una de les coses que hem notat és que es pot no només escriure el codi i executar-lo amb una bandera verda més. En realitat, vostè ha d'utilitzar alguns passos per fer el seu programa en C convertir-se en un arxiu executable. Bàsicament el que fas quan estàs escrivint un programa és que traduir la seva idea en un llenguatge que un compilador pot entendre, així que quan vostè està escrivint un programa en C el que estàs fent és escriure realment una cosa que el compilador va a entendre, i el compilador traduirà aquest codi en alguna cosa que el seu equip va a entendre. I la cosa és que l'equip és realment molt ximple. L'equip només es pot entendre 0s i 1s, el que en realitat en els primers ordinadors gent sol programar amb 0 i 1, però ja no, gràcies a Déu. No hem de memoritzar les seqüències de 0s i 1s per a un bucle o per a un bucle while i així successivament. És per això que tenim un compilador. El que un compilador fa és que bàsicament es tradueix el codi C, en el nostre cas, de la llengua que l'equip va a entendre, que és el codi objecte, i el compilador que estem utilitzant es diu so metàl · lic, així que això és realment el símbol de so metàl · lic. Quan vostè té el seu programa, vostè ha de fer 2 coses. En primer lloc, vostè ha de compilar el programa, i després es va a executar el programa. Per compilar el programa té un munt d'opcions per fer-ho. La primera d'elles té a veure program.c clang en quin programa és el nom del programa. En aquest cas es pot veure que estan dient "Hey, compilar el meu programa". No està dient "Vull que aquest nom per el meu programa", ni res. La segona opció és donar un nom al seu programa. Es pot dir clang-o i després el nom que desitja l'arxiu executable per ser nomenat com i, a continuació program.c. I també es pot fer fer el programa, i veure com en els primers 2 casos Vaig posar. C, i en el tercer només tinc programes? Sí, en realitat no hauria de posar. C quan s'utilitza fer. En cas contrari el compilador és en realitat va a cridar a vostè. I també, no sé si vostès recorden, però moltes vegades també fem servir lcs50-o-lm. Això es diu enllaç. Simplement li diu al compilador que utilitzarà les biblioteques allà mateix, així que si vol utilitzar cs50.h que realment ha d'escriure clang program.c-lcs50. Si no ho fa, el compilador no sabrà que utilitzeu aquestes funcions en cs50.h. I quan es vol executar el programa té 2 opcions. Si vostè va fer program.c clang vostè no ho hàgiu fet al seu programa. Vostè ha d'executar amb. / A.out. A.out és un nom estàndard que li dóna al seu so metàl · lic programa si no li donem un nom. En cas contrari, farem. / Programa si vostè li va donar un nom al seu programa, i també si ho has fet fer el programa el nom d'un programa que es posarà ja serà programat amb el mateix nom que l'arxiu c. Després parlem de tipus de dades i les dades. Bàsicament els tipus de dades són el mateix com petites caixes que utilitzen per emmagatzemar els valors, de manera que els tipus de dades són en realitat com Pokémons. Vénen en totes les mides i tipus. No sé si aquesta analogia té sentit. La mida de les dades depèn en realitat de l'arquitectura de la màquina. Totes les mides de dades que vaig a mostrar aquí són en realitat per a una màquina de 32-bit, que és el cas del nostre aparell, però si vostè està realment codificació del seu Mac o al Windows també Probablement vostè tindrà un equip de 64 bits, així que recordi que les mides de les dades que vaig a mostrar aquí són per a la màquina de 32-bit. El primer que vam veure va ser un int, que és bastant senzill. Utilitzeu int per emmagatzemar un sencer. També vam veure el caràcter, el char. Si voleu utilitzar una lletra o un símbol poc vostè està probablement va a utilitzar un char. Un char té 1 byte, és a dir 8 bits, com va dir Lexi. Bàsicament tenim una taula ASCII que té 256 les possibles combinacions de 0s i 1s, i després, quan s'escriu una xerrada traduirà el caràcter que les entrades que un nombre que té a la taula ASCII, com va dir Lexi. També tenim el flotador, que utilitzem per emmagatzemar nombres decimals. Si vostè vol triar 3.14, per exemple, vostè ha d'utilitzar un flotador o un doble que té més precisió. Un flotador té 4 bytes. Un doble té 8 bytes, de manera que l'única diferència és la precisió. També tenim un llarg que s'utilitza per als nombres enters, i es pot veure una màquina de 32-bit 1 int i un llarg tenen la mateixa mida, pel que en realitat no té sentit utilitzar un llarg en una màquina de 32-bit. Però si vostè està utilitzant un Mac i de 64 bits, en realitat una llarga té una mida de 8, així que realment depèn de l'arquitectura. Perquè la màquina 32-bit no té sentit usar un llarg realitat. I després un llarg temps, d'altra banda, té 8 bytes, pel que és molt bo si vostè vol tenir un enter llarg. I finalment, hem cadena, que és en realitat un char *, que és un punter a un char. És molt fàcil pensar que la mida de la cadena serà com el nombre de caràcters que té allà, però en realitat el propi char * té la mida d'un punter a un char, que és 4 bytes. La mida d'un char * és de 4 bytes. No importa si vostè té una petita paraula o una lletra o gens. Serà de 4 bytes. També hem après una mica sobre càsting, Així com vostè pot veure, si vostè té, per exemple, un programa que diu: int x = 3 i després printf ("% d", x / 2) Vostès saben el que voleu imprimir a la pantalla? Algú? >> [Els estudiants] 2. 1. >> 1, sí. En fer 3/2 que obtindrà 1,5, però ja que estem usant un nombre enter que farà cas omís de la part decimal, i tindràs 1. Si vostè no vol que això succeeixi el que pot fer, per exemple, Es declara un flotador i = x. Llavors x que abans eren 3 ara serà 3,000 en i. I llavors vostè pot imprimir el a / 2. En realitat, jo hauria de tenir un 2. per allà. Farà 3.00/2.00, i obtindràs 1,5. I nosaltres tenim aquest f 0,2 només per demanar 2 unitats decimals de la part decimal. Si té 0,3 f que tindrà realment 1.500. Si es tracta de dues que serà 1,50. També tenim aquest cas. Si ho fa float x = 3,14 x i llavors vostè printf vostè va a obtenir 3,14. I si ho fa x = int x, el que significa tractar x com un enter i s'imprimeix x ara vostè tindrà 3,00. Això té sentit? Com que vostè està tractant primerament x com un enter, pel que està fent cas omís de la part decimal, i després imprimeix x. I, finalment, també es pot fer això, int x = 65, i llavors es declara un char c = x, i després, si s'imprimeix el c estàs realment va a aconseguir A, així que bàsicament el que estàs fent aquí està traduint el sencer en el caràcter, igual que la taula ASCII fa. També parlem dels operadors matemàtics. La majoria d'ells són bastant senzills, de manera que +, -, *, /, i també parlem de mod, que és la resta d'una divisió de dos nombres. Si té 10% 3, per exemple, que significa dividir 10 per 3, i el que és la resta? Serà 1, pel que és realment molt útil per a molts dels programes. Per Vigenère i César estic bastant segur que tots vostès utilitzen mod. Operadors matemàtics, tingui molta cura en combinar * i /. Per exemple, si vostè fa (3/2) * 2 Què vols aconseguir? [Els estudiants] 2. Sí, 2, perquè 3/2 serà 1,5, però ja que estem fent operacions entre dos nombres enters en realitat estàs sol tindrà en compte 1, i després 1 * 2 serà de 2, així que vés amb compte en fer aritmètica amb nombres enters perquè és possible que aconsegueixi que 2 = 3, en aquest cas. I també tenir molta cura amb prioritat. Generalment, vostè ha d'usar parèntesis per estar segur que vostè sap el que està fent. Alguns dreceres útils, és clar, es tracta d'i + + o i + = 1 o usant + =. Això és el mateix que fer i = i + 1. També puc fer - o i - = 1, que és el mateix que i = i -1, cosa que vostès utilitzar en els bucles for, si més no. A més, per *, si utilitzeu * = i si ho fa, per exemple, i * = 2 és el mateix que dir i = i * 2, i el mateix per a la divisió. Si ho fa i / = 2 és el mateix que i = i / 2. Ara, sobre les funcions. Vostès van aprendre que les funcions són una estratègia molt bona per guardar el codi mentre que vostè està programant, així que si vol dur a terme la mateixa tasca en el codi una i altra vegada, probablement vulgui utilitzar una funció només perquè vostè no ha de copiar i enganxar el codi una i altra vegada. En realitat, la principal és una funció, i quan et mostren el format d'una funció veuràs que això és bastant obvi. També utilitzem les funcions d'algunes biblioteques, per exemple, printf, Getin, que és de la biblioteca CS50, i altres funcions com ToUpper. Totes aquestes funcions es duen a la pràctica altres biblioteques, i quan es posa els arxius de subjecció al principi del seu programa que dius pot donar-me el codi per a les funcions així que no has de posar-les en pràctica per mi mateix? I vostè també pot escriure les seves pròpies funcions, de manera que en iniciar la programació t'adones que les biblioteques no tenen totes les funcions que vostè necessita. Per al conjunt de processadors passat, per exemple, escrivim dibuixar, lluita i recerca, i és molt, molt important ser capaç d'escriure funcions perquè són útils, i els fem servir tot el temps en la programació, i s'estalvia una gran quantitat de codi. El format d'una funció és aquest. Comptem amb tipus de retorn al principi. Quin és el tipus de canvi? És només quan la seva funció es tornarà. Si disposa d'una funció, per exemple, factorial, que es va a calcular un factorial d'un nombre enter, és probable que el tornarà un enter també. A continuació, el tipus de retorn serà int. Printf en realitat té un tipus de retorn void perquè no s'està tornant una mica. No ets més que la impressió de les coses a la pantalla i sortida de la funció després. Llavors vostè té el nom de la funció que vostè pot triar. Vostè ha de ser una mica raonable, igual que no tria un nom com xyz o com x2F. Intenta fer un nom que tingui sentit. Per exemple, si és factorial, diguem factorial. Si es tracta d'una funció que es va a dibuixar alguna cosa, el nom de dibuixar. I després tenim als paràmetres, que també s'anomenen arguments, que són com els recursos que necessita la seva funció a partir del seu codi per realitzar la seva tasca. Per calcular el factorial d'un nombre Probablement cal tenir un nombre per calcular un factorial. Un dels arguments que tindrem és el mateix nombre. I després es farà alguna cosa i tornar el valor al final si no és una funció void. Vegem un exemple. Si vull escriure una funció que sumi tots els nombres en una matriu d'enters, en primer lloc, el tipus de retorn serà int perquè tinc una matriu d'enters. I llavors em vaig a tenir el nom de la funció com sumArray, i llavors tindrà el mateix array, int núms a, i llavors la longitud de la matriu, així que sé la quantitat de nombres que cal sumar. Llavors ha de inicialitzar una variable anomenada suma, per exemple, a 0, i cada vegada que veig a un element de la matriu que hauria afegir a la suma, així que vaig fer un bucle for. Com va dir Lexi, oi int i = 0, i longitud 0, llavors és positiu. Si és = a 0, llavors és 0, i si és <0, llavors és negatiu. I l'altre està fent if, else if, else. La diferència entre els dos és que aquest és en realitat serà comprovar si> 0, <0 = 0 o tres vegades, així que si vostè té el número 2, per exemple, vindrà aquí i dir if (x> 0), i que dirà que sí, així d'imprimir positiu. Però encara que sé que és> 0 i que no serà 0 o <0 Jo encara vaig a fer és 0, és <0, així que estic realment va dins de IFS que jo no havia de perquè ja sabem que no va a satisfer alguna d'aquestes condicions. Puc utilitzar el if, else if, else declaració. Bàsicament diu que si x = 0 imprimeixo el positiu. Si no és així, vaig a provar això també. Si és 2, no faré això. Bàsicament si tingués x = 2 li diria if (x> 0), sí, així d'imprimir això. Ara que sé que és> 0 i que satisfà la primera, si Jo ni tan sols vaig a executar aquest codi. El codi s'executa més ràpid, en realitat, tres vegades més ràpid si els fas servir. També vam aprendre sobre AND i OR. No vaig a passar per això perquè Lexi ja parlava d'ells. És només el && i | operador |. L'únic que diré és anar amb compte quan vostè té 3 condicions. Utilitzeu parèntesis perquè és molt confús quan vostè té una condició i un altre o un a l'altre. Utilitzeu parèntesis per estar segur que les seves condicions de tenir sentit perquè en aquest cas, per exemple, es pot imaginar que podria ser la primera condició i una o l'altra o les dues condicions combinades en una i o el tercer, així que vés amb compte. I finalment, hem parlat sobre els modificadors. Un interruptor és molt útil quan es té una variable. Diguem que vostè té una variable com n que pot ser 0, 1, o 2, i per a cada un dels casos vostè va a realitzar una tasca. Es pot dir canviar la variable, i indica que el valor és, doncs, com valor1 vaig a fer això, i després trenco, el que significa que no vaig a mirar en qualsevol dels altres casos perquè ja convençut que el cas i després valor2 i així successivament, i també pot tenir un interruptor predeterminat. Això vol dir que si no satisfà qualsevol dels casos que he tingut que vaig a fer una altra cosa, però això és opcional. Això és tot per a mi. Ara anem a Tommy. Molt bé, això serà la setmana 3-ish. Aquests són alguns dels temes que tractarem, crypto, abast, matrius, etc. Només un breu comentari sobre criptografia. No anem a recalcar aquest. Ho vam fer en conjunt de processadors 2, però per a la prova assegura't de saber la diferència entre el xifrat César i el xifrat Vigenère, com dos funcionen aquestes xifres i el que és per xifrar i desxifrar el text usant aquests 2 xifres. Recordeu, el xifrat César simplement trencada cada personatge en la mateixa quantitat, assegurant-mod pel nombre de lletres en l'alfabet. I el xifrat de Vigenère, d'altra banda, fa girar cada caràcter per una suma diferent, així que en lloc de dir cada personatge gira per 3 Vigenère rotarà cada personatge per una quantitat diferent depenent d'alguna paraula clau on cada lletra de la paraula clau representa una certa quantitat diferent per girar el text clar. Parlarem primer d'abast variable. Hi ha 2 tipus diferents de variables. Tenim les variables locals, i aquests seran definits fora de principal o fora de qualsevol funció o bloc, i aquests seran accessibles en qualsevol part del seu programa. Si vostè té una funció i que en funció d'un bucle while la variable global gran és accessible a tot arreu. Una variable local, d'altra banda, té com aconseguir una posició en què està definida. Si vostè té una funció aquí, per exemple, tenim aquesta funció g, ia l'interior de g no és una variable anomenada aquí i, i això vol dir que es tracta d'una variable local. Tot i que aquesta variable es diu i i aquesta variable s'anomena I Aquestes 2 funcions no tenen idea del que els altres són variables locals. D'altra banda, aquí es diu int x = 5, i això està fora de l'abast de qualsevol funció. Està fora de l'abast de la principal, de manera que aquesta és una variable global. Això significa que dins d'aquestes 2 funcions quan dic x - x + + o Estic accedint a la mateixa de manera que aquest x i i això són variables diferents. Aquesta és la diferència entre una variable global i una variable local. Pel que fa a disseny es refereix, de vegades és probablement una millor idea per mantenir les variables locals sempre que sigui possible ja que tenir un munt de variables globals es pot tornar molt confús. Si vostè té un munt de funcions modificant tot la mateixa cosa és possible que oblidi el que si aquesta funció accidentalment modifica aquest mundial, i aquesta altra funció que no sap res d'ella, i que es posa bastant confús a mesura que més codi. Mantenir les variables locals sempre que sigui possible és només un bon disseny. Arrays, recordem, són simplement llistes d'elements del mateix tipus. Dins de CI no es pot tenir una llista com 1, 2,0, hola. No podem fer això. Quan es declara una matriu C en tots els elements han de ser del mateix tipus. Aquí tinc una matriu de 3 punts. Aquí tinc la longitud de la matriu, però si jo només ho estic declarant en aquesta sintaxi on puc especificar el que tots els elements són tècnicament jo no necessito això 3. El compilador és prou intel · ligent com per saber la mida de la matriu ha de ser. Ara quan vull obtenir o establir el valor d'una matriu aquesta és la sintaxi per fer-ho. En realitat, això modificarà el segon element de la matriu perquè, recordar, numeració comença en 0, no en 1. Si vull llegir aquest valor el que puc dir alguna cosa com int x = array [1]. O si voleu establir aquest valor, com que estic fent aquí, Puc dir array [1] = 4. Que el temps per accedir als elements pel seu índex o la seva posició o on són a la matriu, i que la llista comença a 0. També podem tenir matrius de matrius, i això es diu una matriu multidimensional. Quan tenim una matriu multidimensional això vol dir que podem tenir alguna cosa com files i columnes, i això és només una forma de visualitzar això o pensar-hi. Quan tinc una matriu multidimensional que significa que vaig a començar a necessitar més d'un índex perquè si tinc una xarxa Només dic el que està a la fila no ens dóna un nombre. Això és realment només ens donarà una llista de nombres. Diguem que tinc aquesta sèrie aquí. Tinc una matriu anomenada quadrícula, i jo estic dient que és 2 files i 3 columnes, pel que aquesta és una forma de visualitzar. Quan dic que vull obtenir l'element en [1] [2] que vol dir que pel fet que aquestes són les files primera i després columnes Vaig a saltar a la fila 1 ja he dit 1. Llavors em vaig a venir aquí a la columna 2, i vaig a obtenir el valor 6. Té sentit? Multi-dimensionals, recordem, són tècnicament només un conjunt de matrius. Podem tenir arrays d'arrays d'arrays. Podem seguir endavant, però en realitat una forma de pensar com s'està exposat i el que passa és visualitzar en una xarxa com aquesta. En passar matrius a funcions, que van a comportar una mica diferent que quan passem variables regulars a les funcions com passar un int o un float. Quan passem a un tipus int o char o qualsevol d'aquests altres dades ens ho prenem una ullada a si la funció modifica el valor d'aquesta variable que el canvi no es va a propagar fins a la funció de trucada. Amb una matriu, d'altra banda, que passarà. Si pas en una matriu a una funció i que la funció canvia alguns dels elements, quan torni a la funció que es diu meva matriu ara serà diferent, i el vocabulari perquè és una matriu es passen per referència, com veurem més endavant. Això es relaciona amb com funcionen els punters, on aquests tipus de dades bàsiques, D'altra banda, es passen per valor. Podem pensar que a mesura que es fa una còpia d'una variable i després passar a la còpia. No importa el que fem amb aquesta variable. La funció de trucada no es donarà compte de que s'ha canviat. Les matrius són una mica diferents en aquest sentit. Per exemple, com acabem de veure, la principal és simplement una funció que pot prendre en dos arguments. El primer argument de la funció principal és argc, o el nombre d'arguments, i el segon argument es diu argv, i aquests són els valors reals d'aquests arguments. Diguem que tenen un programa anomenat this.c, i jo dic que això, i vaig a córrer això en la línia d'ordres. Ara, per passar alguns arguments per a mi programa que es diu això, Podria dir alguna cosa així com. / Això és cs 50. Això és el que ens imaginem a David a fer cada dia a la terminal. Però ara la funció principal dins d'aquest programa té aquests valors, de manera que argc és 4. Pot ser una mica confús perquè en realitat només estem passant és cs 50. Això és només 3. Però recorda que el primer element de argv o el primer argument és el nom de la funció en si. Així que això significa que hi ha 4 coses aquí, i el primer element serà. / aquest. I això es representa com una cadena. A continuació, els elements restants són el que va escriure en el després del nom del programa. Així que, en un apart, ja que és probable que vaig veure en pset 2, recordar que la cadena 50 és el nombre enter ≠ 50. Així que no podem dir alguna cosa com, 'int x = argv 3. Això no tindrà sentit, perquè això és una cadena, i aquest és un enter. Així que si vol convertir entre els dos, recorda, anem a té aquesta funció màgica anomenada atoi. Per això es necessita una cadena i retorna el sencer representat dins d'aquesta cadena. Així que això és un error fàcil de fer en el concurs, pensant que aquest serà automàticament el tipus correcte. Però només sé que aquests sempre seran cadenes encara que la cadena només conté un nombre enter o un caràcter o un flotador. Així que ara anem a parlar de temps d'execució. Quan tinguem tots aquests algoritmes que fan totes aquestes coses boges, es fa molt útil per fer la pregunta, "Quant de temps prendrà?" Representem a que, amb una cosa que es diu notació asimptòtica. Així que això significa que - bé, direm que li donem el nostre algorisme algunes entrades molt, molt, molt gran. Volem fer la pregunta, "Quant de temps prendrà? Quants passos es triga en el nostre algoritme per executar com una funció de la mida de l'entrada? " Així que la primera forma podem descriure el temps d'execució és de gran O. I aquest és el pitjor dels casos el temps de funcionament. Així que si volem ordenar una matriu, i donem el nostre algoritme d'una matriu això és en ordre descendent, quan hauria d'estar en ordre ascendent, que serà el pitjor dels casos. Aquest és el nostre límit superior de la durada màxima del temps del nostre algoritme prendrà. D'altra banda, aquest Ω es descriurà millor dels casos el temps de funcionament. Així que si li donem un arranjament ja està ordenat a un algoritme de classificació, Quant de temps es triga a resoldre? I això, a continuació, es descriu un límit inferior en temps d'execució. Així que aquí són només algunes paraules que descriuen alguns moments comuns de funcionament. Aquests són en ordre ascendent. El millor temps de funcionament que tenim es diu constant. Això vol dir que no importa quants elements donem el nostre algorisme, no importa el gran que és la nostra matriu, la seva classificació o fer el que estem fent a la matriu sempre tindrà la mateixa quantitat de temps. Per tant, pot representar que només amb un 1, que és una constant. També ens fixem en temps d'execució logarítmica. Així que alguna cosa com la recerca binària és logarítmica, on tallem el problema a la meitat cada vegada i llavors les coses només arribar més alt des d'allà. I si mai escriure una O de qualsevol algorisme factorial, és probable que no han de considerar això com el seu treball del dia. En comparar els temps d'execució, és important tenir en compte aquestes coses. Així que si tinc un algoritme que és O (n), i una altra persona té un algorisme de O (2n) són en realitat asimptòticament equivalent. Així que si ens imaginem n sigui un nombre gran com 111.000.000.000: així que quan estem comparant 111.000.000.000 a una mena de 111.000.000 + 3, que de sobte tres en realitat no fan una gran diferència ja. És per això que començarem a considerar aquestes coses com equivalents. Així que coses com aquestes constants aquí, hi ha 2 x això, o l'addició d'un 3, aquests són només constants, i aquests van a caure cap amunt. Així que per això tots els 3 d'aquests temps de funcionament són els mateixos que diuen que són O (n). De la mateixa manera, si tenim 2 temps d'execució altres, diguem O (n + 2n ³ ²), podem afegir + N, + 7, i després tenim un altre temps d'execució que és només O (³). de nou, es tracta del mateix, perquè aquests - aquests no són els mateixos. Aquestes són les coses mateixes, ho sento. Així que aquests són els mateixos perquè Aquest ³ va a dominar aquesta ² 2n. El que no és el mateix és que si se'ns ha acabat vegades com O (³) i O (n ²) perquè aquest ³ és molt més gran que aquesta ² n. Així que si tenim exponents, de sobte aquesta s'inicia a la matèria, però quan només estem tractant amb factors com estem aquí, llavors no va a importar, ja que només es va a abandonar. Fem una ullada a alguns dels algorismes que hem vist fins ara i parlar del seu temps d'execució. La primera manera de buscar un número en una llista, que vam veure, era la recerca lineal. I l'aplicació de cerca lineal és super senzill. Només tenim una llista, i anem a veure cada element de la llista fins trobar el nombre que busquem. Això significa que en el pitjor dels casos, aquest O (n). I el pitjor dels casos aquí podria ser si l'element està l'últim element, a continuació, utilitzant una recerca lineal que hem de mirar a cada element fins arribar a l'última amb la finalitat de saber que en realitat era a la llista. No podem abandonar a mig camí i dir: "Probablement no sigui allà". Amb la recerca lineal que hem de mirar a tot l'assumpte. El temps d'execució del millor cas, en canvi, és constant perquè en el millor dels casos l'element que estem buscant és només el primer de la llista. Així que va a portar exactament un pas, no importa el gran que la llista és si estem buscant el primer element cada vegada. Així que quan vostè busca, recordem, no es requereix que la llista estigui ordenada. Perquè estem simplement mirarà per sobre de cada element, i no importa realment quin ordre els elements es in Un algorisme de recerca més intel · ligent és una mena de recerca binària. Recordeu, l'aplicació de cerca binària és quan vostè va a seguir buscant a la meitat de la llista. I pel fet que està buscant en el medi, cal que la llista està ordenada o del que no sabem on el centre és, i hem de mirar per sobre de tota la llista per trobar-la, i llavors en aquest punt estem perdent el temps. Així que si tenim una llista ordenada i ens trobem amb el medi, anem a comparar el medi per l'element que estem buscant. Si és massa alt, llavors ens podem oblidar de la meitat dreta perquè sabem que si la nostra element ja és massa alt i tot a la dreta d'aquest element és encara més gran, llavors no cal mirar allà. Quan per contra, si el nostre element és massa baix, ho sabem tot a l'esquerra de l'element que també és massa baixa, pel que no té gaire sentit mirar allà, tampoc. D'aquesta manera, amb cada pas i cada vegada que ens fixem en el punt mig de la llista, anem a reduir el nostre problema a la meitat perquè de sobte sabem un munt de nombres que no poden ser la que estem buscant. En aquest pseudocodi seria alguna cosa com això, i perquè estem tallant la llista per la meitat cada vegada, nostres pitjors salts de temps d'execució de lineal a logarítmica. Així que de sobte es té log-in passos per tal de trobar un element en una llista. El temps d'execució millor dels casos, però, continua sent constant perquè ara, anem a dir que l'element que estem buscant és sempre el centre exacte de la llista original. Així que podem fer créixer la nostra llista tan gran com vulguem, però si l'element que estem buscant és al mig, llavors només va a portar un pas. Així que per això estem O (log n) i Ω (1) o constant. Anem a executar realment la recerca binària en aquesta llista. Així que diguem que estem buscant l'element 164. El primer que farem és trobar el punt mitjà d'aquesta llista. El que passa és que el punt mitjà es va a caure enmig d'aquests dos nombres, així que anem a dir arbitràriament, cada vegada que el punt mitjà se situa entre dos nombres, anem a reunir. Només hem de assegurar-nos que fem això cada pas del camí. Així que ens anem a reunir i direm que 161 és el centre de la nostra llista. Així 161 <164, i cada element a l'esquerra de 161 També és <164, pel que sabem que no ens ajudarà en absolut per començar a buscar per aquí perquè l'element que estem buscant no pot ser-hi. Així que el que podem fer és simplement podem oblidar que la meitat de tota l'esquerra de la llista, i ara només tenen en compte des de la dreta de la dècada de 161. Així que de nou, aquest és el punt mig, anem a arrodonir. Ara 175 és massa gran. Així que sabem que no ens ajudarà a buscar aquí o aquí, de manera que només es pot tirar això, i al final ens va a colpejar el 164. Qualsevol pregunta sobre la recerca binària? Anem a passar de buscar a través d'una llista ja ordenada- per realment tenint una llista de nombres en qualsevol ordre i fer que la llista en ordre ascendent. El primer algoritme vam veure va ser anomenat tipus bombolla. I això seria més simple dels algoritmes que vam veure. Ordenament de bombolla, diu que quan qualsevol dels 2 elements dins de la llista estan fora de lloc, és a dir, hi ha un nombre superior a l'esquerra d'un nombre més baix, llavors canviarem, perquè això vol dir que la llista serà "Més ordenada" del que era abans. I només continuarem amb aquest procés una i altra vegada i una altra fins que, finalment, el tipus d'elements bombolla a la seva ubicació correcta i tenim una llista ordenada. El temps d'execució que això serà O (n ²). Per què? Bé, doncs en el pitjor dels casos, prendrem cada element, i anem a acabar comparant amb qualsevol altre element a la llista. Però en el millor dels casos, tenim una llista ja ordenada, bombolla tipus de només passarà per una vegada, digui "Nope. Jo no vaig fer cap swaps, així que he acabat." Així que tenim un temps millor dels casos el funcionament de Ω (n). Anem a córrer espècie de bombolla en una llista. O anem a mirar alguns pseudocodi molt ràpid. Volem dir que volem perdre de vista, en cada iteració del bucle, fer un seguiment de si podem o no canviar cap element. Així que la raó d'això és, que anem a parar quan no hem canviat cap element. Així que al principi del nostre bucle no hem canviat res, així que vaig a dir que és fals. Ara, anirem per la llista i comparar element a element i i + 1 i si és el cas que hi ha un nombre més gran a l'esquerra d'un nombre més petit, llavors només anem a intercanviar-les. I després recordarem que ens canviat un element. Això vol dir que hem de passar per la llista almenys una vegada més perquè la condició en què es deté quan tota la llista ja està ordenada, el que significa que no han fet cap swaps. Així que per això la nostra condició aquí és ", mentre que alguns elements han estat canviats. Així que ara anem a veure això que s'executa en una llista. Tinc la llista 5,0,1,6,4. Ordenament de bombolla començarà tot el camí a l'esquerra, i va a comparar Els elements que, de manera 0 a i + 1, que és l'element 1. Va a dir, bé 5> 0, però en aquest moment 5 és a l'esquerra, així que he de canviar el 5 i el 0. Quan els intercanviar, de sobte em surt aquest llista diferent. Ara 5> 1, de manera que anem a intercanviar-les. 5 no és> 6, de manera que no ha de fer res aquí. Però 6> 4, de manera que hem de canviar. Un cop més, hem de repassar la llista sencera per descobrir finalment que aquestes estan fora de servei, ens canviar, i en aquest moment hem de passar per la llista 1 hora més per assegurar-se que tot és al seu ordre, i en aquest tipus bombolla punt ha acabat. Un algorisme diferent per prendre alguns elements i ordenar-és una mena de selecció. La idea darrere d'ordenació per selecció és que construirem una part ordenada de la llista 1 element alhora. I la manera com ho farem és construint el segment esquerre de la llista. I en el fons, tots - a cada pas, tindrem el més mínim element que ens queda que no ha estat encara ordenat, i ens mourem en aquest segment ordenada. Això vol dir que hem de trobar contínuament l'element mínim sense classificar i després prendre aquest element mínim i intercanviar amb el va deixar a la majoria d'elements que no està ordenada. El temps d'execució que això serà O (n ²) perquè en el pitjor dels casos hem de comparar cada element a tots els altres elements. Com que estem dient que si comencem a la meitat esquerra de la llista, cal anar a través de tot el segment dret per trobar l'element més petit. I llavors, de nou, hem d'anar sobre el segment de la dreta i tot seguir repetint una i altra i una altra. Això serà ² n. Anem a necessitar un llaç per l'interior d'un altre bucle for el que suggereix ² n. En el pensament millor dels casos, direm que li donem una llista ja ordenada; que en realitat no fan res millor que ² n. Per tipus de selecció no té manera de saber que l'element mínim és el que succeeix a mirar. Encara necessita per assegurar-se que això és realment mínim. I l'única manera d'assegurar-se que és el mínim, utilitzant aquest algorisme, és mirar cada element nou. Així que en realitat, si li donen - si se li dóna una llista d'ordenació per selecció ja classificada, que no farà res millor que donar-li una llista que no està ordenada encara. Per cert, si passa a ser el cas de que alguna cosa és O (alguna cosa) i l'omega d'alguna cosa, només puc dir més breument que és θ d'alguna cosa. Així que si veus que sorgeixen arreu, això és el que això significa. Si alguna cosa és theta de ² n, és alhora gran O (n ²) i Ω (n ²). Així que el millor i el pitjor cas, no fa cap diferència, l'algorisme es farà la mateixa cosa cada vegada. Així que això és el que pseudocodi per ordenar selecció podria ser similar. Estem bàsicament dirà que vull per iterar sobre la llista d'esquerra a dreta, i en cada iteració del bucle, vaig a moure l'element mínim en aquesta porció de la llista ordenada. I una vegada que em moc una mica allà, no he de mirar a aquest element nou. Perquè tan aviat com canviar un element en el segment esquerre de la llista, s'ordenen perquè estem fent tot en ordre ascendent utilitzant mínims. Llavors vam dir, bé, estem en la posició i, i hem de mirar tots els elements a la dreta de i per tal de trobar el mínim. Així que això significa que volem mirar des i + 1 fins al final de la llista. I ara, si l'element que estem mirant és menor que el nostre mínim fins ara, que, recordem, estem començant el descompte mínim per ser just qualsevol element que estem actualment, vaig a assumir que és el mínim. Si trobo un element que és més petit que això, llavors jo vaig a dir, bé, Bé, he trobat un nou mínim. Vaig a recordar on era aquest mínim. Així que ara, un cop passat per aquest segment sense classificar dret, Puc dir que canviaré l'element mínim amb l'element que es troba en la posició i. Això va a construir la meva llista, la meva porció ordenada de la llista d'esquerra a dreta, i no alguna vegada ha de veure un element de nou una vegada que estigui en aquesta part. Quan l'hem canviat. Així que anem a executar l'ordenació per selecció en aquesta llista. L'element blau aquí serà la i, i l'element vermell serà l'element mínim. Així que comença tot el camí a l'esquerra de la llista, com a mínim 5. Ara hem de trobar l'element Unsorted mínim. Per això diem 0 <5, de manera que 0 és el meu nou mínim. Però no pot quedar-se aquí, perquè encara podem reconèixer que 0 és el més petit, hem de passar per tots els altres elements de la llista per assegurar-se. Així 1 és més gran, és més gran 6, 4 és més gran. Això vol dir que després de veure tots aquests elements, he determinat 0 és el més petit. Així que canviaré el 5 i el 0. Quan canviï això, em vaig a posar una nova llista, i sé que mai he de mirar en aquest 0 de nou perquè una vegada que ho he canviat, ho he classificat i ja està. Ara dóna la casualitat que l'element blau torna a ser el 5, i hem de mirar a la 1, la 6 i la 4 per determinar que una És l'element més petit de menys, així que anem a canviar l'1 i el 5. Un cop més, hem de mirar - comparar el 5 i el 6 i el 4, i canviarem el 4 i el 5, i, finalment, comparar, aquests 2 nombres i intercanviar fins que tinguem la nostra llista ordenada. Qualsevol pregunta sobre tipus de selecció? Bé. Passem a l'últim tema aquí, i que és la recursivitat. La recursivitat, recordi, és aquesta cosa meta realment on una funció repetidament es diu. Llavors, en algun moment, mentre que el nostre succió en repetides ocasions que es fa dir, ha d'haver algun punt en què vam deixar de dir. Perquè si no fem això, llavors només seguirem fent això per sempre, i el nostre programa no només va a acabar. Cridem a aquesta condició, el cas base. I el cas base, diu, en lloc de cridar a una funció més, Només vaig a tornar algun valor. Així que una vegada que hem retornat un valor, hem deixat de cridar a nosaltres mateixos, i la resta de les trucades que hem fet fins ara també poden tornar. El contrari de la hipòtesi de base és el cas recursiu. I aquí és quan volem fer una altra crida a la funció que es troba, I és probable que, encara que no sempre, es vol utilitzar diferents arguments. Així que si tenim una funció anomenada f, i f acaba de cridar a prendre un argument, i ens segueixen trucant f (1), f (1), f (1), i dóna la casualitat que l'argument cau en un cas recursiu, estem encara mai va a parar. Fins i tot si tenim un cas base, cal assegurar-se que a la llarga ens va a colpejar aquest cas base. No ens limitem a seguir romanent en aquest cas recursiu. En general, quan ens truqui, nosaltres probablement tindrem un argument diferent cada vegada. Heus aquí una funció recursiva realment simple. Així que això va a calcular el factorial d'un nombre. A sobre de la tapa aquí tenim al nostre cas base. En el cas que n ≤ 1, no anem a trucar a factorial de nou. Anem a parar, només tornarem algun valor. Si no fos així, llavors anem a colpejar nostre cas recursiu. Noteu aquí que no només estem trucant factorial (n), perquè això no seria molt útil. Anem a trucar a factorial de res més. I perquè pugui veure, amb el temps si passem una mica factorial (5) o, anomenarem a factorial (4) i així successivament, i al final ens va a colpejar aquest cas base. Així que això té bona pinta. Anem a veure què passa quan realment executar aquest. Es tracta de la pila, i diguem que principal dirà a aquesta funció amb un argument (4). Així que un cop factorial veu i = 4, factorial es dirà. Ara, de sobte, tenim factorial (3). Així doncs, aquestes funcions es seguirà creixent fins que finalment arribem al nostre cas base. En aquest punt, el valor de retorn d'això és el retorn (nx el valor de retorn d'aquesta), el valor de retorn d'aquesta nx és el valor de retorn d'aquesta. Finalment, hem d'arribar a algun nombre. A la part superior aquí, diem return 1. Això significa que una vegada que torni a aquest nombre, que pot fer esclatar est de la pila. Així que aquest factorial (1) està fet. Quan un torna, aquesta factorials (1) devolucions, aquest retorn a 1. El valor de retorn d'aquesta, recordem, era nx el valor de retorn d'aquesta. Llavors, de sobte, aquest home sap que vull tornar 2. Així que recorda, tornar el valor d'això és només el valor de retorn nx aquí. Així que ara podem dir 3 x 2, i, finalment, aquí podem dir això serà de 4 x 3 x 2. I una vegada que això torni, ens posem mans a un sol nombre enter dins del principal. Teniu alguna pregunta respecte la recursivitat? Està bé. Així que no hi ha més temps per preguntes al final, però ara Joseph cobrirà els temes restants. [Joseph Ong] D'acord. Així que ara que hem parlat de recurrències, anem a parlar una mica sobre el que merge sort és. Combinar tipus és bàsicament una altra manera d'ordenar una llista de nombres. I la manera com funciona és, amb una mena de barreja té una llista, i és el que fem diem, anem a dividir-la en dues meitats. En primer lloc, es quedarà sense fondre de nou tipus a la meitat esquerra, llavors anem a córrer merge sort en la meitat dreta, i això ens dóna ara dues meitats que s'ordenen, i ara anem a combinar les meitats. És una mica difícil de veure sense un exemple, així que seguirem tot el procediment i veure què passa. Així que començar amb aquesta llista, l'hi divideix en dues meitats. Correm merge sort en la meitat esquerra primer. Així que aquesta és la meitat esquerra, i ara executa a través d'aquesta llista de nou que es passa a una mena de barreja, i després ens veiem, de nou, a la banda esquerra d'aquesta llista i es corre fusionar tipus sobre el mateix. Ara, ens posem mans a una llista de números 2, i ara la meitat esquerra és només un element de llarg, i no podem dividir una llista que és només un element en la meitat, pel que acaba de dir, una vegada que tinguem 50, que és només un element, ja està solucionat. Un cop hàgim acabat amb això, podem veure que podem passar a la part dreta d'aquesta llista, i 3 també es classifiquen, de manera que ara que les dues meitats d'aquesta llista estan ordenades podem unir aquests números de nou junts. Així que veiem 50 i 3; 3 és inferior a 50, el que va en primer lloc i després 50 entra Ara, això està fet, tornem a aquesta llista i ordenar és la meitat dreta. 42 és el seu propi nombre, així que ja ordenats. Així que ara comparem aquests 2 i 3 és menor que 42, per la qual cosa es va posar en primer lloc, ara de 42 anys es va posar en, i el 50 es posa endins Ara, que està classificat, anem tot el camí fins al cim, 1337 i 15. Bé, ara ens fixem en la part esquerra d'aquesta llista; 1337 és per si mateix el que és ordenat i el mateix amb 15. Així que ara combinem aquests dos nombres per ordenar la llista original, 15 <1337, el que va en primer lloc, a continuació, va in 1337 I ara ens ordenen les dues meitats de la llista original fins a la part superior. I tot el que has de fer és combinar aquests. Ens fixem en els 2 primers números d'aquesta llista, 3 <15, per la qual cosa entra en la matriu primer ordenar. 15 <42, així que va polz Ara, 42 <1337, que va in 50 <1337, per la qual cosa va in I noti que només va trigar 2 nombres fora d'aquesta llista. Així que no només estem alternant entre les dues llistes. Estem veient el principi, i estem prenent l'element que és més petit i després posar-lo en la nostra matriu. Ara hem fusionat tots les meitats i ja està. Qualsevol pregunta sobre fusionar tipus? Sí? [Estudiant] Si es tracta de dividir en grups diferents, per què no acaba de dividir una vegada i té 3 i 2 en un grup? [Resta pregunta inintel · ligible] La raó - de manera que la pregunta és, per què no podem simplement combinar-los en aquest primer pas després que els tenim? La raó per la qual podem fer això, comenci en els elements d'esquerra-la majoria de les dues parts, i després prendre la més petita i la va posar dins, és que sabem que aquests llistes individuals de les comandes ordenats. Així que si estic mirant als elements més a l'esquerra de les dues meitats, Jo sé que seran els elements més petits d'aquestes llistes. Així que puc posar-los en els llocs més petits elements d'aquesta llarga llista. D'altra banda, si miro aquests dos llistes en el segon nivell d'allà, 50, 3, 42, 1337 i 15, els que no estan ordenades. Així que si miro als 50 i 1337, em vaig a posar 50 en la meva primera llista. Però això no té molt sentit, ja que 3 és l'element més petit de tots ells. Així que l'única raó per la qual podem fer aquest pas es deu a la combinació de les nostres llistes ja estan ordenats. És per això que hem de baixar tot el camí fins al fons perquè quan tenim un sol nombre, vostè sap que un sol nombre en i de per si ja és una llista ordenada. Alguna pregunta? No? Complexitat? Bé, es pot veure que en cada pas hi ha números finals, i podem dividir una llista en el registre mitjà n vegades, que és d'on s'obté aquest log n x n complexitat. I veuràs el millor dels casos per tipus de combinació és n log n, i que només succeeix així que el pitjor dels casos, o la Ω enllà, també és n log n. Una cosa a tenir en compte. Canviant de tema, anirem a algun arxiu de súper bàsic I / O. Si es mirava a Scramble, t'adonaràs que tenia algun tipus de sistema on es pot escriure en un arxiu de registre si vostè llegeix a través del codi. Anem a veure com es pot fer això. Bé, tenim fprintf, que es pot considerar com just printf, però només imprimir a un fitxer en comptes, i per tant la f al principi. Aquest tipus de codi fins aquí, el que fa és, com hauràs vist en Scramble, passa a través de la impressió matriu 2-dimensional fora fila per fila quins són els números. En aquest cas, printf imprimeix al seu terminal o el que anomenem la sortida estàndard de secció. I ara, en aquest cas, l'únic que has de fer és reemplaçar printf amb fprintf, diuen que sobre el fitxer que voleu imprimir i, en aquest cas, només s'imprimeix a aquest arxiu en lloc d'això imprimint al seu terminal. Bé, llavors això ens porta a la pregunta: D'on traiem aquest tipus de fitxer des, oi? Passem vos per aquest fuction de fprintf, però no teníem idea d'on vi. Bé, al principi del codi, el que vam tenir va ser aquest fragment de codi per aquí, que bàsicament diu que es pot obrir el fitxer log.txt flama. Què fem després d'això és que hem d'assegurar que l'arxiu està realment obert amb èxit. Així que pot fallar per múltiples raons, vostè no té prou espai al seu ordinador, per exemple. Així que sempre és important abans de fer qualsevol operació amb l'arxiu que comprovem si aquest arxiu es va obrir correctament. Així que el que a, aquest és un argument a fopen, bé, pot obrir un arxiu de moltes maneres. El que podem fer és que l'hi pot transmetre w, el que significa reemplaçar l'arxiu si surt ja, Podem passar una a, afegir al final de l'arxiu en lloc que sigui redefinit, o podem especificar r, és a dir, anem a obrir l'arxiu com de només lectura. Així que si el programa intenta fer canvis a l'arxiu, cridar en ells i no deixis que ho facin. Finalment, un cop que hàgim acabat amb l'arxiu, feta realitzar operacions en ell, hem d'assegurar que tanqui l'arxiu. I així, al final del seu programa, que passarà de nou l'arxiu que ha obert, i simplement tancar-la. Així que això és una cosa important que cal assegurar-se que vostè ho fa. Així que recordi que pot obrir un arxiu, llavors es pot escriure a l'arxiu, realitzar operacions a l'arxiu, però després es va a tancar l'arxiu al final. Qualsevol pregunta sobre l'arxiu de base de E / S? Sí? [Pregunta Estudiant, inintel · ligible] Aquí mateix. La pregunta és, ¿d'on ve aquest arxiu log.txt aparèixer? Bé, si només li donen log.txt, es crea en el mateix directori que l'executable. Així que si TEU AQUESTES - >> [pregunta Estudiant, inintel · ligible] Sí A la mateixa carpeta, o en el mateix directori, com l'anomeneu. Ara la memòria, pila i pila. Llavors, com és la memòria s'estableix a l'ordinador? Bé, es pot imaginar com una mena de memòria d'aquest bloc aquí. I en la memòria que tenim el que s'anomena la pila atrapat allà, i la pila que hi és baix. I la pila creix cap avall i la pila creix cap amunt. Així com Tommy esmentar - oh, bé, i tenim aquestes altres 4 segments que vaig a arribar a un segon - Com Tommy dit abans, vostè sap com es diuen les seves funcions i cridar als altres? Ells construeixen aquest tipus de marc de pila. Bé, si els principals trucades foo, foo es posen a la pila. Foo diu bar, bar arribar a posar a la pila, i que es posen a la pila després. I en tornar, cada un d'ells es porten de la pila. Què cadascun d'aquests llocs i mantenir la memòria? Doncs bé, la part superior, que és el segment de text, conté el programa en si. Així que el codi màquina, que hi és, un cop que es compila el programa. A continuació, qualsevol inicialitza les variables globals. Així que hi ha variables globals en el seu programa, i com vostè diu, a = 5, que es va posar en aquest segment, i just a sota d'això, Té dades globals no inicialitzats, que s'acaba de int a, però no et diuen que és igual a res. Adonar-se que aquestes són variables globals, pel que estan fora de la principal. Així que això significa que les variables globals que es declaren però no s'inicialitza. Així que el que està en el munt? La memòria assignada amb malloc, que arribarem a una mica. I, finalment, amb la pila té alguna variables locals i qualsevol altra funció que es podria anomenar en qualsevol dels seus paràmetres. L'última cosa que vostè realment no ha de saber quines són les variables d'entorn fan, però cada vegada que s'executi el programa, hi ha alguna cosa associat, igual que aquest és el nom de la persona que va executar el programa. I això serà una espècie de a la part inferior. En termes d'adreces de memòria, que són valors hexadecimals, els valors al començament superior a 0, i van tot el camí fins al fons. En aquest cas, si vostè està en el sistema de 32-bit, la direcció al final serà 0x, seguit per af, perquè això és 32 bits, que és de 8 bytes, i en aquest cas 8 bytes correspon a 8 dígits hexadecimals. Així que aquí tindrà, com, 0xffffff, i allà tindràs 0. Quins són els punters? Alguns de vostès no han cobert això en la secció anterior. però sí que vam anar a través d'ella a la conferència, de manera que un punter és només un tipus de dades que emmagatzema, en lloc d'algun tipus de valor com 50, que emmagatzema l'adreça d'algun lloc en la memòria. Igual que la memòria [inintel · ligible]. Així que en aquest cas, el que tenim és, tenim un punter a un enter o un int *, i conté la següent adreça hexadecimal de 0xLOQUESEA. Així que el que tenim és, ara, aquest punter en algun lloc de la memòria, i això és només una, el valor 50 està en aquesta posició de memòria. En alguns sistemes de 32-bit, en tots els sistemes de 32-bits, els punters ocupen 32 bits o 4 bytes. Però, per exemple, en un sistema de 64-bit, els punters són de 64 bits. Així que això és una cosa que vostè voldrà tenir en compte. Així en un sistema d'extrem de bits, un punter és cantoneres de llarg. Els punters són una mica difícil de digerir sense coses extres, així que anem a anar a través d'un exemple d'assignació de memòria dinàmica. Què assignació de memòria dinàmica fa per vostè, o el que anomenem malloc, li permet assignar un tipus de dades fora del set. Així que aquest tipus de dades és més permanent per a la durada del programa. Perquè, com vostè sap, si vostè declara x dins d'una funció, i que recupera el funcionament, que ja no tenen accés a les dades emmagatzemades en x. Quins indicadors farem és que anem a emmagatzemar els valors de la memòria o la botiga en un segment diferent de la memòria, és a dir, el munt. Ara, un cop que tornem de la funció, sempre que tenim un punter a aquesta ubicació en la memòria, llavors el que podem fer és simplement podem veure els valors allà. Vegem un exemple: Aquest és el nostre nou disseny de la memòria. I tenim aquesta funció principal. El que fa és - està bé, tan simple, dret - int x = 5, que és només una variable a la pila en principal. D'altra banda, ara es declara un punter que crida als giveMeThreeInts funció. I ara entrem en aquesta funció i es crea un nou marc de pila per a això. No obstant això, en aquest marc de pila, declarem int * temp, que en mallocs 3 punts per a nosaltres. Així que la mida de int ens donarà la quantitat de bytes és int, malloc i ens dóna que molts bytes d'espai en el munt. Així que en aquest cas, hem creat un espai suficient per a 3 nombres enters, i el munt està allà dalt, i per això l'he dibuixat més amunt. Quan hagis acabat, tornem aquí, només necessita 3 sencers retornats, i torna la direcció, en aquest cas més que on la memòria és. I ens vam posar punter = interruptor, i allà tenim més que un altre punter. Però el que retorna la funció s'apila aquí, i desapareix. Així temperatura desapareix, però encara mantenen la direcció d'on aquests 3 nombres enters es troben dins de la xarxa. Així que en aquest joc, els punters estan en l'àmbit local per al marc d'apilament, però la memòria a què es refereixen és al munt. Això té sentit? [Estudiant] Podria repetir això? >> [Joseph] Sí Així que si em torno una mica, es veu que la temperatura assignada part de la memòria en el munt fins allà. Per això, quan aquesta funció, giveMeThreeInts devolucions, aquesta pila d'aquí desapareixerà. I amb això cap de les variables, en aquest cas, aquest punter que s'ha assignat en el marc d'apilament. Això desapareixerà, però des que vam tornar temp i ens vam posar punter = temp, punter ara va a apuntar la mateixa memòria de la ubicació com la temperatura era. Així que ara, tot i que perdi temperatura, aquest punter local, que encara conserven l'adreça de memòria del que estava assenyalant cap a l'interior d'aquest indicador variable. Preguntes? Això pot ser una mica d'un tema confús si vostè no ha passat per sobre de la secció. Podem, la seva TF dubte sobre aquest i, per descomptat, podem respondre a les preguntes al final de la sessió de revisió per això. Però això és una espècie d'un tema complex, i no tinc més exemples que apareixeran que ajudarà a aclarir el que en realitat són punters. En aquest cas, els punters són equivalents a les matrius, de manera que només pot utilitzar aquest indicador com la mateixa cosa com una matriu int. Així que estic d'indexació en 0, i canviant el primer nombre enter de 1, canviant el segon nombre enter de 2, i el sencer tercer a 3. Així que més de punters. Bé, recordo Binky. En aquest cas hem assignat un punter, o que declarem un punter, però al principi, quan m'acaba de declarar un punter, no està apuntant a qualsevol part de la memòria. Són només els valors d'escombraries a l'interior de la mateixa. Així que no tinc idea d'on aquest indicador està apuntant. Té una direcció que s'acaba d'omplir amb 0 i 1, on es va declarar inicialment. No puc fer res amb això fins que jo anomeno malloc-hi i després em fa una mica d'espai a la pila on puc posar els valors a l'interior. D'altra banda, jo no sé el que hi ha dins d'aquesta memòria. Així que el primer que has de fer és comprovar si el sistema té prou memòria que em torni un nombre enter, en primer lloc, pel que jo estic fent aquesta comprovació. Si el punter és nul, el que significa que no té prou espai o algun altre error, així que hauria de sortir del meu programa.  Però si es va tenir èxit, ara puc utilitzar aquest punter i el que fa és * punter es dedueix que la direcció és a on aquest valor és, i el posa igual a 1. Així que aquí, estem comprovant si aquesta memòria existit. Quan se sap que existeix, pot posar-hi quin és el valor que desitja posar en ell, en aquest cas 1. Quan hagi acabat amb ella, la necessitat d'alliberar aquest punter perquè hem de tornar al sistema que la memòria que vostè va sol · licitar en primer lloc. Com que l'equip no sap quan hàgim acabat amb ell. En aquest cas estem dient explícitament, està bé, hem acabat amb aquesta memòria. Si algun altre procés que necessita, algun altre programa que necessita, no dubteu a seguir endavant i prendre-ho. El que també es pot fer és que només es pot obtenir l'adreça de les variables locals en el set. Així int x està dins el marc d'apilament principal. I quan utilitzem aquest signe, aquest i l'operador, el que fa és Es triga x, i x és només algunes dades en la memòria, però que té una direcció. Es troba situat en algun lloc. Llavors, trucant & x, el que això fa és que ens dóna la direcció de x. En fer això, estem fent punter al punt on x és a la memòria. Ara només ens queda fer alguna cosa com * x, arribarem al 5 de tornada. L'estrella es diu eliminació de referències a ell. Seguiu la direcció i s'obté el valor de la mateixa s'emmagatzema allà. Alguna pregunta? Sí? [Estudiant] Si no fa la cosa tres puntes, segueix tenint compilar? Sí Si no fa la cosa de 3-punts, que encara va a compilar, però et vaig a mostrar el que passa en un segon, i sense fer això, això és el que anomenem una pèrdua de memòria. No està donant el sistema còpies de la seva memòria, així que després d'un temps el programa es va a acumular memòria que no està utilitzant, i només pugui usar-lo. Si alguna vegada has vist a Firefox amb 1,5 milions de kilobytes a l'ordinador, en l'administrador de tasques, això és el que està passant. Vostè té una pèrdua de memòria en el programa que no està manejant. Llavors, com fa la feina punter aritmètica? Bé, l'aritmètica de punters és una espècie d'indexació com en una matriu. En aquest cas, tinc un punter, i el que jo faig és fer punt punter al primer element d'aquesta sèrie de tres nombres enters que he assignat. I ara què faig, punter estrella només canvia el primer element de la llista. Estrella punter +1 punts aquí. Així punter està per aquí, un punter és per aquí, punter +2 és per aquí. Així només afegir 1 és el mateix que moure al llarg d'aquesta matriu. El que fem és, quan fem un punter a obtenir l'adreça per aquí, i amb la finalitat d'obtenir el valor d'aquí, es posa un estel en tota l'expressió de per eliminació de referències. Així, en aquest cas, m'estic donant el primer lloc en aquesta matriu a 1, ubicació a 2 segons, i tercera ubicació a 3. Llavors, què estic fent aquí és que estic imprimint nostre punter +1, que només em dóna 2. Ara estic incrementant punter, per la qual cosa és igual punter punter +1, que es mou cap endavant. I ara si em imprimeixi un punter, punter +1 és ara 3 anys, que en aquest cas s'imprimeix 3. I per alguna cosa gratis, el punter que li dono ha d'apuntar al principi de la matriu que vaig tornar de malloc. Així que, en aquest cas, si jo hagués de cridar 3 aquí, això no seria correcte, perquè és al centre de la matriu. He de resta per arribar a la ubicació original l'acte inicial abans que pugui alliberar-lo. Per tant, aquí hi ha un exemple més complicat. En aquest cas, estem assignant 7 caràcters en una matriu de caràcters. I en aquest cas el que estem fent és que estem recórrer els 6 primers d'ells, i els estem establint a la Z. Així, per int i = 0, i> 6, i + +, Per tant, el punter + i només ens donarà, en aquest cas, punter, punter +1, 2 punter, punter 3, i així successivament i així successivament en el bucle. Què farà és que arribi aquesta direcció, desreferencia per obtenir el valor, i que els canvis a un valor Z. Després, al final recorda que això és una cadena, no? Totes les cadenes han d'acabar amb el caràcter nul de terminació. Per tant, el que faig és a punter 6 vaig posar el caràcter terminador nul polz I ara el que estic fent bàsicament aquí està implementant printf per a una cadena, no? Així que, quan printf ara quan s'ha arribat al final d'una cadena? Quan arribi el caràcter nul de terminació. Així, en aquest cas, els meus punts punter original al principi d'aquesta matriu. Puc imprimir el caràcter primer en sortir. El moc a través d'un. Puc publicar aquell personatge. El moc de nou. I segueixo fent això fins que arribi al final. I ara el punter * Final voluntat dereference això i el caràcter nul de terminació de tornada. I així la meva bucle while s'executa només quan aquest valor no és el caràcter nul de terminació. Així que, ara surto d'aquest bucle. I pel que si li resta 6 d'aquest indicador, Torno fins al final fins al principi. Recorda, jo estic fent això perquè he d'anar al principi per tal de alliberar-la. Per tant, sé que era molt. Hi ha alguna pregunta? Si us plau, sí? [Inintel · ligible pregunta Estudiant] Es pot dir que més fort? Em sap greu. [Estudiant] En l'última diapositiva just abans que va alliberar al punter, on estaves realment canviar el valor del punter? [Josep] Per tant, aquí mateix. >> [Estudiant] Oh, està bé. [Josep] Per tant, tinc un punter menys negatiu, dreta, que mou la cosa de nou, i després ho alliberi, perquè aquest punter ha de ser assenyalat al principi de la matriu. [Estudiant] Però això no caldria que es va aturar després d'aquesta línia. [José] Així que, si m'hagués detingut després d'això, això seria considerat una pèrdua de memòria, perquè no s'ha executat el programa gratuït. [Estudiant] I [inintel · ligible] després de les tres primeres línies on tenies punter +1 [inintel · ligible]. [José] Uh-huh. Llavors, ¿quina és la pregunta que cal? Em sap greu. No, no. Vaja, vaja, si us plau. [Estudiant] Per tant, no estem canviant el valor de punters. No hauria hagut de fer punter menys negatiu. [José] Sí, exactament. Per tant, quan faig un punter i el punter +2, No faré punter és igual a un punter. Per tant, el punter només es queda apuntant al principi de la matriu. És només quan ho faig plus plus que estableix el valor de nou en el punter, que en realitat es mou al llarg d'aquest. Està bé. Més preguntes? Un cop més, si això és una espècie de insuportable, això es tractarà en la sessió. Pregúntele al seu company d'ensenyament en això, i podem respondre a les preguntes al final. I en general no ens agrada que facis això menys. Això ha de m'exigeixen fer el seguiment de tot el que he posició de la matriu. Així que, en general, això és només per explicar com funciona l'aritmètica de punters. Però el que normalment volem fer és que ens agrada per crear una còpia del punter, i després utilitzarem aquesta còpia quan ens movem al voltant de la cadena. Per tant, en aquests casos s'utilitza la còpia per imprimir tota la cadena, però no hem de fer com punter menys 6 o portar un registre de quant ens traslladem en això, només perquè sabem que el nostre punt original segueix assenyalar el començament de la llista i tot el que va ser alterat aquesta còpia. Així, en general, modificar les còpies del seu punter original. No tracti d'una cosa així com - no alterar les còpies originals. Tractar d'alterar úniques còpies del seu original. Així, es dóna compte quan passem la cadena a printf vostè no ha de posar una estrella al front d'ella com ho vam fer amb tots els desreferencia altres, no? Per tant, si imprimeix la cadena s% espera que tot és una adreça, i en aquest cas un punter o en aquest cas com una matriu de caràcters. Personatges, char * s, i les matrius són la mateixa cosa. Pointer és caràcters i matrius de caràcters són la mateixa cosa. I així, tot el que hem de fer és passar punter. No hem de passar com punter * ni res d'això. Per tant, les matrius i els punters són la mateixa cosa. Quan estàs fent alguna cosa com x [i] per aquí per una matriu, el que està fent sota el capó és el que està dient, està bé, es tracta d'una matriu de caràcters, pel que és un punter. I així, x són la mateixa cosa, i per tant el que fa és que afegeix Yax, el que és el mateix que moure cap endavant en la memòria que molt. I ara x + i ens dóna algun tipus de direcció, i eliminar la referència al domicili o segueixi la fletxa on aquesta ubicació en la memòria és i obtenim el valor de la ubicació en la memòria. Així, de manera que aquests dos són exactament la mateixa cosa. És només una manera d'expressar. Ells fan el mateix. Són només sintàctica diferents entre si. Així que, què pot anar malament amb punters? Igual, molt. Bé. Així, les coses dolentes. Algunes de les coses dolentes que pot fer no està comprovant si la seva crida malloc retorna un valor nul, no? En aquest cas, estic demanant al sistema que em donés - Quin és aquest nombre? Com 2 mil milions de vegades 4, pel fet que la mida d'un enter de 4 bytes. Ho estic demanant com 8 milions de bytes. Per descomptat, el meu equip no serà capaç de donar-me volta que molta memòria. I no comprovar si aquest és nul, de manera que quan tractem d'eliminar la referència que hi - segueixi la fletxa a on es va a - no tenim aquesta memòria. Això és el que anomenem l'eliminació de referències a un punter nul. I això fa que essencialment violació de segment. Aquesta és una de les formes en què pots violació de segment. Altres coses dolentes que vostè pot fer - bo. Això va ser desreferencia un punter nul. Bé. Altres coses dolentes - bé, en fixar que vostè acaba de posar un xec en allà que comprova si el punter és nul i sortir del programa si passa que malloc retorna un punter nul. Aquest és el còmic xkcd. La gent ho entenc ara. Gairebé. Així, la memòria. I em vaig anar per això. Estem trucant a malloc en un bucle, però cada vegada que fem una crida a malloc estem perdent la pista d'on aquest indicador fa referència, perquè ho estem colpejant fortament. Per tant, la primera crida a malloc em fa memòria aquí. Els meus punters punters a això. Ara, jo no ho alliberarà, així que ara jo dic malloc nou. Ara apunta cap aquí. Ara la meva memòria apunta fins aquí. Apuntant cap aquí. Apuntant cap aquí. Però he perdut el compte de les adreces de tota la memòria per aquí que em van assignar. I ara no tinc cap referència a ells mai més. Per tant, no puc alliberar fora d'aquest bucle. I així, amb la finalitat de fixar alguna cosa com això, si s'oblida de la memòria lliure i s'obté aquesta pèrdua de memòria, Cal alliberar la memòria dins aquest bucle quan hagueu acabat amb ell. Bé, això és el que passa. Sé que molts de vostès odien això. Però ara - yay! S'obté com 44.000 kilobytes. Així, que es lliure en l'extrem del bucle, i això va a alliberar només la memòria cada vegada. En essència, el programa no té una pèrdua de memòria més. I ara una altra cosa que pots fer és alliberar la memòria que vostè ha demanat dues vegades. En aquest cas, és una cosa malloc, canvia el seu valor. Vostè es lliure un cop perquè vas dir que havies acabat amb ella. Però després el va alliberar de nou. Això és una cosa que és bastant dolent. No va a violació de segment al principi, però després d'una estona el que això fa és alliberar aquesta doble corromp l'estructura de munt, i vostè aprendrà una mica més en això vostè decideix prendre una classe com CS61. Però essencialment després d'un temps l'equip va a confondre sobre el que les posicions de memòria on estan i cap a on s'emmagatzema - on les dades s'emmagatzemen a la memòria. I així alliberar un punter dues vegades és negatiu que no vull fer. Altres coses que poden sortir malament no useu sizeof. Així que, en aquest cas malloc 8 bytes, i això és el mateix que dos enters, no? Llavors, això és perfectament segur, però ho és? Bé, com Lucas va parlar sobre diferents arquitectures, sencers són de longituds diferents. Per tant, l'aparell que està utilitzant, els enters són al voltant de 4 bytes, però en algun altre sistema que podria ser de 8 bytes o poden ser 16 bytes. Per tant, si només utilitzen aquest número per aquí, aquest programa pot treballar en l'aparell, però no va a assignar suficient memòria en algun altre sistema. En aquest cas, això és el que l'operador sizeof s'utilitza per. Quan cridem a sizeof (int), el que fa és  que ens dóna la mida d'un sencer en la matriu que s'executa el programa. Així, en aquest cas, sizeof (int) tornarà 4 en alguna cosa com l'aparell, i ara aquesta voluntat 4 * 2, que és 8, que és només la quantitat d'espai necessari per dos enters. En un sistema diferent, si és un int com 16 bytes o 8 bytes que només tornarà suficients bytes per emmagatzemar aquesta quantitat. I, finalment, les estructures. Per tant, si es vol guardar una taula de sudoku en la memòria, com podem fer això? Es podria pensar en com una variable per a la primera cosa, una variable per a la segona cosa, una variable per a la tercera cosa, una variable per a la quarta cosa - dolent, oi? Per tant, una millora que vostè pot fer sobre això és fer una matriu de 9 x 9. Això està bé, però el que si desitja associar altres coses amb la targeta de sudoku com el que la dificultat de la junta és, o, per exemple, quin és la seva puntuació és, o quant temps ha pres vostè per resoldre aquest fòrum? Bé, el que puc fer és que vostè pot crear una estructura. El que estic dient és, bàsicament, estic definint aquesta estructura per aquí, i estic definint un tauler de sudoku que consisteix en una placa que és 9 x 9. I el que ha de té punters a el nom del nivell. També compta amb x i i, que són les coordenades d'on estic ara mateix. També ha temps passat [inintel · ligible], i té el nombre total de moviments que he oferta fins ara. I així, en aquest cas, pot agrupar una gran quantitat de dades en una sola estructura en lloc de tenir-lo com volar al voltant de la mateixa diferents variables que en realitat no puc seguir la pista. I això ens permet tenir només sintaxi agradable per fer referència a una espècie de coses diferents dins d'aquesta estructura. Jo només puc fer board.board, i em surt el tauler sudoku esquena. Board.level, em surt com és de difícil. Board.x board.y i em donen les coordenades d'on podria estar en el tauler. I, llavors, accedir al que anomenem camps de l'estructura. Això defineix sudokuBoard, que és un tipus que tinc. I ara som aquí. Tinc una variable anomenada "junta" de sudokuBoard tipus. I així que ara puc accedir a tots els camps que componen aquesta estructura aquí. Qualsevol pregunta sobre les estructures? Sí? [Estudiant] Per int x, i, al mateix temps que va declarar en una línia? >> [Joseph] Uh-huh. [Estudiant] Així que, pots fer això amb tots ells? Igual que en x, I coma vegades que el total? [José] Sí, definitivament es pot fer això, però la raó per la qual posar x i i en la mateixa línia - i la pregunta és per què només podem fer-ho a la mateixa línia? Per què no només cal posar tot això en la mateixa línia és x i i es relacionen entre si, i això és només estilísticament més correcte, en cert sentit, perquè és agrupar dues coses en la mateixa línia aquest tipus de com es refereixen a la mateixa cosa. I m'acaba de trencar aquests trossos. És només una cosa estil. És funcionalment no fa cap diferència en absolut. Qualsevol altra pregunta sobre les estructures? Es pot definir una Pokédex amb una estructura. Un Pokémon té un nombre i té una carta, un propietari, un tipus. I llavors, si vostè té una gran varietat de Pokémon, vostè pot fer una Pokédex, oi? D'acord, genial. Per tant, les preguntes sobre les estructures. Els que estan relacionats amb les estructures. Finalment, el BGF. Què GDB permeten fer? Permet depurar el programa. I si vostè no ha utilitzat GDB, em va recomanar veure el curt i repassant el que GDB és a dir, com es treballa amb ell, com pot usar-lo, i provar-ho en un programa. I així ho GDB li permet fer és que li permet pausar la [inintel · ligible] seu programa i una línia de pràctica. Per exemple, vull fer una pausa en l'execució com la línia 3 del meu programa, i ja que estic a la línia 3 que pot imprimir tots els valors que hi són. I així el que anomenem com una pausa en una línia Se li diem posar un punt d'interrupció en aquesta línia i llavors podrem imprimir les variables en l'estat del programa en aquest moment. Podem llavors des d'allà pas a pas el programa línia per línia. I llavors pot mirar l'estat de la pila en el moment. I així, per tal d'utilitzar GDB, el que fem és que anomenem so metàl · lic a l'arxiu C, però hem de passar la bandera ggdb. I un cop que hagis acabat amb això en tenim prou amb executar gdb a l'arxiu de sortida resultant. I perquè pugui obtenir una mica de massa com de text com aquest, però en realitat l'única cosa que has de fer és introduir comandaments al principi. Trencar principal posa un punt de ruptura en principal. Llista 400 enumera les línies de codi al voltant de la línia 400. I així, en aquest cas, només pot mirar al voltant i dir, oh, Vull establir un punt d'interrupció en la línia 397, que és aquesta línia, i després el programa s'executa en aquest pas i que trencarà. Es farà una pausa allà, i vostè pot imprimir, per exemple, el valor de baixa o alta. I així hi ha un munt d'opcions que necessita saber, i aquesta presentació pujarà al lloc web, així que si el que desitja fer referència a aquests o similars les va posar en els teus fulls de trucs, no dubti. Cool. Això va ser Quiz Revisió 0, i anem a quedar si té alguna pregunta. Està bé.  [Aplaudiment] [CS50.TV]