JASON HIRSCHHORN: Benvenuto A5, tutti. Abbiamo una settimana emozionante davanti a noi, soprattutto perché ci sono così tanti nuovi volti in questa stanza. E 'meraviglioso. Molti di voi sono qui per caso, che è ancora meglio. Quindi spero che manterrai unirsi a noi. Questa settimana andremo a spendere la maggior parte di sezione preparazione per il quiz. Quindi per la nostra agenda, stiamo andando a parlare un po 'di risorse per la classe, ma anche per il quiz, e poi, di nuovo, trascorrere la maggior parte della classe di parlare su domande. Una volta che abbiamo finito di rispondere alla tua domande, o se le vostre domande naturalmente ci portano a qualche codifica, mi avere problemi di esempio dal midterms passato che ci codificare in tempo reale nella sezione insieme che portano anche qualche altro argomenti buoni per coprire. Quindi, in primo luogo, come abbiamo passato per la ultime due settimane per ricordare ragazzi, ci sono un sacco di risorse disponibili per questo corso. Molti di loro saranno incredibilmente disponibile a voi come si continua a studiare per quiz 0, perché è Martedì pomeriggio. Quindi tutti voi sono stati studiare per un po '. Ci sono dispense e fonte codice che si dovrebbe sicuramente check out. Guarda i pantaloncini. Scopri study.cs50.net. E poi, di seguito elencati, un numero di altre risorse. Ancora una volta, quiz 0 è domani alle 01:00. Se non è stato già fatto, controllare il proposito di quiz 0 documento sul homepage del corso per capire dove si sta prendendo il quiz. Il quiz inizia alle 01:10 e termina 70 minuti più tardi. Quindi, se ti presenti dopo 01:10, siete andando ad ottenere che molti meno minuti oltre il 70 per prendere il quiz. Quindi assicuratevi che ci sei in tempo. Se sei uno studente di estensione o di avere alcune altre considerazioni di prova, essa potrebbe non essere a 1:00 di domani. Ma ancora una volta, controllare il proposito di quiz 0 documento per assicurarsi di sapere quando si sta prendendo il quiz. Ho scritto 75 minuti qui. Penso che sia giusto, non 70. Esso copre tutto il materiale da una settimana 0 alla conferenza della scorsa settimana il Mercoledì. E ancora, per questo quiz, a che documento, si ottiene uno su due lati e 8 1/2 da 11 fogli di carta che si ottiene da utilizzare come appunti durante il quiz. Molte persone, se non la maggior parte delle persone, hanno scoperto che il modo più utile un'unica a studiare per il quiz è di fare un foglio di studio, un uno-sider, di loro. Quindi, guardare a quelle passate, se hai visto quelle passate. Entrare in contatto con gli amici per vedere cosa stanno mettendo a loro. Ma le mani verso il basso, il modo migliore è possibile studio è quello di passare attraverso tutto e whittle giù a ciò che dovrebbe o deve non fanno parte su tale foglio di carta, perché è solo una realtà modo utile per voi per assicurarsi stai passando tutto e avere una certa familiarità con esso. La maggior parte delle persone, si trovano, anche se hanno il foglio di carta seduto proprio accanto a loro il quiz, non girare ad esso, perché, ancora una volta, che molto processo di passare attraverso le informazioni li ha aiutati a imparare. Qualcuno ha domande su quiz 0? Ha tutti - Non ho intenzione di fare per alzata di mano. Si figuri. Stavo per chiedere chi iniziato a studiare. Ma io non voglio farti non tutti di alzare le mani. Così come ho detto - sì, Avi, andare avanti. AVI: Quale sarebbe una cosa utile di mettere sul one-pager? STUDENTE: Ecco a voi. JASON HIRSCHHORN: Si ottiene per utilizzare il vostro giudizio. Cose utili da mettere in un pager, se siete confusi circa la grande O tempo di esecuzione di diversi tipi di ricerca e sorta, che mettono in là in un a portata di mano chart damerino. In questo modo, se ti viene chiesto che il quiz, non è necessario cercare di figura fuori o ragione attraverso il runtime. Si può semplicemente copiare il basso. Se si guarda al quiz passato, un sacco di volte, ci sta funzionando questioni di tempo. Quindi sarebbe un esempio di un buon cosa mettere sul vostro one-pager. Altre cose buone da mettere su, se siete confuso su come dichiarare un funzione o quanto le varie parti la dichiarazione di funzione sono, scrivere che lì, una versione generica e poi magari un esempio. Se siete confusi su puntatori, un diagramma di come puntatori lavoro Probabilmente davvero utile. Se siete confusi su ricorsione, un Campione funzione ricorsiva in là potrebbe anche rivelarsi davvero utile. Ritiene che vi darà qualche idea? AVI: è necessario comprendere la intero processo di compilazione, come come che tutte le opere? JASON HIRSCHHORN: Everything che è stato coperto potrebbe presentarsi sul quiz. Domande - ma ancora una volta, alcune cose saranno ponderati pesantemente di altri. Alcune cose sono venuti di nuovo e ancora in classe, in lezione, e la sezione. Altre cose non hanno venire spesso. Abbiamo parlato molto di # include e Qualcosa-l e ciò significa quelle in il processo di compilazione. Abbiamo parlato molto di GDB, aggrapparsi, queste diverse bandiere che usiamo quando compiliamo qualcosa, e che cosa make15, per esempio, molto mezzi e lo fa davvero. Non abbiamo parla tanto di ogni singola fase il processo di compilazione. Abbiamo ancora parlato. Quindi è ancora qualcosa che si dovrebbe essere a conoscenza. Ma ancora una volta, non stiamo andando ad essere - cose che vengono più spesso in classe sono più propensi a venire più spesso e più pesante ponderati sul quiz. Freddo. Tutte le altre domande circa quiz 0? Ok, così ho messo una lista di argomenti sulla scheda. Sono andato attraverso il programma. Sono andato attraverso la sezione recensione della la scorsa notte e quelle diapositive a venire con un elenco non esaustivo di temi che abbiamo coperto finora in CS50 e le cose che potrebbero apparire sul quiz. Quindi io non ho intenzione di passare attraverso ognuno di questi. Che avrebbe preso molto di più tempo di quello che abbiamo ora. Ma ho messo questo qui si spera di jog la memoria da cose che possono o potrebbe non essere così familiarità con voi. E mi piacerebbe trascorrere la maggior parte del sezione di rispondere alle vostre domande su Questi temi, argomenti che non sono coperti qui. Possiamo scrivere pseudo codice. Siamo in grado di scrivere il codice vero e proprio per garantire che - Posso rispondere alla tua domanda e aiuto tutti fondamentalmente capire un Molti di questi argomenti così vi sentirete preparato e comodo andare in domani quiz. Quindi, leggere sopra l'elenco. Si spera venuti alla sezione con alcune domande pure. Quando sei pronto, alzare la mano e noi cominciamo. Tenete a mente, le domande che hanno, non ci sono domande stupide. Abbiamo sentito che un sacco. E le domande che avete, io sono disposto a scommettere, molte altre persone, sia seduto qui e guardare linea avere pure. Così si può solo aiutare le persone facendo domande. Marcus. MARCUS: Tra stack e il mucchio, c'è un pre-assegnati percentuale di memoria che è definita come questo è per lo stack o per mucchio? Oppure, come funziona, esattamente? JASON HIRSCHHORN: Ottima domanda. Ho intenzione di tornare tracciare un po '. Fa tutti - si prega di essere onesti qui. So che ti sto chiedendo di alzare la mano davanti ai vostri coetanei. Ma ci sono persone che si sentono disagio con lo stack e heap e vorrei andare oltre che e che quelli significa? Alzi la mano chi - OK. Grazie. Quindi stiamo per andare oltre lo stack e l'heap molto velocemente e poi entrare nel rispondere alla tua domanda. Quindi se tracciamo una scatola di rappresentare la memoria del computer, quali sono alcuni cose che vanno in questa scatola? Principale. Una funzione principale. Dove va a finire principale? STUDENTE: [incomprensibile]. JASON HIRSCHHORN: Così faremo mettere principale qui. Cos'altro va in questa scatola? STUDENTE: Le funzioni che si chiama. JASON Hirschhorn: Le funzioni che chiamiamo. E dove vanno? STUDENTE: Nel stack. JASON HIRSCHHORN: Si andare in pila. Quindi stiamo andando a chiamare questo cosa quaggiù lo stack. E in alto, abbiamo l'heap. Così la memoria non è un contenitore, proprio come questo. Ma in realtà è piuttosto simile. Sta andando essere un sacco di scatole su e oltre, a seconda di quanto è grande il tuo computer è o quanto è grande la vostra memoria è. A quote-unquote "bottom" è la pila. E ci sono più cose che vanno in pila. E quelli dipendono dalle funzioni avete nel vostro codice. Si ha sempre una funzione nella vostra codice chiamato principale, quindi c'è sempre un sezione qui nella impilare dedicato alla principale. Queste sezioni nello stack sono chiamati stack frame. Quando si chiama un'altra funzione, diciamo principale chiama una funzione di ricerca binaria, abbiamo messo un altro frame nello stack. Più in particolare, ci accingiamo a donare un pezzo di memoria sul nostro computer per memorizzare ricerca binaria del locale variabili e di eseguire il binario codice di ricerca. Così chiamiamo la ricerca binaria. In questo pezzo di memoria, stiamo andando per memorizzare le sue variabili locali. Stiamo per archiviare i propri chiamate printf. Qualunque cosa accada, che la funzione è andando ad essere conservato proprio lì. Ricerca binaria sta per eseguire. Si sta per completare l'esecuzione. Qual è la parola in C che significa che una funzione deve completare la sua esecuzione? STUDENTE: Return. JASON HIRSCHHORN: di ritorno. Così ogni volta che vedete una dichiarazione di ritorno, le estremità funzionali quando colpisce che. Ricerca in modo binario colpirà il suo ritorno. Questa parte della memoria sarà essenzialmente essere liberato. Ed principale tornerà esecuzione. Quindi principale andrà in pausa, ovunque fosse, chiamata ricerca binaria, ottenere qualche valore di ritorno, e continuare l'esecuzione. Questo stack frame andrà via. Se chiamiamo una funzione ricorsiva, che è una funzione che si chiama over e oltre, potremmo ottenere - diciamo ha fatto ricerca binaria in modo ricorsivo. Potremmo ottenere la ricerca binaria versione uno, ricerca binaria due, ricerca binaria tre, ricerca binaria quattro, ricerca binaria cinque. E poi questa finale ricerca binaria cinque colpirà il caso base, e lo stack cornici andrà indietro e mantenere la chiusura fino a quando torniamo a principale. Siamo in grado di andare oltre la ricorsione in un po '. Ma tutto questo è da dire, se siete chiamando più funzioni contemporaneamente, ci sarà pila multipla frame nello stack. Il mucchio, d'altra parte, fino qui, non è per funzioni, non per le variabili locali. E 'per allocata dinamicamente variabili. Quindi questi sono variabili che possono essere inizializzato sia principale o un funzione che chiama principali. Ovunque nel codice, che può essere inizializzato. E per inizializzare un dinamico variabile assegnata. Quale funzione in C usiamo? STUDENTE: Malloc. JASON HIRSCHHORN: Malloc. Si chiama malloc. Si ottiene uno spazio di memoria. E che lo spazio di memoria è sul mucchio. E quello spazio di memoria rimane lì finché non si chiama libero. Così variabili allocate dinamicamente in esisterà heap per tutto il tempo che vogliono loro di esistere, e non lo faranno andare via fino a quando non esplicitamente dire loro di andare via. È possibile creare in una funzione. Stack di tale funzione telaio andrà via. Ma la variabile esisterà ancora nel mucchio finché non viene liberato, potenzialmente dalla funzione che ha chiamato ricerca binaria o qualsiasi altra cosa. Quindi queste variabili heap rimanere lì per tutto il tempo che vuoi loro di rimanere lì. E ottengono messo qui. E poi quella successiva viene messo lì. Tengono sempre compilato, e rimanere lì fino a quando si chiama libero. E in sostanza, l'heap e stack, arrivare alla domanda di Marcus, crescere verso l'altro. E se corrono l'uno nell'altro, hai utilizzata tutta la memoria nel vostro computer e il programma si chiuderà perché non si dispone di più memoria lasciato da usare. Tra questi, ci sono potenzialmente altre cose. Ma per lo scopo di questo corso, non c'è bisogno di preoccuparsi di questo. Quindi era la risposta alla tua domanda. Non si preoccupi. Ma quella era la risposta lunga. Tutto quello che devi sapere è la heap e lo stack sarà - si inizia nella parte inferiore. Lo stack fa. L'heap è lassù. Essi avvicinarsi l'uno all'altro. E se toccano, questo è un problema. A corto di memoria. Ma anche, oltre a sapere dove essi sono, ciò che è memorizzato sia nella impilare e heap. Curtis. CURTIS: Quando si scontrano, è che un overflow dello stack? JASON HIRSCHHORN: Quando si scontrano, che non è un overflow dello stack. Un overflow dello stack è una zona diversa che possiamo andare oltre se si vuole. OK, torneremo a quello un po '. STUDENTE: Qual è la parola chiamata quando colpiscono l'altro, la impilare e il mucchio? JASON HIRSCHHORN: Per ora, non ti preoccupare. Basta sapere - Risponderò a questa domanda dopo le lezioni. Se si incontrano a vicenda, è stato eseguito fuori della memoria, perché non c'è più spazio c'è. STUDENTE: Mi dispiace, che cosa è un errore seg? JASON HIRSCHHORN: un segmento guasto può essere chiamato per - dipende perché chiamato il guasto seg. A volte, il vostro stack overflow, sarà dire seg guasto come l'errore. STUDENTE: Che dire dereferenziando una variabile nullo? È che un guasto seg? JASON HIRSCHHORN: Dereferenziare un puntatore nullo - OK, quindi se avete un puntatore che si impostare uguale a null, puntatori, richiamo, indirizzi di memoria negozio come i loro valori. E un puntatore nullo è essenzialmente memorizzare 0, 0-esimo affrontare in quella variabile. Così 0x, 0, 0, 0, 0, et cetera. Che 0-esimo indirizzo in memoria che non è a nostra immagine, che è lassù da qualche parte, che è riservato per il computer. Noi non ci è permesso di toccarlo. Così, quando il programma è in esecuzione, se qualcosa sta cercando di andare a memoria indirizzo 0, sa che cioè un valore vuoto. Si sa nulla dovrebbe essere lì. Quindi, se si cerca di usare qualcosa lì e trattare qualcosa come lì o cercando di andare a quella posizione, sei andando ad ottenere un guasto SEG o un errore. Questo risponde alla tua domanda? E adesso ci torneremo di overflow dello stack. Le cose nello stack, come voi ragazzi hanno visto prima, in - cerchiamo di disegnare una stretta up di uno stack frame. Chiunque può vedere che? Quindi abbiamo il nostro stack frame. Stiamo risparmiando un array in un locale variabile in funzione. Quindi dire che la nostra matrice ha cinque punti. Tutti e cinque di questi verranno memorizzati in tale stack frame. Se cominciamo a scrivere al di là del limiti di questa matrice - quindi se cominciamo a scrivere in, diciamo che è 0. Questi sono i cinque indici della nostra matrice. Se cominciamo a scrivere in indice 5, che non abbiamo quando abbiamo un array di dimensione 5, cominciamo a scrivere in indice 6, 7, 8, 9, possiamo ottenere un Stack Errore di overflow. Generalmente non è - probabilmente otterrete nei guai se si va oltre uno. Ma in generale, si otterrà in maggior parte dei problemi se si va oltre da un sacco e si va così lontano sopra che si scrive sopra l'indirizzo di ritorno di quel funzione, che si trova nella inferiore dello stack frame. Perché, giusto? È - in - sorry. Not "perché giusto". Nel stack frame, avete le variabili locali. Nella parte inferiore della pila frame è l'indirizzo di ritorno. Ecco dove la funzione va quando è finita. E se si sovrascrive quel ritorno indirizzo, poi quando questo stack frame, quando si sta andando attraverso lo stack inquadrare e l'esecuzione di ogni linea, sei per andare al tuo nuovo indirizzo di ritorno che è scritto lì, invece del quello attuale. Ed è così che abbiamo visto alcune violazioni della sicurezza può accadere con i computer. Di overflow dello stack Quindi, in breve, è quando si sovrascrive la parte dello stack si suppone di utilizzare il locale variabile che si suppone di utilizzare, e in particolare quando si avvia la sovrascrittura cose importanti come l' indirizzo di ritorno. Ed è qui che si otterrà un errore. O magari si potrebbe iniziare anche la scrittura in - dicono ricerca binaria era proprio sopra principale. Se si sovrascritto molto, sapevano scrivere in principale. Ma in generale, si ottiene un errore prima poi, perché il computer sa si sta facendo qualcosa che si non dovrebbe fare. Già. STUDENTE: Qual è la differenza tra un overflow dello stack e un buffer overflow? JASON HIRSCHHORN: Buffer overflow è un tipo più generico di quello che ho appena descritto. STUDENTE: Quindi un overflow dello stack è un esempio di un buffer overflow. JASON HIRSCHHORN: Esattamente. Si tratta di un array possiamo pensare come un tampone, uno spazio per le cose vadano dentro Questo è un buffer overflow dello stack. Potremmo avere un overflow del buffer di heap. Se ci fosse un buffer, che spesso ci è un array heap, e noi sovrascritto questi limiti, allora avremmo avere un overflow del buffer di heap. E oltre lo scopo di questo corso, stanno rilevato un po 'diverso. Il compilatore è speciale modi di individuare ciascuno. Ma un buffer overflow è un più generico tipo di quello che ho descritto, che era un buffer overflow dello stack. Forse che risponde alla tua domanda? Dolce. C'erano altre domande correlate allo stack o heap? Già. STUDENTE: So che hai in stringhe gratis perché sono nel mucchio e non si vuole perdere la memoria. Ma bisogna liberare le variabili globali e cose del genere? O sono liberati automaticamente? JASON HIRSCHHORN: Bella domanda. Quindi, in CS50.H, creiamo questa cosa per voi chiamato una stringa. Una stringa è davvero quello? STUDENTE: Char stella. JASON HIRSCHHORN: Una stella char, un puntatore ad un carattere, un puntatore un array di caratteri. Questo è ciò che la stringa è. Quindi abbiamo bisogno di liberare, perché GetString, che abbiamo utilizzato un sacco - string name uguale GetString - che mallocs per noi qualche ricordo sul heap e poi ritorna un puntatore al primo carattere che stringa, una stella char. Quindi, apparentemente, se non siete stati la scrittura libera su una qualsiasi delle corde che hai chiamato finora, avete stato che perde un po 'di memoria. Naturalmente non abbiamo parlato di , quindi nessuno ha ottenuto in guai per farlo. Ma andando avanti, sì. Quando si chiama getstring, sei mallocing po 'di spazio sul mucchio. E se non si chiama gratuitamente in seguito che stringa, si ha una perdita di memoria. Questo risponde alla tua domanda? Sì STUDENTE: Quindi, per fare questo, usiamo destra libera prima di ritorno? Come, nel campo di applicazione, credo che se diciamo, come, int principale, all'interno della campo di applicazione del codice che è tra quelle parentesi graffe, subito prima - sai dove ti piacerebbe di solito mettere ritorno. Ti metti libero prima? JASON HIRSCHHORN: Così si può mettere libero dove vuoi mettere gratuitamente. Perché questi sono allocati dinamicamente variabili, perché possono vivere oltre l'ambito di una particolare funzione, se si chiama malloc in un funzione separata, per esempio, GetString, è possibile chiamare gratuitamente in main. Non è necessario chiamare nella funzione specifica dove malloc è chiamato. Ma si ha bisogno di chiamare prima del ritorno principali. E in realtà dipende. Dipende dal motivo per cui si malloced che spazio in primo luogo. Alcune persone chiameranno liberare abbastanza rapidamente. Alcune persone non chiameranno libero fino Alla fine del loro programma. E faranno passare attraverso e libera tutto. Dipende dal motivo per cui si chiama malloc. STUDENTE: E cosa diresti se si chiama uso GetString? Si direbbe libero che cosa? JASON HIRSCHHORN: Quindi la sintassi gratuitamente è semplicemente libero, parentesi aperte, chiudere parentesi, e il nome del puntatore. Quindi, se si scrivere il nome uguale a corda GetString, metti il ​​nome qui. Questo è il nome del puntatore. E si sa per liberare quella memoria. STUDENTE: Quindi, quando si libera quella memoria, il puntatore punta ancora a quel posto nella memoria? O è il puntatore anche svuotato di l'indirizzo a cui punta. JASON HIRSCHHORN: Dovremmo provare che. Dovremmo codice che. Torniamo quando arriviamo al codifica, e facciamo il codice che. E se si vuole capire la risposta a ciò, si può anche codice che nel frattempo. Ma questa è una grande domanda. STUDENTE: E 'possibile qualcosa di gratuito troppo presto? Quindi, hai ancora bisogno per il vostro programma, e liberato quello spazio di memoria? JASON HIRSCHHORN: sì. E 'possibile, se si libera qualcosa e poi lo si utilizza ancora una volta, si vuole incorrere in un errore. Ma questo è su di te, perché hai liberato qualcosa e poi ha chiamato più tardi. Così che è stato l'errore di un programmatore. Ma sì. Si potrebbe scrivere che. Altre domande su - Sì. STUDENTE: Quindi, se si suppone di appena liberarlo in generale prima programma termina, vuol dire che se l' programma termina e non liberarla, che la memoria è ancora allocata? JASON HIRSCHHORN: Se il programma termina e si dimentica di liberare qualcosa, poi che la memoria è stata allocata in tutta la durata del programma. Quando il programma si chiude completamente, che la memoria non sta andando rimanere lì per sempre. Il computer è abbastanza intelligente da sapere che quando il programma si chiude, dovrebbe sbarazzarsi di tutta la memoria che è stato associato con quel programma. Tuttavia, ci sono strumenti che è possibile eseguire su un programma di rilevare se, quando la programma finito, ti sei dimenticato per liberare la memoria. E per il tuo prossimo problema posto dove userete malloc e l'utilizzo di puntatori, si sarà in esecuzione questo programmare sul vostro programma per vedere se, quando ritorna principali, hai avuto qualche cose che sono stati lasciati unfreed. Quindi non stanno andando per rimanere malloced per sempre nel vostro computer. Sarebbe uno spreco, perché molto rapidamente, computer avrebbe esaurito la memoria. Ma se corrono fino alla fine del programmare e non sono liberati e la vostra programma esce, questo è ancora un problema che questo strumento vi aiuterà a risolvere. STUDENTE: È che Valgrind? JASON HIRSCHHORN: E ' chiamato Valgrind. E sarete - STUDENTE: Ma noi non dobbiamo sapere che per il quiz, però? Voglio dire, si è parlato un po 'di lezione. JASON HIRSCHHORN: Così Valgrind è il nome di questo strumento. Conoscere ciò che fa è sufficiente per il quiz. Ma non avete ancora utilizzato su problema impostare perché non abbiamo avuto una problema di set che ha esplicitamente affrontato con malloc o usando malloc. Così non è stato ancora utilizzato Valgrind. Ma si intende utilizzare prima piuttosto che dopo. STUDENTE: Puoi ripetere cosa Valgrind è? JASON HIRSCHHORN: Sorry? STUDENTE: Si può ripetere quanto lo scopo del Valgring è? JASON HIRSCHHORN: Valgrind è il nome - come GDB aiuta il test del programma, Valgrind aiuta a capire se le cose non sono stati liberati quando il programma si chiude. Quindi dovrete eseguirlo sul vostro programma. E il programma esce e si dirà il vostro programma chiamato malloc questo molti volte per questo molti byte, e si solo chiamati libero molte volte. E così te ne sei andato da tanti byte senza essere liberato. Oppure dirà che hai liberato tutto. Buon lavoro. STUDENTE: OK. E si chiama Valgring? JASON HIRSCHHORN: V-A-L-G-R-I-N-D. STUDENTE: Una domanda su puntatori. Quindi dici che hai n stella x è uguale a qualcosa. Che equivale, qualunque cosa si sta mettendo c'è, è che ciò che è stato messo dentro cosa x sta indicando a, o il puntatore di x? JASON HIRSCHHORN: si può ripetere la domanda? Possiamo disegnare mentre lo dici? STUDENTE: Nel quiz, in realtà, l' uno che ci ha inviato, era come, char verità stella uguale rocce CS50, giusto? Quindi vuol dire che tale rocce CS50 è ciò che la verità sta puntando? JASON HIRSCHHORN: Quindi stai parlando su una stella in una stringa, come che funziona? Già. OK. Cerchiamo di disegnare questo qui. [CONVERSAZIONE SIDE] JASON HIRSCHHORN: Quindi questa variabile sta per essere di tipo char stella. Quanto è grande una variabile di tipo char stella? Quanti byte? STUDENTI: Quattro. JASON HIRSCHHORN: E 'di quattro byte. Quante diritti è una variabile di tipo int stella? STUDENTI: Quattro. JASON HIRSCHHORN: quattro byte. Se è un puntatore, allora è sempre quattro byte, perchè puntatori, la loro valore è un indirizzo di memoria. E gli indirizzi di memoria sul CS50 apparecchio sono lunghe quattro byte. Così, quando chiamiamo getstring, o quando per esempio, Stringname uguale, e poi in virgolette mettere una stringa, stiamo mettendo - beh, questo è un po 'diverso. Faremo GetString come esempio. O char stella qualcosa uguale alla stringa. Spiacenti, mi dia l'esempio che hai letto? STUDENTE: char stella verità è uguale "rocce CS50" tra virgolette. JASON HIRSCHHORN: Quindi questa stella, questo chiameremo questa variabile x per il nostro scopi generici. Abbiamo creato una variabile chiamata x. E 'di tipo char stelle. Si tratta di un puntatore a una serie di caratteri. Quindi qui - Quindi questo è come questo sarebbe lavorare in memoria. Ciò memorizzare un indirizzo di memoria. Sarebbe memorizzare l'indirizzo di memoria il primo carattere nella matrice. E poi quando hai seguito il puntatore, si farebbe ottenere il primo carattere. E se stai leggendo questa cosa come una stringa, il computer è intelligente basta conoscere, di leggere tutta questa cosa fino a quando si arriva a una reazione 0. Ma se stai leggendo un carattere un tempo, in modo che stai scorrendo questa stringa, allora si avrà semplicemente leggere un carattere alla volta fino ad arrivare a backslash 0. Che potrebbe non rispondere alla tua domanda, però. STUDENTE: Sì, ma tu non hai malloced che lo spazio ma per tale puntatore. JASON HIRSCHHORN: Quindi io non sono molto sicuro esattamente quello che stai guardando, perché non ho fatto che quiz. Questo doveva essere un utile risorse da un altro TF. Se si sta creando una stringa sul impilare o come variabile locale, sarà essere solo array di tasse piuttosto che generalmente una stella char che punta a un'altra stringa. Ma io non lo so. Questo potrebbe essere un puntatore ad un'altra stringa in pila pure. Già. STUDENTE: So che avete bisogno di allocare la memoria se il puntatore è sempre dichiarata all'interno di un'altra funzione. Avete bisogno di fare la stessa cosa se si tratta di essere dichiarata all'interno del principale, si sta utilizzando dentro di principale? JASON HIRSCHHORN: Quindi sì. È possibile dichiarare un puntatore a qualsiasi indirizzo di memoria nella memoria. Può essere l'indirizzo di memoria di un locale variabile, anche se spesso, persone che non dichiarano indirizzi di memoria alle variabili locali perché vanno via una volta che la funzione restituisce, che è per questo che generalmente malloc cose. Ma sì, si può dichiarare un puntatore a un'altra variabile locale. E 'solo genere non fatto. Ma posso dare un'occhiata a che cosa specifica dopo le lezioni. Già. STUDENTE: Penso che questo è una sorta di ciò che è stato chiesto. Sembra strano essere inizializzazione un puntatore non come indirizzo, ma come quello sembra un valore. Sembra che il CS50 è quello che c'è dentro la cosa si punta e non l'indirizzo effettivo, giusto? JASON HIRSCHHORN: Così che è non è il caso, però. Questo non è ciò che sta accadendo. Quando si dichiara una stella char, si tratta di un indirizzo di memoria. I puntatori sono tutti gli indirizzi di memoria che punta a qualcosa d'altro. Quel qualcos'altro potrebbe essere sulla pila, ma quasi sempre è sul heap nel modo in cui lo vedremo usato. Ma Stringname uguale virgolette "GetString," possiamo vedere che e noi può guardare attraverso quel codice e quello. stringa getString non viene salvato in quella variabile, o qualsiasi altra cosa la stringa nome non viene salvato in quel variabile, non perché è così che puntatori funzionano. Ritiene che senso? STUDENTE: Già. JASON HIRSCHHORN: OK. Speriamo, che non era confuso per chiunque. Ma se fosse, possiamo guardare di nuovo in un po ', perché stiamo effettivamente andando per codificare qualcosa che si spera lavora con stringhe e aiutare a sentirsi più a suo agio con loro. Tutte le altre domande relative a questi argomenti o altri argomenti che Metterò il backup? E - proprio ora. Sì, Alden. ALDEN: Quindi questo è completamente indipendenti, ma possiamo solo andare oltre molto velocemente quello che dobbiamo sapere la differenza tra un 32 e Computer a 64 bit? JASON HIRSCHHORN: sì. Così a 32 bit è il numero di byte? ALDEN: E 'di quattro byte. JASON HIRSCHHORN: E 'di quattro byte. E 64 bit è il numero di byte? STUDENTE: Eight. JASON HIRSCHHORN: otto byte. Quindi, di nuovo, otto bit è un byte. Il vostro apparecchio CS50 è una macchina a 32-bit. Così indirizzi di memoria sono quattro byte lunghi. Esistono 2 al 32 indirizzi di memoria. 0 e 2 alla 32 meno 1. E io non sono positive, ma questo è probabilmente la portata di ciò che è necessario conoscere per una macchina a 32 bit, che la memoria indirizzi sono, di nuovo, lungo quattro byte, e questo è l'importo massimo di indirizzi di memoria. Inoltre, i tipi di dati - questo potrebbe essere qualcosa come bene che è degno di nota. La dimensione di un tipo di dati dipende la macchina si sta lavorando. Quindi un char, un singolo carattere, è come molti byte sul nostro apparecchio CS50? Un byte. Ed è davvero un byte come bene su una macchina a 64-bit. E la maggior parte dei tipi di dati sono lo stesso numero di byte su entrambe le macchine. Ma alcuni tipi di dati sarà diverso su entrambe le macchine. Così che sarebbe potenzialmente la unica cosa che dovete sapere. Ma anche questo, credo, è oltre i limiti - Sono quasi positivo, se si guarda indietro a vecchi quiz, si dice, assumere per problemi di codifica si sta utilizzando una macchina a 32-bit. Ma ci sono, per andare insieme a quella in caso siate interessati, vi sono tipi di dati che sono uguali dimensioni su tutte le macchine. Se hai visto qualcosa di simile uint32_t, si può o può non hanno visto quello. Questo è un tipo di dati. Che sta dicendo, sia a 32 bit non importa quale macchina è acceso. Così, quando le persone stanno scrivendo portatile codice, probabilmente non useranno int. Faranno invece utilizzano questi altri dati tipi che sanno sarà lo stesso dimensioni su ogni singola macchina. Madhu. MADHU: Ho avuto una domanda su il processo di compilazione. Quindi, se si sta scrivendo un programma che utilizza una libreria come CS50 o qualcosa del genere così, so che quella biblioteca deve, ad un certo punto, essere compilato e linkato dentro Ma quanto di ciò che accade durante l' la compilazione del vostro programma? Quale parte di quel processo biblioteca si verifica quando si è compilare il vostro programma? JASON HIRSCHHORN: Quindi cerchiamo di andare oltre generalmente le fasi di questo processo. Si scrive il file. C. Nel vostro file. C, è # includere il biblioteche di intestazione, ad esempio, cs50.h. Che cosa significa che sharp includono linea fare per il vostro programma? Akchar. AKCHAR: Aggiunge i prototipi di le funzioni dall'intestazione file nelle librerie. JASON HIRSCHHORN: Esattamente. Aggiunge quei prototipi di funzione al codice. Così, quando il codice viene compilato in fasi iniziali, il compilatore sa che esistono realmente queste funzioni, e che da qualche parte sono stati definiti. I. H file non comprendono il definizioni per queste funzioni o come lavorano. Cs50.h include solo qualcosa che dice getstring è una cosa reale che può accadere. E standardio.h dice printf è una cosa reale che può accadere. Così il vostro linguaggio C con questo. Intestazione file viene trasformato in qualche codice leggibile dalla macchina, che alla fine viene trasformato in binario codice, 0 e 1 di. E questo è il codice che alla fine viene eseguito. Il-l linea CS50 - per esempio, quando si scrive Clang - e poi si include l-CS50, si digita che dentro E si vede che. Quando si scrive fare, ti vedere che line up qui. E vedremo che in un secondo momento codifichiamo o più tardi, quando abbiamo il codice. Ma quel-l linea CS50 fa qualcosa un po 'diverso le # include cs50.h. Cosa fa la linea che-l CS50 fare? Avi? AVI: voglio dire che si collega la biblioteca alla funzione chiamare, come i file o.. JASON HIRSCHHORN: Quindi molto vicino, se non è spot-on. Il-l CS50 prende il file binario e si fonde con il vostro file binario. Quindi cs50.h, non c'è nessun punto a trasformare cs50.h dal linguaggio C in binario ogni singolo tempo è in uso. Sarebbe sciocco, perché sarebbe sprecare un sacco di tempo. Così è già stato compilato e trasformato in un file eseguibile. E ora sta per essere fusa con il file alla fine. Quindi questi 1 e 0 sono in corso a fondersi con i vostri e 0 di alla fine. Così ora ci troveremo avere l'attuale 1 e 0 che definiscono come GetString, per esempio, le opere, o come printf, per esempio, funziona. E per ulteriori informazioni, c'è un compilatori corti che Nate dà quella si dovrebbe verificare che va attraverso questi passaggi. Ma - Sì. STUDENTE: Sono sempre in file o. quando sono in forma biblioteca, pronti per essere uniti, legati - come sono nel codice binario? JASON HIRSCHHORN: OK. Che - STUDENTE: È sempre il caso per le librerie quando si collegano loro? JASON HIRSCHHORN: sì. Quindi c'è. S file, che saranno codice macchina, che sarà anche criptico per voi. Non c'è bisogno di preoccuparsi di quelli. Ma in generale, sì, faranno essere in formato. o file pronto ad andare. STUDENTE: Quindi, quando spedite una biblioteca, Spedite solo l'. he la. o? Non spedire l'. C o. S. JASON HIRSCHHORN: So - e questo è in questo breve e, se queste informazioni sembra essere venuta un poco rapidamente. Ma il corto di compilatori parla di questo. Quando si invia una biblioteca, se spedite l'. h, il file di intestazione, quelli prototipi di funzione, e l'1 e 0 di, questo è tutto ciò che serve a dare. Non è necessario dare come l' funzione è attiva, il file c.. Perché il punto di astrazione, o l' punto API, il punto in questo SPL, biblioteca portatile Stanford, è per non preoccuparsi di come nuovo GRect funziona, o come muoversi lavori, o come aggiungere funziona. Tutto quello che dovete sapere è che in lista è una funzione che si può uso, e lo fa. Quindi davvero non hanno bisogno di sapere come è scritto in C. Hai solo bisogno di so, qui sono le funzioni, ciò che fanno, e qui sono i di 1 e 0 quando si vuole veramente usarli. Freddo. Altre domande sui compilatori o altri argomenti sulla scheda? STUDENTE: Ho una domanda di attuazione di funzioni ricorsive. Una domanda sulla ricorsione. Ho avuto la sensazione che sarebbe venuto. Quindi andiamo rapidamente attraverso ricorsione con una specifica esempio, una funzione fattoriale. Poiché questo è un esempio che spesso esce o viene utilizzato per illustrare la ricorsione. Così "4!" viene letto come 4 fattoriale. E che cosa fa 4 fattoriale significa? Che cosa fare? Come si calcola 4 fattoriale? 4 volte 3 volte 2 volte 1. Così un altro modo di scrivere 4 fattoriale è quello di scrivere questo. 4 volte 3 fattoriale. Perché 3 fattoriale è 3 volte 2 volte 1. SO 4 volte 3 fattoriale è 4 volte 3 volte 2 volte 1. Questo è il motivo fattoriale è un grande candidato per ricorsione, perché è chiaro che c'è qualcosa che accade più e più e più volte su una minor numero di cose fino a si raggiunge la fine. Quando si raggiunge 1, 1 fattoriale è 1. Non si può fare molto di più. 0 fattoriale è anche definito come 1. Così, quando si arriva a 1 o 0, sei alla fine, e si può inizia risalendo. Quindi, se volessimo scrivere un ricorsiva funzione per calcolare un fattoriale, stiamo andando a scrivere qualche pseudocodice per ora. Prima di scrivere che pseudocode - Darò voi ragazzi un paio di minuti scrivere il codice pseudo o semplicemente pensare a questo proposito - ci sono due cose che ogni funzione ricorsiva ha bisogno. Quali sono queste due cose? JACK: Deve chiamare se stesso. JASON HIRSCHHORN: Noah? Oh, Jack. Vai avanti. JACK: Deve chiamare se stesso. JASON HIRSCHHORN: Quindi un ricorsiva funzione ha bisogno di una chiamata ricorsiva, un chiamare a sé. Questo è uno. E qual è l'altra cosa? JACK: Un caso base. JASON HIRSCHHORN: Un caso base. Un caso base è, ecco quando ci fermiamo. Quindi, la funzione viene chiamata. Il caso base viene prima. Volete sapere se siete alla fine. E se non sei alla fine, si effettuare la chiamata ricorsiva. E si passa attraverso questa funzione di nuovo, controllare nuovamente il caso base. Se non sei alla fine, si fanno un'altra chiamata ricorsiva, et cetera, et cetera. Ecco perché funzioni ricorsive sempre bisogno di quei casi di base e quelli chiamate ricorsive. Se non si dispone di una chiamata ricorsiva, si non sarebbe una funzione ricorsiva. Se non si dispone di un caso base, si dovrebbe andare per sempre e non ci sarebbe fine. E il caso di base viene sempre prima, perché si vuole sempre controllare se siete alla fine prima. Quindi, prima di fare qualche pseudocodice, perché Non si prende un minuto per pensare come una funzione ricorsiva fattoriale sarebbe scritto? Inoltre, come molti come si sta facendo, la scrittura fuori su un foglio di carta è quello che si sta andando ad avere per fare il quiz domani. Quindi probabilmente buone pratiche per rendere che il codice che si sta scrivendo giù sul foglio di carta - o si può fare. Sai dove i punti e virgola sono. Ti ricordi la sintassi. Perché tu non sei in grado di avere una compilatore dire che hai fatto un errore. Inoltre, in tal senso, domani, quando avete problemi di codifica, se si si precipitò per tempo, o se siete molto confuso su come si suppone di scrivere la cosa particolare in C, sarebbe doveroso scrivere pseudo-codice o scrivere commenti in pure. Perché non c'è credito parziale per un Molte delle domande sul quiz. Così si potrebbe essere affrettata, o si potrebbe anche essere confuso. Scrivendo commenti o pseudo-code sono spesso modi che si può ottenere credito parziale. Quindi non lasciare qualcosa vuoto sul quiz. Non ci sono sanzioni per mettere le cose dentro Infatti, mettendo in pseudo-codice o Commenti sta per aiutare il selezionatore capire se si sa cosa stai parlando, e forse di aggiudicazione avete qualche credito parziale per questo. Anche in questo senso, scrivere chiaramente. Se non possiamo davvero quello che si sta scrivendo, non stiamo andando a chiamarti a mezzanotte di domani la figura su quello che hai scritto. Stiamo solo andando a togliere punti. Scrivi in ​​modo chiaro in modo che possiamo sentire, o meglio, possiamo leggere quello che hai scritto. E se dice due frasi, non scrivere un paragrafo. Seguire le istruzioni. Scrivere in modo chiaro. E scrivere in quei commenti o pseudocodice per le domande che potrebbero riconoscimento del credito parziale. OK, andiamo a fattoriale. Quindi abbiamo una funzione fattoriale. Se dovessi scrivere in realtà questo in C, che cosa ho bisogno di mettere prima del nome della funzione? Il tipo di ritorno, che, in questo caso, ci diamo int. E poi all'interno delle parentesi graffe, è ciò che accade dentro le parentesi graffe per una funzione? STUDENTI: Tipo di argomento. JASON HIRSCHHORN: I suoi argomenti. Così fattoriale probabilmente prendere un argomento. Sarà probabilmente solo prendere un argomento. E diremo che ti prende un intero chiamato x. E ancora, quando si scrive il prototipo di una funzione o scrivere la funzione nel codice prima della definizione, è scrivere il tipo di dati e il nome del tale variabile solo quella funzione. Così si può passare qualche numero in questo funzione, che sarà indicato come x internamente. Noi abbiamo la nostra funzione fattoriale. Abbiamo bisogno di due cose, un caso base e una chiamata ricorsiva. Qual è lo scenario di base per il fattoriale? Qualcuno che ha scritto fuori e che non ha ancora parlato, quello che è la base caso per fattoriale? STUDENTE: Se n è meno di 2, ritorno 1. JASON HIRSCHHORN: Se n è meno di 2, ritorno 1. Mi piace, perché si prende cura di 0 e 1. Così faremo x <2, ritorniamo 1. Se ci passammo 0, se otteniamo superato 1, questa funzione restituire immediatamente 1. Se ci passammo qualche numero maggiore o uguale a 2, stiamo andando a avere la nostra chiamata ricorsiva. E così come è quella di andare a lavorare? Può qualcun altro che ha lavorato su questo che non ha ancora parlato mi danno la chiamata ricorsiva per questa funzione in pseudocodice? Se veniamo passati in un numero x ed è maggiore di 2, ciò cosa vogliamo fare? Abbiamo anche un esempio scritto sul laterale che potrebbe dare un suggerimento. STUDENTE: Chiamare x volte l' fattoriale di x meno 1? JASON HIRSCHHORN: Esattamente. Stiamo per tornare x volte il fattoriale di x meno 1. E che, anche se ho scritto, in sostanza, quello che hai detto in inglese, questa funzione fattoriale andranno chiamato di nuovo. Sarà eseguito in x meno 1. Sarà di ritorno con qualche intero, e allora sarà moltiplicare questi due insieme, e questo valore sarà tornato a qualsiasi chiamata questa funzione fattoriale, che potrebbe essere un'altra istanza di questa funzione fattoriale. Così che è un esempio di un ricorsiva funzione, molto semplice funzione ricorsiva. Ma la maggior parte di loro sarà come questo. Se volete un buon ricorsiva sfida per il quiz, provate codifica ricerca binaria in modo ricorsivo. Perché se avete fatto la ricerca binaria per problema impostare tre, probabilmente fatto iterativamente in un ciclo while. Ma può anche essere scritta ricorsivamente. Stai andando ad avere bisogno di scrivere il proprio funzione separata che richiede un po ' diversi argomenti della riga di comando - o non gli argomenti della riga di comando, alcuni diversi argomenti appena regolari. Ma si potrebbe scrivere binario di ricerca ricorsivamente pure. STUDENTE: Così si potrebbe avere anche scritto, invece di x meno 1, è avrebbe potuto anche scritto x meno meno, o si potrebbe avere scritto meno meno x. Si può solo spiegare molto velocemente perché quelli sarebbero cose diverse, come quello che è la differenza tra x meno meno e meno meno x? JASON HIRSCHHORN: No, io non sono per andare in quella. Ma voglio parlarti dopo classe. x meno meno, meno meno x diminuire x di 1. Ma lo fanno un po 'diverso. Ma io non voglio andare in quella. Altre domande sulla ricorsione o questa funzione? Che non è davvero anche pseudocodice. Questo è fondamentalmente il codice C si può scrivere per questo. OK, tutte le altre domande su argomenti qui? Già. STUDENTE: Ho un breve riassunto di virgola mobile e precisione. JASON HIRSCHHORN: Floating punto e precisione. Può qualcuno veramente in fretta dammi una carrellata di in virgola mobile e precisione? È tutto dovuto fare questo per la vostra problema set, quindi siete tutti familiarità con esso. O forse non tutti voi. Chiunque? Datemi un punto iniziato. Virgola mobile e precisione. Qual è il problema? Sì. Victoria? VANESSA: Vanessa. JASON HIRSCHHORN: Vanessa. Scusi. VANESSA: C'è solo un numero finito di numeri che possono essere rappresentati perché sei su una, nel nostro caso, un sistema a 32 bit. Così è sorta di necessario fare un po 'di numeri. JASON HIRSCHHORN: Così che è esattamente a destra. Ci sono solo una certa quantità di numeri che possono essere rappresentati. Se si moltiplica due numeri molto grandi, potrebbe straripare l'importo di spazi dovete rappresentare un numero intero. Ecco perché a volte usiamo un lunga lunga invece di un int. Che ha più spazi. Che può contenere un numero maggiore. Precisione in virgola mobile ha a che fare con che, ma ha anche a che fare con la fatto che i numeri decimali sono Non sempre rappresentato. Scusi. Mettiamola questo back up. Il numero decimale 1.0 non è sempre rappresentata come ci si aspetterebbe, 1,000 milioni. A volte è rappresentato come 1,000000001 o 0,999999999. Si potrebbe addirittura 89 generata da qualche parte. Quindi quei numeri decimali non sono rappresentata esattamente come si farebbe aspettano di essere rappresentate. Così nel problema set - era due? - problema impostare due, dove abbiamo affrontato con numeri in virgola mobile, quando volevamo loro di rappresentare esattamente quello che volevamo li per rappresentare il numero di centesimi, o il numero di centesimi, li moltiplichiamo per 100. Noi li arrotondato. E poi abbiamo tagliato tutto dietro il punto decimale. Che era di assicurare che avrebbero in realtà pari esattamente quello che volevamo loro pari. Perché quando si prende qualcosa che è un galleggiante e trasformarlo in un int, è tagliare tutto a destra del punto decimale. Perché c'è qualche virgola mobile imprecisione, 100.000 potrebbe essere rappresentato come 99,999999999. E se appena tagliato fuori tutto destra subito, si sta andando ad ottenere il numero sbagliato. Già. STUDENTE: Ho avuto una domanda in merito al casting. Quale ordine si manifesta in? Se faresti float, staffe, 1 diviso da 10, fa fare 1 diviso per 10, quindi ottenere 0.1, quindi accendere in un galleggiante? JASON HIRSCHHORN: Se fate galleggiante 1 diviso 10 - STUDENTE: Sì, e poi uguale - Beh, sarebbe normalmente averlo uguale a - Già. Si vuole fare un galleggiante, giusto? JASON HIRSCHHORN: OK, quindi stiamo andando a l'uso che per SEGUE nel capire le risposte a queste domande attraverso la codifica. Perché probabilmente avete un sacco di queste domande minute e un buon modo risolverli è attraverso codifica. Quindi stiamo andando a codificare questo proprio ora, e poi stiamo per tornare indietro e codificare la domanda che avevi. Quindi la prima riga - Non avrei scritto - a quanto è la prima cosa che vogliamo fare quando si aprire un nuovo file in gedit? STUDENTE: Includi. JASON HIRSCHHORN: Includi cosa? STUDENTE: biblioteca CS50. JASON HIRSCHHORN: OK. Cos'altro dovremmo includere? Stiamo solo andando a controllare cosa succede quando lanci qualcosa ad un galleggiante. Ma cosa dobbiamo includere se siamo intenzione di scrivere un programma in C? STUDENTE: Standard I / O. JASON HIRSCHHORN: stdio.h. Noi in realtà non abbiamo bisogno, per questo programma, cs50.h, anche se è sempre disponibile per includerlo. Ma abbiamo sempre bisogno stdio.h. STUDENTE: Quando si codifica in C? JASON HIRSCHHORN: Quando si codifica in C. Così si salva come questo. File c. Ottengo qualche bella evidenziazione della sintassi. Ho scritto vuoto dentro principale. Cosa significa nulla dire? STUDENTE: Non viene compiuta alcuna argomenti della riga di comando. JASON Hirschhorn: mezzo vuoto, in questo caso, principale non assume alcuna argomenti della riga di comando. In altri casi, significa che la funzione non prende argomenti della riga di comando. O la funzione, se dovessi scrivere nulla main (void), che direbbe principali del non tornare nulla. Quindi nulla solo non significa nulla. Che cosa avrei scritto se dovessi prendere gli argomenti della riga di comando? STUDENTE: int arco c corda dell'arco v JASON HIRSCHHORN: int argc stringhe argv. È giusto? STUDENTE: E 'char parentesi stella argv. JASON HIRSCHHORN: Così si potrebbe scrivere staffe stringa argv o char stelle argv parentesi, ma è necessario staffe. Perché argv è un array di stringhe, ricordare. Non è solo una stringa. Così stringa argv è, qui sta una stringa chiamato argv. Staffe String argv è, ecco un array di stringhe. Così int argc staffe stringa argv sarebbe qualcosa che io probabilmente scrittura. Così si voleva salvare in un intero? STUDENTE: Sì, integer. O in un galleggiante. JASON HIRSCHHORN: In un galleggiante? Come, float x è uguale a 1 diviso per 10. JASON HIRSCHHORN: OK. Come faccio a stampare su un galleggiante in printf? Cosa? STUDENTE:% f. JASON HIRSCHHORN:% f. Cos'è un intero? d o i. Che cos'è una stringa? STUDENTE: s. JASON HIRSCHHORN: s. Come posso ottenere una nuova linea? STUDENTE: Barra rovesciata n. JASON HIRSCHHORN: Cosa torno se corre principali correttamente? STUDENTE: 0. Devo scrivere che la linea, però? STUDENTE: No. OK, noi non scriverlo, allora. Chiunque può leggere quella? Sembra un po 'piccola. Chiunque può vedere, o dovrebbe Faccio più grande? Penso che per la fotocamera, faremo un po 'più grande, però. JASON HIRSCHHORN: Se voglio trasformare questo File. C in un file eseguibile, cosa scrivo? STUDENTE: make test. JASON HIRSCHHORN: Sorry? STUDENTE: make test. JASON HIRSCHHORN: make test. Stavamo parlando di questa linea precedente. Clang. Nei clang? Il nome del compilatore. Cos'è questa linea? STUDENTE: Imposta su per l'utilizzo di GDB. JASON Hirschhorn: Sets che per l'utilizzo di GDB. Questa linea, che cos'è? STUDENTE: codice sorgente. JASON HIRSCHHORN: Questo è il file di origine, il file c.. Che cosa significano queste due righe fanno? O queste due righe non. Studente: nomi che prova. JASON HIRSCHHORN: Così il cruscotto o dice, denominarlo qualcosa di diverso. E qui si sta chiamando test. Se non avessi che, quale sarebbe chiamare questo? STUDENTE: a.out. JASON HIRSCHHORN: a.out. Cosa fa questo? STUDENTE: Collega la libreria matematica. JASON HIRSCHHORN: Collega la libreria matematica. Non abbiamo incluso la libreria matematica, ma dato che è così comune, hanno make scritto di includere sempre la libreria matematica. E allo stesso modo, questo include la biblioteca CS50. OK, quindi se elenchiamo, ora abbiamo un eseguibile chiamato test. Per eseguirlo, scrivo test. Vedo che il mio virgola mobile, come previsto, è uguale a 0. Ritiene che - così - STUDENTE: Quindi se si mette galleggiare ora, come lanci come float - JASON HIRSCHHORN: Cast 1 a un galleggiante? STUDENTE: No, scagli la cosa completa - sì. Se hai appena fatto questo, sarebbe che la rendono 0.1? JASON HIRSCHHORN: OK, quindi davvero in fretta, 1 diviso 10, questi sono interi scissa. Quindi, quando si divide interi, sono 0, e si sta salvando che 0 in un float, perché la barra è appena divisione intera. Così ora stiamo girando qualcosa in un galleggiante. Vediamo cosa succede. Faremo test. Così ora vediamo che tale barra non era divisione intera, che galleggiava punto di divisione. Perché uno dei suoi argomenti era stato gettato da un galleggiante. Così ora si diceva, trattare questa divisione come abbiamo a che fare con punti galleggianti, non con numeri interi. E così si ottiene la risposta che ci aspettiamo. Vediamo cosa succede - oops. Se volessi stampare più decimale macchie, come potrei farlo? STUDENTE: Punto punto f, o come molti decimali come si desidera. JASON HIRSCHHORN: Così stampo 10 punti decimali. E ora vediamo che stiamo ottenendo alcune cose strane. E che risale alla tua domanda in merito a virgola mobile imprecisione. Ci sono cose strane memorizzati qui. OK, questo risponde alla tua domanda? Che altro volevi codificare rapidamente? STUDENTE: Volevo solo vedere se no, se liberato un po 'di puntatore, se tale puntatore ancora aveva immagazzinato in è l'indirizzo di quello che era stato indicando precedenza. JASON HIRSCHHORN: OK, quindi cerchiamo di farlo. Char ptr stelle, questo crea una variabile chiamata ptr di tipo char stella. Come faccio a scrivere malloc? Alden? ALDEN: Just malloc. Ma poi deve essere di dimensioni e in questo caso, credo che ci si essere rivolto a char. Quindi sarebbe char. JASON HIRSCHHORN: OK, quindi più genericamente, Inside - cerchiamo di modificare. All'interno malloc, vuoi il numero di byte sul mucchio. In generale, quello che abbiamo visto che siamo facendo è che andremo a malloc stringhe, per esempio, o array di interi. Quindi, se vogliamo 10 interi, o 10 caratteri, 10 ci darà 10. E poi le dimensioni dei caratteri darebbe noi che dimensioni di caratteri, in cui questo caso è 1 byte. Otteniamo 10 byte. Se dovessimo scrivere la dimensione di int che ci darebbe 40 byte. Quindi, più genericamente, all'interno di malloc è il numero di byte che si desidera. In questo caso, stiamo ottenendo 1 byte. Il che sembra un uso strano di malloc, ma per il nostro fini ha senso. Quindi c'è questo. Stiamo per chiamare gratuitamente. Ci liberiamo di essa e usiamo di nuovo ptr. E che cosa si vuole controllare? STUDENTE: Volevo solo controllare se o non c'era niente all'interno di esso. JASON HIRSCHHORN: Quindi, se essa ha a qualcosa? STUDENTE: Sì, esattamente, sia aveva ancora un indirizzo di memoria. JASON HIRSCHHORN: Quindi vuoi per controllare il valore di ptr? STUDENTE: Sì, esattamente. JASON HIRSCHHORN: cosa scrivo qui se voglio controllare il valore della punto - che cosa è, Giordania ha detto, il valore? O quello che è memorizzato all'interno di ptr? STUDENTE: un indirizzo di memoria. JASON HIRSCHHORN: un indirizzo di memoria. Quindi se scrivo solo questo, sarà dammi il valore di ptr. E come faccio a stampare su un indirizzo di memoria? Qual è la stringa di formato per un indirizzo di memoria? STUDENTE:% p. JASON HIRSCHHORN:% p. % S è una stringa. % P per puntatore. È giusto? Che è di destra. Così ptr uguale - ha ancora qualcosa in esso. Questo è probabilmente un più domanda interessante. Che cosa fa il suo effetto? STUDENTE: guasti Seg. JASON HIRSCHHORN: Cosa? STUDENTE: Penso che Seg difetti. JASON HIRSCHHORN: Hm? STUDENTE: Penso che sarà Seg colpa. JASON HIRSCHHORN: Quindi questa linea di codice, stella ptr, cosa significa la stella? STUDENTE: Contenuto. JASON HIRSCHHORN: Già. Andare per ottenere il contenuto di. Quindi questo sta per andare alla memoria affrontare lì e mi dia quello. Ho usato% c proprio qui, perché ci sono caratteri memorizzate. Quindi stiamo per andare a tale indirizzo si appena visto - o probabilmente sarà un po 'questo diverso volta corriamo il programma. Ma andiamo a questo indirizzo che, come sappiamo esiste ancora e vedere cosa c'è. Quindi non Seg colpa. Semplicemente non ci ha dato nulla. Avrebbe potuto effettivamente ci ha dato qualcosa, noi non può vederlo. E che risale a questa idea - e non stiamo andando ottenere troppo in questo, perché è al di là del scopo di questo corso. Ma abbiamo parlato qui, se noi è andato oltre i limiti della matrice da 1, potremmo non finire nei guai. A volte, quando basta andare fuori da 1, che stai facendo qualcosa di sbagliato, e si potrebbe finire nei guai. Ma non sempre nei guai. Dipende quanto di una cosa negativa si fa, si sta andando a finire nei guai. Il che non vuol dire, essere sciatto con il codice. Ma è da dire, il programma non sarà sempre uscire, anche se si va da qualche parte non dovresti andare. Un buon esempio di ciò è, un sacco di persone nella loro problema set 3, che era 15, non ha controllato l' limiti della pensione. Così si guardava a sinistra, guardato al a destra, guardò verso l'alto, sembrava al fondo. Ma non è stata selezionata per vedere se il top era in realtà sta per essere sulla scheda. E un sacco di persone che hanno fatto questo e girato che nel loro programma ha funzionato perfettamente, perché dove quel consiglio era in memoria, se sei andato un sopra o controllato che la memoria indirizzo, non c'era niente particolarmente orribile che, in modo che il programma non è stato andando a urlare a voi. Ma ci sarebbe ancora decollare punti se non è stata selezionata, perché si stavano facendo qualcosa che non eri dovuto fare, e si potrebbe avere messo nei guai. Le probabilità sono, però, probabilmente non l'hai fatto. Quindi questo è quello di mostrare che, sì, possiamo ancora andare ad esso. E non stiamo ottenendo in problemi in questo caso. Se abbiamo cercato di fare leggere il prossimi 100 caratteri, saremmo probabilmente finire nei guai. E si può codificare leggere il prossimo 100 caratteri se volete facendo qualche una sorta di ciclo for. Già. STUDENTE: Dal momento che ci è stata assegnata che spazio un valore reale, non avremmo effettivamente in grado di vedere nulla. Dovremmo provare con l'impostazione che uguale come C o qualcosa del genere? JASON HIRSCHHORN: Ottima domanda. Come faccio a impostare quel valore - Cosa riga di codice faccio a scrivere on line sette a fare quello che hai detto? STUDENTE: Stella ptr uguale singolo citazione c terminare sola offerta. JASON HIRSCHHORN: So che sta mettendo un carattere, c, in tale posizione, perché ancora una volta, quella stella significa andare a lì. E quando viene utilizzato sul lato sinistro un operatore di assegnazione, che equivale a segno, non stiamo andando a ottenere che valore tanto quanto impostato tale valore. Ora vediamo cosa succede. Abbiamo messo qualcosa lì ed era lì. Abbiamo chiamato libero. Alcune cose probabilmente è accaduto sul mucchio. Quindi non è più lì. Ma ancora una volta, non stiamo ottenendo nei guai per andare lì. Io sto facendo questo in codice per illustrare che molti di questi domande che avete, sono davvero interessante risponde un sacco di tempo. E sono davvero buone domande. E si può capire su il proprio se, per esempio, non siamo in sezione. Già. STUDENTE: Perché non stai inviando l' puntatore ovunque, avete bisogno di usare malloc? JASON HIRSCHHORN: Quindi questo va indietro alla tua domanda iniziale. [? ?] E 'solo una variabile locale? Malloc qui non è convincente. L'uso di malloc qui non è che convincente perché è solo una variabile locale. STUDENTE: Allora potresti fare char stella ptr uguale ciao? JASON HIRSCHHORN: Oh. Quindi stiamo andando ora di tornare alla tua domanda iniziale. Penso che tu non eri soddisfatto con la mia risposta. OK? Ti piace questo? STUDENTE: Già. Aspetta. JASON HIRSCHHORN: E dove vuoi stampare? Quindi dovremo stampare una stringa del genere? STUDENTE: Interessante. JASON HIRSCHHORN: Quindi questo lo dice argomento ha il tipo di carattere. Quindi, questo dovrebbe essere un carattere. STUDENTE: prende solo il primo. JASON HIRSCHHORN: Quindi questo è quello che ho detto prima. Come ho detto, non è memorizzare la stringa all'interno puntatore variabile. E 'la memorizzazione - STUDENTE: Il primo valore della stringa. JASON HIRSCHHORN: L'indirizzo del il primo valore della stringa. Se dovessimo stampare questo, siamo ottenere il valore all'interno del puntatore. E vedremo che è, in effetti, un indirizzo di memoria. Ritiene che senso? Scusi. Aspetta, questo risponde alla tua questione, però? STUDENTE: Già. JASON HIRSCHHORN: questa riga di codice è la creazione di una stringa e poi un altro puntatore variabile che sta puntando a tale stringa, tale matrice. Già. STUDENTE: Quindi, se siamo andati un ricordo affrontare ulteriormente, potremmo ottenere l'h? È stato memorizzato come una stringa? JASON HIRSCHHORN: Come, abbiamo fatto - quindi questo è prezioso per fare. Questo è il punto aritmetica, che voi ragazzi ha visto prima e dovrebbe essere relativamente a proprio agio. Questo è simile alla scrittura - se dovessimo scrivere questa riga di codice, abbiamo visto notazione di matrice prima. Questo ci dovrebbe dare la seconda valore in questo array, h. Se abbiamo fatto questo, questo dovrebbe anche dare noi il secondo valore in tale matrice. Perché non sta per la memoria indirizzo la prima cosa, ma la indirizzo di memoria della cosa uno sopra. E poi le dereferenziazioni operatore stelle tale puntatore. E ancora, vediamo. Otteniamo nuovamente h. STUDENTE: Cosa fa esattamente dereferenziare significa? JASON HIRSCHHORN: Dereference è una parola di fantasia per andare. Vai a questo e ottenere quello che c'è è quello di dereference un puntatore. E 'solo una parola di fantasia per questo. STUDENTE: Se volessimo stampa l'intera stringa, potremmo fare puntatore commerciale? JASON HIRSCHHORN: OK, siamo andando a mettere in pausa qui. Stiamo andando a finire qui. Ampersand ti dà l'indirizzo di un posizione, in modo che quando si fa commerciale di una variabile, ti dà l'indirizzo in cui è memorizzata la variabile. Puntatore Ampersand vi darà l' Indirizzo di ptr dove ptr è in memoria. Non abbiamo intenzione di andare avanti con questo esempio. Si può capire questi cose da soli. Ma ancora una volta, questo potrebbe anche essere sull'orlo di un po 'oltre quello che è necessario sapere per lo scopo di questo medio termine - o questo quiz, piuttosto. Scusi. Stiamo per andare avanti, perché vorrei piacerebbe fare un problema di codifica prima che il tempo è scaduto. E ci accingiamo a codificare ciò che penso è il più interessante di questi esempi, atoi. Quindi questa era una domanda su un quiz due anni fa. E ho sul bordo qui. La gente è stato chiesto il quiz - sono stati dati un po 'più in tesxt la domanda, ma ho eliminato l' testo perché era inutile per i nostri scopi momento. Era solo alcuni retroscena su ciò che atoi fatto. Ma tutti voi conoscete e siete molto familiarità con atoi. Vi suggerisco di codificare questo su un foglio di carta. Suggerisco anche di usare la strategia che siamo andati oltre molto nella nostra sezione. In primo luogo, assicurarsi di aver compreso cosa atoi sta facendo. Fai un disegno o trovare un qualche immagine mentale di esso nella vostra testa. Avanti, scrivere pseudocodice per questo. Sul quiz, se tutti si ottiene è pseudocodice, almeno si mettere giù qualcosa. E poi la mappa che pseudocode su C. Se si dispone di un controllo nella vostra pseudocodice, come controllare se qualcosa è 1, che le mappe su un caso condizioni e così via. E, infine, il codice del programma in C. Quindi, tornare a atoi e prendere cinque minuti codificare ciò su un foglio di carta, che è probabilmente sulla quantità di tempo che si sarebbe assumere un quiz a atoi codice. Cinque a 15 minuti, cinque a 12, cinque a 10 minuti, è del numero di il tempo che ci si spende su questo domanda del quiz. Quindi prendere cinque minuti adesso, per favore. E se avete domande, sollevare la tua mano e vengo in giro. [CONVERSAZIONI LATERALI] JASON HIRSCHHORN: OK, così che era di cinque minuti. Questo è stato probabilmente circa la quantità di volta che si era speso per che in un quiz, forse la fascia bassa di quel tempo. Ti ricapitolare un po '. Cominciamo questa codifica. E se non otteniamo tutto il percorso attraverso, le risposte a questo e questo quiz domanda sono disponibili, ancora una volta, Autunno 2011 è quando questa domanda apparso sul quiz. E ne è valsa otto punti il quiz poi. Otto punti è sulla fascia alta del quantità di punti qualcosa vale la pena. La maggior parte delle domande sono nell'intervallo da uno a sei punti. Quindi questo è un più impegnativo domanda, di sicuro. Qualcuno può farmi iniziare? In generale, che cosa stiamo andando a voler fare con questo funzione atoi, logicamente? Che cosa vogliamo fare? Quindi stiamo andando a scrivere alcuni pseudocodice. STUDENTE: Convertire caratteri in numeri interi. JASON HIRSCHHORN: Convertire caratteri in numeri interi. OK. Quindi, quanti caratteri siamo andando ad avere bisogno di passare attraverso? STUDENTE: Tutti loro. STUDENTE: Tutti i personaggi nella stringa. JASON HIRSCHHORN: Tutte le caratteri della stringa. Quindi se volevamo passare attraverso ogni carattere di una stringa, che cosa è una cosa in C abbiamo visto che ha permesso noi di andare attraverso ogni carattere di una stringa? STUDENTI: Un ciclo for. JASON HIRSCHHORN: Un ciclo for. Quindi stiamo andando a scorrere ogni personaggio in s. Allora che cosa stiamo andando a voler fare quando otteniamo un carattere specifico? Dire che siamo sempre passati a 90. Otteniamo il 9. E 'un personaggio. Che cosa vogliamo fare con quel personaggio 9? STUDENTE: Sottrarre dal carattere 0? STUDENTE: Aggiungi 0? JASON HIRSCHHORN: Sottrarre dal carattere 0? STUDENTE: Già. JASON HIRSCHHORN: Perché vuoi fare? STUDENTE: [incomprensibile] valore. Il suo valore int. JASON HIRSCHHORN: OK, quindi prendiamo il carattere 9, sottrarre da carattere 0 per ottenere un integer reale 9. Dolce. E come fai a sapere che carattere 9 minus 0 personaggio è 9? Cosa tabella hai guardato? STUDENTE: Ci sono logicamente nove posti tra 9 e 0. Oppure si potrebbe guardare la tabella ASCII. JASON HIRSCHHORN: tabella ASCII. Ma sì, siete sulla strada giusta pure. Quindi sottraiamo 0. Così ora abbiamo l'intero 9. E cosa vogliamo fare con questo? Se abbiamo 90, è il primo intero abbiamo, cosa vogliamo fare? STUDENTE: avevo messo in un intero temporaneo array, quindi fare matematica ad esso successivamente a farne una fine. JASON HIRSCHHORN: OK. STUDENTE: Si può iniziare alla fine del la matrice e poi andare avanti così che ogni volta che si sposta in avanti, si moltiplica per 10. JASON HIRSCHHORN: OK. Che suona come un bel idea convincente. Possiamo iniziare alla fine del nostro array, e possiamo usare strleng. Possiamo usare strleng qui. Avremo la lunghezza della nostra stringa. Partiamo dalla fine. E + il primo, dobbiamo solo prendere che intero, e magari creiamo come un nuova variabile intera sulla parte superiore dove stiamo memorizzare tutto. Così abbiamo ciclo attraverso ogni carattere in s da posteriore a quella anteriore, sottraiamo 0, e poi lo prendiamo e, a seconda dove si trova, lo moltiplichiamo da una potenza di 10. Perché il primo, quello che facciamo moltiplicare il carattere più a destra da? STUDENTE: 10 a 0. JASON HIRSCHHORN: 10 a 0. Cosa ci moltiplichiamo la seconda carattere più a destra da? STUDENTE: [incomprensibile]. JASON HIRSCHHORN: Cosa? STUDENTE: 10 a 1. JASON HIRSCHHORN: 10 a 1. Il carattere terza a destra? STUDENTE: 10 a 2. JASON HIRSCHHORN: 10 a 2. STUDENTE: Mi dispiace, non capisco quello che stiamo facendo qui. JASON HIRSCHHORN: OK, Torniamo, allora. Quindi stiamo andando ottenere passato in una stringa. Perché stiamo scrivendo atoi. Così otteniamo passati in una stringa. Dire che siamo sempre passati nella stringa 90. La prima cosa che andremo a fare è impostare una nuova variabile intera che siamo solo andando a creare come il nostro nuovo intero. Questo è quello che stiamo andando per tornare alla fine. Abbiamo bisogno di passare attraverso ogni carattere la stringa perché abbiamo stabilito che abbiamo bisogno di toccare ciascuno e quindi aggiungere al nostro nuovo intero. Ma non possiamo aggiungere come un numero. Non possiamo prendere 9 e aggiungere 9 al nostro numero intero. Dipende da quale posto è nella stringa. Stiamo andando ad avere bisogno di moltiplicare esso da una potenza di 10. Perché questo è il modo base di 10 opere. Quindi stiamo andando ad ottenere l'attuale carattere, o l'intero effettivo numero, sottraendo carattere 0 dal carattere 9 come abbiamo fatto con sottraendo capitali carattere A da qualunque personaggio che abbiamo avuto in una delle questi problemi. Quindi dovremo effettivamente ottenere un numero da 0 a 9 salvato come un numero reale, e ti moltiplicarlo per una potenza di 10 a seconda dove siamo nella stringa. E poi stiamo andando ad aggiungere di nuovo nella nostra nuova variabile intera. Così che cosa sarebbe simile farebbe essere - disegneremo qui. Se veniamo passati nella stringa di 90 - STUDENTE: [incomprensibile]. JASON HIRSCHHORN: Ma atoi prende una stringa. Quindi stiamo per passare attraverso l'azienda. Ti avere superato nel 90. Usciamo dal retro al fronte. Prendiamo il 0. STUDENTE: Mi dispiace. Forse questo è stupido. Se stiamo ottenendo passati in una stringa, perché è 90 ciò che siamo sempre passato in? Dato che 90 è un numero intero. JASON HIRSCHHORN: Perché atoi prende una stringa e lo trasforma in numero intero rappresentazione di quella stringa. Ma la stringa 90 non è il numero intero 90 o il numero 90. La stringa 90 è un array di due, o tre personaggi, anzi, il 9 carattere, il carattere 0, e il backslash carattere 0. E stiamo scrivendo atoi perché, per esempio, quando si prende il comando argomento della riga, ed è salvato in argv, viene salvato come stringa. Ma se si vuole trattare come un numero, è necessario convertirlo in un integer reale. Che abbiamo fatto una delle nostre serie di problemi. Che abbiamo fatto in un numero dei nostri insiemi di problemi. Ognuno che ha preso un intero come argomento della riga di comando. Ecco perché la nostra funzione atoi prende una stringa. Quindi, di nuovo, nel nostro esempio qui, siamo andando a prendere l'ultimo. Stiamo andando a sottrarre il carattere 0 da esso, perché i caratteri 0 sottratto dal carattere 0 ti dà il numero effettivo 0, secondo la matematica ASCII che facciamo. Poiché i caratteri sono rappresentati come diverso da quello reale - la un carattere, per esempio, minuscola è 97. Non è - oops! Non è quello che ci si aspetterebbe che sia, 0, per esempio. Quindi bisogna sottrarre l' personaggio una per ottenere 0. Quindi stiamo andando a farlo qui per ottenere il numero effettivo. E poi ci accingiamo a moltiplicarlo per una potenza di 10 a seconda di dove è nella stringa, e poi che e aggiungerlo alla nostra segnaposto variabile in modo da poter venire con il nostro nuovo integer finale. Ritiene che abbia un senso per tutti? Quindi non stiamo andando a codificare questa in questo momento, perché siamo sempre a corto di tempo. Mi scuso per la tempistica di questo. Ma questo è ciò che, si spera, si farebbe essere in grado di fare il quiz - al molto meno, ottenere questo pseudocodice scritto fuori. E poi, se dovessimo scrivere il pseudocodice, in realtà, si potrebbe fare questo abbastanza rapidamente. Ogni riga di commenti che abbiamo scritto qui si traduce in circa una riga di codice C. Dichiarare una nuova variabile, la scrittura un loop, alcuni sottrazione, alcune moltiplicazione, e alcuni assegnazione. Probabilmente Ci piacerebbe Vogliamo anche scrivere una riga di ritorno. Potremmo anche mettere alcuni controlli a qui. Già. STUDENTE: Quindi possiamo trattare s come la stringa effettiva? Perché io so che è solo un indirizzo. Come, come è possibile ottenere la lunghezza di la stringa viene passata attraverso? JASON HIRSCHHORN: Così come ha fatto la lunghezza di una stringa? Strlen. STUDENTE: strlen, sì. Ma si può mettere s come argomento per questo? JASON HIRSCHHORN: Così strlen prende una stella char. E ne consegue che char stella, e continua a contare fino a raggiungere un backslash 0. strlen era in realtà uno degli altri programmi che stavano andando al codice. Questa è un'altra buona al codice. Quello è un po 'più facile, perché se si sta andando a pensare che concettualmente - Ho solo detto ad alta voce - strlen segue un puntatore e mantiene in corso e conteggio e tenere traccia fino si raggiunge un backslash 0. STUDENTE: Ok, capito. JASON HIRSCHHORN: So meglio di fortuna quiz 0 domani. Se avete domande, io essere al di fuori dopo questo. Sentitevi liberi di scrivermi. Raggiungere il proprio TF se sei non nella mia sezione, o avere il mio e-mail se si desidera. Se si vuole fuori di testa e basta inviare me an email, una email Freakout, io inviare indietro, come, una faccina sorridente, o, come, uno scherzo o qualcosa del genere. Quindi sentitevi liberi di fare anche quello. Buona fortuna ancora una volta, e io vedere tutti voi la settimana prossima.