[Powered by Google Translate] [Дел 5: помалку удобно] [Нејт Hardison, Универзитетот Харвард] [Ова е CS50.] [CS50.TV] Па добредојде назад, момци. Добредојдовте во делот 5. Во овој момент, откако заврши квиз 0 и ја видел како сте го направиле, се надевам да се чувствувате навистина добро, бидејќи јас бев многу импресиониран од резултатите во оваа секција. За нашата онлајн гледачите, имавме неколку прашања за последните два проблема на проблемот во собата - или на квизот, а. Па ние ќе одиме во текот оние навистина брзо, така што секој го гледа она што се случи и како да одат низ вистински решение, а не само на гледање на решение себе. Ние ќе одиме во текот на последните неколку проблеми навистина брзо, 32 и 33. Само, повторно, така што онлајн гледачите може да се види тоа. Ако се свртиме кон вашиот проблем 32, кој е на страница 13, 13 од 16, проблемот 32 е за сите свопови. Сето тоа е за Замена на два цели броја. Тоа е проблем што ние би отишол во текот на неколку пати во предавањето. И овде, она што се бара да направите е брз меморија трага. За пополнување на вредности на променливи како што се на магацинот како код оди преку оваа swap функција. Поточно, она што го барате во - I'm случува да се стави оваа iPad надолу - особено, она што го барате на е оваа линија нумерирани 6 право тука. И тоа е нумерирана 6 за само непосредна близина со претходниот проблем. Она што сакаме да направите е да се прикаже или етикета на состојбата на меморијата како што е во времето кога ние се изврши оваа линија број 6, која е ефикасно враќање од нашите swap функција овде. Ако ние дојдете тука, видовме дека на адресите на сè во меморија е обезбедена за нас. Ова е многу клучна, ние ќе се вратам на тоа во само еден миг. А потоа надолу тука на дното, имавме малку меморија дијаграм кој ние ќе се однесуваат. Јас всушност се направи ова на мојот iPad. Па ќе одам да го менува назад и напред меѓу iPad и овој код само за референца. Да почнеме. Прво, да се фокусираат на првите неколку линии на главната овде. За почеток, ние ќе треба да се иницијализира на X да ја 1 и y до 2. Значи имаме две целобројни променливи, тие двете ќе биде ставен на магацинот. Ние ќе се стави 1 и 2 во нив. Значи, ако јас флип над да мојот iPad, се надевам, да видиме - Apple TV mirroring, и таму ќе одиме. Во ред. Значи, ако јас флип над да мојот iPad, Сакам да се иницијализира на X да ја 1 и y до 2. Тоа го правиме сосема едноставно со пишување на 1 во кутија обележана x и 2 во кутија обележана y. Прилично едноставна. Па сега ајде да се вратиме на лаптоп, да видиме што ќе се случи следно. Значи ова следната линија е местото каде што работите се слабо. Ние помине на адресата на x и адресата на y како параметрите a и b на swap функција. Адресата на x и адреса на y работи кои не можеме да се пресмета без однесуваат на овие bullet поени право надолу тука. И за среќа, на првите две точки да ни кажете што точно одговори се. Адресата на x во меморија е 10, а на адреса на y во меморија е 14. Значи тоа се вредности кои се донесени во што a и b до врвот во нашата swap функција. Значи, повторно, прекинувачки назад кон нашите дијаграм, можам да пишувам 10 во и 14 во б. Сега, оваа точка е местото каде што продолжи со размена. Значи гледаме назад на лаптоп повторно, можеме да видиме дека начинот на swap работи е првпат Dereference на и чување на резултат во мали. Па Dereference оператор вели: "Еј. Однесувајте се кон содржината на променливата а како адреса. Оди до она што се чуваат на таа адреса, и оптоварување тоа. " Што ќе се вчита од променливата ќе се чуваат во нашата мали променлива. Нервира назад кон iPad. Ако одиме да се обрати 10, знаеме кои се однесуваат на 10 е varible x бидејќи ни беше кажано од страна на нашите куршум точка дека на адресата на x во меморија е 10. За да можеме да одиме таму, да добијат вредност од неа, кое е 1, како што гледаме на нашите iPad, и оптоварување тоа во мали. Повторно, ова не е финална содржина. Ние ќе одиме преку и ние ќе дојдеме до нашата крајна состојба на програмата на крајот. Но, токму сега, ние имаме вредност 1 чуваат во мали. И таму е брзо станува збор овде. [Александар] е Dereference оператор - тоа е само ѕвезда право во предниот дел на променлива? >> Да. Па Dereference оператор, како што флип назад кон нашите лаптоп уште еднаш, е оваа ѕвезда право напред. Во таа смисла, тоа е - што се спротивставиме со множење оператор која бара две работи, а Dereference оператор е унарни оператор. Само применува една вредност што е спротивно на бинарни оператор, каде што се однесуваат на две различни вредности. Значи тоа е она што се случува во оваа линија. Ние натоварен вредност 1 и чуваат тоа во нашата привремена целобројна променлива. Следната линија, ние зачувување на содржините на б во - или, поточно, ние зачувување на содржините кои б е да се покажува во местото каде што се укажува на. Ако ги анализираме овој од десно кон лево, ние ќе се Dereference б, ние ќе се обрати 14, ние ќе се обидеме да го дофати број кој е таму, и тогаш се случува да одат на адреса 10, и ние се случува да се фрли резултат на нашата Dereference на б во тој простор. Нервира назад кон нашите iPad, каде што може да се направи ова е малку поконкретни, тоа би можело да помогне ако јас пишувам броеви на сите на адреси тука. Па знаеме дека во y, ние сме на адреса 14, x е на адреса 10. Кога ќе почне во б, ние Dereference б, ние ќе треба да го дофати вредност 2. Ние ќе се обидеме да го зграби оваа вредност, бидејќи тоа е вредност, која живее на адреса 14. И ние ќе го стави во променлива која живее на адреса 10, кој е во право таму, што одговара на нашите променливата x. Значи можеме да направиме малку пребрише тука каде што ние да се ослободиме од нашите 1 и наместо ние пишуваме на 2. Па сите е добро и добро во светот, иако ние сме препишани x сега. Имаме чуваат старата вредност на x во нашите мали променлива. Значи можеме да заврши на swap со следната линија. Нервира назад кон нашите лаптоп. Сега сите што останува е да се земе на содржината надвор од нашата привремена целобројна променлива и ги чува во променлива која живее на адресата која б држи. Така ние ќе ефикасно Dereference b за да добиете пристап до променливата која е на адресата што б има во него, и ние ќе работи вредноста што tmp држи во неа. Нервира врати на iPad уште еднаш. Јас може да ја избрише оваа вредност тука, 2, и наместо тоа ќе копирате 1 право во неа. Тогаш следната линија кој извршува, се разбира - ако флип назад на лаптоп - е оваа точка 6, која е точката во која сакавме да имаме дијаграм целосно пополнети. Значи гледаме назад на iPad уште еднаш, само така може да се види завршен дијаграм, можете да видите дека ние имаме 10 во а, 14 во б, 1 во мали, 2 во X, и 1 во y. Дали постојат било какви прашања во врска со ова? Дали ова го направи повеќе смисла, откако влезе низ неа? Направи помалку смисла? Се надевам дека не. Во ред. Покажувачи се многу незгодно тема. Еден од момците ние работиме со има многу честа изрека: "За да се разбере совети, прво мора да се разбере совети." Што мислам дека е многу точно. Тоа го прави да потрае некое време да се навикнеш на него. Ждрепка на слики, ждрепка на меморија дијаграми како овој се многу корисни, и откако ќе прошетка низ пример по пример по пример, тоа ќе почне да се направи малку повеќе разум и малку повеќе разум и малку повеќе смисла. Конечно, еден ден, ќе имате сето тоа целосно владее. Било какви прашања пред да се движи кон следниот проблем? Во ред. Значи флип назад на лаптоп. Следниот проблем што го имаме е проблем број 33 на датотека I / O. Зумирате на оваа малку. Проблемот 33 - Да? [Даниел] Јас само имале брз прашање. Оваа ѕвезда, или ѕвездичка, се вика dereferencing кога користите ѕвездичка порано. Што е тоа се вика кога користите симболот пред тоа? >> На симболот пред е адресата-оператор. Па ајде дојдете назад. Упс. Јас сум во зум на владата, па не можам навистина дојдете. Ако ги погледнеме во овој код навистина брзо, токму тука, повторно, истото се случува. Ако ги погледнеме во овој код токму тука, на оваа линија, каде што се направи повик да се разменуваат, на симболот е само велејќи "ја добиете адресата на која променливата x животи." Кога вашиот компајлер компајлира вашиот код, тоа мора да всушност физички одбележи место во меморијата за сите ваши променливи да се живее. И така што на компајлерот, тогаш може да се направи еднаш тоа е компајлирана сè, тоа го знае, "О, јас се стави x на адреса 10. ставив y на адреса 14." Таа потоа може да се пополни во овие вредности за вас. Па можете да потоа - тоа тогаш може да го помине овој и помине и y во исто така. Овие момци добиете адресата, но тие, исто така, кога ќе ги помине во swap функција, овој тип на информации, овој int * токму тука, кажува на компајлерот, "Добро, ние ќе треба да се толкува оваа адреса како адреса на целобројна променлива." Како адреса на int, која е различна од адресата на лик променлива бидејќи int зазема, на 32-битна машина, зазема 4 бајти на просторот, со оглед на карактерот само зазема 1 бајт на просторот. Па затоа е важно да се знае и она што е - што живее, каков тип на вредност живее на адресата што доби помина внатре Или адресата што сте се занимаваат со. На тој начин, знаеш колку бајти на информации за да всушност се вчита од вашиот RAM меморија. И тогаш, да, ова Dereference оператор, како што се бара, оди и пристапи информации на одредена адреса. Така што се вели, со оваа променлива овде се третираат содржината на како адреса, одат на таа адреса, и извлечете, оптоварување во процесор, оптоварување во регистар вистинските вредности или содржини кои живеат на таа адреса. Други прашања? Овие се добри прашања. Тоа е многу новата терминологија премногу. Тоа е исто така еден вид на фанки, гледајќи & и * во различни места. Во ред. Па назад кон проблемот 33, датотека I / O. Ова беше еден од оние проблеми кои мислам дека неколку нешта се случија. Еден, тоа е прилично нова тема. Тоа беше презентирана наскоро пред квиз, и тогаш мислам дека тоа беше вид на како еден од оние зборот проблеми во математиката каде што тие ви даде многу информации, но вие всушност не завршуваат морале да користите еден тон на неа. Во првиот дел од овој проблем е опишува она CSV датотека е. Сега, CSV датотека, според описот, е одвоени со запирки вредности датотека. Причината овие се на сите интересни, но и причина што досега ги користат, е, затоа што, колку некогаш сте се користи нешто како Excel? Слика повеќето од вас, веројатно, или ќе го користи во одреден момент во вашиот живот. Ќе се користи нешто како Excel. Со цел да се добијат податоци од една табела Excel или не било вид на обработка со него, ако си сакал да се напише програма C или Пајтон програма, Јава програма, да се справи со податоци што се чуваат таму, еден од најчестите начини да го добие во CSV датотека. И може да се отвори Excel и кога одите на "Save As" дијалог, може да се добијат вистински CSV фајл. Корисна за да знам како да се справи со овие работи. Начинот на кој таа работи е дека тоа е слично на - Мислам, тоа е во суштина имитирајќи табеларни пресметки, каде што, како што гледаме тука, во многу лево повеќето парче, имаме сите презиме. Значи имаме Malan, тогаш Hardison, а потоа Бауден, MacWilliam, а потоа Чан. Сите презиме. А потоа запирка одделува последните имиња од првите имиња. Давид, Нејт, Роб, Томи и Zamyla. Јас секогаш се измеша Роби и Том. А потоа, конечно, третата колона е-мејл адреси. Откако ќе се разбере дека, остатокот од програмата е прилично лесно да се имплементира. Она што ние го направивме со цел да го имитираат овој ист структура во нашата Ц програма е ние сме користеле структура. Ќе почнете да играте со овие малку повеќе, како и. Ние ги видов за прв малку во проблем сет 3, кога ние се занимаваат со речници. Но, овој персонал struct продавници последно име, презиме, и-мејл. Исто како и нашата CSV датотека беше складирање. Значи ова е само конвертирање од еден формат во друг. Ние мора да го конвертирате, во овој случај, на персоналот struct во линија, на одвоени со запирки линија, исто како што. Дали тоа има смисла? Вие момци имаат сите преземени на квизот, па Претпоставувам имаш барем имаше некое време да се размислува за тоа. Во изнајмување функција, проблемот бара од нас да се земе во - we'll зумирате на оваа малку - земе во кадровската структура, персонал struct, со името на, и додаваат на неговата содржина во нашата staff.csv датотека. Излезе дека ова е прилично јасна да се користи. Ние вид на ќе се позанимавам со овие функции малку повеќе денес. Но, во овој случај, fprintf функција е навистина клучот. Значи со fprintf, можеме да печатиме, исто како вас момци биле користење printf целата оваа термин. Можете да printf линија во датотеката. Така, наместо на само правење на вообичаените printf повик, каде што го даде формат стринг а потоа ќе ги замени сите променливи со следниве аргументи, со fprintf, вашиот прв аргумент е наместо на датотеката која сакате да се напише. Ако бевме да се погледне на овој во апаратот, на пример, човек fprintf, можеме да видиме разликата помеѓу printf и fprintf. Ќе зумирате тука малку. Значи со printf, ние го даде формат стринг, а потоа следните аргументи се сите променливи за замена или замена во нашата формат стринг. Додека со fprintf, првиот аргумент е навистина оваа датотека * нарекува поток. Се движат назад над тука за да нашите изнајмување, ние веќе доби нашата датотека * поток отвори за нас. Тоа е она што оваа прва линија не, тоа отвора датотеката staff.csv, тоа се отвора во додавај на владата, и сето она што остана за нас да направите е да пишуваат на персоналот структура на датотеката. И, ајде да видиме, не сакам да се користи на iPad? Ќе се користи iPad. Имаме празнина - Да се ​​стави тоа на маса за да можам да пишувам малку подобро - поништат изнајмување и е потребно во еден аргумент, на персоналот структура наречена s. Добивме загради, ние го добивме нашиот датотека * нарекува датотека, ние имаме fopen линија што ни се дава, и јас само ќе го пишувам како точки, бидејќи тоа е веќе во Педија. А потоа на нашата следната линија, ние ќе треба да се направи повик да fprintf и ние ќе помине во датотека која сакаме да се печати, а потоа нашите формат стринг, кои - Јас ќе ти момци ми кажете што изгледа. Како за вас, Стела? Дали знаете што првиот дел од формат стринг личи? [Стела] не сум сигурен. >> Слободно можете да побарате Џими. Дали знаете, Џими? [Jimmy] Зарем тоа само да биде последно? Не знам. Јас не сум сосема сигурен. >> Океј. Како за, дали некој го добивате ова точно на испит? Бр ред. Излегува дека тука сите ние треба да направите е да сакаме секој дел од нашиот тим структура да бидат испечатени како стринг во нашата датотека. Ние само го користите низа замена карактер три различни времиња, бидејќи имаме презиме проследено со запирка, тогаш првото име проследено со запирка, а потоа конечно е-мејл адреса која следеше - што не е монтирање на мојот екран - но тоа е проследено со нова линија карактер. Па јас сум ќе го напишам само таму долу. А потоа по нашите формат стринг, ние само имаме замени кои ние пристап со користење на нотација точка што сме го виделе проблем сет 3. Можеме да го користиме s.last, s.first и s.email за замена во овие три вредности во нашата формат стринг. Па како не, кои одат? Смисла? Да? Не? Можеби? Во ред. Конечниот нешто што правиме после ние сме печатени и откако ќе го отвори нашиот датотека: кога сме отвори датотеката, ние секогаш да се сеќавам да го затворите. Затоа што во спротивно ние ќе завршуваат протекување на меморија, користење на датотеката дескриптори. Значи за да го затворите, кои функционираат ние ги користиме? Даниел? [Даниел] запишам? >> Запишам, точно. Значи последниот дел од овој проблем беше правилно да го затворите датотека, со употреба на запишам функција, што само изгледа како тоа. Не е премногу луд. Кул. Па тоа е проблемот 33 на квизот. Ќе имаме дефинитивно повеќе датотека I / O доаѓа. Ние ќе се направи малку повеќе во предавање денес, или во делот денес, бидејќи тоа е она што се случува да се формира најголемиот дел од оваа претстојните pset. Ајде да се движи на од квизот во овој момент. Да? [Шарлот]] Зошто запишам (датотека) наместо запишам (staff.csv)? >> Ах. Поради тоа што излегува дека - па прашање, кое е голем, Затоа, кога ние пишуваме запишам, дали сме пишување запишам (датотека) ѕвезда променлива за разлика од името на датотеката, staff.csv? Дали е тоа точно? Да. Па ајде да ги разгледаме. Ако јас се вратиш назад на мојот лаптоп, и нека се погледне на запишам функција. Значи запишам функција затвора поток и е потребно во покажувачот на потокот дека сакате да го затворите, за разлика од вистинските името на датотеката што сакате да го затворите. И ова е поради тоа зад сцената, кога ќе се направи повик fopen, кога ќе се отвори датотеката, ти си, всушност доделување меморија за складирање на информации за датотека. Па имате датотека покажувач кој има информации за датотека, како што е отворен, неговата големина, каде и да сте во моментов во датотеката, така што ќе може да направи за читање и пишување повици кон тоа конкретно место во рамките на датотека. Вие завршуваат затворање на покажувачот наместо на затворање на името на датотеката. Да? [Даниел] Значи, со цел да се користи изнајмување, дали би рекле - како да го добие на корисникот влез? Дали fprintf дејствува како GetString во смисла дека тоа само ќе чека за корисникот влез и побара од вас да напишеш ова - или чекаат за да напишете овие три работи во? Или не ви треба да користите нешто да се имплементира изнајмување? >> Да. Значи ние не сме - прашањето е, како ние да добие корисник влез со цел да се спроведе изнајмување? И она што го имаме тука е на повикувачот на изнајмување, донесен во овој персонал struct со сите податоци складирани во struct веќе. Значи fprintf е во состојба само да се напише дека податоците директно во датотеката. Нема чекање за корисникот влез. Корисникот е веќе дадено влезот од правилно да го стави во овој персонал struct. И работите, се разбира, ќе се скрши ако било која од овие совети се нула, па ние дојдете назад до тука и ќе погледнеме во нашите struct. Имаме низа последен, стринг прво, стринг е-мејл. Ние сега знаеме дека сите оние, навистина, под хауба, се char * променливи. Кои може или не може да се укажува на нула. Тие може да се укажува на меморијата на грамада, можеби меморија на магацинот. Ние навистина не знаеме, но ако било кој од овие совети се ништовни, валиден или, дека тоа дефинитивно ќе се сруши нашата изнајмување функција. Тоа беше нешто што беше вид на надвор од опсегот на испитот. Ние не сме се грижиш за тоа. Велики. Во ред. Значи се движат на од квизот. Да го затворите овој човек, и ние ќе се погледне во pset 4. Значи, ако вие момци се погледне на спецификации pset, штом ќе може да го пристап, cs50.net/quizzes, ние се случува да поминат низ неколку од делот проблеми денес. Јас сум лизгање надолу - дел од прашањата започнува на третата страница на pset спецификации. И првиот дел ќе бара да се оди и види краток за пренасочување и цевки. Која беше вид на кул кратко, ви покажува некои нови, кул командната линија трикови кои можете да го користите. И тогаш имаме неколку прашања за вас, како и. Ова првото прашање околу потоци, на која printf пишува по дифолт, ние вид на осврна и на само малку пред еден момент. Ова fprintf дека сме биле само дискутирање зема во датотека * поток како свој аргумент. запишам зема во датотека * поток, како и, и повратната вредност на fopen ви дава датотека * поток, како и. Причината не сме виделе оние пред кога ние сме се занимаваа со printf е затоа printf има стандардно поток. И стандардниот поток на кој пишува ќе дознаете за во краток. Значи дефинитивно ги погледне во него. Во делот денес, ние ќе зборуваме малку за GDB, бидејќи повеќе сте запознаени со тоа, повеќе пракса ќе добијат со тоа, толку подобро можност ќе биде да всушност ги фатат грешки во свој код. Оваа забрзува процесот на дебагирање до неверојатно. Значи со користење printf, секој пат кога ќе го направите тоа што треба да го прекомпајлирате вашиот код, ќе мора да се кандидира повторно, понекогаш треба да се преселат на printf повик наоколу, Коментар од кодот, потребно е само време. Нашата цел е да се обиде да го убеди дека со GDB, можете суштина printf ништо во било која точка во вашиот код и никогаш не треба да го прекомпајлирате. Вие никогаш не треба да се започне и задржи Сомневајќи каде да printf следната. Првото нешто да направите е да ископирате оваа линија и да добијат дел кодот исклучување на интернет. Јас сум копирање оваа линија на кодот кој вели: "wget ​​http://cdn.cs50.net". Одам да го ископирате. Одам да се оди во текот на мојот апарат, одзумирате па можете да видите она што го правам, вметнување во таму, и кога ќе притиснете ентер, ова wget команда буквално е веб добие. Тоа се случува да ги повлечат надолу оваа датотека исклучување на интернет, и тоа се случува да го зачувате тековниот директориум. Сега, ако јас листата мојот тековниот директориум можете да видите дека имам оваа section5.zip датотека во право таму. На начин да се справи со тоа човек е да го отпакувате, што можете да направите во командната линија, исто како и оваа. Section5.zip. Тоа ќе го отпакувате, се создаде папка за мене, надува целата содржина, ги стави во таму. Па сега можам да одам во мојата делот 5 директориум со помош на CD команда. Исчистите екранот користејќи јасно. Па го исчистите екранот. Сега имам убав чист терминал за да се справи со. Сега, ако јас на листата на сите датотеки што гледам во овој директориум, ќе видите дека имам датотеки четири: buggy1, buggy2, buggy3 и buggy4. Јас сум исто така доби нивните соодветни. В датотеки. Ние нема да се погледне на. В датотеки за сега. Наместо тоа, ние ќе ги користат кога ќе се отвори gdb. Ние ги чуваат околу, така што ќе имаат пристап до вистинските изворниот код, кога ние сме со користење GDB, но целта на овој дел од делницата е да нескопосник околу со GDB и да видиме како можеме да ја искористиме да дознаам што се случува погрешно со секој од овие четири кабриолет програми. Значи, ние сме само ќе низ собата навистина брзо, и јас одам да прашам некој да се кандидира една од кабриолет програми, а потоа ќе одиме како група преку GDB и ќе видиме што можеме да направиме за да го надминете овие програми, или барем да се идентификува она што се случува погрешно во секоја од нив. Да почнеме овде со Daniel. Ќе се кандидира buggy1? Ајде да видиме што се случува. [Даниел] Таа вели дека има барање вина. >> Да. Точно. Значи, ако јас се кандидира buggy1, добивам сегмент вина. Во овој момент, би можел да оди и да се отвори buggy1.c, се обиде да дознаам што се случува погрешно, но една од најпознатите ништожно работи за овој сегмент грешка грешка е тоа што не ви каже за тоа што линијата на програмата нешта, всушност не беше во ред и се скрши. Можете вид на треба да се погледне во кодот и дознаам користење погоди и да се провери или printf да се види што се случува погрешно. Една од најкул работи за GDB е дека тоа е навистина, навистина лесно да дознаам линија во која вашата програма падне. Тоа е целосно достоен за тоа да го користат, дури и ако само за тоа. Така да го подигнете нагоре GDB, тип I GDB, а потоа го даде на патот на извршна дека сакам да се кандидира. Еве јас сум пишување gdb ./buggy1. Хит Enter. Ми дава сите овој авторските права на информациите, и овде ќе видите оваа линија во која се вели: "Читање симболи од / home / jharvard/section5/buggy1. " И ако се оди добро, ќе видите го испечатите порака што личи ова. Тоа ќе прочитате симболи, тоа ќе се каже "Јас читам симболи од вашиот извршна датотека," а потоа ќе ја имаат оваа "направено" порака овде. Ако видите некоја друга варијација на ова, или можете да ја видите не може да се најде на симболи или нешто слично, што значи тоа е дека едноставно не се составени вашиот извршна правилно. Кога ќе се собере програми за употреба со GDB, ние треба да го користат специјални г знаме, и тоа е направено по дифолт ако ги собира вашите програми, само со пишување се направи или да направи кабриолет или да се опорави, секоја од нив. Но, ако сте составувањето рачно со ѕвекот, а потоа ќе мора да одат во и вклучуваат што-е знамето. Во овој момент, сега кога имаме GDB брза, тоа е прилично едноставна да ја стартувате програмата. Ние или може да внесете рок, или едноставно можете да напишете r. Повеќето GDB команди може да биде скратен. Обично на само една или неколку букви, што е прилично убаво. Значи Saad, ако го напишете r и притиснете ентер, што се случува? [Саад] добив SIGSEGV, сегментација на вина, а потоа сето ова gobbledygook. >> Да. Како што гледате на екранот во право сега, и како Саад рече, кога ќе напишете рок или r и притиснете Enter, ние сеуште го добиете истиот сегмент вина. Значи со користење GDB не се реши нашиот проблем. Но, тоа ни дава некои gobbledygook, и испоставува дека ова gobbledygook всушност ни кажува каде тоа се случува. Да го анализирам овој малку, овој првиот бит е во функција во која што се случува погрешно. Има оваа __ strcmp_sse4_2, а тоа ни кажува дека тоа се случува во оваа датотека наречен sysdeps/i386, сето ова, пак, вид на хаос - но линија 254. Тоа е вид на тешко да се интерпретира. Обично, кога ќе видите нешто како ова, тоа значи дека тоа е секунда Разлом во една од системски библиотеки. Така нешто да се направи со strcmp. Вие момци сте виделе strcmp порано. Не е премногу лудо, но дали тоа значи дека strcmp е скршен или дека има проблем со strcmp? Што мислите, Александар? [Александар] Дали е тоа - е 254 на линија? И - не бинарни, но тоа не е нивната тавани, а потоа има уште еден јазик за секоја функција. Е дека 254 во таа функција, или - >> Тоа е линија 254. Тоа изгледа како во тоа. Кликнете датотека, па тоа е асемблерски код веројатно. Но, претпоставувам дека повеќе притискање работа е, затоа што ние сме добиле сегмент грешка, и тоа изгледа како да доаѓа од strcmp функција, дали ова значи, тогаш, дека strcmp е скршен? Тоа не треба, се надевам. Па само затоа што имаат сегментација грешка во една од функциите на системот, обично тоа значи дека вие едноставно не го нарекуваат правилно. Најбрзиот нешто што треба да направите за да дознаам што е всушност се случува кога ќе видите нешто лудо како ова, секогаш кога ќе видите сегмент грешка, особено ако имате програма која е со користење на повеќе од само главната, е да се користи трагата. Јас abbreviate трагата со пишување на БТ, за разлика од полно трагата збор. Но Шарлот, што се случува кога ќе напишете БТ и притиснете Ентер? [Шарлот] Тоа ми покажува две линии, линија 0 и линија 1. >> Да. Значи линија 0 и линија 1. Овие се вистинските магацинот рамки кои беа моментално во игра кога вашата програма се урна. Почнувајќи од врвниот рамка, рамка 0, и оди на дното повеќето, која е рамка 1. Нашите врвниот рамка е strcmp рамка. Можеш да мислиш за тоа како сличен на оној проблем бевме само прави на квизот со покажувачи, каде што се разменуваат магацинот рамка на врвот на главниот магацинот рамка, и имавме варијабли кои трампа е користење на врвот на променливи кои главни се користи. Еве нашата несреќа што се случи во нашата strcmp функција, која беше наречен од страна на нашата главна функција, и трагата ни дава не само функциите во која работите не успеа, но тоа е, исто така, ни кажува каде што сè беше наречен од. Значи, ако јас дојдете во текот на еден малку повеќе на десно, можеме да видиме дека да, бевме на линија 254 на овој strcmp-sse4.s датотека. Но, повикот беше донесена на buggy1.c, алинеа 6. Па тоа значи дека можеме да го направиме - е ние едноставно може да оди провери и да видиме што се случува на buggy1.c, алинеа 6. Повторно, постојат неколку начини да го направите тоа. Една од нив е да излезете надвор од GDB или вашиот код отворена во друг прозорец и крос референца. Тоа, само по себе, е прилично корисна, бидејќи сега ако сте на работното време и имаш сегмент грешка и вашата ТФ се прашувате каде што сè е кршење, можете само да се каже, "О, алинеа 6. Не знам што се случува, но нешто во врска со алинеа 6 предизвикува мојата програма да се скрши. " На друг начин да го направите е да можете да го користите оваа команда се нарекува листата во gdb. Исто така можете да го abbreviate со l. Значи, ако ние хит л, што сме се нашле? Ние се еден куп на чудни нешта. Ова е вистинскиот асемблерски код што е во strcmp_sse4_2. Ова изгледа вид на фанки, и причина ние сме добивање ова е затоа што токму сега, GDB нас има во рамката 0. Па во секое време гледаме променливи, во секое време ќе погледнеме во изворниот код, ние сме во потрага на изворниот код што се однесува на магацинот рамка ние сме во моментов внатре Значи, со цел да се добие ништо значајно, ние треба да се преселат во магацинот рамка што го прави повеќе смисла. Во овој случај, главниот магацинот рамка ќе се направи малку повеќе смисла, бидејќи тоа е всушност код кој ние напиша. Не strcmp код. Начинот на кој можете да се движите помеѓу рамки, во овој случај, бидејќи имаме две, имаме 0 и 1, да го направите тоа со нагоре и надолу команди. Ако јас се движат нагоре една рамка, сега сум во главниот магацинот рамка. Јас може да се движи надолу за да се врати на местото каде што беше, одат нагоре, повторно, оди надолу, повторно, и да си одат повторно. Ако некогаш направите вашата програма во GDB, ќе добиете несреќа, ќе го добиете трагата, и ќе видите дека тоа е во некои датотеки кои не знаете што се случува. Ќе се обидат листа, кодот не изгледаат познатите за вас, погледнете во вашата рамки и дознаам каде се наоѓате. Ти си веројатно во ред магацинот рамка. Или барем сте во магацинот рамка која не е онаа која навистина може да debug. Сега дека ние сме во соодветна оџакот рамка, ние сме во главната, сега можеме да го користиме на листата команда за да дознаам што линијата беше. И може да се види, тоа го печатат за нас овде. Но, ние може да ја погоди листата сите исти, како и листа ни дава оваа убава отпечатоците на реалните изворниот код што се случува овде. Особено, можеме да погледнеме во алинеја 6. Можеме да видиме што се случува овде. И тоа изгледа како правиме низа споредба меѓу стринг "CS50 карпи" и avg [1]. Нешто во врска со ова беше паѓа. Значи ма, не имате било какви размислувања за она што може да се случува овде? [Ма] Не знам зошто тоа е паѓа. >> Ти не знаеш зошто тоа е кршењето? Џими, секој мисли? [Jimmy] Јас не сум сосема сигурен, но во последно време ние се користи низа споредба, или strcmp, имавме како три различни случаи под неа. Ние не имаат ==, јас не мислам, десно во првата линија. Наместо тоа, таа беше поделен на три, а еден беше == 0, еден е <0, мислам, а еден беше> 0. Па можеби нешто слично? >> Да. Па таму е ова прашање на правиме споредба правилно? Stella? Секој мисли? [Стела] не сум сигурен. >> Не сум сигурен. Даниел? Мисли? Во ред. Излегува она што се случува токму тука е кога ќе истрча на програмата и добивме сегмент грешка, кога ќе истрча на програмата за прв пат, Даниел, му го даде тоа било командната линија аргументи? [Даниел] бр >> бр Во тој случај, она што е вредноста на avg [1]? >> Нема вредност. >> Право. Па, не постои соодветна вредноста на стрингот. Но има некои вредност. Која е вредноста која добива се чуваат таму? >> А ѓубре вредност? >> Тоа е или ѓубре вредност или, во овој случај, на крајот на низата argv е секогаш прекинува со нула. Значи она што всушност доби чуваат во таму е нула. На друг начин да се реши овој, наместо мислејќи дека преку, е да се обиде печатење тоа надвор. Ова е местото каде што беше велејќи дека користењето GDB е голема, затоа што може да испечатите сите променливи, сите вредности што сакате користење на оваа корисна-елегантен p команда. Значи, ако јас внесете стр а потоа внесете вредноста на променлива или името на променливата, да речеме, argc, гледам дека argc е 1. Ако сакам да се печати avg [0], можам да го стори тоа само така. И како што видовме, avg [0] е секогаш името на вашата програма, секогаш името на извршната датотека. Овде можете да ја видите доби целосната патека име. Јас, исто така може да испечатите avg [1] и да видиме што се случува. Тука имаме овој вид на мистичен вредност. Добивме овој 0x0. Запомни на почетокот на терминот кога ние разговаравме за хексадецимално броеви? Или дека малку прашање на крајот на pset 0 за тоа како да претставуваат 50 во хексадецимален? Начинот на кој ние пишуваме хексадецимален број во CS, само да не се збуни со децимални броеви, е ние секогаш им префиксот со 0x. Значи ова 0x префикс секогаш само значи толкуваат на следниот број како хексадецимален број, не како стринг, а не како децимален број, а не како бинарен број. Бидејќи бројот 5-0 е валиден број во хексадецимално. И тоа е број во децимала, 50. Значи ова е само како disambiguate. Значи 0x0 средства хексадецимален 0, која е исто така децимална 0, бинарна 0. Тоа е само вредност 0. Излезе дека ова е она нула е, всушност, во меморијата. Нула е само 0. Еве, елементот се чуваат во avg [1] е нула. Значи ние се обидуваме да се споредат нашите "CS50 карпи" стринг со нула стринг. Значи dereferencing нула, се обидуваат да пристапите работи на нула, тие обично ќе предизвика некој вид на сегментација на вина или други лоши работи да се случи. И излегува дека strcmp не се провери да се види дали или не сте се донесени во вредност тоа е нула. Напротив, тоа само оди напред, се обидува да си ја работи својата работа, и ако секунда грешки, тоа seg грешки, а тоа е вашиот проблем. Мора да се оди поправите тоа. Навистина брзо, како да го надминете овој проблем? Шарлот? [Шарлот] Можете да проверите користење ако. Значи, ако avg [1] е нула, == 0, а потоа се врати 1, или нешто [неразбирливо]. >> Да. Значи тоа е еден одличен начин да го направи тоа, како можеме да се провери да се види, вредноста ние сме за да помине во strcmp, avg [1], е тоа нула? Ако тоа е нула, тогаш можеме да кажеме во ред, прекин. А повеќе заеднички начин да го направите ова е да се користи argc вредност. Можете да видите тука на почетокот на главната, ние испушти тој тест кој обично се прави кога ние ги користиме командната линија аргументи, која е да се тестира дали или не нашите argc вредност е она што го очекуваме. Во овој случај, ние очекуваме најмалку два аргументи, името на програмата, плус еден друг. Бидејќи ние сме за да се користи вториот аргумент тука. Значи има некој вид на тест однапред, пред нашите strcmp повик дека тестовите дали или не argv е барем 2, исто така, ќе го стори истото вид на работа. Можеме да видиме ако тоа работи со извршување на програмата повторно. Секогаш можете да го рестартирате вашата програма во рамките GDB, што е навистина убаво. Можете да го извршите, и кога ќе помине во аргументите за вашата програма, ќе ги помине во кога ќе се јавите работи, а не кога ќе го подигнете gdb. На тој начин можете да ги повикувајќи вашата програма со различни аргументи секој пат. Значи се кандидира, или пак, можам да Type R, и да видиме што ќе се случи ако напишете "здраво". Тоа секогаш ќе ве праша дали сакате да ја почне од почеток. Вообичаено, вие не сакате да го почне од почеток. И во овој момент, се рестартира повторно, тоа отпечатоци од на програмата, дека ние сме трчање, buggy1, со аргументот здраво, и тоа отпечатоци овој стандард надвор; тој вели: "Ќе добиете Д", тажно лице. Но, ние не секунда грешка. Таа рече дека процесот излезено нормално. Така што изгледа прилично добро. Нема повеќе сегменти вина, ние го направи минатото, па изгледа дека беше навистина сегмент вина бубачка дека сме биле добивање. За жал, тоа ни кажува дека ние сме добивање на Д Можеме да одиме назад и се погледне на код и да видиме што се случува таму да дознаам што беше - зошто беше ни кажува дека имаме Д Ајде да видиме, тука е овој printf велејќи дека ли Д Ако ние напишете листа, како што се задржи пишување листата, се држи процесирањето надолу низ вашата програма, па тоа ќе ви покажам првите неколку линии на вашата програма. Тогаш тоа ќе ви покажам следните неколку линии, а во следниот дел и следниот дел. И тоа ќе се обидувам да одат надолу. И сега ние ќе дојдеме до "линијата број 16 е надвор од опсегот". Поради тоа што има само 15 линии. Ако дојде до оваа точка и вашиот прашувајќи, "Што да правам?" можете да го користите помош команда. Користете помогне, а потоа го даде името на команда. И можете да го видите GDB ни ги дава сите овој вид на работи. Таа вели: "Без аргументи, наведува уште десет линии по или околу претходниот оглас. Листа - список на десет линии пред - " Па ајде обидете се со користење листа минус. И со список на 10 линии претходната, можете да се позанимавам со листа малку. Можете да го направите листа, листа -, можете дури и може да даде листа на број, како листа 8, и тоа ќе листата на 10 линии околу алинеја 8. И можете да видите што се случува тука е имаш едноставна ако друго. Ако го напишете во CS50 карпи, тоа отпечатоци од "Можете да добиете А" Инаку тоа отпечатоци од "Ќе добиете Д" Bummer градот. Во ред. Да? [Даниел] Значи, кога се обидов прави CS50 карпи без наводници, тој вели: "Ќе добиете Д" Требаше наводниците да се добие тоа да работат, зошто е тоа така? >> Да. Излегува дека кога - ова е уште една забава малку хапка - кога ќе ја стартувате програмата, ако се работи и напишете CS50 карпи, само како Даниел велеше тој, и притиснете ентер, сепак вели добиеме Д А прашањето е, зошто е ова? И излегува дека нашите терминал и GDB анализира овие како два одделни аргументи. Бидејќи кога постои простор, тоа е имплицирана како првиот аргумент заврши; следниот аргумент е за да започне. На начин да се комбинираат тие во две или жал, во еден аргумент, е да се користи цитати. Па сега, ако ние го стави во наводници и да ја стартувате повторно, се добива А Значи само да повториме, нема цитати, CS50 и карпи се разложени, како два посебни аргументи. Со цитати, тоа е разложени, како еден аргумент заедно. Можеме да видиме ова со точка на прекин. Досега сме се работи нашата програма, а тоа е се одржува до или таа секунда грешки или хитови грешка или додека не излезе и сите е сосема во ред. Ова не значи дека тоа е најкорисен работа, бидејќи понекогаш Имаш грешка во вашата програма, но тоа не е предизвикува сегментација грешка. Тоа не се предизвикува вашата програма да се запре или нешто слично. На начин да се добие GDB за да го паузирате вашата програма во одредена точка е да се постави точка на прекин. Можете или да го направите ова со поставување на точки на прекин на името на функцијата или можете да поставите точки на прекин на одредена линија код. Ми се допаѓа да го поставите точки на прекин на имиња на функции, бидејќи - лесно да се запомни, и ако навистина оди во и менувате вашите изворниот код се малку, тогаш вашата точка на прекин, всушност, ќе остане на истото место во рамките на вашиот код. А ако сте со користење броеви и броевите на линијата промени затоа што ќе додадете или избришете некој код, тогаш вашиот поминувања сите се целосно зезнав. Еден од најчестите нешта направите е да поставите точки на прекин на главната функција. Често јас ќе го подигнете нагоре GDB, јас ќе тип Б главни, притиснете ентер, и дека ќе се постави точка на прекин на главната функција што само вели, "пауза на програмата штом ќе почнат да оперираат" и на тој начин, кога ќе ја стартувате мојата програма со, да речеме, CS50 карпи како два аргументи и притиснете Enter, таа добива на главната функција и запира на првата линија, непосредно пред тоа го оценува strcmp функција. Бидејќи јас сум на пауза, сега можам да почнам mucking наоколу и види што се случува со сите на различни варијабли кои се пренесуваат во мојата програма. Еве јас може да испечатите argc и да видиме што се случува. Види дека argc е 3, затоа што доби 3 различни вредности во него. Тоа доби името на програмата, тоа е се здобија првиот аргумент и вториот аргумент. Можеме да печатиме оние надвор од страна гледајќи во avg [0], avg [1], и avg [2]. Па сега вие исто така може да се види зошто овој повик strcmp се случува да не успее, бидејќи ќе видите дека тоа не подели на CS50 и карпи во две одделни аргументи. Во овој момент, откако ќе ја погоди точки на прекин, може да продолжи да се зајакне преку вашата програма линија по линија, за разлика ја стартувате програмата повторно. Значи, ако не сакате да ја стартувате програмата повторно и само продолжи од овде, можете да го користите продолжи команда и понатаму ќе ја стартувате програмата до крај. Исто како што беше тука. Сепак, ако рестартирам програмата, CS50 карпи, тоа хитови мојата точка на прекин, повторно, и овој пат, ако не сакате само да одат по целиот пат низ остатокот на програмата, Јас може да се користи следната команда, која Јас, исто така abbreviate со n. И ова ќе влезете низ програмата линија по линија. Така може да се види како работите се изврши, како варијабли промени, како работите да се ажурираат. Што е прилично убаво. Од друга кул работа е наместо повторување на истата команда одново и одново и одново, ако само кликнете Enter - па овде ќе види дека не ја внеле во нешто - ако јас само кликнете Enter, ќе го повтори претходната наредба, или претходната GDB команда која јас само се стави внатре Јас може да се задржи притискање на Enter и ќе продолжиме повлекува низ моите кодот линија по линија. Јас би ве охрабруваме да момци да оди провери од други кабриолет програми, како и. Ние немаме време да се добие преку сите нив денес во секција. Изворниот код е таму, па можете да вид на се види што се случува зад сцената, ако се навистина заглавени, но во најмала рака, само пракса подигнување GDB, водење на програма додека не се крши за вас, добивање на трагата, да пронајдат она што функционира на несреќата беше во, она што линијата што беше, печатење некои променлива вредности, само така ќе се добие чувство за тоа, бидејќи тоа навистина ќе ви помогнат да оди напред. Во овој момент, ние ќе треба да се откажат од GDB, кои се користат да престанам или само q. Ако вашата програма е во средината на водење сепак, и тоа не излезе, таа секогаш ќе ве праша "Дали сте сигурни дека навистина сакате да напуштите?" Вие само може да се погоди да. Сега ние ќе се погледне на следниот проблем што го имаме, кој е мачка програма. Ако се види на кратки за пренасочување и цевки, ќе видите дека Томи користи оваа програма дека во основа отпечатоци сите излез на датотека на екранот. Значи, ако јас се кандидира мачка, ова е всушност вграден во програмата на апаратот, и ако имате Macs можете да го направите ова на вашиот Mac исто така, ако се отвори терминал. А ние - мачка, да речеме, cp.c, и притиснете Enter. Што ова не, ако скролувате нагоре малку и да видиме каде се трчаше на линија, или каде што се трчаше на мачка команда, тој буквално само отпечатени содржината на cp.c на нашите екран. Ние можеме да се кандидира повторно и може да се стави во повеќе датотеки заедно. Па можете да направите мачка cp.c, а потоа ние исто така може да concatenate на cat.c датотека, кој е на програмата ние сме за да се напише, и тоа ќе печати двете датотеки назад да се врати на нашите екран. Значи, ако ние движете нагоре малку, ќе видиме дека кога ние трчаше оваа мачка cp.c, cat.c, прво отпечатени на КП датотека, а потоа под неа, тоа отпечатени на cat.c датотека десно надолу тука. Ние ќе ја користите оваа само да добијат нашите нозе влажни. Позанимавам со едноставни печатење на терминал, да видиме како тоа функционира. Ако вие момци се отвори со gedit cat.c, притиснете ентер, можете да видите на програма која ние сме за да пишувам. Ние сме вклучени во ова фино котел плоча, така што не мора да потрошите време пишување сето тоа надвор. Ние, исто така провери бројот на аргументи предадена внатре Ние печати убав порака за употреба. Ова е вид на нешто што, пак, како ние сме биле зборува за, тоа е речиси како мускулите меморија. Само не заборавајте да го задржи тоа на ист вид на работи и секогаш печатење некој вид на корисни порака така што луѓето знаат како да се кандидира на вашиот програма. Со мачка, тоа е прилично едноставна, ние сме само ќе да поминат низ сите на различни аргументи кои беа предадени на нашата програма, и ние ќе печати нивната содржина надвор на екранот едно по едно време. Со цел да се печати фајлови на екран, ние ќе треба да се направи нешто многу слични на она што ние го сторивме на крајот на квизот. На крајот на квизот, кои вработуваат програма, моравме да се отвори датотеката, а потоа моравме да се печати на него. Во овој случај, ние ќе треба да се отвори датотеката, и ние ќе треба да читаат од неа наместо тоа. Тогаш ние ќе треба да се печати, наместо во датотека, ние ќе печати на екран. Значи печатење на екран сте Сето тоа е направено пред со printf. Значи тоа не е премногу луд. Но, читањето на датотеката е вид на чудно. Ќе одиме преку тоа малку во исто време. Ако вие момци се врати во тоа последниот проблем на вашиот квиз, проблем 33, првата линија која ние ќе го направите тука, за отворање на датотека, е многу слична на она што го правевме таму. Значи Стела, што значи дека линијата изгледа, кога се отвори датотеката? [Стела] Капитал Датотека *, датотеката - >> Океј. >> - Е еднаков на fopen. >> То. Кој во овој случај е тоа? Тоа е во коментар. >> Тоа е во коментар? avg [i] и r? >> Токму така. Право на. Значи Стела е сосема во право. Тоа е она што линија изгледа. Ние ќе добиете датотека поток променлива, чувајте го во датотека *, така што сите капи, Датотека, *, и името на оваа променлива ќе биде датотека. Ние би можеле да го наречеме она што го сакаме. Ние би можеле да го наречеме first_file, или file_i, она што ние би сакале. А потоа името на датотеката беше донесен во на командната линија во оваа програма. Така, тоа е се чуваат во avg [i,] а потоа ние ќе ја отворите оваа датотека во читање на владата. Сега дека ние сме ја отвори датотеката, што е нешто што ние секогаш треба да се запамети да се направи кога сме отвори датотеката? Затворете го. Значи Missy, како ние да го затворите датотеката? [Ма] запишам (датотека) >> запишам (датотека). Точно. Велики. Во ред. Ако ги погледнеме во тоа да го стори коментар токму тука, тој вели: "Отвори avg [i] и печати неговата содржина на stdout." Стандарден излез е чудно име. Stdout е само нашиот начин на велејќи ние сакаме да го испечатите до терминалот, ние сакаме да го испечатите на стандардниот излезен поток. Ние всушност може да се ослободи од овој коментар овде. Одам да го копирате и залепите, бидејќи тоа е она што ние го сторивме. Во овој момент, ние сега треба да ја прочита датотеката малку од малку. Сме разговараа неколку начини на читање датотеки. Кои од нив се вашите омилени досега? Кој начин си ја видел или се сеќаваш ли, да чита датотеки? [Даниел] fread? >> Fread? Значи fread е еден. Џими, знаеш сите други? [Jimmy] бр >> Океј. Не бе. Шарлот? Александар? Сите други? Во ред. Па останатите се fgetc, е оној кој ќе го користите многу. Постои, исто така fscanf, вие момци видите шаблон овде? Тие сите почнуваат со F. Ништо да се направи со датотеката. Има fread, fgetc, fscanf. Овие се сите на читање функции. За пишување имаме запишување, имаме fputc наместо fgetc. Ние исто така имаат fprintf како што видов на квизот. Бидејќи ова е проблем кој вклучува читање од датотека, ние ќе користите една од овие три функции. Ние нема да ги користат овие функции овде долу. Овие функции сите се наоѓаат во стандардната библиотека I / O. Значи, ако се погледне на врвот на оваа програма, можете да видите дека ние сме веќе вклучени во хедер датотека за стандардна библиотека I / O. Ако сакаме да дознаам кој сакаме да се користи, ние секогаш може да се отвори човек страници. Значи можеме да напишете човек stdio и прочитате сите за stdio влезни и излезни функции во C. И веќе може да се види ох, погледнете. Тоа е да се спомене fgetc, тоа е да се спомене fputc. Па можете да разбивка малку и се погледне во, да речеме, fgetc и се погледне во својата човек страница. Можете да видите дека тоа оди заедно со целиот куп на други функции: fgetc, fgets, getc, getchar, добива, ungetc, и внесување на карактери и стрингови. Значи ова е како што читаме во карактери и стрингови од датотеки од стандарден влез, која е во суштина од страна на корисникот. И ова е како да го направи тоа во вистински В Значи ова не е со користење на GetString и GetChar функции дека ние се користи од CS50 библиотека. Ние ќе го направите овој проблем во неколку начини така што можете да видите две различни начини да ја направиш. И fread функција која Даниел споменува и fgetc се добри начини да го стори тоа. Мислам fgetc е малку полесно, бидејќи тоа само ги има, како што гледате, еден аргумент, на датотеката * дека ние се обидуваме да го прочитате лик од, и нејзините вратената вредност е цел број. И ова е малку збунувачки, нели? Бидејќи ние сме добивање карактер, па зошто да не го прави ова враќање на знак? Вие момци имате било какви идеи за тоа зошто тоа не може да се врати знак? [Missy одговори, неразбирливо] >> Да. Значи Missy е сосема во право. Ако тоа е ASCII, тогаш оваа цел број може да биде одбележан на вистински знак. Може да биде ASCII карактер, и дека е во право. Тоа е токму она што се случува. Ние сме со користење на int едноставно поради тоа што има повеќе битови. Тоа е поголема од знак, нашите знак има само 8 бита, дека 1 бајт на нашата 32-битна машини. И int има сите 4 бајти во вредност од простор. И излегува дека начинот на кој fgetc работи, ако дојдете во нашата синопсисот на овој човек страница малку, дојдете сите на патот надолу. Излегува дека тие ги користат оваа посебна вредност наречена EOF. Тоа е специјална постојана како повратната вредност на fgetc функција кога ќе удри на крајот на датотеката или ако добиете грешка. И излегува дека да се направи овие споредби со EOF правилно, дека сакате да го имаат тоа екстра количината на информации кои имате во int за разлика од користење на знак променлива. Иако fgetc е ефикасно добивање на лик од датотека, сакате да се запамети дека тоа е враќање на нешто што е од тип int за вас. Тоа, рече, тоа е прилично лесен за употреба. Тоа ќе ни даде карактер, па сите ние треба да направите е да ги прашува датотеката, "Дајте ми следниот знак, дај ми следниот знак, дај ми следниот карактер," додека не се дојде до крајот на датотеката. И дека ќе се повлече во еден лик во еден момент од нашиот датотека, и потоа можеме да направиме она што го сакаме со него. Ние можеме да се чува, ние може да го додадете во низа, можеме да го испечатите. Дали некој од тоа. Зумирање назад и да се вратам на нашите cat.c програма, ако сте ќе се користи fgetc, како да им пријде на ова следната линија на кодот? Одиме да се користи - fread ќе направи нешто малку поинаква. И овој пат, ние сме само ќе ги користи fgetc да се добие еден лик во исто време. За процесирање на целата датотека, она што можеби ќе треба да се направи? Колку знаци постојат во датотека? Постојат голем број. Па веројатно сакате да се добие една а потоа да добијат уште еден и да добијат друга и се друго. Каков вид на алгоритам мислите ние можеби ќе мора да се користи тука? Каков вид на - [Александар] А за телефонска линија? >> Токму така. Некој вид на јамка. А за телефонска линија е, всушност, голема, во овој случај. И како што велеа, тоа звучи како сакате јамка во текот на целата датотека, добивање на карактер во исто време. Било какви предлози за тоа што тоа може да изгледа како? [Александар, неразбирливо] >> Океј, само кажете ми на англиски јазик она што се обидувате да го направите? [Александар, неразбирливо] Значи во овој случај, тоа звучи како ние сме само се обидува да јамка во текот на целата датотека. [Александар] Па јас <големината на int? >> Големината на - Претпоставувам дека големината на датотеката, нели? Големината - we'll само напиши го тоа како оваа. Големина на датотеката засега, i + +. Значи излегува дека начинот на кој го направите тоа користејќи fgetc, и ова е ново, е дека нема лесен начин да се само да добие со големина на датотека со овој "sizeof" тип на изградба дека сте виделе порано. Кога ние ги користиме која fgetc функција, ние сме за воведување на некои вид на нова, фанки синтаксата на овој за телефонска линија, каде што, наместо користење на само основните контра да одат знак по знак, ние ќе треба да се повлече еден карактер во еден момент, еден карактер во еден момент, и начинот на кој ние знаеме дека сме на крајот е кога не сме сметаат одреден број на карактери, но кога ликот ќе се повлече е тој посебен крајот на датотеката карактер. Значи можеме да го правиме ова преку - Јас ова го нарекуваат ch, и ние ќе го иницијализира со нашиот прв повик за да се добие првиот карактер од датотеката. Значи овој дел токму тука, ова се случува да се добие лик од датотека и се чува во променлива ch. Ние ќе го задржи тоа се додека не стигнете до крајот на датотеката, што правиме со тестирање за карактерот не е еднаква на таа специјална EOF карактер. А потоа наместо да прави CH + +, што само би зголемување на вредноста, па ако читаме А од датотека, капитал, да речеме, CH + + ќе ни даде б, а потоа ние ќе добијам в а потоа г. Тоа не е јасно она што го сакаме. Она што сакаме тука во оваа последната трошка е што сакаме да го добиете следниот карактер од датотеката. Па како да го добиете следниот карактер од датотеката? Како да ја добиете првиот карактер од датотеката? [Студентски] fgetfile? >> Fgetc, или, жал, сте биле сосема во право. Јас го згрешивте во пишувањето право таму. Така да. Еве, наместо за правење на ch + +, ние сме само ќе да се јавите fgetc (датотека) повторно и чување на резултат во нашата истиот ch променлива. [Студентски збор, неразбирливо] >> Ова е местото каде што овие датотеки * момци се специјални. Начинот на кој тие работат е тие - кога за прв пат се отвори - кога за прв пат го направат тој fopen повик, на датотеката * ефикасно служи како покажувач на почетокот на датотеката. И тогаш секој пат кога ќе се јавите fgetc, што се движи еден карактер преку датотека. Значи секогаш кога ќе се јавите ова, ти си ја зголемува датотеката покажувачот од страна на еден карактер. И кога ќе fgetc повторно, ти си го водиш друг карактер и друг карактер и друг карактер и друг карактер. [Студентски збор, неразбирливо] >> И that's - Да. Тоа е вид на оваа магија под хауба. Вие само задржи зголемување, преку. Во овој момент, сте во можност да всушност работат со карактер. Па, како би можеле да печати ја оваа надвор на екранот, сега? Можеме да го користиме истиот printf нешто што ние се користи пред. Дека ние сме биле со користење на сите семестар. Можеме да го наречеме printf, и ние може да помине во знакот само така. Друг начин да го направи тоа е, наместо користење printf и морале да го направите ова формат стринг, ние исто така може да користите една од другите функции. Можеме да го користиме fputc, кој отпечатоци лик на екранот, освен ако гледаме fputc - дозволете ми да одзумирате малку. Можеме да видиме што е убаво е што е потребно во ликот што го читаме со користење fgetc, но тогаш ние треба да го даде поток да се печати. Ние, исто така може да се користи putchar функција, која ќе стави директно на стандарден излез. Па така постојат еден куп на различни опции кои може да се користат за печатење. Сите тие се во стандардната библиотека I / O. Секогаш кога сакате да печатите - па printf, по правило, ќе се печати на посебни стандарден излез поток, а тоа е дека stdout. Па ние само може да се однесува на тоа како вид на оваа магија вредност, stdout тука. Упс. Стави запирка надвор. Ова е многу нова, фанки информации тука. Многу од ова е многу идиоматичен, во смисла дека тоа е код што е напишано овој начин само затоа што е чиста за читање, лесна за читање. Постојат многу различни начини да го направи тоа, многу различни функции можете да го користите, но ние се стремат да, едноставно следете овие исти модели над над и. Затоа, не бидете изненадени ако видите кодот вака доаѓа повторно и повторно. Во ред. Во овој момент, ние треба да пауза за тој ден. Ви благодариме за кои доаѓаат. Ви благодариме за гледање ако сте онлајн. И ќе се видиме следната недела. [CS50.TV]