[Powered by Google Translate] [Преглед] [Quiz 0] [Lexi Рос, Томи MacWilliam, Лукас Freitas, Джоузеф Ong] [Харвардския университет] [Това е CS50. [CS50.TV] Хей, всички. Добре дошли на сесия за преразглеждане Quiz 0, което ще се проведе тази сряда. Това, което ние ще направим тази вечер, аз съм с 3 други TFS, и заедно отиваме да мине през преглед на това, което ние сме направили в хода досега. Това няма да бъде 100% изчерпателен, но тя трябва да ви даде по-добра идея на това, което вече имате и какво още трябва да учат преди сряда. И не се колебайте да вдигнете ръка с въпроси, като ще ни заедно, но имайте предвид, че също така ще има малко време в края ако приключа с няколко минути, за да резервни, за да направи общи въпроси, така че да се има предвид, и така ние ще започнем в началото Седмица 0. [Quiz 0 мнения!] [Част 0] [Lexi Рос Но преди да правим, че да се говори за логистиката на теста. [Логистика] [Quiz се проведе в сряда, 10/10 вместо на лекцията] (Виж http://cdn.cs50.net/2012/fall/quizzes/0/about0.pdf за подробности) е в сряда, 10 октомври. Това е тази сряда, и ако отидете на този адрес тук, която е достъпна също от CS50.net има линк към него можете да видите информация за това къде да отидат на базата на фамилното си име или принадлежност училището, както и разказва за какво точно теста ще обхване и видовете въпроси, които ще получите. Имайте в предвид, че също така ще има възможност да се запознаем за тест в раздел така че вашите TFS трябва да се над някои практики, проблеми, и това е още една добра възможност да видите, където все още трябва да учат за теста. Нека започнем от самото начало с Bytes 'N' Bits. Не забравяйте, малко е само 0 или 1, и един байт е колекция на 8 от тези битове. Нека да разгледаме в тази колекция от бита тук. Ние трябва да бъдем в състояние да разбера колко бита има. Когато ние разчитаме само на 8 от тях, осем 0 или 1. И тъй като има 8 бита, това е един байт, и да го конвертирате в шестнадесетичен. Hexadecimal е с основа 16, а това е доста лесно да конвертирате в двоичен, което е, какво е това, към номер в шестнадесетичен. Всичко, което правим, е да погледнем към групи от по 4, и ние да ги конвертирате в съответната цифра шестнадесетичен. Започваме с най-дясната група от 4, така че 0011. Това ще бъде 1 и 2, така че заедно, което прави 3. И тогава нека да погледнем в другия блок 4. 1101. Това ще бъде един милион, един 4 и един 8. Заедно, че ще бъде 13, което прави D. И ние ще си спомните, че в шестнадесетичен не просто отидете от 0 до 9. Отиваме 0 до F, така че след 9, 10 съответства на 11 до точка Б, и т.н., където F е 15. Ето 13 е D, така да го конвертирате в знак след десетичната всичко, което правим е, че ние всъщност лечение на всяка позиция, с мощност от 2. Това е 1, една 2, нула 4s, нула 8s, един 16, и т.н., и това е малко трудно да се изчисли в главата си, но ако отидем на следващия слайд можем да видим отговора на този въпрос. По същество ние ще намира от дясно на ляво, и ние сме се умножи всяка цифра от съответната степен на 2. И не забравяйте, шестнадесетичен означават тези числа с 0x в началото така че ние не го бъркайте с десетично число. Продължавайки, това е ASCII таблица, и това, което ние използваме ASCII е да картографира от героите на числени стойности. Запомни ме pset криптография широко използване на ASCII таблица с цел да се използват различни методи за криптография, Цезар и шифър Vigenère, да конвертирате различни букви в низ според ключ, зададена от потребителя. Нека погледнем малко ASCII математика. Поглед към "P" + 1, под формата на знак, който ще бъде Q, и не забравяйте, че '5 '≠ 5. И как точно бихме конвертиране между тези две форми? Тя всъщност не е твърде трудно. За да получите 5 извадим '0 ' защото има 5 места между '0 'и '5. За да отидете на друг начин, ние просто добавете 0, така че това е нещо като редовен аритметика. Само не забравяйте, че когато нещо има кавички около него е герой и по този начин отговаря на стойност в ASCII таблица. Преместване в по-общи теми компютърни науки. Ние научихме какво представлява алгоритъм и как я използваме програмиране за изпълнение на алгоритми. Някои примери на алгоритми са нещо наистина просто като да проверяват дали даден номер е равна или странно. За това Спомням си, че Министерството на отбраната на броя на 2 и проверете дали резултатът е 0. Ако е така, това е дори. Ако не, то е странно. И това е пример за наистина основния алгоритъм. Малко по-голямо участие е двоично търсене, които ние ще отидем по-късно в рамките на прегледа на сесията. И програмиране е термин, който ние използваме за алгоритъм и конвертиране за кодирането на компютъра могат да четат. 2 примери за програмиране е Scratch, , което е това, което направихме през седмица 0. Въпреки, че ние не въведете кода това е начин за прилагане на този алгоритъм, който се отпечатва номера 1-10, и тук правим същото на езика за програмиране C. Това са функционално равностоен, просто написани на различни езици или синтаксис. След това научих за булевите изрази, и булев е стойност, която е или вярно или невярно, и тук често булевите изрази влезем вътре условия, така че ако (х ≤ 5), Е, ние вече х = 5, така че ще оцени това условие е да е истина. И ако това е вярно, независимо от кода е под условие ще бъдат оценявани от компютъра, така че низ ще бъдат отпечатани на стандартния изход и хронично състояние се отнася до това, което е вътре в скобите ако изявление. Запомни всички оператори. Запомни && и | | когато ние се опитваме да се комбинират два или повече условия, == = Не, за да се провери дали две неща са равни. Не забравяйте, че = е за възлагане, докато == е булев оператор. ≤, ≥ и след крайния два са ясни. Общ преглед на Булева логика тук. И булеви изрази също са важни в примки, които ние ще отидем сега. Научихме около 3 вида вериги досега в CS50,, а и правя, докато. И това е важно да се знае, че докато за повечето цели всъщност ние можем да използвате всякакъв вид на линия има някои видове на цели или общи модели в програмирането, които конкретно се обадя за една от тези вериги , които го правят най-ефикасният или елегантно да го кодира по този начин. Нека вървим по това, което всеки от тези вериги може да се използва за най-често. В контур ние обикновено вече знаете, колко пъти ние искаме да превъртите. Това е, което ние поставяме в зависимост от състоянието. За I = 0, I <10, например. Вече знаем, че искаме да направим нещо 10 пъти. Сега, за известно време контур, като цяло ние не непременно знам колко пъти искаш цикъла да тече. Но ние знаем, някакво условие, че искаме да винаги е вярно или винаги е невярна. Например, докато е зададен. Да кажем, че е булева променлива. Макар че е вярно, ние искаме код, за да оцени така че малко по-разтегателен, малко по-общо, отколкото линия но всеки контур може да се превръща в линия, докато. Накрая, докато контури, които могат да бъдат най-трудните, за да се разбере веднага, често се използват, когато искаме да се оцени код първо преди първият път, когато се провери състоянието. Общия случай за линия, докато е, когато искате да получите въвеждане от потребителя, и знаете, че искате да поиска от потребителя за въвеждане на най-малко веднъж, но ако те не ви даде добър принос веднага искате да запазите, като иска от тях, докато те ви дават добър вход. Това е най-честата употреба на линия, докато и нека погледнем реалната структура на тези вериги. Те обикновено винаги са склонни да следват тези модели. На за контур вътре има три компонента: инициализация, обикновено нещо като Int = 0, когато е на тезгяха, състояние, когато искаме да кажем стартирате тази линия, докато това състояние все още държи, като <10, и накрая, актуализация, която е как да увеличите контра променлива във всяка точка във веригата. Една обща нещо, което трябва да видите, че има само + + , което означава, че нарастване с 1 всеки път. Вие също може да се направи нещо като + = 2, което означава, добавят се 2 всеки път, когато отидете през примката. И тогава направи това точно се отнася до кода, който всъщност стартира като част от цикъла. И за известно време контур, този път ние всъщност имат инициализация извън цикъла, Така например, нека да кажем, че ние се опитваме да направим един и същ тип линия, както току-що описах. Бихме казали, Int = 0 преди цикъла започва. Тогава бихме могли да кажем, докато аз <10 направите това, така същия блок на кода, както и преди, и този път актуализация на част от кода, например, аз + +, всъщност става в рамките на цикъла. И накрая, за време, той е подобен на линия, докато но ние трябва да помним, че кодът ще оцени веднъж преди условие се проверява, така че има много повече смисъл ако го погледнеш по ред от горе до долу. В правя, докато линия на код оценява преди дори да погледнете, докато условие, като има предвид, че докато контур, той проверява на първо място. Отчети и променливи. Когато искаме да създадем нова променлива, ние първо искам да го инициализира. Например, вътр бар инициализира променлива бар, но тя не даде стойност, така че това, което е стойността на бара сега? Ние не знаем. Тя може да бъде някаква боклук стойност, която е предварително съхраняват в паметта, и не искате да използвате тази променлива докато ние всъщност го даде стойност, така че ние го заявявам тук. Тогава ние се инициализира тя да бъде 42 по-долу. Сега, разбира се, знаем, че това може да бъде направено на един ред, вътр бар = 42. Но само за да се изчистите няколко стъпки, които се случват, декларацията и инициализация се случват отделно тук. Това се случва на една стъпка, и следващата, вътр Баз = бар + 1, това изявление по-долу, че стъпка Баз, така че в края на този кодекс блок ако бяхме да се отпечатва стойността на Баз би било 44 защото ние заявяваме и да я инициализираме да бъде 1 бар> и после го увеличите още веднъж с + +. Минахме през този доста кратко, но е добре да има общ разбиране на какви теми и събития. Ние основно се направи това Scratch така че можеш да се сетиш на теми като няколко поредици от код в същото време. В действителност, това вероятно не работи в същото време, а по-скоро абстрактно можем да мисля за него по този начин. Scratch, например, имахме няколко спрайтове. Тя може да бъде изпълнителен различен код в същото време. Човек може да се разхожда, а другият е да кажа нещо в друга част на екрана. Събитията са друг начин за отделяне на логиката между различните елементи на кода си, и Scratch бяхме в състояние да симулира събития с помощта на излъчване, и това е всъщност, когато получа, а не, когато чуя, но по същество това е начин за предаване на информация от един към друг спрайт. Например, може да искате да предават играта свърши, и когато друг спрайт получи играта, тя реагира по определен начин. Това е важен модел, за да се разбере за програмиране. Само да отида над основния седмица 0, това, което ние сме отишли ​​досега, нека да погледнем на тази проста програма C. Текстът може да бъде малко по-малък от тук, но аз ще отида над него наистина бързо. Ние сме две заглавни файлове на върха, cs50.h и stdio.h. След това определяне на постоянна лимит до 100 години. След това изпълнението на нашата основна функция. Тъй като ние не използват аргументи от командния ред тук трябва да се сложи невалидни като аргументи за основната. Виждаме INT-горе основни. Това е типът на връщане, следователно върне 0 в долния край. И ние използваме CS50 библиотека функция се Int да поиска от потребителя за вход, и ние го съхранява в тази променлива х, така че ние заявяваме, х-горе, и ние го инициализира с х = GetInt. След това проверете, ако потребителят ни даде добър вход. Ако това е ≥ LIMIT искаме да се върне код за грешка от 1 и отпечатване на съобщение за грешка. И накрая, ако потребителят е ни е дал добър вход ние ще площад броя и отпечатате този резултат. Просто за да се уверите, че тези, хит у дома можете да видите етикетите на различни части на код. Споменах Констант, заглавни файлове. О, вътр х. Уверете се, че да се помни, че е локална променлива. Това контрастира от глобална променлива, която ние ще говорим за малко по-късно в рамките на прегледа на сесията, и ние призоваваме библиотека функция ФОРМАТ така че ако не бяхме включени stdio.h заглавен файл нямаше да сме в състояние да се обадя ФОРМАТ. И аз вярвам, че стрелката, която се отсече тук е насочена към% г, форматиране на низ в ФОРМАТ. Той казва отпечатате тази променлива, тъй като редица% г. И това е за седмица 0. Сега Лукас ще продължи. Хей, момчета. Моето име е Лукас. Съм второкурсник в най-хубавата къща в колежа, Mather, и аз отивам да поговорим малко за седмица 1 и 2.1. [Седмица 1 и 2.1!] [Лукас Freitas] Като Lexi казваше, когато започнахме превода код от нулата C едно от нещата, които забелязах е, че можете не само напишете кода си и да го стартирате с помощта на зелен флаг вече. Всъщност, вие трябва да използвате някои стъпки, за да направите вашия C програма се превърне в изпълним файл. По принцип това, което правите, когато сте написването на програмата е, че превод идеята си на език, който може да разбере компилатор така че когато сте написването на програмата в C какво правиш всъщност пишете нещо, което компилатора няма да разбере, и след това компилатора ще преведе този код в нещо, че компютърът ви ще разберат. И това нещо е, че компютърът ви е много тъпо. Вашият компютър може да разбере 0s и 1s Така че всъщност в първите компютри хора, които обикновено са програмирани използване на 0s и 1s, но вече не, благодаря на Бога. Ние не трябва да запомните последователности за 0s и 1s за линия или за известно време контур и така нататък. Ето защо имаме компилатор. Какво компилатор е основно превежда код C, в нашия случай, на език, който вашият компютър ще разбере, , която е обект код и компилатор, който ние използваме се нарича ехтя, така че това е всъщност символ на ехтя. Когато имате вашата програма, което трябва да направите две неща. Първо, вие трябва да компилирате вашата програма, и след това започваш да изпълнявате вашата програма. За да компилирате програмата, имате много възможности да го направят. Първата е да се направи program.c ехтя в коя програма е името на вашата програма. В този случай можете да видите, те просто казват "Хей, съставя програмата ми." Ти не си казва: "Искам това име за моята програма" или нещо. Вторият вариант е да се дава име на вашата програма. Може да се каже ехтя-о, а след това името, което искате изпълнимия файл да бъде назован както и program.c. И вие също може да правят програма, и да видим как в първите два случая Сложих в., и в третия имам само програми? Да, всъщност не трябва да поставят. В., когато използвате. В противен случай компилаторът всъщност се случва да ти крещя. И също така, аз не знам дали вие спомняте, но много пъти ние също използва lcs50 или LM. Това се нарича свързване. Тя просто казва на компилатора, че ще използвате тези библиотеки точно там, така че, ако искате да използвате cs50.h всъщност трябва да въведете ехтя program.c-lcs50. Ако не направим това, компилаторът няма да знаят , че използвате тези функции в cs50.h. А когато искате да изпълнявате вашата програма, имате две възможности. Ако сте направили ехтя program.c вие не дадете име на вашата програма. Трябва да го стартирате. / A.out. A.out е стандартен името, ехтя дава програмата си, ако не му се даде име. В противен случай ти започваш да се направи. / Програма, ако ви е дал име на вашата програма, а също и ако направи програма на име, че програмата ще да се получи вече ще бъдат програмирани същото име като файла в. Тогава говорихме за типове данни и данни. По принцип типове данни са едно и също нещо като малки кутийки, които те използват за съхранение на ценности, така че типове данни всъщност са точно като Pokemons. Те идват във всички размери и видове. Аз не знам дали тази аналогия има смисъл. Размера на данните всъщност зависи от архитектурата на машината. Всички данни, размери, че аз ще покажа тук всъщност са за 32-битова машина, какъвто е случаят на нашия уред, но ако вие всъщност кодиране на вашия Mac или в Windows вероятно ти започваш да имат 64-битова машина, така че не забравяйте, че размера на данните, че аз отивам да се покаже тук са за 32-битова машина. Първата, която видяхме беше вътр което е доста ясен. Можете да използвате INT за съхранение на цяло число. Видяхме характера, Чар. Ако искате да използвате писмо или малък символ, който най-вероятно ще използва Чар. Чар има един байт, което означава, 8 бита, като Lexi каза. По принцип имаме ASCII таблица, която има 256 възможни комбинации на 0s и 1s и след това, когато въвеждате Чар, че ще превежда характер, че входове номер, който имате в ASCII таблица, като Lexi. Ние също имаме поплавък, който ние използваме за съхраняване на десетични числа. Ако искате да изберете 3.14, например, започваш да се използва плувка или двойно по-голяма прецизност. Плаващата платформа има 4 байта. Двойно има 8 байта, така че единствената разлика е прецизността. Ние също имаме дълго време, че се използва за цели числа, и можете да видите за 32-битова машина вътр и дълъг са със същия размер, така че не наистина да има смисъл да се използва дълго време в 32-битова машина. Но ако сте с помощта на Mac и 64-битова машина, всъщност има размер 8, така че наистина зависи от архитектурата. За 32-битова машина няма смисъл да се използва дълго наистина. И тогава много дълго, от друга страна, има 8 байта, така че е много добре, ако искате да имате по-дълго цяло число. И накрая, имаме низ, който всъщност е знак *, което е указател на знака. Това е много лесно да се мисли, че размерът на низа ще бъде като броя на символите, които имате там, но всъщност Чар себе си * размера на показалеца на знака, който е 4 байта. Размерът на Чар * е 4 байта. Няма значение дали имате малък дума или писмо или нещо. Това ще е 4 байта. Ние също така научих малко за леене, така че можете да видите, ако имате, например, една програма, която казва Int х = 3 и след това ФОРМАТ ("% г", Х / 2) вие знаете какво ще да отпечатате на екрана? Някой? >> [Студенти] 2. 1. >> 1, да. Когато направите 3/2 ще получи 1.5, , но тъй като ние сме с помощта на цяло число, че ще игнорира частта от цялото, и ти започваш да има една. Ако не искате това да се случи това, което можете да направите, например, обяви плувка у = х. Тогава х, които са били три, сега щеше да бъде 3.000 в г.. И тогава можете да отпечатате г. / 2. Всъщност, аз трябва да имат два. там. Ще направи 3.00/2.00, и ти започваш да получите 1.5. И ние имаме това 0.2 е само да попитам за две десетични единици в десетичната част. Ако имате 0.3 е, че ще има действително 1,500. Ако е 2, тя ще бъде 1,50. Ние също имаме този случай. Ако го направите плувка х = 3,14 и след това можете ФОРМАТ х ти започваш да се получи 3,14. И ако го направите х = Int от х, което означава лечение на х като едно цяло число и да отпечатате х сега ти започваш да имат 3.00. Това прави ли смисъл? Защото вие сте първият лечение на х като цяло число, така че без да обръща внимание на десетичната част, и след това сте отпечатване. И накрая, можете да направите това, Int х = 65, а след това обяви Чар C = X, и тогава, ако отпечатате в който всъщност ще се получи А, така че в общи линии какво правиш тук превода на цяло число в героя, точно като ASCII таблица. Ние също така говорихме за математически оператори. Повечето от тях са доста ясен, така че +, -, *, /, , а също и ние говорихме за Министерството на отбраната, който е останалата част на разделяне на две числа. Ако имате 10% 3, например, това означава, раздели 10 на 3 и каква е останалата част? Това ще бъде една, така че това е действително много полезно за много от програмите. , За Vigenère и Цезар Аз съм сигурен, че всички от вас, момчета използва мод. За математически оператори, да бъдат много внимателни, когато се комбинират * и /. Така например, ако го направите (3/2) * 2 какво ще да получа? [Студенти] 2. Да, две, защото 3/2 ще бъде 1,5, но тъй като правиш операции между две числа всъщност сте просто ще разгледа 1, и след 1 * 2 ще бъде 2, така че бъдете много, много внимателни когато правиш аритметиката с числа, защото може да се получи, че 2 = 3, в този случай. А също да бъдат много внимателни, за предимство. Обикновено трябва да използвате скоби, за да бъдат сигурни, че знаете какво правите. Някои полезни клавишни комбинации, разбира се, едно е + + или аз + = 1 или използването + =. Това е същото нещо като I = I + 1. Можете също така да правя - или - = 1, , което е едно и също нещо, както аз = I -1, нещо, което вие използвате много за електрически вериги, най-малко. Също така, за *, ако използвате * = и ако го направите, например, I * = 2 е едно и също нещо да казва, че I = I * 2, и също нещо за разделяне. Ако мога / = 2, това е същото нещо като I = I / 2. Сега за функциите. Вие, момчета, научих, че функции са много добра стратегия, за да спаси код докато сте програмиране, така че ако искате да изпълняват същата задача код отново и отново, вероятно искате да използвате функция така че не е нужно да копирате и поставите кода отново и отново. Всъщност, основната е функция, и когато ви покаже формата на функция вие ще видите, че това е доста очевидно. Ние също използваме функции от някои библиотеки, например, ФОРМАТ GetIn, което е от библиотеката CS50 и други функции като toupper. Всички тези функции се прилагат на други библиотеки, и когато тези връзване на файлове в началото на вашата програма казваш, може да ви моля, дайте ми код за изпълнението на тези функции така че аз не трябва да ги изпълнява с себе си? И вие също може да напишете вашите собствени функции, така че, когато започнете програмирането ти осъзнаваш, че библиотеките не разполагат с всички функции, от които имате нужда. За последната pset, например, пише, рисуват, катерене, и търсене, и това е много, много важно да бъде в състояние да напише функции защото те са полезни, а ние ги използва през цялото време в програмирането, и тя спестява много код. Форматът на функция е тази. Връщания тип в началото. Какъв е типът на връщане? Това е просто, когато Ви функция ще се върне. Ако имате функция, например, факторен, , който ще се изчислява факториела на цяло число, вероятно ще се върне цяло число. Тогава типът на връщане ще бъде Int. ФОРМАТ всъщност има невалидни връщания тип защото вие не връщате нищо. Ти си просто отпечатване неща на екрана и отказването на функцията след това. След това имате името на функцията, която можете да избирате. Трябва да бъде малко по-разумно, като не изберете име като XYZ или като x2f. Опитайте се да направите име, което има смисъл. Например, ако това е предпоставки, които казват фактори. Ако това е функция, която ще нарисуваш нещо, кръстете го привлече. И тогава ние имаме параметри, които също са наречени аргументи, които са като ресурсите, които функция трябва от кода си, за да изпълни своята задача. Ако искате да изчислите факториела на число вероятно трябва да има номер, за да се изчисли факториел. Един от аргументите, че започваш да има, е самото число. И тогава той ще направи нещо и да се върнете стойност в края освен ако не е функция празнота. Нека да видим един пример. Ако искам да напиша функция, която сумира всички числа в масив от цели числа, на първо място, типът на връщане ще бъде INT защото имам масив от цели числа. И тогава ще се наложи името на функцията като sumArray, и след това ще вземе със самия масив, за да INT Nums, и тогава дължината на масива, така че знам колко числа трябва да обобщим. След това трябва да се инициализира променлива сума, например, до 0, и всеки път, когато видя елемент в масива трябва да го добави към сумата, така че аз го направих за цикъл. Точно както Lexi каза, нали Int = 0, I <дължина и аз + +. И за всеки елемент в масива сума + = Nums [I], и след това се върнах на сумата, така че е много проста и тя спестява много код ако използвате тази функция много пъти. Тогава взехме погледнете условия. Ние имаме, ако друго, и друго, ако. Нека видим каква е разликата между тези. Обърнете внимание на тези две кодове. Каква е разликата между тях? Първият от тях е основно кодовете искам да кажа Ако даден номер е +, -, или 0. Първият казва, че ако е> 0, тогава това е положително. Ако това е = 0, тогава това е 0, а ако е <0, тогава е отрицателен. А другият се прави, ако, в противен случай, ако друго. Разликата между двете е, че това всъщност ще проверите дали> 0 <0 или = 0 три пъти, така че ако имате 2 броя, например, ще да дойде тук и да каже ако (х> 0), и тя ще каже "да", така че аз отпечатате положителен. Но, въпреки че знам, че това е> 0 и това няма да бъде 0 или <0 Аз съм все още ще е 0, то е <0, така че аз съм всъщност се случва вътре на IFS, че не трябва да защото аз вече знам, че няма да отговаря на някое от тези условия. Мога да използвам, ако друго, ако друго изявление. Това основно се казва, че ако х = 0 отпечатате положителен. Ако не е, аз отивам да тествате това. Ако това е два Отивам да направите това. По принцип, ако имах х = 2 бихте казали ако (х> 0), да, така отпечатате. Сега знам, че това е> 0 и че е изпълнил първо, ако Дори няма да работи този код. Кодът работи по-бързо, всъщност, три пъти по-бързо, ако използвате тази. Ние също така научих за и. Аз няма да мине през това,, защото Lexi вече говорихме за тях. Това е просто && и | | оператор. Единственото нещо, което ще кажа е, бъдете внимателни, когато има три условия. Използвайте скоби, защото това е много объркващо, когато имате състояние и още един или друг. Използвайте скоби, за да се уверите, че вашите условия имат смисъл , защото в този случай, например, можете да си представите, че тя може да бъде първото условие и на една или друга или две условия, съчетани по или третия, така че просто бъдете внимателни. И накрая, ние говорихме за ключове. Превключвател е много полезно, когато имате променлива. Да кажем, че имате променлива като N която може да бъде 0, 1 или 2, както и за всеки от тези случаи ти започваш да се изпълни дадена задача. Може да се каже включите променлива, и това показва, че стойност, то е като value1 аз ще направя това, и след това се счупи, което означава, че няма да изглежда на някой от останалите случаи защото ние вече убеден, че делото и след това стойност2 и така нататък, и аз също да са снабдени с ключ по подразбиране. Това означава, че ако тя не отговаря на някой от случаите, които имах че аз отивам да правя нещо друго, но това е задължително. Това е всичко за мен. Сега нека да Томи. Добре, това ще бъде Седмица 3-Иш. Това са някои от темите, които ще се покрива, крипто, обхват, масиви, и т.н.. Само един бърз дума за крипто. Ние няма да чука на този дом. Ние направихме това в pset 2, но за теста се уверете, че знаете разликата между шифър на Цезар и Vigenère шифър, как и на тези шифри работа и какво е искал да криптирате и декриптиране на текст с помощта на тези две шифри. Не забравяйте, че Цезар шифър просто се върти всеки знак със същата сума, така че да сте сигурни, че Министерството на отбраната на броя на буквите в азбуката. И Vigenère шифър, от друга страна, се върти всеки знак от различно количество, така че вместо да каже всеки герой завърта с 3 Vigenère ще се върти всеки знак с различна сума в зависимост от някои ключови думи където всяка буква в ключовата дума представлява някаква различна сума за да завъртите ясен текст. Нека първо да говори за променливи. Има два различни вида променливи. Имаме локални променливи, а те ще бъдат определени извън основната или извън всяка функция или блок, и те ще бъдат достъпни навсякъде в програмата си. Ако имате функция и тази функция е линия, докато голямата глобална променлива е достъпна навсякъде. Локална променлива, от друга страна, е обхват до мястото, където е дефинирана. Ако имате функция тук, например, ние имаме тази функция грама, и вътре в гр има променлива наречена г., и това означава, че това е локална променлива. Въпреки, че тази променлива се нарича г. и тази променлива се нарича ÿ тези две функции нямат представа какви други локални променливи. От друга страна, тук ние казваме вътр х = 5, и това е извън обхвата на всяка функция. Това е извън обхвата на основния, така че това е глобална променлива. Това означава, че вътре в тези две функции, когато казвам, х - х + + Аз съм достъп до един и същ х като този г. и това г. са две различни променливи. Това е разликата между глобална променлива и локална променлива. Що се отнася до дизайна, понякога това е може би по-добра идея да запазите променливи местно, когато евентуално може тъй като един куп на глобалните променливи може да получите наистина объркващо. Ако имате куп функции всички модифициране на едно и също нещо може да забрави, какво ще стане, ако тази функция случайно променя тази глобална, и това друга функция не знае за това, и тя не получи доста объркващо, тъй като можете да получите повече код. Поддържане на променливи местно, когато евентуално може е просто добър дизайн. Масивите, не забравяйте, са просто списъци на елементи от един и същи вид. Inside CI не може да има списък като 1, 2.0, здравей. Ние просто не можем да направим това. Когато ние заявяваме масив в C всички елементи трябва да са от същия тип. Тук имам масив от три числа. Тук имам дължината на масива, но ако аз съм просто обявяване в този синтаксис където да се уточни какво всички елементи са не технически нужда от това 3. Компилаторът е достатъчно умен, за да разбера колко голям трябва да бъде масив. Сега, когато искате да получите или да настроите стойността на масив това е синтаксис, за да направи това. Това действително ще промени втория елемент на масива, защото, не забравяйте, номерацията започва от 0, а не 1. Ако искам да прочета тази стойност, мога да кажа, нещо като Int х = масив [1]. Или ако искате да настроите тази стойност, като аз правя тук, Мога да кажа, масив [1] = 4. Това време достъп до елементи от техния индекс или си положение или когато те са в масива, и че включването започва от 0. Можем също така да има масиви от масиви, и това се нарича мулти-мерен масив. Когато имаме много-измерен масив това означава, че ние можем да имаме нещо като редове и колони, и това е само един от начините за визуализиране на това или да мисля за това. Когато имам много-измерен масив, това означава, че ще започна да се налага повече от една индекс, защото ако имам мрежа просто казвам какъв ред сте не ни дава номер. Това е наистина само ще ни даде списък на телефонните номера. Да кажем, че имам този масив. Имам масив наречен мрежа, а аз казвам, че е два реда и три колони, и така това е един от начините да го визуализиране. Когато казвам, че искате да получите елемент в [1] [2] това означава, че тъй като това са редове и след това колони Отивам да скочи до ред 1, тъй като казах 1. Тогава аз ще дойда тук, за да колона 2, и аз отивам да получите стойността 6. Уверете се, ли смисъл? Многомерни масиви, не забравяйте, са технически масив от масиви. Ние можем да имаме масиви от масиви от масиви. Ние можем да продължим, но наистина един начин да мислим за това как се определят и какво ще е да се визуализира в мрежата по този начин. Когато минаваме масиви към функции, те започват да се държат малко по-различно, отколкото когато преминават обикновени променливи функции като полагане на вътр или с плаваща запетая. Когато преминават в INT или овъгли или която и да е от тези други данни ние просто се погледнете, ако функцията променя стойността на тази променлива, че промяната няма да се разпространяват на викащата функция. С масив, от друга страна, че ще се случи. Ако премине в масив до известна функция и тази функция се променя, някои от елементите, когато се върна до функция, която се нарича масив ми е сега ще бъде различно, и речник за това е масиви се предават по референция, както ще видим по-късно. Това е свързано с как указатели работа, където тези основни типове данни, от друга страна, се предават по стойност. Ние можем да мислим, че като прави копие на някои променлива и след това преминава в копието. Няма значение какво ще правим с тази променлива. Викащата функция няма да бъде наясно, че това е променено. Масивите са само малко по-различна в това отношение. Например, както току-що видяхме, основната е просто функция , които могат да вземат в два аргумента. Първият аргумент за основната функция е argc, или броя на аргументите, и на втория аргумент се нарича argv, и тези, които са реалните стойности на тези аргументи. Да кажем, че имам една програма, наречена this.c, и казвам направи това, и аз отивам да тичам в командния ред. Сега да премине в някои аргументи за моята програма, наречена това, Бих могъл да кажа нещо подобно / това е CS 50. Това е, което ние си представяме Дейвид да правя всеки ден в рамките на съответния терминал. Но сега основната вътрешната функция на тази програма тези стойности, така argc е 4. Тя може да е малко объркващо, защото наистина сме само бегло е CS 50. Това е само 3. Но не забравяйте, че първият елемент на argv или първият аргумент е името на самата функция. Така че това означава, че има четири неща, и първия елемент ще бъде. / това. И това ще бъде представена като низ. Тогава останалите елементи са това, което сме написали след името на програмата. Така че, точно както настрана, тъй като ние най-вероятно видял в pset 2, не забравяйте, че низът 50 ≠ цяло число 50. Така че не можем да кажем нещо като "Int х = argv 3. Това просто не се случва да има смисъл, защото това е низ, и това е цяло число. Така че, ако искате да конвертирате между две, не забравяйте, ние отиваме да имат тази магия функция, наречена atoi. Това отнема низ и връща цяло число, представени в рамките на тази струна. Така че това е един лесен грешка да направи теста, Просто си мислех, че това ще бъде автоматично правилния тип. Но просто знам, че те винаги ще бъдат струни дори ако низът съдържа само цяло число или символ или число с плаваща запетая. Така че сега, нека поговорим за времето за работа. Когато имаме всички тези алгоритми, които правят всички тези луди неща, става наистина полезно да си зададем въпроса: "Колко дълго те вземат? Ние представляваме, че с нещо, наречено асимптотичната нотация. Така че това означава, че - добре, нека кажем, че ние даваме нашия алгоритъм някои наистина, наистина, наистина голям вход. Ние искаме да си зададем въпроса: "Колко дълго ще да се предприемат? Колко стъпки ще отнеме нашия алгоритъм да тече като функция на размера на входа? Така че първият начин, по който можем да опишем време на изпълнение е с голяма O. И това е нашият най-лошия случай протичане време. Така че, ако искаме да сортирате масив и даваме нашия алгоритъм масив , която е в низходящ ред, когато трябва да бъде във възходящ ред, че ще бъде най-лошия случай. Това е нашата горна граница в максималната дължина на нашия алгоритъм ще се. От друга страна, това Ω ще опишем най-добрия случай времето за работа. Така че, ако ние даваме вече сортиран масив за сортиране алгоритъм, колко време ще отнеме да го оправи? И това, тогава, описва долната граница на времето за работа. Така че тук са само някои думи, които описват някои общи пъти. Те са във възходящ ред. Най-бързо време на работа имаме, се нарича константа. Това означава, че без значение колко елементи даваме нашия алгоритъм, без значение колко голям масив, сортиране или правиш това, което правим, за да масива винаги ще взима същия период от време. Така че можем да декларирате, че само с едно, което е константа. Ние също погледна логаритмична тече в момента. Значи нещо като двоично търсене е логаритмична, където ние нарязани на проблема в рамките на половин всеки път и след това нещата просто получавате по-висока от там. И ако сте някога писмено O на всеки факторен алгоритъм, най-вероятно не трябва да разглеждаме това като деня си работа. Когато сравним пъти, че е важно да се има предвид тези неща. Така че, ако имам алгоритъм, който е O (N), а някой друг е алгоритъм O (2n), те са асимптотично еквивалент. Така че, ако си представим N да бъде голям брой като eleventy милиарда: Така че, когато сравнявате eleventy млрд. нещо подобно eleventy милиарда + 3, внезапно, че 3 не наистина да направи голяма разлика вече. Ето защо ние ще започнат да мислят за тези неща, за да е равна. Така че неща като тези константи тук има 2 X Този, или добавяне на 3, това са само константи, а те няма да се откажа. Така че това е защо всички три от тези, управлявани пъти са едни и същи, като твърдят, че те са O (N). По същия начин, ако имаме два други пъти манш, нека кажем, O (N ³ + 2n ²), ние да добавите + N + 7, и след това имаме друга тече в момента, това е просто O (N ³). отново, те са едно и също нещо, защото тях - те не са едни и същи. Това са същите неща, съжалявам. Така че това са едни и същи, защото ³ N е ще доминират тази 2n ². Какво не е едно и също нещо е, ако ни свършиха пъти, както и O (N ³) и O (N ²) защото това ³ N е много по-голяма от тази ² N. Така че, ако имаме експонати, изведнъж започва да има значение, но когато ние просто се занимават с фактори, тъй като ние сме тук, след това няма да има значение, защото те просто ще отпаднат. Нека да разгледаме някои от алгоритмите, които сме виждали досега и да поговорим за времето си курс. Първият начин търси число в даден списък, че видяхме, е линейна търсене. И прилагането на линейно търсене е супер лесно. Ние просто трябва списък, а ние ще разгледаме всеки един елемент в списъка докато намерим номер търсим. Така че това означава, че в най-лошия случай, това O (N). И най-лошия случай може да бъде, ако елемента е последният елемент, след това с помощта на линейна търсене ние трябва да погледнем на всеки един елемент докато стигнем до последния, за да се знае, че всъщност в списъка. Не можем просто да се откажат по средата и да каже: "Това вероятно не е там." С линейни търсене ние трябва да погледнем към цялото нещо. В най-добрия случай протичане на времето, от друга страна, е постоянна защото в най-добрия случай елемент, който търсим, е първи в списъка. Така че това ще ни отнеме точно 1 стъпка, без значение колко е голям списъка Ако гледаме за първия елемент всеки път. Така че, когато търсите, не забравяйте, че не се изисква да бъдат сортирани, че нашият списък. Защото ние сме просто ще разгледаме всеки един елемент, и това всъщност няма значение какъв ред тези елементи. По-интелигентно търсене алгоритъм е нещо като двоично търсене. Не забравяйте, че изпълнението на двоично търсене е, когато ти започваш да се продължавайте да търсите в средата на списъка. И тъй като ние не търсим в средата, ние изискваме, че списъкът е сортиран или иначе ние не знам къде е средата и ние трябва да погледнем през целия списък да го намерите, и след това в този момент ние просто губене на време. Така че, ако имаме сортиран списък и намери средата, отиваме да се сравни средата до елемента, който търсим. Ако тя е прекалено висока, тогава можем да забравим дясната половина защото знаем, че ако нашата елемент е вече твърде високо и всичко на правото на този елемент е дори по-висок, тогава ние не трябва да се търси там вече. Когато от друга страна, ако ни елемент е твърде ниска, знаем, всичко в ляво на този елемент е твърде ниска, така че не наистина да има смисъл да се търси там,. По този начин с всяка стъпка и всеки път, когато погледнем в средата на списъка, отиваме да ни отрежат проблем в 1/2, защото изведнъж знаем цял куп номера, които не могат да бъдат търсим. В pseudocode това ще изглежда нещо като това, и защото сме рязане на списъка в половината всеки път, нашите най-лошия случай тече в момента скача от линейната логаритмична. Така изведнъж имаме влизане в стъпки, за да открие елемент в списък. В най-добрия случай протичане на времето, обаче, все още е постоянна защото сега, нека просто кажем, че елемент, който търсим, е винаги точно средата на първоначалния списък. Така че ние може да расте в нашия списък по-голям, тъй като ние искаме, но ако елемент, който търсим, е в средата, то тогава само ще ни отнеме 1 стъпка. Така че това е защо ние сме O (дневник н) и Ω (1) или постоянна. Нека всъщност тече двоично търсене в този списък. Така че нека да кажем, че ние не търсим за елемент 164. Първото нещо, което ще направим е да се намери средата на този списък. Просто така се случи, че средата ще попадат между тези две числа, така че нека просто произволно да кажа, всеки път, когато средата попада между две числа, нека просто да закръгли в посока нагоре. Ние просто трябва да сме сигурни, че правим това всяка стъпка от пътя. Така че ние отиваме да закръгли в посока нагоре, и ние ще да кажа, че 161 е в средата на класацията ни. Така че 161 <164, и всеки елемент в ляво от 161 е <164, така че ние знаем, че това няма да ни помогне на всички да започнете да търсите тук, тъй като елемент търсим не може да бъде там. Така че това, което можем да направим, е, че ние може просто да забрави за това цялата лява половина на списъка, и сега разглеждаме само от дясно на 161 нататък. Така че отново, това е средата, нека просто да закръгли в посока нагоре. Сега 175 е твърде голям. Така че ние знаем, че това няма да ни помогне да търсите тук или тук, така че ние може просто да хвърлят това, и в крайна сметка ще удари 164. Всякакви въпроси за двоично търсене? Нека преминем от търсене чрез вече сортиран списък всъщност се списък на телефонните номера в произволен ред и този списък във възходящ ред. Първо алгоритъм погледна се нарича балон вид. И това ще бъде по-опростена на алгоритмите, които видяхме. Bubble вид казва, че когато всеки две елементи в списъка са на място, означава, че има по-голям брой на ляво на по-малък брой, след това отиваме да ги разменят, защото това означава, че списъкът ще бъде "По-подредени", отколкото е било преди. И ние просто ще продължи този процес отново и отново и отново , докато накрая на елементи тип балон за правилното им място и имаме сортиран списък. Време на изпълнение на това ще бъде O (N ²). Защо? Ами, защото в най-лошия случай, ние отиваме да вземе всеки елемент и ние ще се окажете в сравнение с всеки друг елемент в списъка. Но в най-добрия случай, ние имаме вече сортиран списък, балон вид просто ще да мине през веднъж, да кажем "Не. не направи никакви суапове, така съм направил." Така че ние имаме най-добрия случай времето за работа на Ω (N). Нека тече вид балон в списък. Или първо, нека просто погледнете в някои pseudocode наистина бързо. Искаме да кажем, че искаме да следите на всяка итерация на цикъла, да следите дали трябва или не променя всички елементи. Така че причината за това е, отиваме да спре, когато не са сменени всички елементи. Така че в началото на нашата линия не са сменени, нищо, така че ще кажа, че е фалшива. Сега, ние ще отидем в списъка и сравни елемент на елемент + 1 и ако е вярно, че има по-голям брой на ляво по-малък номер, тогава просто щяхме да ги разменят. И тогава отиваме да помним, че разменят елемент. Това означава, че ние трябва да отидем в списъка най-малко още 1 път защото състоянието, в което спряхме, когато целият списък е вече подредени, което означава, че не са направили някакви суапове. Така че защо нашето състояние тук е ", макар някои от елементите са разменени. Така че нека сега просто погледнете това бягане в списък. Имам списъка 5,0,1,6,4. Bubble вид ще започне по целия път от лявата страна, и става за сравнение I елементи, така че 0 до + 1, който е елемент 1. Той ще каже, добре 5> 0, но точно сега 5 е в ляво, така че трябва да сменяте 5 и 0. Когато ги разменят, изведнъж се получи това друг списък. Сега 5> 1, така че отиваме да ги разменят. 5 не е> 6, така че не е нужно да правите нищо тук. Но 6> 4, така че ние трябва да се разменят. Отново, ние трябва да се движат през целия списък, в крайна сметка да открият , че те са на ред, ние ги разменят, и в този момент ние трябва да минава през списъка милион повече време за да се уверите, че всичко е в своето определение, и в този момент вид балон приключи. Различен алгоритъм за вземане на някои елементи и ги сортира е подборът вид. Идеята зад избора Сортиране е, че отиваме да се изгради подредени част от списъка Един елемент в даден момент. И начина, по който отиваме да се направи това е чрез изграждане на левия сегмент на списъка. И в общи линии, всеки - на всяка стъпка, ние отиваме да се вземат най-малкия елемент, ние оставихме , която не е била подредени още, и отиваме да го преместите в тази подредени сегмент. Това означава, че ние трябва непрекъснато да разбера каква е минималната несортирани елемент и след това приемете, че минималния елемент и да го сменяте с каквото най-лявата елемент, който не е сортиран. Време на изпълнение на това ще бъде O (N ²), тъй като в най-лошия случай ние трябва да се сравни всеки един елемент на всеки друг елемент. Защото казвате, че ако започне в лявата половина на списъка, ние се нуждаем да мине през цялата дясна сегмент, за да намерите най-малкия елемент. И тогава, отново, ние трябва да премине цялата дясна сегмент и продължавай, че над и отново, и отново. Това ще бъде н ². Отиваме да се нуждаят от линия вътрешността на друг за контур , което предполага, N ². В най-добрия случай мисъл, нека да кажем, че сме го вече сортиран списък; ние всъщност не правя по-добре от N ². Тъй като избор на вид няма как да знае, че минималния елемент е само една, аз се случи да се търсят в. Тя все още трябва да се уверите, че това е всъщност минимум. И единственият начин да се уверите, че това е минимално, като се използва този алгоритъм, е отново да разгледаме всеки един елемент. Така че наистина, ако ти я дам - ​​ако ви даде избор на вид вече сортиран списък това няма да се направи по-добре, отколкото като списък, който все още не се сортират. Между другото, ако това се случи да се случи, че нещо не е O (нещо) и омегата на нещо, ние може просто да се каже, по-накратко, че това е θ на нещо. Така че, ако видите, че излезе някъде, че това просто означава. Ако нещо е тета на N ², тя е едновременно голяма O (N ²) и Ω (N ²). Така че най-добрия случай и най-лошия случай, той не прави разлика, алгоритъма смяташ да правиш едно и също нещо всеки път. Така че това е какъв pseudocode за избор на сортиране може да изглежда така. Ние сме основно ще кажа, че искам да обхождане на списъка от ляво на дясно, и на всяка итерация на цикъла, аз отивам да се движат минималния елемент в тази сортират част на списъка. И след като се преместя нещо там, аз никога не трябва отново да разгледаме този елемент. Защото веднага след като суап елемент в лявата сегмент на списъка, подредени защото правим всичко, което е във възходящ ред с помощта на минимум. Така че, добре, ние сме и позиция, и ние трябва да погледнем на всички елементи правото на АЗ, за да открие минимум. Така че това означава, че искаме да погледнем от + 1 до края на списъка. И сега, ако елемент, който сме в момента търси е по-малка от нашата минимум досега, , която не забравяйте, ние сме началото на минимално разстояние само за да си каквото елемент сме в момента, ще приемем, че е минималната. Ако намеря един елемент, който е по-малък от този, тогава аз ще кажа, добре, добре, аз не съм намерил нов минимум. Отивам да си спомня къде е този минимум е. Така че сега, след като съм отишъл чрез това право несортирани сегмент, Мога да кажа, че отивам да сменяте минималния елемент с елемент, който е в позицията. Това става да изгради моя списък, подредени част от списъка от ляво на дясно, и ние никога не трябва да се търси елемент отново, след като тя е в тази част. След като сме го разменят. Така че нека да стартирате вид избор в този списък. Синият елемент тук ще бъде I, и червен елемент ще бъде елемент на минимална. Така че аз се започва всичко в лявата страна на списъка, така че на 5. Сега ние трябва да намерим минималната несортирани елемент. Затова ние казваме, 0 <5, така че 0 е моят нов минимум. Но аз не мога да спра там, защото въпреки, че ние можем да признаем, че 0 е най-малкият, ние трябва да тече през всеки друг елемент от списъка, за да се уверите. Така че едно е по-голям, шест е по-голям, 4 е по-голям. Това означава, че след разглеждане на всички тези елементи, аз съм определя 0 е най-малкият. Така че аз отивам да сменяте 5 и 0. След като суап, че аз отивам да се получи нов списък, и аз знам, че никога не трябва да се търси отново в този 0 защото след като веднъж съм го разменят, аз съм го сортират и сме готови. Сега тя просто така се случва, че синята елемент е отново 5, и ние трябва да погледнем в 1, 6 и 4, за да се определи, че 1 е най-малкият елемент на минимална, така че ние ще прекарат 1 и 5. Отново, ние трябва да погледнем в сравнение от 5 до 6 и 4, и отиваме да сменяте 4 и 5, и най-накрая, да сравните тези две числа и ги разменят, докато ще ни сортиран списък. Всякакви въпроси относно избор на вид? Добре. Нека да преминем към последната тема тук, и това е рекурсия. Рекурсия, не забравяйте, това наистина ли е мета нещо функция многократно нарича себе си. Така че в някакъв момент, докато нашият fuction е многократно се обажда, трябва да има някакъв момент, в който ние престанем да се обадите. Защото, ако ние не направим това, тогава ние просто ще продължим да правим това завинаги, и нашата програма просто няма да се прекрати. Ние наричаме това състояние на базата случай. И на база случай се казва, а не отново призовава функция, Аз съм просто ще се върне някаква стойност. Така че след като сме върнали стойност, спряхме да се обадите, и останалата част от поканите, които сме направили досега, може да се върне. Обратното на базовия модел е рекурсивен случай. И това е, когато искаме да извършите друго повикване на функцията, която сме в момента инча И ние вероятно, макар и не винаги, искам да се използват различни аргументи. Така че, ако имаме функция, наречена е, и е току що се обади 1 аргумент, и ние просто да се обадите на е (1), F (1), F (1), и то просто така се случва, че аргумента, 1 попада в рекурсивен случай, ние все още никога не започваш да спре. Дори ако имаме база случай, ние трябва да се уверите, че в крайна сметка ние ще удари този случай база. Ние не просто да остане в този рекурсивен случай. Обикновено, когато ние се наричаме, ние сме най-вероятно ще има друг аргумент всеки път. Тук е много проста рекурсивна функция. Така че това ще изчислим факториела на число. До върха тук имаме нашата база случай. В случай, че N ≤ 1, ние не отиваме да се обадя факториел отново. Отиваме да спре, ние просто ще се върне някаква стойност. Ако това не е вярно, тогава отиваме да удари нашата рекурсивно случай. Забележете, че ние не просто звъните факториел (N), защото това не би било много полезно. Отиваме да се обадя факториела на нещо друго. И така, вие виждате, в крайна сметка, ако ние преминаваме факториел (5) или нещо, отиваме да се обадя факториел (4) и така нататък, и в крайна сметка отиваме да удари този случай база. Така че това изглежда добре. Нека видим какво се случва, когато ние действително стартирате тази. Това е стек, и нека да кажем, че основната Ще се обадя на тази функция с аргумент (4). Така че след като факториел вижда и = 4, факториел ще се нарича. Сега изведнъж, имаме факториел (3). Така че тези функции ще продължават да растат, докато в крайна сметка ние удари нашата база случай. В този момент, връщаната стойност от тази е завръщането (NX връщаната стойност от тази), връщаната стойност от тази е NX връщаната стойност от тази. В крайна сметка ние трябва да се удари някакъв номер. На върха тук, ние казваме връщане 1. Това означава, че след като се върне този номер, можем да се появи това разстояние стека. Така че това факториел (1) се прави. Когато 1 се завръща, този факторни (1) връща, това завръщане към 1. Връщаната стойност от тази, спомням, беше NX връщаната стойност от тази. Така внезапно, този човек знае, че искам да се върна две. Така че не забравяйте, върнете стойността на този е само NX върнатата стойност тук. Така че сега ние може да се каже, 3 х 2, и накрая, тук можем да кажем, това е просто ще бъде 4 х 3 х 2. И след това се връща, ще получите един вътре число на основната. Всякакви въпроси за рекурсия? Добре. Така че има повече време за въпроси, в края на но сега Джоузеф ще покрие останалите теми. [Джоузеф Ong] Добре. Така че сега сме говорили за recursions, нека да поговорим малко за това, което се сливат вид е. Обединяване груб вид е друг начин за сортиране на списък от номера. И как тя работи, с вид сливане имате списък, и това, което правим, е ние казваме, нека се разделим в две половини. Ще изпълните за първи път се слеят вид отново в лявата половина, тогава ще тече сливане нещо в дясната половина, и това ни дава две половини, които са подредени, а сега отиваме да комбинирате тези половини заедно. Това е малко трудно да се види без пример, така че ние ще вършим и да видим какво ще се случи. Така че да започнете с този списък, ние го разделя на две половини. В момента тече сливане нещо в лявата половина първото. Така че това е лявата половина, а сега ние ги управляват чрез този списък отново , която получава премина в вид сливане, и след това ние с нетърпение отново, в лявата страна на този списък и ще свършим сливат нещо върху него. Сега, ние получаваме списък на две числа, и сега лявата половина е дълга само 1 елемент, и ние не можем да разделите списък, който е само 1 елемент в половината, така че можем само да кажа, след като имаме 50, който е само един елемент, това е вече сортирани. След като сме готови с това, можем да видим, че можем се движат в дясната половина на този списък, и 3 се сортират, и сега, когато двете половини на този списък са подредени можем да се присъединят към тези номера отново заедно. Така че ние гледаме на 50 и 3; 3 е по-малък от 50, така че той отива в първо и след това 50. Сега, това е направено, да се върнем до този списък и вид, това е дясната половина. 42 е със собствен номер, така че вече подредени. Така че сега ние ги сравним 2 и 3 е по-малък от 42, така че получава в първия, сега на 42 години получава поставени в и 50 получава пуснати инча Сега, това е сортиран, отиваме по целия път обратно до върха, 1337 и 15. Е, ние сега погледнете в лявата половина на този списък; 1337 е само по себе си, така че те се сортират и с 15. Така че сега ние комбинираме тези две числа да сортирате, че първоначалния списък, 15 <1337, така че отива в първия, а след 1337 отива инча И сега сме сортирали двете половини на първоначалния списък отгоре. И всичко, което трябва да направим, е да съчетае и двете. Очакваме в първите два номера на този списък, 3 <15, така че отива в нещо масив първо. 15 <42, така че той отива. Сега, 42 <1337, който излиза инча 50 <1337, така че той отива. Забележите, че ние просто отне два номера на този списък. Така че ние не просто се редуват между два списъка. Ние просто търсим в началото, и ние сме като елемент че е по-малък, а след това го поставя в нашия масив. Сега сме обединени всички половини и сме готови. Всякакви въпроси, свързани сливат вид? Да? [Student] Ако това е разделяне на различни групи, защо не те просто го разделим веднъж и имате 3 и 2 с група? [Останал въпрос неразбираемо] Причината - така че въпросът е, защо да не можем просто да ги обедините в тази първа стъпка, след като ние ги имаме? Причината можем да направим това, да започне в най-лявата елементи и на двете страни, и тогава се взема по-малка и я сложи в, е, че ние знаем, че това отделните списъци са в сортирани поръчки. Така че, ако аз съм в най-лявата елементи от двете полувремена, Знам, че те ще бъдат най-малките елементи на тези списъци. Така че мога да ги сложа в най-малките петна елемент от този голям списък. От друга страна, ако погледнем на тези два списъка във второто ниво там, 50, 3, 42, 1337 и 15, тези, които не са подредени. Така че, ако погледнем 50 и 1337, аз ще сложа 50 първи в списъка ми. Но това не наистина да има смисъл, защото 3 е най-малкият елемент от всички тези. Така че единствената причина можем да направим това комбиниране стъпка е така, защото нашите списъци вече са подредени. Ето защо ние трябва да слязат по целия път до дъното защото когато имаме само един единствен номер, знаете, че един брой само по себе си вече е сортиран списък. Някакви въпроси? Не? Сложност? Е, можете да видите, че на всяка крачка има крайните числа, и можем да разделим списък в полулогаритмични N пъти, което е мястото, където се получи това N х дневник N сложността. И ще видите най-добрия случай за вид сливане е н дневник N, и то просто така се случва , че най-лошия случай, или Ω там, също е N влезете н. Нещо, което трябва да имате предвид. Продължаваме да вървим в някои супер основен файл I / O. Ако сте разглеждали катеря, ще забележите, имахме някаква система , където можете да напишете в лог файл, ако четете чрез кода. Нека видим как можете да направите. Е, имаме fprintf, които можеш да се сетиш само като ФОРМАТ, но просто отпечатване във файл вместо това, и по този начин е в началото. Този вид код тук, това, което той прави, е, както може би сте виждали в катеря, тя преминава през 2-мерен масив печат, ред по ред, какви са цифрите. В този случай, ФОРМАТ отпечатва до терминала или това, което ние наричаме стандартния изход на раздел. И сега, в този случай, всичко, което трябва да направите, е замени ФОРМАТ с fprintf кажа, че файла, който искате да отпечатате, и в този случай тя просто го отпечатва до този файл вместо да ги извежда до терминала. Е, тогава, че повдига въпроса: Къде сме ние този вид файл от, нали? Минахме влезте в този fprintf fuction но нямахме представа от къде идва. Е, в началото на кода, това, което имахме, беше това парче код тук който основно се казва, че отворите файла призовава log.txt. Какво правим след това е, трябва да се уверите, че файлът е всъщност отвори успешно. Така че може да се провали за няколко причини, не разполагат с достатъчно пространство на вашия компютър, например. Така че тя винаги е важно, преди да направи всякакви операции с файла че ние проверяваме дали този файл е отворен успешно. Така че какво, това е аргумент за fopen, добре, можем да отворите файл по много начини. Какво можем да направим, можем да го премине w, което означава предимство файла, ако то излезе вече, Ние можем да минем а, които те да приложи към края на файла, вместо да го първостепенен, или можем да определим R, което означава, да отворите файла само за четене. Така че, ако програмата се опитва да прави всякакви промени във файла, крещи към тях и не им позволявайте да го направя. Накрая, след като приключите с файла, съставено изпълняваме операции, ние трябва да сме сигурни, че затворете файла. И така, в края на програмата, ще отново да ги предаде този файл, който сте отворили, а просто го затворите. Така че това е нещо важно, което трябва да се уверете, че правя. Така че, не забравяйте, можете да отворите файл, след това можете да пишете на файла, направи операции във файла, но тогава ще трябва да затворите файла в края. Всякакви въпроси относно основните файл I / O? Да? [Student въпрос, неразбираем] Точно тук. Въпросът е, откъде идва тази log.txt файл се появи? Е, ако просто го даде log.txt, тя създава в същата директория, като изпълним. Така че, ако вие сте - >> [Student въпрос, неразбираем] Да. В същата папка, или в същата директория, както ти го наричаш. Сега памет, стек, и куп. Е, как е паметта, в компютъра? Е, можете да си представите паметта като нещо на този блок тук. И в паметта имаме това, което се нарича купчина остана там, и топчето, че е там. И куп расте надолу и стека расте нагоре. Така че, както Томи спомена - Е, добре, и ние имаме тези 4 сегменти, които ще получите в секунда - Томи каза по-рано, вие знаете как неговите функции, които наричат ​​себе си и наричат ​​помежду си? Те изграждат този вид стак рамка. Е, ако основните разговори Foo Foo получава на стека. Foo призовава бар, бар получите на стека, и че получава в стека след И тъй като те се връщат, всеки от тях се вземат стека. Какво всяко от тези места и паметта държи? Е, на върха, която е текстът сегмент, съдържа самата програма. Така машинен код, който е там, след като компилирате вашата програма. На следващо място, всеки инициализира глобални променливи. Така че трябва глобални променливи във вашата програма, а вие казвате, а = 5, , които получава в този сегмент, и точно под това, имате някакви неинициализирани глобални данни, което е само INT, но не казват, че е равно на нищо. Осъзнайте, това са глобални променливи, така че те са извън основната. Така че това означава всички глобални променливи, които са обявени, но не се инициализира. Така че това, което е в купчина? Memory разпределят чрез използването на изчистване, който ние ще стигнем до по малко. И накрая, с стека имате някакви локални променливи и всички функции, може да се обадите в някоя от техните параметри. Последното нещо, което не ми трябва да знам какво правят на околната среда променливи, но всеки път, когато стартирате програмата, е свързана с нещо, подобно на това е име на човек, който се притекъл на програмата. И това ще бъде нещо като в долната част. По отношение на адреси от паметта, които са шестнадесетични стойности, стойностите на върха започват от 0 и те отиват по целия път надолу към дъното. В този случай, ако сте на 32-битова система, адреса, на дъното ще бъде 0x, следвана от AF, защото това е 32 бита, , което е 8 байта, и в този случай 8 байта съответства на 8 шестнадесетични цифри. Така че тук сте ще има, като 0xFFFFFF и там започваш да имате 0. Така че това, което са указатели? Някои от вас не може да са покрили това в раздел преди. но мина над него в лекцията, така че показалецът е само тип данни магазини, вместо на някаква стойност, като 50, тя съхранява адреса на някакво място в паметта. Като че паметта неразбираемо. Така че в този случай, това, което е, ние имаме указател към цяло число или INT * и съдържа този шестнадесетичен адрес на 0xDEADBEEF. Така че това, което имаме, е, сега, този указател точки в някакво място в паметта, и това е само една, на стойност 50 е на това място в паметта. На някои 32-битови системи, на всички 32-битови системи показалки заемат 32 бита или 4 байта. Но, например, на 64-битова система, указатели са 64 бита. Така че това е нещо, което ще искате да имате в предвид. Така че по-битова система, указател е краят бита дълго. Указатели са нещо трудно за храносмилане, без допълнителни неща, така че нека продължим чрез пример за динамично разпределение на паметта. Какво прави за вас динамично разпределение на паметта, или това, което ние наричаме изчистване, тя ви позволява да заделят някакъв вид данни извън снимачната площадка. Така че тези данни е нещо по-постоянно за продължителността на програмата. Защото както знаете, ако Вие декларирате х рамките на функция и тази функция се връща, вече нямате достъп до данни, които са съхранени в х. Какво указатели нека направим, е, че те нека съхранява памет или магазин стойности в различен сегмент на паметта, а именно на куп. Сега, след като се върнем от функция, толкова дълго, тъй като ние имаме показалеца на това място в паметта, а след това какво можем да направим, е, че ние може просто да погледнете стойностите там. Нека разгледаме един пример: Това е нашата памет оформление отново. И ние имаме тази функция, главната. Какво го прави е - добре, толкова просто, нали? Вътр х = 5, това е само една променлива в стека в основната. От друга страна, сега ние заявяваме указател, който нарича функция giveMeThreeInts. И така, сега отиваме в тази функция и ние създаваме нова рамка стека за. Въпреки това, в тази стека рамка, ние заявяваме INT * темп, които в mallocs три числа за нас. Така размер на вътр ще ни даде колко байта това число е, и изчистване ни дава много байтове пространство на куп. Така че в този случай, ние сме създали достатъчно пространство за три числа, и грамада е там, поради което съм го изготвя по-нагоре. След като сте готови, ще се върнем тук, трябва само да върнат три цели числа, и го връща на адреса, в този случай, че паметта е. И ние показалеца = ключ, и там имаме само друг показалеца. Но какво, че функцията връща се подрежда тук и изчезва. Така темп изчезва, но ние все още поддържаме адрес на мястото, където тези три числа са вътре в мрежата. Така че в този набор, указатели са обхванати локално за нагласената рамка, но споменът за които се отнасят, е в куп. Това прави ли смисъл? [Student] Бихте ли повторили? >> [Йосиф] Да. Така че, ако се върна само малко, ще видите, че темп разпределени някои памет на куп там. Така че, когато тази функция, giveMeThreeInts връща, тази стека тук ще изчезне. И с някоя от променливите, в този случай, този указател, която е разпределена в стер рамка. Това ще изчезнат, но тъй като ние се върнахме темп и показалеца = Temp, показалеца сега ще посочим същата памет, на мястото, като температура. Така че сега, въпреки че ние губим темп, че местните показалеца, ние все още запазват адресната памет на това, което сочи към вътрешността на тази променлива показалеца. Въпроси? Това може да бъде вид на объркващо тема, ако не сте отишъл в раздел. Ние можем да си TF определено ще премине и разбира се можем да отговорим на въпроса в края на прегледа сесия за тази. Но това е вид на сложна тема, а аз имам още примери, които предстои да се появи , който ще помогне да се изяснят Какво всъщност са указатели. В този случай, указатели са еквивалентни на масиви, така че може просто да използвате този указател като едно и също нещо като INT масив. Така че аз съм индексиране на 0, и промяна на първото число 1, промяна на второто число на 2 и 3-то число 3. Така че по-указатели. Е, припомни Binky. В този случай ние сме разпределени показалеца, или обявен за показалеца, но първоначално, когато току-що обяви показалеца, това не е насочена навсякъде в паметта. Той е само боклук стойности вътре в него. Така че аз нямам представа къде този указател сочи към. Той има адрес, който е просто изпълнен с 0 и 1, където тя първоначално бе обявено. Не мога да направя нищо с това, докато аз наричам изчистване на и след това ми дава малко място на куп, където мога да сложа стойности вътре. И все пак, аз не знам какво е вътре в тази памет. Така че първото нещо, което трябва да направите, е да проверите дали системата има достатъчно памет да ми даде 1 число на първо място, поради което аз правя тази проверка. Ако показалецът е нула, което означава, че не разполагат с достатъчно пространство или някаква друга станала грешка, така че трябва да излезете от програмата ми.  Но ако го е направил успее, сега мога да използва тази показалеца и какво * показалеца е, когато адресът е до мястото, където тази стойност е, и го постави на равна на 1. Така че тук, ние сме проверка, ако тази памет. След като знаем, че съществува, можете да поставите в него каква стойност искате да поставите в него, в този случай 1. След като сме готови с нея, трябва да освободите че показалеца защото ние трябва да се върнем към системата, която памет, която поиска на първо място. Тъй като компютърът не знае, когато сме готови с него. В този случай ние изрично го казвам, добре, ние сме направили с този спомен. Ако някой друг процес се нуждае от някоя друга програма се нуждае от нея, не се колебайте да вървим напред и да го вземе. Това, което ние можем да направим, е, че ние може просто да получите адреса на локални променливи на снимачната площадка. Така INT х е вътре подредени рамките на главната. И когато ние използваме този символ, това и оператор, това, което той прави, е е необходимо х и х е само някои данни в паметта, но има адрес. Той е разположен някъде. Така че, като се обадите & X, какво прави тя ни дава адреса на х. По този начин, ние правим показалеца точка където х е в паметта. Сега ние просто нещо като * X, ние отиваме да получите 5 гърба. Звездата се нарича го dereferencing. Последвайте адреса и можете да получите на стойност от него се съхранява там. Някакви въпроси? Да? [Student] Ако не направите три лъча нещо, не тя все още компилирам? Да. Ако не направи 3 тройки нещо, тя все още продължава да съставят, но аз ще ви покажа какво се случва в секунда, и без да се прави това, това е, което ние наричаме памет течове. Вие не даваме системата архивирате паметта си, така че след известно време програмата е да се натрупват памет, която не използва, и нищо друго не може да го използвате. Ако някога сте виждали Firefox с 1,5 милиона килобайта на вашия компютър, в диспечера на задачите, това е какво се случва. Имате памет течове в програмата, че те не са работа. Е, как показалеца аритметика работа? Е, показалецът на аритметиката е нещо като индексиране в масив. В този случай, имам указател, и това, което правя е, че показалеца точка за първия елемент на този масив на три числа, които съм разпределени. Така че сега това, което правя, звезда показалеца просто променя първият елемент в списъка. Star показалка една точки тук. Така че показалецът е тук, показалецът на един е тук, показалецът 2 е тук. Така че просто добавяне на 1 е същото като да се движат по този масив. Какво правим, когато правим показалеца един можете да получите на адрес тук, и, за да получите стойността тук, вие поставяте звезда от целия израз да го сочените файлове. Така че, в този случай, аз съм за определяне на първото място в този масив 1 второто място на 2, и трето място 3. Тогава какво правя тук е, че аз съм печат показалеца един, която току-що ми дава 2. Сега увеличаване показалеца, така че показалецът се равнява на показалеца един, който се движи напред. И така, сега, ако разпечатате показалеца един показалеца едно сега е 3, която в този случай се отпечатва 3. И с оглед на свободно нещо, показалеца, че аз я давам трябва да се посочи в началото на масив, който се върнах от изчистване. Така че, в този случай, ако мога да се обадя три тук, това не би било правилно, , защото това е в средата на масива. Аз трябва да се изважда, за да стигнем до първоначалното местоположение първоначалния първото място, преди да мога да го освободи. Така че, тук е по-сложен пример. В този случай, ние сме разпределяне на 7 герои в герой масив. И в този случай това, което правим, е, че ние примка през първите 6 от тях, и ние сме ги, за да Z. Така че, за Int = 0, I> 6, аз + +, Така че, показалеца + I просто ще ни даде, в този случай, показалеца, една показалка, показалецът 2, показалецът на 3 и така нататък и така нататък във веригата. Какво ще направи той получава този адрес, dereferences да получите стойността, и промените в тази стойност до Z. След това в края не забравяйте, това е низ, нали? Всички струни трябва да завършва с нула прекратяване характер. Така че, това, което правя, е да показалка 6 Сложих нулевата характер терминатор. И сега това, което аз съм основно правиш тук изпълнява ФОРМАТ за низ, нали? Така че, когато ФОРМАТ сега, когато той е достигнал края на низ? Когато го удари нула прекратяване характер. Така че, в този случай, моите оригинални показалецът се посочва началото на този масив. Отпечатване на първата характер. Го преместите повече от една. Отпечатвам този характер. Да го преместите. И продължаваш да правиш това, докато не стигнат до края. И сега показалеца края * ще сочен и да получите нула прекратяване характер. И така моята линия, докато тече само когато тази стойност не е нула прекратяване характер. Така че, сега аз излезете от този цикъл. И така, ако аз се изважда 6 от този указател Отивам назад чак до началото. Не забравяйте, че правя това, защото аз трябва да отида в началото, за да го освободи. Така че, аз знам, че е много. Има ли някакви въпроси? Моля, нали? [Студентски неразбираем въпрос] Може ли да се каже, че по-силно? Извинете. [Student] На последния слайд, точно преди да освободи показалеца, , където са били действително се променя стойността на показалеца? [Йосиф] Така че, точно тук. >> Студентски] О, добре. [Йосиф] Така че, имам указател минус минус, нали, който се движи нещо назад с едно, а след това го освободи, трябва да се подчертае, защото този указател към началото на масива. [Student] Но това няма да бъде необходима е спряна, след като тази линия. [Йосиф] Така че, ако бях спрял след това, това ще се счита изтичане на памет, защото аз не пуснете безплатно. [Student] [неразбираемо след първите три реда, където трябваше показалеца един неразбираем]. [Йосиф] Аха. И така, какво е въпросът там? Извинете. Не, не. Давай, давай, моля. [Student] Така че, не променя стойността на указатели. Може би не трябваше да правя показалеца минус минус. [Йосиф] Да, точно така. Така че, когато показалеца на една и показалеца 2, Аз не правя показалеца се равнява на показалеца едно. Така че, показалеца просто остава посочи в началото на масива. Това е само, когато правя плюс плюс, че той определя стойността обратно вътре показалеца, , че в действителност се премести заедно. Добре. Още въпроси? Отново, ако това е нещо огромно, това ще бъдат покрити в сесия. Посъветвайте се с Вашия колега учение за него, и да можем да отговорим на въпроса в края. И обикновено ние не обичаме да направите това минус нещо. Това трябва да изискват от мен следене на колко съм се компенсира в масива. Така че, като цяло, това е само за да обясни как работи аритметиката с указатели. Но това, което ние обикновено искали да направите, ние бихме искали да се създаде копие на показалеца, и след това ще използвате това копие, когато сме се движи в низа. Така че, в тези случаи да използвате копието да отпечатате целия низ, но ние не трябва да направите, като показалеца минус 6 или да следите колко ние се преместихме в това, само защото ние знаем, че нашата отправната точка все още се посочи в началото на списъка и всичко, което сме променили това копие. Така че, като цяло, да променя копия на оригинални показалеца. Не се опитвайте да нещо като - не ... променя оригинални екземпляра. Опитвам се да променя само копия на оригиналните ви. Така че, можете да забележите, когато минаваме покрай низ в ФОРМАТ не е нужно да се сложи звезда пред него, както направихме и с всички други dereferences, нали? Така че, ако разпечатате целия низ% S очаква адрес, и в този случай указател или в този случай като масив от знаци. Символи, Чар * и масиви са едно и също нещо. Pointer е до знака и характер масиви са едно и също нещо. И така, всичко, което трябва да направим, е да премине в показалеца. Ние не трябва да мине като * показалеца или нещо подобно. Така че, масиви и указатели са едно и също нещо. Когато правиш нещо подобно х [Y] тук за масив, какво прави под капака е казва, добре, това е знак, масив, така че това е показалеца. И така, х са едно и също нещо, и така това, което прави, е добавя база до х, което е същото като да се движи напред в паметта, което много. И сега X + Y ни дава някакъв адрес, и ние сочените от адреса или следвайте стрелката когато това място в паметта и получаваме стойността на това място в паметта. Така че, тези двамата са точно едно и също нещо. Това е просто една синтактична захар. Те правят същото нещо. Те са просто различни дял от математиката един за друг. И така, какво може да се обърка с указатели? Например, много. Добре. Така че, лоши неща. Някои лоши неща, които можете да направите, не се проверка,, ако вашият изчистване повикване връща нула, нали? В този случай, аз искам системата да ми дадете - какво е това число? Подобно на 2 милиарда пъти 4, тъй като размерът на целите числа е 4 байта. Аз го питам като 8 милиард байта. Разбира се, компютърът ми не ще да бъде в състояние да ми даде, че много назад с памет. И ние не проверите дали това е нищожна, така че, когато ние се опитваме да го сочен там - Следвайте стрелката до мястото, където ще - ние не разполагат с тази памет. Това е, което ние наричаме dereferencing нулев указател. И това същество ви кара да segfault. Това е един от начините, можете да segfault. Други лошите неща, които можете да направите - о. Това беше dereferencing с нулев указател. Добре. Други лоши неща - добре, за да се определи, че просто сложете отметка там проверява дали показалецът е нищожна и да излезете от програмата, ако това се случи, че изчистване връща нулев указател. Това е xkcd комикс. Хората го разбират. Донякъде. Така че, памет. И аз отидох над това. Ние призоваваме изчистване в една линия, но всеки път, когато ние наричаме изчистване ние губим следите, когато това показалецът сочи, защото ние сме го clobbering. И така, първоначалната покана за изчистване ми дава памет тук. Показалецът указатели за това. Сега, аз не го освободи, така че сега аз наричам изчистване отново. Сега той посочва тук. Сега моята памет е насочена тук. Посочвайки тук. Посочвайки тук. Но аз съм изгубил следите на адресите на всички тук, че аз разпределени памет. И така, сега аз не всяко позоваване на тях вече. Така че, аз не мога да ги освободи извън този цикъл. И така, за да се определи нещо подобно, ако сте пропуснали да освободите памет и да получите тази памет течове, Трябва да освободите памет в рамките на този цикъл, след като сте готови с него. Е, това е, което се случва. Знам, че много от вас, мразя това. Но сега - Уау! Можете да получите като 44000 килобайта. Така че, можете да го освободи в края на цикъла, и че просто ще освободи памет всеки път. Същество, вашата програма не изтичане на памет вече. И сега нещо друго, което може да направите, е да освободите памет, която сте поискали за два пъти. В този случай, изчистване на нещо, промяна на стойността. Го освободи веднага, защото ти каза, че са били извършени с него. Но след това го освободил. Това е нещо, което е доста лошо. Това няма първоначално да segfault, но след известно време какво това не е двойно освобождаването това развращава куп структура, и вие ще научите малко повече за това, ако решите да се вземе един клас като CS61. Но по същество след известно време компютърът ви е да се бърка за паметта са там, където и когато той се съхранява - когато данните се съхраняват в паметта. И така, освобождаването на показалеца два пъти е лошо нещо, което не искам да правя. Други неща, които могат да се объркат не се използва sizeof. Така че, в този случай изчистване 8 байта, и това е едно и също нещо като две числа, нали? Така, че е напълно безопасно, но е? Ами, тъй като Лукас говорихме на различни архитектури, числа са с различна дължина. Така че, на уреда, че използвате числа са около 4 байта, но по някаква друга система може да бъде 8 байта или те могат да бъдат 16 байта. Така че, ако аз просто използвайте този номер тук, тази програма може да работи на уреда, но това няма да се разпределят достатъчно памет на някаква друга система. В този случай, това е, което операторът sizeof се използва за. Когато ние наричаме sizeof (INT), какво прави това  тя ни дава размера на цяло число на системата, която се изпълнява програмата. Така че, в този случай, sizeof (INT) ще се върне 4 от нещо подобно на уреда, и сега тази воля 4 * 2, което е с 8, който е само на размера на пространството, необходимо за две цели числа. На друга система, ако число е като 16 байта или 8 байта, това е просто ще се върне достатъчно байта за съхраняване на тази сума. И накрая, structs. Така че, ако искате да съхранявате судоку съвет в паметта, как бихме могли да направим това? Може би си мислите като променлива за първото нещо, променлива за второто нещо, променлива за третото нещо, променлива за четвъртото нещо лошо, нали? Така че, едно подобрение, което можете да направите в началото на тази е да се направи 9 х 9 масив. Това е добре, но какво ще стане, ако искаш да се сдружават с други неща с борда на судоку харесва това, което трудността на борда е, или, например, каква е вашата оценка е или колко време е взето за решаване на този форум? Е, това, което можеш да направиш е да можете да създадете структура. Това, което аз съм основно казват, е, че се определи тази структура тук, и аз съм определяне на судоку съвет, който се състои от борд, който е 9 х 9. И какво е има указатели към името на нивото. Тя също има X и Y, които са координатите на мястото, където съм сега. Той също така е времето, прекарано [неразбираем], и има общия брой ходове съм въведените досега. И така, в този случай, мога да групирате цял куп данни само в една структура вместо да го сякаш летя около като различни променливи че не мога наистина да следите. И това ни позволява да има само хубаво синтаксис за нещо на съотнасяне на различни неща вътре в тази структура. Мога само да направя board.board, и аз се судоку дъската. Board.level, аз се колко е трудно. Board.x и board.y ми даде координатите на мястото, където мога да бъда в борда. И така, аз съм достъп до това, което ние наричаме полета в структурата. Това определя sudokuBoard, която е един вид, че имам. И сега сме тук. Имам променлива, наречена "борда" от тип sudokuBoard. И така, сега мога да получите достъп до всички области, които правят тази структура тук. Всякакви въпроси за structs? Да? [Student] Int X, Y, обявена на един ред? >> [Йосиф] Аха. [Student] Така че, може просто направи това с всички тях? Като в X, Y запетая пъти, че общо? [Йосиф] Да, определено може да направи това, но причината Сложих х и у по същата линия - и въпросът е защо можем да го направим по същата линия? Защо просто не сложи всичко това на същата линия е х и у са свързани един с друг, и това е само стилистично по-правилно, в известен смисъл, защото това е групиране на две неща по една и съща линия , че подобно нещо се отнасят до едно и също нещо. И аз просто се разделят тези разпада. Това е просто стил нещо. Това функционално прави никаква разлика, каквато. Някакви други въпроси на structs? Можете да определите Pokédex с структура. Pokémon има номер и да го има писмо, собственик, вид. И тогава, ако имате набор от Pokémon, можете да направите на Pokédex, нали? Добре, готин. Така че, въпроси върху structs. Това са свързани с structs. И накрая, GDB. Какво GDB ви позволи да направите? Тя ви позволява да отстранявате грешки във вашата програма. И ако не сте използвали GDB, бих препоръчва гледане на кратко и само над това, което GDB, как се работи с нея, как бихте могли да го използвате, и да го тестваме по програма. И така, какво GDB ви позволява да направите е, тя позволява пауза [неразбираем] програмата си и практически линия. Например, аз искам да пауза изпълнение, като линия 3 от моята програма, и докато аз съм в ред 3 могат да се изведат всички стойности, които са там. И така, това, което ние наричаме като пауза в една линия е ние наричаме това сложи точка на прекъсване на този ред и след това да отпечатате на променливите на състоянието на програмата по това време. Ние можем след това от там стъпка чрез програмата ред по ред. И тогава ние можем да погледнем състоянието на стека по това време. И така, за да използвате GDB, това, което правим, е да се обадя ехтя на файла C, но ние трябва да го давате на ggdb флаг. И след като сме готови с това, ние просто стартирате GDB върху получения изходния файл. И така, можете да получите някои маса на текст като този, но наистина всичко, което трябва да направите е да напишете командата в началото. Почивка главната поставя точка на прекъсване на главната. Списък 400 изброява реда код около линия 400. И така, в този случай може просто да се огледам и да кажа, о, Искам да зададете точка на прекъсване на линията 397, която е тази линия, и след това програмата работи в тази стъпка и че ще ходи да се счупят. Това ще пауза там, и можете да отпечатате, например, стойността на ниско или високо. И така, има един куп от команди, които трябва да знаете, и това слайдшоу ще отидат на сайта, така че ако просто искате да се обърнете тях или като ги поставя на вашите мамят листове, не се колебайте. Cool. Това беше Quiz Review 0, и ние ще се придържаме наоколо, ако имате някакви въпроси. Добре.  [Аплодисменти] [CS50.TV]