[Powered by Google Translate] [Settimana 2, Continua]
[David J. Malan, Harvard University]
[Questo è CS50. - CS50.TV]
Bene. Questo è CS50, e questa è la fine della settimana 2.
Se vi aspettate di avere fame in questo periodo di domani,
So che stiamo andando a convocare un piccolo gruppo domani, Giovedi, 13:15.
C'è questo URL qui se vuoi RSVP.
Lo spazio è limitato, quindi ti prego di perdonare se il modulo è riempito nel momento in cui compili questo.
Un altro URL, però, che potrebbe essere di interesse è questo.
In quasi un mese di tempo, il corso sta per essere messa a disposizione
tanto più in generale tramite edx, attraverso la quale la gente su Internet sarà in grado di seguire,
impegnarsi nel corso abbastanza attivamente, in effetti.
Saranno utilizzando il CS50 Appliance e CS50 Discuti
e la maggior parte degli strumenti software diversi che già hanno utilizzato questo semestre.
E una delle iniziative vorremmo assumere come un esperimento di quest'anno
è quello di vedere quanto siamo in grado di tradurre i contenuti
in altre lingue parlate e scritte.
Quindi, se si potrebbe avere un interesse a partecipare a questo progetto
in base al quale ci fornirà trascrizioni inglese e sottotitoli per le lezioni del corso
e pantaloncini e seminari e sezioni e simili,
se si parla fluentemente o scrivere correntemente un'altra lingua,
ci piacerebbe coinvolgere in questo progetto in base al quale si prende su uno o più dei video,
traducendoli in una lingua che si conosce abbastanza bene.
>> Per dare un senso di interfaccia, c'è questo web-based interfaccia utente
che useremo che creerà essenzialmente un utente come questo.
Questo mi stava insegnando un po 'di Halloween fa,
e sulla destra c'è in nero accanto a queste timestamp,
vedrai le varie cose che sono uscite dalla mia bocca in quel giorno,
e poi sotto di esso sarete in grado di tradurre in qualche altra lingua
esattamente ciò che il mapping è tra, in questo caso, l'inglese e, per esempio, Spagnolo.
Quindi è in realtà una molto user-friendly strumento.
È possibile riavvolgere e far avanzare rapidamente molto rapidamente con le scorciatoie da tastiera.
Quindi, se volete prendere parte a questo esperimento e hanno le tue parole visto e letto
da potenzialmente migliaia di persone là fuori, per favore sentitevi liberi di partecipare.
Una parola circa il gattino da Lunedi.
Per non abbiamo inviato un messaggio di troppo spaventoso, si rendono conto che, come orario di ufficio suggeriscono
e come sezioni suggeriscono, la progettazione del corso è molto
di aver studenti collaborare e parlare a lavorare attraverso insiemi di problemi
e problemi insieme, e in realtà la linea arriva in fondo a,
ancora una volta, il lavoro che in ultima analisi, ritiene debbano essere il tuo.
E così in tutta onestà, in orario di ufficio è del tutto normale,
è del tutto prevedibile, anche, di essere in chat con qualche amico accanto a te.
>> Se lui o lei è alle prese con un argomento e siete come,
"Oh, beh, mi permetta di darle un assaggio di qualche linea di codice che ho scritto," va bene,
ciò che accade, e questo è molto favorevole, credo che, con il processo di apprendimento.
Se la linea viene attraversata è quando la testa è una sorta di inclinata qui per i secondi troppi
o minuti che in realtà di essere stato solo l'occasione di sblocco per il tuo amico,
e sicuramente quando le cose si scambiate via e-mail e Dropbox e simili,
vi è anche la linea.
Quindi, con tutti i mezzi sentirsi a proprio agio e si sentono incoraggiati a chattare con gli amici
compagni di classe e circa pset e molto altro ancora e solo rendersi conto che ciò che si presenta alla fine
in realtà dovrebbe essere il prodotto della vostra creazione e non qualcun altro.
E così uno dei problemi specifici del dominio per pset2,
che uscirà domani sera tardi, è quello di tuffarsi nel mondo della crittografia,
che è l'arte di crittografia o cifratura dei dati,
e questo si riferisce infine al mondo della sicurezza.
Ora, la sicurezza per la maggior parte di noi si presenta sotto forma di meccanismi piuttosto banali.
Tutti noi abbiamo nomi utente e password,
e tutti noi abbiamo nomi utente e le password molto male, molto probabilmente.
>> Se la password è la stessa su più siti web, che probabilmente non è l'idea migliore,
come vedremo verso la fine del semestre.
Se la password è scritto su un post-it - non è uno scherzo - sul monitor,
anche questo non è necessariamente il miglior design, ma un fenomeno piuttosto comune.
E se non si sta usando la crittografia per crittografare le password,
sono particolarmente vulnerabili.
Quindi, se pensi di essere super intelligente da avere un documento di Word nascosta
da qualche parte sul vostro disco rigido che ha tutte le password
ma è in una cartella che non si sta andando a guardare dentro, anche questo non è un meccanismo molto sicuro.
E allora cosa pset2 introdurrà è questa arte della crittografia
scrambling e informazioni in modo che cose come le password sono ancora più sicuro.
Il contesto è che con i dati insicuri
è la possibilità di cifrare e ad esso scramble.
E così questo, per esempio, è un esempio di un messaggio crittografato.
Questo in realtà dice qualcosa in inglese, ma non è chiaramente del tutto evidente.
E torneremo al punto di oggi a prendere in giro a parte ciò che questo messaggio segreto è qui.
Ma nel mondo reale dei computer, le cose non sembra nemmeno che potrebbero essere frasi in inglese.
Per esempio, questo è quello che si potrebbe trovare in un standard di Linux o Mac o UNIX del computer
in un file che una volta era un tempo chiamato il file delle password.
>> Al giorno d'oggi è stata spostata in altri luoghi.
Ma se si guarda al posto giusto su un sistema, si vedrà non solo il tuo nome utente
o quella di altre persone nel sistema, ma vedrete una versione crittografata della password.
In effetti, la cripta parola ci suggerisce che la roba che segue è crittografato,
e questa serie di lettere apparentemente casuali e caratteri e numeri e così via
possono essere decifrati solo generalmente conoscendo un segreto -
una parola segreta, un numero segreto -
e infatti, l'arte della crittografia in ultima analisi si riduce a fidarsi di qualche tipo
e conoscere qualcosa che qualcun altro non lo fa.
Quindi dovremo esplorare questo in dettaglio un po 'di più oggi e in pset a venire.
Ed ora una parola sul passaggio / sicuro.
Tanto più che alcuni di voi hanno tuffò pset1, Appliance,
e un mondo nuovo per lei, si rende conto che le frustrazioni e la confusione
e solo difficoltà tecniche sono abbastanza prevedibile,
soprattutto con il pset prima, dove c'è solo così tanto nuovo,
solo familiarizzare con ls e cd e tutti questi comandi arcani
e un nuovo ambiente, ed è separato dal materiale reale e la programmazione stessa.
Così conto troppo che ci sono certamente ore di ufficio che esistono come una struttura di supporto.
>> Sezioni iniziare il prossimo Domenica.
Ma la cosa più importante, se ti senti solo che questo non è il mondo per voi,
rendersi conto che in realtà si limita a prendere tempo.
E se non fosse per l'occasione anni fa per me di prendere un passaggio di classe / fail,
onestamente, non avrei mai nemmeno messo piede in classe.
E si può cambiare questo fino, diciamo, il Lunedi quinta del corso,
quindi se siete al limite ora, si rendono conto che invece di testa in alcune altre acque del tutto,
non certamente in considerazione il solo cambio di pass / fail.
Anche in questo caso, non c'è davvero questa cultura qui a Harvard di prendere le cose pass / fail
dal momento che tutti vuole davvero raggiungere o otterrebbe,
ma, francamente, questo è un modo meraviglioso di provare qualcosa
che potrebbe non essere familiare a voi, e vi ritroverete a fare, nella maggior parte dei casi, abbastanza bene,
forse molto con vostra sorpresa.
E in termini più concreti, quello che penso pass / fail generalmente fa,
tanto più che si potrebbe avere sperimentato con pset0,
se si mette in 10 ore, 15 ore, 25 ore in alcuni pset
e sei solo sbattere la testa contro il muro e si sta facendo super-a tarda notte
ma hai preso la pset il 90% della strada e proprio non riesco a capire una cosa,
pass / fail prende davvero il bordo al largo di una classe come questa,
dove si può ordinare di felicemente dire: "Va bene, lo so che non è perfetto,
ma ho lavorato il culo su questo, sono abbastanza contento di dove è finito, "
e in grado di soddisfare le aspettative di pass / fail.
Quindi non tenere a mente. Bene.
>> Così quelli di voi che hanno lottato per utilizzare la Harvard University Wi-Fi,
so che c'è un CS50 SSID, una connessione Wi-Fi, galleggianti intorno
che si potrebbe avere più fortuna per.
E 'un po' ironico che la password per questo, se si vuole provare a connettersi a questo
per una migliore velocità - e di farci sapere se si tratta di niente di meglio - è 12345, tutta la strada fino a 8
perché 8 è più sicuro di 5.
Quindi, se avete bisogno di password Wi-Fi, la connessione a CS50 wireless qui, 12345678,
e post su CS50 Discutere se avete ancora problemi di connettività intermittente,
e ti faremo i poteri che sanno essere per questo spazio. Bene.
Quindi un teaser rapida, soprattutto per quelli di voi che sono ragazzi o ragazze fan di tutte le cose di Apple.
Quello che ho riesumato da qualche anno fa era il file qui, iUnlock.c,
solo per fare i tipi di più concreto e più complesso
alcuni dei programmi più basilari C Abbiamo scritto.
Così ho aperto questo file, iUnlock.c. E 'disponibile nella pagina lezioni per oggi.
Sulla sinistra si vede un lungo elenco di funzioni.
Quindi il tizio che ha scritto questo ha scritto un sacco di funzioni, più che principale.
Ha usato un sacco di librerie di qui, e se cominciamo a scorrere,
ciò che questo è in realtà è il primo, credo, crack per l'iPhone originale.
>> Quando si voleva per il jailbreak di iPhone originale, il che significa untether da AT & T
e in realtà installare un software speciale su di esso e fare cose che Apple non voleva che la gente a fare,
qualcuno ha avuto il tempo di capire esattamente come si potrebbe sfruttare falle di software,
errori, bug nel software di Apple, e quindi è nato iUnlock.c--
che se è stato compilato il computer e installato su un iPhone
che era collegato al computer tramite, per esempio, un cavo USB,
questo darebbe privilegi di amministratore o di root sul vostro iPhone
e consentono di fare più o meno quello che vuoi.
E così c'è stato questo gatto affascinante e topo
tra Apple e il resto del mondo, in particolare in quanto, come molte aziende,
cercano di bloccare le loro cose in modo che si può fare solo con essa ciò che intendono.
Ma grazie a gente come questa e la comprensione dei dettagli di basso livello -
e in questo caso C programmazione - e molti dei costrutti familiari
che abbiamo iniziato a giocare con, si è in grado di sfruttare realmente l'hardware
in un modo si vede in forma e non necessariamente una qualche entità aziendale.
Così, per esempio, non ho idea di che cosa tutto questo sta facendo,
ma GetVersion sembra piuttosto semplice,
e sembra che si tratta di una funzione che questa persona ha scritto.
Ci vuole una specie di numero intero come argomento, non restituisce nulla,
ma sembra loop con un ciclo for qui e una condizione if, se rottura condizione,
e si riferisce in qualche modo i numeri di versione, se scorrere verso il basso,
anche se molte di queste parole chiave stanno per essere nuovo.
E ci sono un sacco di funzioni in qui non abbiamo mai visto e forse non mai vedere
nel corso del semestre.
>> Alla fine della giornata, segue le stesse regole e la logica che abbiamo giocato con finora.
Quindi questo è di gran lunga troppo vecchio per risolvere i vostri iPhone o 3s 4s 5s o poco in questi giorni,
ma so che è tutto molto derivato da questo mondo che abbiamo tuffò.
Diamo uno sguardo a un piccolo esempio più semplice:
questo, solo per ottenere riscaldato con qualche sintassi e anche qualche altro tipo di dati
che abbiamo parlato, ma non hanno in realtà visto in C.
Si tratta di un file chiamato positive1.c, e per i commenti in alto,
ciò richiede solo che un utente di fornire un numero positivo.
Quindi è un esempio di un ciclo do-while, che è bello per i programmi utente interattivi
in cui è necessario indicare all'utente di fare qualcosa,
e se non collaborano si urlare contro di loro o rifiutare il loro ingresso.
Caso in questione: ho intenzione di fare le linee 19 a 24
fino a quando l'utente non mi ha dato un numero positivo.
Questo dettaglio qui sulla linea 18, perché dichiaro n di sopra di questo ciclo intero costrutto
al contrario di proprio accanto alla linea 22 dove ho fatto la cura per ottenere n? Gia '.
[Studente] Ambito di applicazione. >> Si ', per cui la questione del campo di applicazione.
E in parole povere, che cosa fare riferimento alla portata?
Gia '. >> [Risposta degli studenti incomprensibile] >> Si può parlare un po 'più forte?
[Studente] Dove è possibile accedere a tale variabile. Perfetto >>.
Dove è possibile accedere a una particolare variabile.
E, in generale, la regola pratica finora è stato che la portata di alcune variabili
è definita dalle parentesi graffe più recenti che avete visto.
>> E così, in questo caso, se ho fatto l'errore di dichiarare n sulla linea 22, la linea avrebbe funzionato.
Vorrei avere un int, e io la metterei in quella variabile n in linea 22,
ma che riga di codice che ora non hanno alcuna idea di cosa sto parlando? >> [Studente] 25.
[Malan] 25, e si scopre che 24 come bene perché in questo caso non rientra le parentesi graffe.
Quindi, solo un po 'di una seccatura, ma molto facilmente risolto semplicemente dichiarando la variabile
fuori della funzione stessa.
Vedremo nel corso della giornata è possibile fare un ulteriore passo avanti
e si potrebbe anche ottenere un po 'pigro.
E questo non è da raccomandare in generale, ma si potrebbe anche ottenere pigri
e mettere una variabile globale, per così dire, non all'interno di una funzione, non all'interno di un ciclo,
ma nel file stesso, al di fuori di tutte le funzioni che hai scritto, come ho fatto qui sulla linea 15.
Questo è generalmente visto di buon occhio, ma mi rendo conto questa è una soluzione a volte per altri problemi,
come vedremo finalmente vedere.
Quindi per ora ci lasciamo così, ma vediamo se siamo in grado di riscrivere il
tanto per cominciare esprimere noi stessi un po 'diverso.
Questo programma, tanto per essere chiari, è positive1.
Lasciami andare avanti qui e nella mia finestra di terminale fare positive1, Invio.
Compila bene. Io vado a correre positive1, premete Invio.
Esigo che tu mi dia un numero intero positivo. Dirò -1. Non ha funzionato.
0, 99. Questo sembra funzionare.
Forse non la prova più rigorosa, ma almeno è un controllo di integrità bella
che siamo sulla strada giusta.
>> Così ora lasciami andare avanti e aprire la versione 2 di questo,
e ciò che è già diverso?
Essa attua la stessa cosa, ma ciò che salta fuori il più chiaramente diverso questa volta?
Questo bool in verde. Si è evidenziato in verde, questa parola chiave conosciuto come bool, che è un tipo di dati.
Non viene integrato in tutte le versioni di C.
È necessario includere una libreria specifica.
Nel nostro caso, ho inserito il CS50 biblioteca in modo da avere accesso a bool.
Ma in linea 18, ci sembra di avere un valore booleano che qui chiamano grati.
Avrei potuto chiamare questo niente, ma ho chiamato grato
solo per trasmettere qualche tipo di significato semantico.
Quindi inizialmente sulla linea 18, non sono evidentemente grato
perché il valore booleano grato è inizializzato a false nella riga 18.
E poi sembra che quello che ho fatto nelle linee 21 e 23
è che ho solo un po 'riscritto la mia logica.
Quindi no funzionalmente diverse, ma in linea 22 ora verificare se l'int l'utente ha fornito
è maggiore di 0, quindi ho semplicemente cambiare il valore di grato su true.
E perché dovrei farlo? Perché in linea 25, a quanto pare ho intenzione di verificare una condizione.
Fate questo ciclo while è falsa grati.
Così ho proposto come alternativa alla versione 1
perché è almeno un po 'più intuitivo, forse, è un po' più a terra in lingua inglese.
Quindi, effettuare le seguenti operazioni, mentre non sei grato o mentre grato è falso.
E anche questa volta mi pare non mi interessa ricordare ciò che l'utente ha digitato
perché non c'è nessun avviso n variabile, quindi in realtà, una piccola bugia bianca lì.
>> Punto di vista funzionale, il programma è un po 'diversa una volta che andare a fondo di esso
perché io non mi ricordo che cosa è n.
Ma ho voluto dimostrare anche qui che, anche se abbiamo visto GetInt
e GetString utilizzato sul lato destro di un segno di uguale finora
in modo da ricordare il valore, tecnicamente, non è strettamente necessario.
Se per qualsiasi motivo non solo la cura per salvare il valore,
si vuole solo controllare il valore, si noti che possiamo semplicemente scrivere questo come GetInt,
aperta parentesi, parentesi vicino.
Tale funzione sta per restituire un valore, come abbiamo detto.
E 'intenzione di dare indietro un int.
E quindi se mentalmente pensa che ciò accada,
quando digito nel 99, GetInt restituisce il numero 99,
e così concettualmente, è come se il mio codice erano in realtà questo.
Quindi, se il 99 è effettivamente maggiore di 0, quindi grato diventa vero,
poi linea 25 si rende conto ooh, abbiamo finito, perché ora sono grato,
e in linea 26, diciamo semplicemente: "Grazie per l'intero positivo!"
qualunque cosa è successo di essere.
Ora facciamo una leggera zucchero sintattico qui, per così dire.
Vediamo se riusciamo a ripulire questa linea 25 con questa variante terzo e ultimo positive3.
>> Si noti la differenza solo ora è quello che riga di codice? >> [Studente] 25. >> [Malan] Si ', 25.
E non abbiamo veramente visto questo trucco appena ancora, ma abbiamo fatto vedere il punto esclamativo il Lunedi,
che indica che cosa? >> [Studente] Non. Non >> o negazione.
Così ha un valore booleano e capovolgere il suo valore.
Vero diventa falso, falso diventa vero.
Quindi questo, vorrei proporre, è anche un po 'più intuitivo il modo di scrivere il codice
perché ancora inizializzare grato a false, ho ancora effettuare le seguenti operazioni,
Ho impostato grato a true quando sarà il momento,
ma ora si può davvero solo tradurre questo codice verbalmente da sinistra a destra,
while (grati!) perché il punto esclamativo indica botto o la nozione di non,
così, mentre non grata.
Quindi, di nuovo, non abbiamo introdotto nuovi concetti di per sé.
Abbiamo parlato di valori booleani indietro quando abbiamo giocato con Scratch,
ma rendersi conto ora possiamo iniziare a scrivere il nostro codice in molti modi diversi.
Quindi, soprattutto in pset1 se siete una sorta di fatica a capire il modo di scrivere qualche programma,
probabilità sono che siete fortunati perché non ci può essere un qualsiasi numero di soluzioni
che può accadere al momento.
Per esempio, questo è solo per 3 anche il più semplice dei programmi. Bene.
E ora ricordo il Lunedi abbiamo lasciato su questa nota con valori di ritorno.
Così, per la prima volta abbiamo scritto un programma che non solo principale;
ma ha anche una sua funzione personalizzata che ho scritto qui.
Quindi, in linea 31 a 34 ho implementato una funzione cubo.
Non è complessa. E 'solo un * a * a in questo caso.
Ma ciò che è importante a questo proposito è che sto prendendo l'input sotto forma di un
e sto tornando in uscita sotto forma di un * a * a.
Così ora ho la possibilità, proprio come facevo con prinf da solo,
per chiamare questa funzione chiamando la funzione cubo.
>> E la funzione cubo richiede un po 'di input, e la funzione cubo restituisce un output.
Al contrario, printf appena fatto qualcosa.
Essa non ha restituito tutto ciò che abbiamo a cuore, anche se, come nota a margine che non restituisce un valore;
basta generalmente ignorarlo.
Printf appena fatto qualcosa. Esso aveva un effetto collaterale di stampa sulla schermata.
Al contrario qui, abbiamo la funzione di cubo, che restituisce effettivamente qualcosa.
Quindi, per chi ha familiarità con questo, è una idea abbastanza semplice.
Ma per coloro che hanno meno familiarità con l'idea di passare in input e tornare uscite,
proviamo solo semplice qualcosa di super.
C'è qualcuno che sta comodo in arrivo sul palco per breve tempo?
Devi stare bene con una macchina fotografica su di voi pure. Si '? Va bene.
Qual è il tuo nome? >> [Studente] Ken. Ken >>. Bene. Ken, vieni su.
Ken sarà una funzione della specie qui.
Andiamo avanti e farlo. Prendiamo un po 'di fantasia.
Lieto di vederla. Benvenuti al centro della scena. Bene.
Che ha colpito questo pulsante qui. Bene.
Così qui avete una lavagna moderna,
e quello che sono è la funzione principale, per esempio,
e non ho un iPad in mano.
>> Non mi ricordo come - Beh, non posso dire che.
Io in realtà non hanno una buona grafia,
e così quindi voglio di stampare qualcosa sullo schermo per me.
Sto è il programma principale, e ho intenzione di averti dire questo
scrivendo nel mio graffi pollo e poi passando voi un ingresso.
Così stupido se questo esercizio è, il concetto di funzioni e chiamare una funzione
e il ritorno di una funzione davvero si riduce a questo.
Sono principale, ho appena scritto printf, quote-unquote qualcosa sullo schermo,
Sono in esecuzione di questo programma, e non appena printf viene chiamato,
ci vuole un argomento o un parametro, talvolta, tra doppi apici.
Ecco questo argomento. Lo sto passando a Ken.
E 'una scatola nera scritto un certo numero di anni fa
che a quanto pare conosce solo come stampare le cose sullo schermo.
Quindi eseguire.
Non è male. Molto buono.
Così ora Ken è fatto in esecuzione. Ha bisogno di darmi nulla in cambio?
Non che abbiamo visto finora.
Anche in questo caso, printf in effetti restituisce un numero, ma abbiamo intenzione di ignorare che per ora
perché non abbiamo mai usato. Ecco, questo è esso per Ken.
E così ora principale assume il controllo del programma di nuovo
perché quella riga di codice, printf, è fatto in esecuzione.
E si va la nostra strada, l'esecuzione di qualunque altre linee ci sono.
Ora proviamo un esempio leggermente diverso.
Questa volta qui si deve prima cancellare lo schermo, e questa volta faremo la funzione di cubatura,
ma questa volta, mi aspetto un valore di uscita.
>> Quindi cerchiamo di andare avanti e farlo.
Ora ho una riga di codice che dice che x diventa cubo di x.
La riga di codice, richiamo, assomiglia a questo: x = cube (x);
Così come è questo di andare a lavorare? Andiamo avanti e dare uno schermo bianco di nuovo.
Ho intenzione di scrivere ora il valore di x,
che in questo momento sembra essere, diciamo, 2 per mantenere le cose semplici.
Ho scritto su un pezzo di carta del valore di 2, che è il mio valore x.
L'ho mano a Ken. >> E ho appena scrivere la risposta? >> Si ', diciamo solo scrivere la risposta.
Va bene. E ora deve restituire qualcosa. Perfetto. Segue Nizza.
Così ora mi porge nuovamente il valore di 8 in questo caso, e cosa devo fare?
In realtà - vediamo, ottenere questo diritto. Cosa devo fare con esso?
Ora sto andando a prendere questo valore e in realtà conservare in quegli stessi bit in memoria.
Ma bando Sono un po 'di lottare qui.
Sono un po 'confuso perché dove ho effettivamente scrivere il valore di x,
perché quello che ho appena fatto è fisicamente Ken mano un pezzo di carta che aveva il valore 2,
che era x, e in effetti, è proprio quello che è successo.
Così si scopre che quando si chiama la funzione e si passa in una discussione
come ciao, mondo o si passa in una discussione come 2,
in generale, si sta passando a una copia di tale argomento.
E così come ho scritto il numero 2 qui e lo porse a Ken,
che deve dire che ho ancora una copia del valore 2 da qualche parte
perché in effetti, ora che ho ottenuto di nuovo il valore 8, ho bisogno di tornare indietro nella RAM
e in realtà scrivere 8, dove una volta ho avuto il numero 2.
Quindi visivamente, ricorda questa nozione di passare a, letteralmente, una copia del valore.
>> Ken fa la sua cosa, mi dà indietro qualcosa - in questo caso un valore come 8 -
e poi devo fare qualcosa con quel valore se voglio tenerlo in giro.
Quindi, tutto questo tornerà a essere fin troppo bene in breve tempo.
Grazie mille per questa demo qui, Ken. [Applausi]
Molto ben fatto.
Vediamo come in ultima analisi, che si riferisce ad alcune delle funzione chiamante che stiamo facendo qui.
Lasciatemi andare avanti e ci riportano alla cubatura esempio qui.
Si noti che se vogliamo iniziare effettivamente l'assunzione di questo ulteriore,
stiamo andando ad avere per essere consapevoli del fatto che il numero x che viene passato qui
è diverso da ciò che è effettivamente essere passato alla funzione.
Quindi, di nuovo, questo passaggio per copia sta per diventare molto germano in un attimo.
Diamo uno sguardo a qualcosa che non tutto funziona bene ancora.
Ho intenzione di andare avanti e aprire un terzo esempio buggy, che è viziata dalla natura,
e si chiama buggy3 e implementa una funzione di scambio.
Qui abbiamo una funzione principale che ha x ed y arbitrariamente inizializzato a 1 e 2, rispettivamente.
Potremmo usare GetInt, ma abbiamo solo bisogno di un semplice esercizio,
quindi è hardcoded come 1 e 2.
In linee 21 e 22, che apparentemente stampare x ed y, 1 per riga.
Poi sulla linea 23, rivendico sto scambiando questi valori, punto, punto, punto.
Mi pare chiamare una funzione alla riga 24 di swap cd che prende 2 argomenti.
E 'del tutto legit per le funzioni di prendere 2 argomenti. Abbiamo visto printf lo fanno già.
>> Quindi scambio prende apparentemente x e y, e come suggerisce il nome,
Mi auguro che sta andando a scambiare questi 2 valori.
Allora io sostengo sulla linea 25 "scambiati!" e io ristampare x e y
sotto l'ipotesi che hanno effettivamente state scambiate.
Ma se io in realtà esegue questo programma - lasciatemi aprire una finestra di terminale,
permettetemi di fare buggy3 - come suggerisce il nome, questo non sta andando a finire bene
perché quando ho premere Invio, si noti che x è 1, y è 2,
e ancora alla fine del programma, sono ancora, infatti, lo stesso.
Quindi, basata sulla dimostrazione poco fa con Ken, cosa sta realmente succedendo?
Tuffiamoci in questa funzione di scambio. E 'super breve. Sono solo poche righe di codice lungo.
Ma qual è il problema fondamentale basato sulla storia semplice che racconta qui con Ken?
Perché è rotto di swap?
[Studente] Ecco la memorizzazione su una copia non, la variabile.
Esattamente. Siamo la memorizzazione su una copia non, la variabile stessa.
In altre parole, scambio prende 2 argomenti a quanto pare, un int,
ed è arbitrariamente chiamati A e B,
e qui ho passato in x ed y, che sono rispettivamente 1 e 2,
ma io non sono letteralmente passando x, non sto letteralmente passando y,
Sto passando una copia di x e una copia di y.
E 'quasi come se è stato copiato e incollato in swap
i valori che si desidera per manipolare effettivamente.
Quindi, se questo è il caso, quando l'avvio del programma di esecuzione linea 35 poi 36,
quando arrivo a riga 37, a questo punto della storia, qual è il valore di un?
A questo punto della storia, riga 37, che è il valore di a questo punto? >> [Studente] 1.
[Malan] Dovrebbe essere solo 1, a destra, in quanto x è stato passato come primo argomento,
e questa funzione è sufficiente arbitrariamente sta chiamando il suo primo argomento a.
Allo stesso modo è Y il secondo argomento, ed è solo arbitrariamente chiamando il b secondo argomento.
>> Questa dicotomia è in realtà abbastanza semplice spiegato. Pensateci.
Nessuno di noi ha incontrato la persona che ha scritto printf,
quindi sicuramente, lui o lei non ha idea di quello che le nostre variabili 30 anni dopo stanno per essere chiamati.
Quindi ci deve essere una distinzione tra ciò che voi chiamate variabili in funzioni che stai scrivendo
e ciò che chiamate variabili in funzioni che si sta chiamando o usando.
In altre parole, ho scritto le mie variabili come x e y,
ma se qualcun altro aveva scritto la funzione di scambio, lui o lei di certo non avrebbe saputo
quello che i miei variabili stanno per essere chiamato,
in modo da rendersi conto che questo è il motivo che ha questa dualità di nomi.
Tecnicamente, potrei fare questo per caso,
ma sarebbe ancora passata in tante copie.
Sarebbe solo una pura coincidenza esteticamente se la persona che ha scritto di swap
aveva usato gli stessi nomi.
Quindi, a questo punto della storia, la linea 37, a è 1, b è 2, e ora procedo per scambiarle.
Prima di tutto, vorrei effettivamente fare questo molto più semplicemente.
Non so che cosa quelle 3 righe di codice sono state facendo.
Vorrei solo fare questo: b = a, a = b; fatto.
Perché è rotto, logico?
È un po 'la cosa intuitiva, giusto?
Così un b and b diventa diventa,
ma il problema è che non appena la linea 37 esegue, qual è il valore di A e B?
Lo stesso, 1, perché hai rovinati, per così dire, hai cambiato b corrisponderanno a.
Quindi una volta che la linea 37 ha eseguito, che è grande, ora avete 2 copie del numero 1
all'interno di questa funzione, così poi quando si dice in linea 38 a = b,
sei tipo di naso, perché si sta solo assegnando 1 a 1.
Hai perso il tipo di valore che si interessava.
Quindi, nella versione originale di questo, nota quello che ho fatto.
Ho invece avuto una terza riga di codice che si presentava così.
Dichiaro una variabile temporanea.
>> Tmp è un nome molto comune per una variabile temporanea, ed è un int
perché deve rispondere a quello che voglio fare una copia di.
Devo conservare copia di un interno di tmp, quindi una volta che la linea 37 è stato eseguito,
il valore di a è - rapido controllo sanity - 1, il valore di b è 2,
e il valore di tmp è anche 1.
Così ora eseguo linea 38.
Una volta eseguita la linea 38, assume un valore di b. E b è stato di 2, quindi un ora 2.
Quindi, a questo punto della storia, a è 2, b è 2, e tmp è 1,
così ora logicamente, possiamo solo valore di tmp plop in b e abbiamo finito.
Così abbiamo risolto il problema.
Purtroppo, quando si esegue il programma in questa forma, in realtà non scambiare i valori.
Ma per essere chiari, perché?
Ho risolto il problema logico da appena un momento fa,
ma ancora una volta, se si esegue il programma, x e y restano invariati
alla fine dell'esecuzione del programma.
[Commento studente incomprensibile] >> Non ci siamo tornati niente, quindi è vero.
Ma si scopre c'è un po 'un problema qui, perché fino ad ora,
l'unica cosa che siamo stati in grado di tornare è una cosa, e questa è una limitazione di C.
È possibile tornare veramente un valore, nel qual caso sono un po 'bloccato qui
perché ho potuto restituire il nuovo valore di x oppure avrei potuto restituire il nuovo valore di y,
ma voglio sia indietro.
Quindi ritorno non è la soluzione più semplice qui.
Ma il problema è fondamentalmente il motivo? Cosa abbiamo scambiato?
[Studente] a e b. >> A e b.
Ma a e b sono copie di x e y, il che significa che abbiamo appena fatto tutto questo lavoro,
abbiamo appena trascorso 3 minuti a parlare sulla funzione swap e tutti e 3 di queste variabili,
e questo è grande, perfettamente corretto in isolamento,
ma una portata e b è solo in queste righe qui.
>> Quindi, proprio come un ciclo for, se si dichiara un intero i all'interno del ciclo for,
Allo stesso modo, se si sta dentro dichiara a e b di una funzione che hai scritto,
sono validi solo all'interno di tale funzione, il che significa che non appena swap è fatto in esecuzione
e si va da riga 24 alla riga 25, x e y non sono stati cambiati per niente.
Hai appena sprecato un sacco di tempo scambiare copie di variabili.
Così si scopre che la soluzione a questo è in realtà non ovvio.
Non è del tutto sufficiente per restituire i valori, perché siamo in grado di restituire solo 1 valore,
e mi voglio scambiare sia x e y, allo stesso tempo,
quindi stiamo andando ad avere per tornare a questo.
Ma per ora conto che il problema fondamentale deriva dal fatto che A e B sono copie
e sono nel loro spazio proprio.
Cerchiamo di risolvere questo problema in qualche modo.
Vorrei in realtà scorrere di nuovo qui e di aprire, diciamo, una quarta variante di questo, buggy4.
Che dire di questo?
Si tratta di un problema simile ma più semplice da guardare prima di prendere una pugnalata a risolverlo.
Questo programma si chiama incremento, e inizializza apparentemente un numero intero x a 1 in linea 18.
Ho poi rivendicazione x è 1, io poi affermare "Incremento ..."
Ho quindi chiamare incremento, ma poi nelle linee 22 e 23, io sostengo che è stato incrementato,
Io sostengo x ora è quello che è - 2, presumibilmente - ma questo programma è bacato.
Qual è il problema?
Gia '. >> [Risposta degli studenti incomprensibile] >> Esattamente.
Quindi x è stata dichiarata, ovviamente, sulla linea 18.
Questo è all'interno delle parentesi graffe principale.
Quindi la risposta semplice è che mentre x esiste qui,
non esiste in linea 32, quindi questo programma effettivamente non anche compilare.
Il compilatore quando provo a compilare questo codice sta per urlare contro di me
su alcuni identificatore non dichiarato o qualcosa in tal senso. Infatti, proviamo.
Questo è fare buggy4. Eccolo.
L'uso di 'x' identificatore non dichiarato in linea 32.
E in realtà, cerchiamo di essere più esplicito qui oggi, in modo che questo sia utile
in orario di ufficio e in casa.
>> Si noti che è un po 'criptico scritto.
Ma il fatto che Clang ha urlato contro di noi, dicendo buggy4.c: 32:5, è effettivamente utile.
Significa che l'errore è sulla linea 32 alla posizione del carattere 5.
Quindi 1, 2, 3, 4, 5. Questo è, infatti, dove il problema è.
E poi, anche, tenere a mente in orario d'ufficio, a casa, sono fortunato qui.
Ho un errore. E 'intenzione di essere relativamente facile da risolvere.
Ma se si ottiene uno schermo pieno di messaggi di errore travolgente,
ancora una volta si rendono conto che quello in basso potrebbe essere solo sintomatico di quello più in alto.
Quindi, sempre inseguire i bug dall'alto verso il basso
perché ci potrebbe essere solo un effetto a catena
che suggerisce di avere problemi più di quanto effettivamente fare.
Quindi, come possiamo risolvere questo problema se il mio obiettivo è quello di incrementare x? >> [Studente] Fai x globale.
Ok, allora possiamo fare x globale.
Prendiamo la scorciatoia che ho avvertito in precedenza, ma diamine, abbiamo solo bisogno di una soluzione rapida,
quindi diciamo solo che x int qui. Che fa x globale.
Così ora principale ha accesso ad esso e incremento ha accesso ad esso,
e così mi permetta di andare avanti e compilare questo ora.
Fai buggy4, Invio. Sembra da compilare al momento.
Corriamo buggy4. E sembra funzionare davvero.
Questa è una di quelle cose che è fare come dico, non come faccio io,
come ho appena fatto qui, perché in generale,
i nostri programmi si sta per ottenere molto più interessante e molto più di questo,
e se la soluzione ai problemi della vita è solo mettere tutte le variabili nella parte superiore del file,
molto velocemente programmi si ottiene terribilmente difficile da gestire.
Diventa sempre più difficile pensare a nuovi nomi delle variabili,
diventa più difficile capire quale variabile sta facendo che cosa,
e quindi, in generale, questa non è una buona soluzione.
Quindi cerchiamo di farlo meglio.
Non vogliamo usare una variabile globale qui.
>> Voglio incrementare x, così ho potuto ovviamente -
alla fine della giornata, questo è una specie di sciocca storia perché solo fare questo -
ma se io non lo sapevo che l'operatore o non mi era permesso di cambiare in principale in sé,
in quale altro modo avrei potuto implementare Ken qui questa volta non per cubo, ma per incrementare?
Come faccio a cambiare questa cosa qui? Gia '.
[Studente] Passa x e poi tornare [incomprensibile] >> Ok, bene.
Allora perché non mi passa in x e allora piuttosto che restituirlo,
perchè non ho riesci a tornare x + 1.
Un altro paio di cose devono cambiare qui. Sono sulla strada giusta.
Che altro ho bisogno di modificare? Qualcun altro. Gia '.
[Risposta degli studenti incomprensibile]
Ho bisogno di cambiare il tipo di ritorno di incremento perché non è nulla.
Significa che non viene restituito Void, ma chiaramente ora è,
così questo deve cambiare - >> [studente] int.
int per essere coerente con quello che sto effettivamente tornando.
Ora ci sia ancora qualcosa buggy qui. Gia '.
[Risposta degli studenti incomprensibile] >> [Malan] Così ho bisogno di incrementare x?
[Risposta degli studenti incomprensibile] >> [Malan] Ah, quindi ho bisogno di passare x.
Quindi ho bisogno di fare questo qui. >> [Commento studente incomprensibile]
[Malan] Il prototipo, devo cambiare questo qui.
Quindi questo deve diventare un int, questo deve diventare -
hmm, io in realtà sono un bug qui. Si può correggere prima.
Che cosa avrebbe dovuto in realtà essere? E 'ottenuto di essere un qualcosa di int.
Potrebbe essere x, ma, francamente, se si inizia a chiamare tutti i tuoi x variabili,
sta andando per ottenere sempre meno chiaro che cosa si tratta.
>> Così facciamo solo arbitrariamente scegliere una diversa convenzione di denominazione per le mie funzioni di supporto,
le funzioni che sto scrivendo. Ci chiamano una, o potremmo chiamarla -
Chiamiamolo il numero per essere ancora più esplicito.
Allora devo restituire ciò che il numero è più 1,
e ora devo cambiare 1 altra cosa qua e un'altra cosa qui.
Che cosa devo cambiare sulla linea 21 prima? >> [Risposta degli studenti incomprensibile]
[Malan] devo assegnarlo a x. Non posso chiamare incremento (x).
Ho bisogno di ricordare la risposta modificando il valore di x sulla sinistra.
E anche se x ora è a sinistra e la destra, questo è tutto bene
perché il lato destro viene eseguito in primo luogo allora si lasciò cadere nella mano sinistra cosa -
x in questo caso.
E poi, infine, si tratta di una soluzione semplice ora.
Questo dovrebbe corrispondere solo ciò che è in basso, il numero int.
Quindi un sacco di cambiamenti per una funzione davvero stupido
ma rappresentativo delle cose che sempre più ci vogliamo fare.
Quindi, fare buggy4. Ho fatto un casino da qualche parte.
Oh, mio ​​Dio.. Cinque errori in 6 linee di programma.
Allora, cosa c'è che non va sulla linea 18, il carattere 5?
Quindi devo dichiarare questo, int.
Vediamo un po '. Ci sono un sacco di altri errori.
Oh, mio ​​Dio - 19, 18, 21 - ma ancora una volta, facciamo solo cancellare lo schermo, L di controllo qui,
ed eseguire nuovamente Clang.
Così cinque problemi è in realtà solo che 1.
Così ora corriamo buggy4, Invio. Accidenti, x è stato incrementato correttamente.
Bene. Hai domande su come incrementare i numeri? Gia '.
[Domanda studente incomprensibile] >> Buona domanda.
Come è possibile che io possa cambiare solo x al numero e il programma saprà immediatamente?
>> Anche in questo caso, pensare ad esso come questa astrazione.
Quindi, se ho am main e Ken è incremento, francamente, non mi interessa quello che Ken chiama il suo iPad.
Non mi interessa quello che lui chiama tutto ciò che ha a che fare con la sua applicazione di questa funzionalità.
Si tratta di un dettaglio di implementazione che io, principale, non c'è bisogno di preoccuparsi.
E così semplicemente cambiando costantemente all'interno della funzione - numero qui e numero qui -
è tutto quello che vuole tanto tempo come ho ricompilare.
E 'un po' come se si pensa che molti di noi, quelli di voi con patenti di guida
che hanno guidato o se hai anche guidato in una macchina,
la maggior parte di noi non hanno idea di come funziona una macchina sotto la cappa.
E letteralmente, se si apre il cofano, la maggior parte di noi - me compreso -
non stanno andando per sapere esattamente cosa stiamo guardando,
un po 'come si potrebbe sentire con roba come questo adesso.
Ma in realtà non hanno di prendersi cura come la macchina funziona,
non abbiamo a importa di quello che tutte le canne e pistoni e cavi all'interno della vettura
sono in realtà facendo.
Quindi, qualcosa di simile a quello che voi chiamate il pistone non ha importanza qui in questo caso. Stessa idea.
Gia '. >> [Domanda studente incomprensibile]
Se ci sono più usi del momento variabile xa fa,
si, il programmatore, dovrebbe cambiare ovunque.
Oppure si potrebbe letteralmente fare file, Menu, quindi Trova, Sostituisci - qualcosa del genere -
ma si sta andando ad avere per fare le modifiche da soli.
Bisogna essere coerenti. >> [Studente] Se non ci sono più variabili [incomprensibile]
Un ordine particolare come qui, se questo fosse int un altro numero? >> [Studente] Esatto.
[Malan] Si '. Ordina che conta quando si chiama la funzione.
>> Quindi, se fossi chiamato Rilancio qui con qualcosa qualcosa di virgola,
c'è una corrispondenza diretta.
La prima variabile, come si chiama, è una copia del primo argomento qui.
Scusi. Questo non dovrebbe essere una parentesi.
Le linee argomento secondo fino con il secondo. Quindi l'ordine, sì, le cose. Bene.
Scusi. Ho preso la strada più lunga per arrivarci. Altre domande? Bene.
Quindi cerchiamo di vedere se non si può dipingere un quadro di ciò che sta realmente accadendo qui
sotto la cappa, per così dire.
Si tratta di un rettangolo che potrebbe rappresentare la memoria del computer.
Anche se non avete idea di come funziona la memoria RAM o come funziona,
almeno si supponga di avere grappoli di esso in questi giorni.
Hai megabyte di esso, hai gigabyte di esso,
e sappiamo da settimana 0 che un byte è proprio quello? >> [Studente] 8 bit.
8 bit, giusto? Quindi 8 zeri e 1.
Quindi, se il vostro computer dispone di un giga di RAM, 2 GB di RAM in questi giorni,
si dispone di un miliardo o 2 miliardi di byte di memoria o di circa 8 miliardi o 16 miliardi di bit
all'interno del computer.
A differenza del piccolo esempio Wooly Willy, non è in genere più particelle magnetiche.
Sempre più spesso - nei computer portatili, almeno - è unità a stato solido, SSD,
che proprio non hanno parti in movimento. E 'tutto elettronico. E 'tutta l'energia elettrica-based.
Quindi, pensare a questo come solo rettangolo che rappresenta i 1 o 2 gigabyte di memoria che avete.
>> Quindi è un pezzo di memoria.
Il mondo dell'informatica è sorta di partizionato
blocchi di memoria per fare cose diverse.
Per esempio, se questa è la RAM del computer, come suggerito dal rettangolo lì,
risulta che per convenzione, nella parte superiore della RAM, per così dire,
è in genere quello che si chiama un segmento di testo.
Questi sono i 0 e 1 che sono stati compilati.
Così, quando abbiamo guardato sotto il cofano a ciò che è a.out,
tutti questi 0 e 1, quando si esegue un programma,
quelli 0 e 1 vengono caricati dal disco rigido in qualcosa chiamato RAM,
e nella RAM vengono messe in alto.
Nel frattempo, si dispone di altre cose: inizializzare i dati, annullare l'inizializzazione dei dati.
Quei 2 andane di memoria fare riferimento a variabili globali, che non si usano spesso
ma a volte se lo fai, finiscono anche lassù.
Poi ci sono alcune altre cose: variabili d'ambiente, che non passerà molto tempo,
ma poi 2 cose importanti che tornerà tutto il semestre,
stack e heap.
Così la maggior parte della memoria del computer è riservato durante l'esecuzione di un programma
per qualcosa chiamato la pila e qualcosa chiamato l'heap.
Non abbiamo intenzione di parlare del mucchio oggi, ma parleremo lo stack.
La pila è destinata a evocare la visuale dei vassoi pasto in sala da pranzo Mather Casa
o dovunque vi capita di essere in cui il personale di sala da pranzo pulirli ogni giorno,
li pila di sopra del piano in su,
e allo stesso modo, nella memoria, c'è questa idea di mettere qualcosa su una pila,
mettere qualcosa su una pila, mettere qualcosa su una pila.
E che cosa si intende con questo?
>> Facciamo zoom solo sulla metà inferiore di questo quadro, la RAM del computer,
di proporre quanto segue.
Si scopre che quando si esegue un programma come a.out o ciao -
qualunque sia il programma che hai scritto -
ancora una volta, quelli che 0 e 1 sono caricati dal disco rigido, che è stoccaggio a lungo termine,
vi rimane anche quando si tira la spina, caricato nella RAM.
RAM è più veloce di hard disk - è più piccolo hard disk -
ma è dove programmi in diretta mentre li stai eseguendo.
Così si fa doppio clic su un programma su un Mac o PC, è caricato dal disco rigido nella RAM.
Non appena viene caricata in RAM, il go 0 e 1 in alto modo,
il cosiddetto segmento di testo, ma poi non appena il programma viene avviato effettivamente in esecuzione,
la funzione principale si chiama, e principale, come abbiamo visto, ha spesso variabili locali,
e ha interi e stringhe e caratteri e simili.
Così, se il programma che hai scritto o il programma che avete fatto doppio clic
utilizzato alcune variabili all'interno del principale,
finiscono nella parte inferiore del tuo stack di memoria, per così dire.
Più concretamente, cosa significa questo in realtà significa?
Questo significa solo che se stavamo per numero i byte di RAM nel computer,
notare che questo potrebbe essere il numero di byte 0, questo potrebbe essere il numero di byte 1, 2, 3, 4, 5, 6,
tutta la strada fino a 2 miliardi sarebbe fin lassù in cima.
In altre parole, quando si parla di RAM o memoria in termini di byte,
significa solo che qualcuno ha deciso che a contare ciascuno di questi pezzi di memoria.
Così, quando avete bisogno di 32 bit per un int o avete bisogno di 8 bit per un char,
dove vanno a finire nella memoria?
>> Concettualmente, hanno appena finiscono in fondo a questa cosa chiamata stack.
Ma ciò che è interessante ora è quando principale chiama una funzione -
supponiamo che una funzione chiamata foo, solo un nome arbitrario -
ciò che accade è principale è in fondo a questa pila di memoria;
pippo ora è messo in cima principale in memoria.
Quindi tutte le variabili locali che pippo ha finiscono sorta di concettualmente superiori a quelli in main.
Se foo chiama un'altra funzione chiamata bar, le variabili finiscono qui.
Se la barra chiama qualcosa d'altro, qui, qui, qui.
Così che cosa è interessante l'esecuzione di un programma è che, come si chiamano funzioni
e come tali funzioni chiamare le funzioni e come tali funzioni chiamare funzioni,
si costruisce questa pila di funzioni in memoria.
E solo una volta restituisce una funzione si fa a iniziare a ricevere che la memoria indietro.
Quindi, uno dei modi più semplici per l'esecuzione di memoria in un programma per computer
è quello di scrivere funzioni che non restituiscono.
Così, per esempio, cerchiamo di dimostrare tanto con un programma creato appositamente per buggy.
Lasciatemi andare avanti e non # include,
int main (),
e ho intenzione di fare, mentre (2> 1), che probabilmente non cambierà mai su di noi,
e lasciami andare avanti ora e fare printf.
A dire il vero, che sta per essere meno visivamente interessante. Facciamolo.
Per int i = 0; i> 0 - facciamo questo errore - i + +.
E non printf qui. Vediamo in pratica quello che predicava.
Facciamo un metodo qui, coro vuoto, e diremo int i,
e poi ho intenzione di dire printf - no, facciamo questo più interessante.
Facciamo in realtà non stampa nulla. Diciamo solo fare questo: coro (i).
Bene. Quindi questo è bacato perché perché?
Sto facendo questo come vado perché il programma non fa niente di interesse.
>> Ma questo non è l'obiettivo.
L'obiettivo è quello di scrivere un programma la cui funzione principale fa che cosa, a quanto pare?
Chiama se stessa. E in realtà, non abbiamo bisogno del ciclo.
Facciamo anche semplificare questo proprio per non perdere di vista proprio il bug fondamentale.
Chiamate principali coro a cantare qualche coro,
poi ho fatto qualcosa di stupido e avevo chiamata coro coro
perché davo per scontato un altro stava per attuarlo forse,
e ora questo non ha intenzione di compilare ancora. Ho bisogno di fare ciò?
Ho bisogno del prototipo, ricorda.
Quindi ho bisogno di avere qui coro void (int i);
Così ora se vado qui - in realtà, cerchiamo di utilizzare la finestra più grande.
Andiamo avanti e fare coro.
L'uso di identificatore non dichiarato i.
Oh, che era stupido. Non abbiamo bisogno l'argomento. Diciamo solo fare questo.
Vorrei che aveva iniziato in questo modo. Sarebbe stato un programma molto più facile da scrivere.
Ecco. Ora andiamo verso la mia finestra di terminale, eseguire nuovamente Clang, e ci siamo.
E 'stato veramente veloce.
Che cosa realmente è successo, però?
Bene, ora mi aggiungere la riga di stampa in modo che possiamo vedere.
Lasciatemi dire printf ("Io sono qui") - nessuna variabile. Lasceremo così.
Permettetemi di fare eseguire nuovamente. Vorrei eseguire di nuovo coro.
E ... andiamo. Continua ad andare.
Per inciso, perché non è ancora caduto?
L'errore di segmentazione successo super veloce prima.
[Risposta degli studenti incomprensibile] >> Esattamente. Quindi, ci vuole tempo per la stampa, giusto?
Ci vuole solo più lavoro da parte del computer.
Ed eccolo lì: Segmentation fault.
>> Quindi, notare quanto i programmi veloci correre.
Se non si sta stampando nulla, super veloce.
Ma abbiamo ancora ottenuto questo errore di segmentazione, perché quello che stava accadendo?
Se si pensa a come la memoria del computer è disposto,
questo sembra essere principale, ma qui facciamo solo chiamare questo coro, e chiama questo coro.
E ora se lo faccio mia estetica a destra, questo è solo andare a dire coro, coro, coro,
coro, coro, coro, coro, fino alla nausea, e alla fine, che cosa succederà?
Se l'immagine grande, letteralmente, è questo, quello che succede solo concettualmente?
I sovraccarichi di stack del mucchio.
O, peggio, basta invaso tutto, compreso il segmento di testo,
che è il 0 e 1 che rappresentano il vostro programma.
In breve, questo è solo super, male super.
Il vostro programma è fuori controllo.
Stai usando la memoria modo più di quanto previsto
tutto a causa di un errore stupido in questo caso,
o in questo caso una funzione molto deliberatamente fatto stesso chiamante.
Ora, questo non è affatto male.
Le funzioni che si definiscono in realtà ha un grande potere quando lo si utilizza correttamente.
Non l'ho usato correttamente qui.
Quindi questo non è affatto male, ma il fatto che non ho mai veramente trattenermi chiamare
è una debolezza fondamentale di questo programma qui.
Allora, dove stiamo andando con tutto questo? Che cosa sta realmente accadendo?
Quando chiamo la funzione di incremento, come stavamo facendo in questi esempi,
Ho un valore come 1 che mi passa trovi
Passo in una copia del numero 1, quindi si verifica quanto segue.
Andiamo in esempio incremento, questo ragazzo proprio qui.
Ecco quello che succede.
Quando chiamo incremento e passare x, pittoricamente, quello che sta succedendo qui è questo.
>> Se ho il valore di 1 memorizzati qui e io in realtà chiamare incremento,
che ora è chiamato coro - l'iPad mi sta gettando via qui.
Chiamiamo questo incremento, e non sappiamo che cosa questa funzione successiva sarà.
Quindi, quello che succede è qui da qualche parte nel principale che ho un pezzo di memoria
che memorizza il numero 1.
Quando chiamo incremento, sto utilizzando un altro pezzo di memoria,
ma ora ho la copia del 1.
Quando ho incrementare tale valore, questo diventa 2,
ma poi cosa succede appena torna incremento?
Questa memoria appena viene restituito al sistema operativo,
il che significa che tutto quello che hai fatto è nulla di utile.
Il 1 che è stato originariamente contenuta nel principale è ancora effettivamente.
Allora, dove stiamo andando con questo?
Si scopre che nella memoria si dispone di questo back-to-back sequenza di byte
che si può mettere roba, e si scopre che abbiamo già visto qualcosa
che coinvolge mettendo le cose back to back to back to back.
Che cosa è una stringa in base a settimana 1 settimana 2 e adesso?
E 'solo un insieme di caratteri.
Così si scopre come si può mettere i numeri in memoria,
Allo stesso modo si può mettere i caratteri in memoria.
E una volta che si inizia personaggi mettendo in memoria back to back to back to back,
si scopre che con la più semplice delle cose come un ciclo for o un ciclo while,
siamo in grado di scorrere da sinistra a destra sopra i caratteri di una stringa
e iniziare a massaggiare in caratteri completamente diversi -
potrebbe diventare un b, b potrebbe diventare c -
in modo che alla fine, siamo in grado di prendere una frase in inglese che rende effettivamente senso
e convertire ciascuna di tali lettere una alla volta
a piedi attraverso la memoria del nostro computer da sinistra a destra per crittografare in realtà.
Quindi cerchiamo di prendere la nostra pausa di cinque minuti qui,
e quando torneremo, inizieremo questo processo di scrambling informazioni.
>> Bene.
Prima di immergersi in un po 'di queste cose e crittografico chiamato array,
fatemi pausa per tutte le domande, perché mi sento come se davvero specie di confusa
alcuni di questi argomenti. Quindi cerchiamo di correggerla se possiamo.
Abbiamo appena parlato di valori di ritorno, abbiamo parlato di argomenti,
e abbiamo parlato di questo concetto, che vedremo tornare nelle settimane a venire,
visualizzazione di memoria come un insieme di questi vassoi sovrapposti, per così dire,
dal basso in alto, in modo tale che ogni vassoio che viene messo in pila
rappresenta una funzione che è attualmente in fase di chiamata.
Hai ancora domande?
Vorrei fare una domanda qui.
Vorrei semplificare questo torna a quello che era prima che alcuni dei nostri precedenti Q & A.
Il fatto che l'incremento ha parentesi aperta, il numero int, chiusa parentesi -
cosa numero int rappresenta?
[Studente] Un argomento. Un argomento >>. Va bene. Ma che cosa è un argomento?
[Risposta degli studenti incomprensibile] >> Che cos'è? >> [Studente] Qualcosa che si passa trovi
Ok, quindi qualcosa che si passa in E, più in generale, è solo l'ingresso.
Se si dovesse scrivere una funzione e lo scopo che la funzione nella vita
è quello di fare qualcosa di diverso ogni volta che lo si utilizza,
allora l'unico modo perché ciò avvenga davvero sembrerebbe essere quello di fornire con ingresso
in modo che possa fare qualcosa di diverso con il medesimo ogni volta.
>> Quindi è necessario specificare due cose quando una funzione riceve l'input.
È necessario specificare il nome che si vuole dare a quella di ingresso
esclusivamente per la vostra convenienza in modo che si può fare riferimento ad essa
nella funzione che ti sta scrivendo, come ho fatto qui in linea 32.
Ma è anche necessario specificarne il tipo, perché C è un linguaggio di programmazione
che richiede solo che se si vuole una variabile, è necessario dire al computer che tipo di dati si tratta,
in gran parte in modo che sappia quanti bit assegnare per tale variabile
perché potrebbe essere di 6 - mi dispiace, non sarà 6.
Esso può essere di 16, può essere 8, può essere 32, anche 64,
ma il computer ha bisogno di sapere.
Ora, l'int sulla sinistra rappresenta ciò, invece?
[Risposta degli studenti incomprensibile] >> Che cos'è? >> [Studente] Tipo di funzione.
Il tipo di una funzione e, più in particolare, il tipo di sua produzione. Giusto.
Così che la cosa in parentesi rappresenta il suo ingresso, eventualmente,
la cosa a sinistra rappresenta la sua uscita.
E in questo caso, a quanto pare incremento restituisce un int,
e così int è il tipo restituito da questa funzione.
Che cosa significa per il ritorno?
Letteralmente, si utilizza la parola chiave return e poi se quello che stanno tornando
alla destra della parola chiave è un numero intero,
allora quello è effettivamente coerente con ciò che abbiamo promesso.
Non si poteva fare qualcosa di simile - ciao, mondo - perché questa è una stringa.
>> Ovviamente, non è un numero intero.
Così, in breve, il peso è davvero su di noi, il programmatore, per essere precisi
da quello che stiamo tornando e poi effettivamente fare per restituirlo.
Il contesto qui è ora che la memoria del computer è un gigabyte, 2 gigabyte -
qualunque cosa - forse è più, forse è meno,
ma il computer lo vede come aventi diverse sezioni.
Qualcosa va laggiù, qualcosa va lassù,
cose diverse va nel mezzo, e oggi abbiamo appena inizia a raccontare la storia,
ma torneremo a questo nel corso del tempo.
Per ora, l'unico pezzo di memoria che veramente interessa è il segmento di testo
perché questo rappresenta solo il 0 e 1 che ha emesso Clang.
Così, quando si esegue un comando a tastiera come a.out
o con un doppio clic su un'icona in Mac OS o Windows,
il programma viene caricato dal disco rigido nella RAM
e si lasciò cadere nella parte superiore della RAM del computer, per così dire.
Nel frattempo, mentre il programma si avvia e principale viene chiamato
nel programma che hai scritto o il programma di Microsoft o Apple ha scritto,
una delle sue variabili locali finiscono laggiù in fondo alla memoria del computer.
Ma se le chiamate principali un'altra funzione che si ha variabili o argomenti, finiscono sopra di esso.
E se tale funzione chiama qualcosa, finiscono sopra, al di sopra, al di sopra di esso.
>> E solo una volta una funzione di esecuzione si è fatto la pila di vassoi, per così dire,
cominciano a farsi sempre più in basso.
E questo è quello che poi, in poche parole, spiega perché quando si chiama cubo
o si chiama incremento, si sta passando a una copia del valore.
E che cosa significa pittoricamente è che si sta letteralmente scrivendo il numero 1
in un'altra parte della memoria, che cambia 1 a 2 in caso di incremento
o ad un 8 nel caso di cubo e poi gettare via che la memoria
appena l'incremento o il ritorno del cubo di funzione. Domanda.
[Studente] dove memorizzate le variabili globali?
Le variabili globali sono memorizzate in quello che è attualmente chiamato i dati inizializzati o dati non inizializzati,
la differenza è se si dispone di una variabile globale e si assegna immediatamente un valore
con il segno di uguale, finisce in alto là,
e se hai appena detto x int, senza alcun valore, finisce leggermente inferiore nella RAM
semplicemente per convenzione.
Altre domande? Bene.
Quindi questa immagine tornerà, come abbiamo più più potente
con quello che si può fare con il computer,
ma per ora, diamo una breve introduzione alla crittografia,
un tipo specifico di crittografia che non risolve tutti i problemi del mondo
ma risolve alcuni di essi.
In questo caso qui, abbiamo qualcosa che si chiama crittografia a chiave segreta.
La crittografia a chiave segreta, come suggerisce il nome, deriva la sua sicurezza da un segreto.
>> Per esempio, se si erano di nuovo in grado di scuola e si passavano un po 'lettera d'amore segreta
per il ragazzo o la ragazza si stava schiacciando in poi, se si vuole passare che nota tra il pubblico,
probabilmente non avrebbe scritto una nota in inglese o qualunque sia la vostra lingua madre è.
Piuttosto, si potrebbe criptare o si potrebbe semplicemente inviare un messaggio di testo in questi giorni.
Ma si potrebbe effettivamente passare una nota in tutta la classe.
E per farlo in modo sicuro, in modo che i tuoi amici e l'insegnante
Non so quello che stai scrivendo, si potrebbe trovare con un algoritmo piuttosto semplice,
giovane anche se si potrebbe essere, a poco rimescolare le parole.
Così, invece di scrivere un si potrebbe scrivere b,
invece di b si potrebbe scrivere c,
invece di c si può scrivere d, e così via.
Oppure si potrebbe trovare una traduzione più sofisticato
di lettere alle lettere diverse.
Ma il fermo è il ragazzo o la ragazza a cui si sta inviando questa nota
ha bisogno di sapere qualcosa, che è ciò che, ovviamente? >> [Studente] Che cosa si sta inviando.
Qual è il tuo segreto, come quello che è che la mappatura tra le b, c e d s.
E 'solo l'aggiunta di 1 a ciascuna delle lettere per andare da A a B, da B a C?
E 'più complesso di quello?
>> Quindi tu e il tuo amore hanno bisogno di avere questa informazioni segrete,
ma c'è una specie di cattura-22 qui.
Se questa è la prima volta che si sta inviando questa lettera d'amore tramite la classe,
come è quel ragazzo o ragazza che va di sapere quale sia il segreto è ancora?
Così a chiave segreta di crittografia non risolve tutti i problemi del mondo,
e c'è in realtà un rapporto di qui che torneremo a verso la fine del semestre.
Allo stesso modo, non la maggior parte di noi conosce qualcuno che lavora, per esempio, su Amazon.com,
eppure molti di noi hanno probabilmente comprato roba su Amazon.com,
e ci è stato insegnato a pensare che queste transazioni e-commerce sono sicure.
L'URL https dice probabilmente, c'è forse l'icona di un piccolo lucchetto sciocco da qualche parte,
c'è un qualche tipo di crittografia proteggere i dati della carta di credito
tra te e Amazon.com.
Eppure, se la crittografia implica conoscere qualche segreto
eppure io non conosco nessuno su Amazon e ho certamente non disposti qualsiasi tipo di segreto
con qualcuno su Amazon, come è il mio computer o il mio browser facendo questo?
Sembra che vi sono altri tipi di crittografia del tutto che risolvere il problema.
Ma per oggi, ci concentreremo sulla semplice
dove è possibile organizzare in anticipo per conoscere qualche segreto
come +1 o un po 'di mapping tra un le b.
E il processo di crittografia comporta generalmente questo.
Hai un po 'di testo, illustrato qui a sinistra,
lo si esegue attraverso un qualche tipo di algoritmo o procedura di crittografia -
forse è solo una diventa b, b diventa c -
e poi si finisce con testo cifrato.
Nel frattempo, una volta che il tuo amore riceve questa nota segreta,
lui o lei deve poi decifrare generalmente le inversioni di algoritmo
in modo da recuperare il testo in chiaro.
Ci sono incarnazioni fisiche di questo.
>> Per esempio, questo è un piccolo anello decodificatore segreto,
e questo è un anello, nel senso che ci sono due quadranti qui.
Alla periferia al di fuori di questa cosa, ci sono le lettere dalla A alla Z,
anche se sono in ordine casuale,
e al suo interno, c'è in realtà alcuni numeri
in modo tale che con questo anello è possibile tipo di trasformare l'esterno ma non l'interno
al fine di allineare i numeri con lettere.
Da un film intitolato Una storia di Natale, vedrai che Ralphie poco
era così ansioso di capire quale messaggio segreto Little Orphan Annie era per lui
che era stata comunicata, credo, sotto forma di messaggi numerici su una scatola di cereali
e si doveva accumulare tutte le carte piccole che è venuto nella scatola di cereali,
si doveva spedirle in, si doveva tornare sul ring segreto decoder
in modo che si possa finalmente capire che cosa è la mappatura tra lettere e numeri
o lettere e lettere.
Come in un computer si può fare per l'attuazione o rappresentare le cose in questo modo?
Abbiamo bisogno di un modo di esprimere se stessi un po 'più flessibile
che le nostre variabili finora hanno permesso.
Abbiamo avuto interi, abbiamo avuto caratteri, abbiamo avuto float e double e pochi altri,
ma questi sono singoli pezzi di memoria che in realtà non ci permettono di esprimere le cose
come le parole e le frasi e frasi.
In effetti, abbiamo chiamato tali stringhe cose,
ma vi promettiamo che questo è davvero solo una semplificazione nella biblioteca CS50
che stiamo intenzione di staccare.
E così cominciamo a farlo qui.
Lasciatemi andare avanti e aprire un file -
tutti questi file sono disponibili, come di consueto, online - array.c chiamato
per risolvere un problema non correlato alle stringhe, ma che dipinge un quadro qui
di come si può utilizzare qualcosa chiamato un array.
>> Un array è un tipo di dati.
E 'un tipo di variabile di sorta che dispone di più tipi di dati più piccoli all'interno di esso
back to back to back to back.
Così, per esempio, se volessimo scrivere un piccolo programma che ti dà la media quiz
per un corso come 50 che ha 2 quiz,
si potrebbe facilmente scrivere questo programma basato anche su alcuni dei materiali della scorsa settimana
utilizzando GetInt e un paio di variabili: int quiz1, int quiz2.
Ed è abbastanza semplice.
E 'forse da 10, 20 righe di codice massimo di attuare un programma
che chiede all'utente di 2 punteggi di quiz e poi calcola la loro media
sommando insieme, dividendo per 2, e quindi la stampa dei risultati.
Si potrebbe probabilmente fare abbastanza facilmente che ora, dopo un certo numero di minuti.
Ma il problema è che supporre che il 50 aveva 3 o 4 quiz.
Supponiamo di voler utilizzare lo stesso programma per una classe che aveva settimanale quiz.
Pensate a una classe che ha quiz settimanale.
Se ci sono 16 o in modo da settimane in un semestre, ora si dispone di 16 variabili:
quiz1 int, int quiz2, quiz3 int, int quiz4.
Non appena si inizia a vedere questa ridondanza, il copia e incolla del codice,
si dovrebbe iniziare a farvi piacerebbe che ci fosse un modo migliore.
E per fortuna, a causa delle matrici che ci sia. Allora, facciamo questo.
In primo luogo, permettetemi di presentarvi una cosa molto semplice che non abbiamo usato finora,
ma lo vedrete tanto in tanto nel codice.
>> Questo è ciò che generalmente chiamato una costante.
Quindi è una costante, nel senso che non è mai tale valore cambia.
La convenzione umana durante la creazione di una costante
è quello di utilizzare tutte le lettere maiuscole solo in modo che si distingue sul serio nel codice,
e la parola chiave speciale che si utilizza è in C # define.
Così diciamo # define, poi uno spazio, quindi la parola che si desidera utilizzare per il nome della costante di
e quindi il valore della costante.
Si noti che questo è diverso da assegnare qualcosa a una variabile.
Non c'è segno di uguale, non c'è punto e virgola.
Questo è ciò che è noto come una direttiva del preprocessore,
ma su questo un'altra volta.
Per ora, questo crea un valore immutabile chiamato QUIZ
il cui valore numerico effettivo è 2.
Quindi, ovunque compaia QUIZZES, quiz, quiz in questo file,
questo è solo il numero 2.
Se guardo principale ora, vediamo come funziona.
In primo luogo sembra un po 'criptico, ma è tutta roba da settimana 1.
Chiedi l'utente per i gradi. Come possiamo fare questo?
In linea 22 - questo è davvero la parte succosa - dichiaro un galleggiante
ma non solo un singolo galleggiante. Sto dichiarando, anzi, una serie di valori a virgola mobile.
Tale variabile sta per essere chiamato gradi, come implicito qui,
ma l'unico pezzo di nuova sintassi allora sono queste parentesi quadre.
Il fatto che io ho detto voti float e poi parentesi aperta e poi un numero -
notare se si tratta di una costante è proprio come abbiamo fatto questo -
questo vuol dire, "Hey computer, dammi 2 galleggianti e andiamo insieme chiamarli gradi."
>> Questo è in contrasto con un processo molto più noioso come questo: float grade1;
galleggiare grade2, e così via.
Quindi un array ci permette di attuare questa idea, ma molto meno disordinato,
in modo tale che possiamo scrivere 1 riga di codice invece di, diciamo, 16 per un 16-settimana semestre.
Non volevo a livello di codice 2, perché se si pensa di questo ora logicamente,
supponiamo che il prossimo anno CS50 cambia di 3 quiz invece
e ho avuto il numero 2 qui, ho avuto il numero 2 qui,
Ho avuto il numero 2 qui, il numero 2 qui.
Diventa molto noioso e molto facile da avvitare
e per cambiare accidentalmente 1 valore a 3 e perdere un altro valore di 2.
Quindi ho intenzione di astratto invece questa distanza e utilizzare questa costante che,
Come suggerisce il nome, cambia mai.
E ora non importa se abbiamo diversi quiz quest'anno o il prossimo,
Devo solo cambiare in un posto qui in alto.
Ecco, questo è tutto un costante.
Nel frattempo, la nuova funzionalità concettuale è quella di una matrice.
Così le parentesi quadre mi danno questo molti carri allegorici e mi permette di chiamarli collettivamente gradi qui.
Così ora vediamo che cosa ho intenzione di fare.
Qui nella riga 24 è l'inizio di un ciclo.
>> Questo è davvero niente di speciale. E 'solo con QUIZ invece di un hard-coded numero.
Ma non c'è nulla di diverso ci intellettualmente dalla settimana scorsa.
Questo è solo printf, così printf ("Quiz #% d di% d:")
perché io voglio solo stampare darmi quiz numero 1 di 2 e poi 2 di 2.
Quindi questa è una cosa puramente estetica.
Ma la parte interessante è ora in linea 27.
Al fine di compilare uno dei due segnaposto con un valore a virgola mobile,
di nuovo utilizzare le parentesi quadre.
In questo caso, sto usando io, perché questo ciclo for è iniziata con i pari che valore, a quanto pare?
[Studente] 0. >> [Malan] 0.
Quindi, alla prima iterazione di questo ciclo, è come se ho scritto questo nel codice,
ma sulla seconda iterazione di questo ciclo, è come se Ho scritto questo nel mio codice.
Ma il fatto che sto usando una variabile è perfetto, perché, come suggerisce il nome,
sta variando il suo valore ad ogni iterazione,
così sto compilando questa matrice un punto alla volta.
Che cosa significa questo array assomiglia?
La ragione per cui ho disegnato il rettangolo super semplice sullo schermo qui prima era per questo motivo.
Un array è solo un pezzo di memoria seguito da un altro pezzo di memoria
seguito da un altro pezzo di memoria e così via.
Quindi, se la mia matrice è di dimensione 2 in questo caso qui, tutto quello che avrebbe fatto
digitando il mio punteggio quiz piace qui - ho preso 100 su questo e poi ho avuto un 99 su questo -
allora questa memoria potrebbe anche non essere usato perché ho chiesto solo il computer
per una matrice di dimensione 2.
Queste piazze sono ancora lì, giusto?
Hai ancora 2 gigabyte di RAM, anche se si sta solo chiedendo 2 galleggianti.
Così l'idea che sta dietro gli array è che il computer richiede solo un pezzo di memoria
e ripartisce poi pezzi più piccoli back to back to back to back.
E così questo è tutto un array è.
>> E 'un pezzo contiguo di memoria interna di cui si possono mettere le cose.
Questo succede a fare allora solo alcuni aritmetica noioso.
Se scorrere verso il basso qui, questo è dove ho poi scorrere l'array.
Io vengo con la somma di tutti i valori nella matrice,
e poi usare la funzione da queste parti per fare realmente la somma divisa per quiz.
Ma permettetemi di salutare la mia mano in quella come una sorta di aritmetica sufficiente per ora.
Ma tutto quello che sta facendo per me, in ultima analisi, sta calcolando una media.
Quindi, primo quiz più quiz secondo diviso per 2 e poi stampare come un int.
Ma andiamo ora transizione verso un esempio diverso chiamato stringa1,
che dipinge un quadro simile, ma con le stringhe.
Lasciatemi andare avanti e semplificare questo solo per un momento.
Perdonate il rientro per ora.
Del bando nella riga 19 di questo esempio, ho una stringa dall'utente.
Ma notate quello che sto facendo in prossima linee 22 in poi.
In realtà sto iterando da i fino a - e questo è un nuovo trucco - strlen, lunghezza della stringa.
Questa è una funzione che viene fornito con C che, se si passa una stringa,
ti dice quanti caratteri sono in quella stringa. Questo è tutto.
E il fatto che si tratta di strlen invece di lunghezza della stringa è solo perché è più succinto.
Trenta anni fa, la gente amava scrivere le cose nel modo più succinto possibile,
così abbiamo mantenuto tale convenzione qui.
i + + significa solo incrementare i in ogni iterazione.
E ora notare questo, che è davvero interessante.
In linea 24, dico, "Computer, dammi un carattere, 8 bit, e lo chiamano c."
Ma che cosa è questo sul lato destro dicendo?
In inglese, che cosa rappresenta?
[Studente] Il primo carattere della matrice.
Esattamente. Dammi il primo carattere della matrice.
O, più in generale, mi danno il carattere i-esimo nella matrice.
E rendo conto che è importante ora che, come gli informatici,
stiamo in realtà a contare da 0.
>> Non hanno la facoltà ora di iniziare a fare questo.
Ora ti devi comportare in linea con le aspettative del computer e contare da 0
perché [0] sta per essere il primo carattere di una stringa,
[1] sarà il secondo, [2] sarà il terzo, e così via.
Quindi questo programma, se lo compila, questo è ancora stringa1, in modo da rendere stringa1,
e ora ho eseguito stringa1 nella mia finestra di terminale.
E 'in attesa di input, così ho intenzione di scrivere in David, Invio,
e ora la stampa David tutto su linee diverse, perché avviso quello che sto facendo.
Sto stampando un carattere alla volta.
Non entreremo nei dettagli oggi su questo, ma ho cancellato poco fa questo controllo qui.
Si scopre che se l'utente si comporta male,, contraddittorio, o semplicemente confusi
si può effettivamente non riescono a dare una stringa di una certa lunghezza.
Se si preme il tasto sbagliato sulla tastiera, si potrebbe dare nessuna stringa a tutti,
o se siete maligni, si potrebbe cercare di incollare merita una gigabyte di un saggio
per riempire questa stringa, e se il computer esaurisce la memoria,
si scopre che stiamo andando a recuperare questo valore speciale chiamato NULL.
Quindi, per ora, è sufficiente sapere che c'è questo valore speciale chiamato NULL
che ci permetterà di controllare quando siamo di memoria, tra le altre cose.
Ma se apro adesso stringa2, si noti una differenza qui.
Si noti una differenza qui con stringa2.
Con stringa2, questo ciclo for è un po 'diverso.
>> Mi permette di cancellare i valori null in modo che si possa parlare di quelli un'altra volta.
Cosa c'è di diverso il ciclo for questa volta?
Posso tornare all'esempio precedente.
Ecco, questo è la versione 2, questa è la versione 1. 1, 2.
1, 2.
La chiamata strlen è dove?
E 'nella prima parte del ciclo for.
Ogni pensiero sul motivo per cui sto facendo questo? Gia '.
[Studente] Quindi non si chiama la funzione ogni volta.
[Malan] Quindi non chiamare la funzione ogni volta. Esattamente.
Ricordiamo da cicli for che sono super semplice
una volta che si ordina di capire che questo è l'inizializzazione, la condizione, e l'aggiornamento.
Il problema è che la condizione si verifica su ogni iterazione del ciclo.
E così, in questo esempio qui, ciò che è male per il fatto che questa è la mia condizione?
[Studente] Tu stai chiamando strlen.
[Malan] Tu stai chiamando strlen ancora e ancora e ancora.
Ma una volta che ho scritto a David, la lunghezza di tale stringa è 5,
e non cambierà ad ogni iterazione del ciclo
poiché la stringa è ancora D-a-v-i-d.
Quindi questo è un accenno a quello che sta per diventare un 'idea sempre più importante
conosciuta come una decisione di progettazione in cui semplicemente non ha il computer a fare lavoro inutile.
>> Proprio come in anteprima pset2, pset2 nella versione standard
sta andando a sfidare di implementare effettivamente un certo numero di cifre,
un certo numero di algoritmi di crittografia, in modo che è possibile sia crittografare
e decifrare i messaggi segreti molto simile al Ralphie lì decodificato.
Nell'edizione hacker di pset2, abbiamo intenzione di andare un po 'oltre.
Stiamo andando a portata di mano è un file da un sistema informatico attuale
che contiene un sacco di nomi utente e password criptate reali,
e la sfida per l'edizione pirata sta per essere a rompere le password
e capire cos'è la crittografia o quale segreto è stato utilizzato per generare effettivamente le password.
E abbiamo intenzione di farlo utilizzando una nuova funzionalità di C
che io ti do solo un demo di nota come argomenti della riga di comando.
Si scopre, come alcuni di voi avranno visto in sezione o nei libri di testo,
principale non sempre deve essere vuoto tra parentesi.
Si scopre che principale può anche essere scritto in questo modo, con due argomenti,
argc e argv, dove argc è il numero di parole
di digitare dopo il nome del programma sulla riga di comando
e argv sono le parole reali.
E come le parentesi quadre ci suggeriscono, argv è apparentemente un array.
E 'intenzione di essere una stringa dopo una stringa dopo una stringa in memoria.
>> Quindi quello che sta andando ad essere in grado di fare a partire da pset 2 è qualcosa di simile a questo.
Se faccio argv1, che è un esempio torneremo a il Lunedi, ed eseguirlo,
notare che non sembra di fare nulla ancora.
Essa si limita a stampare il suo nome.
Ma se io dico addio di classe, si noti che il programma scorre apparentemente
su ciascuna delle parole che sono state digitate al prompt.
E i mezzi con cui si avrà accesso alle parole che l'utente ha digitato al prompt
è cambiando principale a partire da questo fine settimana da int main (void) a int main (argc, argv)
e così nascerà riga di comando argomenti.
E una volta che si ottiene veramente sofisticata di questo, sarete in grado di scrivere programmi molto trippy
come questa qui, che va al di là
alcune delle funzionalità che abbiamo fatto fino ad ora, ma tutti abbastanza potente.
>> Così lasceremo questo con questo sullo schermo, e ci vedremo il Lunedi.
>> [CS50.TV]