[Powered by Google Translate] Problema Sección Set 2: Edición Hacker
Rob Bowden, Universidade de Harvard
Este é CS50. CS50.TV
Entón, eu son Rob. Eu son un Senior en Kirkland. Este é o meu terceiro ano TFing CS50.
É a primeira vez que estamos a cambiar a partir da sección tradicional charla de estilo,
onde só tipo de revisar o que ocorreu na clase e despois vostedes fan preguntas,
agora a ser moito máis baseada en problemas, onde usamos os espazos, e -
Ah, entón a idea é ir ao enlace que lle enviei e entón vai estar no meu espazo.
Será que ninguén ten un portátil? Okay.
Entón nós imos estar usando iso, e nós imos estar facendo problemas vivir sección
e discutir-los e descubrir o que está mal
e eu podería tirar un pouco do seu código, e eu podería discutir as súas ideas.
Entón, ten alguén tiña dificultade?
Podes falar sobre o lado, non sei se imos ter razón para iso.
Agora, como o supersection anterior, se estaba na clase, vostede sabe do que se trata.
En todos os conxuntos P non vai ser esas seccións.
Así, a P-2 set, especificacións, eu creo que viu na P-1 conxunto xa.
Pero podemos ollar para a P-2 set para o que nós imos estar pasando por riba hoxe.
E vai ver unha sección de preguntas.
Entón, iso vai ser en todos os P-sets, haberá unha sección de preguntas.
Ata agora, dixo, "Considero que unha oportunidade de practicar."
Non será convidado a presentar este programa.
A idea é que estas se destinan a especie de axudar a comezar co conxunto de problemas.
Eu creo que na edición Hacker, moitos deles son supostos ser só cousas novas e interesantes para aprender.
Poden non ser directamente aplicable ao conxunto de problemas.
E agora nós non estamos tendo que envialos, pero, en teoría,
para conxuntos de problemas posteriores, pode envialos e, así, pode vir a sección
ou asistir a sección para obter as respostas, ou pode simplemente levalos no seu propio país
se non sentir como gozar da miña presenza.
Así, o - Eu creo que esta é a primeira.
Oh Ademais, nestas seccións de preguntas tamén temos que facer preguntas sobre os shorts.
Entón eu creo que, en teoría, debería prestar atención a estes antes de chegar a sección,
pero todo ben se non fai, nós imos pasar por riba deles de calquera maneira.
Así, podemos comezar con estas: "Como é que un loop while difiren dun loop do-tempo?
Cando é o último especialmente útil? "
Entón, alguén ten algunha -?
[Alumno] O do-while sempre executado polo menos unha vez.
Si Entón esa é a diferencia. Un loop while - eu só fago iso aquí - mentres loop, temos a condición
aquí, mentres que un do-tempo, non ten unha condición ata chegar aquí.
E así, cando o programa está en execución, e queda para o loop while,
inmediatamente para saber se esta condición é verdadeira.
Se esta condición non é verdade, ela só vai saltar o ciclo completo.
Do-while, como o programa é executado, el chega ao "facer".
Nada acontece neste momento, só segue executando.
Entón, cando chega o "tempo", a condición é verdadeira, vai loop de volta e facelo de novo
e de novo e de novo ata que a condición non é verdade e, a continuación, só a través de caídas.
Así, a diferenza é que pode saltar desde o inicio.
Isto necesariamente executa unha vez e entón pode executar máis veces a condición aínda é verdade.
Así, o loop while ha facelo só unha vez, ou - o loop while - non pode ter facelo en todo,
dende logo que chegar a el, a condición é falsa, imos saltar sobre el.
Considerándose mentres loop, imos executa-lo unha vez, necesariamente.
Despois, cando chegamos á condición, imos comprobar se é certa ou falsa.
Se é verdade, nós imos facelo de novo, se é falso, imos seguir indo.
Entón, cando é o último especialmente útil?
Entón eu podo dicir que no conxunto dos 4 anos, 3 anos, calquera que sexa,
que eu teño programado, eu usei iso, como, menos de 10 veces.
E, probabelmente, cinco deles están en CS50 cando estamos introducindo facer mentres-loops.
Entón, cando usou loops do-while?
Cando é o - si?
[Estudante] Cando está intentando obter a entrada do usuario, ou algo que quere comprobar -
Si Entón faga-while, a entrada do usuario é un dos grandes.
É por iso que os conxuntos de problemas primeiro par, cando quere preguntar ao usuario, como,
"Deixa-me unha corda," non pode seguir ata chegar esa cadea.
E para que, necesariamente, ten que preguntar para a cadea polo menos unha vez.
Pero entón, se responden algo malo, entón precisas para facer un loop para atrás e preguntar de novo.
Pero diferente do que a entrada do usuario, é moi raro que eu encontro un caso
onde quero loop "polo menos unha vez", pero posiblemente máis.
Preguntas ou -? Alguén xa usou un do-while noutro lugar?
Okay. Entón o próximo é: "O que non declarado identificador
xeralmente indican se emitido polo bumbum? "
Entón, que tipo de código que eu podería escribir para 'identificador non declarado?
[Estudante] que x = 2?
Así, podemos só probalo aquí, x = 2.
Imos facer iso - oh, eu non prema nel. Entón aquí temos - todos os dereitos.
"O uso de x identificador non declarado".
Entón ese é o identificador non declarado, unha variable.
El vai con frecuencia chamar un identificador dunha variable.
Por iso, quizais non sabe é realmente unha variable, que non sabe o que é.
Entón, é un identificador.
Entón por que non é declarado? Si
Entón, para ser claro sobre a terminoloxía, a declaración dunha variable
é cando di "int x" ou "y", secuencia que sexa.
A inicialización da variábel, ou a asignación de variable,
sempre que di "x = 2".
Así, podemos facelo en etapas separadas, int x, x = 2, e ata - podemos ter unha morea de cousas aquí dentro -
pero ata esta liña acontece, x aínda é inicializar, pero foi declarado.
E así podemos, por suposto, facelo nunha liña, e agora estamos declarando e inicializando.
Preguntas?
E, finalmente, "Por que non é a cifra de César moi seguro?"
Entón, primeiro, que alguén quere dicir que a cifra de César é?
[Estudante] Caesar Cipher só é que mapear, cambia cada letra,
un determinado número de letras pasar por riba, e pasar por riba, e non é moi seguro porque
hai só 26 opcións posibles e só tes que tentar cada unha das persoas, ata lograr.
Oh Entón, eu teño que repetir?
A cifra de César, é - Quero dicir, está lidando con el sobre os problemas que -
ou eu creo que a edición estándar do conxunto de problemas que non está na edición hacker.
Entón, na edición estándar para o conxunto de problemas, recibirá unha mensaxe do tipo: "Ola, mundo",
e tamén ten un número como 6, e levar esa mensaxe, e cada personaxe individual,
vostede xira-lo por seis posicións no alfabeto.
Así, a 'h' Ola quedaría h-i-j-k-l-m-n.
Entón, a primeira letra sería n. Nós facemos o mesmo con e.
Se temos un, como, z ou algo así, entón nós implicados a volta a 'un'.
Pero cada personaxe recibe ciclo 6 caracteres ao final do alfabeto, e non é moi seguro
unha vez que existen só 26 posibilidades de cantas maneiras podería implicar unha única letra.
Entón pode só tentar tódalas 26 deles e, presumiblemente, unha mensaxe suficientemente longo,
só un deses posibles 26 cousas vai ser lexibles,
eo lexible vai ser a mensaxe orixinal.
Polo tanto, non é unha boa forma de cifrar nada.
Alleos a esas shorts, "¿Que é unha función?"
Entón, o que é unha función? Si
[Estudante] É coma se unha peza de código que pode chamar para pasar e, a continuación, obter o valor de retorno de calquera cousa.
Si Entón, eu vou responder por tamén responder a seguinte - ou a repetición por tamén só responder á seguinte.
Pode utilizar funcións en vez de só copiar e pegar o código unha e outra vez.
Só ten que ter o código, coloque o nun fuction, e entón podes só chamar a función
onde queira que fose copiar e pegar.
Así, as funcións son útiles.
Entón agora imos facer problemas reais.
O primeiro. Así, a idea de que a primeira é, pasa unha cadea, e independentemente da -
ou que di en letras minúsculas? Ela non di que todas as letras minúsculas.
Polo tanto, a mensaxe pode ser calquera cousa, e - Oh non. Fai.
"Para simplificar, pode asumir que o usuario só a entrada letras minúsculas e espazos."
Entón nós pasar unha mensaxe con só letras minúsculas e entón cambiar
entre capital e minúsculas - que cambiar a secuencia de ser capital e minúsculas, alternando.
Entón, antes de darlle un segundo para ata mergullo no problema,
cal é o primeiro que temos que facer?
Oh, que eu basta con premer en? Oh, eu só clic en un correo-e aquí.
Entón o primeiro que cómpre facer - estou a ollar para a persoa errada?
Isto é parte dun presente?
Non, estas son aínda está alí, no entanto.
Ok, aínda está aquí.
Agora non podemos asumir -? Si Aquí non podemos asumir que é só minúsculas e espazos.
Entón, agora temos que xestionar o feito de que as cartas pode ser o que queremos que eles sexan.
E así, o primeiro que queremos facer é só recibir a mensaxe.
Nós só necesitamos ter unha cadea, cadea s = GetString, ok.
Agora este problema, existen algunhas formas de facelo.
Pero imos querer usar operadores bit a bit aquí.
Hai persoas que ou non estaban no supersection,
ou algo así, e non sei o que son operadores bit a bit?
Ou como se relacionan con ASCII de algunha maneira?
[Estudante] Eu non estaba no supersection, pero eu sei que os operadores bit a bit son.
Okay. Entón eu non teño que pasar por riba dos principios deles, pero eu vou explicar
o que imos querer usar aquí.
Entón 'A': Representación binaria de capital A, o número é de 65.
Eu só vou mirar - 41 vai ser 01000001.
De xeito que debe ser de 65 en decimal, polo que esta é a representación binaria do carácter de capital A.
Agora, a representación binaria do personaxe minúsculas 'a'
vai ser o mesmo, ou case. É que - 6, si. Isto é correcto.
A capital de modo binario minúsculas, binario 'un'.
Entón, observe que a diferenza entre A e 'a' é este único bit.
E esta pasa a ser a de 32 bits, o bit que representa o número 32.
E iso ten sentido, xa que A é de 65; 'a' e 97.
A diferenza entre eles é 32.
Polo tanto, agora sabemos que podemos converter da a 'a', tomando un
e bits a bit ORing-lo, con - que se parece un 1.
Este é un OR bit a bit, con 00100000, e que vai dar "un".
E podemos empezar a partir de 'a' a A por bitwise AND
con 11, 0 naquel lugar, 11111.
Entón, iso vai entón darnos exactamente o que 'a', pero cancela este bit individual,
por iso imos ter 01000001, eu non sei se eu contei dereito.
Pero esta técnica de bit a bit ORing para comezar a partir de capital en minúscula
e bits a bit AND para comezar a partir de minúsculas para o capital non é exclusivo para A.
Todas as letras, K vs K, Z vs z,
todos eles están indo só para variar por este único bit.
E así pode usar isto para cambiar de calquera letra minúscula para calquera letra maiúscula e viceversa.
Okay. Así, un xeito doado de obter a partir deste - así, en vez de ter que
escribir o que quere que 1011111 é - un xeito doado de representar este número, e iso non é unha
que eu fun no supersection, pero til (~) é outro operador bit a bit.
O que fai é ~ mira para a representación de bits.
Imos dar calquera número.
Este é só un número binario, e que ~ non é só cambia todos os bits.
Polo tanto, esta foi a 1, agora a 0, isto é un 0, agora un 1, 010,100.
Entón iso é todo ~ fai. Entón, 32, vai ser o número - librar-se de que -
32 de xeito que vai ser o número 00100000, e así por ~ desta vai ser
este número ata aquí que eu ANDed 'a' con.
Será que todo o mundo ve isto? Isto é moi común, como cando quere descubrir
para cousas máis recentes que poderiamos estar vendo, cando queremos ver se -
ou queremos todo, cada conxunto único bit, excepto para un
tende a ~ o pouco que nós non queremos definir.
Entón, non queremos que o conxunto de 32 bits, para que non ~ 32.
Okay. Así, podemos usar todos os aquí.
Todo ben, por iso é bo se non está preparado, imos andar lentamente ao longo xuntos,
ou camiñar sobre iso, entón - por iso. Camiño por iso.
Polo tanto, temos a nosa cadea, e queremos loop sobre cada personaxe que secuencia e facer algo para el.
Entón, como imos varrer unha cadea? O que debemos usar?
Eu non vou facer iso aquí. Si
Entón, eu teño o meu iterador, e el dixo iso, pero como sei cantos caracteres están na cadea?
Strlen (s), entón i + +.
Entón o que eu fixen aquí non é a mellor forma de facer as cousas.
Alguén sabe por que?
Porque está comprobando a linguaxe da cadea de cada vez.
Entón, nós imos querer mover strlen, eu podería dicir-se aquí, int tamaño = strlen (s),
e, entón, i <lonxitude, e no caso de non ter visto iso antes,
Eu tamén podería facer int i = 0, lonxitude = strlen (s).
E así, este é un pouco preferible, xa que agora restrinxiu o ámbito
da lonxitude variable para só este lazo 'for' no canto de declarar isto antes
e que sempre hai, e no caso de que vostede non colleu por que iso é malo,
ou porque o orixinal era malo, é - para comezar o loop.
Eu verifiquei a condición. É i <lonxitude de s?
Así, a lonxitude s, imos traballar con "Ola" en todo momento.
Así lonxitude s, h-e-l-l-o. A lonxitude é 5.
Entón, i = 0 lonxitude, é de 5, entón eu non se <5, entón o ciclo continúa.
Entón imos de novo. Nós consideramos a condición. É i <a lonxitude do Ola?
Entón, imos comprobar a lonxitude da Olá H-e-l-l-o. Isto é 5; i non é <5, entón seguimos de novo.
Entón, nós estamos calculando, contamos Ola, para cada iteração do loop,
ata pensei que nunca vai cambiar, pero sempre vai ser 5.
Entón, lembre-se 5 na fronte, e agora todo está mellor.
Entón iteração sobre toda a cadea.
O que queremos facer cada carácter da cadea?
[Falando Estudante, inintelixible]
Si Entón, se o personaxe é non alfabéticos, entón nós só queremos ir sobre el.
Porque só se preocupan con letras do alfabeto, non podemos capitalizar un número.
Entón, como podemos facer iso? Polo tanto, a nosa condición, por iso, se queremos algo - comprobar se é alfabética.
Entón, como podemos comprobar iso?
[Estudante] Pode só usar a función é alfa.
É que incluídos en calquera destes, ou calquera inclúen char.h, como ou algo así?
Non imos utilizar a función é alfa, e usar o explícito - por iso temos s [i],
que é o personaxe do oitavo s, lembre que unha cadea é unha matriz de caracteres,
así que o carácter oitavo de s.
Agora, se é unha letra maiúscula, sabemos que ten que estar en unha franxa específica.
E que é o que van?
Si Entón, se s [i] é ≥ 65 e s [i] é ≤ 90, o que debo facer en vez diso?
Si Entón, vostede non debe absolutamente precisa aínda de saber os valores ASCII de calquera cousa sempre.
Nunca pense que dos 65 números, 90, 97 e 102, ou sexa o que for.
Non precisa - 112 - non precisa saber a todos. Isto é malo tamén.
Só usar os caracteres single-quote, constantes comiñas. Así, "A" e menos de 90 é 'Z.'
E este é significativamente mellor - eu non sei por riba da miña cabeza que Z é 90.
Sei enriba da miña cabeza que 'Z' é a capital Z.
Entón, mentres este está na franxa de capital dun a capital Z, ou podemos comprobar minúsculas,
Ou se é na franxa de ≥ 'a' e ≤ z.
Entón esta é a nosa condición.
O estilo de onde poñer isto varía.
Vou facelo así.
Agora, o que queremos facer?
Sabemos que esta carta é un personaxe, un carácter alfabético.
Polo tanto, temos que cambiar entre esta agora debe ser unha letra maiúscula ou unha letra minúscula.
Como podemos seguir o que que quere que sexa?
[Voces estudantís, inintelixible]
Entón, si, pero deixe-me comprobar.
Módulo 0-2 foi dito, foi unha suxestión xogado fóra, e eu estou de acordo con iso.
Excepto aviso de que, como - é este o caso? Si
E cada un dos outros, pero non podemos módulo 2 do i ou i mod 2, pois
E entender que é capital e 'a' é minúscula? Pero hai un espazo que os separa?
Entón, eles van ser o mesmo mod 2, pero son casos distintos.
[Pregunta do estudante, inintelixible]
Si Entón, nós estamos indo só para manter unha conta.
Tamén podería facelo aquí, se quixésemos, que pode ter un pouco pesado
no de declaracións de lazo, eu vou poñelas aquí.
Entón, int count = comeza en 0.
E agora, eu vou contar cantos caracteres alfabéticos que tivemos.
Entón, nós estamos, inevitablemente, vai contar + +, unha vez que atopou outro carácter alfabético.
Pero, ata agora está dicindo que se mod conta de 2.
Entón, o que se conta mod 2? Oh Vou facer == 0 por agora.
Tamén imos pasar por riba diso. Entón, se a conta de mod 2 == 0, entón o que?
[Os alumnos de resposta, inintelixible]
Entón, nós queremos que acabe maiúsculas.
Hai dous casos; maiúsculas e minúsculas son os dous problemas.
Entón, se estamos en minúsculas necesitamos facelo maiúsculas.
Se é maiúscula, non precisamos facer nada.
Pero hai unha forma - non deben ter virado -
que non precisa aínda de comprobar se é maiúscula ou minúscula?
O que podemos facer para sempre asegurarse de que sempre acaban en maiúscula?
Entón, observe o que fixemos en minúscula 'a', o que se fixo a mesma cousa exacta para maiúsculas A?
Un cambio fai maiúsculas, ou a modificación de valor?
Si Así, calquera letra maiúscula bitwise ANDed con ~ 32 vai ser ese personaxe maiúscula mesmo
porque para calquera carácter maiúsculo o bit 32 non está definido.
Entón, se queremos levar o personaxe s [i] queremos que sexa minúscula ou maiúscula.
Entón, se era minúscula, agora é maiúscula, se era maiúscula, aínda é maiúscula, e que é iso.
Eu dixen iso no supersection: Pode usar 32 se quere, pero eu tenden a preferir facer 'a' - A,
no canto de só 32 liso, porque pode ser calquera outro bit.
Tras o bit 32, que pode ser calquera destes, ou non teriamos suficiente
números para representar todos os caracteres.
Entón, se incorporarse o de 32 bits, que podería ser o de 64 bits, que podería ser a de 128 bits.
Calquera deses bits pode ser o pouco que fai a distinción entre maiúsculas e minúsculas.
Non precisa saber que é o de 32 bits.
I pode empregar esta 'a' - A para obter o bit que é diferente entre os dous
sen necesidade de contar co número máxico que é 32.
E agora, máis contar era estraño, e entón o que quero facer?
[Respostas dos alumnos, inintelixible]
[Estudante] O que é isto?
Vou facelo en un segundo.
Entón, agora, se eu queira - quero estar seguro de que o personaxe é agora minúsculas,
e así podo ou por 32, 32 e significado 'a' - A.
Pero aviso, o mesmo razoamento que o anterior, que se
letra xa era minúscula, seguida por 32 ORing só mantén minúsculas.
Non cambiou o carácter orixinal.
Pero agora eu non teño que evitar dicir: "Se é minúscula, só esquece-lo,
se é maiúscula, entón cambia-lo. "
É moito máis cómodo para facer isto.
[Estudante] Será que a estratexia da subtracción do maiúsculas de minúsculas o traballo se non fose 32?
Se era, tipo, 34 ou algo así?
Entón, ten que saber que a diferenza entre os dous é -? >> 1 bit.
Pode ser máis que 1 bit, sempre que todos os bits a continuación desta posición son as mesmas.
Entón, necesitamos polo menos 26 caracteres - ou, existen 26 caracteres.
Entón, necesitamos polo menos 26 números para representar a diferenza -
A diferenza entre A e 'a' ten que ser de polo menos 26,
ou ben non representaría todos os números de capitais.
Isto significa que a si comezarmos a 1, que vai utilizar todos eses bits,
Todos estes primeiros 5 bits para representar todo a Z.
É por iso que o próximo bit, ou este bit, a próxima é a que escolleu para distinguir entre un e 'un'.
Isto é porque, na táboa ASCII, hai cinco símbolos que separan maiúsculas de minúsculas.
Dende que estes son os símbolos, o 5 extra que trae a 32 sendo a diferenza entre eles.
[Estudante] Entón, nós poderíamos facer iso, porque ASCII é designado desa forma.
Si Pero ASCII - a diferenza podía tamén ser ambos destes bits.
Como, se un era 10000001, e 'a' 11100001 - me esqueza, o que sexa.
Pero se fose iso, entón aínda pode usar 'a' - A.
É só agora a diferencia entre A e 'a' é aínda estes dous bits.
Eu creo que está escrito 48. É 32 + 64? Eu creo que é?
Sería aínda 2 bits; cada personaxe, como, Z e Z, K e K,
aínda terían os mesmos bits exactas definidas excepto para os dous bits.
Entón, mentres iso é sempre certo, independentemente de se estamos usando ASCII ou algún outro sistema,
mentres que hai só un determinado número de bits que son diferentes para cada personaxe,
a continuación, que funciona ben.
É que 32 foi creado porque é o primeiro que podería usar. >> Cool.
Eu tenden a preferir, se non viu, o bloque é só unha soa liña,
pode se librar das claves, de modo que tenden a preferir facelo.
Ademais, vostede sabe como podemos facer cousas como s [i] + = 1?
Tamén pode facer s [i] bitwise E = 32.
E bit a bit OR = 32.
Ademais, contan mod 2 == 0.
Entón lembre que - eu non vou gravala-lo - calquera valor distinto de cero é certo, e 0 é falso.
Así, "a conta mod 2 == 0" é o mesmo que dicir "si non contar mod 2".
Eu probablemente tería só inverteu as liñas e dixo: "se a conta mod 2,
que o OR 1, máis que o AND 1 ", para que eu non precisaba do" non ".
Pero iso funciona tan ben.
E o que máis podo facer aquí?
Pode combina-los con ternário se quería, pero, entón, que acabara de facer as cousas máis confusas
e probablemente máis difícil de ler, por iso non imos facelo.
Alguén ten algunha suxestión?
É que todo o problema pediu? Oh yeah.
Entón, se librar destas liñas baleiras, agora imos imprimir f,% s sexa o único para cordas,
Imos imprimir f, s.
Agora imos executalo. Eu fixen algo mal?
Isto é un \ ", quero un n.
Okay. Agora imos executalo. El probablemente vai berrar comigo.
Strlen é string.h.
Polo tanto, esta é a cousa agradable sobre Clang é mostra o que está,
ao contrario do GCC, que só di: "Ei, esqueceu algo, eu non sei o que era."
Pero iso me vai dicir: "Vostede debe incluir string.h".
Entón eu non pedir nada, por iso non está dicindo nada.
Pero imos facer o seu exemplo, "Grazas 4 Engada o".
Isto parece correcto. Hooray.
Entón, volver para o seu inicio, eu case nunca o fan.
É opcional. E principal é a única función para o que é opcional.
Se non voltar nada da principal, é asumido que pretendía volver 0.
Preguntas?
Okay. Polo tanto, agora o segundo problema.
"Teña en conta que da segunda charla dúas semanas de que o troco de valores 2 variables, pasando
estas dúas variables para unha función (aínda que chamado de intercambio) non é exactamente o traballo, polo menos non sen 'punteiro' ".
E ignorar os punteiros ata chegar a eles.
Queremos cambiar dúas variables; non estamos a usar unha función para facer iso.
Aínda imos facelo principal como el di.
Pero, para usar esas dúas variables, non queremos usar unha variable temporal.
Hai dúas formas de facelo.
Podes facelo usando os seus operadores binarios tradicionais.
Entón, alguén sabe unha maneira rápida e sucia de facelo?
Pode realmente ter un minuto de pensar. Se eu tivera -
Vou definir o problema como se piden. Entón, se eu tivera dúas variables, A, que é só un enteiro
que me dan, e B suma variable, que é un outro número enteiro que eu son dado.
Entón, se eu teño esas dúas variables, agora quero trocalos.
O tradicional, usando os seus operadores binarios estándar, é dicir, como +, -, ÷.
Nin os operadores bitwise que actúan sobre binario.
Entón, usando -, +, ÷, e todos aqueles.
Poderiamos cambiar, facendo algo así como a = a + b, b = a - b, a = a - b.
Entón, comprobación de sanidade, e despois imos ver por que isto funciona.
Imos dicir que a = 7, b = 3, entón a + b que vai ser 10.
Entón, nós estamos agora definindo a = 10, e entón nós estamos facendo b = a - b.
Entón, nós estamos facendo b = a - b, que vai ser 7, e b = a - b, de novo,
ou = a - b. Que vai ser 10-7 que é 3.
Entón, agora, correctamente, 'a' foi de 7, b foi de 3, e agora b é 7 e 'a' e 3.
De modo que o tipo de sentido, 'a' é a combinación dos dous números.
Neste punto, 'a' é a combinación, e entón nós estamos restando ab orixinal,
e entón nós estamos restando o que era o orixinal 'a'.
Pero iso non funciona para todos os números.
Para ver isto, imos considerar un sistema, de xeito que adoitamos pensar en números enteiros como 32 bits.
Imos traballar en algo que é só como 4 bits.
Espero que eu veña con un bo exemplo agora.
Entón, sei, iso vai ser doado.
Imos dicir que os nosos dous números son 1111, e 1111, de xeito que estamos en binario agora.
En decimais reais, se quere pensar desa forma, a. = 15 e b = 15
E entón esperamos que, despois de troca-los - eles non ten sequera a ser os mesmos números,
pero eu fixen iso desa maneira.
Imos facer non lles os mesmos números. Imos facer 1111 e 0001.
Entón, a = 15 e b = 1.
Despois de que troca-los, esperamos que 'a' para ser 1 e B para ser 15.
Entón, o noso primeiro paso é a = a + b.
Os nosos números son só 4 bits de ancho, entón 'un', que é 1111, + B, que é de 0001,
vai acabar sendo 10.000, pero temos só 4 bits.
Entón, agora a = 0.
E agora queremos establecer b = a - b - na verdade, iso aínda funciona perfectamente.
a = a - imos ver se isto funciona perfectamente - b.
Entón, a continuación, b = 0 - 1, o que aínda sería 15, e, a continuación, a = a - b, o que sería un.
Quizais iso non funciona.
Eu sinto que hai unha razón para non funciona con estándar.
Ok, entón a traballar coa suposición de que non funciona coas operacións de binarios regulares,
e eu vou buscar - Eu Google para ver se iso é verdade.
Entón, nós queremos facelo usando os operadores bit a bit, ea pista aquí é XOR.
Así, a introdución de XOR (^) se non viu aínda.
É, unha vez máis, un operador bit a bit polo que actúa aos poucos, e é -
Se ten os bits 0 e 1, entón este será un.
Se ten os bits 1 e 0, vai ser un, ten os bits 0 e 0 que vai ser 0,
e se ten os bits 1 e un vai ser 0.
Entón, é como OR. Se calquera dos bits son certos, é dicir, 1, pero a diferenza OR, non pode ser os dous bits que son certas.
Ou tería esta ser 1, XOR tería este ser 0.
Entón nós imos querer usar XOR aquí.
Pense nisso por un minuto, eu vou a Google.
Ben, non pode ler isto, eu estou actualmente na páxina algoritmo XOR intercambio.
Esperemos que isto ha explicar por que eu non podo -
Este é o algoritmo que acabamos de facer.
Eu aínda non sei por que - debo ter só escolleu un mal exemplo,
pero neste caso, onde 'a' ocorreu para facer 0, despois de chegar ao 5 bits, polo que agora 'a' é 0,
que é o que se chama "estourido de enteiro."
Segundo a Wikipedia, "Ao contrario do intercambio de XOR, esta variación esixe que usa algúns métodos
a garantía de que x + y non causa un exceso de número enteiro ".
Polo tanto, este non ten problemas, o que foi exceso de número enteiro, pero eu fixen algo mal.
Non estou seguro. Vou tentar chegar a un outro.
[Estudante] Ben, non é exceso de número enteiro cando está tentando poñer un número no que
maior que a cantidade de bits que recibe?
Si Temos 4 bits. Isto - que tivo 4 bits, que intente engadir un para ela, entón imos acabar con 5 bits.
Pero o quinto bit só é cortada, si.
Pode, de feito -
[Estudante] Será que xogue un erro, ou fai iso - tería que publicar un erro?
Non entón non hai erro. Cando chegar ao nivel da montaxe, un pouco especial
en algún lugar está definido que dixo que houbo un estourido, pero en C que medio que simplemente non tratar con isto.
Realmente non pode tratar con isto, a menos que use instrucións de montaxe especiais en C.
Imos pensar sobre XOR cambio.
E eu creo que o artigo da Wikipedia tamén pode vir a dicir que -
Por iso, tamén trouxeron aritmética modular, entón eu creo que era, en teoría, a aritmética modular
cando dixo que 0-1 é de 15 novo.
Para que poida, de feito - un procesador estándar que fai 0 - 1 = 15.
Dende que acabar en 0, restar 1, así el só enrola de volta en torno a 1111.
Polo tanto, este algoritmo pode realmente funciona, a a + b, a - b, b - a, que pode ser óptimo.
Pero hai algúns procesadores que non facelo, e por iso non quedaría ben en aqueles específicos.
Cambio de XOR funcionará en calquera procesador. Okay.
A idea é que el debería ser o mesmo, con todo.
Onde estamos usando XOR dalgunha forma obter a información de ambos nunha das variables,
e, a continuación, elimina a información das variables individuais de novo.
Entón, alguén ten ideas / a resposta?
[Responder Estudante, inintelixible]
Polo tanto, este debe funcionar, e tamén, XOR é conmutativa.
Independentemente de cal orde estes dous números que ser ata aquí,
este resultado será o mesmo.
Entón a ^ b e b ^ a.
Tamén podes ver este escrito como un ^ = b, b ^ = a, a ^ = b novo.
Entón, iso é certo, e ver por que isto funciona, creo que dos bits.
Empregando un número pequeno, digamos 11001, e 01100.
Polo tanto, esta é 'a', o que é b.
Entón a ^ = b.
Nós imos estar definindo "a" = a XOR destas dúas cousas.
Entón, 1 ^ 0 e 1, 1 ^ 1 e 0, 0 ^ 1 e 1, e 0 ^ 0 0, 1 ^ 0 e 1.
So 'unha', se ollar o número decimal, que vai ser -
non vai ver moito dunha relación entre o orixinal 'a' eo novo 'a',
pero mirando para os bits, 'a' agora como unha malla de información
de tanto o orixinal 'a' e b orixinal.
Entón, se tomamos b ^ a, vemos que imos terminar no orixinal 'un'.
E se tomamos o orixinal 'a' ^ o novo 'a', vemos que acabar no b orixinal.
Entón, (a ^ b) ^ b = orixinal 'a'.
E (a ^ b) ^ a = b orixinal.
Non hai - outra forma de ver isto é XOR nada en si é sempre 0.
Así, 1101 ^ 1101, todos os bits van ser os mesmos.
Entón non vai ser un caso en que un é un 0 eo outro é un.
Polo tanto, este é 0000.
O mesmo con este. (A ^ b) ^ b é como a ^ (b ^ b).
(B ^ b) será 0; a ^ 0 é só vai ser 'a', xa que todos os bits son 0.
Así, os únicos que están indo para estar onde 'a' era orixinalmente un 1 - tiña uns.
E a mesma idea aquí, eu estou seguro que el tamén é conmutativa.
Si Eu dixen antes que era conmutativa.
O ^ 'a,' e asociativa, por iso agora (b ^ a) ^ a.
E podemos facer b ^ (a ^ a).
E entón, de novo, temos a b orixinal.
Así, 'a' é agora a combinación de 'a' e b en conxunto.
Usando a nosa nova combinación 'a' dicimos b = combinación 'a' ^ b do orixinal, temos o orixinal 'a'.
E agora un combo = 'a' ^ ab novo, que era o orixinal - ou o que é agora o que era 'a' b.
Iso é caso aquí. Este é = b, b idade.
Entón agora todo está de volta na orde trocada.
Se realmente mirou para os bits, b = a ^ b, vai XOR estes dous,
ea resposta vai ser iso, e entón a = a ^ b é XORing estes dous ea resposta é esta.
Preguntas? Okay. Así, o último é un pouco significativamente máis difícil.
[Estudante] Coido que ten unha pregunta sobre iso. >> Oh, desculpe.
[Alumno] O que é realmente máis rápido? Se usar este XOR, ou se se declara unha nova variable?
Entón, o que é realmente máis rápido, declarando unha nova variable ou usando XOR para intercambiar?
A resposta é, con toda probabilidade, dunha variable temporal.
E iso porque unha vez que está feita para abaixo - así no nivel da montaxe,
non hai tal cousa como variables locais ou calquera variables temporais ou calquera destas cousas.
Son como - non hai memoria, e existen rexistros.
Os rexistros son onde as cousas están a ocorrer activamente.
Non engadir dúas cousas na memoria, engade dúas cousas en rexistros.
E levar as cousas de memoria para os rexistros despois engadila los,
e entón pode poñer-los de volta na memoria, pero toda a acción ocorre en rexistros.
Entón, cando está usando o achegamento temporal variable, xeralmente o que pasa é
eses dous números xa están en rexistros.
E entón, a partir dese punto, despois de trocar eles,
el só vai comezar a usar o outro rexistro.
En calquera lugar que estaba usando b, el só vai usar o rexistro que xa estaba almacenando 'a'.
Por iso, non é preciso facer nada para realmente facer o intercambio. Si?
[Estudante] Pero tamén ten máis memoria, non?
Só vai ter máis memoria, se precisa para almacenar a variable temporal.
Como se usa máis tarde que a variable temporal de novo en algún lugar,
entón - ou atribúe algo para esa variable temporal.
Así, en calquera punto no tempo "a," b tempo teñen valores diferentes ou algo así,
a continuación, que vai ter locais distinguidos na memoria, pero é certo que
hai moitas variables locais, que só existen en rexistros.
Neste caso, nunca é colocada na memoria, e así nunca está perdendo a memoria.
Okay. Última pregunta é un pouco máis.
Entón, aquí, neste aparello CS50, hai un dicionario.
E a razón para iso é porque [? B66] é un corrector ortográfico onde vai escribir
o uso de táboas de hash ou intenta ou algunha estrutura de datos.
Vai estar escribindo un corrector ortográfico, e vai estar usando este dicionario para facelo.
Pero a este problema, imos só ollar para arriba para ver se é unha soa palabra no dicionario.
Entón, en vez de almacenar dicionario enteiro nalgunha estrutura de datos
e, a continuación, ollando para un documento enteiro para ver se algo está incorrecto,
só queremos atopar unha palabra. Así, podemos só dixitalizar sobre o dicionario enteiro
e nunca atopamos a palabra no dicionario enteiro, entón el non estaba alí.
Se a pescudas sobre o dicionario enteiro e non ver a palabra, entón estamos ben, nós o atopamos.
Di aquí que queremos comezar a ollar para a función C de manipulación de arquivos,
xa que queremos ler o dicionario,
pero vou dar a información aquí, como para as funcións que ten que pensar.
Vou escribir-los espazos.
Así, os principais que vai querer ollar para f son abertos e, entón, inevitablemente, f pechada,
que vai ao final do seu programa, e f f dixitalización.
Tamén pode usar f ler, pero probablemente non quere
porque iso - non acabar precisando diso.
F f varrido é o que vai empregar para dixitalizar sobre o dicionario.
E para que non precisa codificar a solución, só tentar e como pseudo-código o seu camiño
a unha solución, e despois imos discutir iso.
E, de feito, sempre que eu xa che dei estes, se vostede poñerse en calquera terminal ou shell do seu dispositivo,
Eu - Eu normalmente - se aínda non viu, eu non sei se fixo en clase,
pero o home, de xeito que as páxinas do manual, son bastante útiles para ollar para practicamente calquera función.
Entón eu podo facer, como, f home, dixitalización f.
Esta é agora a información sobre a familia f varrido de funcións.
Eu tamén podería facer f home, abertos, e que me vai dar máis detalles do que iso.
Entón, se sabe cal é a función que está a usar, ou estás lendo código
e ve algunha función e pensa, "O que iso fai?"
Só un home nome da función que.
Hai un par de exemplos estraños, onde pode ter que dicir
gusto. home 2, que o nome da función, ou o home que 3 nome da función,
pero só tes que facelo o nome de función de home non acontecer a traballar por primeira vez.
[Estudante] Entón, eu estou lendo a páxina man para abrir, pero aínda estou confuso sobre como usalo eo programa.
Okay. Unha morea de páxinas de manual son menos que útil.
Son máis útiles se xa sabe o que facer
e entón só precisa lembrar da orde dos argumentos ou algo así.
Ou poden dar unha visión xeral, pero algúns deles son moi grande.
Como f varrido f, tamén. El lle dá a información para todas estas funcións,
e unha liña de baixo aquí acontece a dicir, "F varrido f le dende o punto de corda ou cadea."
Pero f abrir. Entón, como é que usamos f aberta?
A idea dun programa que precisa facer ficheiro I / O é que
primeiro ten que abrir o arquivo que quere facer as cousas con e, inevitablemente,
ler cousas dese ficheiro e facer cousas con eles.
F aberto é o que usan para abrir o ficheiro.
O único que volver, entón o arquivo que queremos abrir, dános a -
aquí el di que "usuario / / share Dict / / palabras".
Este é o ficheiro que quere abrir, e queremos abrilo -
temos que especificar explicitamente se queremos abri-lo para ler ou se queremos abrilo a escribir.
Hai un par de combinacións e outras cousas, pero queremos abrir este para lectura.
Queremos ler desde o ficheiro.
Así que este retorno? El retorna un arquivo de estrela (*),
e eu vou amosar todo na variable f, entón *,
de novo, é un punteiro, pero non queren tratar con punteiros.
Podes pensar en f como f agora é a variable que vai empregar para representar o arquivo.
Entón, se quere ler o ficheiro, le a partir de f.
Se queres pechar o ficheiro, pecha f.
Así, a finais do programa, cando inevitablemente quere pechar o ficheiro, o que temos que facer?
Queremos pechar f.
Entón, agora a función de último arquivo que imos querer usar é varrido f, f f dixitalización.
E o que iso fai é que varreu sobre o arquivo buscando un patrón para responder.
Mirando á páxina home aquí vemos int f f dixitalización, ignorar o valor de retorno para agora.
O primeiro argumento é o fluxo de ficheiro *, de xeito que o primeiro argumento que imos querer pasar é f.
Estamos pescudas sobre f.
O segundo argumento é unha secuencia de formato.
Vou dar-lle unha secuencia de formato agora.
Creo que acontecer que dicir, 127s \ n, unha morea de que é necesario.
A idea de que esa secuencia de formato, é que pode pensar de f dixitalización como o oposto de f impresión.
Entón f impresión, impresión f tamén usan este tipo de parámetro formato,
pero en f impresión que estamos facendo é - imos ollar para un equivalente.
Así imprimir f, e non hai, en realidade tamén f impresión f, onde o primeiro argumento será f.
Ao imprimir f, poderiamos dicir algo así como, "print 127s \ n" e despois pasar algunha corda,
que vai imprimir esa cadea e logo unha nova liña.
O que 127 significa, eu estou seguro, pero eu nunca me restrinxido a el,
Non é preciso nin dicir '127 'en f impresión,
pero o que significa imprimir os primeiros 127 carácteres.
Entón, eu estou seguro que é o caso. Podes Google para iso.
Pero o próximo que eu teño case seguro que significa iso.
Polo tanto, esta é imprimir os primeiros 127 carácteres, seguido por unha nova liña.
F varrido f agora, en vez de ollar a unha variable e imprimir lo,
vai mirar para algunhas cordas, e almacenar o estándar para a variable.
Imos realmente usar f verificación nun exemplo diferente.
Entón, imos dicir que tivemos algúns int, x = 4,
e queriamos crear unha cadea de feitos - quería crear a cadea
que era como este vai aparecer moito máis tarde,
algo que é como 4.jpg.
Polo tanto, este pode ser un programa onde terá contador de suma,
Resumindo combater i, e quere gardar unha chea de imaxes.
Entón quere gardar i.jpg, onde i é algunha iteração do loop.
Entón, como imos facer esa secuencia para que o JPEG?
Se queres imprimir 4.jpg, podemos só dicir f impresión, d.jpg%
e entón el vai imprimir para que o JPEG.
Pero, se queremos salvar o 4.jpg cadea, usan f dixitalización.
Así cadea s - na verdade, non podo - personaxe, char s, imos 100.
Entón, eu só dixo algunha matriz de 100 caracteres,
e iso é o que nós estamos, inevitablemente, vai estar almacenando que JPEG dentro
Entón, nós estamos indo a usar f, dixitalización e do formato, como diriamos d.jpg%
para imprimir 4.jpg, o formato deste será d.jpg%.
Así, o formato é d.jpg%, o que queremos para substituír d% con é x,
e agora necesitamos almacenar esa cadea en algún lugar.
E onde estamos indo para almacenar esta cadea está na matriz s.
Entón, despois de esta liña de código, s, se imprimir f% s, da variable s,
que vai imprimir 4.jpg.
Entón f varrido f é o mesmo que f varrido, só que agora está a mirar para este ficheiro
para o que para almacenar en s.
Isto é o que o último argumento é que vai ser.
Queremos gravar - "familia f dixitalización de exames de funcións tanto no acordo co formato como intentou a continuación.
Se o son almacenados nos puntos de localización pode volver - "
Non pode ser bo. Deixe-me pensar por un segundo.
Entón varrido f non fai - o que diaños é a función que fai iso?
Entón varrido f non vai levar un enteiro e facer punto jpg.
Vai [resmunga].
Salva variable int en cadea int C.
¿Que é esta variable, ou o que é esta función chamada?
Si Isto - si. Entón, o que eu estaba definindo a vostede antes era s f de impresión,
que - que fai moito máis sentido, por iso que eu dixo que era moito máis como f impresión.
Dixitalización f aínda é tipo como de f impresión, pero s f impresión vai examina-lo máis de
e substituír as variables e, agora, almacena-lo nunha corda.
En vez de imprimir, el almacena en unha cadea.
Así, ignorar que enteiramente. Aínda pode pensar en como o especificador de formato semellante ao f impresión.
Entón, agora, se quixésemos facer as cousas 4.jpg, fariamos s f impresión, x iso.
Entón, o que está facendo pescudas f - Cal foi a súa pregunta vai ser?
[Estudante] Eu só estou confuso sobre o que estamos intentando facer aquí
que o JPEG. Podes explicar que un tempo máis?
Polo tanto, este foi - é menos relevent para f varrido f agora, espero, vai amarre de volta en algún tipo de camiño.
Pero o que eu inicialmente tiña a intención de amosar era - esta é, en realidade, directamente relevante para estes [? F5]
Vai estar usando s f de impresión, onde, dicir que temos 100 imaxes,
e quere ler a imaxe 1.jpg, 2.jpg, 3.jpg.
Polo tanto, a fin de facelo, ten que f aberta, e entón ten que pasar a secuencia que quere abrir.
Entón, quere abrir 1.jpg;, a fin de crear a cadea que é 1.jpg,
facemos s f impresión de% d.jpg-non fixemos por int i = 0.
i <40, i + +.
Entón s% f d.jpg impresión de i.
Entón, despois desta liña, agora a variable ou matriz s vai 1.jpg.
Ou, 0.jpg, 1.jpg, 2.jpg. E así podemos abrir, á súa vez, cada imaxe para ler.
Entón é iso que s imprimir f fai. Vostede ve o que s imprimir f está facendo agora?
[Estudante] Ok, entón está tomando - el crea unha cadea, something.jpg, e despois almacena.
Si El crea - esta é outra secuencia de formato, así como pescudas F e F de impresión,
onde se insere todas as variables para o segundo argumento, pode s en oposición ao i.
Quizais - quero dicir, este é o caso. Pero calquera que sexa a orde dos argumentos é.
Vai para introducir todas as variables para a cadea de formato
e despois gardar no noso buffer; chamamos iso de un buffer, que é onde estamos almacenando a cadea.
Entón, nós estamos almacenando dentro s a cadea formato correctamente, d%, sendo substituído por 4.
[Estudante] Entón, se fixésemos iso, é a variable f só vai ser trasladado?
Si Así, debemos pechar o orixinal f antes de facelo.
Pero - e entón, tamén, se non houbese un f abrir aquí, entón sería preciso dicir -
Si Pero sería abrir un centenar de arquivos diferentes.
[Estudante] Mais non sería capaz de acceder ou - ok.
Okay. Entón varrido f, f varrido f, é unha especie da mesma idea,
pero en vez de, en vez de almacena-lo nunha corda, é máis como está agora
pasando por unha picada e matrimonio de estándares contra esa secuencia e almacenar os resultados variables.
Podes empregar f varrido para analizar sobre algo 4.jpg, e almacenar a 4 enteiro int x suma.
Isto é o que podemos utilizar para f pescudas.
F varrido f vai facer na liña de comandos.
Eu estou realmente seguro de que isto é o que a biblioteca CS50 fai.
Entón, cando di, "obter int," e exame f-ing máis - f verificación é o xeito que obter entrada do usuario.
F varrido f vai facer a mesma cousa, pero usando un arquivo de dixitalizar máis.
Entón, aquí estamos pescudas sobre este ficheiro.
O estándar que estamos intentando combinar algunha cadea que é de 127 caracteres
seguido por unha nova liña
Entón, eu estou seguro que nós poderíamos mesmo dicir "corresponder s", xa que no dicionario
acontece que temos, estamos garantir ningunha palabra é moito tempo,
e tamén f f Scania, eu creo, vai parar na liña de novo, non importa o que.
Pero imos incluír a liña nova no xogo, e -
[Estudante] Se non incluír a nova liña, non sería atopar partes dunha palabra?
El - cada un - ollando para o dicionario -
Así, no dicionario, estas son todas as nosas palabras.
Cada un está nunha nova liña.
O f varrido vai pegar esa palabra.
Se non incluir a liña nova, entón é posible que o f próxima pescudas só vai ler a nova liña.
Pero incluíndo nova liña entón simplemente ignorar a nova liña.
Pero nós nunca imos conseguir parte dunha palabra, unha vez que estamos sempre lendo-se a unha nova liña, non importa o que.
[Estudante] Pero e se buscar a palabra "Cissa", como Cissa.
Será que vai atopar iso, e dicir que é un xogo?
Entón aquí estamos nós - el ha ler a - este é realmente un bo punto.
Nós nunca está usando o actual - a palabra que estamos a buscar é o primeiro argumento da liña de comandos.
Así a palabra de corda, argv = 1.
Así que a corda que estamos a buscar é unha argv.
Non estamos á procura dunha palabra en todo na nosa f dixitalización.
O que estabamos facendo pescudas f está quedando cada palabra no dicionario,
e, a continuación, unha vez que temos que palabra imos usar strcmp para comparalos-los.
Imos comparar a nosa palabra eo que acabamos de ler dentro
Entón, inevitablemente, imos acabar facendo unha morea de varrido FS
ata que iso só acontece que f dixitalización vai volver -
ela retorne un, sempre que igualou unha nova palabra,
e volverá algo máis, logo que fallou para coincidir coa palabra.
Estamos lendo todo o dicionario, almacenar liña por liña en cada palabra variable s.
A continuación, nós estamos comparando coa palabra s, e se a comparación == 0,
strcmp pasa para traer 0 un xogo foi feito.
Entón, se é 0, entón podemos imprimir f, combinados,
ou palabra no dicionario, ou o que quere imprimir f.
E entón - non queremos f pechar unha e outra vez.
Este é o tipo de cousas que queremos facer, e non estamos só á procura de palabra no dicionario.
Entón, nós poderíamos facer isto, se queremos mirar para o seu estándar, Cissa, como dixen antes,
se quería mirar para este estándar, entón ía fallar no caso
porque iso non é realmente unha palabra, pero unha das palabras no dicionario pasa de ter que nel.
Polo tanto, sería combinar esa palabra, pero este subconxunto da palabra non é unha palabra en si.
Pero non é así que estamos a usalo, estamos lendo cada palabra
e despois comparando a palabra que temos con esa palabra.
Entón, nós estamos sempre comparando palabras completas.
Podo enviar as solucións finalizados despois.
Este é o tipo de case a resposta correcta, eu creo.
[Comentario do estudante, inintelixible]
Ah, eu se librar do que antes? Char s, creo que dixo 127 - eu esquezo o que o maior é.
Nós imos só facer 128; agora s é o tempo suficiente.
Non precisa imprimir nada.
Tamén imos querer ter que pechar o seu arquivo, e que debe ser sobre a resposta correcta.
CS50.TV