[Powered by Google Translate] Sectie Probleem Set 2: Hacker Edition Rob Bowden, Harvard University Dit is CS50. CS50.TV Dus, ik ben Rob. Ik ben een senior in Kirkland. Dit is mijn derde jaar TFing CS50. Het is de eerste keer dat we veranderen van de traditionele-lezing-style sectie, waar we gewoon een soort van beoordeling wat er in collegezalen en dan jullie vragen te stellen, nu het feit dat veel meer probleemgestuurd, waarbij we gebruik maken van Spaces, en - Oh, dus het idee is om naar die link die ik je gestuurd en dan zul je in mijn Space. Heeft iemand niet beschikt over een laptop? Oke. Dus we gaan gebruiken dit, en we gaan moeten doen problemen wonen in paragraaf en te bespreken en uit te zoeken wat er mis is en ik kan trek een deel van je code, en ik zou bespreek uw ideeën. Dus heeft iemand had moeite? U kunt chatten aan de kant, ik weet niet of we reden voor hebben. Nu, net als de vorige supersection, als je in die klasse, weet je wat dat over gaat. Op alle van P sets er gaat worden deze secties. Dus P-set 2, specificaties, ik denk dat je zag het al op de P-set 1. Maar we kunnen kijken naar P-set 2 voor wat we gaan te gaan over vandaag. En zie je een deel van de vragen. Dus zal dit in alle P-sets, er zal een deel van zijn vragen. Tot nu toe hebben we gezegd: "Beschouw dit als een kans om te oefenen." U wordt niet gevraagd om dit programma in te dienen. Het idee is dat deze worden verondersteld soort hulp die u aan de slag met het probleem set. Ik denk dat op de Hacker editie, zijn veel van hen zou gewoon nieuwe, interessante dingen te leren. Zij mogen niet rechtstreeks op het probleem set. En op dit moment zijn we niet met u stellen door, maar in theorie, voor later probleem sets, kunt u deze voorleggen, en daarom kun je ofwel komen in hoofdstuk of kijken naar de sectie om de antwoorden te krijgen, of je kunt ze gewoon te krijgen op je eigen als je geen zin hebt om te genieten van mijn aanwezigheid. Dus de - Ik denk dat dit de eerste. Oh. Ook onder deze secties van vragen die wij ook hebben jullie vragen stellen over de korte broek. Dus ik denk dat, in theorie, je moet om deze te bekijken voordat ik naar sectie maar het is fijn als je dat niet doet, zullen we toch te gaan over hen. Dus we kunnen beginnen met deze: "Hoe kan een while-lus verschillen van een do-while-lus? Wanneer is deze bijzonder nuttig? " Dus iemand enig -? [Student] De do-while-lus zal altijd uit te voeren ten minste een keer. Ja. Zodat het verschil. Een while-lus - Ik zal doen het gewoon hier te bekijken - maar loop, wij hebben de aandoening hier, terwijl een do-while, u niet beschikt over een aandoening totdat we hier beneden. En ja, wanneer je programma's uitvoeren, en het wordt aan de while-lus, controleert onmiddellijk als deze voorwaarde waar is. Indien aan deze voorwaarde niet waar is, zal het gewoon overslaan de lus volledig. Do-while-lus, als het programma wordt uitgevoerd, wordt het naar de "te doen." Er gebeurt niets op dit punt, maar verder wordt uitgevoerd. Toen het de "tijd" raakt als de voorwaarde waar is, zal het back-loop en het opnieuw doen en opnieuw en opnieuw totdat de conditie niet waar is en dan gewoon niet doorgaat. Dus, het verschil is, dat dit recht kan overslaan vanaf het allereerste begin. Deze voert noodzakelijkerwijs een keer en dan kan uitvoeren keer als de voorwaarde is nog steeds waar. Dus de while-lus zal maar een keer doen, of - de while-lus - we misschien niet nodig om het te doen op alle, omdat zodra we in te gaan als de voorwaarde onwaar is, zullen we precies goed negeren. Overwegende dat de do-while-lus, zullen we een keer voer het uit, per se. Dan, als we aan de voorwaarde, controleren we of het waar of onwaar is. Als het waar is, zullen we nog een keer doen, maar als het is vals, we zullen gewoon blijven gaan. Dus wanneer is de laatste vooral nuttig? Dus ik kan zeggen dat in het geheel van de 4 jaar, 3 jaar, wat dan ook, dat ik heb het programmeren, heb ik gebruik gemaakt van deze, zoals, onder 10 keer. En waarschijnlijk 5 van hen zijn in CS50 toen introduceren we do-while loops. Dus wanneer ga je gebruikt do-while loops? Wanneer is het - ja? [Student] Als je probeert om invoer van de gebruiker, of iets wat je wilt controleren te krijgen - Ja. Dus do-while loops, input van de gebruiker is de grote. Dat is de reden waarom op de eerste paar probleem sets, wanneer u de gebruiker wilt vragen, zoals, "Geef me een string," je kan niet doorgaan tot je die string. En dus, per definitie, moet om de string ten minste een keer. Maar dan, als ze antwoorden iets slechts, dan moet je loop terug en vraag het opnieuw. Maar anders dan input van de gebruiker, is het zeer zeldzaam dat ik geconfronteerd met een geval waar ik wil lus "ten minste een keer", maar mogelijk meer. Vragen of -? Heeft iemand een do-while-lus ergens anders gebruikt? Oke. Dus de volgende is: "Wat betekent zwartwerk identificatie meestal aangeven of uitgevoerd door clang? " Dus wat voor soort code kon ik schrijf om 'zwart identifier?' [Student] Dat x = 2? Dus we kunnen het uit te proberen hier, x = 2. We zullen het uitvoeren van deze - oh, ik heb niet op klikken. Dus hier krijgen we - in orde. "Gebruik van niet-aangegeven identifier x." Dus dat is de zwart identifier, een variabele. Het zal vaak belt een variabele een identifier. Dus is het misschien niet weet dat het eigenlijk een variabele, maar weet niet wat het is. Dus het is een identifier. Dus waarom is het zwartwerk? Ja. Dus om duidelijk te zijn over de terminologie, de verklaring van een variabele is als je zegt "int x," of "string y," wat dan ook. De initialisatie van de variabele of de toewijzing van de variabele is wanneer je zegt "x = 2." Dus we kunnen deze doen in afzonderlijke stappen, int x, x = 2, en tot - kunnen we een heleboel dingen hebben hier - maar tot deze lijn gebeurt, is nog steeds x geïnitialiseerde, maar het is verklaard. En dus kunnen we natuurlijk doen in 1 lijn, en nu zijn we verklaren en initialiseren. Vragen? En tenslotte: "Waarom is de Caesar Cipher niet erg veilig? ' Dus eerst, wil iemand zeggen wat de Caesar Cipher is? [Student] Caesar Cipher precies is dat je in kaart, schuift u elke letter, een aantal brieven gaan over, en ga terug over, en het is niet erg veilig, omdat er is slechts 26 mogelijke opties en je moet gewoon om elk 1 proberen van die tot je het. Oh. Dus, moet ik herhalen? De Caesar Cipher, het is - ik bedoel, dan heb je te maken met het op de problemen die je - of ik denk dat de standaard editie van het probleem set die is niet op de hacker editie. Dus op de standaard editie van het probleem set, krijg je een melding als: "Hallo, wereld," en je hebt ook een nummer als 6, en je neemt die boodschap, en elk individueel karakter, u de foto roteren met 6 posities in het alfabet. De 'h' in hello zou worden h-i-j-k-l-m-n. Dus de eerste letter zou zijn n. We doen hetzelfde met e. Als we een, zoals, z of iets, dan gaan we achterom wikkelen naar 'een.' Maar elk karakter krijgt gefietst 6 tekens later in het alfabet, en het is niet erg veilig omdat er slechts 26 mogelijkheden voor hoeveel manieren kun je een letter te wikkelen. Dus je kunt gewoon proberen alle 26 van hen en, vermoedelijk, voor een lang genoeg bericht, slechts 1 van die mogelijke 26 dingen gaat worden leesbaar, en de leesbare men gaat het oorspronkelijke bericht. Dus het is niet een zeer goede manier van coderen helemaal niets. Niets te maken met die korte broek, "Wat is een functie?" Dus wat is een functie? Ja. [Student] Het is als een apart stuk code die u kunt bellen om te gaan door en dan de return waarde van wat dan ook te krijgen. Ja. Dus ik zal beantwoorden door ook het beantwoorden van de volgende - of herhalen door ook gewoon het beantwoorden van de volgende. U kunt gebruik maken van functies in plaats van alleen kopiëren en plakken code over en weer. Neem de code, zet het in een fuction, en dan kon je gewoon bellen met de functie waar u ook zijn kopiëren en plakken. Dus zijn nuttig. Dus nu doen we de werkelijke problemen. De eerste. Dus het idee van de eerste is, passeert u het een string, en ongeacht de - of staat er allemaal kleine letters? Er staat niet dat alle kleine letters. Dus de boodschap kan van alles zijn, en - oh nee. Het doet. "Voor de eenvoud, kunt u ervan uitgaan dat de gebruiker zal alleen invoeren kleine letters en spaties." Dus geven we het een bericht met alleen kleine letters en dan gaan we afwisselen tussen hoofdletters en kleine - we veranderen de string aan het kapitaal en kleine letters, afgewisseld. Dus voordat we geven u een tweede om zelfs een duik in het probleem, wat is het eerste wat we moeten doen? O, wat heb ik net op? Oh, ik klikte op een e-mail hier. Dus het eerste wat we moeten doen - kijk ik naar de verkeerde? Is dit deel van deze? Nee, dat zijn er nog steeds in, dat wel. Oke, er nog steeds. Nu kunnen we er niet van uitgaan -? Ja. Hier kunnen we niet aannemen dat het alleen kleine letters en spaties. Dus nu hebben we te maken met het feit dat de letters kan zijn wat we willen dat ze zijn. En dus het eerste wat we willen doen is gewoon de boodschap. We moeten alleen een string te krijgen, string s = GetString, oke. Nu dit probleem, er zijn een paar manieren om het te doen. Maar we gaan hier wilt gebruiken bitwise operators. Zijn er mensen die ofwel niet waren op de supersection, of iets, en niet weet wat bitwise operators zijn? Of hoe zij betrekking hebben op ASCII of andere manier? [Student] Ik was niet op de supersection, maar ik weet wat bitwise operatoren zijn. Oke. Dus dan heb ik niet te gaan over de basis van hen, maar ik zal het uitleggen wat we gaan hier willen gebruiken. Dus 'A': binaire representatie van het kapitaal A, het nummer 65. Ik ga gewoon om naar te kijken - 41 gaat worden 01000001. Dus dat zou moeten zijn 65 in decimaal, dus dit is de binaire representatie van het personage kapitaal A. Nu de binaire representatie van het teken kleine letter 'a' gaat om het zelfde ding bijna zijn,. Is dat - 6, ja. Dit is gelijk. Dus binaire hoofdletter A, binaire kleine letter 'a'. Dus merken dat het verschil tussen de A en 'een' is dit enkele bit. En dit gebeurt als de 32 bit, het bit die het nummer 32. En dat is logisch, omdat A is 65 jaar; 'a' is 97. Het verschil tussen hen is 32. Dus nu we weten dat we kunnen van A naar 'een' te zetten door het nemen van een en bitwise ORing het, met - dat lijkt op een 1. Dit is een bitwise OR, met 00100000, en dat zal ons 'een.' En we kunnen krijgen van 'een' naar A door bitwise Anding met 11, 0 in die plaats, 11111. Dus dit zal dan geeft ons precies wat 'a' was, maar heffen deze persoon bit, dus we moeten 01000001, ik weet niet of ik telde rechts. Maar deze techniek van bitsgewijze Oring om van het kapitaal naar kleine letters, en bitwise Anding om van kleine letters tot kapitaal is niet exclusief voor A. Alle letters, K vs k, Z vs z, alle van hen zijn gewoon gaan verschillen door deze enkele bit. En dus je kunt dit gebruiken om vanaf een kleine letter veranderen in een hoofdletter en vice versa. Oke. Dus een makkelijke manier om van deze - dus in plaats van te schrijven wat 1011111 is - een gemakkelijke manier te vertegenwoordigen dit nummer, en dit is niet een dat ik ging in de supersection, maar tilde (~) is een andere logische bewerking. Wat ~ doet is het ziet er op de bit-representatie. Laten we een willekeurig aantal. Dit is slechts een binair getal, en welke ~ doet is het gewoon draait alle bits. Dus dit was een 1, een 0 nu is dit een 0 nu een 1, 010,100. Dus dat is allemaal ~ doet. Dus 32 is zal het nummer zijn - ontdoen van die te krijgen - dus 32 gaat het nummer 00100000, enzovoort ~ deze zal worden dit nummer hier dat ik 'a' ge-AND met. Heeft iedereen dat? Dit is vrij normaal, zoals wanneer je wilt uitzoeken voor later dingen die we zouden kunnen zien, wanneer we willen zien of - of we willen alles, elke bit set met uitzondering van 1 je de neiging om te doen ~ van het beetje dat we niet willen stellen. Dus we niet de 32 bit set willen, dus we hoeven ~ van 32. Oke. Dus we kunnen hier gebruik maken van al die. Oke, dus het is prima als je nog niet klaar, we langzaam zullen samen lopen over, of lopen over dit, dus - via deze. Loop door deze. Dus we hebben onze string, en we willen lus over elk teken in die string en iets doen om het. Dus hoe kunnen we lus over een string? Wat moeten we gebruiken? Ik ben niet van plan om het te doen hier. Ja. Dus ik heb mijn iterator, en hij zei, maar hoe weet ik hoeveel tekens zijn in de string? Strlen (s) en i + +. Dus wat ik hier heb gedaan is niet de beste manier om dingen te doen. Weet iemand waarom? Omdat je het controleren van de taal van de snaar elke keer weer. Dus we gaan willen strlen bewegen, ik kon hier zeggen op, int lengte = strlen (s), en dan krijg ik > 1 bit. Het kan meer dan een beetje, zolang alle bits boven dit punt zijn hetzelfde. Dus we moeten ten minste 26 tekens - of, zijn er 26 tekens. Dus we moeten ten minste 26 nummers om het verschil te vertegenwoordigen - Het verschil tussen A en A moet ten minste 26, of anders zouden we niet hebben vertegenwoordigd alle hoofdstad nummers. Dat betekent dat A wanneer we beginnen bij 1, het zal al deze bits te gebruiken, al deze eerste 5 bits, om alles te vertegenwoordigen tot en met Z. Dat is de reden waarom de volgende bit, of deze bit, de volgende bits is degene die is gekozen om onderscheid te maken tussen A en 'een.' Dat is ook de reden waarom, in ASCII-tabel, zijn er 5 symbolen te scheiden hoofdletters van kleine letters. Daar zijn de symbolen, de extra 5 dat brengt de 32 zijnde het verschil tussen hen. [Student] Dus we konden doen, omdat ASCII is ontworpen op die manier. Ja. Maar ASCII - het verschil kan ook beide bits. Zoals, als A waren 10000001, en 'een' was 11100001 - ik het vergeet, wat dan ook. Maar als het dit, dan kunnen we nog steeds gebruik maken van 'a' - A. Het is gewoon nu het verschil tussen A en 'a' is nog steeds deze 2 bits. Ik denk dat het 48 geschreven. Is het 32 ​​+ 64? Ik denk dat het is? Het zou nog 2 bits; elke letter, zoals, Z en Z, K en k, zouden ze nog steeds exact dezelfde bits ingesteld met uitzondering van de 2 bits. Dus zolang die altijd waar is, ongeacht of we met behulp van ASCII of een ander systeem, zolang er slechts een bepaald aantal bits die verschillend zijn voor elk teken, dan is dat werkt prima. Het is gewoon dat 32 is opgezet, want het is de eerste die we zouden kunnen gebruiken. >> Cool. Ik ben geneigd de voorkeur te geven, voor het geval je dat nog niet gezien, als het blok is slechts een enkele lijn, je kunt ontdoen van de accolades, dus ik de neiging om de voorkeur om dit te doen. Ook, je weet hoe we dingen doen zoals s [i] + = 1? U kunt ook s [i] bitwise AND = 32. En bitwise OR = 32. Ook tellen mod 2 == 0. Dus denk eraan dat - ik zal niet schrijven - elke niet-nul waarde true is, en 0 is onwaar. Dus "indien count mod 2 == 0" is hetzelfde als zeggen "als deze niet meetellen mod 2." Ik zou waarschijnlijk net omgekeerd de lijnen en zei: "Als count mod 2, anders komen de OF 1, zijn de EN 1, "zodat ik geen behoefte aan de" niet. " Maar dit werkt net zo goed. En wat kan ik hier doen? Je zou kunnen combineren ze met ternaire als je wilde, maar dan is dat net had om dingen messier en waarschijnlijk moeilijker te lezen, dus we zullen dat niet doen. Iemand nog andere suggesties? Is dat alles wat het probleem gevraagd? Oh yeah. Dus ontdoen van deze lege regels, nu wij drukken f,% s, zijnde het voor strijkers, Wij drukken f, s. Laten we nu uitvoeren. Heb ik iets verkeerd? Dat is een \ "; Ik wil een n. Oke. Nu gaan we draaien. Het zal waarschijnlijk tegen me schreeuwen. Strlen in string.h. Dus dit is het leuke van Clang is het vertelt je hoe het is in, in plaats van GCC die gewoon zegt: "He, je iets vergeten, ik weet niet wat het was." Maar dit zal mij vertellen, "Je bedoeld string.h op te nemen." Dus ik heb niet gevraagd voor iets, dus het is niet iets te zeggen. Maar we zullen doen hun voorbeeld, "Thanks 4 the add". Dat ziet er goed uit. Hooray. Dus terug te keren naar uw belangrijkste, ik bijna nooit doen. Het is optioneel. En de belangrijkste is de enige functie waarvoor het is optioneel. Als je niet iets terug van de belangrijkste, is ervan uitgegaan dat je bedoelde op 0 terug te keren. Vragen? Oke. Dus nu het tweede probleem. "Recall uit de tweede week 2 van de lezing die ruilt 2 variabelen 'waarden door het passeren van die 2 variabelen om een ​​functie (ook al genoemd swap) niet precies, werken in ieder geval niet zonder 'pointers'. " En negeer pointers tot we bij hen. We willen 2 variabelen wisselen, we zijn niet met behulp van een functie om het te doen. We zijn nog steeds gaan om het te doen in de belangrijkste, zoals het zegt. Maar om die 2 variabelen gebruiken, we willen niet naar een tijdelijke variabele te gebruiken. Er zijn 2 manieren om dit te doen. U kunt dit doen met behulp van uw traditionele binaire operatoren. Dus weet iemand een snelle en vuile manier om dat te doen? Het zou eigenlijk een minuut van denken. Als ik - Ik zet het probleem op als ze vragen. Dus als ik 2 variabelen hebben, Een, dat is gewoon een geheel getal dat ze mij geven, en som variabele B, dat is een ander geheel getal dat ik gegeven. Dus als ik deze 2 variabelen, nu wil ik om ze te verwisselen. De traditionele, met behulp van uw reguliere binaire operatoren, ik bedoel, zoals +, -, ÷. Niet bitwise operatoren die inwerken op binair. Dus met behulp van -, +, ÷, en al die. We konden wisselen door het doen van iets als a = a + b en b = a - b, a = a - b. Dus, geestelijke gezondheid controleren, en dan zien we wel hoe dat werkt. Stel dat a = 7, b = 3, a + b dan gaat worden 10. Dus we nu het instellen van een = 10, en dan doen we b = a - b. Dus we doen b = a - b, die zal worden 7 en b = a - b weer, of a = a - b. Die zal: 10 - 7, dat is 3. Dus nu, terecht, 'a' was 7, b was 3, en nu b is 7 en "a" 3. Dat soort zinvol, 'a' is de combinatie van de 2 getallen. Op dit punt, 'a' is de combinatie, en dan zijn we af te trekken van de oorspronkelijke b, en dan gaan we aftrekken van wat was de oorspronkelijke 'een.' Maar dit werkt niet voor alle nummers. Om dit te zien, laten we eens kijken een systeem, dus denken we meestal van gehele getallen als 32 bits. Laten we werken aan iets dat is nog maar net 4 bits. Hopelijk heb ik komen met een goed voorbeeld op dit moment. Dus, ik weet het, dit gemakkelijk zal zijn. Laten we zeggen dat onze 2 nummers zijn 1111, en 1111, dus we zijn in binaire nu. In werkelijkheid decimalen, als je wilt om te denken van het op die manier, a = 15 en b = 15. En dus verwachten we, nadat we ruilen - ze niet eens te zijn dezelfde nummers, maar ik heb het op deze manier. Laten we hen niet dezelfde nummers. Laten we 1111 en 0001. Dus a = 15 en b = 1. Nadat we ruilen ze, verwachten we dat 'een' te zijn 1 en b te zijn 15. Dus onze eerste stap is a = a + b. De cijfers zijn slechts 4 bits breed, zodat 'een', dat is 1111, + b, die 0001, gaat uiteindelijk op een 10000, maar we hebben maar 4 bits. Dus nu a = 0. En nu willen we het b = a - b - in feite, nog steeds dit werkt perfect. a = a - b - laten we eens kijken of dit werkt perfect. Dus dan b = 0 - 1, wat nog steeds 15 en a = a - b, die zou zijn 1. Misschien werkt dit wel. Ik heb het gevoel alsof er een reden waarom het niet werkt met behulp van reguliere. Oke, dus het werken in de veronderstelling dat het niet werkt met gewone binaire operaties, en ik zal kijken voor - ik zal Google om te zien of dat waar is. Dus we willen doen met behulp van bitwise operators, en het idee is hier XOR. Dus, de invoering van XOR (^) als je het nog niet gezien. Het is, nogmaals, een logische bewerking dus het werkt beetje bij beetje, en het is - Als je de bits 0 en 1, dan zal dit 1. Als je de bits 1 en 0, het zal 1, heb je de bits 0 en 0 het zal 0, en als je de bits 1 en 1 hebben het zal 0. Dus het is alsof OR. Als een van de bits waar is, is 1, maar in tegenstelling OR, het kan niet beide bits die waar. Of zou dit hebben op 1, zou XOR hebben dit 0 zijn. Dus we gaan hier willen gebruiken XOR. Denk er eens over voor een minuut, ik ga naar Google. Nou, je kunt niet lezen dat, ik ben momenteel op de XOR swap algoritme pagina. Hopelijk zal dit uitleggen waarom Ik kan niet - Dit is precies het algoritme dat we net gedaan. Ik snap nog steeds niet waarom - ik moet gewoon hebben gekozen voor een slecht voorbeeld, maar dit geval waarin a toevallig worden 0, na verkrijgen van 5 bits, zodat nu 'a' is 0, dat is wat wordt genoemd "integer overflow". Volgens Wikipedia, "In tegenstelling tot de XOR swap, deze variatie vereist dat het aantal methoden gebruikt te waarborgen dat x + y geen geheel getal overflow veroorzaken. " Dus dit heeft wel problemen, dit was integer overflow, maar ik deed iets verkeerd. Ik weet het niet zeker. Ik zal proberen om te komen met een ander. [Student] Nou, is niet integer overflow wanneer je probeert om een ​​nummer in daar te zetten groter dan de hoeveelheid bits die u hebt toegewezen? Ja. We hebben 4 bits. Dat is - we hadden 4 bits, dan proberen we tot en met 1 toe te voegen, zodat we uiteindelijk met 5 bits. Maar de vijfde bit net wordt afgesneden, ja. Het zou kunnen eigenlijk - [Student] Maakt dat gooi je een fout, of is dat - zou dat een fout optreedt? Nee Dus er is geen fout. Als je bij de montage-niveau, een bijzonder stukje ergens is ingesteld dat zei dat er een overloop, maar in C je soort van gewoon niet omgaan met dat. Je kan eigenlijk niet mee omgaan, tenzij u gebruik maken van speciale montage-instructies in C. Laten we eens nadenken over XOR swap. En ik denk dat het Wikipedia artikel kan ook zijn te zeggen dat - Dus het bracht ook modulaire rekenkunde, dus ik denk dat ik was, in theorie, het doen van modulaire rekenkunde toen ik zei dat 0 - 1 is weer 15. Dus dat in feite zou kunnen - op een regelmatige processor die 0 doet - 1 = 15. Aangezien we eindigen op 0, trekken we 1, dus dan is het wraps gewoon terug rond om 1111. Dus dit algoritme zou eigenlijk de a + b, de a - b, b - a; mogelijk goed. Maar er is een aantal processoren die geen doen, en dus het zou niet goed zijn in die specifieke. XOR swap zal werken op een processor. Oke. Het idee is dat het zou moeten zijn hetzelfde, hoewel. Waar maken we gebruik van XOR om de informatie van zowel een of andere manier te krijgen in een van de variabelen, en trek vervolgens de gegevens van de individuele variabelen weer. Dus heeft iemand nog ideeën / het antwoord? [Student antwoord, onverstaanbaar] Dus dit zou moeten werken, en ook, XOR is commutatief. Ongeacht welke volgorde deze 2 nummers toevallig in hier, dit resultaat zal hetzelfde. Dus een ^ b is b ^ a. U kunt ook zien geschreven als een ^ = b, b ^ = a, a ^ = b opnieuw. Dus dit is recht, en te zien waarom dit werkt, denk aan de bits. Met behulp van een vrij kleine aantal, laten we zeggen 11001, en 01100. Dus dit is 'a', dit is b. Dus een ^ = b. We gaan worden het instellen van "a" = de XOR van deze 2 dingen. Dus 1 ^ 0 is 1, 1 ^ 1 0, 0 ^ 1 1 en 0 ^ 0 is 0, 1 ^ 0 1. Dus 'een,' als je kijkt naar het decimale getal, het gaat om - je bent niet van plan om veel van een relatie tussen de oorspronkelijke 'a' en de nieuwe zie 'a,' maar gezien de bits, 'a' is nu als een mesh van de informatie van zowel de oorspronkelijke 'a' en de oorspronkelijke b. Dus als we b ^ een, zien we dat we uiteindelijk op de oorspronkelijke 'een.' En als we de oorspronkelijke 'a' ^ de nieuwe 'a,' zien we belanden we op de oorspronkelijke b. Dus (a ^ b) ^ b = de oorspronkelijke 'een.' En (a ^ b) ^ a = de oorspronkelijke b. Er is - een andere manier van kijken is dit iets XOR zelf is altijd 0. Dus 1101 ^ 1101, worden alle bits naar hetzelfde. Er zal nooit een geval waarin 1 een 0 en de andere is 1 zijn. Dus dit is 0000. Hetzelfde met dit. (A ^ b) ^ b is als een ^ (b ^ b). (B ^ b) gaat als: 0; a ^ 0 wordt alleen maar als 'een', omdat alle bits 0 zijn. Dus de enigen die zullen worden waar 'een' was oorspronkelijk een 1 - hadden degenen. En hetzelfde idee hier, ik ben er vrij zeker van dat het ook commutatief is. Ja. Ik heb zeggen voordat dat het commutatieve was. De ^ 'a,' en het is associatief, dus nu (b ^ a) ^ a. En we kunnen doen b ^ (a ^ a). En dus nogmaals, we krijgen de oorspronkelijke b. Dus 'a' is nu de combinatie van 'a' en b samen. Met behulp van onze nieuwe combo 'a' zeggen we b = combo 'a' ^ de oorspronkelijke b, krijgen we de oorspronkelijke 'een.' En nu a = combo 'a' ^ de nieuwe b, dat was de oorspronkelijke - of die nu wat was 'a' of b. Dat is dit geval hier beneden. Dit is = b, oud b. Dus nu is alles weer in de geruilde volgorde. Als we echt gekeken naar de bits, b = a ^ b, gaat deze 2 XOR, en het antwoord zal zijn dit, en dan a = a ^ b is logische XOF-schakeling deze 2 en het antwoord is dit. Vragen? Oke. Dus de laatste is wat aanzienlijk moeilijker. [Student] Ik denk dat hij een vraag over het. >> Oh, sorry. [Student] Wat is eigenlijk sneller? Als u deze XOR is, of is het als declareer je een nieuwe variabele? Dus wat is eigenlijk sneller, waarbij een nieuwe variabele of met behulp van XOR om te ruilen? Het antwoord is, naar alle waarschijnlijkheid, een tijdelijke variabele. En dat komt omdat als het eenmaal is gecompileerd naar beneden - dus op de montage-niveau, er is niet zoiets als lokale variabelen of een tijdelijke variabelen of voor een van deze spullen. Ze zijn net als - er is geheugen, en er zijn registers. Registers zijn waar dingen worden actief gebeuren. Je hoeft niet toe te voegen 2 dingen in het geheugen, je toe te voegen 2 dingen in de registers. En breng je dingen uit het geheugen in de registers om vervolgens toe te voegen, en dan kun je ze terug in het geheugen, maar alle actie gebeurt in de registers. Dus als je de tijdelijke variabele benadering met behulp van, meestal wat er gebeurt is deze 2 nummers zijn al in registers. En dan vanaf dat moment, nadat je ze verwisseld, het zal gewoon beginnen met de andere register. Overal waar je was met b, zal het gewoon gebruik maken van het register, dat al was het opslaan van 'een.' Het maakt dus niet nodig om iets daadwerkelijk doen de swap te doen. Ja? [Student] Maar er is ook meer geheugen, toch? Het duurt maar meer geheugen als het nodig heeft om op te slaan die tijdelijke variabele. Net als je later weer kunt gebruiken die tijdelijke variabele ergens, dan - of u toewijst iets in die tijdelijke variabele. Dus als op enig moment in de tijd 'a,' b in temp hebben verschillende waarden of iets, dan dat het gaat om verschillende locaties hebben in het geheugen, maar het is waar dat er zijn veel lokale variabelen die alleen bestaan ​​in registers. In dat geval, is het nooit in het geheugen, en dus je bent nooit verspilt geheugen. Oke. Laatste vraag is een beetje meer. Hier, in deze CS50 apparaat is een woordenboek. En de reden hiervoor is omdat [? B66] is een spellingscontrole waar je het schrijven van met behulp van hash tabellen of pogingen of een datastructuur. Je gaat te schrijven van een spellingcontrole, en je gaat worden met behulp van dit woordenboek om dat te doen. Maar voor dit probleem, zijn we gewoon gaan kijken om te zien of een enkel woord in het woordenboek. In plaats van opslag van de gehele woordenboek een datastructuur en dan kijken over een volledig document om te zien of er iets is verkeerd gespeld, we willen gewoon een woord te vinden. Dus we kunnen gewoon te scannen via het hele woordenboek en als we nooit vinden het woord in het hele woordenboek, dan was het er niet in. Als we scannen over het gehele woordenboek en er het woord te zien, dan zijn we goed zijn, we vonden het. Er staat hier dat we willen gaan kijken naar C's file-handling-functie, want we willen het woordenboek lezen, maar ik zal de hint hier aan welke taken u moet bedenken. Ik schrijf ze op Spaces. Dus de belangrijkste die je zult willen kijken naar zijn f open en dan, onvermijdelijk, f gesloten, die zal gaan aan het eind van uw programma, en f scan f. U kunt ook gebruik maken van f lezen, maar je waarschijnlijk niet wilt want dat - je uiteindelijk niet nodig dat. F scan f is wat je gaat om te worden gebruikt om te scannen via het woordenboek. En zodat u niet hoeft te coderen de oplossing, gewoon proberen en als pseudo-code uw manier om een ​​oplossing, en dan zullen we bespreken. En eigenlijk, aangezien ik al gaf je deze, als je in een terminal of uw toestel shell, Ik zou - ik meestal - als je nog niet hebt gezien, ik weet niet als je dat deed in de klas, maar de mens, zodat de man pagina's, zijn vrij nuttig om naar te kijken vrijwel elke functie. Dus ik kan doen, zoals, man f-, scan-f. Dit is nu de informatie over de scan f familie van functies. Ik kon ook doen man f, open, en dat geeft me de details van dat. Dus als je weet wat functie die u gebruikt, of u leest code en je ziet een functie en je net als, 'Wat heeft dit te doen? " Rechtvaardig man die functie naam. Er zijn een paar rare voorbeelden waar je zou kunnen hebben om te zeggen wilt. man 2 die functie naam of man 3 die functie naam, maar u hoeft te doen dat als de mens de functie naam niet toevallig de eerste keer werken. [Student] Dus ik ben het lezen van de man pagina voor open, maar ik ben nog steeds verward over hoe het en het programma te gebruiken. Oke. Een groot deel van de man-pagina's zijn minder dan nuttig. Ze zijn meer handig als je al weet wat ze doen en dan hoeft u alleen maar de volgorde van de argumenten of iets te herinneren. Of ze kunnen geven u een algemeen overzicht, maar sommige van hen zijn zeer overweldigend. Net als f scan f, ook. Het geeft je de informatie voor al deze functies, en 1 regel hier beneden gebeurt zeggen, "F scan f leest van de string punt of stroom." Maar f te openen. Dus, hoe zouden we f open? Het idee van een programma dat moet doen file I / O, is dat moet u eerst het bestand dat u wilt om dingen te doen met te openen, en onvermijdelijk, lees dingen van dat bestand en dingen doen met hen. F geopend is wat we gebruiken om het bestand te openen. Het ding we terug, dus wat bestand willen we openen, het geeft ons de - hier het zegt "/ user / share / dict / words." Dit is het bestand dat we willen openen, en we willen om het te openen - moeten we expliciet aangeven of we willen openen om te lezen of als we willen openen om te schrijven. Er zijn een paar combinaties en zo, maar we willen dit openen om te lezen. We willen lezen uit het bestand. Dus wat doet deze terugkeer? Het geeft een bestand ster (*), en Ik zal gewoon alles laten zien in de variabele f, dus *, nogmaals, het is een pointer, maar we willen niet om te gaan met pointers. U kunt denken aan f als, f nu is de variabele die u gaat gebruiken om het bestand te vertegenwoordigen. Dus als je wilt lezen uit het bestand, je leest van f. Als u het bestand wilt sluiten, sluit u f. Dus aan het einde van het programma wanneer we onvermijdelijk het bestand wilt sluiten, wat moeten we doen? We willen f sluiten. Dus nu het laatste bestand functie die we gaan wilt gebruiken, is scannen f, f scan f. En wat dat doet is het scant over het bestand op zoek naar een patroon aan te passen. Kijkend naar de man pagina hier, we int f scan f te zien, negeer de return waarde voor nu. Het eerste argument is het bestand * stroom, zodat het eerste argument gaan we langs wilt komen is f. We scannen via f. Het tweede argument is een format string. Ik zal u een format string nu. Ik denk dat we toevallig om te zeggen, 127S \ n, veel van dat is onnodig. Het idee van wat dat format string is, is dat je kunt van scan f denken als het tegenovergestelde van print f. Dus printen f, printen f we ook gebruik maken van dit type parameter format, maar in print f wat we doen is - laten we eens kijken naar een equivalent. Zo af te drukken f, en er is eigenlijk ook f afdruk f, waarbij het eerste argument gaat worden f. Wanneer u afdrukt f, kunnen we iets zeggen als, "print 127S \ n" en dan als we doorgeven stukje tekst, het gaat om deze string en vervolgens een nieuwe lijn af te drukken. Wat 127 betekent, ik ben er vrij zeker van, maar ik heb nog nooit me beperkt tot het, Je zou het niet eens nodig om '127 'te zeggen in de print f, maar wat het betekent is printen we het eerste 127 tekens. Dus ik ben er vrij zeker van dat het geval is. U kunt Google voor. Maar in de volgende ben ik bijna zeker betekent dit dat. Dus dit is af te drukken de eerste 127 tekens, gevolgd door een nieuwe regel. F scan f nu, in plaats van te kijken naar een variabele en deze af te drukken, het gaat om te kijken naar een stukje tekst, en het patroon in de variabele op te slaan. Laten we eigenlijk scan f gebruiken in een ander voorbeeld. Dus laten we zeggen dat we hadden een paar int, x = 4, en we wilden een string gemaakt van te maken - wilde de tekenreeks te maken dat was als, dit zal komen veel later, iets dat is net als 4.jpg. Dus dit zou een programma waar je totaal teller te hebben, Samengevat tegen te gaan i, en u wilt een bos van beelden op te slaan. Dus je wilt i.jpg, waarbij i een aantal iteratie van je loop op te slaan. Dus hoe maken we deze string voor die JPEG? Als je wilde om af te drukken 4.jpg, kunnen we alleen maar zeggen afdruk f,% d.jpg, en dan zou het af te drukken voor die JPEG. Maar als we willen de string 4.jpg opslaan, gebruiken we scan f. Dus string s - in feite hebben we KAN NIET - karakter, char s, laten we gaan 100. Dus ik verklaarde enkele array van 100 tekens, en dat is wat we onvermijdelijk gaat worden het opslaan van die JPEG-inch Dus we gaan scannen f te gebruiken, en het formaat, hoe we zouden% d.jpg zeggen met het oog op 4.jpg af te drukken, wordt het formaat van dit gaat% d.jpg zijn. Dus het formaat% d.jpg, wat we willen% d vervangen door x is, en nu moeten we die string ergens op te slaan. En waar gaan we deze string op te slaan is in de array s. Dus na deze regel code, s, als we drukken f,% s van de variabele s, het gaat om 4.jpg af te drukken. Dus f scan f is hetzelfde als scan f, behalve nu is het uitzicht over dit bestand voor wat te slaan in s. Dat is wat de laatste argument gaat worden. We willen slaan - "Scan f familie van functies scans in zowel volgens de indeling zoals hieronder geprobeerd. Als er worden opgeslagen in de locatie punten die u zou kunnen terugkeren - " Nee, kunnen we goed zijn. Laat me denken voor een tweede. Dus scan f niet - wat de heck is de functie die dat doet? Dus scan f is niet van plan om een ​​geheel getal te nemen en dot jpg doen. Het gaat om [Mumbles]. Sla int variabele in string int C. Wat is deze variabele, of wat is deze functie genoemd? Ja. Dat is - ja. Dus wat ik het definiëren van je eerder was s afdrukken f, die - dat er veel meer verstand, waarom ik zei dat het nog veel meer, zoals print f maakt. Scan f is nog steeds een soort afdruk f, maar print van f gaat om het te scannen via en vervang de variabelen en nu is het op te slaan in een string. Plaats van deze, slaat in een string. Dus negeren die volledig. U kunt nog steeds denken aan het formaat specifier als op dat van gedrukte f. Dus nu, als we wilden de 4.jpg ding te doen, zouden we dat doen is druk f, x van deze. Dus wat scan f doet - wat uw vraag gaat worden? [Student] Ik ben gewoon in de war over wat we proberen om hier te doen met die JPEG. Kunt u uitleggen dat nog 1 keer? Dus dit was - het is minder relevent tot en met f scan f nu, hopelijk, het zal weer aansluiten bij een of andere manier. Maar wat ik in eerste instantie van plan was om te laten zien was - dit is eigenlijk direct relevant is voor deze [?? F5] Je gaat worden met behulp van s afdrukken f, waar, zeggen dat we 100 foto's, en u wilt dat het beeld 1.jpg, 2.jpg, 3.jpg lezen. Dus om dat te doen, moet je f open, en dan moet je gaan in de tekenreeks die u wilt openen. Dus we zouden willen openen 1.jpg, om de tekenreeks die 1.jpg creëren, we doen print van f van% D.jpg--we niet doen voor int i = 0. i <40, i + +. Dus print van f% D.jpg van i. Dus na deze lijn, nu de variabele of de array s gaat 1.jpg. Of, 0.jpg, 1.jpg, 2.jpg. En dus kunnen we, opent op zijn beurt, elk beeld om te lezen. Dus dat is wat is af te drukken f doet. Zie je wat s af te drukken f is nu aan het doen? [Student] Oke, dus het neemt - het creëert een string, something.jpg, en dan slaat het. Ja. Het creëert - dit is een ander format string, net als scan f en printen f, waar het voegt alle variabelen in het tweede argument, misschien wel s in tegenstelling tot i. Misschien - ik bedoel, dat is het geval. Maar wat de volgorde van argumenten is. Het gaat om alle variabelen in te voegen in de format string en dan op te slaan in onze buffer, we noemen dat een buffer, het is waar we het opslaan van de string. Dus we zijn binnenkant van s opslaan van de juiste-geformatteerde string,% d te zijn vervangen door 4. [Student] Dus als we dit deden, is de variabele f gewoon te worden toegewezen? Ja. Dus we moeten sluit het origineel f voordat je dit doet. Maar - en dan ook, als er niet een f hier open te stellen, dan zouden we moeten zeggen - Ja. Maar het zou het openen van een honderd verschillende bestanden. [Student] Maar we zouden niet in staat zijn om toegang te krijgen of - oke. Oke. Dus scan f, f scan f, is een soort van hetzelfde idee, maar in plaats van, in plaats van te slaan in een string, het is meer als je nu bent gaan over een angel en pattern matching tegen die string en het opslaan van de resultaten in variabelen. U kunt gebruik maken van scan f te ontleden dan iets als 4.jpg, en het geheel getal 4 op te slaan in som int x. Dat is wat we kunnen scannen f gebruiken. F scan f gaat om dat te doen op de opdrachtregel. Ik ben eigenlijk vrij zeker dat dit is wat de CS50 bibliotheek doet. Dus als u zegt: "int te krijgen," het is scan f-ing over - scan f is de manier waarop je krijgt input van de gebruiker. F scan f gaat om hetzelfde te doen, maar met behulp van een bestand om te scannen via. Dus hier zijn we scannen via dit bestand. Het patroon waarin we proberen aan te passen is een stukje tekst dat is 127 tekens lang zijn gevolgd door een nieuwe lijn Dus ik ben er vrij zeker van dat we konden zelfs alleen maar zeggen: "match s," omdat in het woordenboek we toevallig hebben, zijn we gegarandeerd geen woord is dat lange, en ook f scan f, denk ik, zal stoppen bij de nieuwe lijn maakt niet uit wat. Maar we zullen ook de nieuwe lijn in de wedstrijd, en - [Student] Als we niet de nieuwe lijn zijn, zou het niet vinden delen van een woord? Het - per stuk - te kijken naar het woordenboek - Dus in het woordenboek, het zijn allemaal van onze woorden. Elke kamer is op een nieuwe regel. De scan f gaat halen dit woord. Als we geen rekening met de nieuwe lijn, dan is het mogelijk dat de volgende scan f gewoon lezen de nieuwe lijn. Maar ook nieuwe lijn zal dan gewoon negeren de nieuwe lijn. Maar we zullen nooit deel van een woord, want we zijn altijd het lezen tot een nieuwe lijn, wat er ook gebeurt. [Student] Maar wat als je zoekt naar het woord "Cissa," zoals Cissa. Zal het zijn dat, en zeggen dat het een wedstrijd? Dus hier zijn we - het zal lezen in - dit is eigenlijk een goed punt. We zijn nooit met de huidige - het woord dat we zoeken is de eerste opdrachtregelargument. Dus string, woord = argv 1. Dus de string die we zoeken is argv 1. We zijn niet op zoek naar een woord op alle in onze scan f. Wat we aan het doen waren met scan f wordt steeds elk woord in het woordenboek, en dan een keer hebben we dat woord gaan we strcmp gebruiken om ze te vergelijken. We gaan ons woord te vergelijken en wat we zojuist gelezen inch Dus onvermijdelijk, we gaan uiteindelijk doen een heleboel scan fs totdat het gewoon zo gebeurt het dat scan f zal terugkeren - deze resultaten is, zolang zij een nieuw woord gekoppeld, en het zal terug iets anders, zodra deze heeft nagelaten het woord te passen. We lezen over de gehele woordenboek, het opslaan van regel voor regel elk woord in de variabele s. Dan zijn we het vergelijken woord met s, en als de vergelijking == 0, strcmp gebeurt op 0 te brengen als er een match is gemaakt. Dus als het was 0, dan kunnen we afdrukken f, afgestemd, of woord is in het woordenboek, of wat je wilt tot en met f te drukken. En dan - we willen niet f sluiten over en weer. Dit is het soort van wat we willen doen, en we zijn niet alleen op zoek naar woord in het woordenboek. Dus we konden dat doen, als we wilden om te zoeken naar hun voorbeeld, Cissa, zoals je al eerder zei, als we wilden om te zoeken naar dat patroon, dan zou het niet in het geval want dat is niet echt een woord, maar een van de woorden in het woordenboek toevallig dat in het. Dus het zou overeenkomen met dit woord, maar dit deel van het woord is niet een woord zelf. Maar dat is niet hoe we met behulp van, we lezen in elk woord en vervolgens te vergelijken het woord dat we hebben met dat woord. Dus we zijn altijd op het vergelijken van volledige woorden. Ik kan het verzenden van de definitieve oplossingen later. Dit is een soort van bijna het juiste antwoord, denk ik. [Student reactie, onverstaanbaar] Oh, had ik te ontdoen van dat voor? Char s, ik denk dat we zeiden 127 - ik vergeten wat de grootste is. We zullen gewoon doen 128; dus nu is lang genoeg is. We hoeven niet om iets af te drukken. We gaan ook willen hebben om ons dossier te sluiten, en dat moet ongeveer het juiste antwoord. CS50.TV