[Powered by Google Translate] [Semana 2, continuação]
[David J. Malan, Harvard University]
[Esta é CS50. - CS50.TV]
Tudo bem. Este é CS50, e este é o fim da semana 2.
Se você esperar para estar com fome volta a esta hora amanhã,
sei que nós vamos convocar como um pequeno grupo amanhã, quinta-feira, 1:15 pm.
Há essa URL aqui se você gostaria de RSVP.
O espaço é limitado, portanto, por favor, perdoe se o formulário foi preenchido pelo tempo que você preencher isso.
Outra URL, no entanto, que pode ser de interesse é esse.
Em apenas cerca de um mês, o curso vai ser disponibilizado
tudo o mais amplamente por EDX, através do qual as pessoas na Internet será capaz de acompanhar,
engajar no curso bastante activa, na verdade.
Eles vão estar usando o aparelho CS50 e CS50 Discutir
e na maioria das várias ferramentas de software que já vêm usando este semestre.
E uma das iniciativas que gostaria de assumir como uma experiência este ano
é para ver o quanto de conteúdo que pode traduzir
em outras línguas faladas e escritas.
Então, se você pode ter interesse em participar neste projecto
qual iremos fornecer transcrições em inglês e legendas para palestras do curso
e shorts e seminários e seções e similares,
se você falar fluentemente ou escrever fluentemente outra língua,
nós gostaríamos de envolver você neste projeto pelo qual você assume um ou mais dos vídeos,
traduzi-las em uma língua que você conhece muito bem.
>> Para dar-lhe um sentido de interface, não há essa interface de usuário baseada na web
que nós vamos usar que irá criar, essencialmente, uma interface de usuário como este.
Isso foi me ensinando alguns Halloween atrás,
e no lado direito lá em preto ao lado desses carimbos de tempo,
você vai ver as várias coisas que saíram da minha boca naquele dia,
e abaixo, você será capaz de traduzir para outra língua
exactamente o que é o mapeamento entre, neste caso, Inglês e, digamos, espanhol.
Então, é realmente uma ferramenta muito amigável.
Você pode retroceder e avançar muito rapidamente com atalhos de teclado.
Então, se você gostaria de participar nesta experiência e ter suas palavras visto e lido
por potencialmente milhares de pessoas lá fora, por favor, sinta-se livre para participar.
Uma palavra sobre o gatinho de segunda-feira.
Para que não nos enviou uma mensagem de muito assustador, fazer perceber que, como sugerem as horas de expediente
e como secções sugere, o desenho do curso é muito
ter alunos a colaborar e falando para trabalhar com conjuntos de problemas
e problemas juntos, e realmente a linha só vem para baixo,
novamente, o trabalho que, em última análise apresentar deve ser o seu próprio.
E assim, sinceramente, em horário de expediente é totalmente normal,
É totalmente de se esperar mesmo, para estar conversando com algum amigo ao seu lado.
>> Se ele ou ela está lutando com algum tema e você é como,
"Oh, bem, deixe-me dar-lhe um vislumbre de alguma linha de código que eu escrevi", que é bom,
o que acontece, e isso é muito favorável, eu acho que, com o processo de aprendizagem.
Onde a linha fica cruzada é quando a cabeça é uma espécie de inclinada aqui para segundo demasiadas
ou minutos para que realmente ter sido apenas uma oportunidade de desbloqueio para o seu amigo,
e, certamente, quando as coisas ficam trocadas via e-mail e Dropbox e afins,
lá também é a linha.
Então, por todos os meios se sentir confortável e se sentir estimulados a conversar com os amigos
e colegas sobre Série de Exercícios e mais e só perceber que o que você finalmente apresentar
realmente deve ser o produto de sua criação e não outra pessoa.
E assim um dos problemas específicos de domínio para pset2,
que sairá amanhã à noite tarde, é mergulhar no mundo da criptografia,
que é a arte de criptografia ou cifragem da informação,
e esta última instância, para o mundo da segurança.
Agora, a segurança para a maioria de nós vem na forma de mecanismos muito mundanas.
Todos nós temos nomes de usuários e senhas,
e todos nós temos nomes de usuários e senhas muito ruins, mais provável.
>> Se sua senha é a mesma em vários sites, que provavelmente não é a melhor idéia,
como discutiremos em direção final do semestre.
Se sua senha é escrito em uma nota - não é brincadeira - em seu monitor,
que também não é necessariamente o melhor projeto, mas um fenômeno bastante comum.
E se você não está usando criptografia para criptografar suas senhas,
eles são particularmente vulneráveis.
Então, se você acha que está sendo super inteligente por ter um documento do Word oculta
em algum lugar no seu disco rígido que tem todas as suas senhas
mas é em uma pasta que ninguém vai procurar, isso também não é um mecanismo muito seguro.
E então o que pset2 irá introduzir é esta arte de criptografia
e lutando informações para que coisas como senhas são as mais seguras.
O contexto aqui é que, com dados inseguras
vem uma oportunidade de criptografá-lo e para embaralhar-lo.
E de modo que este, por exemplo, é um exemplo de uma mensagem encriptada.
Isso realmente diz algo em Inglês, mas claramente não é totalmente óbvia.
E vamos fechar o círculo hoje a separar o que esta mensagem segredo aqui é.
Mas no mundo real dos computadores, as coisas nem sequer olhar como eles podem ser frases em inglês.
Por exemplo, este é o que você pode encontrar em um padrão do Linux ou Mac ou computador UNIX
em um arquivo que foi outrora chamado de arquivo de senha.
>> Hoje em dia, ele foi transferido para outros lugares.
Mas se você olhar no lugar certo em um sistema, você verá não só seu nome de usuário
ou a de outras pessoas no sistema, mas você vai ver uma versão criptografada da sua senha.
De fato, a cripta palavra ali sugere que o material que se segue é criptografada,
e esta série de letras aparentemente aleatórias e personagens e números e assim por diante
pode ser decifrada apenas por geralmente sabendo algum segredo -
uma palavra secreta, um número secreto -
e assim, de fato, a arte de criptografia, em última análise resume-se a confiança de algum tipo
e saber algo que alguém não faz.
Então, vamos explorar isso em detalhes um pouco mais hoje e no pset para vir.
E agora uma palavra sobre passa / falha.
Especialmente como alguns de vocês já mergulhou pset1, o aparelho,
e um mundo muito novo para si mesmo, perceber que as frustrações e confusão
e apenas a dificuldades técnicas são muito de se esperar,
especialmente com a pset primeiro, onde há tanta coisa nova,
apenas se familiarizar com ls e cd e todos estes comandos arcanos
e um novo ambiente, e é separado do material real e própria programação.
Então percebemos também que há certamente expediente que existem como uma estrutura de apoio.
>> Seções começam no próximo domingo.
Mas o mais importante, se você está se sentindo apenas que este não é o mundo para você,
perceber que realmente levam tempo.
E se não fosse por essa oportunidade há anos para me de tomar um passe de classe / falhar,
honestamente, eu nunca teria sequer pôs os pés na sala de aula.
E você pode mudar isso até, digamos, a segunda-feira quinta do curso,
por isso, se você está na borda agora, perceber que, em vez de cabeça em algumas outras águas completamente,
que certamente considerar apenas mudando a aprovação / reprovação.
Novamente, não há realmente esta cultura aqui em Harvard de levar as coisas de aprovação / reprovação
já que todo mundo realmente quer alcançar ou ultrapassar,
mas, francamente, esta é uma ótima maneira de tentar algo fora
que pode não ser familiar a você, e você vai acabar fazendo, na maioria dos casos, muito bem,
talvez para sua surpresa.
E, em termos mais concretos, o que eu acho que passa / falha geralmente faz,
especialmente no que você pode ter experimentado com pset0,
se você colocar em 10 horas, 15 horas, 25 horas em alguns pset
e você está apenas bater a cabeça contra a parede e está ficando super tarde da noite
mas você tomou os 90% pset do caminho e você simplesmente não consegue descobrir uma coisa,
passa / falha realmente leva a borda fora de uma classe como esta,
onde você pode classificar de dizer felizmente, "Ok, eu sei que não é perfeito,
mas eu trabalhei pra caramba sobre isso, eu estou muito feliz com o local onde ele acabou "
e que vão atender as expectativas de aprovação / reprovação.
Assim que manter isso em mente. Tudo bem.
>> Então, aqueles de vocês que têm se esforçado para usar a Universidade de Harvard Wi-Fi,
sei que há um SSID CS50, uma conexão Wi-Fi, flutuando
que você pode ter melhor sorte para.
É um pouco irônico que a senha para isso, se você gostaria de tentar ligar a este
para velocidades melhores - e deixe-nos saber se não é melhor - é 12345, todo o caminho até a 8
8, porque é mais seguro do que 5.
Então, se você precisa da senha de acesso Wi-Fi, conecte-se sem fio CS50 aqui, 12345678,
e pós em CS50 Discutir se você ainda tiver problemas intermitentes de conectividade,
e vamos deixar que os poderes que conhece para este espaço. Tudo bem.
Então, um teaser rápido, especialmente para aqueles de vocês que são meninos ou meninas de fãs da Apple de todos as coisas.
O que eu retirado de alguns anos atrás era este arquivo aqui, iUnlock.c,
apenas para o tipo de tornar mais concreto e mais complexo
alguns dos programas mais básicos C que tenho escrito.
Então eu abri o arquivo, iUnlock.c. Ele está disponível na página de Palestras para hoje.
No lado esquerdo você verá uma longa lista de funções.
Assim, o sujeito que escreveu este escreveu um monte de funções, mais do que apenas principal.
Ele usou um monte de bibliotecas aqui, e se começarmos a percorrer,
o que isto realmente é, é o primeiro de crack, eu acredito, para o iPhone original.
>> Quando você queria fazer o jailbreak do iPhone original, o que significa untether-os da AT & T
e realmente instalar um software especial sobre ele e fazer as coisas que a Apple não quer que as pessoas fazem,
alguém teve tempo para descobrir exatamente como eles poderiam explorar falhas de software,
erros, bugs em softwares da Apple, e assim nasceu iUnlock.c -
que se você compilou em seu computador e instalá-lo em um iPhone
que foi conectado ao computador através de, por exemplo, um cabo USB,
isto lhe daria privilégios administrativos ou raiz em seu iPhone
e deixá-lo fazer praticamente o que quiser.
E assim houve este gato fascinante e rato
entre a Apple eo resto do mundo, em particular no que se, como muitas empresas,
tentar bloquear as suas coisas para baixo assim que você só pode fazer com ele o que eles pretendem.
Mas, graças a pessoas como esta e para a compreensão de detalhes de baixo nível -
e, neste caso, de programação C - e muitas das construções conhecidas
que já começou a jogar com, você é capaz de realmente alavancar o hardware
de uma maneira que achar melhor e não necessariamente uma entidade corporativa.
Assim, por exemplo, eu não tenho idéia do que tudo isso está fazendo,
GetVersion mas soa bastante simples,
e parece que esta é uma função que a pessoa escreveu.
É preciso algum tipo de número inteiro como argumento, não retorna nada,
mas parece loop com um laço e um aqui se a condição, se a interrupção condição,
e de alguma forma se relaciona com números de versão se deslocar para baixo,
mesmo que muitas destas palavras-chave vai ser novo.
E há toda uma série de funções no aqui nunca vimos e talvez nunca mais ver
ao longo do semestre.
>> No final do dia, ele segue as mesmas regras e lógica que temos vindo a jogar até agora.
Portanto, este é velho demais para quebrar seu iPhone ou 3s 4s 5s ou logo estes dias,
mas sei que está tudo muito derivado deste mundo que nós mergulhou.
Vamos dar uma olhada em um exemplo um pouco mais simples:
este, apenas para se aquecer com uma sintaxe e também outro tipo de dados
que temos falado, mas realmente não tenho visto em C.
Este é um arquivo chamado positive1.c, e por os comentários na parte superior,
este apenas exige que um utilizador forneça um número positivo.
Então, é um exemplo de um loop do-tempo, o que é bom para os programas de usuário interativas
onde você precisa dizer ao usuário para fazer alguma coisa,
e se eles não cooperarem você gritar com eles ou rejeitar a sua entrada.
Caso em questão: Eu vou fazer linhas de 19 a 24
desde que o usuário não tenha me dado um número positivo.
Este detalhe aqui na linha 18, por que eu declarar n acima deste looping toda construção
em oposição à direita ao lado da linha 22, onde eu realmente importam para obter n? Sim.
[Aluno] Escopo. >> Sim, então essa questão da abrangência.
E, em termos leigos, o que âmbito se refere?
Sim. >> [Resposta do aluno inaudível] >> Você pode falar um pouco mais alto?
[Aluno] Onde você pode acessar essa variável. >> Perfeito.
Onde você pode acessar uma determinada variável.
E, geralmente, a regra de ouro até agora tem sido a de que o alcance de algumas variáveis
é definido pelas chaves mais recentes encaracolados que você já viu.
>> E por isso, neste caso, se eu cometi o erro de declarar n na linha 22, que a linha iria trabalhar.
Gostaria de obter um int, e gostaria de colocá-lo em que n variável na linha 22,
mas que linha de código que agora não têm idéia do que eu estou falando? >> [Aluno] 25.
[Malan] 25, e verifica-se 24, mas também porque, neste caso, está fora das chaves.
Então, um pouco de incômodo, mas muito fácil de resolver, basta declarar a variável
fora da própria função.
Vamos ver mais tarde hoje você pode ir um passo além
e você pode até ficar um pouco preguiçoso.
E isso não é recomendado em geral, mas você pode até ficar com preguiça
e colocar uma variável globalmente, por assim dizer, e não dentro de uma função, e não dentro de um loop,
mas no próprio arquivo, fora de todas as funções que você escreveu, como eu fiz aqui na linha 15.
Este é geralmente desaprovado, mas que esta é uma solução, por vezes, a outros problemas,
como vai finalmente ver.
Então, por agora, vamos deixá-lo assim, mas vamos ver se podemos reescrever essa
só para começar a expressar-nos um pouco diferente.
Este programa, só para ficar claro, é positive1.
Deixe-me ir à frente e aqui na minha janela de terminal fazer positive1, Enter.
Compila bem. Eu vou correr positive1, pressione Enter.
Eu exijo que você me dê um número inteiro positivo. Eu vou dizer -1. Isso não funcionou.
0, 99. Que parece funcionar.
Talvez não o teste mais rigoroso, mas pelo menos é um bom teste de sanidade
que estamos no caminho certo.
>> Então, agora deixe-me ir em frente e abra a versão 2 do presente,
eo que é diferente já?
Ele implementa a mesma coisa, mas o que está pulando fora tão claramente diferente desta vez?
Este bool em verde. Destaca-se no verde, esta palavra-chave conhecida como bool, que é um tipo de dados.
Ele não vem construído em a todas as versões de C.
Você precisa incluir uma biblioteca específica.
No nosso caso, eu incluída a biblioteca CS50 para que tenhamos acesso a bool.
Mas, na linha 18, parece que temos um valor booleano aqui chamado agradecido.
Eu poderia ter chamado este nada, mas eu chamei-lhe grato
apenas para transmitir algum tipo de significado semântico.
Portanto, inicialmente na linha 18, eu não sou aparentemente grato
porque o valor booleano grato é inicializado como false na linha 18.
E então parece que eu fiz aqui em linhas de 21 a 23
é que eu tenho apenas uma espécie de reescrita minha lógica.
Portanto, não funcionalmente diferente, mas na linha 22 agora eu verificar se o int o usuário forneceu
é maior que 0, então eu simplesmente alterar o valor de grato a verdade.
E por que eu faria isso? Porque, na linha 25, aparentemente, eu estou indo para verificar uma condição.
Faça isso loop while grato é falsa.
Então eu propus isso como uma alternativa à versão 1
porque é pelo menos um pouco mais intuitivo, talvez, seja um pouco mais fundamentada em Inglês.
Então faça o seguinte enquanto você não está grato ou agradecido enquanto é falso.
E desta vez também eu, aparentemente, não se preocupam em lembrar o que o usuário digitou
porque não há nenhum aviso n variável, portanto, na verdade, uma pequena mentira lá.
>> Funcionalmente, o programa é um pouco diferente, uma vez que chegar ao fundo da questão
porque eu não estou lembrando o que n é.
Mas eu queria demonstrar aqui também que mesmo que temos visto GetInt
e GetString a ser utilizado no lado da mão direita de um sinal de igual até agora
para que lembrar o valor, tecnicamente, isso não é estritamente necessário.
Se por qualquer motivo você simplesmente não se importam para salvar o valor,
você quer apenas verificar o valor, observe que podemos simplesmente escrever isso como GetInt,
aberto paren, paren perto.
Essa função vai retornar um valor, como temos vindo a dizer.
Vai lhe dar de volta um int.
E se você acha que mentalmente de isso acontecer,
quando eu digitar 99, GetInt retorna o número 99,
e assim, conceitualmente, é como se o meu código eram, na verdade isso.
Então, se 99 é de fato maior que 0, então grato se torna verdade,
depois a linha 25 realiza ooh, estamos a fazer porque eu sou grato agora,
e na linha 26, nós simplesmente dizer: "Obrigado pela inteiro positivo!"
o que quer que estivesse.
Agora vamos fazer açúcar sintático ligeiro aqui, por assim dizer.
Vamos ver se conseguimos limpar essa linha 25 com esta variante terceiro e último positive3.
>> Observe a única diferença agora é que linha de código? >> [Aluno] 25. >> [Malan] Sim, 25.
E nós não temos realmente visto este truque ainda, mas fez ver o ponto de exclamação na segunda-feira,
que denota o quê? >> [Aluno] não. Não >> ou negação.
Então, ter um valor booleano e virar o seu valor.
Torna-se verdadeiro, o falso se torna verdadeiro.
Então isso, eu gostaria de propor, é até um pouco mais intuitiva maneira de escrever o código
porque eu ainda inicializar grato a falsa, eu ainda fazer o seguinte,
Eu defini grato a verdade quando chegar a hora,
mas agora você pode realmente apenas traduzir este código verbalmente esquerda para a direita,
while (grato!);, porque o ponto de exclamação ou estrondo denota a noção de não,
Assim, embora não grato.
Então, novamente, não introduziram novos conceitos em si.
Nós conversamos sobre Booleanos para trás quando nós tocamos com o Scratch,
mas percebo agora podemos apenas começar a escrever o nosso código de muitas maneiras diferentes.
Assim, especialmente no pset1 se você é uma espécie de luta para descobrir a maneira de escrever algum programa,
probabilidades são que você está com sorte, porque não pode haver qualquer número de soluções
que pode acontecer em cima.
Por exemplo, esta é apenas a 3, mesmo para o mais simples dos programas. Tudo bem.
E agora recordar na segunda-feira que deixou esta nota com valores de retorno.
Assim, para a primeira vez que escreveu um programa que não tem apenas principal;
também tem sua própria função personalizada que eu escrevi aqui.
Assim, na linha 31 a 34 eu implementei uma função cubo.
Não é complexo. É apenas a * a * a neste caso.
Mas o que é importante sobre o que é que eu estou tendo de entrada na forma de uma
e estou retornando saída sob a forma de um * a * a.
Então agora eu tenho a capacidade, tanto como eu costumava fazer com prinf sozinho,
chamar esta função chamando a função cubo.
>> E a função cubo tem alguma entrada, ea função cubo retorna alguma saída.
Por outro lado, printf apenas fiz algo.
Ele não retornou qualquer coisa que importava, mesmo que como um aparte ele não retornar um valor;
você geralmente só ignorá-lo.
Printf apenas fiz algo. Ele tinha um efeito colateral de impressão à tela.
Em contraste aqui, temos a função de cubo, que na verdade retorna algo.
Portanto, para aqueles familiarizados com este, que é uma idéia bastante simples.
Mas, para os menos familiarizados com a idéia de passar em entradas e saídas de voltar,
vamos tentar apenas algo simples super.
Alguém está confortável chegando no palco brevemente?
Você tem que estar confortável com uma câmera em você também. Sim? Okay.
Qual é o seu nome? >> [Aluno] Ken. >> Ken. Tudo bem. Ken, vamos lá para cima.
Ken vai ser uma função do tipo aqui.
Vamos em frente e fazer isso. Vamos pegar um pouco de fantasia.
Prazer em conhecê lo. Bem-vindo ao centro do palco. Tudo bem.
Vamos bater este botão aqui. Tudo bem.
Então aqui você tem um quadro moderno,
eo que eu sou é a função principal, por exemplo,
e eu não tenho um iPad na mão.
>> Eu realmente não me lembro como - Bem, eu não posso dizer isso.
Eu realmente não tenho boa caligrafia,
e assim, portanto, eu quero que você imprimir algo na tela para mim.
Eu estou sendo o programa principal, e eu vou ter que dizer isso
escrevendo no meu zero frango e em seguida, passando-lhe uma entrada.
Tão bobo que este exercício é, a noção de funções e chamar uma função
e retornando uma função na verdade se resume a isso.
Estou principal, que acabo de escrever printf, algo entre aspas na tela,
Estou executando este programa, e logo que printf é chamado,
é preciso um argumento ou um parâmetro, por vezes, entre aspas duplas.
Aqui é que o argumento. Estou passando-a para Ken.
Ele é uma caixa preta escrito um certo número de anos atrás
que, aparentemente, só sabe como imprimir coisas na tela.
Então executar.
Isso não é ruim. Muito bom.
Então, agora é feito Ken execução. Será que ele precisa me dar nada em troca?
Não que temos visto até agora.
Mais uma vez, printf faz realmente retornar um número, mas vamos ignorar que, por agora
porque nunca usei. Então é isso para Ken.
E agora principal assume o controle do programa novamente
porque essa linha de código, printf, é feita a execução.
E nós vamos sobre nosso caminho, executando o que as outras linhas estão lá.
Então, agora vamos tentar um exemplo um pouco diferente.
Desta vez, aqui vamos primeiro limpar a tela, e desta vez vamos fazer a função de cubagem,
mas desta vez, espero um valor de saída.
>> Então, vamos em frente e fazer isso.
Agora eu tenho uma linha de código que diz x recebe cubo de x.
A linha de código, recall, fica assim: x = cubo (x);
Então, como é que isto vai funcionar? Vamos em frente e dar-lhe uma tela branca novamente.
Eu vou escrever agora o valor de x,
que, neste momento passa a ser, digamos, de 2 a mantê-lo simples.
Eu escrevi em um pedaço de papel o valor de 2, que é o meu valor x.
Eu entregá-lo a Ken. >> E eu só escrever a resposta? >> Sim, vamos apenas escrever a resposta.
Okay. E agora ele tem de voltar-me algo. Perfeito. Segue agradável.
Então, agora ele me dá de volta o valor de 8, neste caso, eo que eu faço com ele?
Na verdade - vamos ver, obter este direito. O que eu vou fazer com ele?
Agora eu vou levar esse valor e, na verdade, armazená-lo nos mesmos bits na memória.
Mas repare que eu sou o tipo de luta aqui.
Eu estou um pouco confuso, porque onde eu realmente escrever o valor de x,
porque o que eu acabei de fazer é Ken fisicamente mão de um pedaço de papel que tinha o valor 2,
que era x, e, de fato, isso é precisamente o que aconteceu.
Assim, verifica-se que quando você chamar a função e você passar em um argumento
como Olá, mundo ou você passa um argumento como 2,
geralmente, você está passando em uma cópia do argumento.
E assim como eu escrevi o número 2 aqui e entregou-a a Ken,
isso deve significar que eu ainda tenho uma cópia do valor de dois em algum lugar
porque na verdade, agora que eu comecei de volta o valor 8, eu preciso voltar na RAM
e realmente escrever 8, onde uma vez eu tive o número 2.
Assim, visualmente, lembre-se essa noção de passagem em, literalmente, uma cópia do valor.
>> Ken faz sua coisa, me dá de volta algo - neste caso um valor como 8 -
e então eu tenho que fazer alguma coisa com esse valor, se eu quiser mantê-lo por perto.
Então, tudo isso vai voltar a ser tudo muito familiar antes do tempo.
Muito obrigado por esta demo aqui, Ken. [Aplausos]
Muito bem feito.
Vamos ver como é que, em última análise relaciona-se com algumas das funções de chamada que estamos fazendo aqui.
Deixe-me ir em frente e nos trazer de volta ao exemplo cubagem aqui.
Observe que, se queremos realmente começar a tomar isso ainda mais,
vamos ter que estar atentos ao fato de que o número x que está sendo passado aqui
é diferente do que realmente está sendo passado para a função.
Então, novamente, este passe por cópia vai tornar-se bastante pertinente em apenas um momento.
Vamos dar uma olhada em algo que não funciona muito bem certo ainda.
Eu estou indo para ir em frente e abrir um exemplo de buggy terceiro, que é falho por natureza,
e é chamado buggy3 e implementa uma função de troca.
Aqui temos uma função principal que x e y arbitrariamente inicializado com 1 e 2, respectivamente.
Nós poderíamos usar GetInt, mas só precisa de um simples exercício,
então é codificado como 1 e 2.
Nas linhas 21 e 22, que, aparentemente, imprimir x e y, 1 por linha.
Em seguida, na linha 23, eu afirmo que estou trocando estes valores, ponto, ponto, ponto.
Eu aparentemente chamar uma função na linha 24 swap de chamada que leva dois argumentos.
É totalmente legítimo para funções de tomar dois argumentos. Temos visto printf fazê-lo já.
>> Então troca aparentemente leva x e y, e como o próprio nome sugere,
Espero que ele vai trocar esses dois valores.
Então eu reclamar na linha 25 "trocados!" e I reimprimir x e y
sob a suposição de que eles realmente foram trocados.
Mas se eu realmente executar este programa - deixe-me abrir uma janela de terminal,
deixe-me fazer buggy3 - como o nome sugere, isso não vai acabar bem
porque quando eu pressione Enter, observe que x é 1, y é 2,
e ainda, no final do programa, eles ainda são, de facto, o mesmo.
Assim, com base na demonstração apenas agora com Ken, o que está realmente acontecendo?
Vamos mergulhar esta função swap. É super curto. É apenas algumas linhas de código longo.
Mas qual é o problema fundamental, baseado na história simples contada aqui com Ken?
Por que a troca de partido?
[Aluno] Você está armazenando a uma cópia, e não variável.
Exatamente. Nós estamos armazenando a uma cópia, e não a própria variável.
Em outras palavras, troca aparentemente leva dois argumentos, um int,
e é chamada arbitrariamente a e b,
e aqui eu passei em X e Y, que são, respectivamente, 1 e 2,
mas eu não estou literalmente passando em x, eu não estou literalmente passando em y,
Estou passando uma cópia de x e uma cópia do y.
É quase como se você copiado e colado em troca
os valores que você quer que ele realmente manipular.
Então, se esse é o caso, quando eu o início do programa em execução a linha 35, então 36,
quando eu chegar à linha 37, neste ponto da história, o que é o valor de uma?
Neste ponto da história, linha 37, que é o valor de um, neste ponto? >> [Aluno] 1.
[Malan] Deve ser apenas um, certo, porque x foi passado como o primeiro argumento,
e esta função apenas arbitrariamente está chamando seu primeiro argumento um.
Da mesma forma é y o segundo argumento, e é apenas arbitrariamente chamar a b segundo argumento.
>> Esta dicotomia é realmente bastante simples explicou. Pense sobre isso.
Nenhum de nós conheceu a pessoa que escreveu printf,
assim, certamente, ele ou ela não tem idéia do que nossas variáveis ​​30 anos mais tarde vai ser chamado.
Então, tem que haver uma distinção entre o que você chama de variáveis ​​em funções que você está escrevendo
e que vocês chamam de variáveis ​​em funções que você está chamando ou usando.
Portanto, em outras palavras, eu escrevi minhas variáveis ​​como X e Y,
mas se alguém tinha escrito a função swap, ele ou ela certamente não saberia
o que os meus variáveis ​​vão ser chamados,
para perceber que é por isso que você tem esta dualidade de nomes.
Tecnicamente, eu poderia fazer isso por coincidência,
mas eles ainda ser passado como cópias.
Seria apenas pura coincidência esteticamente se essa pessoa que escreveu troca
tinha usado os mesmos nomes.
Portanto, neste ponto da história, linha 37, um é 1, b é 2, e agora devo proceder para trocá-los.
Primeiro de tudo, deixe-me realmente fazer isso muito mais simples.
Eu não sei o que essas três linhas de código foram fazendo.
Deixe-me fazer isso: b = a, a = b; feito.
Por que isso é quebrado, logicamente?
É o tipo da coisa intuitiva, certo?
Assim, torna-se e a b b torna-se,
mas o problema é que, logo que linha 37 é executado, o que é o valor de a e b?
O mesmo, 1, porque você derrotado, por assim dizer, você mudou b para igualar um.
Portanto, uma vez linha 37 foi executado, isso é ótimo, agora você tem duas cópias do número 1
dentro desta função, assim então quando você diz na linha 38 a = b,
você está ferrado tipo de porque você está apenas a atribuição de 1 a 1.
Você meio que perdi o valor que você se preocupava.
Assim, na versão original do presente, observe o que eu fiz.
Eu em vez teve uma terceira linha de código que era assim.
Eu declaro uma variável temporária.
>> Tmp é um nome muito comum para uma variável temporária, e é um int
porque tem que coincidir com o que eu quero fazer uma cópia.
Eu armazenar cópia de um dentro de tmp, então quando linha 37 foi executado,
o valor de a é - verificação de sanidade rápido - 1, o valor de b é 2,
e o valor do tmp também é 1.
Então agora eu executar a linha 38.
Uma vez linha 38 é executado, uma toma o valor de b. E b foi de 2, assim que uma é agora 2.
Assim, neste ponto da história, a é 2, b é 2 e tmp é 1,
agora, logicamente, nós podemos apenas valor tmp plop de em b e estamos a fazer.
Então nós resolvemos esse problema.
Infelizmente, quando eu executar este programa sob esta forma, que na verdade não trocar quaisquer valores.
Mas, para ser claro, por quê?
Corrigi o problema lógico de um momento atrás,
mas, novamente, se eu executar este programa, X e Y permanecem inalterados
até o final da execução do programa.
[Comentário do estudante inaudível] >> Nós não retornou nada, então isso é verdade.
Mas acontece que há um pouco de um problema aqui, porque, até agora,
a única coisa que tenho sido capaz de voltar é uma coisa, e esta é uma restrição de C.
Você só pode voltar realmente um valor, caso em que eu sou o tipo de preso aqui
porque eu poderia retornar o novo valor de x ou eu poderia retornar o novo valor de y,
mas eu quero tanto de volta.
Então, retornando não é a solução simples aqui.
Mas o problema fundamental é por quê? O que nós realmente trocados?
[Estudante] a e b. >> A e b.
Mas a e b são cópias de x e y, o que significa que apenas fez todo este trabalho,
que acabamos passado 3 minutos falando sobre a função de troca e todos os 3 dessas variáveis,
e isso é ótimo, perfeitamente correto em isolamento,
mas e âmbito de b é apenas nestas linhas aqui.
>> Então, tal como um loop, se você declarar um inteiro i dentro do loop for,
Da mesma forma, se você está declarando dentro a e b de uma função que você escreveu,
eles são apenas válido dentro dessa função, o que significa que, logo que swap é feito executando
e vamos da linha 24 para a linha 25, x e y não foram alteradas de forma alguma.
Você desperdiçou apenas um monte de tempo a troca de cópias de variáveis.
Assim, verifica-se que a solução para isso é, na verdade, não óbvia.
Não é bem suficiente para retornar valores, porque só podemos retornar um valor,
e eu realmente quero trocar x e y, ao mesmo tempo,
então nós vamos ter que voltar a este.
Mas, por agora, perceber que a questão fundamentalmente derivada do fato de que a e b são cópias
e eles estão em seu próprio escopo.
Vamos tentar resolver isso de alguma forma.
Deixe-me realmente rolar de volta aqui e abrir-se, digamos, uma quarta variante deste, buggy4.
Que tal isso?
Este é um problema semelhante, mas mais simples de olhar antes de tomar uma facada em resolvê-lo.
Este programa é chamado de incremento, e, aparentemente, inicializa um número inteiro de 1 x na linha 18.
Eu, então, afirmar que x é 1, então eu reclamar "Incrementando ..."
Eu, então, chamar incremento, mas, em seguida, as linhas 22 e 23, eu afirmo que tem sido incrementado,
Eu reivindico x é agora que quer que seja - 2, provavelmente -, mas este programa é buggy.
Qual é o problema?
Sim. >> [Resposta do aluno inaudível] >> Exatamente.
Então x foi declarada, obviamente, na linha 18.
Que está dentro de chaves principais de.
Portanto, a resposta simples é que enquanto x existe aqui,
ela não existe na linha 32, assim que este programa realmente não vai nem compilar.
O compilador quando eu tento compilar este código vai gritar comigo
sobre alguns identificador não declarado ou alguma coisa nesse sentido. Na verdade, vamos tentar.
Esta é fazer buggy4. Não é.
Uso de 'x' identificador não declarado na linha 32.
E, na verdade, vamos ser mais explícito aqui hoje para que isso seja útil
em horário de expediente e em casa.
>> Observe que é um pouco enigmática escrita.
Mas o fato de que Clang tem gritado, dizendo buggy4.c: 32:5, é realmente útil.
Isso significa que o erro está na linha 32 na posição de caractere 5.
Então, 1, 2, 3, 4, 5. Isso é, de fato, onde está o problema.
E, também, também, ter em mente na hora de escritório e em casa, tenho sorte aqui.
Eu tenho um erro. Vai ser relativamente fácil de corrigir.
Mas se você receber uma tela cheia de mensagens de erro esmagadora,
novamente perceber que o mais inferior pode ser apenas um sintoma da um superior.
Então, sempre perseguir seus erros, de cima para baixo
porque não pode ser apenas um efeito em cadeia
que está sugerindo que você tem problemas de maneira mais do que você realmente faz.
Então, como poderíamos corrigir isso se meu objetivo é incrementar x? >> [Aluno] Fazer x global.
Ok, então podemos fazer x global.
Vamos pegar o atalho que eu avisei sobre a anterior, mas que diabo, só precisamos de uma solução rápida,
então vamos apenas dizer int x aqui. Isso faz x global.
Então, agora principal tem acesso a ele e incremento tem acesso a ele,
e então deixe-me ir em frente e compile isso agora.
Faça buggy4, Enter. Parece compilar.
Vamos correr buggy4. E parece realmente funcionar.
Esta é uma dessas coisas que fazem o que eu digo, não o que faço,
como eu acabei de fazer aqui, porque, em geral,
nossos programas vão ficar muito mais interessante e muito mais do que isso,
e se a sua solução para os problemas da vida é apenas colocar todas as variáveis ​​no topo do seu arquivo,
muito rapidamente que os programas ficam terrivelmente difícil de gerir.
Fica mais difícil de pensar em novos nomes de variáveis,
fica mais difícil de entender o que está fazendo o que variável,
e assim, em geral, isto não é uma boa solução.
Então, vamos fazer isso melhor.
Nós não queremos usar uma variável global aqui.
>> Eu quero incrementar x, para que eu pudesse obviamente -
no final do dia, este é um tipo de história boba, porque acabamos de fazer isso -
mas se eu não sabia que o operador ou eu não tinha permissão para alterá-lo no principal em si,
de que outra forma eu poderia implementar Ken aqui desta vez não para cubo, mas para incrementar?
Como faço para mudar esta coisa aqui? Sim.
[Aluno] Pass em x e em seguida, retornar [inaudível] >> Ok, bom.
Então, por que não eu passar em x e em seguida, em vez de devolvê-lo,
por que eu não apenas me retornar x + 1.
Mais algumas coisas têm que mudar aqui. Eu estou no caminho certo.
O que mais eu preciso para ajustar? Alguém. Sim.
[Resposta do aluno inaudível]
Eu preciso mudar o tipo de retorno de incremento porque não está vazio.
Não significa nada vazio está sendo devolvido, mas claramente agora é,
para isso precisa mudar para - >> [aluno] int.
int para ser coerente com o que eu realmente estou voltando.
Agora outra coisa ainda é de buggy aqui. Sim.
[Resposta do aluno inaudível] >> [Malan] Então eu preciso incrementar x?
[Resposta do aluno inaudível] >> [Malan] Ah, então eu preciso passar x.
Então eu preciso fazer isso aqui. >> [Comentário do estudante inaudível]
[Malan] Então o protótipo, eu tenho que mudar isso aqui.
Portanto, este tem de se tornar um int, este tem de se tornar -
hmm, eu realmente tenho um bug aqui. Vamos corrigir isso primeiro.
O que isso realmente deve ser? Tem que ser uma coisa int.
Poderia ser x, mas, francamente, se você começar a chamar toda a sua x variáveis,
ele vai ficar cada vez menos clara qual é qual.
>> Então vamos escolher arbitrariamente uma convenção de nomenclatura diferente para as minhas funções de auxiliares,
as funções que eu estou escrevendo. Vamos chamar-lhe uma, ou podemos chamá-lo -
Vamos chamá-lo de o número ser ainda mais explícito.
Então eu tenho que devolver qualquer que seja o número é mais 1,
e agora eu tenho que mudar uma coisa aqui e outra coisa aqui.
O que eu tenho que mudar na linha 21 em primeiro lugar? >> [Resposta do aluno inaudível]
[Malan] Eu tenho que atribuir a x. Eu não posso simplesmente chamar de incremento (x).
Preciso lembrar a resposta, alterando o valor de x no lado esquerdo.
E mesmo que x é agora à esquerda e à direita, que é totalmente bem
porque o lado direito é executado primeiro, então, é a coisa pulou na sua mão esquerda -
x neste caso.
E então, finalmente, este é um reparo fácil agora.
Este deve apenas combinar o que há lá embaixo, número int.
Então, um monte de mudanças para uma função realmente estúpido
mas representativa de coisas que nós vamos cada vez mais quer fazer.
Então faça buggy4. Eu estraguei tudo em algum lugar.
Oh, meu Deus. Cinco erros em um programa de 6 linhas.
Então, o que há de errado na linha 18, o personagem de 5?
Então eu tenho que declarar este int,.
Vamos ver. Há um monte de outros erros.
Oh, meu Deus - 19, 18, 21 - mas, novamente, vamos limpar a tela, L Controle aqui,
e execute novamente Clang.
Então, cinco problemas que na verdade é apenas uma.
Então, agora vamos executar buggy4, Enter. Ufa, x foi incrementado corretamente.
Tudo bem. Qualquer dúvida sobre como incrementar números? Sim.
[Pergunta estudante inaudível] >> Boa pergunta.
Como é que eu posso simplesmente mudar para o número x eo programa vai saber imediatamente?
>> Mais uma vez, pense nisso como essa abstração.
Então, se eu sou principal e Ken é incremento, francamente, eu não me importo com o Ken chama seu iPad.
Eu não ligo para o que ele chama de nada que tenha a ver com a sua implementação dessa funcionalidade.
Este é um detalhe de implementação que eu, principal, não tem que se preocupar.
E assim simplesmente mudar consistentemente dentro da função - número aqui e número aqui -
é tudo o que leva tanto tempo como eu recompilar.
É uma espécie de gosto, se você pensar que muitos de nós, aqueles com carteiras de motorista
que têm conduzido ou se você mesmo conduzido em um carro,
a maioria de nós não tem idéia de como um carro funciona debaixo do capô.
E, literalmente, se você abrir o capô, a maioria de nós - eu incluído -
não estão indo para realmente saber o que estamos olhando,
tipo de como você pode se sentir com coisas como esta agora.
Mas nós realmente não precisa se preocupar como o carro funciona,
não temos de cuidar o que todos os bastões e pistões e os cabos dentro do carro
estão realmente fazendo.
Portanto, algo como o que vocês chamam o pistão não importa aqui neste caso. Mesma idéia.
Sim. >> [Questão estudante inaudível]
Se há mais usos do momento xa variável atrás,
você, programador, teria que mudar todos os lugares.
Ou você pode literalmente fazer menu Arquivo, e em Localizar, Substituir - algo assim -
mas você vai ter que fazer essas mudanças mesmo.
Você tem que ser consistente. >> [Aluno] Se há múltiplas variáveis ​​[inaudível]
A ordem particular como aqui, se isso era int outro número? >> [Aluno] Correto.
[Malan] Yeah. Ordem importa quando você está chamando a função.
>> Então, se eu estivesse chamando incremento aqui com algo vírgula alguma coisa,
há um mapeamento direto.
A primeira variável, o que é chamado, é feita uma cópia do primeiro argumento aqui.
Desculpe. Isso não deve ser um parêntese.
O segundo argumento linhas acima com o segundo. Assim, a ordem, sim, importa. Tudo bem.
Desculpe. Tomei o caminho mais longo para chegar lá. Outras perguntas? Tudo bem.
Então vamos ver se não podemos pintar uma imagem do que está realmente acontecendo aqui
debaixo do capô, por assim dizer.
Este é um retângulo que pode representar a memória do seu computador.
Mesmo se você não tem idéia de como funciona a memória ou como funciona a memória RAM,
pelo menos assumir que você tem cachos de hoje em dia.
Você tem megabytes de que, você tem gigabytes de que,
e sabemos que a partir da semana que um byte 0 é apenas o que? >> [Aluno] 8 bits.
8 bits, certo? Então 8 zeros e 1.
Então, se o seu computador tem um giga de RAM, 2 GB de RAM estes dias,
você tem um bilhão ou 2 bilhões de bytes de memória ou cerca de 8.000 milhões ou 16 bilhões de bits
dentro do seu computador.
Ao contrário do exemplo pouco Willy Wooly, não é tipicamente mais partículas magnéticas.
Cada vez mais - em laptops, pelo menos - é drives de estado sólido, SSDs
que apenas não têm partes móveis. É tudo eletrônico. É tudo baseado em eletricidade.
Então, acho que desse retângulo como apenas representando os 1 ou 2 gigabytes de memória que você tem.
>> Portanto, é um pedaço da memória.
O mundo da informática tem a sorte de dissociado
pedaços de memória para fazer coisas diferentes.
Por exemplo, se esta é a memória RAM do computador, tal como sugerido pelo rectângulo lá,
verifica-se que, por convenção, no topo de sua memória RAM, por assim dizer,
é, geralmente, o que é chamado de um segmento de texto.
Esses são os 0s e 1s que você tenha compilado.
Então, quando nós olhamos debaixo do capô o que a.out é,
todos estes 0s e 1s, quando você executar um programa,
os 0s e 1s são carregados a partir do seu disco rígido em algo chamado de memória RAM,
e na RAM são colocadas no topo.
Enquanto isso, você tem outras coisas: iniciar os dados, não inicializar dados.
Esses dois trechos de memória referem-se a variáveis ​​globais, que você não costuma usar
mas, às vezes, se você fizer isso, eles acabam se lá também.
Depois, há algumas outras coisas: as variáveis ​​de ambiente, que não vai passar muito tempo,
mas, em seguida, duas coisas importantes que vão voltar ao longo do semestre,
pilha e heap.
Assim, a maioria da memória do seu computador é reservado ao executar um programa
para algo chamado de pilha e algo chamado de pilha.
Nós não vamos falar sobre a pilha de hoje, mas vamos falar sobre a pilha.
A pilha é destinado a conjurar o visual das refeições bandejas de refeição salão em Mather Casa
ou onde quer que seja, onde a equipe refeitório limpá-los todos os dias,
eles empilhá-los do chão em cima,
e da mesma forma, na memória, não é essa idéia de colocar algo em uma pilha,
colocar algo em uma pilha, colocar algo em uma pilha.
E o que queremos dizer com isso?
>> Vamos aumentar o zoom em apenas a metade inferior da imagem, memória RAM de seu computador,
a propor o seguinte.
Acontece que quando você executar um programa como a.out ou Olá -
qualquer que seja o programa é que você escreveu -
novamente, os 0s e 1s são carregados a partir do seu disco rígido, que é de longo prazo de armazenamento,
permanece lá mesmo quando você puxar a ficha, carregado na memória RAM.
RAM é mais rápida do que os discos rígidos - é menor do que os discos rígidos -
mas é onde os programas ao vivo, enquanto você está executando-os.
Então você clicar duas vezes um programa em um Mac ou PC, ele é carregado do disco rígido para a RAM.
Assim como é carregado na memória RAM, o go 0s e 1s no topo forma,
o segmento de texto chamado, mas assim que o programa realmente começa a correr,
a principal função é chamado, e principal, como já vimos, muitas vezes tem variáveis ​​locais,
e tem ints e cordas e caractere e semelhantes.
Portanto, se seu programa que você escreveu ou o programa que você clicar duas vezes
usou algumas variáveis ​​dentro de principal,
eles acabam no fundo de sua pilha de memória, por assim dizer.
Mais concretamente, o que isso realmente significa?
Isto apenas significa que se nós estávamos indo para o número de bytes de memória RAM em seu computador,
notar 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 caminho até 2 bilhões seria todo o caminho até lá em cima.
Portanto, em outras palavras, quando falamos de memória RAM ou em termos de bytes,
significa apenas que alguém decidiu que a contar cada um desses pedaços de memória.
Assim, quando você precisar de 32 bits para um int ou você precisa de 8 bits para um char,
onde é que eles acabam na memória?
>> Conceitualmente, eles simplesmente acabar no fundo de uma coisa chamada a pilha.
Mas o que é interessante agora é quando chama uma função principal -
suponha que uma função chamada foo, apenas o nome de um arbitrário -
o que acontece é principal está na parte inferior desta pilha de memória;
foo agora é colocar em cima do principal na memória.
Assim, todas as variáveis ​​locais que foo tem acabam tipo de conceitualmente acima dos de principal.
Se foo chama outra função chamada bar, essas variáveis ​​acabam aqui.
Se a barra de chama outra coisa, aqui, aqui, aqui.
Então, o que é interessante sobre a execução de um programa é que, como você chamar funções
e como essas funções chamar funções e como essas funções chamar funções,
você construir esta pilha de funções na memória.
E apenas uma vez a função retorna você começar a que a memória de volta.
Portanto, uma das maneiras mais fáceis de ficar sem memória em um programa de computador
é escrever funções que nunca retornam.
Assim, por exemplo, vamos demonstrar tanto com um programa intencionalmente buggy.
Deixe-me ir em frente e fazer # include,
int main (void),
e eu vou fazer enquanto (2> 1), o que provavelmente não vai mudar em nós,
e deixe-me ir em frente agora e fazer printf.
Na verdade, isso vai ser menos interessante visualmente. Vamos fazer isso.
Para int i = 0; i> 0 - vamos cometer esse erro - i + +.
E não vamos printf aqui. Vamos praticar o que eu estava pregando.
Vamos ter um método aqui, refrão vazio, e vamos dizer int i,
e então eu vou dizer printf - não, vamos tornar isso mais interessante.
Não vamos realmente imprimir nada. Vamos fazer o seguinte: coro (i).
Tudo bem. Portanto, este é buggy por que?
Eu estou fazendo isso como eu ir, porque o programa não faz nada de interesse.
>> Mas esse não é o objetivo.
O objetivo é escrever um programa que tem como principal função faz o que, aparentemente?
Se identificar. E, na verdade, nós não precisamos do loop.
Vamos mesmo simplificar este só para não perder de vista o bug realmente fundamental.
Chamadas principais coro a cantar alguma coro,
então eu fiz algo estúpido e eu tive coro chamada coro
porque eu assumi alguém estava indo para implementá-lo, talvez,
e agora isso não vai compilar ainda. Eu preciso fazer o quê?
Eu preciso do protótipo, lembre-se.
Então, eu preciso ter-se aqui coro void (int i);
Portanto, agora se eu descer aqui - na verdade, vamos usar a janela maior.
Vamos em frente e fazer coro.
Utilização de identificador não declarado i.
Ah, isso foi estúpido. Nós não precisamos do argumento. Vamos fazer isso.
Eu gostaria que tivesse começado dessa maneira. Teria sido um programa muito mais fácil escrever.
Lá. Agora vamos para a minha janela de terminal, execute novamente Clang, e aqui vamos nós.
Isso foi muito rápido.
O que realmente aconteceu, entretanto?
Bem, agora eu vou adicionar a linha de impressão para que possamos ver.
Deixe-me dizer printf ("Eu estou aqui") - não variáveis. Vamos deixá-lo assim.
Deixe-me fazer reprise. Deixe-me reprise coro.
E ... vamos lá. Continue indo.
Como um aparte, por que ainda não caiu ainda?
A falha de segmentação aconteceu super rápido antes.
[Resposta do aluno inaudível] >> Exatamente. Então, é preciso tempo para imprimir, certo?
Ele só tem mais trabalho por parte do computador.
E lá está: falha de segmentação.
>> Então, observe o quão rápido os programas executados.
Se você não está imprimindo nada, super rápido.
Mas ainda tenho essa falha de segmentação, porque o que estava acontecendo?
Se você pensar sobre como a memória do seu computador é colocado para fora,
este passa a ser principal, mas aqui vamos chamar este coro, e vamos chamar esse refrão.
E agora, se eu fizer minha estética certo, isso só vai dizer coro coro, coro,
coro, coro, coro, coro, ad nauseum, e, eventualmente, o que vai acontecer?
Se a imagem grande, literalmente, é isso, o que acontece apenas conceitualmente?
As derrapagens pilha a pilha.
Ou, pior, você só superado tudo, incluindo o segmento de texto,
que é a 0s e 1s que representam o seu programa.
Em suma, este é apenas super, super-ruim.
Seu programa entrou em uma espiral fora de controle.
Você está usando a memória muito mais do que você pretendeu
tudo por causa de um erro estúpido, neste caso,
ou, neste caso uma função muito deliberadamente feito ligando-se.
Agora, isso não é de todo ruim.
Funções que chamam-se, na verdade, tem um grande poder quando você usá-lo corretamente.
Eu não tenho usado corretamente aqui.
Então isso não é de todo ruim, mas o fato de que eu nunca realmente parar de chamar-me
é uma fraqueza fundamental aqui deste programa.
Então para onde estamos indo com tudo isso? O que está realmente acontecendo?
Quando eu chamo a função de incremento como estávamos fazendo nesses exemplos,
Eu tenho um valor como uma que eu passar dentro
Eu passar em uma cópia do número 1, então acontece o seguinte.
Vamos para o exemplo de incremento, esse cara por aqui.
Aqui está o que realmente está acontecendo.
Quando eu chamo incremento e eu passar em x, pictoricamente, o que está acontecendo aqui é esta.
>> Se eu tiver o valor de um armazenados aqui e eu realmente chamar incremento,
que agora é chamado coro - o iPad está jogando-me aqui.
Vamos chamar esse incremento, e não sabemos o que esta função próximo vai ser.
Então o que está realmente acontecendo é aqui em algum lugar na principal Eu tenho um pedaço de memória
que está a armazenar o número 1.
Quando eu chamo incremento, estou usando outro pedaço de memória,
mas agora eu tenho a cópia do 1.
Quando eu incrementar esse valor, isso se torna 2,
mas então o que acontece logo que retorna de incremento?
Esta memória só fica transferido de volta para o sistema operacional,
o que significa que tudo que você fez não é nada útil.
O 1 que foi originalmente contido no principal ainda é realmente lá.
Então para onde estamos indo com isso?
Acontece que na memória você ter esta sequência de back-to-back de bytes
que você pode colocar coisas dentro, e verifica-se que já vimos algo
que envolve colocar as coisas de volta para trás, para trás, para trás.
O que é um texto baseado na 1 ª semana e agora 2 semanas?
É apenas uma coleção de personagens.
Assim, verifica-se apenas como você pode colocar números na memória,
da mesma forma que você pode colocar os caracteres na memória.
E quando começamos a colocar personagens na memória de costas para trás, para trás,
verifica-se que usando a mais simples das coisas como um loop ou um loop while,
podemos iterar da esquerda para a direita sobre os caracteres de uma string
e começar massageando-os em personagens completamente diferentes -
poderia tornar-se um b, b poderia tornar-se c -
de modo que, em última análise, podemos tomar uma frase Inglês que realmente faz sentido
e converter cada uma das referidas cartas de cada vez
andando através da memória do nosso computador esquerda para a direita para realmente criptografar.
Portanto, vamos ter a nossa pausa de cinco minutos aqui,
e quando voltar, vamos começar esse processo de codificação de informações.
>> Tudo bem.
Antes de mergulhar em alguns criptografia e essas coisas chamadas de matrizes,
deixe-me fazer uma pausa para todas as perguntas, porque eu sinto como se eu realmente tipo de confusa
alguns desses temas. Então vamos corrigir agora, se pudermos.
Acabamos de falar sobre valores de retorno, nós conversamos sobre argumentos,
e conversamos sobre esta noção, que nós vamos voltar a nos próximas semanas,
de ver a memória como um monte de estas bandejas empilhadas, por assim dizer,
a partir de baixo, de cima, de tal modo que cada bandeja, que é colocado na pilha
representa uma função que está sendo chamado.
Alguma pergunta?
Deixe-me fazer uma pergunta aqui.
Deixe-me simplificar isso volta ao que era antes de alguns dos nossos mais cedo Q & A.
O fato de que o incremento tem parêntese aberto, número int, fechou parênteses -
o que é que o número int representa?
[Aluno] Um argumento. >> Um argumento. Okay. Mas o que é um argumento?
[Resposta do aluno inaudível] >> O que é isso? >> [Aluno] Algo que você passa dentro
Ok, então algo que você passa dentro E de modo mais geral, é apenas a entrada.
Se você fosse escrever uma função e finalidade dessa função na vida
é fazer algo um pouco diferente cada vez que você usá-lo,
então a única maneira para que isso aconteça realmente parece ser o de fornecer com entrada
para que ele possa fazer algo diferente com que a entrada de cada vez.
>> Então, você precisa especificar duas coisas quando leva uma função de entrada.
Você precisa especificar o nome que você quiser dar a essa entrada
exclusivamente para sua própria conveniência para que você possa consultá-la
na função que você mesmo está escrevendo, como eu fiz aqui na linha 32.
Mas você também precisa especificar o tipo porque C é uma linguagem de programação
que exige apenas que se você quiser uma variável, você tem que dizer ao computador o tipo de dados que é,
em boa parte, de modo que ele sabe quantos bits para alocar para essa variável
porque poderia ser 6 - desculpe, isso não vai ser 6.
Ele pode ser de 16, pode ser de 8, pode ser de 32, mesmo 64,
mas o computador precisa saber.
Agora, a int no lado esquerdo representa o que, por outro lado?
[Resposta do aluno inaudível] >> O que é isso? >> [Aluno] Tipo de função.
O tipo de uma função e, mais especificamente, do tipo da sua produção. Direito.
Assim, enquanto que a única coisa entre parênteses representa sua entrada, se houver,
a coisa para a esquerda representa sua saída.
E, neste caso, o incremento aparentemente retorna um inteiro
e assim int é o tipo de retorno desta função.
O que significa retornar?
Literalmente, você usa a palavra-chave return e então, se o que você está voltando
à direita da palavra-chave é um número inteiro,
em seguida, que é de fato consistente com o que prometeram.
Você não poderia fazer algo assim - Olá mundo, - porque isso é uma string.
>> Obviamente, isto não é um número inteiro.
Assim, em breve, a carga é realmente em nós, o programador, para ser específico
quanto ao que estamos retornando e então realmente ir sobre a devolver.
O contexto aqui agora é que a memória do computador é um gigabyte, 2 gigabytes -
qualquer que seja - talvez seja mais, talvez seja menos,
mas o computador vê-lo como tendo diferentes seções.
Algo vai lá, outra coisa vai lá em cima,
coisas diferentes vai no meio, e hoje nós só começar a contar a história,
mas vamos voltar a esse tempo acabou.
Por enquanto, a única lembrança que realmente importa é o segmento de texto
porque isso só representa os 0s e 1s Clang que tem emitido.
Então, quando você executar um comando no teclado como a.out
ou duplo clique em um ícone no Mac OS ou Windows,
seu programa é carregado a partir do disco rígido para a RAM
e está se estatelou no topo da RAM do seu computador, por assim dizer.
Enquanto isso, como o seu programa começa a ser executado e principal é chamado
no programa que você escreveu ou o programa Microsoft ou a Apple escreveu,
qualquer uma de suas variáveis ​​locais acabam lá no fundo da memória de seu computador.
Mas, se as chamadas principais outra função que em si tem variáveis ​​ou argumentos, eles acabam por cima.
E se essa função chama alguma coisa, eles acabam acima dele, acima dele, acima dele.
>> E apenas uma vez uma função de execução que é feito a pilha de tabuleiros, por assim dizer,
começam a ficar mais e mais.
E isto é o que então, em poucas palavras, explica porque quando você chama cubo
ou você chamar de incremento, você está passando em uma cópia do valor.
E o que isso significa pictoricamente é que você está, literalmente, escrevendo o número 1
em outra parte da memória, mudando que 1 a 2, no caso de incremento
ou de um 8, no caso de cubo e, em seguida, que a memória de distância jogando
assim que o aumento ou a função retorna de cubo. Pergunta.
[Estudante] Onde são variáveis ​​globais são armazenados?
As variáveis ​​globais são armazenados em que está atualmente chamado os dados inicializados ou dados não inicializados,
a diferença é se você tiver uma variável global e lhe atribui um valor imediato
com o sinal de igual, ele acaba no topo lá,
e se você acabou de dizer int x; sem valor, acaba um pouco menor na RAM
simplesmente por convenção.
Outras perguntas? Tudo bem.
Portanto, esta imagem vai voltar como temos mais poderoso
com o que podemos fazer com o computador,
mas por agora, vamos ter uma breve introdução à criptografia,
um tipo específico de criptografia que não resolve todos os problemas do mundo
mas não resolve alguns deles.
Neste caso aqui, temos uma coisa chamada criptografia de chave secreta.
Criptografia de chave secreta, como o nome sugere, deriva a sua segurança a partir de um segredo.
>> Por exemplo, se você estava de volta na escola e você estava passando uma carta de amor pouco secreto
para o menino ou a menina que estava esmagando, se você queria passar essa nota por meio da audiência,
você provavelmente não iria escrever tal nota em Inglês ou qualquer que seja sua língua nativa é.
Em vez disso, você pode criptografar ou você pode apenas enviar-lhes uma mensagem de texto estes dias.
Mas você pode realmente passar-lhes uma nota ao longo da sala de aula.
E para fazer isso de forma segura, de tal forma que os seus amigos e os professores
não sei o que você está escrevendo, você pode chegar a um algoritmo bastante simples,
jovem que você pode ser, apenas para embaralhar as palavras.
Então, em vez de escrever um você pode escrever b,
em vez de b você pode escrever c,
em vez de c você pode escrever d, e assim por diante.
Ou você pode vir com uma tradução mais sofisticado
de cartas para letras diferentes.
Mas o problema é o menino ou menina a quem você está enviando esta nota
precisa saber alguma coisa, que é o que, obviamente? >> [Aluno] O que você está enviando.
Qual é o seu segredo, como o que é que o mapeamento entre um e b e c e d's.
É apenas adicionando uma a cada uma das letras para ir de um para b, b para c?
O que é mais complexa do que a?
>> Assim, você e sua paixão precisa ter essa informação secreta,
mas há uma espécie de catch-22 aqui.
Se esta é a primeira vez que você está enviando esta carta de amor através da classe,
como é que o menino ou a menina vai saber o que o segredo é mesmo?
Então de chave secreta de criptografia não resolve todos os problemas do mundo,
e há, na verdade, um relacionamento aqui que nós vamos voltar a em direção ao fim do semestre.
Da mesma forma que não a maioria de nós conhece alguém que trabalha, por exemplo, a Amazon.com,
e ainda muitos de nós provavelmente já comprou coisas no Amazon.com,
e nós fomos ensinados a assumir que essas transações de e-commerce são seguras.
A URL provavelmente diz https, há talvez um ícone de cadeado pouco bobo em algum lugar,
há algum tipo de criptografia de proteger suas informações de cartão de crédito
entre você e Amazon.com.
E, no entanto, se a criptografia envolve saber algum segredo
e eu ainda não conheço ninguém na Amazon e eu certamente não dispostos qualquer tipo de segredo
com alguém na Amazônia, como é o meu computador ou o meu navegador fazendo isso?
Acontece que há outros tipos de criptografia completamente que resolver esse problema.
Mas por hoje, vamos nos concentrar na simples
onde você pode organizar com antecedência para saber algum segredo
como uma ou algumas mapeamento entre um e b do.
E o processo de criptografia envolve geralmente a este.
Você tem algum texto simples, representado aqui na esquerda,
executá-lo através de algum tipo de algoritmo ou procedimento para criptografá-lo -
talvez isso seja apenas uma se torna b, b torna-se c -
e então você acaba com texto cifrado.
Enquanto isso, uma vez que a sua paixão recebe esta nota secreta,
ele ou ela tem que decifrá-lo, então por que geralmente invertendo algoritmo
de modo a obter de volta o texto simples.
Existem encarnações físicas deste.
>> Por exemplo, este é um anel decodificador pouco segredo,
e este é um anel, no sentido de que há dois mostradores aqui.
Na periferia fora desta coisa, há letras de A a Z,
embora eles estão em ordem aleatória,
e no interior, há realmente alguns números
de tal forma que com este anel, você pode transformar o tipo de fora, mas não no interior
, a fim de alinhar números com letras.
A partir de um filme chamado Uma História de Natal, você vai ver que Ralphie pouco
estava tão ansioso para descobrir o que mensagem secreta Little Orphan Annie era para ele
que havia sido comunicado, penso eu, na forma de mensagens numéricas em uma caixa de cereal
e você teve que acumular todos os cartões pequenos que vieram na caixa de cereal,
você tinha que enviá-los, você tinha que voltar o anel decodificador secreto
de modo que você pode finalmente descobrir o que é o mapeamento entre letras e números
ou cartas e cartas.
Como em um computador podemos ir sobre a implementação ou representando coisas como esta?
Precisamos de uma maneira de nos expressar um pouco mais flexível
do que as nossas variáveis ​​até agora têm permitido.
Tivemos ints, tivemos chars, tivemos carros alegóricos e de duplas e alguns outros,
mas essas são peças individuais de memória que realmente não nos permitem expressar coisas
como palavras e frases e frases.
Na verdade, nós temos chamado cordas tais coisas,
mas nós prometemos que isso é realmente apenas uma simplificação na biblioteca CS50
que estamos com a intenção de descascar.
E assim vamos começar a fazer isso aqui.
Deixe-me ir em frente e abrir um arquivo -
todos esses arquivos estão disponíveis, como de costume, online - array.c chamado
para resolver um problema relacionado com cordas, mas que pinta um quadro aqui
de como podemos usar uma coisa chamada matriz.
>> Uma matriz é um tipo de dados.
É um tipo de variável do tipo que tem vários tipos de dados menores dentro dela
de costas para trás, para trás.
Assim, por exemplo, se quiséssemos escrever um pequeno programa que lhe dá a sua média de teste
para um curso como 50, que tem dois questionários,
você poderia muito facilmente escrever este programa baseado mesmo em alguns dos materiais da semana passada
usando GetInt e um par de variáveis: int quiz1, int quiz2.
E é bastante simples.
É talvez 10, 20 linhas de código máximo para implementar um programa de
que pede ao usuário para duas pontuações do questionário e calcula a média
somando-os, dividindo por 2, e em seguida a impressão dos resultados.
Nós provavelmente poderia fazer isso muito rapidamente agora, depois de um determinado número de minutos.
Mas o problema é que, suponhamos que 50 tinham 3 ou 4 testes.
Suponha que você queria usar o mesmo programa para uma classe que teve testes semanalmente.
Pense em uma classe que tem testes semanalmente.
Se há 16 ou mais semanas, em um semestre, agora você tem 16 variáveis:
int quiz1, int quiz2, int quiz3, int quiz4.
Assim que você começar a ver essa redundância, esta cópia e colagem de código,
ele deve começar a fazer você gostaria que houvesse uma maneira melhor.
E, felizmente, porque de matrizes há. Então, vamos fazer isso.
Primeiro, deixe-me apresentar uma coisa muito simples que não usei até agora,
mas você vai ver que, ocasionalmente, em código.
>> Isto é o que é geralmente chamado de uma constante.
Então, é uma constante no sentido de que este valor nunca muda.
A convenção humana ao criar uma constante
é usar todas as letras maiúsculas apenas para que ele realmente se destaca em seu código,
ea palavra-chave especial que você usa em C # é definir.
Assim, dizemos # define, então, um espaço, então a palavra que você deseja usar para o nome constante do
e, em seguida, o valor da constante.
Note que isto é diferente de atribuir algo a uma variável.
Não há sinal de igual, não há ponto e vírgula.
Isso é o que é geralmente conhecido como uma diretiva de pré-processamento,
mas mais sobre isso em outro momento.
Por agora, isso cria um valor imutável chamado QUESTIONÁRIOS
cujo valor numérico real é 2.
Então, em qualquer lugar que você vê testes, questionários, testes ao longo deste arquivo,
isso é apenas o número 2.
Se eu olhar para principal agora, vamos ver como isso funciona.
Primeiro, ele parece um pouco enigmático, mas é tudo coisa de 1 semana.
Peça ao usuário para notas. Como podemos fazer isso?
Na linha 22 - este é realmente a parte suculenta - Declaro um flutuador
mas não apenas um único flutuador. Estou declarando, antes, um conjunto de valores de ponto flutuante.
Essa variável vai ser chamado de notas, como implicado aqui,
mas a única peça de nova sintaxe, então são estes colchetes.
O fato de que eu disse notas float e, em seguida, suporte aberto e, em seguida, um número -
perceber se esta é uma constante este é apenas como nós fizemos isso -
isso significa, "Hey computador, dá-me dois carros alegóricos e vamos chamá-los coletivamente notas."
>> Isto está em contraste com um processo muito mais tedioso assim: flutuador classe1;
grade2 flutuar, e assim por diante.
Assim, uma matriz que nos permite implementar esta idéia, mas muito menos messily,
de modo a que podemos escrever uma linha de código, em vez de, digamos, 16 para um semestre de 16 semanas.
Eu não queria rígido código-2 porque se você pensar sobre isso agora, logicamente,
suponho que no próximo ano CS50 alterações 3 quizzes vez
e eu tinha o número 2 aqui, eu tinha o número 2 aqui,
Eu tive o número 2 aqui, o número 2 aqui.
Torna-se muito tedioso e muito fácil de estragar
e mudar acidentalmente um valor para 3 e perder algum outro valor de 2.
Então, eu estou indo para lugar abstrato isso adiante e usar essa constante que,
Como o nome sugere, nunca muda.
E agora não importa se temos diferentes testes este ano ou no próximo,
Eu só tenho que mudá-lo em um lugar aqui em cima.
Então isso é tudo uma constante é.
Enquanto isso, o novo recurso conceitual é que de uma matriz.
Assim, os colchetes me dar esta flutua muitas e deixa-me chamá-los coletivamente notas aqui.
Então agora vamos ver o que eu vou fazer.
Aqui, na linha 24 é o início de um laço.
>> Isto é realmente nada extravagante. É só usar QUESTIONÁRIOS vez de um número codificado.
Mas não há nada intelectualmente diferente lá desde a semana passada.
Este é apenas printf, assim printf ("Quiz d #% de% d:")
porque eu só quero imprimir me dar questionário número 1 de 2 e, em seguida, 2 a 2.
Então isso é uma coisa puramente estética.
Mas a parte interessante agora é na linha 27.
A fim de preencher um dos dois marcadores de posição com um valor de ponto flutuante,
novamente usar colchetes.
Neste caso, eu estou usando i porque este loop começou com i igualando o valor que, aparentemente?
[Estudante] 0. >> [Malan] 0.
Assim, na primeira iteração do loop, é como se eu escrevi isso no código,
mas na segunda iteração do loop, é como se eu escrevi isso no meu código.
Mas o fato de que eu estou usando uma variável é perfeito, porque, como o nome sugere,
está variando o seu valor a cada iteração,
então eu estou preenchendo essa matriz um ponto de cada vez.
O que essa matriz se parece?
A razão que eu desenhei o retângulo super simples na tela aqui antes foi por este motivo.
Uma matriz é apenas um pedaço de memória seguido por outro pedaço de memória
seguido por um outro bloco de memória e assim por diante.
Então, se minha matriz é de tamanho 2, neste caso, aqui, tudo o que eu estaria fazendo
digitando na pontuação meus questionário como aqui - Eu tenho 100 em um presente e então eu tenho um 99 em um presente -
então esta memória não pode ser usado até mesmo porque eu só perguntei o computador
para uma matriz de tamanho 2.
Essas praças ainda estão lá, certo?
Você ainda tem 2 gigabytes de RAM, mesmo se você está apenas pedindo para 2 carros alegóricos.
Assim, a idéia por trás de matrizes é que o computador só tem um pedaço da memória
e depois reparte pequenos pedaços de costas para trás, para trás.
E para que é tudo uma matriz é.
>> É um pedaço contíguo de memória dentro do qual você pode colocar as coisas.
Isso acontece para depois fazer apenas alguns aritmética chato.
Se eu rolar por aqui, este é o lugar onde eu então iterar sobre o array.
Eu venho com o somatório de todos os valores na matriz,
e então eu uso a função round aqui para realmente fazer a soma dividida por testes.
Mas deixe-me acenar a minha mão em que, como espécie de aritmética suficiente por enquanto.
Mas tudo o que está fazendo para mim, em última análise é o cálculo de uma média.
Então, primeiro questionário, mais segundo questionário dividido por 2 e depois mostrá-lo como um int.
Mas vamos transição agora a um exemplo diferente, chamado string1,
que pinta um quadro similar, mas usando cordas.
Deixe-me ir em frente e simplificar este apenas por um momento.
Perdoe o recuo para agora.
Observe na linha 19 deste exemplo, eu recebo uma string do usuário.
Mas note o que eu estou fazendo no próximo linhas de 22 em diante.
Na verdade, estou repetindo a partir de i-se - e este é um novo truque - strlen comprimento da corda,.
Esta é uma função que vem com o C que se você passar uma string,
ele diz que o número de caracteres que estão na cadeia. Isto é tudo.
E o fato de que é strlen em vez de comprimento da corda é apenas porque é mais sucinto.
Trinta anos atrás, as pessoas gostavam de escrever coisas da forma mais sucinta possível,
por isso temos mantido essa convenção aqui.
i + + significa apenas incrementar i em cada iteração.
E agora perceber isso, o que é realmente interessante.
Na linha 24, eu digo, "Computador, dê-me um personagem, 8 bits, e chamá-lo de c."
Mas o que é isso no lado direito dizendo?
Em Inglês, o que isso representa?
[Aluno] O primeiro caractere na matriz.
Exatamente. Dá-me o primeiro caractere na matriz.
Ou, mais geralmente, dá-me o caráter om na matriz.
E perceber que é importante agora que os cientistas de computador,
na verdade estamos a contar 0.
>> Você não tem a critério agora para começar a fazer isso.
Agora você tem que se comportar de acordo com as expectativas do computador e contar de 0
porque [0] vai ser o primeiro caractere em uma seqüência,
[1] será o segundo, [2], vai ser o terceiro, e assim por diante.
Portanto, este programa, se eu compilar ele, este é novamente string1, assim que string1,
e agora eu tenho que correr string1 na minha janela de terminal.
Ele está esperando por entrada, então eu vou digitar David, Enter
e agora ela imprime Davi tudo em linhas diferentes, pois observe o que eu estou fazendo.
Estou imprimindo um caráter de cada vez.
Nós não vamos entrar em detalhes hoje sobre isso, mas eu deletei há pouco esta verificação aqui.
Acontece que se o usuário está se comportando mal, contraditório, ou apenas confuso
você pode realmente deixar de dar uma seqüência de algum tempo.
Se você bater na tecla errada no teclado, você pode dar nenhuma seqüência em tudo,
ou se você é malicioso, você pode tentar colar no valor de um gigabyte de um ensaio
para preencher essa seqüência, e se o computador ficar sem memória,
acontece que nós vamos voltar este valor especial chamado NULL.
Então, por enquanto, só sei que há esse valor especial chamado NULL
que nos permitirá verificar quando estamos fora de memória, entre outras coisas.
Mas se eu abrir agora string2, notar uma diferença aqui.
Observe uma diferença aqui com string2.
Com string2, este loop é um pouco diferente.
>> Deixe-me apagar os nulos, para que possamos falar sobre isso outra hora.
O que é diferente sobre o laço for desta vez?
Eu posso voltar ao exemplo anterior.
Então essa é a versão 2, esta é a versão 1. 1, 2.
1, 2.
A chamada strlen é onde?
É na primeira parte do loop.
Todos os pensamentos a respeito de porque eu estou fazendo isso? Sim.
[Estudante] Então você não chamar a função de cada vez.
[Malan] Então, nós não chamar a função a cada momento. Exatamente.
Lembre-se de laços que são super simples
uma vez que tipo de entender que esta é a inicialização, a condição ea atualização.
O problema é que a condição ocorre em cada iteração do loop.
E assim, neste exemplo aqui, o que é ruim sobre o fato de que esta é a minha condição?
[Aluno] Você está chamando strlen.
[Malan] Você está chamando strlen novo e de novo e de novo.
Mas uma vez que eu digitei em Davi, o comprimento da corda que é 5,
e isso não vai mudar em cada iteração do loop
porque a cadeia ainda é D-a-v-i-d.
Portanto, esta é uma dica do que vai se tornar uma idéia cada vez mais importante
conhecido como uma decisão de projeto, onde só não fazer o computador fazer um trabalho desnecessário.
>> Assim como uma prévia de pset2, pset2 na edição padrão
vai desafiá-lo para realmente implementar um número de cifras,
um número de algoritmos de criptografia, de modo que você pode tanto criptografar
e decifrar mensagens secretas, como a muito não Ralphie um decodificado.
Na edição de hacker de pset2, vamos ir um pouco mais longe.
Nós vamos entregar-lhe um arquivo de um sistema de computador real
que contém um monte de nomes de usuário e senhas criptografadas reais,
eo desafio para a edição de hacker vai ser para quebrar as senhas
e descobrir o que a criptografia ou que segredo foi usado para realmente gerar essas senhas.
E nós vamos fazer isso usando um novo recurso aqui de C
que eu vou dar-lhe apenas uma demo de conhecido como linha de comando argumentos.
Acontece que, como alguns de vocês podem ter visto na seção ou nos livros didáticos,
principal nem sempre tem que ser nula entre parênteses.
Acontece que principal também pode ser escrito assim, com dois argumentos,
argc e argv, argc, onde é o número de palavras
que você escreva depois o nome do programa em sua linha de comando
e argv são as palavras reais.
E, como os colchetes lá sugerir, argv é, aparentemente, um array.
Vai ser uma seqüência, após uma série depois de uma série na memória.
>> Então, o que nós vamos ser capazes de fazer começando com pset 2 é algo como isto.
Se eu fizer argv1, que é um exemplo que vai voltar para segunda-feira, e executá-lo,
notar que não parece fazer nada ainda.
Ele só imprime seu próprio nome.
Mas se eu disser adeus classe, aviso que este programa aparentemente itera
sobre cada uma das palavras que foram digitados no prompt.
E os meios pelos quais nós vamos ter acesso a palavras que o usuário digitou no prompt
é mudando principal a partir deste fim de semana int main (void) para int main (argc, argv)
e, assim, vai nascer de linha de comando argumentos.
E uma vez que você realmente sofisticado com isso, você vai ser capaz de escrever programas realmente trippy
como este aqui, que vai acima e além
algumas das funcionalidades que temos feito até agora, mas todos muito poderoso.
>> Então, vamos deixar isso com isso na tela, e vamos vê-lo na segunda-feira.
>> [CS50.TV]