[Powered by Google Translate] DAVID J. MALAN: Tudo bem, isso é CS50, e este é o início de duas semanas. Obrigado. Vamos começar aqui com um telefonema. Estou prestes a marcar 617-BUG-CS50. CS50: Este é CS50. Para Menino Shuttle, pressione 1. Para começar de novo, pressione 9. DAVID J. MALAN: Então ele disse para o menino Shuttle, pressione 1. Então, nós estamos indo para pressionar 1. CS50: Qual é a sua origem? Para quad, pressione 1. Mather, pressione 2. Boylston, pressione 3. Lamont, pressione 4. Mem Hall, pressione 5. Para começar de novo, prima 0. DAVID J. MALAN: Vamos pressionar 1 para o quad. CS50: próximo ônibus deixa isso muito minuto a 1:10 PM, e em seguida, às 1:20 PM, 1:30, 1:40 PM. Este é CS50. DAVID J. MALAN: Então esta é a voz do CS50. E é um exemplo dos tipos de projetos finais, para exemplo, você pode morder para o fim do semestre. Por exemplo, que existe shuttleboy.cs50.net - na verdade, um projeto que escrevi pela primeira vez depois de tomar CS51 quando eu era estudante de graduação. E a inspiração aqui era naquela época, tudo o que eles tinham era os horários de ônibus impressos de ônibus, e não havia noção de olhar as coisas online. E assim eu espécie de pomba em um fim de semana, filtrado através da impresso, cronograma e portou para um programa de computador. Na altura, o programa de computador aconteceu ser escrito em C. E você, na verdade, ele correu por Boy Shuttle digitando em um piscando prompt como temos vindo a fazer até agora. Mas ao longo dos anos, tem evoluído em um instante mensagens bot. Ele evoluiu mais recentemente para este site, em um SMS ferramenta baseada, bem como para esta ferramenta baseada em voz. E esta é a dica para os tipos de coisas que você pode fazer por si mesmo até o final do semestre. Por exemplo, lá, a versão SMS do Menino Shuttle acontece para operar como segue. Se, no seu telefone celular, enviar uma mensagem de texto para 41411 e em seguida, enviar o sboy símbolo especial, para o menino de Transporte seguido de A e B, onde A é uma origem e B é um destino - por exemplo, Boylston Espaço Quad - o que você deve voltar dentro de alguns segundos é um texto mensagem do Menino Shuttle dizer exatamente quando o próximos ônibus são poucos, de que o ponto A, que vai ponto B. E este é um exemplo mais geral do que é conhecido como utilizando uma API. Assim, por exemplo, este aqui é apenas shuttleboy.cs50.net, o encarnação web-based real deste. Mas os dados que sublinha este e outros aplicativos que CS50 desenvolveu são todos expostos a todos aqui na forma de APIs, interfaces de programação de aplicativos. E isso é apenas uma maneira elegante de dizer que as pessoas gostam em nós a Internet e outros de ter passado algum tempo a criar software que você pode usar para pegar os dados de nós e em seguida, construir seus próprios aplicativos em cima de que o conjunto de dados. Assim, por exemplo, este Shuttle página da API do menino aqui, que passa a ser no manual CS50, essencialmente documentos como você pode ir em pedir CS50 servidores de dados. Por exemplo, se você está familiarizado com arquivos CSV, vírgula valores separados, estes são apenas uma espécie de rápida e suja Excel-como arquivos. Então você pode perguntar Boy Shuttle para todos os dados em toda a casas e coordena seus GPS, e você vai ter volta, essencialmente, uma planilha assim que então você pode ler em um programa de sua preferência e, em seguida gerar resultados, como Menino Shuttle si passa a ser fazer. Para aqueles mais familiares, representações mais modernas de dados incluem JSON, JavaScript Object Notation. Alguma coisa vai voltar para você direção o fim do semestre. Mas, novamente, esta é apenas uma das várias APIs do próprio CS50. E a coisa excitante é agora, nestes dias, Facebook e Twitter e Google e praticamente todos os site popular para fora lá tem algum tipo de API, o que significa que se você ler o documentação em seu site, que você se inscrever para uma conta, você pode então começar a escrever software em cima de quaisquer ferramentas ou dados da empresa que fornece. E assim um de nossos companheiros de ensino próprios um par de anos para trás escreveu uma versão para Mac deste. Então, no link intitulado Mac aqui no canto superior esquerdo, você pode realmente download de um Mac OS Widget que executa em seu próprio Mac para fazer o mesmos tipos de coisas. Então, é tudo sobre a construção em cima de conjuntos de dados como estes. Mas mais sobre isso no final do semestre. Então, vamos mergulhar em rápido real a um bug, apenas para obter o tipo de coisas aquecido hoje, e pensar no passado em alguns dos coisas que olhou para a semana passada. Em particular, deixe-me ir em frente e puxe-se, por exemplo, Neste exemplo aqui. Buggy1.c, este está disponível no site do curso se você gostaria de baixá-lo e picar em torno de si. Mas vamos zoom aqui neste programa bastante curta, e apenas uma recapitulação super-rápido de alguns dos blocos básicos de construção que realmente estamos indo apenas para começar a tomar para concedido. Então, as coisas azuis, nas linhas 1 a 9, são apenas perguntas softball. Então, essas são apenas comentários. Eles não têm nenhum significado funcional. Mas eles são comentários no sentido de que eles são notas que Eu, o ser humano, feito para mim para que na aula e depois palestra, eu consigo me lembrar o que este programa faz sem ter que lê-lo linha por linha e recriando a história em minha mente. Além disso, se eu entregar esse programa para outra pessoa como você, é muito mais clara para você, por causa de comentários como este, o que o programa está realmente fazendo, ou pelo menos o que o programa deveria estar fazendo. Se é ou não é correto é outra questão. Agora, em C, com comentários de várias linhas, recordar que na linha aqui é o símbolo mágico, / *. Isso significa que aqui vem o início de um comentário. E nada mais importa, até você chegar ao final de terminação, que é * /, o oposto. Então o fato de que eu tenho 80-algumas estrelas estranhas aqui de esquerda para a direita é realmente apenas um detalhe estético. Não tem nenhum significado funcional. Agora, que tal linha 11? O que isso faz em termos leigos? O que é isso? AUDIÊNCIA: Inclui o padrão. DAVID J. MALAN: OK, ótimo. Por isso inclui a biblioteca stdio.h. Então, o que isso significa? Bem, dentro desse arquivo, stdio.h, são um monte de declarações de função - isto é, o código que alguém escreveu. E um exemplo perfeito de uma função que é declarada no stdio.h é - que favorito até agora? Assim printf, uma das mais comuns de usar, certamente no início, a partir dessa biblioteca é ali. Se eu excluir essa linha de código, Clang vai gritar para mim algo sobre o uso de um símbolo não declarado. Algo não declarado é, provavelmente, a palavra-chave, pois não ter informado ao compilador o printf parece como se não incluir essa linha. E mais para a Terra, realmente, o que essa linha está dizendo é abrir esse arquivo, stdio.h, onde quer que seja sobre a do servidor disco rígido, ou disco rígido do aparelho, e copiar-colar-lo ali em meu arquivo, sem a minha ter que fazer isso manualmente. Agora, uma vez que temos aqui em baixo a principal, em pouco tempo vamos começar provocando separar o que int e que o vazio é. Mas, por agora, vamos olhar para as três linhas no prazo de 15 a 17. Este aqui eu reivindico como buggy. Linha 7 em meus comentários diz "Se imprimir 10 asteriscos, mas não. "Por que isso não imprimir, de fato, 10 dessas estrelas? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Exatamente. Então, observe que estamos começando a contar a partir de 0. E isso é realmente uma convenção na programação e ciência da computação em geral, começando a contar a partir de 0 em vez de 1. E este realmente só deriva do fato de que, para exemplo, quando tivemos oito pessoas no palco, quando ninguém estava levantando a mão, eles foram todos os zeros de forma eficaz. E por isso é apenas uma espécie de convenção computador assim, portanto, para iniciar a contagem de 0. Se esse é o menor número que pode representar em binário. Então aqui nós começamos inicializar i a 0. Nós criamos i igual a 0. Mas então eu cometi este erro aqui, dizendo que eu é menor ou igual a 10. Mas se você acha que, por meio, se eu começar em 0 e então eu vou até 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, eu estou indo realmente para imprimir 11 estrelas para a tela, porque eu tenho ido até a e igual a 10. Assim, a correção fácil aqui, então é o que? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Apenas alterá-lo para menos. Se você realmente quiser, você pode fazer isso. Mas, em geral, que é desaprovada. E assim começa a contar a partir de 0 é apenas algo que você deve normalmente se acostumar. Agora, o que dizer de toda essa construção em si? Esta linha 15 demarks um loop. Assim, para não é uma função. É apenas uma declaração. É uma construção de loop, como vimos no Scratch. E tem três partes. Note-se que há a primeira parte a à esquerda do ponto e vírgula. Há a parte do meio, entre as duas vírgulas. E depois há a parte da mão direita para a direita do ponto e vírgula segundo. Agora, o primeiro deles faz o quê? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Volta lá? Sim? AUDIÊNCIA: Inicialização. DAVID J. MALAN: Inicialização. Então, o que isso significa? Declaramos uma variável chamada i. Ele é do tipo int, porque eu especifiquei int i. E estou inicializando i como o valor de 0. Então, o que isso realmente dizendo? É efetivamente dizendo ao computador hey, dá-me o suficiente memória RAM, o suficiente, para atender um número, e depois colocar o número 0, em que pedaço de memória RAM. E como um aparte, quão grande é um int normalmente, pelo menos dentro do aparelho? AUDIÊNCIA: 32 bits. DAVID J. MALAN: 32 bits. Então isso significa que me dar 32 bits, também conhecido como 4 bytes, e colocar o valor 0 na mesma, o que é muito fácil, porque Significa apenas que definir todos os bits a 0. Então, agora, a segunda parte aqui é a condição. E a condição de, como o nome sugere, é o que é verificado de novo e de novo e de novo para saber se é verdadeiro ou falso. Portanto, este é apenas dizer fazer as seguintes linhas de código - ou seja, linha 16, porque essa é a única recuado embaixo - desde que i seja inferior a 10. E depois de cada iteração através deste circuito, faça o incrementação, o que neste caso é a i + +. Agora, isto não tem de ser i + +. Pode ser i -. Mas se eu fizesse isso, o que está acontecendo o comportamento ser deste programa? AUDIÊNCIA: Vai ser um loop infinito. DAVID J. MALAN: Vai ser uma espécie de loop infinito, a não ser que tenha sorte depois de 2 bilhões negativo ou assim. Talvez as coisas vão envolver, apenas pela natureza do finito número de bits que foram afectados por um int. Mas é, certamente, vai repetir muito mais do que 10 e certamente mais de 11 vezes aqui. E agora, como um aparte, perceber que i + + e i - são realmente apenas açúcar sintático. É apenas notação abreviada para o que é um pouco mais explicitamente escrito da seguinte forma: i = i + 1. Isso é idêntico ao i + +. É apenas uma espécie de aparência mais bonita para dizer i + +. É mais sucinta, mais legível. E assim a maioria das pessoas que, em vez. Mas esta é idêntica funcionalmente o que acabamos de ver. Assim, em breve, a solução rápida aqui é só para dizer iteração i desde 0 por todo o caminho até menos do que 10. E então nós vamos realmente obter 10 estrelas. Então, vamos tentar isso. Deixe-me abrir o terminal na parte inferior. Deixe-me ir para o diretório que esta está dentro E eu vou compilá-lo manualmente com Clang por agora. E eu estou indo para compilar isto como buggy1.c, Enter. E agora buggy1, por que não há tal arquivo ou diretório buggy1 chamado? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Yeah. Portanto, é na verdade chamado a.out. Então, se você apenas recordar executar Clang, onde é o Clang compilador, e você não especificar o nome que você deseja dar ao seu programa, que vai para o padrão para a.out. Então, na verdade, se eu faço ls - oops. E eu didn't - a questão em preto-e-branco alguns dos você enfrentou foi corrigido. Mas deixe-me fazer isso. Há que ter a.out no lado da mão esquerda lá. Então temos que correr a.out em vez de buggy1. Então deixe-me ir em frente e fazer isso. . A.out /, Enter. E eu, aparentemente, não fazer o que? AUDIÊNCIA: Salvar. DAVID J. MALAN: Salvar o meu arquivo. De modo que é facilmente resolvido por bater S de controle, ou vai Arquivo, Salvar, como na maioria dos programas. Deixe-me ir aqui em baixo, limpar a tela, execute-o novamente. E ainda há um bug. Então o que está acontecendo - AUDIÊNCIA: Você não compilar. DAVID J. MALAN: Ah, bom. Eu não compilá-lo. Como um idiota, eu estou olhando para o código para ver o que está errado. Então buggy1.c bumbum, agora a.out. E ufa, salva. Portanto, parece um pouco feio, porque não há nenhuma nova linha em qualquer ponto do programa. Mas, novamente, isso é apenas um detalhe estético. E pelo menos se contarmos aqueles fora, devemos ver agora 10 dessas estrelas. Bem, que tal este exemplo de aquecimento segundo? Assim, em buggy2, eu afirmo que essa versão, também, imprimir 10 estrelas, uma por linha. Então, desta vez, eu tenho um caractere de nova linha, só para fazer as coisas um pouco mais bonitas. Mas em vez disso o que eu recebo é esse. Então deixe-me fazer buggy2.c bumbum, Enter. Agora é novamente chamado a.out. Enter. Eu só vejo uma nova linha, apenas a linha de muito novo que passado move meu aviso para a próxima linha. E ainda claramente eu tenho a impressão *, em seguida, uma nova linha, *, Em seguida, uma nova linha. Mas o que é o erro aqui? Sim? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Exatamente. Assim, ao contrário de algumas linguagens, como Python, onde o recuo na verdade, tem um significado funcional, uma linguagem como C - como veremos, PHP, JavaScript - o recuo é realmente apenas para benefício dos seres humanos. Então o fato de que eu tenho recuado linha 16 e 17 parece ótimo, mas não tem significado funcional aqui. Se eu quiser ambas as linhas para executar como parte do para loop, então eu tenho que colocá-los em chaves, fazendo isso. Você só pode cortar aquele canto e omitir as chaves se qual é o caso? AUDIÊNCIA: apenas uma linha. DAVID J. MALAN: apenas uma linha. Então, isso é apenas uma espécie de uma espécie agradável de detalhe de sintaxe, de modo que você não perca tempo escrevendo três linhas, duas das quais são chaves, apenas para escrever uma única linha de código. Mas se você tiver duas ou mais linhas, realmente precisa fazer isso. Então, agora deixe-me guardar este. Deixe-me ir em frente e re-executar Clang. Então deixe-me reprise a.out, e agora eu pegá-los um por linha. Agora, a.out novamente é uma espécie de um nome idiota para um programa. Como posso saber Clang para realmente me dar um nome de arquivo que é mais user-friendly, como buggy2 si? Um pouco mais claramente? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: OK, para que eu possa realmente tomar o muito user-friendly de atalho e escrever apenas fazer buggy2. Eu não especificar. C neste caso, e pressione Enter. E o que fazem faz é que compila buggy2.c por mim Clang pedindo para fazer isso. Especificamente, ele chama Clang, corre Clang usando maneira mais linha de comando argumentos ou switches do que eu realmente precisa. Com o tempo, vamos voltar ao que todos esses diferentes enigmáticas expressões hifenizadas significa. Mas, por enquanto, isso é apenas poupando-me o trabalho de ter que se lembrar e ter que digitar todos aqueles várias expressões hifenizadas. E a vantagem de que, em última análise é que agora eu tenho buggy2. Se eu quiser fazer isso manualmente, porém, eu pode, em vez fazer isso - clang-o e, em seguida buggy2 buggy2.c. E que também irá dar-me um arquivo chamado buggy2. Então, em suma, é o compilador Clang. Fazer é apenas uma ferramenta de fácil utilização que vamos usar mais e mais, porque só começa a simplificar as coisas para nós. E nós retornar 0, finalmente. Por agora, apenas porque, mas vamos começar a provocá que parte hoje e na quarta-feira. Qualquer dúvida sobre isto? Sim? AUDIÊNCIA: [inaudível] ls entre aspas lá? DAVID J. MALAN: OK. Quando eu ls digitado entre aspas, que foi me fazendo um pouco de magia nos bastidores para corrigir um bug. Esqueci-me, como temos vindo a dizer que muitos de vocês no fóruns de discussão, o que fazer - vamos fazer isso agora - sudo yum-y update appliance50. Opa, que isso está escrito certo. Assim, o aparelho é como um sistema operativo. Está funcionando neste sistema operacional chamado Fedora. E agora por causa de minha conexão de internet lenta, eu tenho realmente hosed isso. Então, correndo yum update sudo, como dizem para fazer na conjunto de problemas, é, essencialmente, gosto de correr atualizações automáticas no Mac OS ou Windows. E a razão para executar esta muito no começo do conjunto de problemas é porque quando criamos o aparelho, eu desarrumada, e eu acidentalmente fez todos os seus programas olhar preto em uma tela preta, que é por isso que você não está vendo-os por padrão. Mas a versão mais recente do aparelho corrige isso. E eu vou consertar isso durante as férias uma vez que tenho Internet conectividade. Assim, as aspas apenas esconde o meu erro, muito discretamente, aparentemente. Outras perguntas? Sim? AUDIÊNCIA: Onde faz vem? [Inaudível] DAVID J. MALAN: Boa pergunta. Onde faz vem? É um programa do Linux que já existe há muitos anos, muito tempo antes CS50. E ele vem com um sistema operacional como o Fedora. Ele não vem da biblioteca CS50. Na verdade, as únicas coisas que vêm da biblioteca CS50 até agora, que temos visto, são GetString, GetInt, todos Obter as funções e, a seqüência de palavras e, em certa extensão, a palavra bool. Mas vamos brincar que além quando mergulhar no CS50 próprio aparelho. Então, sim, mais uma pergunta aqui. AUDIÊNCIA: Quando você disse fazer e, em seguida, buggy, como é que o computador sabe [inaudível]? DAVID J. MALAN: Boa pergunta. Então, quando você acabou de executar o make buggy1 ou fazer buggy2, como faz saber? Então, por padrão, se você digitar buggy1 fazer, fazer looks para um arquivo chamado buggy1.c. E então ele executa os comandos apropriados Clang, assim, substituindo o arquivo de saída padrão chamado a.out. Na verdade, se olharmos para o que fazem, o que - vamos sair desta. Se olharmos para o que fazem realmente estava fazendo, fazer buggy2, ele já está atualizado. Então deixe-me tirar o comando rm, o programa que eu escrevi antes. Digitando Y-E-S para confirmar que eu quero removê-lo. Se eu agora fazem, observe que nesta linha de muito tempo, há essa última coisa aqui,-o buggy2. Todos marca está a fazer é passar esse argumento, por assim dizer, a Clang, de modo que eu não tenho que digitá-lo eu mesmo. Tudo bem, então um par rápido administrativa anúncios. Assim, por seções, que começou oficialmente no próximo Domingo, você sempre quer trazer, se você tem um, um laptop. Se você não tiver um laptop, chegam a mim por deixar-me um e-mail. E nós vamos descobrir um fluxo de trabalho. O que geralmente você vai encontrar na seção é que eles são parte parte conceitual, hands-on. Nós vamos usar especificamente a seção de perguntas, parte de conjunto da semana problema, para percorrer algumas das material conceitual da palestra. E isso é tudo no conjunto de problemas atuais. E nós também vamos mergulhar em algumas actividades hands-on, por vezes de que será necessário para ser apresentado, por vezes de que não. Por exemplo, esta primeira semana, eles foram feitos apenas como um exercício de aquecimento. E você verá que esses problemas são realmente apenas isso. Eles foram feitos para ser relativamente pequeno, mas não necessariamente programas simples de escrever, que não são necessariamente emocionantes em si mesmos, mas são boas oportunidades para praticar com a sintaxe, com novas funções, no conforto de um onde você tem alguns de seus colegas se apresentar como bem como o seu TF. E o que vamos fazer ao longo do tempo é usar uma ferramenta chamada CS50 Spaces, em que em vez de apenas utilizar o aparelho CS50, você vai em vez de ir para uma página Web em um navegador, onde você poderá escrever código em uma janela do navegador durante a seção. E então, se você optar, seu companheiro de ensino pode, então, mostrar tudo o que você está digitando em sua tela em seu navegador janela-se na frente da classe, seja de forma anónima ou público, para que ele ou ela pode, então, percorrer com seus colegas o que você fez bem, o que você não faz bem. E mais uma vez, a certeza de tudo isso pode ser bem anónimos. Mas vai ser uma boa oportunidade para muito mais interatividade do que algo como palestra permite. Enquanto isso, nós vamos ter essas coisas, chamado de super seções, que são opcionais, mas estão abertos a todos em a classe, para que você possa fazer isso mais coletivamente para problema definido. Aqui está o calendário. Isso também é publicado na página inicial em cs50.net. Observe que haverá um hacker específica- uma tarde de amanhã. E vamos filmar um hoje e um amanhã e postar os online dentro de 24 horas. Portanto, não se você não pode fazer qualquer uma dessas vezes, a se preocupar. E, novamente, o cronograma está online agora em cs50.net. Em termos de corte em si, você deveria ter obtido uma enviar e-mail com instruções para ir para a página inicial do curso para encontrar a sua seção. Se a vida mudou e você precisa mudar sua seção, não um problema. Volte para o mesmo URL, cs50.net/section, singular, e você vai preencher o formulário semelhante, de modo que você pode em seguida, dar-nos as suas preferências. E nós vamos acompanhar até o fim da semana, como o que pudermos acomodar. Na semana passada, lembre que propôs usar CS50 discutir, ferramenta do curso, discussão em aula. Então, nós tivemos 40 perguntas que foram feitas e respondidas durante a palestra. Portanto, pareceu funcionar bem, por isso vamos continuar tentando fazer isso. Se, durante a palestra, você não me sinto confortável levantamento sua mão, não um problema. Ir para cs50.net/discuss, postar lá, e um de nosso ensino companheiros vão quer respondê-la eletronicamente ou aumentar a sua mão em seu nome de forma anônima para pedir, dependendo sobre a natureza da pergunta. E em termos de feedback, em geral Série de Exercícios será devolvidos no prazo de uma semana. Porque é preciso um pouco de tempo para seções de alcançar de equilíbrio, o primeiro pset, 0 e 1, será um pouco atrasadas como as coisas se acalmarem. Mas fique atento para que nas próximas semanas. Tudo bem, então deixe-me colocar no meu grave voz por um momento. Portanto, este é realmente um clima interessante para ser tendo essa discussão, o que com todas as outras coisas acontecendo na mesma campus relacionado. Mas CS50 tem certamente teve sua história deste especial tema, na medida em que a cada ano, este curso, para muitos anos, Ad-Boards cerca de 3% da classe. Este ano, mais recente, de 2011, CS50 Ad-Embarcado de 35 alunos. Este não é, penso eu, devido à falta de clareza. Compreender que, no decurso do programa, existe uma página de declaração explicando onde as linhas são. Esta afirmação se repete em cada um dos problema define na primeira página. Então eu falar isso hoje realmente apenas para fazer pessoas conscientes deste. E nós tentamos coisas diferentes. E o que eu pensei que iria fazer hoje é apenas ter um momento para realmente olhar para alguns dos casos do passado que surgiram. Ao invés de manter esses segredos tão sujos, na verdade apontar o que os alunos fizeram e como temos detectado e realmente o que a motivação principal é para mesmo tendo essa conversa. Então, com o que disse, a linha é essencialmente isso - por o programa, você é bem-vindo, que são incentivados, para conversar com colegas de classe. Esse é o propósito de ter estes colaborativo o horário de expediente em Annenberg e incentivar as pessoas para a final do projeto para trabalhar juntos. Mas a linha é desenhada quando chega a hora de realmente escrever sua solução final. Falando em Inglês, totalmente bem, falando em código pseudo totalmente bem. E-mail para um colega seu pset, deixando-os olhar sobre a tela como as mãos continua digitando, ao longo da linha também. Não olhar para o currículo para as linhas específicas. Mas só para pintar um retrato de como este é, infelizmente, uma realidade, perceber que existem sites por aí que ter soluções a partir desta classe e muitas outras classes. O fato de que você ou cerca de 3% de vocês sabem que isso existe significa que sabemos que isso existe. O fato de que existem sites como este onde você pode pagar alguém para realmente fazer seus conjuntos de problemas - isso foi um caso real que surgiu no ano passado. Este é um site chamado odesk.com. E Tim era o nome da pessoa aqui que estava postando em este site e pediu a alguém para fazer o seu pset 7 em Neste caso em particular. Bem, é muito odesk.com Google-capaz, e nós também somos muito bom pesquisando. Aqui, também, existem sites - e este é bastante atroz, francamente. [Risos] DAVID J. MALAN: O engraçado sobre este site é se você ler a página Sobre, eles falam sobre a sua empresa cultura e como o serviço ao cliente é o seu número um prioridade, para certificar-se de que suas atribuições chegar virou na hora. Mas, falando sério, novamente, o fato de que esses sites existir, percebemos que, também, estão cientes de estes tipos de sites. E para dar uma sensação de que forma isso geralmente leva, geralmente não tem grandes escândalos, onde as pessoas estão a colaborar em qualquer tipo de escala, mas sim É nestes momentos de fim de noite de fraqueza, em que você tem assim muito a fazer, é 04:00, você está exausto, e você pensar a si mesmo, bem, deixe-me dar uma olhada no meu colega de quarto ou o código do meu amigo ou similar. E as manifestações desta infelizmente envolver Estudante Um algo a apresentação como esta e apresentação de B Estudante algo assim, o que certamente, em um computador ciência de classe, é extremamente fácil para os cientistas da computação para detectar com software. Este é um outro paradigma comum, onde tenho a sorte de vindo a trabalhar ao lado de alguém, talvez falando em Inglês, bem pseudocódigo. Mas então chega a hora de realmente apresentar, e os Série de Exercícios apenas se trocadas via e-mail ou Dropbox ou similar. Mas, numa tentativa de tornar menos evidente que esta é o que aconteceu, então é isso que está submetido. Isto, também, não faz viagem até bem escritos peças de software como o que temos de realmente detectar estes tipos de coisas. E de fato o que fazemos é um software de execução que compara todos submissões deste ano contra todo o passado ano submissões, contra tudo o que encontramos na Internet, contra qualquer site de emprego lá fora. É tudo muito automatizado. E, assim, fazer isso muito em justiça grande os 97% que estão realmente trabalhando suas bundas, neste e em outros classes e colocando em todos que o esforço para que o trabalho eles finalmente apresentar é a sua própria. E eu posso ir para as idades. Estes são apenas um punhado de casos do ano passado. Alguns alunos submetidos esses arquivos da mesma forma para pset 2, pset 3, pset 4, pset 5, pset 6, pset 9. Neste caso, esta foi questionário 0 e no último ano, onde dois estudantes apresentado esta frase idêntica entre muitos outros, "A pedido do tipo -" ponto, ponto, ponto. Assim, mesmo em uma classe de 600 que nós detectar esta em questionários apresentados. Assim, em breve, este -, francamente, eu odeio ter esse tipo de conversa - mas este é realmente um esforço deliberado este ano para tentar reduzir esse número. Porque mesmo que dizer que estes tipos de coisas a cada anos, eu acho que a realidade de ter morado nela para poucos mais segundos do que o habitual e, na verdade, apenas apontando que o que pode parecer, não é, não um negócio tão grande, pelo menos acho que volta a este momento especial, tanto na justiça para si mesmo e para seus colegas aqui. Então, se você tiver alguma dúvida a respeito de onde a linha é, por favor, chegar a mim pessoalmente. Mas a resposta é sempre, completamente estressado no último minuto, dinheiro em um dia de atraso. Ou se é uma questão de não ter nenhum dia de atraso, honestamente, me e-mail pessoal. Nós vamos descobrir alguma coisa. Por favor, não coloque o tempo aqui em Harvard em risco. Agora, eu pensei que deveria aliviar o clima, então eu incluído este como o próximo slide. [Risos] DAVID J. MALAN: Este site foi ótimo. Eu realmente tenho um pouco distraído. Há um presente. E então este foi incrível. Ok, então pense que gatinho tarde da noite ao fazer destas decisões. Todas as coisas, certo modo de volta para mais diversão e menos grave, como condições. Tudo bem, então nós conversamos um pouco sobre isso. Isso é algo que provavelmente é bastante familiar a partir de o mundo do Scratch. E no mundo do Scratch, temos essa necessidade, por vezes, a ir fazer garfos na estrada. Ou isso ou aquilo ou esta outra coisa aqui. E quando a gente quer fazer isso, podemos usar, em C agora, isso se outra construção. E então aqui temos expressões booleanas. Por exemplo, expressões booleanas aqui, podemos OU los em conjunto, no sentido de que têm essa condição OR essa condição. Podemos e juntos, no sentido de que queremos verificar essa condição e essa condição. E aqui temos um switch agora, que não é tão sintaticamente semelhante a esses tipos de condições, mas nos permite fazer o equivalente a if, else if, else if, else se, e semelhantes, bastando enumerando-los, caso a caso a caso a caso. Então vimos os da última vez. E então começamos a tocar em coisas como loops. Vimos um destes apenas um momento atrás. Mas há essas outras construções de looping. Por exemplo, este aqui. Assim, enquanto (condição), fazer esta coisa de novo e de novo. Então, fundamentalmente, o que parece ser diferente entre esta loop e este loop enquanto aqui? Este loop e este loop while. Sim? O que é isso? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Ótimo. Assim, enquanto na condição de loop, há claramente sintaxe mais. Há essa inicialização, há essa atualização. Em um loop enquanto, há apenas essa condição. Portanto, parece que é um pouco preparados para baixo em relação ao de loop, o que significa que, se quisermos ter variáveis ​​e queremos ter incremento, nós realmente temos que fazer isso nós mesmos. Então deixe-me ir em frente e abrir gedit. Deixe-me passar para o aparelho. E vamos fazer um rápido exemplo de que distingue um destes a partir do outro. E no fundo da minha mente aqui, devo dizer uma coisa. Eu especificamente mencionado o nome de Tim. Tim era, na verdade, alguém que um estudante tentou encontrar para fazer seu dever de casa para eles. Nós não tivemos nenhuma Tim que em determinado ponto. Então percebe, para que eu não divulgado um estudante, que não era um aluno. Ele era uma pessoa aleatória na internet fazendo coisas no ano passado proxy. Então nós achamos que, também. Portanto, neste caso aqui, deixe-me ir em frente e abrir um novo arquivo. Arquivo, Novo. Isso me dá um guia aqui. Deixe-me ir em frente e salve-o como loop.c. Deixe-me ir e clique em Salvar. E então, aqui, vamos em frente e começar a escrever # Include. Deixe-me fazer zoom in Agora vamos fazer int main (void). Agora deixe-me ir em frente e fazer para (int i = 0; i < oh, 10; i + +). E agora eu estou indo para a frente e não imprimir a estrela que eu fez anteriormente. E então, no final deste programa, nós apenas estamos indo para imprimir uma nova linha, apenas para que meu prompt não olhar tudo bagunçado. retornar 0. Parece sintaticamente corretas? Até agora. Então, vamos ver. Então deixe-me afastar, ir para a minha janela de terminal. E deixe-me ir em frente e executar loop, porque eu chamei esta loop.c. coisa Então faça loop. Parece compilar OK. Deixa-me correr loop, e agora Enter. E parece ter impresso 10 estrelas. Então vamos converter isso em um loop while e ver o que os tipos de questões que tropeçar. Então, ao invés disso, deixe-me entrar aqui e dizer enquanto i é inferior a 10 - deixe-me livrar do laço for. OK, então nós temos alguns problemas já. Assim, a condição é a mesma, mas eu estou, obviamente, falta a inicialização. Estou perdendo a incrementação. Então, o que o compilador provavelmente dizer-me quando tento compilar este programa? Sim? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Ótimo. Por isso, vai dizer algo como não declarado - neste caso, a variável i. E, de fato, o uso do identificador não declarado i. E assim, em contraste com linguagens como PHP e Python e Ruby, com a qual alguns de vocês podem estar familiarizados, onde você pode apenas uma espécie de início utilizando variáveis querendo ou não, e não precisa se preocupar com os declarar explicitamente sempre. Em C e em linguagens como Java e C + +, você tem que ser Super explícito. E se você quiser uma variável chamada i, você tem que me dizer o tipo de variável que é. Então nós vamos ter que resolver isso da seguinte forma. Eu vou ter que ir até aqui e digite int i, portanto, Tenho declarado uma variável chamada i. Agora, eu tenho pulado um passo. Eu, obviamente, não inicializado, mas vamos ver se que em parada pelo Clang marcas reclamando. Então deixe-me refazer este programa. Tudo bem, agora é só reclamar por uma razão diferente. "Variável" i "não é inicializado quando utilizado aqui." Tudo bem, então isso é muito explícito. Inicializada apenas significa defini-lo igual a um valor. E nós não fizemos isso, então deixe-me tentar igual a 0. Agora vamos tentar isso de novo e voltar a executar Clang. Compilados neste momento. E eu estou prestes a executá-lo. Mas laço velho grande infinito, porque eu fiz o inicialização, eu fiz a condição, mas eu nunca fiz qualquer tipo de incremento. Então, como posso fazer a incrementação? Bem, em um loop while, parece que eu vou ter para fazê-lo dentro do loop, porque assim como o primeiro exemplos semana de fazer construções de iteração, como com as meias e com a auto-contagem, nós tivemos que fazer algo no final, como ir de volta para a linha seguinte. E se eu ir em frente e fazer isso i + + aqui? Não vamos nem compilar este. Apanha-me já. O que está errado aqui? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Então, definitivamente não é int. É i. E as chaves, como antes, recuo não é suficiente. Então agora eu tenho essa construção. Então, enquanto eu for menor que 10, imprima uma estrela, então incrementar i. E a forma de um tempo obras de laço é que, logo que você apertar o inferior da alça, o que neste caso se parece com a linha 10, ele vai voltar para a linha 6, altura em que o condição será verificada novamente. E se eu ainda é menor que 10, vamos fazer linhas 8 e em seguida, 9, depois vamos acertar 10, e voltar a 6, de novo e de de novo e de novo e de novo, desde que i é menor que 10. Então vamos voltar a correr fazer aqui. Ok, nós compilamos bem. Deixe-me re-correr loop. E agora, na verdade, parece funcionar. Então prós e contras aqui? Bem, até agora não há, na verdade, um conjunto de plo - tão bonito. Tudo bem, que era um - ah, isso foi um acidente. Tudo bem, então vamos voltar para o loop. Assim, para os loops são bons porque eles são super explícito. E mesmo que eles estão um pouco desajeitado para escrever, é muito poderosa e permite que você faça várias coisas ao mesmo tempo. Enquanto laços não parecem ter uma enorme quantidade de valor apenas ainda, porque parece que só temos de fazer mais trabalho. Temos que colocar a inicialização até aqui, o atualizar aqui, e temos que lembrar de fazer tudo isso. Então, vamos ver com o tempo que laços, enquanto na verdade emprestar si para apenas diferentes contextos, dados diferentes estruturas como listas e tabelas de hash, coisas que nós vamos chegar a meados semestre. Mas, por agora, sei que há este terceiro tipo conhecido como um do- while. E temos visto isso brevemente. E isso pode ser super atenciosa com pset 1. Toda vez que você quer fazer algo e depois verificar se o utilizador colaborou, e se eles não o fez, faça-o de novo, um do- while se presta a esse tipo de lógica. Porque, como a ordenação de cima para baixo aqui sugere, que significa, literalmente, fazer isso. E fazer isso de novo e de novo, o que pode ser isso? Talvez isso signifique GetInt chamada ou GetString e depois verificar o valor de GetInt ou GetString e gritando ao usuário se eles não têm cooperado, pedindo-lhes de novo e de novo e de novo. Onde você quer fazer algo uma vez, em seguida, verificar alguma condição. Então, vamos tentar isso. Deixe-me realmente mudar isto agora para um loop do-while. E eu estou indo para ir em frente e fazer o seguinte. Então faça o seguinte. Vamos fazer int i = GetInt (), mas vamos primeiro dizer que o usuário o que fazer. Então, um pouco diferente desta vez. "Dê-me um int". Então, eu vou usar printf para isso. E agora eu vou descer aqui, e eu vou fazer isso enquanto i é, digamos, maior que - vamos ver, i é, digamos, menos que 0, ou i é superior a 10. Em outras palavras, quer um número de 1 a 9, só arbitrariamente. Então, eu estou usando uma expressão combinada Boolean aqui para certificar-se de que i seja inferior a 0 ou superior a 10, em que caso, vou fazer este loop aqui novamente. Então, novamente, fazer isso - enquanto i é menor que 0 ou i é maior do que 10. Então agora vamos seguir em frente e fazer isso uma vez que fizemos isso. Vamos fazer um teste de sanidade rápido. printf ("Obrigado, i é% d", i). Portanto, este programa simples pede ao usuário para um int, certifica-se de que é dentro de algum intervalo de 1 a 9, inclusive, e depois agradece ao usuário, lembrando-lhes o que eles apenas digitada, assim como um teste de sanidade pouco. Mas vamos ver se isso funciona como pretendido. Deixe-me ir de cabeça para baixo aqui e voltar a correr fazer loop. Hmm. "O uso de identificador não declarado 'i'". Isso é estranho. Eu pensei que nós resolvemos isso. Mesmo sintoma, mas de código diferente. Sim? AUDIÊNCIA: [inaudível] dentro de dois, temos que [Inaudível]. DAVID J. MALAN: Exatamente. Então, isso realmente nos leva a um tema conhecido como escopo. Acontece que C, de novo, realmente leva você literalmente. E se você faz algo como este onde você declarar um int e depois atribuir-lhe algum valor, mas você faz isso dentro de uma par de chaves, o que C faz é ele assume que você só quero os bits 32, conhecidos como i para existir dentro do contexto dessas chaves, dentro do contexto de linhas 6 a 9. Então eu é declarada, e é atribuído um valor na linha 8, mas logo que você começa fora de linha 9 abaixo da chaveta, eu já não está em escopo, por assim dizer. S-C-O-P-E. Não é mais no contexto certo. Portanto, agora não há i, por isso é como se não tivesse mesmo declarou ele em tudo. Então, o que é uma correção em seguida, para algo como isso, se o razão é que eu seja declarada dentro das chaves, que aparentemente é ruim? Aqui? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Yeah. Assim, podemos inicializá-lo fora. Então deixe-me ir em frente e eliminar as partes declaração em que Eu especificar o tipo, e deixe-me fazê-lo aqui. Assim, na linha 5, que agora diz "Dê-me um int." Chame-o i. Observe na linha 9, eu não quero fazer isso, porque eu já tem os bits 32. Eu não quero pedir ao computador por um diferentes de 32 bits. Eu quero usar esses mesmos 32 bits. E agora, porque eu é declarado na linha 5, ainda é legítimo usá-lo na linha 11 e linha 12. Então deixe-me tentar recompilar isso e ver se Clang pára de gritar. fazer loop. Portanto, agora é "declaração implícita da função 'GetInt' é inválida na C99. "O que é isso? Sim? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Yeah. Portanto, agora que eu estou realmente usando GetInt, isso não é algo que só vem com C. Isto vem de CS50. Então precisamos disso aqui. E deixe-me voltar para o prompt de baixo aqui e re-executar o make. Ok, finalmente. Agora nós temos que resolver e que o erro dos outros. Deixa-me correr loop e ver o que acontece. "Dê-me um int." Eu vou dar-lhe 11. Eu vou dar -1. Eu vou dar foo. Eu vou dar 5. E agora ele realmente funciona. Mas o prompt mudou para uma razão aqui. Porque é que dizem que repetir uma dessas vezes, mas me dê um int outras três vezes? Por que é que o comportamento diferente? AUDIÊNCIA: deu-lhe uma corda. DAVID J. MALAN: Desculpe? AUDIÊNCIA: Você deu uma corda. DAVID J. MALAN: Yeah. Portanto, deram uma string neste terceira tentativa, quando eu digitei foo. Foo é uma string. Obviamente não é um int. E da maneira que CS50 implementou GetInt é que não verificar se algo é menor que 0 ou maior do que 10 para você, porque como sabemos de antemão que tipo de int que você quer? Mas podemos minimamente verificar para você, se o usuário pelo menos digite um número inteiro? E se não o fez, nós gritar com o usuário digitando "repetir" na tela. Portanto, agora temos um programa que é looping. Okay. Agora, qual destes é o melhor tipo de construção? Então é aqui que as coisas começam a ficar um pouco confuso, o fato de que você deve se lembrar de declarar uma variável-se aqui se você quiser usá-lo dentro de alguns chaves e fora. Mas mesmo que isso parece um pouco enigmática em primeiro vista, apenas mais uma vez, lembre-se a lógica simples. A fim de usar qualquer coisa em C, se é uma função ou é uma variável, você tem que incluí-lo se é uma função em alguma biblioteca, ou você precisa declarar. Mas agora você precisa estar consciente extra do fato de que você está declarando que no âmbito direita. Você não está colocando muita força dentro de parênteses. Então deixe-me realmente reverter. Se voltarmos ao nosso, por exemplo, de mais cedo, e eu vou de volta para para int, int i = 0; i <10, i + +, e eu printf fazer estrelas, como este, em seguida, paren perto, e agora printf i é agora - de acordo com a mesma lógica, o que vai acontecer quando eu tento compilar este programa? AUDIÊNCIA: identificador inválido. DAVID J. MALAN: Então é outro identificador inválido, identificador não declarado. Agora, a razão é um pouco diferente. Há, obviamente, não há chaves aqui, mas o mesmo idéia, a mesma história de escopo se aplica. Se você declarou uma variável como i dentro de uma loop for, mesmo se você não tiver explicitamente escrito o crespo chaves, pensar-los mentalmente como ainda estar lá, em que caso eu só é válido dentro do loop. Não é válido quando você chegar para a próxima linha, que em neste caso, é agora 10. Assim, apenas algumas questões de âmbito e similares. Tudo bem, alguma dúvida? Tudo bem, então esse é um tipo de programa trivial pouco, imprimir apenas pequenas estrelas. Mas vamos ver se você se lembra desta música aqui. Esta é uma música extremamente irritante as crianças cantavam em o ônibus escolar e afins. Mas o que é bom nisso é que ele tem essa ciclicidade, qual é "99 garrafas de cerveja na parede, 99 garrafas de cerveja. Tome um para baixo, passe adiante, 98 garrafas de cerveja na parede. "E então a canção repete a 97, depois 96, depois 95, 94, todo o caminho para 0 se você realmente tem que agora no ônibus. Portanto, este é um bom programa para classificar de implemento, porque a minha Deus, se você poderia apenas implementar isso com alguns linhas de código, você pode cuspir as letras inteiras para este canção muito rapidamente. Mas ao longo do caminho, podemos começar agora desmembrar alguns dessas construções básicas looping e agora também introduzir funções que nós escrevemos nós mesmos, retornar valores que passar ao redor. Mas, primeiro, por que não ir em frente e ter a nossa cinco minutos quebrar aqui? E quando voltarmos, vamos cantar essa música. Tudo bem, então estamos de volta. E quando eu digo agora vamos cantar essa música, eu quero dizer programaticamente, não verbalmente. Portanto, temos aqui beer1.c, que é uma implementação deste música em particular. E só para ficar claro, para aqueles não familiarizados com o que esta coisa parece, deixe-me ir em frente e fazer beer1, Enter. Agora deixe-me correr beer1, eo que vamos ver - quantas garrafas de cerveja haverá? Eu vou digitar em 99, como diz a canção. Enter. E agora se percorrer - oops - se percorrer tudo isso, nós vamos ver que este, de fato, cantar a música inteira. Espere um minuto. Minha barra de rolagem é um pouco confuso. Vamos usar a janela maior. Então beer1, 99, lá vamos nós. Portanto, temos aqui toda a música, cantada muito mais rápido do computador do que poderia ter sido por nós. Então, observe, porém, a natureza cíclica aqui. Ele diz que 99, então 99, em seguida, "tomar um baixo, passá-lo volta ", então 98. E agora ele repete uma e outra vez. Portanto, esta é realmente uma oportunidade perfeita para algum tipo de looping construir. Repare que eu sou o tipo de corte de um canto aqui. Repare que eu estou dizendo "98 garrafas de cerveja na parede, 97 garrafas de cerveja na parede ", e que era tão que quando chegarmos a um garrafas de cerveja, eu não tenho se preocupar com a gramática do Inglês. Mas também podemos corrigir isso com um pouco mais de um se condição, talvez. Se esse número é singular, vá em frente e dizer "garrafa", caso contrário, se ele é plural, dizer "garrafas". Mas, por agora, estou completamente corte que canto. Então vamos ver o que temos aqui. Então, nós temos alguns comentários no topo. Estou incluindo estas duas bibliotecas, como temos sido comumente. E agora deixe-me rolar para a primeira linhas de código. Linha 17 começa principal. Linha 21 e 20 tem o número de garrafas de cerveja haverá? E então eu chamo GetInt. E agora eu tenho um pouco de um teste de sanidade. Portanto, esta é uma convenção que vamos agora começar a adoptar para mais rigor verificar a entrada do usuário. Às vezes você apenas não quer levá-los novamente e de novo e de novo. Se o usuário se parafusos e não cooperar, tudo bem. Saia e simplesmente não lidar com eles. E é isso que eu estou fazendo aqui. Se n é menor do que 1, eu estou indo só para gritar com o usuário, "Desculpe, isso não faz sentido." E então eu vou arbitrariamente retornar 1. Então, novamente, esta é apenas uma convenção para se acostumar. Por agora, levá-lo na fé. Mas, até agora, temos sido sempre retornando 0, porque dissemos retornando 0 denota o quê? AUDIÊNCIA: Sucesso. DAVID J. MALAN: Sucesso, isso é tudo. Portanto, agora que finalmente estamos começando a pensar em não-sucessos - em outras palavras, os casos de canto, as condições de erro - agora eu tenho uma fonte infinita, ou pelo menos quatro bilião possíveis coisas que podem dar errado em meus programas. E eu posso começar a atribuir-lhes números individuais. Agora, geralmente basta apenas voltar algo diferente de 0. Então, nós vamos simplesmente retornar um por agora. Mas a razão para retornar 1 é que, logo que você voltar 1, acho que o que acontece com o resto do programa? Que ele pare. É isso aí. Assim, o fato de que estou retornando 1 é efetivamente curto-circuito a execução deste programa, de modo que nada abaixo da linha de 27 vai continuar a execução. Assim que retorna principais, que é ele. Tudo bem, por isso, se o usuário faz cooperar e chegar a linha 30 porque digitaram um número legítimo, aqui é o meu implementação desta canção. Então eu primeiro imprimir um caractere de nova linha, apenas para estética. Agora tenho um loop. E repare que eu estou fazendo as coisas com um pouco de uma direção diferente. Eu não tenho que fazer menos do que, eu não tenho que fazer + +. Eu posso dizer que em vez inicializar uma variável i, configurá-lo igual a n, o número que o usuário digitou, então faça o seguinte, de forma enquanto i é maior que 0, então i - uma vez que você terminar uma iteração deste loop. Assim, podemos contar para baixo, usando um loop também. Agora, esta é uma semana bastante coisas agora, com printf. Assim impressão "% garrafas d de cerveja na parede." Print "% d garrafas de cerveja. "" Tome uma para baixo, passe adiante. "Imprimir "% D garrafas de cerveja na parede." Então ainda é d%, mas notar que o argumento de printf está mudando. Após a vírgula, tenho eu, porque eu quero dizer 99. Após esta vírgula, tenho eu, porque eu quero dizer 99. Após esta vírgula, tenho i - 1, porque eu quero dizer 98 em esta primeira iteração, e assim por diante. E agora aqui, eu só tenho uma observação estúpida. E depois a linha 42, eu retornar 0, por convenção, o que significa que está tudo ok. Então, o que se eu goofed? O que pode um erro comum aqui estar? Bem, e se eu acidentalmente disse bem, eu quero contar a 0, eu quero 0 garrafas de cerveja na parede? Então, digo, i é superior ou igual a 0. O que vai ser o sintoma de que agora eu ver se eu recompilar beer1 e executá-lo? AUDIÊNCIA: Negativo. DAVID J. MALAN: Sim, ele vai ir negativo. Este é um erro off-by-one, incrivelmente erro comum de fazer. Vamos realmente voltar para a janela do terminal e fazê-lo aqui, para que possamos ver mais de uma vez. Enter, 99 garrafas de cerveja. Perto, mas fomos sempre tão pouco longe demais. Nós cantamos a música muito baixo, de modo que agora atingiu o número negativo. Por isso, não funciona muito bem. Tudo bem, então podemos facilmente corrigir isso, indo de volta para a jeito que era. Mas o que são algumas oportunidades agora para melhoria? Bem, deixe-me abrir beer2.c e desça aqui e dar uma olhar para esta versão. Qual é a primeira coisa que salta em você como diferente nesta versão aqui? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Sim, assim, não mais eu, porque ocorreu a mim que você sabe o que eu estou pedindo ao usuário para n, e então eu sou definindo i igual a n, e então eu vou mudar eu, mas eu nunca sou n tocando novamente. Então o que diabos era o ponto de você alocar outro 32 bits chamado i apenas para que eu possa ter uma variável diferente? Portanto, neste caso, eu meio que reconheceu que desnecessária característica de projeto. E agora vou dizer enquanto n é maior que 0, ir frente e imprimir a mesma canção, passando um n para printf como o segundo argumento, e n - 1 como o segundo argumento aqui. E então, em cada iteração do loop, vá em frente e apenas decrementar o próprio n. Agora, funcionalmente, este programa vai ser idênticas. Se eu digitar 99, n começa em 99. Eu decremento, decremento, decremento, decremento. Eu estou indo para obter todo o caminho para "Uma garrafa de cerveja em a parede, uma garrafa de cerveja. Tome um para baixo, passe adiante. 0 garrafas de cerveja na parede. "O fim, porque eu fiz obter a condição correta. É maior que 0. Eu não cometer este erro. Então, o que é melhor, uma versão ou a versão de dois? Então eu ouvi um monte de murmúrios para dois. Por que dois? O que é isso? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Ah, ok. Então ele não vai abaixo de 0, mas lembre-se, em uma versão, a versão original correto não ir abaixo de 0 também. Então lembre-se que esta é a versão correta. Então, vamos pelo menos comparar as duas versões corretas. O que é um argumento a favor da versão dois sendo, mmm, melhor? Sim? AUDIÊNCIA: Ele usa menos espaço. DAVID J. MALAN: Ok, então ele usa menos espaço, certo? Considerando uma versão de 32 bits usado para n, e depois outro 32 bits para i. Versão dois apenas usa 32 bits para n, a fim de que parece ser uma vantagem. Outros pensamentos? Alguém quer argumentar em favor de uma? Sim? AUDIÊNCIA: Você tem que usar linha extra de código para n -. DAVID J. MALAN: Ok, com certeza. Então, isso é justo. Portanto, este justo, pelo menos para mim - Quer dizer, isso realmente se sente um pouco mais confuso, o fato de que Eu não posso classificar de encapsular toda a minha lógica em um linha bonita, o loop, como o laço for possível. Aqui, eu meio que tenho para alinhavar este n - no fim do ciclo, porque é logicamente necessário. Mas que tipo de esfrega-me o caminho errado, apenas porque parece separada da lógica de até aqui, embora, mais uma vez, que é necessário. Outros pensamentos? Sim? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Yeah. Assim que se você em vez disso, no final da canção, queria imprimir novamente o nome da música? Como "Obrigado por jogar 99 garrafas de cerveja", ou algo assim bobagem como essa? Mas o ponto é, você queria ter acesso ao valor original. O fato de você ter mutado ou mudado em cada n iteração e, portanto, ter destruído o seu valor original Significa que você não pode fazer isso no final. Agora, sem dúvida, nós claramente não quer fazer que neste programa. Então, quem se importa? Mas isso é um ponto muito válido. E para ser honesto, realmente não há uma direito responder aqui. Ambos são igualmente corretas. Eu poderia ser convencido de qualquer maneira. Posso dizer que, em geral, é um bom princípio, se você perguntou o usuário para algum valor e você armazenado em uma variável como n, apenas uma espécie de em princípio, é provavelmente bom para manter esta situação. E todos os dados que você quer se transformar de novo e de novo, apenas dar-te uma cópia da variável, apenas para que você ter acesso ao original. Você está gastando mais de 32 bits, mas a realidade é esta computador, como, dois gigabytes de memória RAM estes dias, e nós estamos discutindo acerca de 32 bits? Realmente não um negócio tão grande. E mesmo neste dispositivo aqui, com uma meia de um show ou uma gigabyte de memória RAM, 32 bits versus 64 bits, não um grande negócio. Certamente, hoje, que vai ser muito oprimido pelo tamanho do programa em si, que vai ser centenas kilobytes, se não alguns megabytes, estes dias. Então preocupações razoáveis, não uma resposta certa. Mas pelo menos esses são os pensamentos que deve começar a passar por sua mente? Porque em pset 0, mesmo que nós realmente só esperar correção, ou pelo menos a renúncia de vários bugs que você pode ter encontrado, à medida que avançamos, o design é vai ser outro aspecto fundamental, tanto de escrever código e também a avaliação de código. E assim, pelo menos, reflectir sobre coisas como esta. E só porque algo funciona não significa que ele é bom, não quer dizer que é bem concebido. E isso é uma das coisas que os companheiros de ensino e conjuntos de problemas nos ajudará a provocar peça ao longo do tempo. Bem, o que dizer, vamos dizer, esta versão aqui? Deixe-me fazer algo um pouco sexy aqui em um momento. Primeiro deixe-me livrar desta. E agora vamos corrigir esse problema gramatical. Assim, nesta versão, eu quero corrigir a gramática de forma que, ao invés de apenas dizer s entre parênteses, como "garrafa" ou "garrafas" - Eu não quero cortar esse canto - Eu também quero imprimir dinamicamente a palavra "garrafas" ou "garrafa", assim, usando espaços reservados estes% s hoje. Então eu preciso condicionalmente verificar qual é o valor de i. E se é um, eu quero dizer "garrafa", e se é qualquer coisa outra coisa, eu quero dizer "garrafas". Então, vamos tentar fazer isso. Então, se eu == 1, então deixe-me ir em frente e declarar - Eu preciso de uma string, então deixe-me fazer string s1, porque é a primeira corda que me importa agora. Eu vou dizer "garrafa". E então, vamos ver, string s2 - e eu vou explicar para onde estou indo em um momento - "Garrafas". Então, lembrar que, nesta música, precisamos ser capazes para imprimir coisas, duas palavras diferentes potencialmente. Então, se olharmos para trás, aqui, notar que quando chegarmos ao este exemplo aqui ", duas garrafas de cerveja na parede, duas garrafas de cerveja, tomar um para baixo, passe adiante ", eu quero esta quarta linha para agora dizer "uma garrafa de cerveja na parede ". Então eu preciso decidir, eu quero dizer" garrafas "ou "Garrafa"? Então eu vou dizer arbitrariamente, tudo bem, Vou agora declarar uma variável chamada s1 string, um, que vai ficar ligado aqui e também aqui, porque essas palavras são sempre idênticos, apenas por causa da natureza da música. E eu vou chamar s2 qualquer palavra que eu quero eventualmente aparecem por aqui. Agora, literalmente, 99 vezes de 100, que vai ser o mesmo em ambos os casos, porque 3 é plural, 2 é plural, 4 é plural. Mas, neste caso, canto, onde se obter a 2 e, em seguida, 1, ou mesmo 1 e 0, eu preciso esta lógica. Então eu tenho que passar algum tempo no meu código recebendo esse direito. Então, se eu fizer isso, se i == 1, então s1 definido igual a "garrafa" e s2 igual a "garrafas", porque isso vai ser para um garrafa, e isto será por 0 garrafas. E este aqui, o que isso representa? Só para ficar claro. Este é apenas um comentário. Assim, o fato de que você pode ter comentários de uma linha significa que você pode comentar o seu código como este, mas outro comum paradigma, também, é que se você tem uma frase super-curto que você quer colocar a si mesmo e que é apenas mais legível para colocar que à direita no final da linha de código, você pode absolutamente fazer algo assim. Então agora o que se eu fizer isso? Else if i não é igual a 1. Então estrondo iguais - ponto de exclamação é conhecido como "bang". Então estrondo = 1. Então, se eu não for igual a 1, o que eu quero fazer em vez? Bem, a primeira palavra que eu quero ser o que? Então deve ser uma cadeia de "garrafas" para garrafas plurais, e então este será plural "garrafas", bem como, por agora. E vamos ver se isso realmente nos leva a onde queremos ir. Portanto, agora se eu rolar por aqui, perceber que eu estou conectando Não só eu, mas S1. Estou ligando i e S1. E, em seguida, aqui em baixo, sou menos 1, o qual é o mesmo que antes, mas s2. Em outras palavras, eu quero a palavra Inglês para mudar de acordo nessa lógica. Agora, já há alguns problemas neste código. O que está quebrado já fora do portão aqui? Sim? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Exatamente. Então eu já violou a lição de escopo. Então eu declarou S1 e S2, mas eu tenho feito isso dentro de chaves, o que significa que, sim, esse código irá trabalhar até até a linha 42, mas assim que eu bati linha 43, acho que não existe mais? Bem, acho que já não é de âmbito - nem S1 ou S2. Então nós temos que corrigir isso. Então deixe-me apagar as declarações. E eu vou deixar os nomes das variáveis ​​e apague esta aqui e excluir isso aqui. E em que linhas devo realmente declarar essas coisas? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Sim, então, provavelmente, até aqui, 33-ish. Assim string s1 e string s2. E não é que, eu posso fazer isso. Se você está declarando duas variáveis ​​do mesmo tipo, você pode realmente usar apenas uma vírgula e fazer isso em C. Todos bem, agora eu tenho duas variáveis ​​- S1 e S2. Estou atribuindo-lhes valores nestes condições aqui, ou aqui. E então eu estou usando-as abaixo. Como está isso agora vai dar certo? Bem, é ainda um pouco de buggy, mas vamos pelo menos ver quão longe chegamos. Então deixe-me ir em frente e fazer beer3. É este beer3? Sim, este é beer3. E agora deixe-me ir em frente e correr beer3. 399 99. Provavelmente, podemos ignorar a maioria deles. E aqui em baixo, olha isso. "Uma garrafa de cerveja na parede, uma garrafa de cerveja, tomar um para baixo, passe adiante, 0 garrafas de cerveja na parede. " Mas eu estou chamando a sua atenção para apenas metade da solução. Tipo de asneira aqui. Portanto, parece que os casos de canto surgem quando i é igual o que dois valores? AUDIÊNCIA: 2, 1. DAVID J. MALAN: 2 e 1. Não é um e não 1. É realmente apenas estas duas últimas estrofes desta música. Então o que eu quero fazer em vez? Assim, parece-me ter apanhado o caso em que se i é == a 1, em seguida, a primeira palavra é "garrafa", mas a segunda palavra é "garrafas". Mas aqui, eu quero mudar isso seja == 2. E se este for o caso, o que eu quero a primeira palavra a ser? AUDIÊNCIA: "Garrafas". DAVID J. MALAN: "Garrafas", assim para duas garrafas. E então esta palavra aqui deve ser - AUDIÊNCIA: "Bottle". DAVID J. MALAN: "Bottle", no singular. Tudo bem, vamos diminuir o zoom, voltar aqui, re-executar o make, re-run beer3 tipo, 99 novamente. Ok, "Falha de segmentação (núcleo)." O que eu fiz de errado? AUDIÊNCIA: Você não tem um valor [inaudível]. DAVID J. MALAN: Ah ponto, excelente. Tudo bem, então o que está errado aqui? Assim falha de segmentação, e nós estamos indo realmente para ver este algumas vezes no futuro, deliberadamente. Mas, por agora, o que isso realmente significa? Uma falha de segmentação quase sempre significa que você tem de alguma forma, tentou acessar memória RAM, em seu computador, que você não possui, que você não tenha realmente pediu o sistema operacional para. Portanto, neste caso, observe o que eu fiz, que é falha na minha lógica. Eu atribuído S1 e S2 um valor se eu for igual a 1. Também fiz que se eu for igual a 2. Mas eu não tenho feito isso no número infinito de outros possibilidades - em particular, 3 ou 4, ou um ponto, ponto, ponto, 99. Então, uma correção para isso poderia ser apenas vamos ter uma condição mais. E deixe-me entrar aqui e dizer s1 iguais - o que deveria estar aqui? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: "Garrafas", porque, em casos comuns, É exatamente a mesma coisa. Então é igual citações, unquote, "garrafas". Então, para o plural garrafas, e em seguida, até aqui, para garrafas de plural. Ok, então agora deixe-me voltar para a minha janela de terminal, recompilar, re-executá-lo. 99. Ufa. E vamos fazer um teste de sanidade rápido. Tecnicamente, nós queremos ler tudo isso para ter certeza de estão corretas, mas vamos olhar para menos os culpados conhecidos. 3 garrafas, 2 garrafas, 2 garrafas, 1 garrafa, uma garrafa, 0 garrafas. Parece que temos, pelo menos, fixa-lo por enquanto. Mas a questão aqui é que o que uma bagunça terrível deus este é apenas para resolver um estúpido um personagem-detalhe gramatical. Portanto, há um tipo de razão que eu cortar este canto antes, porque é apenas completamente chato ter que escrever este código muito. Mas acontece que há maneiras ligeiramente mais elegantes de expressando exatamente a mesma coisa. E nós podemos fazer isso da seguinte forma. Permita-me deixar isso na tela por um momento e introduzir algo conhecido como um operador ternário. Este é um tipo de um forro que é apenas a intenção de fazer o nosso vive um pouco mais sexy, como prometido. E eu vou fazer isso da seguinte forma. Dê-me uma string chamada s1, e deixe-me atribuí-lo como segue. (I == 1)? "Garrafa", caso contrário, "garrafas". String s2 recebe (i == 2)? "Garrafa", caso contrário, "garrafas". Então, o que é então a diferença aqui? Estas duas linhas de código, argumentam, pode substituir toda esta confusão. Então, eu chamo isso de bagunça, só porque é o tipo de esfrega-me o maneira errada de que é tantas linhas de código. Não é errado. Não é má concepção. Tipo, isso é perfeitamente correta e perfeitamente bem. Mas codificação fica aborrecido se você tem de expressar-se de modo caramba especificamente novo e de novo e de novo com um simples cenário como este. Então C tem alguns atalhos, como este. Portanto, este é essencialmente dizendo declarar uma string chamada s1 atribuir qualquer valor este ou este valor se i é == - desculpe, eu deveria dizer isso mais claramente. Declare uma variável s1, atribuir este valor se isto é verdade. Caso contrário, atribuir-lhe este valor. Assim, em outras palavras, este é um tipo de forma de uma linha de dizendo que se mais, mas fazendo um trabalho ao longo do caminho. Então, se eu for 1, então vá em frente e chamam isso de "garrafa". E então essa pessoa, chamá-lo de "garrafas". Enquanto isso, s2, o segunda palavra que precisamos definir, se eu for igual a 2, vamos s2 definir a "garrafa". Caso contrário, defina-o para "garrafas". E o que isso significa que agora é que eu posso passar por isso e apagar todos essas linhas de código. E quando eu digo, um pouco ridícula, que este é agora mais sexy, é mais sexy em um tipo de senso de estilo. O fato de que funcionalmente, esse código é realmente vai fazer exatamente a mesma coisa. E, embora possa parecer um pouco enigmática em primeiro olhar, porque não vi essa construção antes, eu argumentam que ele é, em última análise vai ser muito mais legível e muito mais fácil para nós, humanos, para classificar de compreender, porque agora você pode apenas ler o código em uma única linha. Ainda é semelhante em espírito a um a se, sempre que tal se condição e isso é o que está dentro do caso e este é o que está dentro da pessoa. Mas podemos fazer isso apenas muito mais elegante. E se eu agora vou voltar para o meu terminal, tendo eliminado todos dessas linhas e os substituiu com apenas esses dois, recompilar, re-run garrafas de cerveja com 99, aviso que minha gramática é, na verdade, ainda está correto. Então, novamente, algo para começar. 2 garrafas de cerveja, uma garrafa de cerveja. Parece certo. Sim. Portanto, temos uma solução muito mais sucinta. Portanto, isto também, como você se sentir mais confortável com C, não necessariamente com o pset primeiro ou mesmo segundo, mas perceber que essas construções podem permitir-nos a fazer coisas que nunca mais elegante. Agora vamos fazer uma outra coisa aqui. Deixe-me ir em frente e abrir return1.c. Agora vamos começar a resolver outro problema de uma forma que nos permite escrever código mais sofisticado. Então aqui está um programa simples e pequeno, cujo objetivo na vida é incrementar valores. E, na verdade, vamos dar um passo para trás. Deixe-me fazer isso manualmente. Deixe-me fazer incluir e int main (void). E deixe-me chamar esta increment.c. E o que eu quero fazer? Eu estou indo para ir em frente e dizer algo como - vamos ligar para os números o mesmo - int x. Então x int recebe 2; x printf é% d, a nova linha, x. Então, eu estou digitando rápido, mas tipo de coisa familiar agora. Então eu vou fazer x + +. Então eu vou para imprimir essa mesma frase novamente. E então eu vou retornar 0 apenas para sair do programa. Tudo bem, então este é um programa que incrementos de um número. É primeiro indo para inicializar algo a dois, e então é vai incrementá-lo e imprimi-lo novamente. Então vamos correr incremento, programa extremamente simples. Mas suponho que agora que eu quero cubo o valor, assim como algo um tanto arbitrária. E eu realmente quero fazer x recebe o cubo da mesma. Então eu poderia usar o que é chamado a função pow, mas eu não realmente sei onde é ainda. Então eu vou fazer isso da maneira old-fashioned. x vezes o que equivale a x vezes x vezes x. Então, eu estou cubing o valor, multiplicando-se por si mesmo novamente e de novo e de novo, para que possamos obter o poder de 3 neste caso. Portanto, agora os números que eu deveria imprimir deve ser, como veremos aqui - fazer incremento, por isso é, na verdade, não é realmente incrementar mais, mas vamos deixar o nome sozinho - 2 e, em seguida, 8. Agora, temos o início de uma oportunidade para o refinamento aqui, segundo a qual essa coisa cubagem da multiplicação de um número por si só, por si só, por si só, se sente como isso pode ser apenas útil ter como função, bem como alguém decidiu anos - você sabe, tipo de útil se um de nós se senta e escreve printf para que o resto do mundo pode usá-lo, por que não sentar e escrever uma função chamada cube que faz isso cubagem para nós para que não tem que manualmente implementar a noção de cubagem valores aqui? Assim, um exemplo simples, mas vamos em frente e usar isso é como um oportunidade de escrever a nossa própria função. Então, até agora, só usei principal, e nós usamos outro funções das pessoas, mas não ter escrito o nosso. Então, vamos lá. Eu estou indo para ir em frente e escrever uma função chamada cubo. E eu vou ter que tomar uma entrada. Portanto, sua entrada vai ser um inteiro. E o que é que vai fazer? Vai declarar saída int = Entrada de entrada vezes input vezes. E então ele vai voltar essa saída. E então eu tenho que ser específico agora. Esta função vai retornar um int. Então, aqui, então, é como você escrever suas próprias funções. Você primeiro decidir o que é o nome do seu função vai ser. E, geralmente, algo explicativo é bom, então eu vou chamá-lo de cubo. Então você tem que especificar o que ele vai voltar, o que é sua saída vai ser. E não temos opções que muitos ainda. Int, char, float, bool, string. Por enquanto, eu vou ficar com um int, porque eu quero para retornar um inteiro. Então você tem que especificar o que suas entradas, se houver, são. E se cubo tem um argumento, leva algo entre parênteses, você tem que dar esse argumento um nome para que você pode chamá-lo de algo como você está implementando ou escrever esta função, e você tem que dar um tipo, que neste caso vai ser int. Assim, em breve, o cubo é uma função que recebe um inteiro como entrada e retorna um inteiro como saída. Então, o que fazer com essa entrada? Bem, na linha 14, eu declarar uma variável chamada de saída, e eu atribuir-lhe o valor, a entrada de entrada de entrada vezes vezes. E então eu retornar a saída. Então, como posso usar isso, então? O que faço para mudar esses personagens destacados em linha 7 seja, que você acha? AUDIÊNCIA: [inaudível]. DAVID J. MALAN: Sim, então cubo de x. Então x é uma variável, o que significa que tem algum valor. Felizmente, é do tipo inteiro. E porque é um int x, o que significa que eu posso passá-lo em cubo. E mesmo que eu estou substituindo o valor de x com o valor x de cubo, tal como tem sido o caso até agora, qualquer hora tem sinal de igual e uma linha de código, o material sobre o direito é executado e depois é atribuído ao valor do lado esquerdo. Portanto, a ordem de operações é como seria de esperar. Então, isso funciona? Bem, deixe-me ir para baixo aqui. Deixe-me abrir a minha janela de terminal. Deixe-me faça incremento, Enter. "Declaração implícita de 'cubo' função é inválida em C99. "Como um aparte, C99 refere-se à linguagem C como era definido em 1999, que foi uma atualização sobre a versão de 1989, que é uma actualização em relação ao original. Então, isso é tudo o que isso significa. Então, o que significa que a declaração "implícita de 'cubo' função é inválido? "É aqui mesmo. É ali na linha 12. AUDIÊNCIA: [inaudível]. DAVID J. MALAN: O que é isso? AUDIÊNCIA: Não é antes. DAVID J. MALAN: Não é antes. Portanto, esta é a coisa. C é uma espécie de idiota, ou compiladores C são uma espécie de estúpida. Eles realmente só fazer o que lhes dizem para fazer. E eles, em particular, apenas ler seu código topo para a base, esquerda para a direita. Então, se o compilador, Clang, está lendo o seu código, linha 1, descobre como fazer isso. Oh, aqui vem principal. Ok, deixe-me ir em frente e declarar uma variável x. Deixe-me imprimir algo. Linha 7, o que diabos é cubo? Não é declarada em stdio.h. Ele não vem com C. Eu não tenho nenhuma idéia do que fazer. E assim Clang apenas socorre e encerra com a mensagem de erro. Assim, podemos corrigir isso em um par de formas. Podemos ensinar Clang o cubo é apenas movendo onde o declaração é. Então eu cortei e colei no topo principal. Agora percebo que só porque principal já não é primeiro, é ainda executado por padrão. Principal é principal. É o nome da função padrão. Não importa onde ele está em um arquivo. Mas pelo menos agora Clang viu cubo antes de usá-lo. Então, vamos ver se Clang é mais feliz agora. Faça incremento, ele fez compilar este tempo. Deixa-me correr incremento. E, de fato, parece estar funcionando. Agora, você pode criar cenários onde eventualmente não é possível colocar todas as funções acima de qualquer outra função. Você vai ficar preso neste loop infinito, na realidade, onde esse cara quer estar aqui, mas isso cara precisa estar lá. De modo que nem sempre funciona. Então, felizmente, C tem uma solução mais elegante. Vou colocar isso de volta onde estava, só porque eu preferir, como uma questão de princípio, que principal sempre no topo, porque é apenas bom para ver o que este programa faz por padrão. E o que eu vou fazer aqui é declarar o que é chamado um protótipo. Eu vou voltar a declarar minha função cubo literalmente copiando e colando. Na verdade, isso não é literalmente. Então, literalmente copiando e colando linha 15 -se acima da linha 6. Não importa o que esta linha acaba em. Ele passa a ser na linha 4. Mas tem que ser antes de principal. Mas note a diferença. Linha 4 termina com um ponto e vírgula, o que significa hey, Clang, pegue a minha palavra de que existe uma função chamado cubo que recebe um int e retorna um int. Mas eu não vou dizer o que é ainda. Só sei que eu prometo contar eventualmente. E, de fato, agora está tudo bem que este é baixo. Portanto, este é, geralmente, melhor, porque então no topo do seu arquivo, você pode simplesmente recitar, rápido-fogo, uma linha cada um, o que os nomes de suas funções são, qual o seu entradas são, o que os seus resultados são. E, para ser mais claro, a entrada geralmente significa argumento ou parâmetro, sinônimos. Saída significa valor de retorno, o que faz mão de volta para mim. Portanto, neste caso aqui, o cubo foi declarado no início, mas definido, também conhecido como implementado, na parte inferior. Então agora vamos voltar aqui e re-executar esta. Então, agora deixe-me ir em frente e re-executar o make, re-executar incremento. E agora parece estar funcionando muito bem. Então agora podemos ir em frente e fatorar algo como o cerveja exemplo para esta quarta versão. Então deixe-me rolar aqui. E notem que eu meio que levou essa lição para o coração agora. O fato de que eu estava cantando mesma estrofe novamente e uma e outra vez, a linha mesmo coro na música, sentiu gosto Porque eu não fator que em uma função? E, de fato, esta deve ser uma das motivações. Além do fato de que alguém no mundo poderia querer usar uma função cubo - essa é uma boa razão para o fator algo e escrever o seu função personalizada própria - se há um pedaço de código em seu programa que só faz sentido conceitual, que tipo de querer dar-lhe um nome - como neste caso, coro, - então você pode igualmente escrever que, como uma função separada. Você não tem que escrever tudo em principal, se ele só parece mais limpo para separá-lo e dar-lhe um nome. Portanto, neste caso aqui, perceber que eu tenho um comentário sobre esta função que só canta sobre a números especificados de garrafas. Note aqui que eu não preciso chamar estes coisas de entrada e saída. Na verdade, desta vez eu chamei meu b entrada para garrafa. E notar aqui, nula sugere o que? Esse refrão - AUDIÊNCIA: Não devolvê-lo. DAVID J. MALAN: não retorna um valor. E, de fato, não tem funções para retornar valores. Eles só podem fazer alguma coisa. Eles podem ter o que é chamado de efeitos secundários, o que neste caso é apenas um monte de imprimir na tela. Então, observe que este código aqui, eu literalmente roubou no exemplo anterior. A única diferença é, em vez de utilizar como i meu variável, agora estou usando b como minha variável. Então, eu tenho b aqui, tenho b aqui, tenho b menos 1 aqui. Mas o código é exatamente o mesmo. Mas só para te mostrar agora como podemos usar isso, deixe-me ir em frente e realmente mudar este é um loop for. for (i = n; i> n; i -). Então eu roubei isso de nosso exemplo anterior. Anteriormente, é na linha 37 que eu teria começado cantando essa música irritante. Mas em vez disso, eu só vou agora chamar coro de i. Concluído. Então, agora em cada iteração deste laço, eu chamo este outro coro, função, que aconteceu de eu escrever. Ele não foi escrito por outra pessoa de anos atrás. Mas coro, por sua vez, usa printf para imprimir essas quatro linhas. Mas o fato de que eu estou chamando refrão novamente e novamente em um laço significa que eu estou indo para obter, no final, o mesma música exatamente como eu tenho até agora. Assim, em breve, agora se eu olhar para trás, o meu código, apesar de funcionalmente é equivalente, perceber que é começando a ficar ainda mais legível. Eu não sei exatamente como GetInt é implementado. Francamente, eu não sei como refrão é implementado. Mas isso não importa para mim. Eu não me importo, porque agora eu posso classificar de, como um ser humano, leia este, de cima para baixo. E porque as funções são nomeados de acordo com o que eles fazer, o meu código é cada vez mais legível. E como nossos programas de ficar muito mais complexo - até o final do semestre, você vai escrever centenas de linhas de código em linguagens como PHP e JavaScript e outros - você verá que ele é muito mais fácil do que manter o controle de o que você fez. E quando você começar a colaborar com os amigos ou parceiros ou colegas, você vai ser capaz de escrever muito mais programas maciços de começar a se exercitar estes básica blocos de construção. Assim, com o que disse, por que não chamá-lo um dia? E nós vamos vê-lo na quarta-feira. [Aplausos]