[Powered by Google Translate] [SEMANA 5]
[David J. Malan, Harvard University]
[Esta é CS50.] [CS50.TV]
[Mulher] Ele está mentindo, sobre o que, eu não sei.
[Homem] Então, o que nós sabemos?
[Mulher] Isso às 9:15, Ray Santoya estava no caixa eletrônico.
[Homem] Então a questão é, o que ele estava fazendo em 9:16?
[Mulher] Tiro a 9 mm em alguma coisa.
Talvez ele viu o atirador.
[Homem] Ou ele estava trabalhando com ele.
[Mulher] Espere. Volte um.
[Homem] O que você vê?
[♫ ♫ música suspense]
[Mulher] Traga o rosto. Tela cheia.
[Homem] Seus óculos. >> Há uma reflexão.
[♫ ♫ música suspense]
[Homem] Essa é a equipe do Nuevita de beisebol. Essa é a sua logomarca.
[Mulher] E ele está falando com quem está vestindo a jaqueta.
>> [David Malan] Então, isso é CS50 semana 5, e hoje nós estragar um pouco de televisão e filme para você.
Assim, sempre que você está assistindo a um show como este aqui,
e os policiais dizem "Você pode limpar isso?" ou "Melhorar",
não há nenhum realce no mundo real.
Na verdade, o que realmente se é um pouco algo como isto.
Eu já puxou uma das fotos da equipe a partir da página.
Este é um programa chamado Photoshop. Esta é uma das duas Bowdens,
1 de 3 Bowdens Na verdade, hoje, porque temos a Sra. Bowden aqui também, com Rob e Paulo.
Mas aqui é Rob na tela, e se aumentar o zoom em um brilho que ele sempre teve em seu olho,
o que você realmente vê é o que você vê é o que você recebe.
Este é o "melhor", para "CSI" tem um pouco errado.
Há um outro clipe, se é que podemos escolher em "CSI" apenas um pouco mais longo.
Esta é uma frase legal para proferir doravante se você quiser
parecer técnico com seus amigos quando, na verdade, você está dizendo absolutamente nada.
>> [Homem] Durante semanas eu estive a investigar os assassinatos do assassino Cabby
com uma certa fascinação mórbida.
[Woman # 1] Esta é em tempo real.
[Woman # 2] Eu vou criar uma interface gráfica usando o Visual Basic, ver se consigo controlar um endereço IP.
>> [Malan] Então áudio fora de sincronia de lado, a criação de uma interface gráfica usando o Visual Basic
para rastrear um endereço IP é um disparate completo.
Estes dias você não usar o Visual Basic,
não há necessidade de uma interface gráfica, eo endereço IP era um termo tecnicamente preciso.
Portanto, manter um olho para fora para estes, e um dos meus favoritos:
Este é um pouco mais misterioso, porque você precisa saber uma língua diferente.
Há uma linguagem chamada Objective-C, que é um superconjunto de C.
Que significa que é C mais alguns recursos adicionais, entre eles, programação orientada a objetos.
E esta é a linguagem que a Apple popularizou para programação iOS.
E aqui está um clipe de um show completamente diferente, de "Números",
que, se você olhar de perto, na verdade, em seu TiVo e pausa no momento certo,
você vai ver que o que eles estão olhando não é muito o que está sendo descrito.
E deixe-me tentar um conector de áudio diferente aqui e ver se nós não podemos
manter o áudio em sincronia este tempo.
Eu dar-lhe "Números".
>> [Man # 1] É um endereço de 32 bits do IPv4.
[Man # 2] IP, que é a Internet. >> Rede privada. É rede privada de Anita.
[Malan] Okay. Este é Objective-C, e é para o programa de um garoto de coloração,
como você pode talvez inferir a partir do nome da variável de lá.
Para que, então, era "Números". Então, hoje e esta semana vamos introduzir
um pouco do mundo da ciência forense e do contexto dos problemas, portanto.
Hoje será uma palestra abreviada porque há um evento especial aqui
depois, por isso vamos dar uma olhada, e provocar os estudantes e pais de hoje
com algumas das coisas que são no horizonte.
Entre eles, a partir de segunda-feira, você terá um pouco mais colegas.
EDX, Harvard e MITs nova iniciativa online para Open Courseware
e mais, está lançando no campus de Harvard, na segunda-feira.
O que significa que segunda-feira é que você terá - a partir de última contagem,
86.000 colegas adicionais serão acompanhando com palestras do CS50
e seções e orientações e conjuntos de problema.
E, como parte disso, você vai se tornar membros da aula inaugural do
CS50 e agora CS50x.
>> Como parte deste, agora, perceber que haverá algumas upsides também.
Para se preparar para isso, para o grande número de estudantes,
basta dizer que, embora tenhamos 108 TFs e CAs,
não é bem a melhor relação aluno / professor, uma vez que atingiu 80.000 outros estudantes.
Portanto, não vai ser problema para muitos classificação define manualmente.
Então, introduziu esta semana no conjunto de problemas será CS50 Check,
que vai ser uma linha de comando no interior do aparelho
que você vai ter uma vez que você atualizá-lo mais tarde neste fim de semana,
e você vai ser capaz de executar um comando, verifique 50,
em seu pset próprio, e você vai obter algum feedback para saber se o seu programa é
correta ou incorreta de acordo com especificações de design diferentes que nós fornecemos.
Então mais sobre isso ea especificação do conjunto de problemas e
os colegas CS50x vai usar isso também.
>> Então conjunto de problemas 4 é tudo sobre forense.
E esta peça foi inspirada por algumas coisas da vida real,
em que quando eu estava na faculdade, eu internados por um tempo com
Escritório Distrital do Condado de Middlesex da Procuradoria está fazendo o trabalho forense
com o seu principal investigador forense, eo que isso representou
é, eu acho que eu mencionei passado algumas semanas, é a polícia do estado de Massa ou outros
iria entrar, eles cairia coisas como discos rígidos, CDs e disquetes
e similares, e, em seguida, o objectivo do escritório forense era determinar se
lá era ou não evidência de algum tipo.
Esta foi a Unidade de Investigações Especiais, por isso era crime de colarinho branco,
ele era uma espécie mais preocupante de crimes,
qualquer coisa que envolva algum tipo de mídia digital; Acontece que não que muitas pessoas
escrever um e-mail dizendo "eu fiz isso."
Então, muitas vezes essas pesquisas forenses não apareceu todos os frutos que muito,
mas às vezes as pessoas escrevem e-mails desse tipo.
Então, às vezes os esforços foram recompensados.
>> Mas, para levar até este pset forense, estaremos introduzindo no pset 4 um pouco de gráficos.
Portanto, você provavelmente levar estas coisas para concedido, JPEGs, GIFs e como nos dias de hoje,
mas se você realmente pensa sobre isso, uma imagem, assim como o rosto de Rob,
pode ser modelada como uma sequência de pontos, ou pixels.
Agora, no caso de rosto de Rob, existem todos os tipos de cores,
e começamos a ver os pontos individuais, otherwide conhecidos como pixels,
uma vez que começou a fazer zoom in
Mas se simplificar o mundo um pouco, e apenas dizer que isso aqui é Rob
em preto e branco, bem, para representar o preto e branco podemos usar apenas binário.
E se vamos usar binário, 1 ou 0, podemos expressar esta mesma imagem
de rosto sorridente de Rob com esse padrão de bits: 11000011 representa
branco, branco, preto, preto, preto, preto, branco branco.
E por isso não é um grande salto, então, começar a falar sobre fotografias coloridas.
Coisas que você veria no Facebook ou levar com uma câmera digital,
mas, certamente, quando se trata de cores, você precisa mais bits.
E bastante comum no mundo das fotografias é usar uma cor não-bit,
como isso sugere, mas cor de 24 bits, onde você realmente obter milhões de cores.
Assim como no caso quando o zoom no olho do Rob,
que era um número qualquer de milhões de diferentes possibilidades coloridas.
>> Então, nós vamos introduzir este problema em conjunto 4, bem como no passo a passo,
que será hoje às 3:30 em vez de 2:30 o habitual por causa de palestra de sexta-feira aqui.
Mas o vídeo vai estar on-line, como de costume, amanhã.
Também vamos apresentá-lo para outro formato de arquivo.
Portanto, este é deliberadamente quis olhar intimidador no início,
mas isso é apenas uma documentação alguma para uma struct C.
Acontece que a Microsoft, há anos, ajudou a popularizar este formato,
chamado o formato de arquivo bitmap, BMP, e este foi um super-simples,
formato de arquivo colorido gráfico que foi usado por algum tempo
e às vezes ainda para papéis de parede em desktops.
Se você acha que volta para o Windows XP e as colinas e céu azul,
que era tipicamente um BMP ou imagem bitmap, e bitmaps
são divertido para nós, porque eles têm um pouco mais de complexidade.
Não é tão simples como esta grade de 0 e 1 de;
em vez disso, você tem coisas como um cabeçalho no início de um arquivo.
Portanto, em outras palavras, dentro de um arquivo bmp. É um monte de 0 e 1, o
mas há algum adicional 0 e 1 em lá.
E acontece que o que nós provavelmente já um dado adquirido há anos,
formatos de arquivo como. doc ou. xls ou. mp3 ou. mp4,
quaisquer que sejam os formatos de arquivo que você está familiarizado.
Bem, o que ainda significa ser um formato de arquivo?
Porque no fim do dia, todos estes ficheiros usamos têm apenas 0 e 1 do
e talvez os 0 e 1 representam a, b, c, através ASCII ou similar,
mas até o final do dia, é apenas de 0 e 1.
>> Assim, os seres humanos apenas ocasionalmente decidem inventar um novo formato de arquivo
onde padronizar o que padrões de bits vai realmente significar.
E, neste caso aqui, o pessoal que projetou o formato de arquivo bitmap
disse que no primeiro byte em um arquivo bitmap, como indicado por offset 0, ali,
lá vai ser algum enigmaticamente chamado bfType variável chamada,
que só fica para o tipo de arquivo de bitmap, que tipo de arquivo de bitmap que é isso.
Você pode inferir, talvez, a partir de segunda linha que compensar 2, número de bytes 2,
tem um padrão de 0 e 1, que representa o que?
O tamanho de algo, e vai de lá.
Assim, no conjunto de problemas 4, você vai ser orientado por algumas destas coisas.
>> Nós não vai acabar se preocupar com todos eles, mas aviso que começa a ficar interessante
em torno da linha ou byte 54, rgbtBlue, Verde e Vermelho.
Se você já ouviu a sigla RGB, vermelho, verde azul, esta é uma referência a isso.
Porque não é que você pode pintar todas as cores do arco-íris
com uma combinação de vermelho e azul e verde.
E, de fato, os pais no quarto pode recordar alguns dos primeiros projetores.
Estes dias, você só vê uma luz brilhante que sai de uma lente.
Mas de volta ao dia, você teve a lente vermelha, lente azul, ea lente verde
e, juntos, visam a tela e formou uma imagem colorida.
E muitas vezes escolas de ensino médio e escolas secundárias teria aquelas lentes
tão-pouco torta, para que eram uma espécie de ver imagens duplas ou triplas,
mas essa era a idéia. Você tinha luz vermelha, verde e azul pintar um quadro.
E esse mesmo princípio é usado em computadores.
>> Assim, entre os desafios, então, para você em conjunto de problemas 4
vão ser algumas coisas: uma é para redimensionar uma imagem.
Para tomar um padrão de 0 e 1, o
descobrir qual pedaços de 0 e 1 representam o que de uma estrutura como esta,
e então descobrir como replicar os pixels: os vermelhos, os azuis, os verdes
dentro de modo que, quando uma imagem fica assim, inicialmente, pode ter este aspecto em vez depois disso.
Entre outros desafios, também, vai ser que você vai ser entregue
uma imagem forense de um arquivo real de uma câmera digital
e em que a câmera, era uma vez, foram um monte de fotos.
O problema é que nós acidentalmente apagados ou teve a imagem corrompida de algum modo.
Coisas ruins acontecem com câmeras digitais, e portanto, rapidamente copiado todos os de 0 e 1 do
fora desse cartão para você, salvou-los todos em um arquivo grande, e depois nós vamos entregá-los para você
no conjunto de problemas 4, de modo que você pode escrever um programa em C com o qual se recuperar
todas essas JPEGs, idealmente.
E acontece que JPEGs, mesmo que sejam um pouco de um formato de arquivo complexo,
eles são muito mais complexos do que este sorriso aqui.
Acontece que cada JPEG começa com os mesmos padrões de 0 e 1 do.
Então, usando um loop while ou um loop for ou similar,
você pode iterar sobre todos os de 0 e 1 nesta imagem forense
e cada vez que você ver o padrão especial que está definido na especificação do conjunto de problemas, a
você pode supor, 'Oh, aqui é, com grande probabilidade,
o início de um JPEG ', e assim que encontrar o mesmo padrão,
um número de bytes ou kilobytes ou megabytes depois,
você pode supor, "Ooh! Aqui é um JPEG segunda, a foto que eu tomei depois da primeira.
Deixe-me parar de ler esse arquivo em primeiro lugar, começar a escrever este novo. "
E a saída do seu programa para pset 4 vai ser cerca de 50 JPEGs.
E se não é 50 JPEGs, você tem um pouco de um loop.
Se você tem um número infinito de JPEGs, você tem um loop infinito.
De modo que, também, vai ser muito caso comum.
Isso é o que está no horizonte.
>> Questionário 0, atrás de nós. Perceba, por meu e-mail, que, invariavelmente, há pessoas
que são ambos tipo, feliz de neutro, e triste em torno de 0 Quiz tempo.
E por favor, chegar a mim, os TFs cabeça, Zamyla, sua própria TF
ou um dos CAs que você sabe, se você gostaria de discutir como as coisas correram.
>> Então, para impressionar os pais aqui na sala,
o que é a biblioteca CS50? Bom trabalho.
O que é a biblioteca CS50? Sim? [Respostas dos alunos, ininteligível]
>> Ok, bom. Portanto, é um conjunto de pré-escrita de código que nós, da equipe, escreveu:
nós fornecemos para você, para fornecer algumas funcionalidades comuns.
Coisas como me uma corda; me um int, todas as funções que estão listadas aqui.
A partir de agora, começamos a realmente tomar essas rodinhas.
Então, vamos começar a tirar uma "cadeia" de você,
que, recall, era apenas um sinônimo para o tipo de dados real? char *.
Então, para os pais, que foi provavelmente - que é bom, então char * nós vamos começar a ver
na tela tudo o mais que nós removemos "cadeia" de nosso vocabulário,
pelo menos quando se trata de realmente escrever código.
Da mesma forma, nós vamos parar de usar algumas dessas funções tanto,
porque os nossos programas estão indo para obter mais sofisticado
em vez de apenas escrever programas que ficam lá com um piscar prompt,
à espera de que o usuário digite algo dentro
Você terá suas entradas a partir de outro lugar.
Por exemplo, você vai levá-los a partir de uma série de bits no disco rígido local.
Você vai em vez levá-los no futuro a partir de uma conexão de rede, algum site em algum lugar.
Então, vamos descascar essa camada pela primeira vez, e puxar para cima o aparelho CS50
e este arquivo chamado CS50.h, que você tenha sido acentuada incluindo por semanas.
>> Mas vamos ver realmente o que está dentro do presente.
Assim, o início do arquivo em azul é apenas um monte de comentários,
informações sobre a garantia e licenciamento. Esta é uma espécie de paradigma comum
em software, porque um monte de software nos dias de hoje é o que é chamado de "código aberto",
o que significa que alguém tenha escrito o código
e tornou disponível gratuitamente, e não apenas para correr e para usar,
mas, na verdade, ler e alterar e integrar no seu próprio trabalho.
Então é isso que você está usando, o software de código aberto,
embora de uma forma muito pequena.
Se eu rolar para baixo após os comentários, porém, vamos começar a ver algumas coisas mais familiares.
Então, observe no topo aqui, que o arquivo CS50.h inclui um conjunto de arquivos de cabeçalho.
Agora, a maioria destes não vimos antes, mas é um
familiar; qual destes temos visto, ainda que brevemente, até agora?
Sim, bibliotecas padrão. Stdlib.h tem malloc,
Portanto, uma vez que começamos a falar sobre a alocação dinâmica de memória,
que vamos voltar para a próxima semana, assim, começamos incluindo o arquivo.
Acontece que bool e verdadeiro e falso na verdade, não existe em C, por si só,
a menos que você inclua esse arquivo aqui.
Portanto, temos, por semana, incluindo sido padrão bool.h
de modo que você pode usar a noção de um. bool, verdadeiro ou falso
Sem isso, você teria que classificar de fingir e usar um int
e apenas arbitrariamente assumir que 0 é falso e 1 é verdadeira.
>> Agora, se rolar mais, aqui é a nossa definição de uma cadeia.
Acontece que, como já disse antes, que quando isso * é realmente não importa.
Você pode até ter todo o espaço ao redor.
Nós, neste semestre, têm vindo a promover-lo como esta para deixar claro que o * tem a ver com o tipo.
Mas perceber, como comum, se não um pouco mais comum, é colocá-lo lá
mas funcionalmente é a mesma coisa.
Mas agora, se lermos mais para baixo, vamos dar uma olhada em, digamos, GetInt,
porque usamos que, talvez, antes de mais nada neste semestre.
E aqui está GetInt. Isto é o que?
Este é o protótipo. Então, muitas vezes, temos que colocar protótipos no topo de nossa. Arquivos c,
mas você também pode colocar protótipos em arquivos de cabeçalho, arquivos. h,
como este aqui, de modo que quando você escreve algumas funções
que você quer que outras pessoas para ser capaz de usar, que é exatamente o caso com a biblioteca CS50,
você não só implementar suas funções em algo como CS50.c,
você também colocar os protótipos não no topo do arquivo, mas no topo de um arquivo de cabeçalho,
em seguida, o arquivo de cabeçalho é o que os amigos e colegas de incluir,
com acentuada incluir no seu próprio código.
Então, todo esse tempo que você tem, incluindo todos os protótipos
efetivamente no topo do seu arquivo, mas por meio deste mecanismo incluem afiada
que praticamente copia e cola este arquivo em seu próprio país.
Agora, aqui está alguma documentação bastante detalhada.
>> Nós praticamente um dado adquirido que GetInt recebe um int,
mas acontece que há alguns casos de canto, certo?
E se o usuário digita um número que é muito grande?
A quintilhões, que simplesmente não pode caber dentro de um int?
Qual é o comportamento esperado? Bem, idealmente, é previsível.
Portanto, neste caso, se você realmente ler a cópia fina,
você vai ver que, se a linha não pode ser lido, INT_MAX este retorno.
Nós nunca conversamos sobre isso, mas com base na sua capitalização,
o que é, provavelmente?
É uma constante, por isso é uma constante especial que é, provavelmente, declarou
em um desses arquivos de cabeçalho que é até maior no arquivo,
e INT_MAX é provavelmente algo como, aproximadamente, 2 bilhões.
A idéia é que, porque precisamos de alguma forma, significa que algo saiu errado,
temos, sim, tem 4 bilhões de números à nossa disposição,
negativa 2 bilhões em até 2 bilhões, mais ou menos.
Bem, o que é comum em programação é você roubar apenas um desses números.
Talvez 0, talvez 2 bilhões, talvez negativo 2 bilhões.
Então você gasta um de seus valores possíveis de modo que você pode cometer ao mundo
que, se algo der errado, eu vou retornar esse valor super-grande.
Mas você não quer que o usuário digitar algo enigmático como "2, 3, 4 ..."
de número realmente grande, onde você generalizar vez como uma constante.
Então, realmente, se você estava sendo anal nas últimas semanas,
quando você chamar GetInt, você deveria ter vindo a verificar com uma condição se.
Será que o usuário digite INT_MAX, ou mais especificamente,
fez GetInt INT_MAX retorno? Porque, se o fez,
que realmente significa que eles não digitá-lo, algo deu errado neste caso.
Portanto, este é o que é geralmente conhecido como "sentinela" valor, o que significa apenas especial.
>> Bem, vamos agora para os arquivos. C.
O arquivo C existiu no aparelho por algum tempo,
e, de fato, o aparelho tem pré-compilado para você
nessa coisa que chamamos de "código objeto",
mas ele simplesmente não importa para onde está porque o sistema sabe,
neste caso, em que é, o aparelho.
Mas vamos rolar agora para getInt, e ver como GetInt vem trabalhando todo esse tempo.
Portanto, temos aqui comentários similares de antes.
Deixe-me zoom em apenas parte do código,
eo que temos para GetInt é o seguinte.
Não é preciso de entrada e retorna um int, enquanto (verdadeiro), por isso temos um loop infinito deliberada
mas, provavelmente, vamos romper com isso de alguma forma, ou retornar a partir desta.
Então vamos ver como isso funciona. Bem, parece que estamos usando GetString
nesta primeira linha dentro do loop, 166.
Isto agora é uma boa prática, porque em que circunstâncias
GetString poderia retornar este especial palavra-chave NULL,?
Se algo der errado. O que poderia dar errado quando você chamar algo como GetString?
Sim? [Responder Estudante, ininteligível] >> Yeah. Então talvez malloc falhar.
Em algum lugar debaixo do capô GetString está chamando malloc,
que aloca memória, que permite que a loja de informática
todos os caracteres que o usuário digita no teclado.
E suponha que o usuário tinha um monte de tempo livre
e digitado mais, por exemplo, de 2 biliões de caracteres.
Mais caracteres que o computador ainda tem RAM.
Bem, GetString tem de ser capaz de significar que a você,
mesmo que este é um super, super-canto caso incomum.
Ela tem, de alguma forma ser capaz de lidar com isto, e de modo GetString,
se voltar e ler sua documentação, se, de fato, retornar NULL.
Agora, se GetString falhar, retornando NULL, GetInt vai falhar
retornando INT_MAX, como uma sentinela.
Estes são apenas convenções humanas. A única maneira que você sabe que este é o caso
é lendo a documentação.
Então, vamos rolar para onde o int é realmente GotInt.
>> Então, se eu rolar um pouco mais, na linha 170, temos um comentário acima destas linhas.
Assim, declaramos, em 172, um n int e um char c, e então esta nova função
que alguns de vocês ter tropeçado antes, mas sscanf.
Isso significa string f digitalização.
Em outras palavras, dá-me uma corda e eu irá procurar por peças de informação de interesse.
Então, o que isso significa? Bem, suponha que eu digitar, literalmente, 1 2 3 no teclado,
e tecle enter. Qual é o tipo de dados de 1 2 3 quando retornou por GetString?
É óbvio que é uma string, certo? Eu tenho uma string, assim 1 2 3 é realmente "1 2 3"
com o 0 \ no final da mesma. Isso não é um int.
Isso não é um número. Parece um número, mas isso não é verdade.
Então, o que GetInt tenho que fazer? Tem que analisar essa seqüência esquerda para a direita,
1 2 3 \ 0, e de alguma forma, convertê-lo em um inteiro real.
Agora, você pode descobrir como fazer isso.
Se você acha que volta para pset 2, você provavelmente tem um pouco confortável
com César ou vigenere assim você pode iterar sobre uma corda,
você pode converter caracteres para ints com picareta. Isso é um monte de trabalho.
Por que não chamar uma função como sscanf que faz isso para você?
Então sscanf espera um argumento, neste caso chamado de linha, que é uma cadeia.
Você, então, especificar, entre aspas, muito semelhante ao printf,
o que você espera para ver nesta corda?
O que eu estou dizendo aqui é que, eu espero ver um número decimal e talvez um personagem.
E vamos ver por que este é o caso em apenas um momento.
Acontece que esta notação é agora lembra de coisas
começamos a falar sobre pouco mais de uma semana atrás.
>> O que é & n & c e fazendo por nós aqui? [Respostas dos alunos, ininteligível]
Sim >>. Está me dando o endereço de n e endereço do c.
Agora, por que isso é importante? Bem, você sabe que com funções em C
você sempre pode retornar um valor ou nenhum valor.
Você pode retornar um int, uma corda, uma bóia, um char, o que for.
Ou você pode retornar vazio, mas você só pode retornar 1 coisa ao máximo.
Mas, aqui queremos sscanf para voltar me talvez um int, um número decimal,
e também um. char, e eu vou explicar por que o char em um momento
Então você efetivamente quer f para retornar 2 coisas, que não é apenas possível em C.
Então você pode resolver isso passando em dois endereços,
porque assim que você entrega uma função de dois endereços, o que essa função faz com eles?
Ele pode escrever para esses endereços. Você pode usar a operação * e "ir lá" para cada um desses endereços.
É uma espécie de este mecanismo backdoor, mas muito comum para alterar os valores das variáveis
em mais do que apenas um lugar, neste caso 2.
Agora, repare que eu estou verificando para == to1, e depois retornando n se isso, de fato, avaliar a verdade.
Então, o que está acontecendo? Bem, tecnicamente, tudo o que realmente quer que aconteça em GetInt é esta.
Queremos analisar, por assim dizer, queremos ler a seqüência
"1 2 3" e se parece que há um número lá,
o que estamos dizendo sscanf a fazer é colocar esse número, 1 2 3, nesta variável n para mim.
Por que, então, eu tinha isso também?
Qual é o papel de também dizer, sscanf, você também pode obter um personagem aqui.
[Falando Estudante, ininteligível] >> Não - um ponto decimal podia trabalhar.
Vamos sustentar que pensou por um momento. O que mais?
[Estudante, ininteligível] >> Então, o pensamento bom, poderia ser o caractere nulo.
Na verdade não é, neste caso. Sim? [Estudante, ininteligível]
>> >> ASCII. Ou, deixe-me generalizar ainda mais.
O c% não é apenas para verificação de erros.
Nós não queremos que haja caráter após o número,
mas o que isso me permite fazer é o seguinte:
Acontece que sscanf, além de armazenar valores de n e c, neste exemplo aqui,
o que também não é ele retorna o número de variáveis ​​que colocar valores dentro
Então, se você digitar apenas na 1 2 3, somente o% d vai coincidir com
e só n fica armazenado com um valor como 1 2 3 e nada é colocado em c;
c continua a ser um valor de lixo, por assim dizer.
Lixo, porque isso nunca foi inicializado como algum valor.
Assim, neste caso, sscanf retornará 1, porque I preenchida uma destas indicações,
caso em que, ótimo. Eu tenho um int, então eu liberar a linha para liberar a memória
GetString que efectivamente atribuído, e então eu voltar n.
Outra coisa, se você já se perguntou onde que repetir declaração vem, vem aqui.
Se, pelo contrário, eu digitar 1 2 3 foo,
apenas uma seqüência aleatória de algum texto, sscanf vai ver,
ooh, número, ooh, número, ooh, número, ooh - f.
E vai colocar o 1 2 3 no n.
Vai colocar o f em c, e depois voltar 2.
Então nós temos, apenas usando a definição básica de comportamento do scanf,
uma maneira muito simples - bem, complexo, à primeira vista, mas no final do dia,
mecanismo bastante simples de dizer, há um int, e se assim for, é que a única coisa que eu encontrei?
E o espaço em branco aqui é deliberada. Se você ler a documentação para sscanf,
ele diz-lhe que, se você incluir um pedaço de espaço em branco no início ou no final,
sscanf também vai permitir que o usuário, por qualquer motivo, a barra de espaço para bater 1 2 3, e que será legítimo.
Ele não vai gritar com o usuário só porque bateu a barra de espaço no início ou no final,
que é apenas um pouco mais user-friendly.
>> Qualquer dúvida, então, sobre GetInts? Sim?
[Pergunta do estudante, ininteligível]
>> Boa pergunta. E se você acabou de digitar em um char, como hit f, e digite
sem nunca digitando 1 2 3, o que você acha que o comportamento desta linha de código seria então?
Assim sscanf pode cobrir isso também, porque, nesse caso,
não vai encher n ou c, que vai, em vez retornar 0.
Nesse caso, eu também estou pegando esse cenário, porque o valor esperado que eu quero é 1.
Eu só quero uma, e apenas uma coisa a ser preenchido. Boa pergunta. Outros?
>> Tudo bem, então não vamos passar por todas as funções aqui,
mas o que parece ser, talvez, da participação remanescente
é GetString pois verifica-se que GetFloat, GetInt,
GetDouble, GetLongLong todos punt muito de sua funcionalidade para GetString.
Então, vamos dar uma olhada em como ele é implementado aqui.
Este parece um pouco complexo, mas ele usa os mesmos fundamentos
que começamos a falar sobre a semana passada. Assim, em GetString,
que leva nenhum argumento conforme o vazio até aqui,
e retorna uma string, por isso eu estou declarando uma string chamada buffer.
Eu realmente não sei o que vai ser usado para ainda, mas vamos ver.
Parece que a capacidade é, por padrão, 0; não tem certeza de onde isso vai dar.
Não sei o que n vai ser usado para ainda.
Mas agora está ficando um pouco mais interessante, assim, em linha 243,
declaramos um int c, isto é uma espécie de um detalhe estúpido.
Um char é de 8 bits, e 8 bits pode armazenar quantos valores diferentes?
256. O problema é que, se você quer ter 256 diferentes caracteres ASCII,
que há, se você olhar para trás, e isso não é algo para memorizar.
Mas se você acha que volta para esse gráfico grande ASCII tivemos semanas atrás,
foram, neste caso, de 128 ou 256 caracteres ASCII.
Nós usamos todos os padrões de 0 e 1 para cima.
Isso é um problema se você quiser ser capaz de detectar um erro.
Porque se você já está usando 256 valores para seus personagens,
você realmente não planejar com antecedência, porque agora você não tem nenhuma maneira de dizer,
"Este não é um personagem legal, o que é uma mensagem errada".
Então, o que o mundo faz é, eles usam o valor maior seguinte,
algo como um int para que você tenha um número louco de bits,
32 para 4 mil milhões de valores possíveis, de modo que você pode simplesmente acabar usando,
essencialmente, 257 deles, um dos quais tem algum significado especial como um erro.
>> Então vamos ver como isso funciona. Na linha 246, eu tenho essa grande loop while
que está chamando fgetc; f arquivo significado, getc, e depois stdin.
Acontece que esta é apenas a maneira mais precisa de dizer "ler a entrada do teclado."
Teclado meio padrão de entrada, saída padrão significa tela,
e erro padrão, o que veremos na pset 4, significa que o ecrã,
mas uma parte especial da tela de modo que não é confundida
com a saída real que você pretende imprimir, mas mais sobre isso no futuro.
Então fgetc significa apenas ler um caracter do teclado, e armazená-lo onde?
Guarde-o em c, e depois verificar, então eu estou usando apenas algumas conjunções booleanos aqui,
verificar que não é igual a \ n, de modo que o usuário tenha aperte enter.
Queremos parar nesse ponto, final do ciclo, e também queremos verificar
para a constante especial, EOF, que se você saber ou adivinhar - o que é que significa?
Fim do arquivo. Portanto, este é o tipo de absurdo, porque se eu estou digitando no teclado,
não há realmente nenhum arquivo envolvido nisso,
mas isso é apenas uma espécie de o termo genérico utilizado para significar
que nada mais é que vem dedos dos humanos. EOF. Fim do arquivo.
Como um aparte, se você já atingiu o controle d em seu teclado,
não que você teria ainda, você bateu controle c.
Mas o controle d envia esta constante EOF especial chamado.
>> Portanto, agora só temos alguns alocação dinâmica de memória.
Então, se n + 1> capacidade, agora eu vou explicar n.
n é apenas quantos bytes estão atualmente no buffer,
a seqüência que você está actualmente a construir-se a partir do usuário.
Se você tem mais caracteres em seu buffer do que você tem capacidade de buffer,
intuitivamente, o que precisamos fazer, então, é alocar mais capacidade.
Eu estou indo para pular um pouco da aritmética aqui
e focar apenas esta função aqui.
Sabe o que malloc é, ou pelo menos geralmente familiar.
Adivinha o que realloc faz. [Responder Estudante, ininteligível]
Sim >>. E não é muito a adição de memória, que realoca memória da seguinte maneira:
Se ainda há espaço no final da cadeia para dar-lhe mais do que a memória
do que originalmente lhe dá, então você vai ter que memória adicional.
Então você pode apenas colocar os personagens cordas de costas para trás, para trás.
Mas se esse não é o caso, porque você esperou muito tempo
e algo aleatório tem se estatelou na memória lá, mas não é extra
memória aqui, tudo bem. Realloc vai fazer todo o trabalho pesado para você,
mover a seqüência que você já leu em assim muito longe daqui,
colocá-lo lá em baixo, e depois dar-lhe um pouco mais de pista naquele ponto.
Assim, com um aceno de mão, deixe-me dizer que o que está fazendo GetString
é que está começando com um buffer pequeno, talvez um caráter único,
e se o usuário digita em dois personagens, GetString acaba
chamando realloc e diz, 'Oh, um personagem não foi suficiente.
Dá-me duas personagens. " Então, se você ler a lógica do circuito,
ele vai dizer: 'Oh, o usuário digitou 3 caracteres.
Dê-me agora não dois, mas quatro personagens, então me dar oito, então me dê 16 e 32. "
O fato de que eu estou dobrando a capacidade de cada vez
significa que o buffer não vai crescer lentamente.
Vai crescer super rápido, eo que poderia ser a vantagem disso?
Por que eu estou dobrando o tamanho do buffer, mesmo que o usuário
só precisa um personagem extra a partir do teclado?
[Responder Estudante, ininteligível]. >> O que é isso?
Exatamente. Você não tem que crescer sempre.
E esta é apenas uma espécie de - você cobertura suas apostas aqui.
A idéia é que você não quer chamar realloc muito, porque ele tende a ser lenta.
Toda vez que você perguntar o sistema operacional para a memória, como você verá em breve
em um conjunto de problema futuro, tende a levar algum tempo.
Assim, minimizando a quantidade de tempo, mesmo se você está perdendo um pouco de espaço, tende a ser uma coisa boa.
>> Mas se lermos a parte final da GetString aqui,
e, novamente, a compreensão de cada linha, aqui, não é tão importante hoje.
Mas note que, eventualmente, chama malloc novamente, e ele aloca
exatamente como muitos bytes que ele precisa para a cadeia
e depois joga fora chamando livre, o buffer excessivamente grande,
se realmente foi dobrado muitas vezes.
Em suma, é assim que GetString vem trabalhando todo esse tempo.
Tudo que faz é ler um personagem em um momento novo e de novo e de novo
e cada vez que precisa de um pouco de memória adicional, pede ao sistema operacional para ele chamando realloc.
Alguma pergunta? Tudo bem.
>> Um ataque. Agora que entendemos ponteiros, ou pelo menos
estão cada vez mais familiarizados com ponteiros,
vamos considerar como o mundo inteiro começa a entrar em colapso
se você não consegue se defender contra os usuários contraditório,
pessoas que estão tentando invadir seu sistema.
As pessoas que estão tentando roubar o seu software, contornando alguns código de registro
que eles poderiam ter que digitar dentro
Dê uma olhada neste exemplo aqui, que é apenas o código C
que tem uma função principal na parte inferior, que chama uma função foo,
e para que é que passa a foo? [Estudante] Um único argumento.
>> Único argumento. Então, argv [1], o que significa que a primeira palavra que o usuário digitou
na linha de comando depois de a.out ou qualquer que seja o programa é chamado.
Então foo, na parte superior, leva em um char *, char *, mas é exatamente o que?
String. Não há nada de novo aqui, e essa seqüência é arbitrariamente sendo chamado de bar.
Nesta linha aqui, char c [12], em uma espécie de semi-técnico Inglês, o que é essa linha está fazendo?
Matriz de -? Caracteres. Dê-me um conjunto de 12 caracteres.
Assim, poderíamos chamar isso de um buffer. É tecnicamente chamado de c, mas um tampão na programação
significa apenas um monte de espaço que você pode colocar algumas coisas dentro
>> Então, por fim, memcpy, não usei antes.
Mas você pode adivinhar o que ele faz. Ele copia memória.
O que ele faz? Bem, aparentemente copia bar, sua entrada, em c,
mas apenas até o comprimento da barra.
Mas há um bug aqui.
Ok, então, tecnicamente, deve realmente fazer strlen (bar) x sizeof (char), isso é correto.
Mas, no pior caso aqui, vamos supor que isso é - assim, tudo bem.
Então há dois bugs. Então, sizeof (char), tudo bem, vamos fazer isso um pouco mais.
Então, agora ainda há um bug, que é o que?
[Responder Estudante, ininteligível] Verificação >> para quê? Ok, então nós deve verificar
para NULL, porque as coisas ruins acontecem quando o ponteiro é NULL,
Porque você pode acabar indo lá, e você não deve nunca estar indo para NULL
por desreferência-lo com o operador *.
Então, isso é bom, eo que mais estamos fazendo? Logicamente há uma falha aqui também.
[Responder Estudante, ininteligível]
Portanto, verifique se >> argc ≥ 2?
Ok, então há três bugs neste programa.
Nós não estamos verificando se o usuário realmente digitou alguma coisa em argv [1], bom.
Então, qual é o bug terceiro? Sim?
[Responder Estudante, ininteligível] >> Boa.
Então, vamos checar um cenário. Nós implicitamente verificado não copie mais memória
que excede o comprimento da barra.
Então, se a string que o usuário digitou é de 10 caracteres,
isto está dizendo: "Só copiar 10 caracteres.
E está tudo bem, mas e se o usuário digitou uma palavra no prompt
como uma palavra de 20 caracteres, isto é, dizendo cópia 20 caracteres de bar em que?
c, também conhecido como o nosso buffer, o que significa que você acabou de escrever dados
a 8 locais de bytes que você não possui,
e você não possuí-los no sentido de que você nunca alocados eles.
Portanto, este é o que é geralmente conhecido como o ataque de estouro de buffer,
ou tampão ataque superação, e é ataque no sentido de que se o usuário
ou o programa que está chamando a sua função é fazer isso de forma maliciosa,
o que realmente acontece próximo pode ser muito ruim.
>> Vamos dar uma olhada nesta foto aqui.
Esta imagem representa sua pilha de memória.
E lembrar que cada vez que você chamar uma função,
você tem esse quadro pouco na pilha e depois outro e depois outro e depois outro.
E, até agora, temos apenas um tipo de abstraídas estas longe como retângulos
ou há no conselho ou na tela aqui.
Mas, se aproximar de um desses rectângulos,
quando você chamar uma função foo, verifica-se que há mais na pilha
dentro desse quadro e que retângulo
que apenas x e y e a e b, como fizemos falando sobre swap.
Acontece que há alguns detalhes de nível inferior,
entre eles retornam endereço.
Assim, verifica-se quando principal chama foo, principal tem de informar foo
o endereço principal está na memória do computador.
Porque, caso contrário, logo que foo é feito de execução, tal como neste caso aqui,
uma vez que você chegar a esta estreita cinta encaracolado no final de foo,
como o diabo não foo sabe onde o controle do programa deve ir?
Acontece que a resposta a essa pergunta é em que retângulo vermelho aqui.
Isso representa um ponteiro, e cabe ao computador para armazenar, temporariamente,
sobre a pilha de chamada o endereço da página, de modo que, logo que é feito foo execução,
o computador sabe onde e qual linha principal para voltar.
Ponteiro do quadro salvo se relaciona de forma semelhante a esta.
Char bar * aqui representa o que?
Bem, agora este segmento azul aqui é frame foo, o que é bar?
Ok, então barra é apenas o argumento para a função foo.
>> Portanto, agora estamos de volta para o quadro familiar.
Há mais coisas e mais distrações na tela
mas esse segmento de luz azul é o que estamos desenhando no quadro-negro para algo como swap.
Esse é o quadro para foo ea única coisa em que agora é bar,
que é este parâmetro.
Mas o que mais deve estar na pilha, de acordo com este código aqui?
Char c [12]. Assim, devemos também ver 12 quadrados de memória,
atribuída a uma variável chamada c.
E de fato temos que na tela.
O topo há c [0], e em seguida o autor deste diagrama
não se incomodou desenhar todas as praças, mas há de fato há 12
porque se você olhar no canto inferior direito, c [11], se você contar de 0, é o 12 bytes tais.
Mas aqui está o problema: Em que direção está crescendo c?
Tipo de cima para baixo, certo? Se ele começa na parte superior e aumenta para o fundo,
não se parece com nós mesmos deixamos pista muito aqui.
Nós tipo de pintado nos em um canto,
e que c [11] é até contra bar, que fica à direita contra o ponteiro quadro de pilha,
que é até contra o endereço de retorno, não há mais espaço.
Então, qual é a implicação, então, se você estragar,
e você tenta ler 20 bytes em um buffer de 12 bytes?
Onde estão os 8 bytes adicionais indo?
Dentro de tudo o resto, alguns dos quais é super importante.
E a coisa mais importante, potencialmente, é a caixa vermelha lá, endereço de retorno.
Porque acho que você é acidentalmente ou adversarially
substituir esses 4 bytes, que endereço do ponteiro,
não apenas com o lixo, mas com um número que acontece para representar um endereço real na memória?
Qual é a implicaiton, logicamente?
[Respostas dos alunos, ininteligível] >> Exatamente. Quando retorna foo
e hits que chaveta, o programa vai continuar não voltar ao principal,
ele vai voltar a qualquer endereço em que é caixa vermelha.
>> Agora, no caso do registo do software contornar,
qual é o endereço que está sendo retornado para a função é
que normalmente é chamado depois que você paga pelo software e inserido o seu código de registro?
Você poderia classificar de enganar o computador em não ir aqui, mas em vez disso, vai-se aqui.
Ou, se você é realmente inteligente, um adversário pode realmente digitar no teclado,
por exemplo, não uma palavra real, e não de 20 personagens, mas suponho que ele ou ela
em alguns tipos de caracteres que representam o código?
E não vai ser de código C, que vai ser os personagens
que representam códigos binários de máquinas, 0 e 1 a.
Mas suponha que eles são espertos o suficiente para fazer isso, de alguma forma, colar no prompt GetString
algo que é, essencialmente, o código compilado,
e os últimos 4 bytes substituir esse endereço de retorno, e que endereço se que a entrada de fazer?
Ele armazena neste retângulo vermelho o endereço do primeiro byte do buffer.
Então você tem que ser realmente inteligente, e isso é um monte de tentativa e erro
para pessoas ruins lá fora, mas se você pode descobrir o quão grande é este tampão,
de tal forma que os bytes últimos na entrada que você fornecer para o programa
Acontece que equivale ao endereço de início do seu tampão,
você pode fazer isso. Se dizemos, normalmente, Olá, e \ 0, que é o que acaba no buffer.
Mas se nós somos mais inteligentes, e preenchemos o buffer com o que vamos chamar genericamente código de ataque,
A, A, A, A: Ataque, ataque, ataque, ataque, onde este é apenas algo que faz algo ruim.
Bem, o que acontece se você é realmente inteligente, você pode fazer isso:
Na caixa vermelha aqui é uma seqüência de números: 80, CO, 35, 08.
Note que que coincide com o número que está aqui em cima.
É na ordem inversa, mas mais sobre isso em outro momento.
Note que este endereço de retorno foi deliberadamente alterado
para igualar o endereço aqui, não o endereço do principal.
Então, se o cara mau é super inteligente, ele ou ela vai incluir nesse código de ataque
algo como, 'Apagar todos os arquivos do usuário. "
Ou "copiar as senhas", ou "Criar uma conta de usuário que eu possa entrar em '.
Qualquer coisa, e isso é tanto perigo quanto o poder de C.
Porque você tem acesso a memória através de ponteiros
e, portanto, você pode escrever o que quiser na memória de um computador.
Você pode fazer um computador fazer o que quiser, simplesmente
tendo que pular dentro do seu próprio espaço de memória.
E assim, até hoje, tantos programas e sites de tantos que estão comprometidas
resumem-se a pessoas que tomam vantagem disso.
E isso pode parecer um ataque super-sofisticado,
mas nem sempre é iniciado assim.
>> A realidade é que o que as pessoas ruins normalmente fazer é,
se é um programa em uma linha de comando ou um programa gráfico ou um site,
é que você acabou de começar a fornecer um absurdo.
Você digita uma palavra muito grande no campo de pesquisa e tecle enter,
e esperar para ver se as falhas do site.
Ou você esperar para ver se o programa se manifesta alguma mensagem de erro.
Porque, se você tiver sorte, como o cara mau,
e você fornecer algumas informações louco que trava o programa,
isso significa que o programador não antecipou o seu mau comportamento
o que significa que você pode provavelmente, com bastante esforço,
julgamento suficiente e erro, descobrir como travar um ataque mais preciso.
Assim como uma grande parte de segurança não é apenas evitar estes ataques completamente, mas detectá-los
e realmente olhar para os logs e ver o que as pessoas loucas entradas digitadas em seu site.
Que termos de pesquisa digitados pessoas em seu site, na esperança de transbordar alguns buffer?
E isso tudo se resume a os princípios simples do que é uma matriz,
eo que isso significa para alocar e usar a memória?
E, com relação a isso, também, é isso.
>> Então vamos apenas olhar para dentro de um disco rígido novamente.
Então, você se lembra de uma ou duas semanas atrás que quando você arrastar os arquivos
a sua lixeira ou lata de lixo, o que acontece?
[Estudante] Nada. >> Sim, absolutamente nada. Eventualmente, se você executar baixa
espaço em disco, Windows ou Mac OS vai começar a apagar arquivos para você.
Mas se você arrastar alguma coisa lá dentro, então não é de todo segura.
Todo o seu membro do amigo companheiro de quarto, ou a família tem que fazer é clicar duas vezes, e pronto.
Há todos os arquivos esboçado que você tentou excluir.
Assim, a maioria de nós, pelo menos, saber que você tem com o botão direito ou clique
e lixo o vazio, ou algo assim.
Mas, mesmo assim, que não chega a fazer o truque.
Porque o que acontece quando você tem um arquivo em seu disco rígido
que representa algum documento ou alguma palavra JPEG?
E isso representa o seu disco rígido, e vamos dizer que esta faixa aqui representa o arquivo,
e é composto de um monte de 0 e 1 do.
O que acontece quando você não só arrastar o arquivo para a lixeira ou lixeira,
mas também esvaziá-la?
Espécie de nada. Não há absolutamente nada agora.
Agora é só nada, porque alguma coisa acontece na forma de tabela.
Portanto, há uma espécie de banco de dados ou tabela dentro da memória de um computador
que, essencialmente, tem uma coluna de nomes de arquivos,
e uma coluna para o local do arquivo, onde este pode ser local 123, apenas um número aleatório.
Assim, poderíamos ter algo como x.jpg e localização 123.
E o que acontece, então, quando você esvaziar o seu lixo?
Que vai embora. Mas o que não vai embora é o de 0 e 1.
>> Então, o que, então, a conexão com PSet 4?
Bem, com pset 4, só porque temos acidentalmente apagados
o cartão de memória flash compacto que tinha todas essas fotos,
ou apenas porque pela má sorte tornou-se corrompido,
não significa que a 0 e 1 não ainda estão lá.
Talvez alguns deles são perdidos porque algo foi corrompido
no sentido de que alguns de 0 tornou-se 1 e tornou-se um 0.
Coisas ruins podem acontecer por causa do software de buggy ou hardware defeituoso.
Mas muitos desses bits, talvez até 100% deles ainda estão lá,
é só que o computador ou a câmera não sabe onde JPEG 1 começou
e onde JPEG 2 começou, mas se você, programador,
sabe, com um pouco de habilidade, onde os JPEGs são ou o que eles se parecem,
você pode analisar o de 0 e 1, e dizer, 'Ooh. JPEG. Ooh, JPEG.
Você pode escrever um programa com essencialmente apenas um for ou while
que recupera todos e cada um desses arquivos.
Assim, a lição, então, é começar a "segurança" de apagar seus arquivos
se você gostaria de evitar este completamente. Sim?
[Pergunta do estudante, ininteligível]
>> Tenha mais memória do que você fez antes -
Oh! Boa pergunta. Então, por que, então, depois de esvaziar a lixeira,
se o seu computador te dizer que você tem mais espaço livre do que você fez antes?
Em poucas palavras, porque ele está mentindo. Mais tecnicamente, você tem mais espaço.
Porque agora você disse, você pode colocar outras coisas em que o arquivo era uma vez,
mas isso não significa que os bits estão indo embora,
e isso não significa que os bits estão sendo alterados todos os 0, por exemplo, para sua proteção.
Por outro lado, se você "seguramente" apagar arquivos ou destruir fisicamente o dispositivo,
que realmente é o único caminho, às vezes, em torno disso.
Então, por que não deixamos em que a nota semi-assustador, e vamos vê-lo na segunda-feira.
CS50.TV