[Powered by Google Translate] [Semana 2, continuación]
[David J. Malan, Harvard University]
[Esta é CS50. - CS50.TV]
Todo ben. Este é CS50, e este é o fin de semana 2.
Se esperar a estar con fame volta a esta hora mañá,
sei que nós imos convocar coma un pequeno grupo mañá, xoves, 1:15 pm.
Hai esa URL aquí se desexa RSVP.
O espazo é limitado, polo tanto, por favor, Perdoando o formulario foi cuberto polo tempo que cubrir isto.
Outra URL, con todo, que pode ser de interese é ese.
En só preto de un mes, o curso vai ser facilitado
todo o máis amplamente por EDX, a través do cal as persoas na Internet será capaz de seguir,
implican no curso bastante activa, en realidade.
Eles van estar a usar o aparello CS50 e CS50 Discutir
e na maioría das varias ferramentas de software que xa veñen utilizando este semestre.
E unha das iniciativas que quere asumir como unha experiencia deste ano
é ver o que de contido que pode traducir
noutras linguas faladas e escritas.
Entón, se pode ter interese en participar neste proxecto
cal iremos proporcionar transcricións en inglés e subtítulos para conferencias do curso
e shorts e seminarios e seccións e similares,
se falar fluentemente ou escribir con fluidez outra lingua,
nós queremos involucrar vostede neste proxecto polo cal asume un ou máis dos vídeos,
traducilo las nunha lingua que coñece moi ben.
>> Para darlle un sentido de interface, non hai esa interface de usuario baseada na web
que nós imos usar que pode crear, esencialmente, unha interface de usuario como este.
Isto foi me ensinando uns Halloween atrás,
e no lado dereito alí negro ao lado destes selos de tempo,
vai ver as moitas cousas que saíron da miña boca aquel día,
e abaixo, será capaz de traducir a outra lingua
exactamente o que é o mapeamento entre, neste caso, inglés e, digamos, español.
Entón, é realmente unha ferramenta moi agradable.
Pode retroceder e avanzar moi rapidamente con atallos de teclado.
Entón, se quere participar nesta experiencia e ter as súas palabras visto e lido
por potencialmente miles de persoas alí fóra, por favor, Sinto-se libre para participar.
Unha palabra sobre o gatinho de luns.
Para que non nos enviou unha mensaxe de moi asustado, facer entender que, como suxiren as horas de oficina
e como seccións suxire, o deseño do curso é moi
ter alumnos a colaborar e falando para traballar con conxuntos de problemas
e problemas xuntos, e realmente a liña só vén para abaixo,
novo, o traballo que, en última análise presentar debe ser o seu propio.
E así, sinceramente, en horario de oficina é totalmente normal,
É totalmente de esperar mesmo, para estar falando con algún amigo ao seu lado.
>> Se el ou ela está loitando con algún tema e é como,
"Oh, así, deixe-me dar-lle un reflexo dalgunha liña de código que escribín", que é bo,
o que pasa, e iso é moi favorable, creo que, co proceso de aprendizaxe.
Onde a liña está cruzada é cando a cabeza é unha especie de inclinada aquí para segundo demasiadas
ou minutos para que realmente ser só unha oportunidade de desbloqueo para o seu amigo,
e, por suposto, cando as cousas están trocadas por correo electrónico e Dropbox e afíns,
alí tamén é a liña.
Entón, por todos os medios sentirse cómodo e sentirse estimular a falar cos amigos
e compañeiros sobre serie de exercicios e máis e só entender que o que finalmente presentar
realmente debe ser o produto da súa creación e non outra persoa.
E así un dos problemas específicos de dominio para pset2,
que sairá mañá á noite tarde, e mergullo no mundo da criptografía,
Que é a arte de cifrado ou codificación da información,
e esta última instancia, para o mundo da seguridade.
Agora, a seguridade para a maioría de nós ven en forma de mecanismos moi mundanas.
Todos temos nomes de usuarios e contrasinais,
e todos temos nomes de usuarios e contrasinais moi malas, máis probable.
>> Se o teu contrasinal é o mesmo en varios sitios, que probablemente non é a mellor idea,
como discutir cara finais do semestre.
Se o teu contrasinal está escrito nunha nota - non é broma - no seu monitor,
que tamén non é necesariamente o mellor proxecto, pero un fenómeno bastante común.
E se non está a usar cifrado para cifrar as súas claves,
son particularmente vulnerables.
Entón, se pensas que está a ser super intelixente por un documento de Word oculta
en algún lugar no seu disco duro que ten todas as súas claves
pero é en unha carpeta que ninguén vai buscar, iso non é un mecanismo moi seguro.
E entón o que pset2 ha introducir e esta arte de cifrado
e loitando información para que cousas como claves son as máis seguras.
O contexto aquí é que, con datos inseguros
vén unha oportunidade de criptografía-lo e para embaralhar-lo.
E para que este, por exemplo, é un exemplo dunha mensaxe cifrada.
Isto realmente di algo en inglés, pero claramente non é totalmente obvia.
E imos pechar o círculo hoxe a separar o que esta mensaxe segredo aquí é.
Pero no mundo real dos ordenadores, as cousas nin sequera ollar como poden ser frases en inglés.
Por exemplo, este é o que se pode atopar nun estándar de Linux ou Mac ou ordenador UNIX
nun arquivo que foi outrora chamado de arquivo de contrasinal.
>> Hoxe en día, el foi trasladado para outros lugares.
Pero se ollar no lugar seguro nun sistema, verás que non só o seu nome de usuario
ou doutras persoas no sistema, pero vai ver unha versión cifrada da súa contrasinal.
De feito, a cripta palabra alí suxire que o material que se segue é cifrada,
e esta serie de letras aparentemente aleatorias e personaxes e números e así por diante
pode ser decifrada só por xeralmente sabendo algún segredo -
unha palabra secreta, un número secreto -
e así, de feito, a arte de cifrado, en última análise resúmese a confianza dalgún tipo
e saber algo que alguén non fai.
Entón, imos explorar iso en detalles un pouco máis hoxe e no pset para vir.
E agora unha palabra sobre pasa / fallo.
Especialmente como algúns de vós xa mergullou pset1, o aparello,
e un mundo moi novo para si mesmo, entender que as frustracións e confusión
e só a dificultades técnicas son moi de esperar,
especialmente coa pset primeiro, onde hai tanta cousa nova,
só familiarizarse co ls e CD e todos estes comandos arcanos
e un novo ambiente, e está separado do material real e propia programación.
Entón entendemos tamén que hai certamente expediente que existen como unha estrutura de apoio.
>> Seccións comezan o vindeiro domingo.
Pero o máis importante, se está sentindo só que este non é o mundo para ti,
entender que realmente levan tempo.
E se non fose por esa oportunidade hai anos para me dar un pase de clase / falla,
Honesta, eu nunca tería sequera puxo os pés na aula.
E pode cambiar isto ata, digamos, o luns quinta do curso,
por iso, se está no bordo agora, entender que, no canto de cabeza nalgunhas outras augas completamente,
que seguramente considerar só cambiando a aprobación / reprovação.
De novo, non hai realmente esta cultura aquí en Harvard de levar as cousas de aprobación / reprovação
xa que todo o mundo realmente quere alcanzar ou superar,
pero, francamente, esta é unha boa forma de probar algo fóra
que pode non ser familiar a vostede, e vai acabar facendo, na maioría dos casos, moi ben,
quizais a súa sorpresa.
E, en termos máis concretos, o que eu creo que pasa / fallo xeralmente fai,
especialmente no que se pode probar con pset0,
se pór en 10 horas, 15 horas, 25 horas nalgúns pset
e só está bater a cabeza contra a parede e está quedando super tarde da noite
pero tomou os 90% pset do camiño e simplemente non pode descubrir unha cousa,
pasa / falla realmente leva a bordo fora dunha clase como esta,
onde podes Ordenar dicir afortunadamente, "Ok, sei que non é perfecto,
pero eu traballei para caramba sobre iso, eu estou moi feliz con o lugar onde acabou "
e que van atender as expectativas de aprobación / reprovação.
Así que manter isto presente. Todo ben.
>> Entón, aqueles de vostedes que teñen se pretensado para usar a Universidade de Harvard Wi-Fi,
sei que hai un SSID CS50, unha conexión Wi-Fi, flotando
que pode ter mellor sorte para.
É un pouco irónico que o contrasinal que se quere tentar conectar a este
para as velocidades mellores - e déixenos saber se non é mellor - é 12345, todo o camiño ata o 8
8, porque é máis seguro que 5.
Entón, se precisa de contrasinal de acceso Wi-Fi, conectar-se sen fíos CS50 aquí, 12345678,
e puxo en CS50 Discutir se aínda ten problemas intermitentes de conectividade,
e imos deixar que os poderes que coñece a este espazo. Todo ben.
Entón, un teaser rápido, especialmente para aqueles de vostedes que son nenos ou nenas de fans de Apple de todo as cousas.
O que eu retirado uns anos era este ficheiro aquí, iUnlock.c,
só para o tipo de facer máis concreto e máis complexo
algúns dos programas máis básicos C que teño escrito.
Entón eu abri-lo arquivo, iUnlock.c. Está dispoñible na páxina de conferencias para hoxe.
No lado esquerdo podes ver unha longa lista de funcións.
Así, o suxeito que escribiu este escribiu unha morea de funcións, máis que de inicio.
El usou unha morea de bibliotecas aquí, e comezar a percorrer,
o que dicir realmente é, é o primeiro de crack, eu creo, para o iPhone orixinal.
>> Cando quería facer o Jailbreak do iPhone orixinal, o que significa untether os da AT & T
e realmente instalar un programa especial sobre el e facer as cousas que Apple non quere que as persoas fan,
alguén tivo tempo para descubrir exactamente como eles poderían explotar erros de software,
erros, erros en programas de Apple, e así naceu iUnlock.c -
que se compilou no seu ordenador e instala-lo en un iPhone
que foi conectado ao ordenador a través de, por exemplo, un cable USB,
isto lle daría privilexios administrativos ou raíz no seu iPhone
e deixalo facer practicamente o que quere.
E así houbo este gato fascinante e rato
entre a Apple eo resto do mundo, en particular no que, como moitas empresas,
tentar bloquear as súas cousas para abaixo así que só pode facer con el o que pretenden.
Pero, grazas a xente como esta e para a comprensión de detalles de baixo nivel -
e, neste caso, de programación C - e moitas das construcións coñecidas
que xa comezou a xogar con, vostede é capaz de realmente aproveitar o hardware
dunha maneira que pensar mellor e non necesariamente unha entidade corporativa.
Así, por exemplo, eu non teño idea do que todo isto está facendo,
GetVersion pero soa moi sinxelo,
e parece que esta é unha función que a persoa escribiu.
É preciso algún tipo de número enteiro como argumento, non retorna nada,
pero parece loop cun lazo e un aquí a condición, se a interrupción condición,
e dalgunha forma relacionado con números de versión desprazarse cara a abaixo,
aínda que moitas destas palabras clave vai ser novo.
E hai toda unha serie de funcións no aquí nunca vimos e quizais nunca máis ver
ao longo do semestre.
>> Ao final do día, el segue as mesmas regras e lóxica que vimos xogar ata agora.
Polo tanto, este é vello de máis para romper o seu iPhone ou 3s 4s 5S ou logo estes días,
pero sei que está todo moi derivado deste mundo que nos mergullou.
Imos dar un ollo a un exemplo un pouco máis simple:
este, só para quentar cunha sintaxe e tamén outro tipo de datos
que temos falado, pero realmente non teño visto en C.
Este é un ficheiro chamado positive1.c, e por os comentarios na parte superior,
este só esixe que o usuario facilite un número positivo.
Entón, é un exemplo de un loop do-tempo, o que é bo para os programas de usuario interactivas
onde cómpre dicir ao usuario para facer algo,
e se eles non cooperaren vostede gritar con eles ou rexeitar a súa entrada.
Caso en cuestión: Eu vou facer liñas de 19 a 24
sempre que o usuario non teña me deu un número positivo.
Este detalle aquí na liña 18, por que eu declarar n riba deste looping toda construción
en oposición á dereita ao lado da liña 22, onde realmente importan para n? Si
[Alumno] Alcance. >> Si, entón esa cuestión da eido.
E, en termos leigos, o que ámbito se refire?
Si >> [Resposta do alumno inaudível] >> Podes falar un pouco máis alto?
[Alumno] Onde podes acceder a esta variable. >> Perfecto.
Onde podes acceder a unha determinada variable.
E, xeralmente, a regra de ouro ata agora foi a de que o alcance dalgunhas variables
é definido polas claves máis recentes rizados que xa viu.
>> E por iso, neste caso, se eu cometín o erro de declarar n na liña 22, que a liña ía traballar.
Quere obter un int, e quere poñelas en que n variable na liña 22,
pero que liña de código que agora non teñen idea do que estou falando? >> [Alumno] 25.
[Malan] 25, e verifica-se 24, pero tamén porque, neste caso, está fóra das claves.
Entón, un pouco de problema, pero moi doado de resolver, pode declarar a variable
fóra da propia función.
Imos ver máis tarde hoxe pode ir un paso máis aló
e pode ata quedar un pouco preguiceiro.
E iso non é recomendado en xeral, pero pode ata ir con preguiza
e poñer unha variable global, por así dicir, e non dentro dunha función, e non dentro dun loop,
pero no propio arquivo, fóra de todas as funcións que escribiu, como eu fixen aquí en liña 15.
Este é xeralmente desaprovado, pero que esta é unha solución, por veces, a outros problemas,
como vai finalmente ver.
Entón, por agora, imos deixalo así, pero imos ver se podemos reescribir esa
só para comezar a expresar-nos un pouco diferente.
Este programa, só para quedar claro, é positive1.
Deixe-me ir á fronte e aquí na miña xanela de terminal facer positive1, Intro.
Compila ben. Vou correr positive1, prema Intro.
Eu esixo que me dea un número enteiro positivo. Eu vou dicir -1. Isto non funcionou.
0, 99. Que parece funcionar.
Quizais non a proba máis rigoroso, pero polo menos é un bo test de sanidade
que estamos no camiño correcto.
>> Entón, agora deixe-me ir adiante e abra a versión 2 do presente,
eo que é diferente xa?
El aplica a mesma cousa, pero o que está pulando fóra tan claramente distinto desta vez?
Este bool en verde. Destaca no verde, esta palabra clave coñecida como bool, que é un tipo de datos.
El non vén construído en todas as versións de C.
Debe incluír unha biblioteca específica.
No noso caso, eu incluída a biblioteca CS50 para que teñamos acceso a bool.
Pero, na liña 18, parece que temos un valor booleano aquí chamado agradecido.
Eu podería ter chamado este nada, pero eu chamei-lle grata
só para transmitir algún tipo de significado semántico.
Polo tanto, inicialmente na liña 18, eu non son aparentemente grata
porque o valor booleano grata é inicializar como false na liña 18.
E entón parece que eu fixen aquí en liñas de 21 a 23
é que eu teño só unha especie de reescrita miña lóxica.
Polo tanto, non funcionalmente diferente, pero na liña 22 agora comprobar que o int usuario proporcionou
é maior que 0, entón eu simplemente cambiar o valor de grata a verdade.
E por que eu faría iso? Porque, na liña 25, ao parecer, eu estou indo para comprobar unha condición.
Fai iso loop while grata é falsa.
Entón eu propuxen iso como unha alternativa á versión 1
porque é polo menos un pouco máis intuitivo, quizais, sexa un pouco máis fundamentada en inglés.
Entón faga o seguinte mentres non está grata ou agradecido mentres é falso.
E esta vez tamén eu, ao parecer, non se preocupan en lembrar o que o usuario introduciu
porque non hai ningún aviso n variable, polo tanto, en realidade, unha pequena mentira alí.
>> Funcionalmente, o programa é un pouco diferente, xa que chegar ao fondo da cuestión
porque eu non estou lembrando que n é.
Pero eu quería demostrar aquí tamén que aínda que vimos GetInt
e GetString a empregar no lado da man dereita de un sinal de igual ata agora
para que recordar o valor, tecnicamente, iso non é estrictamente necesario.
Se por calquera motivo vostede simplemente non lles importa para salvar o valor,
quere só comprobar o valor, observe que podemos simplemente escribir isto como GetInt,
aberto paren, paren preto.
Esta función devolverá un valor, como temos benvida a dicir.
Vai dar de volta un int.
E se pensas que mentalmente de isto acontecer,
cando inserir 99, GetInt retorna o número 99,
e así, conceptualmente, é coma se o meu código eran, en realidade iso.
Entón, se 99 é de feito maior que 0, entón grata se fai realidade,
despois a liña 25 realiza Ooh, estamos a facer porque eu son grata agora,
e na liña 26, nós simplemente dicir: "Grazas pola enteiro positivo!"
o que quere que estivese.
Agora imos facer azucre sintático lixeiro aquí, por así dicir.
Imos ver se conseguimos limpar esa liña 25 con esta variante terceiro e último positive3.
>> Observe a única diferenza agora é que liña de código? >> [Alumno] 25. >> [Malan] Si, 25.
E nós non temos realmente visto este truco aínda, pero fixo ver o punto de exclamación o luns,
que denota o que? >> [Alumno] non. Non >> ou denegación.
Entón, ter un valor booleano e virar o seu valor.
Torna-se certo, o falso se fai certo.
Así, gustaríame propoñer, é ata un pouco máis intuitiva xeito de escribir o código
porque eu aínda arrincar grata a falsa, aínda facer o seguinte,
Eu define grata a verdade cando chegue a hora,
pero agora pode realmente só traducir este código verbalmente esquerda a dereita,
while (grato!);, porque o signo de admiración ou estrondo denota a noción de non,
Así, aínda que non grata.
Entón, de novo, non introduciron novos conceptos en si.
Nós conversas sobre booleanos atrás cando nós tocamos co scratch,
pero entendo agora podemos só comezar a escribir o noso código de moitas maneiras diferentes.
Así, especialmente no pset1 se é unha especie de loita para descubrir a forma de escribir algún programa,
probabilidades son que está con sorte, porque non pode haber ningún número de solucións
que pode ocorrer enriba.
Por exemplo, esta é só a 3, mesmo para o máis simple dos programas. Todo ben.
E agora lembrar o luns que deixou esta nota con valores de retorno.
Así, a primeira vez que escribiu nun programa que non só principal;
tamén ten a súa propia función personalizada que escribín aquí.
Así, na liña 31 a 34 eu apliquei unha función cubo.
Non é complexo. É só a * a * a neste caso.
Pero o que é importante sobre o que é que eu estou tendo entrada en forma de
e estou retornando saída baixo a forma dun * a * a.
Entón agora eu teño a capacidade, tanto como eu adoitaba facer prinf só,
chamar esta función chamando a función cubo.
>> E a función cubo ten algunha entrada, ea función cubo retorna algunha saída.
Por outra banda, printf só fixen algo.
El non devolveu algo que importaba, aínda que como un aparte non voltar un valor;
normalmente só ignore-lo.
Printf só fixen algo. El tiña un efecto colateral de impresión á pantalla.
En contraste aquí, temos a función de cubo, que en realidade volve algo.
Polo tanto, para aqueles familiarizados con este, que é unha idea moi sinxelo.
Pero, para os menos familiarizados coa idea de pasar entradas e saídas de volver,
imos tentar só algo simple super.
Alguén está cómodo chegando no escenario brevemente?
Ten que estar cómodo con unha cámara tamén. Si? Okay.
Cal é o seu nome? >> [Alumno] Ken. >> Ken. Todo ben. Ken, imos alí cara arriba.
Ken vai ser unha función do tipo aquí.
Imos adiante e facelo. Imos pegar un pouco de fantasía.
Pracer de coñece lo. Benvido ao centro do escenario. Todo ben.
Imos bater este botón aquí. Todo ben.
Entón aquí tes un cadro moderno,
eo que eu son é a función principal, por exemplo,
e eu non teño un iPad na man.
>> Eu realmente non me lembro como - Ben, eu non podo dicir iso.
Eu realmente non teño boa caligrafía,
e así, polo tanto, quero que imprimir algo na pantalla para min.
Eu estou sendo o programa principal, e eu vou ter que dicir isto
escribindo no meu cero polo e logo pasando-lle unha entrada.
Tan parvo que este exercicio é, a noción de funcións e chamar a unha función
e retornando dunha función en realidade se reduce a iso.
Estou principal, que acabo de escribir printf, algo entre comiñas na pantalla,
Estou executando este programa, e logo que printf é chamado,
é preciso un argumento ou un parámetro, por veces, entre comiñas dobres.
Aquí é que o argumento. Estou pasando para Ken.
El é unha caixa negra escrito un número de anos
que, ao parecer, só sabe como imprimir cousas na pantalla.
Entón executar.
Isto non é malo. Moi bo.
Entón, agora está feito Ken execución. Será que precisa me dar nada a cambio?
Non é que vimos ata agora.
Unha vez máis, printf fai realmente voltar un número, pero imos ignorar que, por agora
porque nunca usei. Entón é iso para Ken.
E agora principal asume o control do programa de novo
porque esa liña de código, printf, está feita a execución.
E nós imos sobre o noso camiño, executando as outras liñas están alí.
Entón, agora imos tratar un exemplo un pouco diferente.
Esta vez, aquí imos primeiro limpar a pantalla, e esta vez imos facer a función de cubagem,
pero esta vez, espero un valor de saída.
>> Entón, imos adiante e facelo.
Agora eu teño unha liña de código que se x recibe cubo de x.
A liña de código, recall, queda así: x = cubo (x);
Entón, como é que isto vai funcionar? Imos adiante e dar-lle unha pantalla branca de novo.
Eu vou escribir agora o valor de x,
que, neste momento pasa a ser, digamos, de 2 a mantelo simple.
Eu escribín nun anaco de papel o valor 2, que é o meu valor x.
Eu entregalo a Ken. >> E eu só escribir a resposta? >> Si, imos só escribir a resposta.
Okay. E agora ten que volver-me algo. Perfecto. Segue agradable.
Entón, agora me dá de volta o valor de 8, neste caso, eo que fago con el?
En realidade - imos ver, obter este dereito. O que eu vou facer con el?
Agora eu vou levar ese valor e, de feito, almacena-lo nos mesmos bits na memoria.
Pero repare que eu son o tipo de loita aquí.
Estou un pouco confuso, porque onde eu realmente escribir o valor de x,
porque o que eu acaba de facer é Ken fisicamente man dun anaco de papel que tiña o valor 2,
que era x, e, de feito, iso é precisamente o que pasou.
Así, verifícase que cando chamar a función e pasar un argumento
como Ola, mundo ou pasa un argumento como 2,
xeralmente, está pasando unha copia do argumento.
E como eu escribín o número 2 aquí e entregouna a Ken,
iso debe significar que eu aínda teño unha copia do valor de dous en algún lugar
porque en realidade, agora que eu comece de novo o valor 8, eu teño volver na memoria RAM
e realmente escribir 8, onde unha vez eu tiven o número 2.
Así, visualmente, lembre-se esta noción de paso en, literalmente, unha copia do valor.
>> Ken fai a súa cousa, me dá de volta algo - neste caso un valor como 8 -
e entón eu teño que facer algo con ese valor, se eu queira mantelo por preto.
Entón, todo isto vai volver a ser todo moi familiar antes de tempo.
Moitas grazas por esta demo aquí, Ken. [Aplausos]
Moi ben feito.
Imos ver como é que, en última análise relaciónase con algunhas das funcións de chamada que estamos facendo aquí.
Deixe-me ir adiante e nos traer de volta ao exemplo cubagem aquí.
Teña en conta que, se queremos realmente comezar a tomar isto aínda máis,
imos ter que estar atentos ao feito de que o número x que está a ser pasado aquí
é diferente do que realmente está a ser pasado para a función.
Entón, de novo, este pase por copia vai tornar-se bastante pertinente en só un momento.
Imos dar un ollo a algo que non funciona moi ben certo aínda.
Eu estou indo a ir adiante e abrir un exemplo de buggy terceiro, que é fallo por natureza,
e chámase buggy3 e implementa unha función de cambio.
Aquí temos unha función principal que X e Y arbitrariamente inicializar con 1 e 2, respectivamente.
Nós poderiamos usar GetInt, pero só precisa dun simple exercicio
entón é codificado como 1 e 2.
Nas liñas 21 e 22, que, ao parecer, imprimir X e Y, 1 por liña.
A continuación, na liña 23, eu afirmo que estou cambiando estes valores, punto, punto, punto.
Eu aparentemente chamar unha función na liña 24 intercambio de chamada que leva dous argumentos.
É totalmente lexítimo para funcións de tomar dous argumentos. Vimos printf facelo xa.
>> Entón intercambio aparentemente leva x e y, e como o propio nome suxire,
Espero que vai cambiar estes dous valores.
Entón eu reclamar na liña 25 "trocados!" e I reimprimir X e Y
baixo a suposición de que realmente foron trocados.
Pero se realmente executar este programa - deixe-me abrir unha xanela de terminal,
deixe-me facer buggy3 - como o nome suxire, iso non vai acabar ben
porque cando prema Intro, observe que x é 1, y é 2,
e aínda, ao final do programa, eles aínda son, de feito, o mesmo.
Así, con base na demostración só agora con Ken, o que está realmente a suceder?
Imos mergullo esta función de intercambio. É super curto. É só unhas liñas de código longo.
Pero cal é o problema fundamental, baseado na historia sinxela contada aquí con Ken?
Por que o intercambio de partido?
[Alumno] Está almacenando a unha copia, e non variable.
Exactamente. Estamos almacenando a unha copia, e non a propia variable.
Noutras palabras, cambio aparentemente leva dous argumentos, un int,
e é chamada arbitrariamente a e b,
e aquí eu pase en X e Y, que son, respectivamente, 1 e 2,
pero eu non estou literalmente pasando x, eu non estou literalmente pasando y,
Estou pasando unha copia de X e unha copia do y.
É case como se copiado e pegado a cambio
os valores que quere que realmente manipular.
Entón, se ese é o caso, cando o inicio do programa executando a liña 35, entón 36,
cando chegar á liña 37, neste punto da historia, o que é o valor dunha?
Neste punto da historia, liña 37, que é o valor dun, neste punto? >> [Alumno] 1.
[Malan] Debe ser só un, non, porque x foi pasado como o primeiro argumento,
e esta función só arbitrariamente está chamando o seu primeiro argumento un.
Do mesmo xeito é y segundo argumento, e é só arbitrariamente chamar a b segundo argumento.
>> Esta dicotomía é realmente moi sinxelo explicou. Pense sobre iso.
Ningún de nós coñeceu a persoa que escribiu printf,
así, certamente, el ou ela non ten idea do que as nosas variables 30 anos máis tarde vai ser chamado.
Entón, ten que haber unha distinción entre o que chama de variables en funcións que está escribindo
e que vostedes chaman de variables en funcións que está chamando ou usar.
Polo tanto, noutras palabras, eu escribín os meus variables como X e Y,
pero se alguén tiña escrito a función de intercambio, el ou ela certamente non sabería
o que os meus variables van ser chamados,
para entender que é por iso que ten esta dualidade de nomes.
Tecnicamente, eu podería facelo por coincidencia,
pero eles aínda ser pasado como copias.
Sería só pura coincidencia esteticamente se esa persoa que escribiu cambio
usara os mesmos nomes.
Polo tanto, neste punto da historia, liña 37, un é 1, B e 2, e agora debo proceder para trocalos.
Primeiro de todo, deixe-me realmente facelo moito máis simple.
Eu non sei o que estas tres liñas de código foron facendo.
Deixe-me facer isto: b = a, a = b; feito.
Por que iso é roto, loxicamente?
É o tipo de cousa intuitiva, non?
Así, torna-se e ab b torna-se,
pero o problema é que, logo que liña 37 é executado, o que é o valor a e b?
O mesmo, 1, porque derrotado, por así dicir, vostede cambiou b para igualar un.
Polo tanto, unha vez liña 37 foi executado, iso é óptimo, agora tes dúas copias do número 1
dentro desta función, así entón cando di na liña 38 a = b,
está ferrado tipo de porque está só a asignación de 1 a 1.
Vostede medio que perdín o valor que se preocupaba.
Así, na versión orixinal do presente, observe o que eu fixen.
Eu en vez tivo unha terceira liña de código que era así.
Eu declaro dunha variable temporal.
>> Tmp é un nome moi común para unha variable temporal, e é un int
porque ten que coincidir co que quero facer unha copia.
Eu gardar copia dun dentro tmp, entón cando liña 37 foi executado,
o valor de a é - verificación de sanidade rápido - 1, o valor de b é 2,
e o valor do tmp tamén é 1.
Entón agora eu executar a liña 38.
Unha vez liña 38 é executado, unha toma o valor de b. B foi de 2, así que unha é agora 2.
Así, neste punto da historia, a é 2, B e 2 e tmp é 1,
agora, loxicamente, podemos só valor tmp plop de en B e estamos a facer.
Entón nós decidimos este problema.
Desafortunadamente, cando executar este programa baixo esta forma, que en realidade non cambiar os valores.
Pero, para ser claro, por que?
Resolve o problema lóxico dun momento atrás,
pero, de novo, se eu executar este programa, X e Y permanecen inalterados
ata o final da execución do programa.
[Comentario do estudante inaudível] >> Non devolveu nada, entón iso é verdade.
Pero acontece que hai un pouco de un problema aquí, porque, ata agora,
a única cousa que teño sido capaz de volver é unha cousa, e esta é unha restrición de C.
Só podes volver realmente un valor, caso en que eu son o tipo de preso aquí
porque eu podería voltar o novo valor de x ou eu podería voltar o novo valor de y,
pero quero tanto de volta.
Entón, retornando non é a solución simple aquí.
Pero o problema fundamental é por que? O que realmente trocados?
[Estudante] a e b. >> A e B.
Pero a e b son copias de x e y, o que significa que só fixo todo este traballo,
que acabamos pasado 3 minutos falando sobre a función de intercambio e todos os 3 destas variables,
e iso é óptimo, perfectamente correcto en illamento,
pero e ámbito de b é só nestas liñas aquí.
>> Entón, como un loop, se declara un enteiro i dentro do loop for,
Do mesmo xeito, se está declarando dentro a e b dunha función que escribiu,
son só válido dentro desa función, o que significa que, unha vez que intercambio é feito executando
e imos da liña 24 para a liña 25, x e y non foron alteradas de forma algunha.
Vostede desperdiçar só unha morea de tempo a cambio de copias de variables.
Así, verifícase que a solución para iso é, en realidade, non obvia.
Non é ben abondo para voltar valores, porque só podemos voltar un valor,
e eu realmente quero cambiar x e y, ao mesmo tempo,
entón nós imos ter que volver a este.
Pero, por agora, entender que a cuestión fundamentalmente derivada do feito de que a e b son copias
e eles están no seu propio ámbito.
Imos tentar solucionar isto de algunha maneira.
Deixe-me realmente rolar de volta aquí e abrir-se, por exemplo, unha cuarta variante deste, buggy4.
Que tal isto?
Este é un problema semellante, pero máis sinxelo de ollar antes de tomar unha facada en resolver-lo.
Este programa é chamado de incremento, e, ao parecer, arrincar un número enteiro de 1 x na liña 18.
Eu, entón, dicir que x é 1, entón eu reclamar "incrementando ..."
Eu, entón, chamar incremento, pero, a continuación, as liñas 22 e 23, eu afirmo que foi incrementado,
Eu reivindico x agora que quere que sexa - 2, probabelmente -, pero este programa é buggy.
Cal é o problema?
Si >> [Resposta do alumno inaudível] >> Exactamente.
Entón x foi declarada, obviamente, na liña 18.
Que está dentro de chaves principais.
Polo tanto, a resposta simple é que mentres x existe aquí,
non existe na liña 32, así que este programa realmente non vai nin compilar.
O compilador cando intento compilar este código vai berrar comigo
sobre algúns identificador non declarado ou algo nese sentido. En realidade, imos tratar.
Esta é facer buggy4. Non é.
Uso de 'x' identificador non declarado na liña 32.
E, de feito, imos ser máis explícito aquí hoxe para que iso sexa útil
en horario de oficina e na casa.
>> Teña en conta que é un pouco enigmática escritura.
Pero o feito de que Clang ten chamado, dicindo buggy4.c: 32:5, é realmente útil.
Isto significa que o erro está na liña 32 na posición de carácter 5.
Entón, 1, 2, 3, 4, 5. Isto é, de feito, onde está o problema.
E, tamén, tamén, ter presente á hora de oficina e na casa, teño sorte aquí.
Eu teño un erro. Vai ser relativamente doado de corrixir.
Pero se recibir unha pantalla chea de mensaxes de erro esmagadora,
novo entender que o máis inferior pode ser só un síntoma da dun superior.
Entón, sempre perseguir os seus erros, de arriba para abaixo
porque non pode ser só un efecto en cadea
que está suxerindo que ten problemas de xeito máis que realmente fai.
Entón, como poderiamos resolver iso o meu obxectivo é incrementar x? >> [Alumno] Facer x global.
Ok, entón podemos facer x global.
Imos incorporarse a ligazón que eu avisei sobre a anterior, pero que demo, só necesitamos unha solución rápida,
entón imos só dicir int x aquí. Isto fai x global.
Entón, agora principal ten acceso a el e incremento ten acceso a el,
e entón deixe-me ir adiante e compile iso agora.
Fai buggy4, Intro. Parece compilar.
Imos correr buggy4. E parece realmente funciona.
Esta é unha desas cousas que fan o que eu digo, non o que fago,
como eu acaba de facer aquí, porque, en xeral,
Os nosos programas van ser moito máis interesante e máis que iso,
e se a súa solución para os problemas da vida é só poñer todas as variables na parte superior do seu arquivo,
moi rapidamente que os programas están terriblemente difícil de xestionar.
Está máis difícil de pensar en novos nomes de variables,
está máis difícil de entender o que está facendo o que variable,
e así, en xeral, isto non é unha boa solución.
Entón, imos facelo mellor.
Nós non queremos usar unha variable global aquí.
>> Eu quero incrementar x, para que eu puidese obviamente -
ao final do día, este é un tipo de historia boba, porque acabamos de facer iso -
pero se eu non sabía que o operador ou eu non tiña permiso para cambia-lo no principal en si,
de que outra forma eu podería aplicar Ken aquí esta vez non para cubo, pero para incrementar?
¿Como cambiar a cousa aquí? Si
[Alumno] Paso en x e logo voltar [inaudível] >> Ok, bo.
Entón, por que non eu pasar x e en seguida, en vez de devolve-lo,
Por que non só me volver x + 1.
Máis algunhas cousas teñen que cambiar aquí. Eu estou no camiño correcto.
O que máis me teño para axustar? Alguén. Si
[Resposta do alumno inaudível]
Eu teño cambiar o tipo de retorno de incremento porque non está baleiro.
Non significa nada baleiro está a ser devolto, pero claramente agora,
para iso ten que cambiar a - >> [alumno] int.
int para ser coherente co que realmente estou volvendo.
Agora outra cousa aínda é buggy aquí. Si
[Resposta do alumno inaudível] >> [Malan] Entón eu teño incrementar x?
[Resposta do alumno inaudível] >> [Malan] Ah, entón eu teño pasar x.
Entón eu teño que facer iso aquí. >> [Comentario do estudante inaudível]
[Malan] Entón o prototipo, eu teño que cambiar isto aquí.
Polo tanto, este ten que facer un int, este ten que facer -
hmm, realmente teño un erro aquí. Imos solucionar isto primeiro.
O que isto realmente debe ser? Ten que ser unha cousa int.
Podería ser X, pero, francamente, se comezar a chamar toda a súa x variables,
só pode ir cada vez menos clara cal é cal.
>> Entón imos escoller arbitrariamente unha convención de nomenclatura diferente para as miñas funcións de auxiliares,
as funcións que eu estou escribindo. Imos chamar-lle unha, ou podemos chamalo -
Imos chamalo de número ser aínda máis explícito.
Entón eu teño que devolver calquera que sexa o número máis 1,
e agora eu teño que cambiar unha cousa aquí e outra cousa aquí.
O que eu teño que cambiar en liña 21 en primeiro lugar? >> [Resposta do alumno inaudível]
[Malan] Eu teño que asignar a x. Eu non podo simplemente chamar de incremento (x).
Cómpre lembrar a resposta, cambiando o valor de x na parte esquerda.
E aínda que x é agora á esquerda e á dereita, que é totalmente ben
porque o lado dereito é executado primeiro, entón, é a cousa pulou na súa man esquerda -
x neste caso.
E entón, finalmente, este é un reparación doado agora.
Este debe só combinar o que hai alí embaixo, número int.
Entón, unha morea de cambios para unha función realmente estúpido
pero representativa de cousas que nós imos cada vez máis quere facer.
Entón faga buggy4. Eu estraguei todo en algún lugar.
Oh, meu Deus. Cinco erros nun programa de 6 liñas.
Entón, o que hai de malo en liña 18, o personaxe de 5?
Entón eu teño que declarar este int,.
Imos ver. Hai unha morea de outros erros.
Oh, meu Deus - 19, 18, 21 - pero, de novo, imos limpar a pantalla, L Control aquí,
e executa de novo Clang.
Entón, cinco problemas que en realidade é só unha.
Entón, agora imos realizar buggy4, Intro. Uf, X foi incrementado correctamente.
Todo ben. Calquera dúbida sobre como incrementar números? Si
[Pregunta estudante inaudível] >> Boa pregunta.
Como é que podo simplemente cambiar o número x eo programa vai saber inmediatamente?
>> Unha vez máis, pense nisto como esa abstracción.
Entón, se eu son de inicio e Ken e incremento, francamente, eu non me importa o Ken chama o seu iPad.
Eu non ligo para o que el chama de nada que teña que ver coa súa implementación desa función.
Este é un detalle de implementación que, de inicio, non ten que se preocupar.
E así simplemente cambiar consistente dentro da función - número aquí e número aquí -
é todo o que leva tanto tempo como eu recompilar.
É unha especie de sabor, se pensar que moitos de nós, aqueles con bolsas de condutor
que teñen conducido ou se mesmo conducido nun coche,
a maioría de nós non ten idea de como un coche funciona baixo o capo.
E, literalmente, se abrir o capó, a maioría de nós - eu incluído -
non están indo para realmente saber o que estamos mirando,
tipo de como pode se sentir con cousas como esta agora.
Pero nós realmente non se preocupe como o coche funciona,
non temos que coidar o que todos os bastóns e pistóns e os cables dentro do coche
están realmente facendo.
Polo tanto, algo así como o que vostedes chaman o pistón non importa aquí neste caso. Mesma idea.
Si >> [Cuestión estudante inaudível]
Se hai máis usos do momento XA variable atrás,
ti, programador, tería que cambiar todos os lugares.
Ou pode literalmente facer menú Arquivo, e en Buscar, Reemplazar - algo así -
pero vai ter que facer estas modificacións mesmo.
Ten que ser consistente. >> [Alumno] Se hai múltiples variables [inaudível]
A orde particular como aquí, se iso era int outro número? >> [Alumno] correcta.
[Malan] Yeah. Orde importa cando está chamando a función.
>> Entón, se eu estivese chamando incremento aquí con algo coma algo
hai un mapeamento directo.
A primeira variable, o que se chama, faise unha copia do primeiro argumento aquí.
Sentímolo. Isto non debe ser un paréntese.
O segundo argumento liñas anteriores co segundo. Así, a orde, si, importa. Todo ben.
Sentímolo. Tomei o camiño máis longo para chegar alí. Outras preguntas? Todo ben.
Entón imos ver se non podemos pintar unha imaxe do que está realmente a suceder aquí
debaixo do capó, por así dicir.
Este é un rectángulo que pode representar a memoria do seu ordenador.
Mesmo se non ten idea de como funciona a memoria ou como funciona a memoria RAM,
polo menos asumir que ten acios de hoxe en día.
Tes megabytes de que, ten gigabytes de que,
e sabemos que a partir da semana que un byte 0 é só o que? >> [Alumno] 8 bits.
8 bits, non? Entón 8 ceros e 1.
Entón, se o seu ordenador ten un giga de RAM, 2 Gb de RAM nestes días,
ten un billón ou 2 millóns de bytes de memoria ou preto de 8.000 millóns ou 16 millóns de bits
dentro do seu ordenador.
Ao contrario do exemplo pouco Willy Wooly, non é tipicamente máis partículas magnéticas.
Cada vez máis - en portátiles, polo menos - é drives de estado sólido, SSDs
que só non teñen partes móbiles. É todo electrónico. É todo baseado en electricidade.
Entón, creo que dese rectángulo como só representando os 1 ou 2 gigabytes de memoria que ten.
>> Polo tanto, é unha peza da memoria.
O mundo da informática ten a sorte de dissociado
anacos de memoria para facer cousas distintas.
Por exemplo, se esta é a memoria RAM do ordenador, como suxerido polo rectángulo alí,
verifícase que, por convención, na parte superior da súa memoria RAM, por así dicir,
é, xeralmente, o que se denomina un segmento de texto.
Estes son os 0s e 1s que teña compilado.
Entón, cando nós miramos debaixo do capo que a.out é,
todos estes 0s e 1s, cando executar un programa,
os 0s e 1s son cargados a partir do seu disco duro en algo chamado de memoria RAM,
e na RAM son colocadas na parte superior.
Mentres tanto, ten outras cousas: iniciar os datos, non arrincar datos.
Eses dous fragmentos de memoria refírense a variables globais, que non adoita usar
pero, ás veces, se fai iso, eles acaban alí tamén.
Despois, hai algunhas outras cousas: as variables de ambiente, que non vai pasar moito tempo,
pero, a continuación, dúas cousas importantes que van volver ao longo do semestre,
pila e heap.
Así, a maioría da memoria do seu ordenador está reservado ao executar un programa
para algo chamado de pila e algo chamado de pila.
Non imos falar sobre a pila de hoxe, pero imos falar sobre a pila.
A pila é destinado a conxurar a vista das comidas bandexas de comida salón en Mather Casa
ou onde queira que sexa, onde o equipo comedor limpa-los todos os días,
eles empilhá-los do chan enriba,
e do mesmo xeito, na memoria, non é esa idea de poñer algo en unha pila,
poñer algo nunha pila, poñer algo nunha pila.
E o que queremos dicir con iso?
>> Imos aumentar o zoom en só a metade inferior da imaxe, memoria RAM do seu ordenador,
a propoñer o seguinte.
Acontece que cando executar un programa como a.out ou Ola -
calquera que sexa o programa que escribiu -
de novo, os 0s e 1s son cargados a partir do seu disco duro, que é a longo prazo de almacenamento,
permanece alí mesmo cando puxar a ficha, cargado na memoria RAM.
RAM é máis rápida que os discos duros - é menor que os discos duros -
pero é que os programas en directo, mentres está executando-os.
Entón premer dúas veces un programa en un Mac ou PC, é cargado do disco duro para a memoria RAM.
Así como é cargado na memoria RAM, o go 0s e 1s na parte superior forma,
o segmento de texto chamado, pero así que o programa realmente comeza a correr,
A principal función é chamado, e principal, como xa vimos, moitas veces ten variables locais,
e ints e cordas e carácter e semellantes.
Polo tanto, se o seu programa que escribiu ou o programa que premer dúas veces
usou algunhas variables dentro principal,
eles acaban no fondo da súa pila de memoria, por así dicir.
Máis concretamente, o que iso realmente significa?
Isto só significa que se nós estabamos indo ao número de bytes de memoria RAM no seu computador,
conta que este pode ser o número de bytes 0, este pode ser o número de bytes 1, 2, 3, 4, 5, 6,
todo o camiño ata 2 millóns sería todo o camiño ata alí enriba.
Polo tanto, noutras palabras, cando falamos de memoria RAM ou en termos de bytes,
significa só que alguén decidiu que a partir cada un destes anacos de memoria.
Así, cando precisa de 32 bits para un int ou precisa de 8 bits para un char,
onde é que acaban na memoria?
>> Conceptualmente, eles simplemente acabar no fondo dunha cousa chamada a pila.
Pero o que é interesante agora é cando chama unha función principal -
supoña que unha función chamada foo, só o nome dun arbitrario -
o que pasa é principal na parte inferior desta pila de memoria;
foo agora é poñer enriba do principal na memoria.
Así, todas as variables locais que foo ten acaban tipo de conceptualmente por riba dos de inicio.
Se foo chama outra función chamada bar, estas variables acaban aquí.
Se a barra de chama outra cousa, aquí, aquí, aquí.
Entón, o que é interesante sobre a execución dun programa que, como chamar funcións
e como esas funcións chamar funcións e como esas funcións chamar funcións,
construír esta pila de funcións na memoria.
E só unha vez a función devolve comezar a que a memoria de volta.
Polo tanto, unha das formas máis fáciles de quedar sen memoria nun programa de ordenador
é escribir funcións que nunca retornan.
Así, por exemplo, imos demostrar tanto cun programa intencionalmente buggy.
Deixe-me ir adiante e facer # include,
int main (void),
e eu vou facer mentres (2> 1), o que probablemente non vai cambiar en nós,
e deixe-me ir adiante agora e facer printf.
En realidade, iso vai ser menos interesante visualmente. Imos facelo.
Para int i = 0; i> 0 - imos cometer ese erro - I + +.
E non imos printf aquí. Imos practicar o que eu estaba predicando.
Imos ter un método aquí, refrán baleiro, e imos dicir int i,
e entón eu vou dicir printf - non, imos facer isto máis interesante.
Non imos realmente imprimir nada. Imos facer o seguinte: coro (i).
Todo ben. Polo tanto, este é buggy por que?
Eu estou facendo iso como eu ir, porque o programa non fai nada de interese.
>> Pero ese non é o obxectivo.
O obxectivo é escribir un programa que ten como principal función fai o que, ao parecer?
Identificar. E, en realidade, nós non precisamos do loop.
Imos mesmo simplificar este só para non perder de vista o erro realmente fundamental.
Chamadas principais coro a cantar algunha coro,
entón eu fixen algo estúpido e eu tiven coro chamada coro
porque eu asumir alguén estaba indo a implementar lo, quizais,
e agora iso non vai compilar aínda. Eu teño que facer o que?
Eu teño do prototipo, lembre-se.
Entón, eu preciso ter-se aquí coro void (int i);
Polo tanto, agora eu baixar aquí - na verdade, imos usar a xanela máis grande.
Imos adiante e facer coro.
Utilización de identificador non declarado i.
Ah, iso foi estúpido. Nós non precisamos do argumento. Imos facelo.
Gustaríame que tivese comezado desta maneira. Sería un programa moito máis doado escribir.
Alí. Agora imos para a miña xanela de terminal, siga novamente Clang, e aquí imos nós.
Iso foi moi rápido.
O que realmente aconteceu, mentres?
Ben, agora eu vou engadir a liña de impresión para que poidamos ver.
Deixe-me dicir printf ("Eu estou aquí") - non variables. Imos deixalo así.
Deixe-me facer reprise. Deixe-me reprise coro.
E ... imos alí. Continúe indo.
Como un aparte, por que aínda non caeu aínda?
O fallo de segmentación ocorreu super rápido antes.
[Resposta do alumno inaudível] >> Exactamente. Entón, hai que tempo para imprimir, non?
El só ten máis traballo por parte do ordenador.
E alí está: fallo de segmento.
>> Entón, observe o quão rápido os programas executados.
Se vostede non está imprimindo nada, super rápido.
Pero aínda teño esa fallo de segmento, porque o que estaba a suceder?
Se pensar sobre como a memoria do seu ordenador e colocar a fóra,
este pasa a ser principal, pero aquí imos chamar este coro, e imos chamar este refrán.
E agora, se eu fai a miña estética certo, iso só vai dicir coro coro, coro,
coro, coro, coro, coro, relativa nauseum, e, finalmente, o que vai ocorrer?
Se a imaxe grande, literalmente, é iso, o que pasa só conceptualmente?
As derrapagens pila a pila.
Ou, peor, só superado todo, incluíndo o segmento de texto,
que é a 0s e 1s que representan o seu programa.
En suma, este é só super, super-malo.
O seu programa entrou nunha espiral fóra de control.
Está a usar a memoria moito máis do que pretendeu
todo por causa dun erro estúpido, neste caso,
ou, neste caso unha función moi deliberadamente feito ligando-se.
Agora, iso non é de todo malo.
Funcións que chaman-se, en realidade, ten un gran poder cando usalo correctamente.
Eu non teño usado correctamente aquí.
Entón iso non é de todo malo, pero o feito de que eu nunca realmente deixar de chamar-me
é unha debilidade fundamental aquí deste programa.
Entón onde estamos indo con todo isto? O que está realmente a suceder?
Cando eu chamo a función de incremento como estabamos facendo nestes exemplos,
Eu teño un valor como unha que eu pasar dentro
Eu pasar unha copia do número 1, entón acontece o seguinte.
Imos ao exemplo de incremento, este cara por aquí.
Aquí está o que realmente está a suceder.
Cando eu chamo incremento e eu pasar x, pictoricamente, o que está a suceder aquí é esta.
>> Se eu tivera o valor dun almacenados aquí e realmente chamar incremento,
que agora é chamado coro - o iPad está xogando-me aquí.
Imos chamar ese incremento, e non sabemos o que esta función próximo vai ser.
Entón o que está realmente a suceder aquí en algún lugar na principal Eu teño un anaco de memoria
que está a gardar o número 1.
Cando eu chamo incremento, está a usar outro anaco de memoria,
pero agora eu teño a copia do 1.
Cando incrementar ese valor, iso fai 2,
pero entón o que ocorre logo que retorna de incremento?
Esta memoria só queda trasladado ao seu sistema operativo,
o que significa que todo o que fixo non é nada útil.
O 1 que foi orixinalmente contido no principal aínda é realmente alí.
Entón onde estamos indo con iso?
Acontece que na memoria que vostede esta secuencia de back-to-back de bytes
que pode poñer cousas dentro, e verifícase que vimos algo
que implica poñer as cousas de volta para atrás, cara atrás, cara atrás.
¿Que é un texto baseado na 1 ª semana, e agora 2 semanas?
É só unha colección de personaxes.
Así, parece só como pode pór números na memoria,
do mesmo xeito que pode poñer os caracteres na memoria.
E cando comezamos a poñer personaxes na memoria de costas cara atrás, cara atrás,
verifícase que usar a máis simple das cousas como un loop ou un loop while,
podemos iterar de esquerda a dereita sobre os carácteres dunha cadea
e comezar Masaxes-os en personaxes completamente diferentes -
podería ser un b, b podería tornar-se c -
de xeito que, en última análise, podemos tomar unha frase Inglés que realmente ten sentido
e converter cada unha das referidas cartas de cada vez
camiñando a través da memoria do noso ordenador esquerda a dereita para realmente cifrar.
Polo tanto, imos ter a nosa pausa de cinco minutos aquí,
e cando volten, imos comezar este proceso de codificación de información.
>> Todo ben.
Antes de mergullo en algúns cifrado e esas cousas chamadas de matrices,
deixe-me facer unha pausa para todas as preguntas, porque eu sinto como se eu realmente tipo de confusa
algúns destes temas. Entón imos corrixir agora, se pudermos.
Acaba de falar sobre valores de retorno, nós conversas sobre argumentos,
e falamos sobre esta noción, que nós imos volver nos próximas semanas,
ver a memoria como unha morea de estas bandexas amoreadas, por así dicir,
desde abaixo, de arriba, de tal xeito que cada bandexa, que é colocado na pila
representa unha función que está a ser chamado.
Algunha pregunta?
Deixe-me facer unha pregunta aquí.
Deixe-me simplificar iso volve ao que era antes de algúns dos nosos máis cedo Q & A.
O feito de que o incremento ten paréntese aberto, número int, pechou parénteses -
que é o que o número int representa?
[Alumno] Un argumento. >> Un argumento. Okay. Pero o que é un argumento?
[Resposta do alumno inaudível] >> ¿Que é iso? >> [Alumno] Algo que pasa dentro
Ok, entón algo que pasa dentro e de modo máis xeral, é só a entrada.
Se fose escribir unha función e finalidade desa función na vida
é facer algo un pouco diferente cada vez que usalo,
entón o único xeito para que isto ocorre realmente parece ser o de proporcionar con entrada
para que poida facer algo diferente que a entrada de cada vez.
>> Entón, ten que especificar dúas cousas cando leva unha función de entrada.
Debe especificar o nome que quere dar a esta entrada
exclusivamente para a súa propia conveniencia para que poida consultala la
na función que mesmo está escribindo, como eu fixen aquí en liña 32.
Pero tamén precisa especificar o tipo porque C é unha linguaxe de programación
que esixe só que se quere unha variable, ten que dicir ao computador o tipo de datos que é,
en gran parte, para que saiba cantos bits para reservar para esa variable
porque podería ser 6 - desculpe, iso non vai ser 6.
Pode ser de 16, pode ser de 8, pode ser de 32, aínda 64,
pero o ordenador precisa saber.
Agora, a int no lado esquerdo representa o que, por outra banda?
[Resposta do alumno inaudível] >> ¿Que é iso? >> [Alumno] Tipo de función.
O tipo de función e, máis concretamente, do tipo da súa produción. Dereito.
Así, mentres que o único entre parénteses representa a súa entrada, se o houbera,
a cousa á esquerda representa a súa saída.
E, neste caso, o incremento aparentemente retorna un enteiro
e así int é o tipo de retorno desta función.
O que significa volver?
Literalmente, usa a palabra chave return e entón, se o que está volvendo
á dereita da palabra clave é un número enteiro,
a continuación, que é de feito consistente co que prometeron.
Non podería facer algo así - Ola mundo, - porque iso é unha cadea.
>> Obviamente, isto non é un número enteiro.
Así, en breve, a carga é realmente en nós, o programador, para ser específico
En canto ao que estamos volvendo e entón realmente ir sobre a devolver.
O contexto aquí agora é que a memoria do ordenador é un gigabyte, 2 gigabytes -
calquera que sexa - quizais sexa máis, quizais sexa menos
pero o ordenador velo como tendo distintas seccións.
Algo vai alí, outra cousa vai alí enriba,
cousas distintas vai no medio, e hoxe nós só comezar a contar a historia,
pero imos volver a ese tempo rematou.
Polo momento, a única lembranza que realmente importa é o segmento de texto
porque iso só representa os 0s e 1s Clang que emite.
Entón, cando executar un comando no teclado como a.out
ou dobre clic nun icono en Mac OS ou Windows,
seu programa cargado dende o disco duro para a memoria RAM
e está estatelou na parte superior da RAM do seu ordenador, por así dicir.
Mentres tanto, como o seu programa comeza a ser executado e principal é chamado
no programa que escribiu ou o programa Microsoft ou Apple escribiu,
calquera das súas variables locais acaban alí no fondo da memoria do seu ordenador.
Pero, se as chamadas principais outra función que si ten variables ou argumentos, eles acaban por riba.
E se esa función chámase algo, eles acaban por riba del, por riba del, por riba del.
>> E só unha vez unha función de execución que está feito a pila de taboleiros, por así dicir,
comezan a estar máis e máis.
E isto é o que entón, en poucas palabras, explica porque cando chama cubo
ou chamar incremento, está pasando unha copia do valor.
E o que iso significa pictoricamente é que está, literalmente, escribindo o número 1
noutra parte da memoria, cambiando que 1 a 2, no caso de incremento
ou dun 8, no caso de cubo e, a continuación, que a memoria de distancia xogando
así que o aumento ou a función devolve de cubo. Pregunta.
[Estudante] Onde son variables globais son almacenados?
As variables globais son almacenados en que está actualmente chamado os datos inicializados ou datos non inicializados,
a diferenza é se ten unha variable global e lle atribúe un valor inmediato
co signo igual, el acaba na parte superior alí,
e acaba de dicir int x; sen valor, acaba un pouco menor na RAM
simplemente por convención.
Outras preguntas? Todo ben.
Polo tanto, esta imaxe vai volver como temos máis poderoso
co que podemos facer co ordenador,
pero por agora, imos ter unha breve introdución á criptografía,
un tipo específico de cifrado que non resolve todos os problemas do mundo
pero non resolve algúns deles.
Neste caso aquí, temos unha cousa chamada criptografía de clave secreta.
Criptografía de clave secreta, como o nome suxire, deriva a súa seguridade a partir dun segredo.
>> Por exemplo, se estaba de volta na escola e estaba pasando unha carta de amor pouco secreto
para o neno ou a nena que estaba esmagando, se quería pasar esa nota por medio da audiencia,
probablemente non ía escribir tal nota en inglés ou calquera que sexa a súa lingua nativa é.
En vez diso, pode Encriptar ou pode só enviar-lles unha mensaxe de texto nestes días.
Pero realmente pode pasar-lles unha nota ao longo da clase.
E para facelo de forma segura, de tal forma que os seus amigos e os profesores
non sei o que está escribindo, pode chegar a un algoritmo moi sinxelo,
mozo que pode ser, só para embaralhar as palabras.
Entón, en vez de escribir un pode escribir B,
en vez de b pode escribir c,
en vez de c podes escribir d, e así por diante.
Ou pode vir con unha tradución máis sofisticado
de cartas para letras diferentes.
Pero o problema é o neno ou nena a quen está enviando esta nota
Debe saber algo, que é o que, obviamente? >> [Alumno] O que está enviando.
Cal é o seu segredo, como o que é que o mapeamento entre un e B e C e d's.
É só engadindo unha a cada unha das letras para ir de un a B, B para C?
O que é máis complexa do que a?
>> Así, vostede ea súa paixón é preciso ter esa información secreta,
pero hai unha especie de catch-22 aquí.
Se esta é a primeira vez que está enviando esta carta de amor a través da clase,
como é que o neno ou a nena vai saber o que o segredo é?
Entón chave secreta de cifrado non resolve todos os problemas do mundo,
e hai, en realidade, unha relación aquí que nós imos volver en dirección ao fin do semestre.
Do mesmo xeito que non a maioría de nós coñece a alguén que traballa, por exemplo, a Amazon.com,
e aínda que moitos de nós probablemente xa comprou cousas no Amazon.com,
e nós fomos ensino a asumir que esas transaccións de comercio electrónico son seguras.
A URL probablemente di https, hai quizais unha icona de cadeado pouco parvo en algún lugar,
hai algún tipo de criptografía de protexer a súa información de tarxeta de crédito
entre vostede e Amazon.com.
E, con todo, a criptografía implica coñecer algún segredo
e eu non coñezo ninguén en Amazon e eu certamente non dispostos calquera tipo de segredo
con alguén na Amazonia, como é o meu ordenador ou o meu navegador facendo iso?
Acontece que hai outros tipos de cifrado completamente que resolver este problema.
Pero por hoxe, imos nos centrarse na simple
onde podes organizar con antelación para saber algún segredo
como unha ou algunhas cartografía entre un e B do.
E o proceso de cifrado implica xeralmente a este.
Ten algún texto simple, representado aquí na esquerda,
executa-lo a través de algún tipo de algoritmo ou procedemento para criptografía-lo -
quizais iso sexa só unha se fai b, b torna-se c -
e entón acaba con texto cifrado.
Mentres tanto, unha vez que a súa paixón recibe esta nota secreta,
el ou ela ten que decifra-lo, entón por que xeralmente invertendo algoritmo
para obter de volta o texto simple.
Existen encarnações físicas deste.
>> Por exemplo, este é un anel decodificar pouco segredo,
e este é un anel, no sentido de que hai dous mostradores aquí.
Na periferia fóra desta cousa, hai letras de A a Z,
aínda están en orde aleatoria,
e no interior, hai realmente algúns números
de tal forma que con este anel, pode converter o tipo de fóra, pero non no interior
, A fin de aliñar números con letras.
A partir dun filme chamado Unha Historia de Nadal, vai ver que Ralphie pouco
estaba tan ansioso para descubrir o que a mensaxe secreta Little Orphan Annie era para el
que fora comunicado, penso eu, en forma de mensaxes numéricas nunha caixa de cereal
e tivo que acumular todas as tarxetas pequenos que viñeron na caixa de cereal,
tiña que envialos, tiña que volver o anel decodificar secreto
de modo que pode finalmente descubrir o que é o mapeamento entre letras e números
ou cartas e cartas.
Como un ordenador pode ir sobre a implementación ou representando cousas como esta?
Necesitamos un xeito de nos expresar un pouco máis flexible
que as nosas variables ata agora permitiron.
Tivemos ints, tivemos chars, tivemos coches alegóricos e de dobres e algúns outros,
pero esas son pezas individuais de memoria que realmente non nos permiten expresar cousas
como palabras e frases e oracións.
En realidade, nós temos chamado cordas tales cousas,
pero nós prometemos que iso é realmente só unha simplificación na biblioteca CS50
que estamos coa intención de pelar.
E así imos comezar a facelo aquí.
Deixe-me ir adiante e abrir un ficheiro -
todos estes arquivos están dispoñibles, como de costume, en liña - array.c chamado
para resolver un problema relacionado con cordas, pero que pinta un cadro aquí
de como podemos utilizar unha cousa chamada matriz.
>> Unha matriz é un tipo de datos.
É un tipo de variable do tipo que ten varios tipos de datos máis pequenos dentro dela
de costas cara atrás, cara atrás.
Así, por exemplo, se quixésemos escribir un pequeno programa que lle dá a súa media de proba
para un curso como 50, que ten dous cuestionarios,
podería moi facilmente escribir este programa baseado mesmo en algúns dos materiais da semana pasada
usando GetInt e un par de variables: int quiz1, int quiz2.
E é moi sinxelo.
É quizais 10, 20 liñas de código máximo para aplicar un programa de
que pide ao usuario para dúas puntuacións do cuestionario e calcúlase a media
sumando os, dividindo por 2, e logo a impresión dos resultados.
Nós probablemente podería facelo moi rapidamente agora, despois dun determinado número de minutos.
Pero o problema é que, supoñamos que 50 tiñan 3 ou 4 probas.
Supoña que vostede quería usar o mesmo programa para unha clase que tivo probas semanalmente.
Debería unha clase que ten probas semanalmente.
Se hai 16 ou máis semanas, nun semestre, agora ten 16 variables:
int quiz1, int quiz2, int quiz3, int quiz4.
Así que comezar a ver esa redundancia, esta copia e pegado de código,
debe comezar a facer desexa que houbese un xeito mellor.
E, por sorte, porque de matrices hai. Entón, imos facelo.
En primeiro lugar, deixe-me presentar unha cousa moi simple que non usei ata agora,
pero vai ver que, en ocasións, en código.
>> Isto é o que é xeralmente chamado de unha constante.
Entón, é unha constante no sentido de que este valor nunca cambia.
A convención humana ao crear unha constante
é por todas as letras maiúsculas só para que realmente destaca no seu código,
ea palabra clave especial que usa en C # é definir.
Así, dicimos # define, entón, un espazo, entón a palabra que quere empregar o nome constante do
e, a continuación, o valor da constante.
Teña en conta que isto é diferente de asignar algo a unha variable.
Non hai signo igual, non hai punto e coma.
Isto é o que é xeralmente coñecido como unha directiva de pre-procesamento,
pero máis sobre iso noutro momento.
De momento, iso crea un valor inmutable chamado cuestionarios
cuxo valor numérico real é 2.
Entón, en calquera lugar que ve probas, cuestionarios, probas ao longo deste arquivo,
iso é só o número 2.
Se eu ollar para inicio Agora, imos ver como funciona isto.
En primeiro lugar, parece un pouco enigmático, pero é todo cousa de 1 semana.
Peza ao usuario notas. Como podemos facer iso?
Na liña 22 - este é realmente a parte suculenta - Declaro un flotador
pero non só un único flotador. Estou declarando, antes, un conxunto de valores de punto flotante.
Esta variable vai ser chamado de notas, como implicado aquí,
pero a única peza de nova sintaxe, entón son estes corchetes.
O feito de que eu dixen notas float e, a continuación, soporte aberto e, a continuación, un número -
entender esta é unha constante que é só como nós fixemos iso -
isto significa, "Hey ordenador, dáme dous coches alegóricos e imos chamalos colectivamente notas."
>> Isto está en contraste con un proceso moito máis tedioso así: flotador classe1;
grade2 flotar, e así por diante.
Así, unha matriz que nos permite implementar esta idea, pero moito menos messily,
de xeito que podemos escribir unha liña de código, en vez de, digamos, 16 para un semestre de 16 semanas.
Eu non quería ríxido código 2 porque se pensar sobre iso agora, loxicamente,
supoño que o próximo ano CS50 cambios 3 quizzes vez
e eu tiña o número 2 aquí, eu tiña o número 2 aquí,
Eu tiven o número 2 aquí, o número 2 aquí.
Tórnase moi tedioso e moi fácil de romper
e cambiar accidentalmente un valor para 3 e perder algún outro valor de 2.
Entón, eu estou indo a lugar abstracto iso adiante e utilizar esa constante que,
Como o nome suxire, nunca cambia.
E agora non importa se temos diferentes probas este ano ou o próximo,
Eu só teño que mudalo nun lugar aquí enriba.
Entón iso é todo unha constante é.
Mentres tanto, o novo recurso conceptual que dunha matriz.
Así, os corchetes me dar esta flota moitas e déixame chamalos colectivamente notas aquí.
Entón agora imos ver o que eu vou facer.
Aquí, na liña 24 é o inicio dun lazo.
>> Isto é realmente nada extravagante. É só usar cuestionarios vez de un número codificado.
Pero non hai nada intelectualmente diferente alí desde a semana pasada.
Este é só printf, así printf ("Quiz d #% de% d:")
porque eu só quero imprimir me dar cuestionario número 1 de 2 e, a continuación, 2 a 2.
Entón iso é unha cousa puramente estética.
Pero a parte interesante é agora na liña 27.
Co fin de cubrir un dos dous marcadores de posición cun valor de punto flotante,
novo usar corchetes.
Neste caso, eu estou usando i porque este loop comezou con i igualando o valor que, ao parecer?
[Estudante] 0. >> [Malan] 0.
Así, na primeira iteração do loop, é como se eu escribín iso no código,
pero na segunda iteração do loop, é como se eu escribín iso no meu código.
Pero o feito de que eu estou usando unha variable é perfecto, porque, como o nome suxire,
está variando o seu valor cada iteração,
entón eu estou cubrindo esta matriz un punto de cada vez.
O que esta matriz parece?
A razón que eu deseñei o rectángulo super sinxelo na pantalla aquí antes foi por este motivo.
Unha matriz é só unha peza de memoria seguido por outro anaco de memoria
seguido por outro bloque de memoria e así por diante.
Entón, se a miña matriz é de tamaño 2, neste caso, aquí, todo o que eu estaría facendo
escribindo na puntuación meus cuestionario como aquí - Eu teño 100 en un presente e entón eu teño un 99 nun presente -
entón esta memoria non pode ser usado incluso porque eu só preguntei o ordenador
para unha matriz de tamaño 2.
Estas prazas aínda están alí, non?
Aínda ten 2 gigabytes de memoria RAM, mesmo se está só pedindo para 2 coches alegóricos.
Así, a idea detrás de matrices é que o ordenador só ten un anaco da memoria
e despois reparte pequenos anacos de costas cara atrás, cara atrás.
E para que é todo unha matriz é.
>> É unha peza contiguo de memoria dentro do cal pode pór as cousas.
Isto acontece para despois facer só algúns aritmética chat.
Se rolar por aquí, este é o lugar onde eu entón iterar sobre o array.
Eu veño co sumatorio de todos os valores na matriz,
e entón eu uso a función round aquí para realmente facer a suma dividida por probas.
Pero deixe-me acenar a miña man no que, como especie de aritmética suficiente por agora.
Pero todo o que está facendo para min, en última análise é o cálculo dunha media.
Entón, primeiro cuestionario, máis segundo cuestionario dividido por 2 e despois mostralo como un int.
Pero imos transición agora un exemplo diferente, chamado string1,
que pinta un cadro similar, pero usando cordas.
Deixe-me ir adiante e simplificar este só por un momento.
Perdoe o recúo por agora.
Obsérvese na liña 19 deste exemplo, eu recibín unha cadea de usuario.
Pero teña en conta o que eu estou facendo o próximo liñas de 22 en diante.
En realidade, estou repetindo a partir de i-se - e este é un novo truco - strlen lonxitude da corda,.
Esta é unha función que vén co C que se pasar unha cadea,
el di que o número de caracteres que están na cadea. Isto é todo.
E o feito de que é strlen en vez de lonxitude da corda é só porque é máis sucinto.
Trinta anos, as persoas gustaban de escribir cousas da forma máis sucinta posible,
por iso temos mantido esta convención aquí.
i + + significa só incrementar i en cada iteração.
E agora entender iso, o que é realmente interesante.
Na liña 24, digo, "Ordenador, deixa-me un personaxe, 8 bits, e chamalo de c."
Pero o que é iso no lado dereito dicindo?
En inglés, o que iso supón?
[Alumno] O primeiro carácter da matriz.
Exactamente. Dáme o primeiro carácter da matriz.
Ou, máis xeralmente, dáme o carácter om na matriz.
E entender que é importante agora que os científicos de ordenador,
en realidade estamos a contar 0.
>> Non ten a criterio agora para comezar a facer iso.
Agora tes que comportarse de acordo coas expectativas do equipo e contar de 0
porque [0] vai ser o primeiro carácter nunha secuencia,
[1] será o segundo, [2], vai ser o terceiro, e así por diante.
Polo tanto, este programa, se eu compilar el, este é novo string1, así que string1,
e agora eu teño que correr string1 na miña xanela de terminal.
El está esperando por entrada, entón eu vou escribir David, intro
e agora ela imprime David todo en liñas diferentes, pois observe o que eu estou facendo.
Estou imprimindo un carácter de cada vez.
Non imos entrar en detalles hoxe sobre iso, pero eu deletei hai pouco esta verificación aquí.
Acontece que o usuario está comportándose mal, contraditorio, ou simplemente confuso
realmente pode deixar de dar unha secuencia de tempo.
Se bater na tecla equivocada no teclado, pode dar ningunha secuencia en todo,
ou se é malicioso, podes probar pegar no valor dun gigabyte dun ensaio
para cubrir esa secuencia, e se o ordenador ficar sen memoria,
Acontece que imos volver este valor especial chamado NULL.
Entón, por agora, só sei que hai ese valor especial chamado NULL
que nos permitirá comprobar cando estamos fóra de memoria, entre outras cousas.
Pero se eu abrir agora string2, notar unha diferenza aquí.
Teña en conta unha diferenza aquí con string2.
Con string2, este loop é un pouco diferente.
>> Deixe-me borrar os nulos, para que poidamos falar sobre iso outra hora.
¿Que é diferente sobre o lazo se esta vez?
Eu podo volver ao exemplo anterior.
Entón esta é a versión 2, esta é a versión 1. 1, 2.
1, 2.
A chamada strlen é onde?
É a primeira parte do loop.
Todos os pensamentos acerca de porque eu estou facendo isto? Si
[Estudante] Entón non chamar a función de cada vez.
[Malan] Entón, nós non chamar a función en cada momento. Exactamente.
Lembre-se de lazos que son super sinxelo
unha vez que tipo de entender que esta é a inicialización, a condición ea actualización.
O problema é que a condición ocorre en cada iteração do loop.
E así, neste exemplo aquí, o que é malo sobre o feito de que esta é a miña condición?
[Alumno] está chamando strlen.
[Malan] está chamando strlen novo e de novo e de novo.
Pero unha vez que eu escriba en David, a lonxitude da corda que é 5,
e iso non vai cambiar en cada iteração do loop
porque a cadea aínda é D-a-v-i-d.
Polo tanto, esta é unha información que vai facer unha idea cada vez máis importante
coñecido como unha decisión de proxecto, onde só non facer o ordenador facer un traballo innecesario.
>> Así como unha previa pset2, pset2 na edición estándar
vai desafia-lo para realmente implementar un número de cifras,
un número de algoritmos de cifrado, de modo que pode tanto cifrar
e descifrar mensaxes secretas, como a moito non Ralphie un decodificar.
Na edición de hacker de pset2, imos ir un pouco máis lonxe.
Nós imos entregar-lle un ficheiro dun sistema informático real
que contén unha chea de nomes de usuario e contrasinais cifradas reais,
eo desafío para a edición de hacker vai ser para romper os contrasinais
e descubrir o que o cifrado ou segredo foi usado para realmente xerar esas contrasinais.
E nós imos facelo empregando un novo recurso aquí C
que eu vou dar-lle só unha demo de coñecido como liña de comando argumentos.
Acontece que, como algúns de vostedes poden ver na sección ou nos libros de texto,
Inicio nin sempre ten que ser nula entre parénteses.
Acontece que principal tamén pode ser escrito así, con dous argumentos,
argc e argv, argc, onde é o número de palabras
que escribas logo o nome do programa na súa liña de ordes
e argv son as palabras reais.
E, como os corchetes alí suxerir, argv é, aparentemente, un array.
Vai ser unha secuencia, tras unha serie despois dunha serie na memoria.
>> Entón, o que nós imos ser capaces de facer comezando con pset 2 é algo como isto.
Se eu fai argv1, que é un exemplo que vai voltar a luns, e executa-lo,
notar que non parece facer nada aínda.
El só imprime o seu propio nome.
Pero se eu dixer adeus clase, aviso que este programa aparentemente itera
sobre cada unha das palabras que foron escritas no prompt.
E os medios polos que imos ter acceso a palabras que o usuario introduciu no poder
e cambiando principal a partir deste fin de semana int main (void) para int main (argc, argv)
e, así, vai nacer de liña de comandos argumentos.
E unha vez que realmente sofisticado con iso, vai ser capaz de escribir programas realmente trippy
como este aquí, que vai enriba e alén
algunhas das características que temos feito ata agora, pero todos moi poderoso.
>> Entón, imos deixar isto con iso na pantalla, e imos velo o luns.
>> [CS50.TV]