[Seção 9] [mais confortável] [Rob Bowden] [Harvard University] [Isto é CS50.] [CS50.TV] Tudo bem. Basicamente hoje é tudo até vocês para fazer algumas perguntas. Eu poderia ser capaz de passear com alguns tópicos para um pouco se ninguém tem perguntas a fazer. Espero que você faz. Alguém tem alguma dúvida? Talvez a partir de testes passados, coisas que você não está confortável com ele. Sim. [Estudante] Você pode passar por cima de ataques de estouro de buffer? [Rob] Claro. O principal exemplo na verdade pode estar bem aqui. O principal negócio por trás dos ataques de estouro de buffer são nós temos algum buffer, aqui. Char c - que é apenas de tamanho 12 - mas então estamos inserindo algo em que reserva mas não verificar exatamente quanto estamos inserindo. Aqui estamos inserindo strlen (bar) em C, mas quem sabe quanto tempo é bar. Se for mais de 12 caracteres, então isso vai estourar este buffer. Olhando para este quadro - se você tomar 61 você vai ter muito mais familiarizado com esse tipo de esquema e lidar com o ponteiro do quadro salvo e endereço de retorno e pilha rotina dos pais e todas essas coisas reais. Mas aqui você só precisa saber que temos este pequeno espaço para o nosso buffer. Aqui temos c (0) e, em seguida, temos c, 1, 2, 3, 4, 5 e assim por diante. Em circunstâncias normais, teríamos preencher este buffer como de costume. Se inserido 'Olá' teríamos h-e-l-l-o / 0, e, em seguida, apenas um monte de espaço vazio. Para um hacker - oh, eu acho que este é o exemplo. Para um hacker que conseguir algo como este, onde o que eles estão especificamente tentando fazer é geralmente substituir o endereço de retorno. Sempre que você chamar uma função e seu quadro de pilha é empurrado para a pilha que quadro de pilha precisa saber como - bem, a função que tem sido chamado precisa saber como voltar para a função que o chamou. Assim, se as chamadas principais foo, foo precisa retornar ao principal, e é isso que este endereço de retorno faz. Mas o que o hacker vai fazer é substituí-lo com um endereço de retorno especial onde mais uma vez - Little Indian - não é simples, mas cada byte é para trás. Este endereço de retorno na medida em que o computador está em causa voltar a este endereço é equivalente a retornar para foo ou principal ou qualquer que seja a função chamou. Então ele vai voltar para este endereço que só acontece de ser este endereço que seja, por vezes, o que eles fazem aqui é usar o endereço de retorno de uma função específica que eles sabem já está lá. Eu não consigo lembrar o que a função é chamada. Vou procurá-lo mais tarde. Aqui o que eles estão fazendo é passar o endereço de retorno a si mesmo, e isso é um pouco estranho, onde pilha existem exemplos de memória onde - memória pode ser dividida em somente leitura, leitura e escrita, e memória executável onde vimos memória só de leitura antes de onde o - se eu disser char * s = Olá eu não posso modificar Olá. Que a memória de somente leitura. Há também a ideia de memória executável onde a memória executável seria o segmento de texto do seu código. Olhando para o seu endereço de layout do espaço habitual - Acredito que vai ser uma boa imagem - isso funciona - onde nós temos a nossa pilha aqui. Temos memória de dados. Ignorar isso basicamente. Este é o nosso heap. E então nós temos aqui o nosso código principal do programa. Isto é semelhante ao lugar onde colocamos nossas cordas como char * = Olá e que é somente leitura. Mas você também pode marcar este código principal do programa como executável. E se você estiver fazendo isso, ou seu sistema operacional faz isso corretamente então este deve ser o único lugar na memória que o código pode realmente executar o que significa que este tipo de estouro de buffer ataque temos aqui seria ineficaz porque este está tentando executar memória até aqui em nossa pilha. Repare que as imagens são em primeiro lugar. Nós temos nossa pilha crescendo. Aqui a pilha está crescendo para baixo. Para fins CS50 a pilha cresce. É possível contornar esse tipo específico de estouro de buffer por ter essas áreas de memória executáveis ​​em regiões não-executáveis. Mas isso só acontece que raramente é memória executável marcado como executável. Ele só tende a ser somente leitura e re-escrever são as únicas coisas que são utilizados, de modo que este ainda é muito eficaz. E aqui podemos colocar o que quisermos. Não foi realmente feito como um Pset em 61 deste ano, mas se você olhar para oferta do ano passado do mesmo ou qualquer ano anterior um Pset é que você está especificamente suposto inserir aqui o código que é suposto imprimir algum valor específico ou retornar um valor que é diferente de o valor que deve ser impresso. Ou ainda mais inteligente, ele quer que você ligue ou escreva - então isso vai voltar até aqui e depois você vai executar algum código aqui, eo mais inteligente de estouros, então, voltar ao que este endereço de retorno costumava ser. Assim, mesmo que precisávamos substituir essa para vir até aqui, nós ainda lembrar que endereço de retorno em algum lugar para que possamos voltar ao principal ou qualquer outra coisa, e é como se nós nunca sequer percebeu que as coisas deram errado. Mas as coisas fizeram de modo que é o caso em que talvez dentro de nós aqui gelbroke nosso iPhone. As coisas vão tão normal - como corremos algum programa e as coisas acabam retornando para seja o que deveria retornar a, mas, entretanto, você conseguiu destruir todo o sistema operacional. Você não precisa saber código sobre estouros de buffer ou a tirar proveito dela. Você precisa conhecer as idéias básicas de este é o buffer que está sendo transbordou, e esta é a razão que ele pode ser transbordou porque não estamos verificando se estamos, na verdade, dentro dos limites do mesmo. [Estudante] A solução para prevenir-se apenas a verificação dos limites? [Rob] Sim. Neste caso, a solução seria Você poderia dizer se strlen de bar é maior que 12-1 - porque você precisa do / 0 no final - ou você poderia fazer manualmente um loop que só copia os primeiros 11 caracteres, ou qualquer coisa onde você está, na verdade, a verificação para certificar-se de que você não transbordar que buffer. Outras perguntas? Sim? [Estudante] Você pode falar sobre tentativas e talvez algo sobre programação (inaudível). [Rob] Claro. O programa atual - nunca faria você fazer uma implementação de um trie no exame porque seria injusto com aqueles que fizeram tabelas de hash. E da mesma forma que nunca faria você implementar uma tabela hash no exame porque seria injusto com aqueles que fizeram tentativas. Você deve, no entanto, conhecer a estrutura de um trie ou a estrutura de uma tabela hash ou o que seja. Isso é realmente verdade para qualquer tipo de estrutura de dados que já vimos. Listas encadeadas, skews empilhados, árvores binárias - você deve ser capaz de definir as estruturas de cor. A trie - o que significa a única coisa que você precisa fazer é talvez nós vamos dar-lhe alguma palavra ou algo assim e vamos dizer construir a trie que - nós vamos dar-lhe talvez um conjunto de palavras e nós somos como construir uma trie que representa este dicionário. Vamos fazer o nosso gato dicionário e cão. A idéia do trie é que começar com essa matriz - 26 slots - e em cada slot do índice real do slot corresponde à letra que estamos preocupados com. Então, aqui, se nós estamos tentando inserir gato em nossa trie o primeiro caractere é 'c', que vai ser ", se a é 0, então b é 1, c é 2. ' Nós estamos indo para ir para o segundo índice, e vamos criar um trie fora disso. Nós vamos ter 26 slots. E então nós estamos indo para o segundo personagem índice de gato. Isso é 'a', que vai ser o ponto 0. E isso vai ter 26 pontos. Então vamos para 't' e também teríamos que descer que é na verdade uma espécie de importante porque - vamos ter que vir até aqui. Aqui está o nosso trie para 't'. Digamos que este é o índice "t" é 19. A coisa importante a lembrar sobre tentativas é que você não pode apenas acompanhar esses ponteiros. Você também tem que acompanhar se este é realmente o fim de uma palavra. Então, aqui dentro precisamos de algum tipo de bandeira que diz Tudo bem, este é realmente o fim de uma palavra. A razão de ser, se mais tarde tentar inserir catastrófica em nosso dicionário que tem as mesmas a partir de 3 caracteres mas vai além, precisamos reconhecer que este é o fim de uma palavra. Ou, alternativamente, se tentarmos olhar para cima 'ca' que talvez não é uma palavra mas nós chegar até aqui, então nós - ou seria c e depois olhamos para a - precisamos reconhecer que, apesar de há um ponteiro saindo deste nó não representa o fim da palavra. Então, o que isso significa - o que você ia dizer? O que significa a nossa estrutura se parece? [Estudante] É uma matriz de ponteiros que é 26 de comprimento e, em seguida, um bool eram ou não eram. [Rob] Yeah. Então, nós vamos ter uma estrutura trie * ponteiros - aqui vamos dizer [26] em e, em seguida, o ponto e vírgula aqui. Mas no Pset, também precisamos dar conta de apóstrofos, o que significava que você precisava para codificar essa apóstrofe com o índice de 27 ou algo assim. Mas aqui só se preocupam com 26. E então temos talvez um char ou bool - vamos chamá-lo é a palavra. Isso é 2 das 3 coisas que eu acho que você poderia precisar de saber sobre tentativas - construí-los, a estrutura deles, ea última coisa que é o tempo de execução delas. O que é o tempo de execução de um trie - ou a pesquisa em uma trie? É aqui que diz que é o (k), onde k é o comprimento da palavra que estejamos olhando para cima; mas, ao mesmo tempo que dizemos - pelo menos, por causa Pset 5 de speller - dizemos a maior palavra no dicionário é de 45 caracteres, de modo que este é basicamente O de 45, que é o tempo constante. Então, se há um limite superior sobre o seu maior palavra em seguida - ou até mesmo como o dicionário de Inglês - há um limite superior sobre o seu maior palavra. Ou qualquer dicionário - há um maior ligado na sua palavra superior. Não importa o que você está fazendo é de tempo constante, mas O de k é bom porque há realmente uma diferença entre correr dizer Palavra de 45 caracteres contra um alfabeto que só tem palavras até 3 caracteres. Outra coisa sobre isso é que o - oh, porque apenas dizer que 45 passa a ser a nossa palavra mais longa é meio bobo, porque, ao mesmo tempo, digamos que um algoritmo é O de N. Bem tudo bem, porque a memória só suporta até 2 ^ 32 bytes, então N é no máximo 4 bilhões e que é tempo constante, razão pela qual, em algum momento é bobagem dizer esse tipo de coisa onde há um limite superior que podemos apenas reduzir a constante de tempo, porque tudo é de tempo constante quando você pensar nisso dessa forma. Mas nós provavelmente aceitar ambos. Em qualquer caso, explicar ou que O (1) significa que você tem um comprimento superior limitada de palavra; O (k) significa que o comprimento da palavra - assim, k significa o comprimento da palavra. Sim >>. [Estudante] Será que o bool - porque quando você fez a sua trie parecia que era - você iria gato e, em seguida, você vai para o próximo ponteiro e então você dizer se isso é igual a verdade - se você colocar essa verdade em como com a t? [Rob] Vamos pensar este é o caso em que um monte de exemplos que você pode apenas tentar e chegar a exemplos simples e / ou extremas e que deveria ser, então vamos pensar na palavra 'a'. Em nossa trie originais - se queremos colocar a 1 aqui, ou que gostaria de colocar um 1 aqui. Eu diria que, no final, provavelmente seria ou / ou. Eu não posso pensar em uma razão - ou realmente você wouldn't - a razão que eu não iria colocá-lo lá em baixo é porque você não precisa nem ir tão longe. Nós nunca precisa alocar este trie. Acabamos de colocar a 1 lá em cima. Isso ainda está apontando para NULL. Se nós estamos indo só para ter caracteres simples não há nenhuma razão para estender-se a outro trie apenas para marcar essa letra como usado. Da mesma forma, se tivéssemos colocado o 'a' lá em baixo então necessariamente todos estes seria apenas 0 em todos os momentos. [Estudante] Mas não precisamos de um trie partida que irá apontar para este 'a'? [Rob] Temos algumas struct trie * mundial ou algo t que aponta aqui, mas isso é apenas um ponteiro. Não é um trie full-blown que está apontando para ele. [Estudante] Okay. Como poderíamos atribuir a letra 'I' - com a palavra que eu? [Rob] Sua pergunta pode estar respondendo isso. Espere um pouco. Essa é uma questão em que a trie em si - Eu não sei o caminho a Pset teria escrito. A estrutura anterior foi ruim. Mas também poderia fazer nó struct é um bool - e um ponteiro - há realmente várias maneiras que você poderia escrevê-lo. Alternativamente, uma trie não precisa ser um struct. Pode até ser trie - nó typedef * - nó [26] é uma trie, e isso não é mais estrutura. Agora não vai ser - estou tentando pensar da forma que Pset teria esperado que você. [Estudante] Puxei que sessão de revisão e eu acho que eles só vão - como se você tem um um, então você ir para o próximo - [Rob] É assim que eles fazem isso? [Estudante] e, em seguida, se há uma verdade que ele não funciona - [Rob] Yeah. Isso não funciona. Desperdiça o espaço - você necessariamente tem um outro nível de trie que você não precisa, em primeiro lugar. Aqui está ficando feio com cada - basicamente o que eu estou tentando fazer aqui é associado - em vez de ser 26 ponteiros para suas tentativas, é 26 ponteiro bool, ponteiro bool, ponteiro bool, e assim por diante. [Estudante] Você não pode fazer que as duas matrizes? Uma matriz de bools e uma matriz de ponteiros? [Rob] Você poderia, mas então você precisa - 2 matrizes de booleanos e ponteiros. Você precisaria, então, construir sua matriz de booleanos - sua matriz de booleanos precisa ser tão grande quanto o trie porque você não pode apenas ter 26 booleanos. Ele tem a crescer com cada possível - como o seu trie tem mais de 26 verdadeiras ou falsas palavras possíveis. Nesse ponto, eles podem muito bem ser apenas uma única estrutura que seu trie cresce para baixo com. Isso não parece certo, porque - o que eu quero aqui? Então, trie * t - você pode fazer typedef (nó *) [26] trie; que pode ser a sintaxe que eu estou procurando. E isso deve ser apenas uma trie regular. Não tenho a certeza. Mas essa é a maneira que fizemos na revisão, de modo que funciona perfeitamente bem, também. Nesse caso, se é apenas bool é a palavra e, em seguida, uma série de 26 então você tem que ir para o próximo nível. Vou pensar sobre a maneira que eu faria isso. Outras perguntas? [Estudante] Posso fazer perguntas sobre qualquer outra coisa? [Rob] Sim. [Estudante] Você pode passar por cima de qual é a diferença e quando você usaria jQuery contra Ajax? [Rob] Eles são em si mesmas completamente diferente. JQuery não permitir Ajax. Ele nos dá algum uso mais fácil do Ajax. Mas Ajax vem enviado com JavaScript. JavaScript tem capacidades Ajax. Todos Ajax significa é Liken eu já estou em uma página e quando eu quiser - quando eu clicar em algo que eu não precisa recarregar a página para baixar a nova informação. Eu só solicitar que novas informações. Você pode olhar para ele no Facebook ou algo assim. Inspecione rede. Encolher isso. Por aqui vemos que estamos recebendo todos esses pedidos. Agora, quando eu clicar em - bem, ele está fazendo Ajax antes mesmo de eu clicar em nada. Mas se eu clicar sobre isso, então ele vai fazer um monte de pedidos aqui que apenas fazer esses pedidos - oh, agora é aqui. Vamos atualizar. Faça isso de novo. Vemos que temos todos esses pedidos, mas isso poderia ainda estar em processo de carregamento da página. Observe Facebook está fazendo essas solicitações constantes, mesmo depois de a página foi carregada. E se eu clicar aqui, ele vai fazer mais alguns pedidos de alguns dados que é em resposta à coisa eu só clicado. Isso é apenas o que é Ajax. Ele permite que você puxar para dados que não foram baixados com a página original. JQuery é separado. JQuery é apenas uma biblioteca JavaScript que faz um monte de coisas mais fáceis. Com jQuery é muito da vantagem isso é apenas - cifrão - sinal de dólar é uma variável válida em JavaScript. Então, jQuery - tudo o que está fazendo é dizer como var $ = um monte de coisas - como uma grande função com todas essas coisas nele - e, em seguida, você usa esse sinal de dólar em aspectos como $ ("# Footer"). Estilo ("text-align", "center"). JQuery nos dá este tipo de sintaxe em que uma grande vantagem - tem outras características, mas o que nós queremos que você se concentrar em mais é apenas ser capaz de selecionar elementos como este. Em regular, bom e velho JavaScript que você pode fazer coisas como documento-dot-get elemento por ID footer-dot - Eu não sei o que é nesse ponto - algo sobre CSS ou estilo ou algo assim - mas então, em alternativa, vamos dizer que queria selecionar por classe. Agora estamos denominando tudo com um rodapé de classe com este modelo. Mesmo se quiséssemos denominar todos os parágrafos. Assim, este seletor - ser capaz de selecionar as coisas no dom como esse é extremamente conveniente uma vez que no bom e velho JavaScript você teria que fazer documento-dot-obter elementos pelo nome da classe ou seja o que for, ou se eu queria uma marca que eu preciso dizer obter elementos por nome da marca. Então, eu preciso saber as formas específicas que eu acessar todas essas coisas. As funções vão ser diferentes, dependendo se eu estou usando uma classe ou uma ID ou um tag ou o que, enquanto jQuery só faz isso por mim. [Estudante] é jQuery vai ser usado quando você está fazendo o estilo inicial da página? Ou para mudar o estilo depois que já é - [Rob] Para alterá-lo. [Estudante] Depois ele já está carregado. [Rob] Yeah. Qualquer estilo inicial - bem, até mesmo o - geralmente você usaria esse tipo de mudança. Você não vai mudar - isso funcionaria perfeitamente bem. Mas normalmente você não iria alterar o estilo como esta. Em vez disso, você daria uma nova classe ou algo enquanto o CSS já foi definido para essa classe de uma certa maneira. Ao dar esses itens eu estou selecionando uma nova classe Estou aplicando os estilos que já foram baixados. [Estudante] Então você selecionar um par de caixas de seleção e as coisas que você selecionou mudar para um novo estilo e começar a olhar diferente. [Rob] Yeah. As outras coisas para se lembrar sobre - bem, há várias funções que você deve se lembrar sobre jQuery. Digamos que estamos selecionando algo com ID P. [Estudante] Você sempre tem que usar a libra? [Rob] Isto significa ID. É equivalente a CSS, assim seletores CSS - é inspirado por isso. Onde no CSS se eu queria estilizar um rodapé - ou algo com ID footer - seria como text-align: center; você não vai precisar de escrever CSS no exame, mas você precisa saber os seletores. Você precisa saber o que - o que você precisa saber como lê-lo. Mas nunca o faria - você não precisa memorizar todas as diferentes coisas de estilo possíveis. Ou qualquer um deles. JQuery coisas que você deve se lembrar - você deve se lembrar dot-HTML, e um padrão comum em jQuery - vamos re-escrever isso. Um padrão comum é que temos $ ("# f"). Html Se eu colocar parênteses simplesmente que significa obter o HTML; ao passo que se eu digo HTML e colocar o que eu quiser aqui - alguma ligação com alguma coisa - colocar algo dentro dos parênteses agora define o HTML. Isso é muito comum entre um grupo de funções. Não é a mesma coisa com o texto. A diferença entre HTML e texto é que o texto vai inserir este como literal menos do que um, maior que em vez de como uma marca de âncora. E o texto vai ser a mesma coisa se eu fizer isso. Vai recuperar o texto do documento - e não o HTML do documento mas apenas o texto dentro deste elemento. Outra é se 'f' passa a ser um ID para uma entrada, depois de hash-f-dot-val - se eu quiser definir a entrada para algo como - digamos que eu bati uma caixa de seleção e quero definir um valor padrão - dot-val - Eu nem sei - 3 - de modo que irá inserir automaticamente na caixa de texto 3, mas se eu disser 3-ponto-val, que irá recuperar o que está atualmente na caixa de texto para mim. Isso é útil para validação de formulário onde se eu só quero ter certeza de que eles realmente preencheu todas as coisas. Uma maneira de fazer isso é se depois que eu clique em enviar é inevitavelmente enviado para alguma página no servidor - como para nós seria PHP - e que iria tentar processar os dados e diria eles não preencher alguma coisa, de modo que agora redireciona para outra página que diz você não preencher tudo. Em vez de ter de fazer isso, em JavaScript / jQuery você pode apenas ver se val está vazio. Ou é val - citações vazias. Isso vai apenas - agora podemos alertá-los de que você não preencher este campo. Inevitavelmente você precisa fazer o PHP verificação do lado do servidor, porque você pode simplesmente desativar o JavaScript em todos os navegadores. Mas JavaScript torna conveniente para aqueles que tê-lo ativado, e praticamente cento e noventa e nove pontos, algo de navegadores tê-lo na atualidade. Muito poucas pessoas se voltam JavaScript desligado. É uma conveniência do usuário. Você precisa fazer a validação PHP. Você deve fazer a validação JavaScript. [Estudante] O que # f referem-se aqui? [Rob] O que # f se refere? Há algum elemento no meu documento com ID 'f'. Veremos - provavelmente o Facebook tem muitos exemplos em que se eu chegar a elementos olhando aqui sob a tag elementos vejo esta div particular que está sendo destacado até aqui - ou é a página inteira - sim, é lá em cima. Isto tem ID pagelet_bluebar. Na consola Eu presumo que eles estão usando jQuery. Então, eu poderia selecionar pagelet_bluebar para que seleciona isso, e eu fiz algo errado. Vamos tentar - ou talvez eles não estão usando jQuery e que o personagem de mapeado para alguma outra coisa. Um exemplo melhor em algo que eu sei está usando jQuery - ainda olhando para os nossos elementos aqui - temos aqui classe é igual a barra de navegação. Isso é algo com classe barra de navegação, tão dentro da nossa consola podemos olhar para cima a coisa com classe barra de navegação. Aqui podemos rolar sobre isso e ver que é o que isto é. Se eu quisesse fazer. Texto Este é o texto de que, assim que eu vejo as configurações para o relatório acima log out que estão todos aqui em baixo, mas que ainda é texto dentro dessa tag HTML. Eu poderia definir o HTML apenas alguns link, então eu vou me livrar do meu bar. Agora que se livrou do cabeçalho inteiramente só por isso está ligado ao YouTube. E há alguma forma de exemplo? Aqui está um formulário. Eu posso clicar com o botão direito e inspecionar elemento a vir a ele aqui. Vejo que o seu ID é a busca de texto, então para cá, se eu faço pesquisa de texto ID. Eu vou trazer sobre ela e vejo que é a coisa certa que eu estava procurando. Se eu quiser fazer. Val que me daria o que eu tinha digitado lá. Se eu quisesse fazer Olá ele vai mudar-se aqui para Olá - jQuery. É claro que eu poderia fazer ridículo como document.get elemento por ID - pesquisa de texto - Eu nem sequer sei o que é neste momento - valor de ponto - não, eu esqueci aquele cara. Então, isso é Olá. Eu não sei como eu defini-lo é igual a alguma coisa. Sim, por isso que mudou isso. Mas você não precisa usar esses e muitos sites neste ponto uso jQuery. Mesmo como em um projeto final - se você está fazendo um projeto web - a primeira coisa Eu recomendo é apenas incluindo jQuery para que possa obter a conveniência de todas estas funções. [Estudante] Eu acho que eu vi um caminho diferente para chegar a um elemento usando dom. Você tem que usar ponto e, em seguida, continue indo para baixo? [Rob] Você pode fazer isso. Eu não sei se ele iria trabalhar muito bem. É difícil navegar dessa forma. Um exemplo é - Eu nem sei se temos quaisquer formas - mas document.forms vai retornar a lista das formas que está nesta página, então eu posso fazer document.forms 0 vai ser a primeira forma. Dot - Eu não sei o que nós chamamos isso - por isso nem sequer tem um nome, então talvez entradas funcionará. Não. Eu nem sei como começar neste - obter a entrada nome do elemento-I-tag. Sim, isso me deu a entrada, e agora eu quero o 0 a entrada e eu quero selecionar o seu valor, de modo que vai ser texto. Eu tive que acabar fazendo elementos Receba por nome da marca de qualquer maneira. Pode haver alguma forma para selecioná-lo diretamente através da forma 0, mas a coisa boa sobre isso ainda é como se eu só tinha que se as tags chamada de entrada que era uma criança desta forma, caso contrário, se eu fazer isso em linha reta na frente isso iria selecionar todos os elementos na página inteira, em todo o documento em vez de apenas aquela forma e provavelmente não vai mesmo ser o que eu quero. Eu nem sei qual é. Eu não sei. Eu acho que o primeiro elemento de entrada em nossa página é esta opção pouco. [Estudante] Isso é muito relacionado e, possivelmente, meio bobo, mas na chave de resposta que diz que o PHP - Eu não sei se é a resposta-chave ou notas, mas ele diz que o PHP é server-side e JavaScript do lado do cliente. O que é a diferença entre o 2? [Rob] A diferença entre JavaScript do lado do cliente e do lado do servidor PHP. Se você já ouviu falar da barra / js nó utilizado antes de você pensaria que JavaScript não é apenas do lado do cliente, mas para fins CS50 que é - ou pelo menos para fins deste questionário é. PHP é server-side. Sem JavaScript. Quando você escreve sua página você estará escrevendo PHP no servidor. Você nunca vai estar escrevendo JavaScript no servidor. JavaScript acaba sendo enviado para o navegador onde o código JavaScript é executado. E o código JavaScript precisa para viver no navegador, pois caso contrário, quando eu quero apenas fazer qualquer tipo de JavaScript-y coisa como clicar sobre isso, Eu não estou recarregando a página. Este é apenas JavaScript re-formatação as coisas para mim. Se o JavaScript viveu no servidor, então eu teria que inevitavelmente pedir algo do servidor para saber o que fazer. PHP - não existe tal coisa como PHP no navegador. Quando eu solicitar uma página - por isso vamos dizer que aqui eu pedi esta página particular. Isso significa que este vai pedir - atualizar - que vai para atualizar esta página - de modo que este pedido vai para o nosso servidor. Ela vê que ele precisa devolver este segmento específico com este ID particular, então agora que vai haver alguma PHP que o interpretador PHP vai interpretar essa página e transformá-lo em apenas HTML, CSS, JavaScript, talvez, seja o que for. É PHP que processa este pedido e recupera todo o texto e outras coisas que eu estou realmente procurando a partir do banco de dados. Mas o que deixa o servidor é apenas HTML / JS / CSS. Não há PHP que deixa o servidor, porque se ele realmente fez em seguida, o navegador não teria nenhuma idéia do que fazer com ele, porque ele não sabe o que é PHP. Mas, no mesmo pensamento, porque o JavaScript está do lado do cliente, você nunca pode acessar MySQL a partir dele. Porque PHP é server-side que você acessar MySQL a partir dele. [Estudante] Você pode passar por cima de alguns dos problemas de segurança com os cookies em HTTP? [Rob] Aqueles que não são coisas que vamos precisar de saber. Alguns dos problemas de segurança com os cookies em HTTP. A grande questão aqui é que vemos aqui que o meu cookie é PHP / ID. Isso é como o PHP universal sua sessão. A sessão é algo que dentro de PHP nunca terá de ser validado porque é o servidor que tem controle completo sobre a sessão. Você não pode tocá-lo em tudo. Mas é esse cookie - um presente - e eu acho que você poderia fazer o login como me agora mesmo, se você quiser usar isso - mas é que o cookie que - inevitavelmente você fazer um único pedido para o servidor. O servidor retorna a página. O pedido é feito. Ele já não tem qualquer idéia de quem você é. Então, o próximo pedido que você faz vai incluir esse cookie para que ele saiba esta é a pessoa que fez este pedido antes. Estes são os dados de sessão que está associado a este usuário. É por isso que você não precisa se logar para cada página que você usa. O problema de segurança aqui é que esse cookie é enviado através da web. Estamos usando HTTPS aqui, então, neste caso, isso significa que estamos criptografando este material. Alguém não pode entrar e roubar meu biscoito e agora o servidor acho que eles me são. Mas com HTTP direto que podem. Assim como essas coisas WireShark / Firesheep que você pode apenas ouvir toda a wi-fis no ar e interceptar o que quiser, então sim. [Estudante] Uma espécie de risco de segurança semelhante está armazenando identificação de usuários no post porque que pode ser editado livremente usando consoles e coisas. [Rob] Sim. Há uma abundância de questões em que, como qualquer coisa que vem do usuário você precisa para validar. Há uma abundância de casos em que seria útil para o que estou prestes a fazer um post. Blá, blá, blá, blá, blá. Então eu bati resposta. Seria muito útil se o pedido do cargo incluiu meu ID porque  Quero associar este post comigo. Mas eu não posso fazer isso porque eu sou livre para fazer uma solicitação post - assim como manualmente venha com meu próprio pedido de pós - que usa seu ID de usuário e agora vou postar como você. É por isso que do lado do servidor que não pode contar com os pedidos pós contendo o ID de usuário correto. É por isso que ele tem que pertencer a minha sessão. Então eu olho o seu ID de usuário no meu array de sessão e eu inserir isso em meu banco de dados como o usuário que realmente fez este post. [Estudante] E isso com base no seu biscoito? [Rob] Yeah. Ele usa o cookie para igualar-se-lhe como o usuário que fez esse pedido. Ele pega o ID do usuário a partir dessa sessão e que, em seguida, insere no banco de dados usando esse ID de usuário. Este botão like - o que está realmente fazendo é - Eu não estou indo encontrá-lo aqui. Vai ser uma função Ajax Qual é a função Ajax? Deixe-me saber o que o meu JavaScript. Foi um projeto CS50 há um tempo atrás. Não me lembro o que é. Função Ajax - todas as funções Ajax está a fazer é fazer uma requisição Ajax para uma página com este ID - com a ID 22453. Não é nem uma solicitação post. É um pedido get o que torna ainda mais fácil. Se eu soubesse o que a URL é - é algo parecido como isto / ID = 22453 - ou ID = 22453? - então visitar este URL vai gostar disso. O que não seria como um grande problema, mas é incrivelmente fácil de escrever um loop que está indo só para visitar este URL e outra vez, e é por isso que você vê Isawyouharvard postar com milhares de coisas. E eles tendem a ser baseados em mensagens Isawyouharvard CS50. Como faço para encontrar o mais popular? Eles tendem a ficar excluído muito rapidamente também. Este não é o mais popular. Lá vamos nós. Cheaters na página mais gostei - isso é muito relevante para este agora. Oh wow. Eles já excluída qualquer dos entes a partir deste ano que foram traiu. Aqueles foram todos apagados. Nunca haverá um post que recebe este elevado. Este foi obviamente traiu a ir até a página mais gostava. Mais perguntas? [Estudante] O que devemos saber sobre XHTML? [Rob] Praticamente nada. Apenas o que é. A diferença entre ele e sendo que XML HTML é muito similar na aparência ao HTML exceto em HTML só temos que ter um conjunto pré-definido de tags. Mas com XML - XML ​​é como um formato geral onde você pode fazer um documento XML para quaisquer fins que quiser. Assim, por exemplo, se eu quisesse eu poderia construir um XML para os cursos - e eu realmente acho que CS50 tem uma API para isso. Meu documento XML poderia ser algo como - cursos e, claro, eu preciso de alguns cursos finais. Eu poderia ter um curso e que poderia ter o nome igual CS50. E então o meu curso final e eu poderia colocar aqui dentro os alunos, e, em seguida, dentro de estudantes Eu tenho uma lista de um aluno cujo nome é o que quer. Termino esse aluno e assim por diante. Eu só acontecerá a ter construído algum documento XML arbitrário, mas é XML válido. XML - tudo isso é esse tipo de estrutura ea coisa agradável - a razão que nós até chamá-lo XML é que esse tipo de coisa é muito fácil de analisar. É muito fácil tirar esse documento e fazer uma matriz de fora. E assim, XHTML é uma tentativa de obter HTML para ser XML válido. Já este parece muito semelhante ao HTML. Algumas das diferenças são HTML você é capaz de fazer coisas como entrada talvez tipo é igual a texto que é o padrão, então eu não preciso dizer isso. Desativado. Há duas coisas aqui que fazem desta XHTML inválido. A primeira coisa é que todas as tags XML precisa de um marca de fechamento. Assim, no caso de entrada que eu preciso fazer o - qual a direção da barra é? Esta direção? Isso parece errado. Outra direção. Auto-fechamento tag. A segunda coisa é que com o XML que você precisa estes tipos de como pares de valores-chave. Ele precisa de um valor associado a ele. Assim, mesmo que pessoas com deficiência em si expressa o que eu quero - esta entrada deve ser desativado - isso é XHTML inválido. O que eu realmente preciso escrever é desativado iguala desativado. Agora é XHTML válido. E estes são apenas essas pequenas diferenças que transformam HTML a um tipo de coisa baseada em XML. [Estudante] XML é sobre como puxar através de seu próprio X completamente como por que é (inaudível) [Rob] A coisa de como um CSV - um arquivo CSV que você acabou de valores separados por - basta pensar em uma planilha. A CSV é basicamente uma folha de cálculo. Você tem talvez colunas e você tem um monte de linhas que dados associados com as colunas, mas é isso. XML é muito mais versátil que você pode - você tem uma hierarquia arbitrária de dados. Eu poderia ter vários cursos que têm vários alunos dentro dele onde seria difícil pensar em uma planilha que - só que única planilha - CSV especialmente é como apenas uma única planilha - de modo que só folha de cálculo tendo todos CS50, 51, e 61 e dentro de todos aqueles do estudantes relacionadas a esses tempos, tempos talvez reuniões e todo esse tipo de coisa. A outra coisa é que os nomes de tags dar um nome bom para todos os elementos por isso a leitura de um arquivo CSV pode ser difícil tentar e analisar o que está realmente vendo. XML é muito mais legível é por isso que gosto - chegar a alguma pessoa que não realmente sabe o que é um arquivo CSV ou gosto não é um programador ou algo assim - você pode dar-lhes como um arquivo de modelo XML e podem seguir as linhas e - oh, eu devo inserir meu nome aqui. É um formato muito mais utilizável. CSV tem muitos usos, mas XML tem usos diferentes. Mais perguntas? Outras perguntas? [Estudante] Desde o quiz anterior - escala vertical em relação a escala horizontal. [Rob] Você não precisa saber disso. Eu não acho que nós até discutimos isso. Eu estou supondo que era apenas um comentário one-off. Oh. Escalabilidade horizontal versus vertical não é algo que você precisa saber. Acho que a diferença é como - oh bem, a chave de resposta vai dizer a diferença. A escala vertical é apenas gostar oh, meu computador está fazendo mal. Vou pegar um melhor. Considerando a escala horizontal é oh, meu computador está fazendo mal - deixe-me ver 20 deles a todo o trabalho na mesma tarefa. [Estudante] Podemos passar por cima da maneira lista encadeada de fazer filas. [Rob] Claro. Isso é mais fácil do que a forma de matriz. A maneira lista encadeada de fazer filas. Em primeiro lugar, o que faz a nossa estrutura para uma lista ligada parece? [Estudante] Estamos fazendo isso para - [Rob] Vamos fazer o seu - sim. Int val; então nó struct * próximo; então é isso que nós vamos usar para o exemplo aqui. Vamos realmente digitar essas coisas. Vamos fazer linked_list. Nossa estrutura - Okay. Agora, olhando para a nossa fila, temos a - vamos fazer uma fila global. Vai ser nó * fila, e nós temos uma função dequeue. Eu acho que essas coisas também poderiam virar verdadeiras ou falsas - vamos fazer isso. Bool dequeue - e estamos de retirar da fila - oh. Hmm. Int dequeue - o que é que vamos fazer com isso antes? Int dequeue e temos bool enfileiramento e precisamos enfileirar alguns meios verdade. Vamos fazer de enfileiramento primeiro. Nós temos nossa fila. Queremos inserir algo na fila. Qual é a melhor maneira de fazer isso? Aqui nossa fila parece atualmente como nós temos alguns ponteiro global para começar. Não é a nossa fila. Assumindo que desenfileirá tomando o primeiro elemento, onde vamos querer inserir o nosso nó para que as filas funcionam como deveriam? [Estudante] Ao fim. [Rob] Yeah. As filas são suposto ser first in, first out. O que significa que o novo elemento deve ser inserido aqui. Okay. Voltando ao código, isso significa que vamos querer varrer a nossa fila. Vamos fazer nó * atual = fila, enquanto atual não é igual a NULL. Eu faria - tudo bem, vamos fazê-lo separadamente. Primeiro, atual = fila. O que vamos fazer se a corrente começa como NULL? Nós vamos fazer isso de 2 maneiras. Primeiro desta forma. O que vamos fazer se a corrente é NULL? É este o equivalente a fila se é NULL? [Estudante] Vai retornar falso. [Rob] Devemos retornar falso? O que há de errado com a inserção de algo em uma lista vazia? [Estudante] Nada há de errado com isso. Desculpe. [Rob] Yeah. Então, aqui, a única diferença é a minha fila global está sendo enviado para o meu novo nó. E então eu tenho que fazer meus cheques de se fila é NULL. Return false. E então fila val é igual a i; fila ao lado é igual a NULL; retornar true. Okay. Vou saltar a arma aqui. Lembre-se o que fizemos da última vez onde disse que era muito mais fácil trabalhar com o nó ** com esse tipo de coisa. Então agora atual vai ser e fila, e descendo para cá - enquanto a corrente - enquanto * atual não é igual a NULL - Então deixe-me fazer atual - nós falar sobre isso em um segundo. Próximo atual. Okay. Olhando para ele, desta forma, esta é a iteração sobre todos os meus ponteiros até chegar a um ponteiro nulo. O ponteiro nulo vai ser o ponteiro Quero substituir com o meu novo nó. Olhando para a versão iPad - se o meu ponteiro original ea lista ligada está vazia então atual vai apontar aqui. Isso vai apontar para null, por isso este é o ponteiro eu acabar movendo para apontar para algum outro novo nó. Considerando que, se o exemplo é este caso aqui então vigente vai percorrer a partir daqui - eu errei um pouco. Onde atual é suposto ser o endereço do próximo curso. É isso o que eu quero? Atual so * atual me dá um nó. Em seguida atravessa para a próxima. Atualmente estou apontando aqui. Vamos fazer vermelho - assim que eu atualmente estou apontando aqui. Então * atual está indo para referenciar esse nó. E * atuais próximas referências deste nó, mas não é isso que eu quero. Eu quero que este ponteiro para esse nó. Então, esse ponteiro para esse nó é comercial (* atual) seguinte. Neste momento eu alcancei oficialmente o nó que deseja substituir. Vamos substituir todos estes filas atuais - e agora estamos a fazer. Pode haver erros de digitação, mas a idéia é que com a inserção neste tipo de forma é mais fácil trabalhar com os ponteiros que queremos mudar em vez de precisar de acompanhar - tudo bem, é a minha NULL começo? Ah é? Então eu preciso para criar o nó de início para ser algo específico então eu vou querer fazer uma iteração até a próxima coisa que eu apontar é NULL, e então eu vou substituir isso - o que o próximo passo é - ao meu nó malloc. Em vez de precisar de separar os casos, aqui eu só lidar com o caso de o que é o ponteiro que é NULL que eu já não quero ser NULL, e que torna a vida mais fácil, exceto estes devem ser todos atual * agora porque - [Estudante] Eles ainda estão do tamanho de um nó? [Rob] Sim. Eu ainda estou mallocing um nó. [Estudante] Será que vai ser do tamanho de um nó *? [Rob] Voltando aqui, acho que o caso se esta é a nossa lista encadeada. Esse cara pontos fora para NULL. Após isso porque laço, corrente aponta para aqui porque este é o ponteiro que é NULL. Agora eu quero mudar esse ponteiro para apontar para um novo nó. Primeiro eu malloc que novo nó - tamanho para malloc de nó. E que retorna um nó * e agora mudar este ponteiro está construindo para * iguais atuais este novo nó que alocado. Então, se a corrente é um nó **, então * atual vai ser um nó *, e se eu estou mallocing algo do tamanho de nó então este está retornando um ponteiro para um nó por isso este é um nó * - para que ambos os lados têm corretamente do mesmo tipo. E por isso, se o que eu acabei atribuído era NULL, return false; mais terminar de configurar-los para o que eu quero que eles sejam - exceto estes precisam parênteses porque não é assim que a ordem das coisas funcionam. Sem os parênteses que estava sendo interpretado como atual de seta-val desreferenciava isso. Em vez disso, eu quero excluir a referência atual o que me leva a um nó. Então eu quero obter o valor associado a esse nó. [Estudante] Eu pensei setas lhe permitiu ignorar isso e ir direto para o valor. [Rob] Eles fazem. Isto é, se eu tenho - digamos fila é um exemplo. Eu estou autorizado a fazer fila de seta-val é igual a i porque fila é um nó *. Se houvesse algum bom sintaxe de como corrente mais arrow-val ou algo que fez 2 dereferences, então isso iria funcionar bem. [Estudante] Assim, a seta é apenas para 1 desreferenciava. [Rob] Yeah. Como alternativa eu ​​poderia escrever isso como (** current.val). Assim como eu também poderia escrever fila como (* fila). Val. Então, vamos inserir. Bem, isso é na fila, eu acho. Desenfileiramento vai ser significativamente menor. Vamos colocar vazio aqui para limpeza. Então, dequeue. O elemento que eu estou de retirar da fila? [Estudante] O primeiro? [Rob] Yeah. Se o meu primeiro é NULL - retorno - Eu não sei o que nós queremos para voltar - INT_MAX; e então você deve fazer uma verificação para ver se INT_MAX foi devolvido. Esse é o tipo de coisa que se inc não mais queremos - podemos simplesmente voltar fila val? É isso que nós queremos fazer? Dequeue também remove implicitamente o item da fila, então vamos começar por dizer - vamos obter um tmp para apontar para o primeiro nó da nossa fila. Agora queremos avançar a nossa fila para apontar para a próxima coisa na fila. Agora temos tmp esquerda. Tmp val é a coisa que queremos voltar. Então, val = tmp-> val; mas, antes de devolvê-lo, devemos libertar tmp e retornar val. A ordem das operações aqui é importante para que nós precisamos pegar um tmp antes de passarmos fila para o próximo elemento. Precisamos obter o valor antes de libertar tmp, e depois podemos voltar a val. [Estudante] Devemos definir a fila na fila ao lado? [Rob] Sim. Isso foi criando um ciclo ruim / que não iria funcionar depois de libertá-la de qualquer maneira. Queue = queue-> seguinte. Queremos avançar na fila para o próximo elemento não avançar o próximo elemento em que o elemento é actualmente. Pilhas seria significativamente - como ainda mais fácil na medida em que dequeue é exatamente o mesmo porque estamos tirando a frente da pilha. Fim da fila seria muito semelhante, onde nós só queremos alocar um nó e inserir na frente da pilha, de modo que não precisa nem de varrer qualquer coisa. Nós apenas inserir diretamente na frente. Está todo mundo bem com isso? Okay. Mais perguntas? [Estudante] Que coisas importantes que eu deveria ter em mente a partir da palestra mais recente? [Rob] A palestra mais recente. Você não precisa saber qualquer código. Você deve saber as idéias gerais. Metade de Nate não tinha nenhum código e para que esses slides são online. Eles são como olhar para eles e eles têm as idéias principais. Minha metade - sabendo a idéia geral do primeiro você não pode confiar em qualquer coisa. O facto de, como talvez o processo do compilador podem ser má, mas isso não importa mesmo que o código fonte parece bem. Porque o compilador pode ser especificamente alterada para mudar o código fonte  no processo de elaboração. Ao mesmo tempo, assim como - Eu acho que esses são como as grandes idéias dele. [Estudante] Você mencionou que não precisa saber qualquer coisa relacionada ao Firesheep - ou que precisamos de saber isso? [Rob] Com metade de Nate de coisas, qualquer coisa que Nate tocou - como Firesheep, WireShark - Eu nem acho que ele fez Firesheep em detalhe. Você também fez alguma coisa com isso - foi Firesheep - na semana passada? Você tocou em que? [Estudante] Sim, eu acho que pode ter - [Rob] Yeah. Nós não estamos indo dar-lhe saída Firesheep e dizer interpretar isso. Ele só vai ser - seria uma pergunta como o que é Firesheep? O que é utilizado? [Estudante] Eu acho que ele só funciona em versão 4 do Firefox ou algo assim. [Rob] Pode ser quebrado por agora. Eu não tenho idéia. Eles não parecem ter desativado manualmente, mas talvez ele não funciona com o mais recente Firefox. [Estudante] Na verdade, eu tentei instalá-lo porque ele disse que seria compatível. [Rob] Então, eu acho que não funciona com o mais recente Firefox. Mas a idéia ainda está de pé do que ele foi concebido para mostrar. Era absurdo como grande parte do mundo não estava vivendo em HTTPS no momento. Mesmo nos últimos 2 anos, ou seja o que for, ainda é - há uma melhoria dramática no número de sites que usam HTTPS. [Estudante] Não precisamos passar por cima de HTTP? [Rob] O protocolo dele? [Estudante] Algumas das coisas que deve saber. [Rob] Tudo bem. Coisas básicas são tudo o que você pode ver na sua aba de rede. Quando eu solicitar uma página - voltar até o topo para as coisas principais. Você pode ver aqui o pedido que eu faço. Chrome passa a formatar tudo bem para nós onde o URL pedido foi isso, o método da requisição GET, eo código de status foi de 200 OK. Se eu acertar fonte vista, vejo que mais diretamente - e esta é - poderíamos mostrar-lhe um desses, mas não é muito difícil de interpretar entre eles. Aqui está o pedido direto que eu fiz, então isso significa que eu fui para apps.cs50.net/discuss/threads/inbox/all/HTTP/1.1. E o protocolo que costumava foi HTTP/1.1 que é virtualmente - é sempre vai ser isso. Aqui usamos GET, então isso pode ser também POST. E, em seguida, descendo - todo o caminho para cabeçalhos de resposta - se encararmos essa fonte, é onde vemos a 200 OK. Conheça os possíveis códigos de status diferentes destes. Eu acho que na revisão nós dizemos um par destes, então 403, 404 - esse tipo de mais comuns. Essa é a grande idéia. A diferença apenas entre HTTP e HTTPS é essa criptografia. [Estudante] que você é feito? [Rob] Eu acho que sim. Bem, sim. [Estudante] Vai falar muito geral sobre como funciona a criptografia? Porque nós falamos, por exemplo, quando a compactação de arquivos Huffman, você sabe como descompactá-los, porque você realmente enviou a hashtable dentro do arquivo assim como o trabalho de criptografia? Como você sabe como criptografar informações, se você não tiver realmente enviou a cliente a chave para o - e você pode realmente pegar a chave de -? Como é que o processo geral funciona? [Rob] O processo geral de criptografia - que é uma questão incrivelmente detalhado eu responderei. Há uma pequena - bem, Tommy e eu fiz o curta. Infelizmente, é como 26 minutos, por isso não é um curta. É um longo. Mas a nossa curta foi em RSA, que é apenas um exemplo destes, e este RSA é parte do protocolo HTTPS global. A idéia - RSA é um exemplo de criptografia de chave pública, o que significa que você tem 2 chaves separadas. Você pode usar uma chave para criptografar as coisas realmente, e você usar outra chave para decifrar as coisas. Esta chave que você usa para criptografar as coisas é o que é público. O site pode enviar-lhe esta chave de criptografia. Eles fazem lhe enviar a chave de criptografia, e quando você quiser enviar algo de volta para eles você usa a chave de criptografia para criptografar todos os seus dados e enviá-lo para eles. Então, eles são os únicos com a chave privada. Se essa chave privada tornou-se conhecido depois ninguém seria capaz de decifrar os dados. Mas essa chave privada - que é matematicamente relacionada à chave pública, mas você não pode descobrir um fora do outro - de modo que a chave privada pode ser usada para descriptografar os dados. Uma vez que eles são os únicos com a chave privada, eles são os únicos que podem ler os dados. Assim, mesmo que a chave pública é pública, Eu uso o mesmo - quando vou ao Google.com ou o que for, eles podem ter múltipla, eu não sei - mas se eu for para o Google.com, ele vai para o Google.com, ela vai para o Google.com-- todos nós podemos usar a mesma chave pública para criptografar a nossa própria informação entretanto que queremos. Mas nenhum de nós vai ser capaz de descobrir - vai ser capaz de decifrar às suas informações, porque a chave pública não é capaz de decifrar. Ela só pode criptografar. E é divertido / matemática detalhada de - como um bando de operadores do módulo e exponenciais e outras coisas, que ele só funciona se a chave privada é a única coisa que pode decifrar coisas da chave pública de criptografia. É. Veja a curto RSA para mais detalhes. [Estudante] é que no site? [Rob] Sim, eu acho que é neste momento. Ou pelo menos um link do YouTube para ele foi postado. Vamos ver. Shorts. Eu acho que teria sido a semana 2-relacionados. É. RSA. E é - nós não estamos indo para jogar este - 24 minutos. É um longa. Mais perguntas? [Estudante] Você poderia falar um pouco sobre os bitmasks? [Rob] Claro. Em resumo, a idéia é apenas isso como - [Aluno] O que é isso, Rob? [Rob] bitmasks. A idéia é - vamos apenas dizer que temos alguns - estamos usando algum inteiro - int x - então, nós começamos-lo em 0. Agora, este número inteiro é de 32 bits, de modo que qualquer um único desses bits pode ser utilizado para representar um FLAC específico. Este é o lugar onde se você olhar para os códigos do sistema operacional, eles usam isso em todo o lugar onde talvez lá em cima em algum lugar eles hash definir - Vamos ver alguns exemplos. Man-2-aberto - a chamada de sistema aberto, podemos ver aqui que um de seus argumentos é int flags - o que espera em que este argumento são algumas dessas bandeiras. Vemos O_APPEND, O_ASYNC, O_CLOEXEC, O_CREAT, e assim por diante. O_DIRECT. Esses tipos de bandeiras são de hash definido em algum lugar. E todos eles são exatamente 1 bit. Então, O_CREAT poderia ser como um definido pelo hash-shift esquerda, 4 (1 << 4). Isso vai ser o - sempre que eu uso O_CREAT que só vai ser - em zeros binários 1, 0, 0, 0, e 30-ish antes. É apenas um único bit de um conjunto, e que pouco representa esta bandeira. E assim nenhuma outra bandeira vai ser esquerda deslocada por 4. Eu sou capaz de representar até 32 bandeiras em um único inteiro, fazendo - x = bit O_CREAT sábio ou O_DIRECT. Você só escolher qualquer 2 desses sinalizadores. Agora x vai ter 2 bits definidos que correspondem aos 2 bits de O_CREAT e O_DIRECT. A maneira que então - por isso, então nós passamos x na função aberta, e as necessidades abertos para ver o que as bandeiras foram realmente definir. Então, é aí que ele vai fazer coisas como if (x & O_CREAT) fazer alguma coisa, ou se (x & O_DIRECT) fazer outra coisa, e, em seguida, pode haver alguma bandeira que não tiver definido - if (x & O_ - Eu não sei o que as outras bandeiras foram - (X & O_RDONLY) - essa condição especial não vai ser executado. Ou que bloco de código não vai ser executado, mas estes dois são porque essas duas bandeiras foram definidos. E note que em C, qualquer valor que não seja 0 é verdade. Então, (x & O_CREAT) vai ser 0 ou O_CREAT porque O_CREAT só tem um único conjunto de bits. Se esse bit é definido próximo, então esta vai voltar O_CREAT - o binário, onde apenas um pouco está definido. Se esse bit seguinte não está definido, então ele vai retornar 0, caso em que sabemos que a bandeira não foi definida. Isso é como você usa bitmasks. Eu acho que em um exame anterior ou talvez na sala de aula ou algo assim - você também pode usar bitmasks para imprimir o binário de uma variável. Então eu posso usar - looping sobre - 1,-shift esquerda, 0 - e, em seguida, imprimir, se x e que - se x e 1, desvio à esquerda, 0 - em seguida, imprimir um 0 ou 1. Ou imprimir um 1 else imprimir um 0. E então eu passar por cima mais uma vez - se x 1 e, de deslocamento para a esquerda, 2 -, então isso significa que o segundo bit da variável é definida, então eu imprimir um 1 mais eu imprimir um 0. E eu acho que nós poderíamos realmente quer fazer isso na ordem inversa porque normalmente você quer do lado esquerdo para ser os maiores fim-bits eo lado direito de ser os bits de ordem mais baixa, de modo que seria provavelmente loop de 4 int i = 31 até que eu bati 0, em seguida, fazer essa condição exata - se x 1 e, de deslocamento para a esquerda, i; imprimir 1 else 0. [Estudante] Obrigado. [Rob] Acho que estamos sem tempo. Mais alguma pergunta no último par de segundos de falta de tempo? Tudo bem. Boa sorte amanhã. Esta foi a última seção onde na próxima semana vai ser opcional. Eu vou dar a volta quizzes e podemos passar por cima deles e talvez passar por cima de outras coisas que você estava interessado, ou final coisas projeto ou futuras CS aulas ou coisas - Eu não sei. Mas esta é a última seção cheia de material. Bye! (Aplausos) [CS50.TV]