[Powered by Google Translate] [Члан 5 - Више Удобан] [Роб Бовден - Универзитет Харвард] [Ово је ЦС50. - ЦС50.ТВ] Као што сам рекао у свом е-поште, постоји много ствари које можете да користите осим апарата да се заиста уради сетове проблема. Препоручујемо да то уради у апарату само зато што онда можемо лакше да вам помогне а ми знамо како све иде на посао. Али, као један пример, где можете да урадите ствари ако, рецимо, немате приступ на апарату, или желите да радите у подруму Сциенце Центер - који заправо имају превише апарата - Ако желите да раде било где. Један од примера је да ли сте видели / чули ССХ? ССХ је у основи исто као повежете на нешто. Заправо, сада сам ССХед у апарату. Ја никад не раде директно у апарат. Овде је апарат, а ако погледате овде да видите ову ИП адресу. Ја никад не раде у самом апарату; Ја сам увек доћи до иТерм2 прозора / терминал прозор. Можете ССХ на ту ИП адресу, ссх јхарвард@192.168.129.128. Сећам се да је број врло лако, јер то је тако лепо образац. Али то ће ме питати за лозинку, а сада сам у апарату. У суштини, у овом тренутку, ако сте отворили терминал унутар самог апарата, Овај интерфејс је, међутим ви то користите, је управо иста као интерфејс ја користим овде, али сада си ССХед. Не морате да ССХ на апарату. Један пример другом месту можеш ССХ на је прилично сам сигуран да имају по дефаулту - О. Већи. Сви ви би требало да има по рачунима подразумеване ФАС на ФАС серверима. За мене, ја бих се ССХ рбовден@нице.фас.харвард.еду. То ће да вас питам да први пут, а ви да кажете. Моја лозинка је само ће бити мој ФСС лозинку. И сада, ја ССХед на лепим серверима, а ја могу да урадим шта год пожелим овде. Много класа можда узети као 124, ће морати да отпремите ствари овде да стварно пошаљете сетова проблема. Али рећи да немате приступ свом уређају. Онда можете да урадите ствари, као што се овде то ће рећи - Ово је само наш део питања. То ће вас питати да се то уради у апарату. Уместо тога, само ћу то урадити на серверу. Ја ћу да унзип то. Проблем ће бити да сте навикли да користите нешто као гедит или било унутар апарата. Нећеш имати то на ФСС серверу. То је све само це бити овако текстуално интерфејс. Тако да би било једно, покушајте да научите текст едитор који они имају. Они имају Нано. Нано је обично прилично једноставан за коришћење. Можете да користите стрелице и упишите нормално. Дакле, то није тешко. Ако желите да се заиста фенси можете да користите Емацс, који сам вероватно не би требало да отвори, јер ја не знам ни како да затворите Емацс. Контрола Кс контрола Ц? Да. Или можете користити Вим, што је оно што ја користим. И тако они су ваше опције. Ако не желите да то урадите, можете такође, ако се осврнемо на мануал.цс50.нет-- О. На рачунару, можете да користите ССХ ПуТТИ, што ћеш морати да одвојено преузимање. На Мац, можете само Терминала подразумевани коришћења или можете преузети иТерм2, који је као леп, фенси терминала. Ако идете на мануал.цс50.нет видећете линк на Нотепад + +, што је оно што можете да користите на рачунару. Она вам омогућава да СФТП из Нотепад + +, што је у суштини ССХ. Шта ово ће вам урадити је измените локално своје фајлове, и онда кад год желите да их сачувате, она ће их сачувате у нице.фас, где можете да их покрену. И еквивалент на Мац ће бити ТектВранглер. Дакле, то вам омогућава да урадите исту ствар. Она вам омогућава да измените фајлове локално и сачувајте их на нице.фас, где можете да их покрену. Дакле, ако сте икада заглавили без апарата, имате ове опције да и даље раде свој сетова проблема. Један проблем ће бити да нећеш имати ЦС50 библиотеку јер нице.фас нема по дефаулту имамо. Можете да преузмете ЦС50 библиотеку - Ја не мислим да је потребно да у овом тренутку. Можете да преузмете ЦС50 библиотеку и копирајте га до нице.фас, или мислим да у овом тренутку ми га не користимо више свеједно. Или, ако то урадимо, можете за сада га замените могућим од функција у ЦС50 библиотеци у сваком случају. Тако да не би требало да буде да много ограничења. И то је то. Вратићу се на апарату сада, ми ћемо учинити све што је у апарату. Гледајући нашој секцији питања, на почетку, као што сам рекао у свом е-маил, морамо да разговарамо о једном кратком сте требали да гледају. Имамо преусмеравањем и цеви и ова три питања. На које поток не функционише као иф пишем по дефаулту? Тако поток. Шта је поток? Поток је у основи као да је то само неки - То није ни извор 1с и 0с. Поток је то тражим овде је стандардна напоље. И тако стандардни излаз је поток да када пишете на њега, се појављује на екрану. Стандард се, потока, то значи да само пишите 1с и 0с до њега, а други крај стандардног излаза само чита из тог потока. То је само низ 1с и 0с. Можете да пишете потока или можете читати из потока зависно од тога шта је заправо поток. Преостале две стандардне потоци су стандардни у и стандардну грешку. Стандардна ин је кад год се ГетСтринг, то је за вас чека за унос ствари. Тако да чека, она заправо чека на стандард у, што је заиста оно што ћете добити када откуцате на тастатури. Ви куцате на стандард ин Стандардна грешка је у суштини еквивалентно стандарду излаза, али је специјализована у томе када штампате на стандардну грешку, Требало вам да штампате само поруке о грешкама које тако да можете разликовати редовних поруке штампане на екрану насупрот грешци у зависности од тога да ли су они отишли ​​на стандардни излаз или стандардног грешке. Фајлови превише. Стандард се, стандардно у, а стандардна грешка је само посебни токови, али стварно свака датотека, када отворите датотеку, она постаје ток бајтова где можете само читати из тог потока. Ви, у највећем делу, могу само мислити датотеке као ток бајтова. Па шта потоци они писати по дефаулту? Стандардна напоље. Која је разлика између> и >>? Да ли је ико гледа унапред видео? Ок. > Биће како преусмерити у фајлове, и >> такође ће преусмерити излаз у фајлове, али је уместо тога ће додати у датотеку. На пример, рецимо да сам се десити да ДИЦТ овде, и само ствари унутар ДИЦТ је мачка, мачка, пас, риба, пас. Једна команда да имате у командној линији је мачка, који је само ће да штампа шта је у датотеци. Дакле, када кажем мачку ДИЦТ, то ће штампати мачка, мачка, пас, риба, пса. То је све мачка ради. То значи да је штампа стандарду од мачка, мачка, пас, риба, пса. Ако бих уместо тога желе да преусмерите у датотеку, могу користити> и преусмери га на било фајл. Позваћу фајла. Па сад, ако И лс, видећу имам нови фајл под називом датотека. А ако га отворите, то ће имати шта мачка ставио у командној линији. Па сад, ако то урадим поново, онда ће преусмерити излаз у фајл, и ја ћу имати исту тачан ствар. Дакле технички, потпуно поништио оно што смо имали. И ми ћемо видети ако променим ДИЦТ, извадио сам пса. Сада, ако се мачка дицт у фајлу опет ћемо имати нову верзију са пса уклоњена. Тако да је потпуно замењује. Уместо тога, ако >> користимо, то ће додати фајл. Сада, отварање датотеке, видимо да имамо само исту ствар два пута штампан јер је тамо био једном, онда смо у прилогу оригинала. Дакле, то је оно што> и >> уради. Да ли следећи пита - не пита о томе. Други је да имамо <, који ако> преусмерава стандардну аут, <Ће бити преусмеравање стандард за Хајде да видимо да ли имамо пример. Могу да напишем један прави брзо. Узмимо било који фајл, хелло.ц. Релативно једноставан фајл. Ја сам само добијање ниску, а затим штампа "Здраво", шта год стринг сам ушао била. Тако да здраво и онда / здраво.. Сада ме је навело да уђе у нешто, што значи да чека на ствари које треба унети у стандард ин Зато унесите год хоћу у стандард за Само ћемо рећи Здраво, Роб! Онда је штампање стандарду од Здраво, Роб! Ако урадим / здраво и. Преусмеравање, за сада само може да преусмери из датотеке. Дакле, ако сам ставио у неком фајлу, ткт, и ставио сам Роб, ако здраво покренути и преусмеравање ткт у. / здраво, то ће рећи Здраво, Роб! одмах. Када је први стигне до ГетСтринг и чека на стандарду у, стандард у више не чека на тастатури за податке да се уносе. Уместо тога, ми смо преусмерени стандард да чита из датотеке ткт. И тако ће да чита из датотеке ТКСТ, што је само линија Роб, а онда ће се штампати Здраво, Роб! И ако сам желео, ја могао да урадим / здраво <ткт. и онда стандардна напоље да је штампа, која је Здраво, Роб!, Ја могу преусмерити то у сопственом фајлу. Само ћу звати фајл здраво - не, ја нећу, јер је извршна - ткт2. Сада ткт2 ће имати излаз / Хелло <. Ткт, који ће бити Здраво, Роб! Питања? Ок. Дакле, овде имамо нафтовод. Цеви су последња јединица преусмеравање. О. Ваљда још један јединица преусмеравање је ако уместо> ти 2>, то је преусмеравање стандардну грешку. Дакле, ако нешто оде на стандардну грешку, не би се ставио у ткт2. Али приметити ако ја 2>, онда је још увек штампа Здраво, Роб! на командној линији јер сам само ја преусмерава стандардну грешку, нисам преусмеравање стандард напоље. Стандардна грешка и стандардни напоље су различити. Ако сте желели да заправо пише на стандардном грешком, онда бих могао да промени ово буде иф на стдерр. Дакле принтф, по дефаулту, штампа на стандардну напоље. Ако желим да штампате на стандардну грешку ручно, онда морам да користе иф и одредите шта желите да одштампате на. Ако уместо јесам фпринтф стдоут, онда је то у суштини еквивалентно принтф. Али иф на стандардну грешку. Па сад, ако сам преусмери ово у ткт2, Здраво, Роб! још увек узимајући штампа у командној линији пошто је добијање штампа стандардне грешке, а ја сам само преусмерава стандард напоље. Ако сад преусмери стандардну грешку, а сада нису добили штампане и ткт2 ће бити Здраво, Роб! Тако сада можете да одштампате стварне грешке у стандардну грешку и одштампали своје редовне поруке стандардног излаза. И тако, када покренете програм, можете да га покренете као / здраво овај тип. Са 2> тако да је ваш програм ће да ради нормално, али све поруке о грешкама које сте добили касније можете проверити у свом дневнику о грешци, тако грешака, а затим погледајте касније и ваш фајл грешака које ће имати било какве грешке које су се дешавале. Питања? Последња је цев коју можете мислити као узимање стандард из једне команде и што је стандард у наредне команде. Пример овде ехо је командна линија ствар то је само ехо ће све што сам ставио као свој аргумент. Нећу ставити наводнике. Ехо бла, бла, бла је само łтампања бла, бла, бла. Раније, када сам рекао да сам морао да ставим Роба у ткт фајлу јер ја могу само да преусмери ТКСТ фајлове, уместо тога, / ако сам ецхо Роб а онда га у цеви / здраво, све ће учинити исту врсту ствари.. Ово је узимање излаз ове команде, ехо Роб, и да га користите као улаз за / здраво.. Можете мислити о томе као први преусмери ехо Роба у фајл а затим улаз у / здраво ту. фајл који је управо излазног. Али је потребно привремену датотеку из слике. Питања о томе? Следеће питање ће укључити ово. Шта гасовод могао да користите да бисте пронашли број јединствених имена у датотеку под називом намес.ткт? Команде да ћемо желети да овде користимо су јединствени, толико уник, а онда вц. То можете да урадите Уник човек да стварно погледате шта то ради, и то само иде да филтрира суседних подударају линије од улаза. И човек вц ће одштампате нови ред, Ворд и бајтова за сваки фајл. И последња ћемо желети да користите сортирање, који ће само да сортирате редове ткт фајла. Ако сам направити неки ткт фајл, намес.ткт, и то је Роб, Томи, Јосиф, Томи, Јосиф, РЈ, Роб, шта ја желим овде да урадите је да пронађете број јединствених имена у овом фајлу. Дакле, шта би требало да буде одговор? >> [Ученик] 4. >> Да. То би требало да буде 4 од Роб, Томи, Јосиф, РЈ су само јединствени имена у овом фајлу. Први корак, ако сам урадим број речи на намес.ткт, ово је стварно ми говори све. То је заправо штампа - да се види, човек вц - редовима, речи, и бајт рачунају. Ако сам само стало линије, онда могу само да урадим вц-л намес.ткт. Дакле, то је корак 1. Али ја не желим да вц-л намес.ткт јер намес.ткт само садржи сва имена, и желим да филтрира неке не-јединствене оне. Дакле, ако ја Уник намес.ткт, баш не дај оно што желим јер су дуплирани имена су још увек тамо. Зашто је то тако? Зашто уник не ради оно што ја желим? [Ученик] дупликати нису [нечујан] >> Да. Запамтите ман страницу за Уник каже филтер суседних Матцхинг линије. Они нису суседне, тако да их неће филтрирати. Ако сам поређај их први, нека намес.ткт ће саставити све дуплиране редове. Дакле, сада некако намес.ткт је то. Ја ћу желети да користите као да је улаз на Уник, која је | уник. То ми даје Јосифа, РЈ, Роб, Томи, и желим да то користити као улаз у ВЦ-л, који ће ми дати 4. Као што овде пише, шта гасовод могао да користите? То можете да урадите много ствари, попут коришћења низ команди где користите излаз из једне команде као улаз у следећу команду. То можете да урадите много ствари, много паметних ствари. Питања? Ок. То је то за цеви и преусмеравање. Сада идемо на стварне ствари, кодирање стварима. Унутар овог ПДФ, видећете ову команду, а ви ћете желети да покренете ову команду у свом уређају. вгет је команда за само добијам нешто са Интернета, у основи, па вгет и овај УРЛ. Ако сте отишли ​​на овај УРЛ у прегледачу, да би преузели тај фајл. Само сам кликнуо на њега, па је скинуо фајл за мене. Али писање вгет те ствари унутар терминала је само ће га преузети на вашем терминалу. Имам сецтион5.зип, а ви ћете желети да унзип сецтион5.зип, која ће вам дати фолдер зове сецтион5, који ће имати све фајлове да ћемо користити данас унутар њега. Како ови програми "имена датотека сугеришу, они мало луд, па ваша мисија је да схватим зашто коришћење ГДБ. Да ли сви су их преузели / знају како да их преузети у свом апарату? Ок. Трчање ./бугги1, то ће рећи кривице сегментације (језгро бачена) који сваки пут кад се сегфаулт, то је лоша ствар. Под којим околностима не добијате сегфаулт? [Ученик] Дереференцинг нулл показивач. >> Да. Дакле, то је један пример. Дереференцинг нулл показивач идете да добијете сегфаулт. Шта значи сегфаулт је ви додирујете меморију не би требало да буде дирљиво. Дакле дереференцинг нулл показивач додирује адресу 0, и у суштини, сви рачунари данас кажу да је меморија адреса 0 не би требало да додирује. Зато дереференцинг нулл поинтер резултате у сегфаулт. Када се деси да се не покрене показивач, онда она има смеће вредност, па када покушате да дереференце то, по свему судећи ти додиривања меморију то је у сред недођије. Ако вам се деси да се среће и смеће вредност десило да се укаже на негде на стек, или тако нешто, онда када дереференце да показивач које нисте иницијализован, ништа неће поћи наопако. Али ако се то показује, рецимо, негде између стека и гомиле, или је то само показује да негде да није коришћена од стране вашег програма увек, онда сте додиривања меморију не би требало да се додирују, а ви сегфаулт. Када пишете рекурзивно функцију и рецурсес превише пута и ваш штек расте сувише велики и ланцани судари у ствари да то не би требало да буде судара са, ви додирујете меморију не би требало да буде дирљив, па сегфаулт. То је оно што је сегфаулт. То је такође исти разлог да ако имате ниску као - Вратимо се на претходни програм. У хелло.ц--Ја само ће направити нешто друго. цхар * с = "Хелло Ворлд!"; Ако користим * с = нешто или с [0] = "Кс"; па се здраво, / здраво. зашто је то сегфаулт? Зашто је ово сегфаулт? Шта би сте очекивали да се деси? Ако сам урадио принтф ("% с \ н", с); шта би сте очекивали да се штампа? [Ученик] Кс здраво. >> Да. Проблем је у томе што када прогласи ниску овако, с је показивач који ће ићи на стек, а шта се указује на ово стринг који је садржан у само за читање меморије. Дакле, само по имену, меморија само за читање, требало би да добијете идеју да ако покушате да промените оно што је у само за читање меморије, радиш нешто што не би требало да раде са меморијом и сегфаулт. Ово је заправо велика разлика између цхар * с и цхар с []. Дакле, цхар с [], сада овај стринг ће бити стављен на стек, и стек није само за читање, што значи да овај посао савршено добро. И то чини. Запамтите да када радим цхар * с = "Хелло Ворлд!", А сама је на стеку али с указује на неком другом месту, и да негде другде деси да буде само за читање. Али цхар с [] је само нешто на стек. Дакле, то је још један пример сегфаулт дешава. Видели смо да ./бугги1 резултирало сегфаулт. У теорији, не би требало да изгледа на бугги1.ц одмах. Уместо тога, ми ћемо на то гледате кроз ГДБ. Приметите да када сте добили сегментације грешку (језгро бачена) ти овај фајл овде зове језгро. Ако смо лс-л, ми ћемо видети да језгро је обично прилично велики фајл. Ово је број бајтова у фајлу, тако да изгледа као да је 250-нешто килобајта. Разлог за то је да је оно што је заправо срж депонија је када ваш програм сруши, стање меморије вашег програма само добија копирали и налепили у овом фајлу. Бива бачена је на тај фајл. Овај програм, док је трчао, десило се да имају употребу меморије од око 250 килобајта, па то је оно што је добио бачена у овом фајлу. Сада можете да погледате тај фајл ако урадимо ГДБ бугги1 језгро. Ми само можемо учинити ГДБ бугги1, и да ће само покренути ГДБ редовно, користи бугги1 као свог улазног фајла. Али ако ти ГДБ бугги1 језгро, онда посебно ће се покренути ГДБ гледајући тај основни фајл. И ви кажете бугги1 значи ГДБ зна да је цоре датотека долази из бугги1 програма. Дакле ГДБ бугги1 језгро ће се одмах нам донесе где програма десило да прекине. Ми овде видимо програм престаје са сигналом 11, сегментација грешке. Ми се десити да видимо линију окупљања, која вероватно није од велике помоћи. Али, ако откуцате Бт или Бацктраце, то ће бити функција која нам даје списак наших тренутних стека оквире. Тако повратно праћење. Изгледа да имамо само два стек оквире. Први је наш главни стек оквир, а други је стек оквир за ову функцију да ми се деси да се у, који изгледа као да има само код монтаже за. Дакле, хајде да се вратимо у нашу основну функцију, и да урадимо што можемо учинити рам 1, и мислим да можемо урадити доле, али ја скоро никада не доле - или горе. Да. Горе и доле. До вам доноси један стек оквир, доле доноси вам доле стека оквир. Склон сам да никада не користим то. Ја само да кажем конкретно оквир 1, која се иде на рам са ознаком 1. Оквир 1 ће да нас доведе у главни стек оквира, и каже управо овде линију кода ми се деси да буде у. Ако бисмо хтели још пар линија кода, можемо рећи листу, и да ће нам дати све линије кода око њега. Линија ми сегфаултед на било 6: иф (стрцмп ("ЦС50 стене", аргв [1]) == 0). Ако није очигледно још увек можете добити директно одавде само размишљам зашто је сегфаултед. Али можемо да га узме један корак даље и кажу: "Зашто би аргв [1] сегфаулт?" Хајде да штампа аргв [1], и изгледа као да је 0к0, који је нулл показивач. Ми стрцмпинг ЦС50 стене и ништавном, као и да ће се сегфаулт. И зашто је аргв [1] нулл? [Ученик] Пошто нисмо дају никакве аргументе командне линије. Да. Нисмо се дају никакве аргументе командне линије. Тако ./бугги1 само ће имати аргв [0] бити ./бугги1. То неће имати аргв [1], тако да ће сегфаулт. Али ако, уместо тога, ја само ЦС50, то ће рећи ћете добити Д јер то је оно што је требало да уради. Гледајући бугги1.ц, то је требало да штампа "Добићете Д" - Ако аргв [1] није "ЦС50 стене", "Добићете Д", други "Добићете!" Дакле, ако желимо, морамо ово да упоредите као истинито, што значи да се пореди са 0. Дакле, аргв [1] треба да буде "ЦС50 стене". Ако желите да урадите да на командној линији, морате да користите \ да побегне простор. Дакле ЦС50 \ стене и добићете а! Ако не урадите обрнуту косу црту, зашто се то не ради? [Ученик] То су два различита аргумента. >> Да. Аргв [1] ће бити ЦС50, а аргв [2] ће бити стене. Ок. Сада ./бугги2 ће поново сегфаулт. Уместо отварања је са својим језгром фајлу, само ћемо отворити бугги2 директно, тако ГДБ бугги2. Сада, ако смо само покренули наш програм, онда ће рећи програма добио сигнал СИГСЕГВ, који је сегфаулт сигнал, а то је место где се то десило да се догоди. Гледајући наше Бацктраце, видимо да смо били у функцији ох_но, који је позван од стране функције Динки, који је сазвао функције бинки, који је позвао главни. Такође можемо видети аргументе ових функција. Аргумент да Динки и бинки је 1. Ако се наведе ох_но функцију, видимо да је управо ради ох_но цхар ** С = нулл; * С = "БООМ"; Зашто би то успети? [Ученик] Ти не можеш дереференце нулл показивач? >> Да. Ово је само говори с је НУЛЛ, без обзира ако се то деси да буде цхар **, који, у зависности од тога како га тумаче, то може бити показивач на показивач на стринг или низ стрингова. То је с је НУЛЛ, тако * с је дереференцинг нулл показивач, па ово ће да се сруши. Ово је један од најбржих начина да евентуално може сегфаулт. То је само проглашење нулл показивач и одмах сегфаултинг. То је оно што ох_но ради. Ако идемо горе за један фрејм, онда ћемо ући у функцију која се зове ох_но. Морам да урадим то. Ако не унесете команду и само притисните Ентер поново, само ће се поновити претходну команду коју сте покренули. Ми смо у оквиру 1. Наводећи овом оквиру, видимо овде је наша функција. Можете да притиснете поново списак, или можете да урадите листу 20 и то ће навести више. Функција Динки каже да ако је ја 1, онда идите на ох_но функцији, иначе ће ићи на Слинки функцију. А знамо и је 1, јер ми се деси да видим овде да Динки звала са аргументом 1. Или једноставно можете да одштампам и то ће рећи да је 1. Тренутно смо у Динки, и ако одемо још један оквир, знамо да ћемо завршити у бинки. Горе. Сада смо у бинки. Наводећи ову функцију - листа од пре пола ме одсечен - је почела као да и је 0, онда ћемо да га зову ох_но, иначе зовем Динки. Знамо сам био 1, па Динки зове. А сада смо се вратили у главни, а главни је само ће бити инт = ранд ()% 3; То је само ће вам дати случајни број који је било 0, 1 или 2. То ће позвати бинки са тим бројем, а она ће се вратити 0. Гледајући ово, само шетају кроз програм ручно, а да је покренут одмах, ти би поставили тачку бреак на главном, што значи да када смо покренули програм ваш програм траје до удара паузе тачку. Дакле, ради програм, он ће покренути и онда ће погодити главну функцију и престати да се приказују. Сада смо унутар главни, и корак или поред ће нас довести до следеће линије кода. То можете да урадите корак или следећи. Ударање поред, сада сам је постављена на РАНД ()% 3, тако да можемо да штампамо вредност и, и то ће рећи да је 1. Сада је битно да ли ћемо користити следеће или корак. Претпостављам да је важно у претходном један, али ми би желели да користе следеће. Ако користимо корак, ми смо корак у функцију, што значи поглед на стварне ствари што се дешава унутар бинки. Ако користимо следећи, онда то значи да иде преко функције и само идите на следећу линију кода у нашем главном функцијом. Управо овде на овој линији, ја сам био на којој је писало ранд ()% 3; ако јесам корак, то би ићи у реализацију ранда и погледати шта се тамо дешава, а ја сам могао корак кроз РАНД функцију. Али ја не брига о РАНД функцију. Ја само желим да идем на следећу линију кода у основни, тако да користим следећа. Али сада ми је стало у бинки функцији, тако да желим да закорачите у то. Сада сам у бинки. Прва линија кода ће рећи ако (и == 0), узимам корак, видимо се завршити на Динки. Ако смо списак ствари, видимо да је то проверио и је = 0. И није једнак 0, па је отишао у другом стању, који ће позвати Динки (и). Можда се Ви збуњени. Ако само погледате ове линије директно, можда мислите ако (и == 0), ок, онда сам узео корак и сада сам на Динки (и) Ви можда мислите да мора да значи и = 0 или тако нешто. Не само значи да она зна да може директно да се држимо линије Динки (и). Пошто нисам је 0, следећи корак неће завршити на другом месту. Друго није ред да ће то зауставити на. То је само да идем на следећу линију заправо може да изврши, што је Динки (и). Степпинг у Динки (и), видимо ако (и == 1). Ми ја знам = 1, па кад смо корак, знамо да ћемо завршити у ох_но јер сам = 1 позива функцију ох_но, коју може стати у, који ће поставити цхар ** е = на НУЛЛ и одмах "БООМ". И онда стварно гледа на имплементацију бугги2, ово, само сам се добија случајни број - 0, 1 или 2 - позивање бинки, који ако и је 0 она позива ох_но, друго је Динки позива, који долази овде. Ако сам је 1, позив ох_но, иначе зовем Слинки, који долазе овде, ако сам је 2, позовите ох_но. Ја чак и не мислим да постоји начин - Да ли неко види начин да ово програм који неће сегфаулт? Јер осим ако сам нешто пропустио, ако сам 0, одмах ћете сегфаулт, одис на функцији која ако сам је 1 ти сегфаулт, одис на функцији где ако сам је 2 сте сегфаулт. Дакле, без обзира шта радите, ви сегфаулт. Претпостављам један начин одређивања било би уместо да ради цхар ** С = нулл, бисте могли да маллоц простор за ту жицу. Могли би до маллоц (сизеоф) - сизеоф шта? [Ученик] (цхар) * 5? >> Да ли ово изгледа добро? Претпостављам да ће радити ако га стварно побегао, али то није оно што ја тражим. Погледајте врсте е. Хајде да додамо инт *, па инт * к. Ја бих урадио маллоц (сизеоф (инт)). Или, ако сам хтео низ од 5, ја бих урадио (сизеоф (инт) * 5); Шта ако имам инт **? Оно што бих маллоц? [Ученик] Величина показивача. >> Да. (Сизеоф (инт *)); Иста ствар овде. Желим (сизеоф (цхар *)); Ово ће доделити простор за показивач који указује на "бум". Не треба да издвоји простор за "БООМ" сама јер је то у суштини еквивалентно ономе што сам рекао раније од цхар * к = "БООМ". "БООМ" већ постоји. То се дешава да постоји у само за читање региону меморије. Али већ постоји, што значи да ову линију кода, ако је с цхар **, онда * с је цхар * и ви поставите ову цхар * да укаже на "бум". Да сам хтео да копира "бум" у С, онда би требало да издвоји простор за с. Урадићу * с = маллоц (сизеоф (цхар) * 5); Зашто 5? Зашто не 4? То изгледа као "БООМ" је 4 карактера. >> [Ученик] нулл карактер. Да. Сви ваши ниски ће морати нулл карактер. Сада могу да урадим нешто као стрцат - Шта је функција за копирање ниску? [Ученик] КПЈ? >> Стрцпи. Човек стрцпи. Дакле стрцпи или стрнцпи. стрнцпи је мало сигурније, јер можете да одредите тачно колико карактера, али овде то није битно јер знамо. Тако стрцпи и погледајте у аргумената. Први аргумент је наша дестинација. Други аргумент је наш извор. Идемо да копирате у наше одредиште * С показивач "БООМ". Зашто би желите да урадите са стрцпи уместо само оно што смо имали раније од * с = "БООМ"? Постоји разлог можда желите да урадите ово, али шта је то разлог? [Ученик] Ако желите да промените нешто у "бум". >> Да. Сада могу да урадим нешто слично с [0] = "Кс"; јер с указује на гомилу и да је простор на гомили да је с указује на је показивач на више простора на гомили, који је чување "бум". Дакле, ово копија "бум" се чува у гомили. Технички Постоје две копије "бум" у нашем програму. Ту је први који је само дао овај "бум" стринг константа, а други примерак "бум", стрцпи створио копију "бум". Али копија "бум" се складиште на гомилу, и гомила сте слободни да промените. Гомиле није само за читање, тако да значи да је с [0] ће се дозволити да промените вредност "бум". То ће дозволити да промените те знакове. Питања? Ок. Прелазак на бугги3, идемо ГДБ бугги3. Ми само покренути и видимо добијамо сегфаулт. Ако се повратно праћење, постоје само две функције. Ако идемо горе у нашем главном функцији, видимо да смо сегфаултед на овој линији. Дакле, само гледајући ову линију, за (инт ред = 0; фгетс ова ствар није једнак НУЛЛ; линија + +). Наша претходна оквир назван _ИО_фгетс. Видећете да доста са уграђеним Ц функције, да када добијете сегфаулт, ту ће бити стварно загонетна имена функција Лике Тхис _ИО_фгетс. Али то ће се односе на овај позив фгетс. Негде овде унутра, ми смо сегфаултинг. Ако се осврнемо на аргументе да фгетс, можемо да штампамо бафер. Хајде да штампају као - Ох, не. Штампа неће радити онако како ја желим. Погледајмо самог програма. Бафер је карактер низ. То је карактер низ од 128 знакова. Дакле, када кажем штампа тампон, то ће штампати те 128 знакова, што претпостављам је оно што се очекује. Оно што сам тражио је одштампате адресу бафера, али то заиста не реци много. Дакле, када сам се деси да кажем овде к бафер, то ми показује 0кбфффф090, који, ако се сећате од раније, или неком тренутку, Окбфффф тежи да буде стек-исх региону. Стек тежи почети негде испод 0кц000. Само гледајући ову адресу, ја знам да бафер се дешава на стеку. Рестартовање мој програм, трчи, горе, баферује смо видели било је ту низ знакова које су прилично бесмислене. Затим штампа фајл, шта фајл изгледа? [Ученик] Нула. >> Да. Датотека је од * типа ФИЛЕ, па је показивач, и вредност тог показивача је нулл. Дакле фгетс ће покушати да чита из тог показивача на посредан начин, али да би приступили тој показивача, то мора да дереференце га. Или, како би приступили оно што би требало бити усмерена на, он га дереференцес. Дакле, то је дереференцинг нулл показивач и ИТ сегфаултс. Могао сам да га поново тамо. Ако се пробије у нашем главном месту и покренути, Прва линија кода је цхар * филенаме = "нонекистент.ткт"; То би требало да дају лепу велику наговештај о томе зашто овај програм не успе. Куцање поред ме доводи до следеће линије, где сам отворити овај фајл, и онда сам одмах уђем у нашој линији, где сам једном погодио следећи, то ће сегфаулт. Да ли неко жели да избаци разлог зашто смо можда сегфаултинг? [Ученик] Фајл не постоји. >> Да. Ово је требало да буде наговештај да кад год ви отварате датотеку морате да проверите да ли фајл заиста постоји. Па ево, "нонекистент.ткт"; Када смо фопен фајла за читање, онда треба рећи иф (фајл == НУЛЛ) и кажу принтф ("Фајл не постоји!" или - још боље - филенаме); ретурн 1; Дакле, сада смо проверили да ли је НУЛЛ пре него што уствари наставља и покушава да чита из тог фајла. Можемо га преобликује само да видимо да то ради. Намеравао сам да укључи нову линију. Дакле, сада нонекистент.ткт не постоји. Увек треба да проверите за овакве ствари. Увек треба да проверите да ли фопен враца НУЛЛ. Увек треба да проверите да бисте се уверили да маллоц не врати НУЛЛ, или друго што сегфаулт. Сада бугги4.ц. Руннинг. Нагађам то чека за улаз или евентуално бесконачне петље. Да, то је бесконачна петље. Тако бугги4. Изгледа да смо бескрајно петље. Можемо сломити на главни, покрените наш програм. У гдб, док скраћеница користите је недвосмислен или посебне скраћенице које они пружају за тебе, онда можете користити н користити следећа уместо да откуцате од следећег скроз. И сада, када сам ударио Н једном, само да притиснете Ентер да наставим следећу уместо да удари н Ентер, н Ентер, н Ентер. Изгледа као да сам у некој врсти за петљу која се постављањем низ [и] да 0. Изгледа као да никада нећу избијања ово за петљу. Ако сам ја штампа, тако да сам је 2, онда ћу ићи даље. Ја ћу да одштампам, ја је 3, а онда ћу ићи даље. Ја ћу да одштампам и ја је 3. Даље, одштампајте ја, ја је 4. Заправо, штампање сизеоф (арраи), тако да величина низа је 20. Али изгледа као да постоји нека посебна гдб команда за одлазак док се нешто деси. То је као постављање услов на вредност променљиве. Али ја се не сећам шта је то. Дакле, ако наставимо - Шта си рекао? Шта си поменуо? [Ученик] Да ли приказати додам - ​​>> Да. Дакле, приказали ја могу да помогнем. Ако смо само да прикажем, то ће ставити овде ста вредност И је тако да не морате да га одштампате сваки пут. Ако само наставимо даље, видимо 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5. Нешто се дешава ужасно лоше, а ја се ресетује на 0. Гледајући бугги4.ц, видимо све што се дешава је инт низ [5]; фор (и = 0; и <= сизеоф (арраи); и + +) низ [и] = 0; Шта видимо да је то у реду овде? Као наговештај, када сам радио у ГДБ бугги4 - хајде да прекине главни, трчање - Ја нисам принт сизеоф (арраи), само да видим шта стање је где сам коначно треба избити. Где сам ја? Јесам ли покренути? Нисам још изјасне. Дакле принт сизеоф (арраи), а то је 20, што се очекује, јер је мој низ од величине 5 и то је од 5 целих бројева, па цела ствар треба да буде 5 * сизеоф (инт) бајтова, где сизеоф (инт) настоји да буде 4. Дакле, сизеоф (арраи) је 20. Шта би то требало да буде? [Ученик] подељени по сизеоф (инт). >> Да, / сизеоф (инт). Изгледа још увек је овде проблем. Мислим да ово треба да буде само < пошто је прилично увек <и никада <=. Сада хајде да размислимо о томе зашто је то заправо сломљен. Да ли неко има нагађања зашто сам ресетује на 0 преко сваке итерације петље? Једина ствар унутар овде да се дешава је да се низ [и] је подешена на 0. Тако некако, ова линија кода изазива нашу инт да се подеси на 0. [Ученик] Да ли је могуће, јер је то најважнији сећање на овом делу И када мисли да је следећи елемент низа? >> [Боуден] Да. Кад идемо ван на крају нашег низа, некако тај простор да смо најважнији је најважнији вредност и. И тако, ако погледамо у бугги4, разбити главни, трчи, хајде да одштампате адресу и. Изгледа као да је бфффф124. Сада идемо одштампате адресу низа [0]. 110. Шта [1]? 114. [2], 118. 11ц, 120. низ [5] је бффф124. Дакле, низ [5] има исту адресу као и, што значи да низ [5] и је. Ако они имају исту адресу, они су иста ствар. Дакле, када смо поставили низ [5] на 0, ми смо ја постављање на 0. А ако мислите да о томе у смислу стека, инт прво сам изјавио, што значи да добија мало простора на стеку. Тада низ [5] је додељен, па онда 20 бајтова се додељују на стеку. Тако сам први пут добија додељена, онда се ови 20 бајтова се издвојила. Тако сам се дешава непосредно пред низа, и због начина на који, као што сам рекао прошле недеље, где је технички стек расте надоле, када индекс у низу, ми гарантује да је 0. положај у низу Увек се дешава пре прве позиције у низу. То је врста како сам га извукао просле недеље. Приметите да је на дну имамо адресу 0 и на врху имамо адресу Мак. Стек се увек расте надоле. Рецимо да ја издвоји. Ми издвојити цео ја, што значи да рецимо само овде цео сам бива додељен. Онда ћемо издвојити нашу палету 5 целих бројева, што значи да испод тога, јер стек расте надоле, те 5 целих бројева се издвојила. Али због како низови раде, ми гарантовано да је први положај у низу увек има адресу мање него друге ствари у низу. Дакле, низ позиција 0 увек мора да се деси први у меморији, док низ позиција 1 има да се деси после тога и низ позиција 2 мора да се деси после тога, што значи да је низ позиција 0 бих негде десити овде доле, низа позиција 1 ће се догодити изнад тога јер се креће нагоре значи веће адресе јер максимална адреса је овде. Дакле, низ [0] овде доле, низ [1] овде, низ [2] овде, низ [3] овде. Обратите пажњу како пре него што издваја цео сам све пут до овде, како идемо даље и даље у нашем низу, ми смо све ближе и ближе нашим и цео број. То је тако једноставно дешава да арраи [5], који је једно место изнад нашег низу, је тачно тамо где цео ми се десило да се додели. Дакле, то је место где смо се деси да се удара простора на стек која је намењена за цео и, и ми смо то постављање 0. Тако то функционише. Питања? Да. [Ученик] Не смета. Ок. [Ученик] Како да избегнете ове врсте грешака? Такве грешке? Немојте користити Ц као програмски језик. Користите језик који има низа границе проверу. Докле год сте пажљиви, само је потребно да се избегне одлазак поред граница вашег низа. [Ученик] Дакле, овде, када смо пролазили граница вашег низа - [Бовден] То је место где се ствари кренути наопако. >> [Ученик] Ох, у реду. Докле год остану у сећању издваја за низ, ти си у реду. Али Ц не никакву грешку проверу. Ако урадим низ [1000], он радо ће само мењати шта год се деси - Она одлази на почетку низа, онда то иде 1000 положаје после и поставља га на 0. То не раде никакву проверу да ох, не заправо имају 1000 ствари у њему. 1000 је далеко више од онога што сам треба да се мења, док Јава или нешто ћете добити низ од излази индекса или индекс од изузетка излази. Зато много вишим језицима имају те ствари где ако идете ван граница низа, не успеш тако да не може да промени ствари одоздо тебе и онда ствари иду много горе него само добијање изузетак кажете да сте отишли ​​након краја низа. [Ученик] И тако би смо управо променили <= само да > [Боуден] Да. То би требало да буде <сизеоф (арраи) / сизеоф (инт); јер сизеоф (арраи) је 20, али ми само желимо 5. >> [Ученик] Тачно. Још питања? Ок. [Ученик] Имам једно питање. >> Да. [Ученик] Шта је актуелно низ променљива? [Бовден] Као што је низ? Низ је сама симбол. То је само адреса поцетка од 20 бајтова које смо референцирање. Можете мислити о томе као показивача, али је константан показивач. Чим се ствари саставио, променљива низ више не постоји. [Ученик] Па како то наћи на величину низа? Величина низа се односи на величину тог блока да је симбол односи. Када урадим нешто слично принтф ("% п \ н", низ); хајде да пробамо. Шта сам погрешио? Арраи "низ" проглашен овде. О, овде. Цланг је паметан, и то се дешава да се примети да сам проглашен за низ од 5 елемената али ја индексира у положај 1000. То могу да урадим, јер су само константе. То само може да иде толико далеко у приметим да идем ван граница низа. Али пре него што приметите када смо имали и нетачно, она не може да се утврди колико вредности и може да преузме, тако да не може да утврди да ћу након краја низа. То је само кланг бити паметан. Али сада би бугги4. Па шта друго радим погрешно? Имплицитно декларисање библиотека функција "иф". Ја ћу желети да # инцлуде. Ок. Сада ради бугги4. Штампање вредност низа као што сам овде урадио, штампа га као показивач отисци нешто што изгледа овако - бфб8805ц - што је нека адреса која је у штек-исх региону. Низ је сама као показивача, али то није стварна показивач, пошто редовно показивач можемо променити. Низ је само нека константа. Тих 20 блокова меморије крећу адреси 0кбфб8805ц. Дакле бфб8805ц кроз ову адресу +20--или претпостављам -20 - Све је меморије издвојене за ову низа. Арраи, сама променљива не чувају нигде. Када сте прикупљање, преводилац - рука талас на томе - али компајлер ће само користити, где се зна ред да буде. Он зна где је низ почиње, па увек можемо урадити ствари у погледу компензације од тог почетка. То не треба да представља саму променљиву низ. Али када урадим нешто слично инт * п = низу, сада је п показивач који указује на то низу, и сада п заправо постоји на стеку. Ја сам слободан да промени стр. Ја могу да урадим п = маллоц. Тако је првобитно указала на низ, сада указује на неком простору на гомили. Ја не могу да урадим низа = маллоц. Ако цланг је паметан, он ће викати на мене право са палицом. Заправо, прилично сам сигуран гцц би урадили исто. Дакле, низ типа 'инт [5] "није прилагодљиви. Не можете доделити нешто низа типа јер је само низ константа. То је симбол који референце тих 20 бајтова. Ја не могу да га промени. [Ученик] А где је величина низа чувају? [Бовден] То не чувају нигде. То је када се то састављања. Па где је величина низа чувају? Можете да користите само сизеоф (арраи) унутар функције коју низ се декларисала. Дакле, ако ја неку функцију, Фоо, и ја (инт низ []) принтф ("% д \ н", сизеоф (арраи)); и онда доле зовем фоо (низ); унутар ове функције - хајде да пробамо. Ово је цланг бити паметан поново. То ми говори да је сизеоф на параметар низа функција ће вратити величину 'инт *'. То би грешка ако то није оно што сам хтео да се догоди. Хајде да ствари искључите Веррор. Упозорење. Упозорења су у реду. И даље ће саставити док има упозорење. /. А.оут ће штампати 4. Упозорење која је генерисана је јасан показатељ шта је пошло наопако. Ова инт низ је само łтампања сизеоф (инт *). Чак и ако сам ставио низ [5] овде, то је још увек само łтампања сизеоф (инт *). Дакле, чим га прође у функцију, разлика између низова и показивача не постоји. То се дешава да се низ који је проглашен на стек, али чим пређемо ту вредност, да 0кбф бла, бла, бла у овој функцији, онда овај показивач указује на то низу на стек. То значи да сизеоф важи само у функцији да се низ проглашен, што значи да када се изради ову функцију, када цланг пролази кроз ову функцију, види низ је инт низ величине 5. Онда види сизеоф (арраи). Па, то је 20. То је заправо начин сизеоф основи ради скоро свим случајевима. Сизеоф није функција, то је оператер. Не звати сизеоф функцију. Сизеоф (инт), компајлер ће само превести то 4. Капираш? Ок. [Ученик] Дакле, шта је разлика између сизеоф (арраи) у главни и фоо? То је зато што говоримо сизеоф (арраи), који је од * типа инт, док је низ овде није од типа инт *, то је инт низ. [Ученик] Дакле, ако сте имали параметар у низу [], уместо инт * низу, да ли би то значило да још увек може да промени низ, јер сада је показивач? [Бовден] Овако? >> [Ученик] Да. Можете да промените низ у функцији сада? [Бовден] Ти би могао да промени низ у оба случаја. У оба случаја сте слободни да кажете арраи [4] = 0. [Ученик] Али можете направити тачку низа на нешто друго? [Боуден] О. Да. У сваком случају - >> [ученик] Да. [Бовден] Разлика између низа [] и инт * низ, нема. Такође можете добити неке вишедимензионални низ овде за неке погодан синтаксе, али то је још увек само показивач. То значи да сам слободан да уради низ = маллоц (сизеоф (инт)); и сада указује негде другде. Али само ми се како ово ради заувек и увек, мења овај низ тако да што указује на нешто друго не мења овај низ овде јер је копија аргумента, није показивач на тај аргумент. И заправо, баш као и више индикација да се управо то исто - смо већ видели шта штампа низа отиске - шта ако смо одштампали адресу низа или адресу на адресу низа на било које од ових? Хајде да игноришемо ово. Ок. То је у реду. Сада трчи / а.оут.. Штампање низа, а затим штампа адресу низа, иста ствар. Низ једноставно не постоји. Она зна кад штампате низ, да ли штампате симбол који се односи на тих 20 бајтова. Штампање адресу низа, па низ не постоји. Он нема адресу, тако да само исписује адресу тих 20 бајтова. Чим компајлирате доле, као у вашем саставио бугги4 / а.оут., низ је безначајна. Показивачи постоје. Низови не. Блокови меморије представљају низ и даље постоје, али променљива низ и променљиве тог типа не постоје. Они су као главних разлика између низова и показивача се чим да функција позива, нема разлике. Али унутар функције коју је сама низ буде проглашен, сизеоф ради другације пошто сте штампање величину блокова уместо величине типа, а ви не можете да промените, јер је то симбол. Штампање ствар и адресу ствар штампа исту ствар. И то је прилично кошта. [Ученик] Можете ли рећи да још једном? Можда сам нешто пропустио. Штампање низа и адреса низа штампа исту ствар, а ако штампате показивач у односу на адресу показивача, једна ствар штампа адресу шта указује да, друга штампа адресу показивач на стек. Можете променити показивач, ви не можете да промените један симбол низа. А сизеоф показивач ће штампати величину тог показивача типа. Дакле, инт * п сизеоф (п) ће штампати 4, али инт низ [5] штампа сизеоф (арраи) ће штампати 20. [Ученик] Дакле инт низ [5] ће штампати 20? >> Да. Зато унутар бугги4 када је то било сизеоф (арраи) ово сам ја радио <20, што није оно што смо желели. Желимо И <5. >> [Ученик] Ок. [Бовден] И онда чим почнете пролазу у функцијама, ако смо урадили инт * п = арраи; унутар ове функције, ми смо у основи могу користити п и низ у тачно на исти начин, осим сизеоф проблем и промену проблема. Али п [0] = 1; је исто као и рећи низ [0] = 1; И чим кажемо фоо (арраи), или фоо (п); унутар фоо функције, то је два пута исти позив. Не постоји разлика између ова два позива. Свако добро на то? Ок. Имамо 10 минута. Ми ћемо покушати да кроз овај програм Хацкер Типер, овај сајт, који је изашао прошле године или тако нешто. То је само требало да буде као да си случајно откуцате и штампа - Шта год фајл се деси да се учита оно што изгледа као да куцате. Изгледа као нека врста оперативног система кода. То је оно што ми желимо да спроведе. Требало би да имате бинарни екецутабле називом хацкер_типер која узима у једном аргументу, фајл за "хакерске типа." Покретање извршну треба обрисали екран и онда штампају један карактер из прошлих-у фајлу сваки пут када корисник притисне тастер. Дакле, шта год притиснете тастер, треба бацити и уместо одштампати карактер из фајла то је аргумент. Ја ћу прилично ти рећи шта оно да ћемо морати да знамо. Али ми желимо да проверимо термиос библиотеку. Никада нисам користио ову библиотеку у мом животу, тако да има веома минималне сврхе. Али ово ће бити библиотека можемо користити да баците карактер те ударим када куцате на стандард ин Дакле хацкер_типер.ц, и ми ћемо желети да # инцлуде. Гледајући ман страну за термиос - Ја претпостављам да је терминал ОС или тако нешто - Ја не знам како да га прочитам. Гледајући ово, каже да укључе ове 2 датотеке, тако да ћемо то урадити. Прва ствар прво, желимо да у једном аргументу, који је фајл треба да отвори. Па шта желим да урадим? Како да проверите да ли имам један аргумент? [Ученик] Ако је аргц једнакима. >> [Боуден] Да. Дакле, ако (аргц = 2!) Принтф ("Употреба:% с [фајл да отворим]"). Па сад, ако сам покренути ово без пружања други аргумент - Ох, морам нову линију - видећете каже употреба: / хацкер_типер. а онда други аргумент треба да буде датотека Желим да отворим. Шта сад да радим? Желим да прочитам од овог фајла. Како сам прочитао из датотеке? [Ученик] Можете отворити први. >> Да. Тако фопен. Шта фопен изгледа? [Ученик] датотеке. >> [Бовден] датотеке ће бити аргв [1]. [Ученик] И онда шта желите да урадите са њом, тако да - >> [Боуден] Да. Дакле, ако се не сећате, само да урадите фопен човека, где ће бити цхар * патх, где путања фајла, цхар * режим. Ако вам се деси да се не сетим шта је режим, онда можете тражити режим. Унутар ман страницама, Сласх лик је оно што можете да користите за тражење ствари. Тако куцам / режим за претраживање режим. н и Н су оно што можете да користите да бисте се кретали кроз претраге утакмице. Овде пише аргументом режима указује на ниску почињу са једним од следећих секвенци. Дакле р, отворени текст фајл за читање. То је оно што ми желимо да урадимо. За читање, а ја желим да ускладиштите то. Оно ће бити ФИЛЕ *. Сада шта желим да урадим? Дај ми секунд. Ок. Сада шта желим да урадим? [Ученик] Проверите да ли је НУЛЛ. >> [Боуден] Да. Сваки пут када отворите датотеку, проверите да ли сте у стању успешно да га отвори. Сада желим да урадим то термиос ствари где желим да прво прочитате моје тренутне поставке и сачувати оне у нешто, онда желим да променим моја подешавања да баци сваки карактер који сам куцање, и онда желим да ажурирате те поставке. И онда на крају програма, желим да се вратите у своје оригиналне поставке. Дакле струцт ће бити од типа термиос, а ја ћу желети двојицу од оних. Први ће бити моји цуррент_сеттингс, а онда ћемо ми бити хацкер_сеттингс. Прво, ја ћу желети да сачувате своје тренутне поставке, онда ћу желети да ажурирате хацкер_сеттингс, па тако на крају мог програма, желим да се вратите на тренутним поставкама. Дакле, чување тренутне поставке, начин на који функционише, ми човек термиос. Видимо да имамо овај инт тцсетаттр, инт тцгетаттр. Прођем у термиос струцт по својој показивачем. Начин ово ће изгледати је - И'ве већ заборавили шта је функција зове. Копирајте и налепите га. Дакле тцгетаттр, онда желим да прође у струцт да штедим информације у, која ће бити цуррент_сеттингс, а први аргумент је фајл дескриптор за ствар коју желим да сачувате атрибуте. Који фајл дескриптор је је као и сваки пут када отворите датотеку, она добија фајл дескриптор. Када сам фопен аргв [1], добија датотеке дескриптор који сте референце кад год желите да читате или пишете на њега. То није фајл дескриптор желим да овде користите. Постоје три датотека дескриптори имате по дефаулту, који су стандард у, стандардни напоље, и стандардна грешка. По дефаулту, мислим да је то стандард у је 0, стандардни излаз је 1, а стандардна грешка је 2. Па шта ја желим да промените поставке? Желим да променим поставке кад сам ударио карактер, Желим да бацим тај лик далеко уместо да га штампа на екран. Шта поток - стандард, стандардне напоље, или стандардне грешке - реагује на ствари када куцам на тастатури? >> [Ученик] Стандард за >> Да. Тако да могу да урадим или 0 или ја могу да урадим стдин. Идем по цуррент_сеттингс стандардних ин Сада желим да ажурирате те поставке, па прво ћу копирати у хацкер_сеттингс шта моји цуррент_сеттингс су. А како Структуре рад ће само копирате. Овај копира сва поља, као што бисте очекивали. Сада желим да ажурирате неке од области. Гледајући термиос, морали бисте да прочитате кроз много тога само да видим шта би желео да тражи, али заставе идете да желе да траже су ехо, па ЕЦХО Ецхо унос карактера. Прво желим да сет - И'ве већ заборавили шта су поља. То је оно што струцт изгледа. Тако режими уноса мислим желимо да променимо. Ми ћемо погледати решење да се уверите да је оно што желимо да променимо. Желимо да променимо лфлаг у циљу спречавања потребе да гледате кроз све ово. Желимо да променимо локалне режиме. Ви би требало да прочитате целу ову ствар да схвате где све припада које желимо да променимо. Али унутра је локалних режима где идемо да желе да се то промени. Дакле хацкер_сеттингс.цц_лмоде је оно што се зове. ц_лфлаг. Ово је место где смо добили у над битовима оператера. Некако смо ван времена, али ћемо проћи кроз то врло брзо. Ово је место где смо добили у над битовима оператера, где сам да сам рекао једном давно да кад год почнемо да се бавимо са заставама, ћеш користити над битовима оператеру много. Сваки бит у заставу одговара некој врсти понашања. Па ево, ово застава има гомилу разних ствари, где сви они значе нешто друго. Али оно што ја желим да урадите је да само искључите мало која одговара ЕЦХО. Дакле, да бисте да скинем урадим & = ¬ ЕЦХО. Заправо, мислим да је то као Тецхо или тако нешто. Ја ћу само да поново проверим. Ја могу да га термиос. То је само ехо. ЕХО ће бити један бит. ¬ ЕХО ће значити сви битови су постављени на 1, што значи да су сви заставе су постављене на истина осим за ЕЦХО мало. По окончању своје локалне заставе са овим, то значи све заставе које су тренутно постављене на истина ће и даље бити постављен на труе. Ако мој ЕЦХО застава је постављена на тачно, онда је нужно постављен на лаж на ЕЦХО заставом. Дакле, ова линија кода само искључује ЕЦХО заставу. Остале линије кода, ја ћу их копирати у интересу времена, а затим објасните их. У решењу, рекао је 0. Вероватно је боље да експлицитно рећи стдин. Приметите да сам и ја радим ЕЦХО | ицанон овде. Ицанон се односи на нешто одвојено, што значи канонски режим. Шта значи канонским режим је обично када куцате из командне линије, стандард у не обрађује ништа док си ударио знака. Дакле, када се ГетСтринг, куцате гомилу ствари, онда ударио знака. То је када је послао стандарду за То је стандардна. Када искључите канонски режим, сада сваки појединачни карактер када притиснете је оно што се обрађује, што је обично нека врста лоше јер је спор у обради ове ствари, због чега је добро да се бафер у целом линија. Али желим сваки знак да се обради пошто ја не желим да чекам да ме удари знака пре него што се обрађује све карактере сам куцање. Ово искључује канонски режим. Ова ствар само значи када је заправо процеси знакове. То значи да обрадимо их одмах; чим сам их куцате, обрадити их. И ово је функција која се ажурира моје поставке за стандард у, и ТЦСА значи то одмах. Друге опције су сачекати све што је тренутно на потока обрађује. То није битно. Управо сада променити моје подешавања да буде оно што је тренутно у хацкер_типер_сеттингс. Ваљда сам га звао хацкер_сеттингс, па хајде да променимо. Промените све на хацкер_сеттингс. Сада на крају нашег програма ћемо желети да вратите на оно што је тренутно унутар нормал_сеттингс, који ће само да изгледа и нормал_сеттингс. Обавештење Нисам променио ниједан од мојих нормал_сеттингс од првобитно добија. Онда само да их промените назад, ја сам их пролазе назад на крају. Ово је исправка. Ок. Сада унутар овде ћу објаснити код у интересу времена. Није толико код. Видимо читамо карактер из фајла. Звали смо га ф. Сада можете човек фгетц, али како фгетц ће радити је само да ће то вратити знак који сте управо прочитали или ЕОФ, што одговара до краја датотеке или грешке неког дешава. Ми петље, настављајући да чита један карактер из фајла, док смо понестане знакова да чита. И док смо то радили, ми чекамо на једном од стандардних карактера ин Сваки пут када откуцате нешто у командној линији, да чита у карактеру од стандарда за Онда путцхар је само ће ставити знак читамо овде из датотеке на стандардном напоље. Можете човек путцхар, али то је само стављање на стандарду напоље, то је штампа тај лик. Ви такође можете да урадите само принтф ("ц%", ц); исту идеју. То ће урадити највећи део нашег посла. Последња ствар коју ћемо желети да урадите је само фцлосе нашу датотеку. Ако не фцлосе, то је осипање меморије. Желимо да фцлосе фајл смо првобитно отворен, и мислим да је то то. Ако направимо то, ја већ имам проблеме. Хајде да видимо. Шта се то жале? Очекивани 'инт', али аргумент типа 'струцт _ИО_ФИЛЕ *'. Видећемо да ли је ради. Дозвољено само у Ц99. Аугх. Ок, да хацкер_типер. Сада смо добили више корисне описе. Дакле, коришћење непријављеног идентификатора "нормал_сеттингс '. Нисам назвао нормал_сеттингс. Звала сам га цуррент_сеттингс. Дакле, хајде да променимо све то. Сада пролази аргумент. Ја ћу направити овај 0 за сада. Ок. / Хацкер_типер цп.ц.. Такође није јасно екран на почетку. Али можете погледати назад до последњег сета проблем да видим како сте обрисали екран. То је само штампање неке знакове док ово радим оно што желим да радим. Ок. И размишљам о томе зашто је то требало да буде 0, уместо стдин, који би требало да буде # дефине 0, ово се жале да - Пре када сам рекао да постоји фајл дескриптора али онда имате и свој * Филе, фајл дескриптор је само један цео број, док ФИЛЕ * има гомилу ствари у вези са њим. Разлог морамо да кажемо 0 уместо стдин је да је стдин ФИЛЕ * што указује на ствари која је референцирање датотеке дескриптор 0. Дакле, чак и овде када радим фопен (аргв [1], ја се вратим на ФИЛЕ *. Али негде у том филе * је ствар одговара фајл дескриптора за тај фајл. Ако погледате ман страницу за отворен, тако да мислим да ћете морати да урадите ман 3 отворена - Јок - Човек 2 отворена - да. Ако погледате на страници за отворено, отворена је као нижег нивоа фопен, и то се враћа стварне датотеке дескриптор. фопен ради гомилу ствари на врху отвореног, која уместо враћања само тај фајл дескриптор враћа целу датотеку * показивач унутар којег је наш мали фајл дескриптор. Дакле стандард се односи на ствари ФИЛЕ *, док 0 односи само на стандард фајл дескриптор у себи. Питања? [Смех] Блев кроз то. У реду. Завршили смо. [Смех] [ЦС50.ТВ]