[Powered by Google Translate] Раздел Проблем 2: Hacker Edition
Роб Боудън, Харвардски университет
Това е CS50. CS50.TV
Така че, аз съм Роб. Аз съм старши в Къркланд. Това е третата ми година TFing CS50.
Това е първият път, че ние се променяме от секцията в стила на традиционната лекция,
къде сме просто на преглед, какво се е случило в лекцията и след това вие задавате въпроси,
сега е много по-проблемно-базирано, където ние използваме пространства, и -
О, така че идеята е да отидете, които сочат, че сте изпратили и тогава вие ще бъдете в моето пространство.
Не някой има лаптоп? Добре.
Така че ние ще се използва този и отиваме да се прави проблеми, живеят в раздел
и обсъждането им и разберете какво не е наред
и аз може да дръпне част от кода си, и аз може да обсъждате своите идеи.
Така е някой е имал затруднение?
Можете да чатите в страната, аз не знам дали ще имат основание за това.
Сега, като предишната supersection, ако сте били в този клас, знаете какво е за.
На всички комплекти P ще бъде тези раздели.
Така че P-комплект 2, характеристики, предполагам, че вече го видях на P-комплект 1.
Но ние можем да погледнем в P-комплект 2 за какво ще се случва днес.
И ще видите част от въпроси.
Така че това ще бъде по всички P-комплекти; ще има раздел от въпроси.
Досега сме каза: "Помислете за това възможност да практикуват."
Вие няма да бъдете помолени да представят тази програма.
Идеята е, че те би трябвало да ви помогне да започнете с проблема.
Предполагам на Hacker издание, много от тях се очаква да бъде само нови, интересни неща за учене.
Те не могат да бъдат пряко приложими към проблема.
И точно сега ние не сме като вас да ги представи, но на теория,
за по-късно комплекти проблемни, може да ги представи, и по този начин може да дойде в раздел
или гледате секция, за да получите отговорите, или просто можете да ги получите на собствения си
ако не се чувствам като се наслаждавате на присъствието ми.
Така че - Мисля, че това е първият.
О. Също така, в тези участъци на въпроси ние също ви задават въпроси относно шорти.
Така че, предполагам, на теория, би трябвало да гледат преди да дойде в раздел,
но това е добре, ако не, ние ще отидем над тях, така или иначе.
Така че можем да започнем с тези: "Как един цикъл, докато се различават от направи линия, докато?
Кога е последният особено полезно?
Така че някой има?
[Student] направи, докато цикълът се изпълнява поне веднъж.
Да. Така че това е разликата. А докато линия - Ще го направя тук - докато контур, имаме състояние
точно тук, като има предвид, че не се прави, докато не имате състояние, докато не получите тук.
И така, когато програмата ви изпълнява, и го получава на линия, докато,
тя веднага се проверява дали това условие е вярно.
Ако това условие не е вярно, тя просто ще прескочат цикъла изцяло.
Направи линия, докато, тъй като програмата се изпълнява, той получава "направи".
Нищо не се случва в този момент, просто продължава изпълнение.
Тогава, когато го удари ", докато", ако условието е вярно, че ще контур назад и да го направя отново
и отново, и отново, докато състоянието не е вярно, и след това просто пада през.
Така че, като разликата е, че това може да пропуснете още от самото начало.
Това задължително изпълнява веднъж и след това може да изпълнява повече пъти, ако условието е все още е вярно.
Така че цикъл, докато само ще го направи веднъж, или - цикъл, докато ние не може да се наложи да го правя изобщо,
, тъй като веднага след като стигнем до него, ако условието е невярно, ние просто ще пропуснете правата върху нея.
Като има предвид, че направи линия, докато ние ще го изпълни веднъж, задължително.
След това, когато стигнем до състоянието, ние проверяваме дали това е вярно или невярно.
Ако това е вярно, ние ще го направя отново, ако това е невярно, ние просто ще продължи да ходи.
Така че, когато е последното особено полезно?
Затова мога да кажа, че в цялост от 4 години, на 3 години, независимо,
че съм бил програмиране, са използвали това, като по-малко от 10 пъти.
И вероятно пет от тях са в CS50, когато ние ви представяме направи докато вериги.
Така че, когато сте използвали направи, докато вериги?
Кога е ли?
[Student] Когато се опитвате да получите потребителски вход, или нещо, което искате да проверите
Да. Така правят, докато вериги, потребителски вход е голяма.
Ето защо на първите набори няколко проблемни, когато искате да поиска от потребителя, като
"Дайте ми низ," не може да продължи, докато не се получи, че низ.
И така, задължително трябва да си зададем за струнен поне веднъж.
Но след това, ако те отговарят нещо лошо, тогава трябва да отскача назад и питам отново.
Но, различна от приноса на потребителите, това е много рядък, че се натъкнете на делото
, където искам да линия "поне веднъж", но може и повече.
Въпроси или? Има ли някой направи линия, докато навсякъде другаде?
Добре. Така че следващия е: "Какво се недекларирани идентификатор
обикновено показват, ако е изведен от ехтя?
Така че какъв код да пиша, за да получите "недекларирания идентификатор?
Студентски], че х = 2?
Така че ние можем просто го опитате тук, х = 2.
Ще пуснем това - О, аз не щракнете върху него. Така че тук сме се - всичко е наред.
"Използване на недекларирани х идентификатори.
Така че това е недекларирания идентификатор, променлива.
Тя често ще наричаме променлива идентификатор.
Така че може и да не знаят, че всъщност е променлива, тя не знае какво е то.
Така че това е идентификатор.
Така че, защо е пазен в тайна? Да.
Така че, за да бъде ясно на терминологията, декларацията на променливата
е, когато ти казват "INT х" или "низ у", независимо.
Инициализация на променлива, или за прехвърлянето на променливата,
е, когато вие казвате "х = 2."
Така че можем да направим това в отделни стъпки, вътр х, х = 2, и докато можем да имаме един куп неща тук -
но докато тази линия се случва, Х е все още неинициализирана, но тя е била обявена.
И така, ние очевидно може да го направи в 1 линия, и сега ние сме деклариране и инициализиране.
Въпроси?
И накрая, "Защо не е Cipher Цезар много сигурен?
Така че, първо, няма ли някой да каже какво Cipher Цезар?
[Студентски] Цезар Cipher е, че можете Карта, ти смени всяко писмо,
определен брой писма вървят, и да се премести обратно над, и това не е много сигурно, защото
има само 26 възможни варианти, и просто трябва да се опитаме всеки 1 от тези докато не го получи.
О. Така че, аз трябва да се повтаря?
Цезар Cipher, it's - Искам да кажа, че ще се занимава с него проблемите, които ви -
или аз предполагам, стандартно издание на проблема, че не е хакер издание.
На стандартната версия на проблема, ще получите съобщение като "Здравей, свят"
и имате номер като 6, и да приемете това съобщение, и всеки индивидуален характер,
можете да го въртите с 6 позиции в азбуката.
Така "з" в здравей ще стане з-и-к-к-л-м-н.
Така че първото писмо ще бъдат н. Ние правим едно и също нещо с електронна поща.
Ако имаме, като, Z или нещо подобно, тогава ние приключи обратно около ".
Но всеки един от героите получава реинвестират по-късно от 6 символа в азбуката, и това не е много сигурно
, тъй като има само 26 възможности за това колко много начини може да приключи една буква.
Така че можете да опитате всички 26 от тях, а вероятно, за достатъчно дълго съобщение,
само 1 от тези възможни 26 неща ще бъдат четливи,
и четливи ще бъде оригиналното съобщение.
Така че това не е много добър начин за криптиране на каквото и да било.
Свързани с тези шорти, "Какво е функция?"
Така че това, което е функция? Да.
[Student] Това е като отделна част от код, който можете да се обадите, за да мине през и след това получи връщане стойността на каквото.
Да. Така че аз ще отговоря с отговора на следващия - или повторение просто отговора на следващия.
Можете да използвате функции, вместо просто копиране и вмъкване на код и отново.
Просто приемете, че кода, сложи го в fuction, и след това бихте могли просто да извикате функцията
където и да са копирате и поставяте.
Така функции са полезни.
Така че сега ние ще направим действителни проблеми.
Първия. Така че идеята на първата е, да го премине низ, и независимо от
или не го казвам с малки букви? Той не казва с малки букви.
Така че посланието може да бъде нещо, и - о, не. Това е така.
"За простота, може да се предположи, че потребителят ще трябва само въвеждане на малки букви и интервали.
Така че ние го премине съобщение само с малки букви и след това се редуват
между главни и малки букви - ние промените низ да бъдат главни и малки букви, редуващи се.
Така че, преди да ви даде втори, дори и да се потопите в проблема,
какво е първото нещо, което ние трябва да направим?
О, какво съм просто кликнете върху? О, аз просто кликнах върху имейл тук.
Така че първото нещо, което трябва да се направи - търси в грешното?
Дали това е част от това?
Не, това са все още там, все пак.
Добре, все още тук.
Сега ние не можем да приемем? Да. Тук не можем да приемем, че тя е само с малки букви и пространства.
Така че сега ние трябва да се справят с факта, че писмата могат да бъдат каквото си искаме те да бъдат.
И така, първото нещо, което искаме да направим, е просто да получи съобщението.
Ние просто трябва да се низ, низ = GetString, добре.
Сега този проблем, има няколко начина да го направите.
Но ние ще искате да използвате побитовите оператори.
Има ли хора, които или не са били в supersection
или нещо такова, и не знам какво побитовите оператори?
Или как те се отнасят до ASCII по някакъв начин?
[Student] не е в supersection, но аз знам какви са побитовите оператори.
Добре. Така че след това не е нужно да отидете през основите на тях, но аз ще обясня
това, което ще искате да използвате тук.
Така че, "А": Binary представителство на капитала на, броят им е 65.
Аз съм просто ще да погледнете - 41 ще бъде 01000001.
Така че това трябва да бъде 65 в десетична, така че това е двоичен представителство на характер А. капитал
Сега, двоичен представа за характера малки букви "а"
ще бъде едно и също нещо, почти. - 6, да. Това е правилно.
Така двоичен капитал, двоичен малки ".
Така забележите, че разликата между А и "а" това е едно малко.
И това се случва да бъде 32 бита, бит, представляващи 32 броя.
И това има смисъл, тъй като е 65 "а" е 97.
Разликата между тях е 32.
Така че сега ние знаем, че може да конвертира от А до "А", като А
и побитови ORing, с който изглежда като едно.
Това е побитово ИЛИ, 00100000, и това ще ни дават ".
И можем да получим от "а" от побитови ANDing
с 11, 0 на това място, 11 111.
Така че това ще ни даде точно това, което "а" е, но се компенсира този човек малко,
така че ще имаме 01000001, аз не знам дали аз преброих право.
Но тази техника на побитови ORing към получите от капитала на малки букви,
и побитови ANDing да получите от малки до капитал не е само до А.
На буквите, K - к, Z - Z
всички от тях са просто ще се различава от това едно малко.
И така, можете да използвате това да се промени от всяка малка буква на всяка главна буква и обратно.
Добре. Така че един лесен начин за получаване от това - така че вместо да се налага да
напишете каквото 1011111 - лесен начин за представяне на това число, и това не е един
че отидох в supersection, но тилда (~) е друг побитови оператора.
Какво ~ прави е изглежда по малко представителство.
Нека вземем произволен брой.
Това е само част двоично число, и какво ~ е просто обръща всичко на бита.
Така че това беше един, сега е 0, това е на 0, сега е 1, 010 100.
Така че това е всичко ~. Така че 32 ще бъде номер - да се отървем от това -
така 32 ще бъде номер 00100000, и така ~ за това ще бъде
този номер, че ANDed "а" с.
Ли всеки да види това? Това е доста често срещано, като например, когато искате да разбера
за по-късно нещата, които бихме могли да се видим, когато искаме да видим дали -
или искаме всичко, всеки един бит с изключение на 1
сте склонни да се ~ от малко, че ние не искаме определени.
Така че ние не искаме 32 бит, така че ние ~ 32.
Добре. Така че ние можем да използваме всички тези тук.
Добре, така че всичко е наред, ако не сте готови, бавно ще ходят заедно,
или разходка през това, така че през това. Разходка през това.
Така че ние имаме низ, и ние искаме да отскача над всеки един от героите в този низ и да направим нещо за да го.
Така че, как правим примка над низ? Какво трябва да се използват?
Аз няма да го направя тук. Да.
Така че аз имам итератор, и той го каза, но как мога да знам колко знака в низа?
Strlen (а), тогава аз + +.
Така че това, което съм направил тук не е най-добрият начин за правене на нещата.
Някой знае ли защо?
Защото сте проверка на езика на низа всеки един момент.
Така че ние ще искате да преместите strlen, бих могъл да кажа тук, вътр дължина = strlen (а),
и след това мога да <дължина, и в случай, че не са го виждали и преди,
Аз също може да направи Int I = 0, дължина = strlen (ите).
И така, това е малко по-за предпочитане, тъй като сега съм ограничи обхвата
на променлива дължина само това "за" линия, вместо да го деклариране пред
и че винаги съществува, и в случай, че не разбрах, защо това е лошо,
или защо оригиналът е лошо, it's - начало за цикъл.
Аз проверих състоянието. I <дължината на S?
Така дължината на S, нека работим с "здравей" през цялото време.
Така дължина, з-д-л-л-о. Дължината му е 5.
Така че аз = 0, дължина е 5, така че не е по-малко от пет, така че цикълът продължава.
Тогава отиваме отново. Ние проверяваме състоянието. I <дължината на здравей?
Така че нека да проверим дължината на здравей. H-е-л-л-о. Това е 5; не е по-малко от пет, така че ние продължаваме отново.
Така че ние изчисляване, разчитаме Здравейте, за всяка итерация на цикъла,
дори мислех, че никога няма да се промени, то винаги ще бъде 5.
Така че ние просто не забравяйте 5 отпред, а сега всичко е по-добре.
Така итерации през целия низ.
Какво искаш да направя за всеки знак на низа?
[Student казано, неразбираемо]
Да. Така че, ако героя не е азбучен, тогава ние просто искате да пропуснете над него.
Защото ние само се грижи за букви, не можем да се възползва номер.
Така че как можем да направим това? Така че нашето състояние, така че ако искаме нещо - да се провери дали това е азбучен.
Е, как да проверя това?
[Student], можете просто да използвате функцията е алфа.
Е, че са включени в нито един от тях, или други подобни, char.h или нещо?
Да не се използва е алфа функция и използвайте категорични - така че ние имаме [],
това е осмата характер и не забравяйте, че низ е за масив от знаци,
така осмото характер на S.
Сега, ако това е главна буква, знаем, че трябва да бъде в определен обхват.
И какъв е този кръг?
Да. Така че, ако [I] е ≥ 65, и е [I] е ≤ 90, какво трябва да направя, вместо?
Да. Така че абсолютно никога не трябва дори да се наложи да се запознаят с ASCII стойности на всичко, което някога.
Никога не мисля за номера 65, 90, 97 и 102, или каквото и да е.
Не е нужно - 112 - не е нужно да знаят тези, които изобщо. Това е грешно.
Използвайте само един цитат герои, самотни цитат константи. Така че, "А" и по-малко от 90 "Z."
И това е значително по-добре - не знам на разстояние от върха на главата ми, че Z е 90.
Знам, на разстояние от върха на главата ми, че 'Z' е столицата Z.
Така че, докато това е в обхвата на капитала на столицата Z, или ние да проверите за малки,
Или, ако това е в диапазона ≥ "а" и ≤ Z.
Така че това е нашето състояние.
Стил, където да поставите тези неща се променя.
Аз ще го направя по този начин.
Сега, какво искаш да направя?
Знаем, че това писмо е знак, буква.
Така че ние трябва да се редуват между това дали сега трябва да бъде главна буква или малка буква.
Как да следим, единият от които искаме да бъде?
[Студентски гласове, неразбираеми]
Така че, да, но нека да проверя.
Модул 0-2 беше казано, беше предложение изхвърлят, и аз съм съгласен с това.
Освен известие, че подобно - това е така? Да.
Това е всеки друг, но не можем модул 2 на "Аз, или мод 2, тъй като
забележите, че E е столица и "а" е с малки букви? Но там е пространството, което ги разделя?
Така те ще бъдат същия мод 2, но те са различни случаи.
[Student въпрос, неразбираем]
Да. Така че ние просто ще продължим да брой.
Бихме могли да направим това тук, ако искаме, може да се получи малко тромава
в за контур декларации; ще го сложа тук.
Така INT брой = започва от 0.
И така, сега, аз отивам да брои колко букви от азбуката сме имали.
Така че ние неизбежно ще се броят + +, тъй като ние открихме друга буква.
Но, така че сега сте, че ако Министерството на отбраната на брой 2.
И какво, ако броя на Министерството на отбраната 2? О. Ще направя == 0 за сега.
Ние също така ще премине. Така че, ако брой мод 2 == 0, тогава какво?
[Студентите отговор, неразбираеми]
Така че ние искаме да се окажете с главни букви.
Има две дела; главни и малки букви са 2 случая.
Така че, ако ние сме малки, ние трябва да го правят главни букви.
Ако това е главна ние не трябва да правите нищо.
Но все пак има начин - shouldn't са огледален -
че ние дори не е необходимо да се провери дали това е главни или малки?
Какво можем да направим, винаги да сме сигурни, че винаги в крайна сметка най-главни?
Така че забележите това, което направихме за малки букви "а", а какво ще стане, ако ние направихме същата тази точното нещо в главни?
Главни промяна, или промяната в стойността?
Да. Така че всяка капитала побитови писмо, ANDed с ~ 32 ще бъде същия характер главни
защото за всяка главна буква, не е настроен на 32-ия малко.
Така че, ако искаме да характера [], ние искаме тя да се превърне малки или главни букви.
Така че, ако това е с малки букви, сега е с главни букви, ако тя е главна, все още е главна буква, и това е всичко.
Казах това в supersection: Можете да използвате 32, ако искате, но съм склонен да предпочитат да се прави "а" - A,
вместо просто 32, тъй като тя може да бъде всеки друг малко.
След 32-битов, може да бъде някой от тях, или няма да имаме достатъчно
номера, за да представляват всички герои.
Така че, ако имате 32-битов, може да е 64-битов, тя може да бъде 128-битово.
Всяко едно от тези битове може да бъде малко, че прави разлика между главни и малки букви.
Аз няма да се налага да знаете, че това е 32-битов.
Мога да използвам тази "а" - да получите най-малко, че се различава между двете
без да се налага да разчита на магията номер, който е 32.
И така, сега, в противен разчита беше странно и така, какво искам да направя?
[Студентски отговори, неразбираем]
Студентски] Какво е това?
Аз ще го направя за 1 секунда.
Така че сега, ако искам да - Искам да се уверите, герой е с малки букви,
и затова може или с 32 и 32 смисъла "а" - А.
Но забележете, по същата логика като предишната, че ако
писмото е вече с малки букви, а след това от 32 ORing просто го поддържа малки.
Тя не се е променила първоначалния си характер.
Но сега не трябва да се избегне, казвайки: "Ако той е с малки букви, просто да забравите за това,
ако е с главни букви, а след това се промени. "
Това е много по-удобно да се направи това.
[Student] Дали тази стратегия за изваждане на главни от малки работа, ако не беше 32?
Ако е така,, ​​34 или нещо такова?
Така че, трябва да знаят, че разликата между два? >> 1 бит.
Тя може да бъде повече от 1 бит, толкова дълго, колкото всички бита под тази позиция са едни и същи.
Така че ние трябва най-малко 26 символа - или, има 26 знака.
Така че ние трябва най-малко 26 номера, за да представляват разликата -
Разликата между А и "а" трябва да бъде най-малко 26,
или иначе ние няма да представлява всички капиталови номера.
Това означава, че А, ако започне в 1, е да използвате всички тези битове,
всички тези първи пет бита, да представляват всичко до Z.
Ето защо следващата част или този бит, бит е този, който е избрал да се прави разлика между А и "."
Това е и причината в ASCII таблицата, там са 5-те символа, разделящи главни букви от малки букви.
Тъй като това са символи, допълнително 5, което води до 32, като разликата между тях.
[Student] Така че можем да го направим,, защото ASCII е проектиран по този начин.
Да. Но ASCII - разликата може да бъде както на тези битове.
Подобно, ако бяха 10000001 и "а" е 11100001 - забравя, независимо.
Но ако беше това, тогава ние все още може да се използва "а" - А.
Това е просто разликата между А и "а" е все пак тези два бита.
Мисля, че е написал 48. Е 32 + 64? Мисля, че е?
Тя все още ще бъде два бита, всеки един характер, като Z и Z, К и К,
те все още ще има абсолютно същите бита, с изключение на тези два бита.
Така че толкова дълго, тъй като това винаги е вярно, независимо от това, ако ние използваме ASCII или някаква друга система,
толкова дълго, тъй като има само определен брой на битовете, които са различни за всеки знак,
това работи добре.
Това е просто, че 32 е създадена, защото това е първата бихме могли да използвате. >> Cool.
Склонен съм да предпочитате, в случай, че не сте виждали, ако блока е само един ред,
можете да се отървете от фигурни скоби, така че са склонни да предпочитат този начин.
Също така, вие знаете как можем да направим неща, като [] + = 1?
Можете да направите [] побитово И = 32.
И побитови OR = 32.
Също така, броят мод 2 == 0.
Така че не забравяйте, че аз няма да го напиша - всяка ненулева стойност е вярна, а 0 е фалшива.
Така че, "ако Министерството на отбраната на брой 2 == 0" е същият като каза: "ако не се брои мод 2".
Сигурно щях просто да обърнат линиите и каза: "ако брой мод 2,
ли или 1, друго и 1 ", така че аз не се нуждаят от" не ".
Но това работи също толкова добре.
И какво друго да правя тук?
Можете да ги комбинирате с трикомпонентна, ако искате, но след това, че току-що направим нещата по-мръсно
и вероятно по-трудно да се чете, така че ние няма да направим това.
Всеки, който има ли други предложения?
Е, че всички проблема поиска? О, да.
Така се отървете от тези празни редове, сега ние ще отпечатаме е,% S е за струнни,
Ние ще отпечата е,
Сега нека да го стартирате. Ли съм направил нищо лошо?
Това е \ "; Искам н.
Добре. Сега ние ще го изпълним. Той най-вероятно ще ми крещи.
Strlen е в string.h.
Така че това е хубавото звъня тя ви казва какво е,
вместо от Персийския залив, която просто казва: "Хей, сте забравили нещо, аз не знам какво е то."
Но това ще ми каже: "Ти предназначено да включва string.h".
Така че аз не пита за нищо, така че не казва нищо.
Но ние ще направим техния пример "Благодаря четири добавки".
Това изглежда добре. Ура.
Така че връщане към вашия основен, почти никога не го правя.
Това е задължително. И главната е само функцията, за която не е задължително.
Ако не върне нищо от основната, се предполага, че сте искал да се върне 0.
Въпроси?
Добре. Така че сега втория проблем.
"Изтегли от втората лекция седмица две, че размяна на стойностите на две променливи чрез предаване
тези две променливи функция (дори ако суап), не точно работят, поне не и без "указатели."
И да игнорирам указатели, докато не стигнем до тях.
Ние искаме да размените две променливи, ние не използвате функция, за да го направя.
Ние все пак ще го направя в основната, както се казва.
Но за да се използват тези две променливи, ние не искате да използвате временна променлива.
Има два начина да направите това.
Можете да го направя, използвайки традиционните оператори двоични.
Така че няма кой знае бърз и мръсен начин за това?
Това всъщност може да отнеме минута на мислене. Ако имам -
Ще уредя проблема като искат. Така че, ако имам две променливи, A, която е само цяло число
, че те ми дават и Б сумата променлива, която е друго число, който съм дал.
Така че, ако имам тези две променливи, сега искам да ги разменят.
Традиционна, с редовните си бинарни оператори, искам да кажа, като +, -, ÷.
Не побитовите оператори, които действат на двоична.
Така че -, +, ÷, и всички онези.
Бихме могли да прекарат с нещо подобно а = а + б и б = а - б, а = а - б.
Така че, здрав разум проверка, и след това ще видим защо това работи.
Да кажем, = 7, б = 3, А + Б ще бъде 10.
Така че ние сега определя = 10, и след това правим б = а - б.
Така че ние правим б = а - б, което ще бъде 7, и б = а - б отново
или а = а - б. , Която ще бъде 10 - 7, което е три.
Така че сега, правилно, "а", е бил 7, б е 3, а сега б е 7, а "а" е 3.
Така че този вид има смисъл "а" е комбинация от две числа.
В този момент, "а" е комбинацията, а след това сме се извади оригиналния б,
и след това сме се извади това, което беше първоначалната ".
Но това не работи за всички номера.
За да видите това, нека разгледаме система, така че ние обикновено мислим за числа като 32 бита.
Нека да работим върху нещо, което е само 4 бита.
Надявам се, че излезе с добър пример точно сега.
Така че, аз знам, това ще бъде лесно.
Да кажем, че нашите два номера 1111 и 1111, така че ние сме в двоичен точно сега.
В реалните знака след десетичната запетая, ако искате да мисля за него по този начин, а = 15 и B = 15.
И така, ние очакваме, след като сме ги разменят, те не дори трябва да бъдат едни и същи числа,
но аз го направих по този начин.
Нека да не ги едни и същи числа. Нека направим 1111 и 0001.
Така = 15 и B = 1.
След като ги разменят, ние очакваме "а" да бъде 1 и Б е 15.
Така че първата стъпка е = а + б.
Нашите числа са само 4 бита, така че "", който е 1111 + б, който е 0001,
е в крайна сметка ще е 10 000, но ние имаме само 4 бита.
Така че сега е = 0.
И сега искаме да настроите б = а - б - всъщност, това все още работи перфектно.
= а - б - нека видим дали това работи перфектно.
Тогава б = 0 - 1, която все още ще бъде 15, а след това = а - б, която ще бъде една.
Може би това е работа.
Имам чувството, че е причина тя не работи, използващи обикновен.
Добре, така че работи върху предположението, че тя не работи с редовни операции двоични,
и аз ще гледам - ​​ще Google, за да видите, ако това е вярно.
Така че ние искаме да го направя, използвайки побитовите оператори и следа тук е XOR.
Така че, въвеждане XOR (^), ако не съм го виждал още.
Това е, отново, побитови оператора, така че да действа малко по малко, и it's
Ако имате битове 0 и 1, то това ще бъде 1.
Ако имате бита 1 и 0, това ще бъде едно, имате битове 0 и 0, че ще бъде 0,
и ако имате бита 1 и 1 ще бъде 0.
Така че това е като OR. Ако някоя от бита са верни, това е едно, но за разлика ИЛИ, той не може да бъде двата бита, които са верни.
Или може би това е 1, XOR би трябвало това да е 0.
Така че ние ще искате да използвате XOR тук.
Помислете за това за минута, аз отивам да Google.
Е, не може да чете, че Аз съм в момента на XOR алгоритъм на страница суап.
Надяваме се, че това ще обясня защо Не можеш -
Това е точно алгоритъм, който току-що направих.
Аз все още не виждам защо трябва да съм просто избра лош пример,
но този случай, където "а" се случи да стане 0, след получаване на 5 бита, така че сега "а" е 0,
това е, което се нарича "цяло число преливане".
Според Уикипедия, "За разлика от XOR суап, този вариант изисква, че той използва някои методи
да се гарантира, че X + Y не доведе до цяло число преливане ".
Така че това има проблеми, това е цяло число преливане, но съм направил нещо нередно.
Не съм сигурен. Ще се опитам да излезе с друга.
[Student] Е, не е цяло число преливане, когато се опитвате да се сложи там
по-голям от размера на бита, които сте разпределени?
Да. Имаме 4 бита. Това е - имахме 4 бита, след това се опитайте да добавите 1 към него, така че в крайна сметка с 5 бита.
Но петата малко получава отрязани, да.
Той може в действителност -
[Student ли, че ви хвърли грешка, или това, че ще хвърли грешка?
Номер Така че няма грешка. Когато стигнете до нивото на събранието, специален малко
някъде е, че каза, че има преливник, но в C вид просто не се занимават с това.
Вие всъщност не може да се справи с него, освен ако не използвате специални инструкции за монтаж в C.
Нека помислим за XOR суап.
И аз мисля, статия в Уикипедия може да са също така казва, че
Така че това също доведе модулна аритметика, така че предполагам, аз бях на теория, прави модулна аритметика
, когато казах, че 0 - 1 е 15 отново.
Така че може в действителност - на редовно процесор, който прави 0 - 1 = петнайсет милиона.
Тъй като до края на 0, извадим 1, така че след това просто се загърнала отново около 1111.
Така че този алгоритъм може действително работят, а + б, - б, б - а, може да се оправи.
Но има някои процесори, които не правят това, така че не би било добре в тези специфични.
Суап XOR ще работи на всеки компютър. Добре.
Идеята е, че той е трябвало да бъде същото, макар че.
Когато ние използваме XOR по някакъв начин да получите информация и за двете в един от променливите,
и след това отново да извадя информация на отделните променливи.
Така че някой има идеи / отговори?
[Student отговор, неразбираем]
Така че това трябва да работи, а също така, XOR е комутативен.
Независимо от които за тези две числа се случи да бъде тук,
този резултат ще бъде една и съща.
Така че ^ б е б ^ а.
Можете също така да видя това, написано като ^ = б, б ^ = а, ^ = б отново.
Така че това е правилно, и да се види защо това работи, мисля, на бита.
С помощта на неголям брой, нека кажем, 11001 и 01100.
Така че това е "а", това е б.
Така че ^ = б.
Отиваме да бъде създаването на "A" = XOR от тези две неща.
Така 1 ^ 0 1 1 ^ 1 0 0 ^ 1 е 1, и 0 ^ 0 0 1 ^ 0 е 1.
Така "," ако се вгледате в десетично число, то ще да бъде -
вие няма да видите много на отношенията между оригиналния "а" и новия ""
но преглежда битовете, "а" сега е като окото на информацията
както оригинала "а" и оригиналния б.
Така че, ако вземем б ^, виждаме, че ние ще се окажете в оригинал ".
И ако вземем оригинала "а" ^ новата "," ние виждаме, че в крайна сметка в оригиналния б.
Така че (а ^ б) ^ б = оригинала ".
И (^ б) ^ а = оригиналния б.
Има друг начин - да види, че това е нещо себе си XOR винаги е 0.
Така 1101 ^ 1101, всички части ще бъдат едни и същи.
Така че никога няма да бъде случай, където 1 е 0, а другият е едно.
Така че това е 0000.
Същото е и с това. (^ Б) ^ б е като ^ (B ^ б).
(Б ^ б) ще бъде 0, ^ 0 е просто ще бъде "," тъй като всички битове са 0.
Така единствените, които ще бъдат, където "а" първоначално е бил един - не са имали такива.
И съща идея тук, аз съм сигурен, че тя също е комутативен.
Да. Аз съм казал преди това е комутативен.
^ "," И това е асоциативен, така че сега (B ^) ^ а.
И ние можем да направим б ^ (^).
И така, отново, ще получите оригиналния б.
Така че "сега е комбинация от" а "и б.
Използване на нашия нов комбо "" казваме б = комбо 'на' ^ оригиналния б, ще получите оригинала ".
И сега е = комбо "а" ^ новата б, който беше първоначалната - или, което е сега какво е "а" или б.
Това е този случай тук. Това е = б, стари б.
Така че сега всичко е обратно в разменят ред.
Ако ние действително погледна в бита, б = а ^ б, ще да XOR тези две,
и отговорът ще бъде това, и след това A = A ^ B XORing тези 2 и отговорът е това.
Въпроси? Добре. Така последните донякъде е значително по-трудно.
[Student] Мисля, че има съмнение за това. >> О, съжалявам.
Студентски] Какво всъщност е по-бързо? Ако използвате този XOR, или то е, ако Вие декларирате нова променлива?
Така че това, което всъщност е по-бързо, за обявяване на нова променлива или използване на XOR да сменяте?
Отговорът е, по всяка вероятност, временна променлива.
И това е, защото след като е съставен - така на събранието,
няма такова нещо като локални променливи или каквито и да било временни променливи или някое от тези неща.
Те просто искали - има памет, а има и регистри.
Регистрите са там, където нещата са активно случва.
Не се добавят две неща в паметта, добави две неща в регистрите.
И ще ви заведе неща от паметта в регистрите след това да ги добавите,
и след това може да ги пуснат обратно в паметта, но всички действия се случва в регистрите.
Така че, когато използвате временната променлива подход, обикновено това, което се случва, е
тези две числа са вече в регистрите.
И след това от този момент нататък, след като сте ги разменят,
тя просто ще започнат да използват другия регистър.
Където и да са използвали б, тя просто ще използват регистъра, за която вече е била съхраняване ".
Така че не е необходимо да се направи всичко, за да направи суап. Да?
[Student] Но той също така отнема повече памет, нали?
Това ще ви отнеме повече памет, ако е необходимо да се съхранява, че временната променлива.
Като, ако използвате по-късно, че временната променлива отново някъде,
след това - или да присвоите нещо, че временната променлива.
Така че, ако във всеки един момент във времето "," б за температура имат различни стойности или нещо,
то тогава ще има на различни места в паметта, но е вярно, че
има много локални променливи, които ще съществуват само в регистрите.
В такъв случай, тя никога не е в паметта, така че никога не си губиш паметта.
Добре. Последен въпрос е малко по-.
Така че тук, в този уред CS50, има речник.
И причината за това е, защото [? B66] е проверка на правописа, където ще се пише
използване на хеш-таблици или се опитва или някаква структура на данните.
Започваш да се пише за проверка на правописа, и ти започваш да се използва този речник, за да направим това.
Но за този проблем, ние просто ще изглежда, за да видите, ако една-единствена дума в речника.
Така че, вместо да съхранявате целия речник в структурата някои данни
и след това върху целия документ, за да се види дали всичко е сгрешена,
ние просто искаме да се намери едно слово. Така че ние може просто да сканира целия речник
и ако ние никога не намерите думата в целия речник, то тогава не е бил там.
Ако се сканира целия речник и да видите думата, тогава ние сме добри, ние го намерихме.
Тук пише, че искаме да започнете да търсите най-функция за обработка на файлове C,
, тъй като искаме да чете речника,
но ще дам намек, в които функциите, които трябва да мислят за.
Ще ги напиша в пространства.
Така че, основните от които вие ще искате да погледнете се е отворен и след това, неизбежно е затворен,
които ще отидат в края на програмата, и е сканиране е
Можете също да използвате е прочетете, но най-вероятно не искате да
защото това не свърши нуждаят че.
F сканиране е е това, което ще се използва, за да сканира речника.
И така, вие не трябва да се кодира на решение, просто се опитвам и като псевдо-код пътя си
решение, и тогава ние ще го обсъдим.
И действително, тъй като аз вече ви е дал тези, ако отидеш във всеки терминал или черупка на вашия уред,
Бих - обикновено - ако все още не сте виждали, аз не знам, ако си направил в клас,
но човек, така че човек страници, са доста полезни за търсене в почти всяка функция.
Така че мога да направя, харесва, е човек, сканиране е.
Това е информация за е семейството сканиране на функциите.
Аз също може да направи MAN F, отворени, и че ще ми даде подробности за това.
Така че, ако знаете каква функция, която използвате, или четеш код
и ще видите някои функции и вие сте като "Какво означава това правя?"
Просто човек, който името на функцията.
Има няколко странни примери, където може да се наложи да се каже
харесва. човек 2, че името на функцията, или човек, три, че името на функцията,
но вие само трябва да направите, че ако името на функцията човек не се случи, да се работи за първи път.
[Student] Така че аз съм четене на човек страница за отворен, но аз съм все още са объркани за това как да го използвате и програмата.
Добре. Много от страниците на човек са по-малко отколкото полезни.
Те са по-полезни, ако вече знаят какво правят
и след това просто трябва да запомните реда на аргументите или нещо.
Или пък може да ви даде обща представа, но някои от тях са много поразителен.
Както е сканиране е, също. Тя ви дава информация за всички тези функции,
и един ред тук се случва да се каже, "F сканиране е чете от низ точка или поток".
Но е отвори. Така че, как ще използваме е отворен?
Идеята за програма, която трябва да направи файл I / O е, че
първо трябва да отворите файла, който искате да прави неща с и неизбежно
прочета неща от този файл и да правя неща с тях.
F открито е това, което използвате, за да отворите файла.
Нещо, което се върна, така че какво файл искате да отворите, тя ни дава
тук се казва "/ потребител / акции / Dict / думи."
Това е файл, който искате да отворите, и ние искаме да го отворите -
ние трябва изрично да се уточни, дали искаме да го отворите да четат или ако искаме да го отворите да пиша.
Има няколко комбинации и такива неща, но ние искаме да се отвори за четене.
Ние искаме да се чете от файла.
Е, какво значи това завръщане? Тя връща файл звездичка (*),
и аз просто ще покажа всичко в променливата е, така *,
отново, това е указател, но ние не искаме да се справят с указатели.
Можете да мислите е, тъй като е в момента е променлива, ти започваш да се използват, за да представлява файл.
Така че, ако искате да се чете от файла, можете да прочетете от е
Ако искате да затворите файла, близо е.
Така че в края на програмата, когато неизбежно искате да затворите файла, какво трябва да направя?
Искаме да затворите е.
Така че сега последната функция файл, който ние ще искате да използвате сканиране е, е сканиране е.
И какво, което прави е да го сканира над файла, търси модел, който да съвпада.
Търси в мъжа страница тук, ние виждаме INT е сканиране е, не обръщайте внимание на връщаната стойност за сега.
Първият аргумент е файл * поток, така че е е първият аргумент, че ще искат да преминат.
Сканиране над F.
Вторият аргумент е низ формат.
Аз ще ви дам един низ формат точно сега.
Мисля, че се случи да се каже, 127s \ N, много от това е ненужна.
Идеята на този формат низ, можете да мислите за сканиране е като противоположност на печат е.
Така печат е, е печат, ние също да използват този тип формат параметър,
но в печатна форма е това, което правим, е - нека да погледнем в еквивалентен.
Отпечатате Така е, и там е всъщност също е печат е, където ще бъде първият аргумент е.
Когато отпечатвате е, ние може да се каже нещо като "печат 127s \ N" и след това, ако ние го давате някои низ,
ще да отпечатате тази низ и след това на нов ред.
127 средства, аз съм сигурен, но аз никога не съм се ограничава до,
Може би не е необходимо дори да се каже, 127 "в печатния е,
но какво означава извежда първите 127 знака.
Така че аз съм сигурен, че е така. Можете да Google за това.
Но в следващия аз съм почти сигурен, това означава, че.
Така че това е извежда първите 127 знака, последвани от нов ред.
F сканиране е сега, вместо да гледаме при променлив и печат,
ще разгледаме някои низ, и съхранява модела на променливите.
Нека всъщност е сканиране в различен пример.
Така че нека да кажем, че имахме някои вътр, х = 4,
и ние искахме да се създаде нишка - Искахме да създадем низ
това е като, това ще излезе много по-късно,
нещо, което е точно като 4.jpg.
Така че това може да бъде една програма, където ще имате брояч сума,
обобщение и брояч, и искате да спестите куп изображения.
Значи вие искате да спестите i.jpg, където е известно повторение на вашата линия.
Е, как да правим този низ за тази JPEG?
Ако сте искали да отпечатате 4.jpg, бихме могли просто да се каже печат е% d.jpg,
и след това ще отпечата за тази JPEG.
Но ако искаме да запазим 4.jpg низ, ние използваме сканиране е.
Така низ е - всъщност ние Не можеш - характер, Чар и, да вървим 100.
Така че аз просто обявява някакъв масив от 100 символа,
и това е, което ние сме неизбежно ще се съхраняване че JPEG инча
Така че ние ще използваме сканиране е и формата, как бихме казали d.jpg%
За да отпечатате 4.jpg, форматът на това ще бъде d.jpg%.
Така че форматът е% d.jpg, това, което искаме да замени г% е х,
и сега ние трябва да запишем, че низ някъде.
И къде отиваме да съхраните този низ е в масива.
Така след този ред на код, ако се печата е,% S на променливата S
ще да отпечатате 4.jpg.
Така е сканиране е същото като сканиране е, освен сега е над този файл
за какво да се съхранява в а.
Това е, което ще бъде последният аргумент.
Искате да съхранявате - "Scan е семейството на функциите сканиране в двете според формат, като се опитали по-долу.
Ако някой се съхраняват в местоположението точки може да се върне "
Не, ние може да бъде добър. Нека да помисля за секунда.
Така сканиране е не - какво по дяволите е функция, която прави това?
Така сканиране е няма да вземат число и направи точка JPG.
Това ще [Mumbles].
Запиши Int променлива в низ INT C.
Каква е тази променлива, или какво е това функция, наречена?
Да. Това е - да. Така че това, което е определяне за вас преди беше и печат е
които - това прави много повече смисъл, защо казах, че е много повече като печат е.
Scan е все още е вид като печат е, но ще го сканира и печат е
и замени променливи и сега се съхранява в низ.
Вместо да го отпечатате, той го съхранява в низ.
Така че да пренебрегнем факта, че изцяло. Все още можете да мислите за спецификатор формат, като тази на печат е.
Така че сега, ако искахме да направим 4.jpg нещо, ние ще направи и е печат, х за това.
Така че това, което се прави сканиране е - това, което е въпрос ще бъде?
[Student] Аз съм просто объркан от това, което се опитваме да направим тук
че JPEG. Можеш ли да обясниш, че едно повече време?
Така че това беше - това е по-малко relevent е сканиране е сега; се надяваме, че ще вържеш обратно по някакъв начин.
Но това, което първоначално възнамерява да покаже - това е пряко свързани с [? F5]
Вие ще се използват и печат е, когато кажем, че имаме 100 снимки,
и искате да прочетете снимка 1.jpg, 2.jpg, 3.jpg.
Така че, за да направим това, трябва да е отворен, а след това ще трябва да преминат в низа, който искате да отворите.
Така че ние ще искате да отворите 1.jpg, за да се създаде низ, който е 1.jpg
правим печат е от% d.jpg-ние не направим за Int I = 0.
<40, аз + +.
Така% печат е d.jpg аз.
Така след този ред, сега променлива или е масив ще 1.jpg.
Или 0.jpg 1.jpg, 2.jpg. И така, ние може да се отвори, от своя страна, всяка картинка за четене.
Така че това е, което и отпечатате е прави. Виждате ли какво е отпечатате е сега се прави?
[Student] Добре, така че да поема - тя създава низ, something.jpg, и след това го съхранява.
Да. Тя създава - това е друг формат низ, точно както е сканиране и печат е,
където да вмъква всички променливи във втория аргумент, може да е толкова против да съм.
Може би - Искам да кажа, че е така. Но независимо от реда на аргументи.
Това ще поставите всички променливи във формат низ
и след това се съхранява в нашата буфер, ние наричаме това буфер, това е мястото, където ние сме съхранение на низ.
Така че ние сме съхранение на вътрешната страна и правилно форматиран низ,% г са заменени с 4.
Студентски Така че, ако ние направихме това, е променлива е просто ще се преразпределят?
Да. Така че ние трябва да закриете първоначалния си е преди да направите това.
Но и след това също така, ако не е отвори тук, тогава ние ще трябва да се каже -
Да. Но това ще отвори стотици различни файлове.
[Student Но ние не ще бъде в състояние за достъп или - Добре.
Добре. Така сканиране е, е сканиране е, е вид на една и съща идея,
но вместо това, вместо да го приберете в низ, е по-скоро сте сега
Стинг и модел за съвпадение срещу тази струна и съхраняване на резултатите в променливи.
Можете да използвате сканиране е да се направи разбор нещо подобно 4.jpg и съхранява цялото число 4 в х сума Int.
Това е, което можем да използваме е сканиране за.
F сканиране е да направите това в командния ред.
Аз всъщност съм сигурен, че това е, което библиотеката CS50.
Така че, когато ви казват, "да INT", това е сканиране е над сканиране е начина, по който можете да получите потребителския вход.
F сканиране е ще направи същото нещо, но с помощта на файл, за да сканира.
Така че тук, ние сме сканиране над този файл.
Модел, ние се опитваме да съответстват на някои низ, който е с дължина 127 символа
последван от нов ред
Така че аз съм сигурен, че дори бихме могли просто да кажа "и съвпадат", тъй като в речника
ние се случи да има, ние сме гарантирани, думата не е толкова дълго,
и също е сканиране е, мисля, че ще спре най-новата линия без значение какво.
Но ние ще включва нова линия в мача, и -
[Student] Ако ние не включват новата линия няма да го намерите части от една дума?
- Всеки - в речника
Така че в речника, това са всички наши думи.
Всяка една е на нов ред.
Е сканиране ще се вдигне тази дума.
Ако ние не включват новата линия, а след това е възможно, че следващото е сканиране просто ще чете новата линия.
Но, включително нов ред, тогава ще можете да пренебрегнете на новата линия.
Но ние никога няма да получи част от дума, тъй като ние винаги сме четене на нов ред, без значение какво.
[Student] Но какво, ако търсите думата "cissa", като cissa.
Ще откриете, че и казват, че това е мача?
Така че тук ние - това ще прочетете в това всъщност е добра отправна точка.
Ние никога не използвате ток - думата, която търсим е първият аргумент на командния ред.
Така низ, дума = argv 1.
Така низ търсим argv 1.
Ние не търсим дума всички в нашата сканиране е.
Какво правим с сканиране е всяка дума в речника,
а след това веднъж имаме тази дума, ние ще използваме strcmp да ги сравни.
Отиваме да се сравни нашата дума и за това, което току-що прочетох инча
Така неизбежно, ние ще се окажете прави куп сканиране FS
, докато тя просто така се случва, че ще се върне сканиране е -
тя ще се върне, толкова дълго, колкото е съчетана нова дума,
и тя ще се върне нещо друго, веднага след като тя не успя да съответства на думата.
Четат през целия речник, съхраняване ред по ред, всяка дума в променливата а.
След това се сравняват дума с S, и ако сравнението == 0,
strcmp се случва да 0 ако има съвпадение.
Така че, ако тя е 0, тогава ние може да печата е съвпадение,
или думата е в речника, или каквото искате да отпечатате е.
И после - ние не искаме да е близо отново и отново.
Това е вид на нещо, което искаме да направим, и ние не сме просто търси дума в речника.
Така че бихме могли да направим това, ако искаме да се търси модел, cissa, както ти каза преди,
ако искаме да се търси този модел, то той ще се провали в случай
защото това не е една дума, но една от думите в речника се случва да има в него.
Така че би съвпада с тази дума, но тази подгрупа на думата не е самата дума.
Но това не е начина, по който го използвате, четем във всяка една дума
и след сравняване на думата, ние имаме с тази дума.
Така че ние винаги се сравняват цели думи.
Мога да изпратя на окончателните решения по-късно.
Това е вид на почти правилният отговор, мисля.
[Student коментар, неразбираем]
О, не мога да се отърва от това преди? Чар и, предполагам, че казахме 127 - Забравил съм това, което най-голямата.
Ние просто ще направи 128, така че сега и е достатъчно дълъг.
Ние не трябва да отпечатате нищо.
Ние също ще искате да имате за да затворите файл, и че трябва да бъде около верния отговор.
CS50.TV