[Powered by Google Translate] [Раздзел 5: менш камфортна]
[Nate Хардисон, Гарвардскі універсітэт]
[Гэта CS50.] [CS50.TV]
Так што сардэчна запрашаем, хлопцы.
Сардэчна запрашаем у профіль 5.
На дадзены момант, скончыўшы тэст 0 і убачыўшы, як вы зрабілі,
спадзяюся, вы адчуваеце сябе сапраўды добра, таму што я быў вельмі ўражаны балы ў гэтай частцы.
Для нашых гледачоў онлайн, у нас было некалькі пытанняў
Пра двух апошніх праблем на праблемы набору - або на тэст, а.
Так што мы збіраемся перайсці на тых, хто сапраўды хутка, так што кожны бачыць тое, што адбылося
і як ісці праз само рашэнне, а не проста прагляд самога рашэння.
Мы збіраемся пайсці за апошнія некалькі праблем вельмі хутка, 32 і 33.
Толькі, зноў жа, так што анлайн-гледачы могуць убачыць гэта.
>> Калі вы звернецеся да вашай праблеме 32, якая знаходзіцца на старонцы 13,
13 з 16, 32, праблема ўсё пра своп.
Гэта ўсё аб абмене двух цэлых лікаў.
Гэта праблема, што мы перайшлі пару разоў у лекцыі.
І тут, што мы просім вас зрабіць, гэта хутка следу памяці.
Для запаўнення значэнняў зменных, так як яны знаходзяцца на стэку
як код праходзіць праз гэтую функцыю падпампоўкі.
У прыватнасці, тое, што мы шукаем - я збіраюся паставіць гэтую Ipad ўніз -
У прыватнасці, тое, што мы глядзім на гэты радок з нумарам 6 прама тут.
І гэта нумарам 6, толькі судотык з папярэдняй задачы.
Тое, што мы хочам зрабіць, гэта паказаць або абазначэння стану памяці
як гэта ў той час, калі мы выконваем гэтую лінію № 6,
які фактычна з'яўляецца вяртанне з нашых своп функцыі прама тут.
Калі мы пракруціць ўніз тут, мы ўбачылі, што ўсе адрасы ў памяці была прадастаўлена для нас.
Гэта вельмі ключа; мы вернемся да гэтага праз хвіліну.
А потым тут на дне, у нас было трохі схема памяці, якія мы збіраемся спасылацца.
На самай справе я зрабіў гэта на маім iPad.
Так што я буду чаргаваць назад і наперад паміж IPad і гэты код проста для даведкі.
>> Давайце пачнем. Па-першае, давайце засяродзімся на першых двух лініях асноўны прама тут.
Для пачатку, мы збіраемся, каб ініцыялізаваць х 1 і ў 2.
Такім чынам, мы маем два цэлалікавых зменных, яны абодва будуць змешчаныя ў стэк.
Мы збіраемся паставіць 1 і 2 у іх.
Так што калі я перавярнуцца на мой IPad, спадзяюся, давайце паглядзім, -
Apple TV люстраное адлюстраванне, і мы ідзем. Добра.
Так што калі я перавярнуцца на мой IPad,
Я хачу, каб ініцыялізаваць х 1 і ў 2.
Мы робім гэта даволі проста, напісаўшы 1 у скрынку з надпісам х
і 2 у графе у. Даволі проста.
Такім чынам, цяпер давайце вернемся да ноўтбука, паглядзім, што будзе далей.
Так што наступная радок, дзе ўсё становіцца складаней.
Мы перадаем адрас х і адрас у як параметры А і Ва ў своп функцыі.
Адрас х і адрас у рэчы, якія мы не можам вылічыць
без спасылкі на гэтыя кулі паказвае прама тут.
І, на шчасце, першыя два пункты кажуць нам менавіта тое, што адказы на іх.
Адрас х у памяці 10, і адрас у ў памяці 14.
Так што тыя каштоўнасці, якія атрымліваюць перадаецца ў якасці і б наверсе ў нашай своп функцыі.
Такім чынам, зноў перайсці назад на нашу схему, я магу напісаць 10 у
і 14 у б.
Цяпер гэты пункт, дзе мы працягваем падпампоўкі.
Такім чынам, гартаць назад у ноўтбук зноў,
мы бачым, што шлях падпампоўкі працуе, я спачатку разыменовать і захаваць вынік у TMP.
Такім чынам, аператар разнаймення кажа: "Прывітанне. Лячыць змесціва зменнай у якасці адрасу.
Перайсці да таго, што захоўваецца па гэтым адрасе, і загрузіць яго. "
Што вы загружаеце з зменнай будуць захоўвацца ў нашай TMP зменная.
Падаваць назад у iPad.
Калі мы пойдзем па рашэнні 10, мы ведаем, што адрас 10 з'яўляецца varible х
таму што нам сказалі, што нашы кулі, што адрас х у памяць 10.
Так што мы можам пайсці туды, атрымаць значэнне яго, што 1, як мы бачым на нашых Ipad,
і загрузіць у TMP.
Зноў жа, гэта не канчатковы змест.
Мы збіраемся прайсці і мы вернемся да нашых канчатковым станам праграмы ў канцы.
Але цяпер у нас ёсць значэнне 1 захоўваецца ў TMP.
>> І ёсць хуткі пытанне тут.
[Аляксандр] З'яўляецца аператарам разнаймення - гэта толькі зоркі прама перад зменнай?
>> Так. Такім чынам, аператар разнаймення, як мы перавярнуць назад у наш наўтбук яшчэ раз,
гэтая зорка прама перад.
У гэтым сэнсе, гэта - вы параўнаць яе з аператарам множання
якая патрабуе двух рэчаў; разыменовать аператар унарный аператар.
Толькі ў дачыненні да аднаго значэнні, а не бінарны аператар,
дзе вы падаеце заяўку на два розных значэння.
Так што тое, што адбываецца ў гэтай лініі.
Мы пагрузілі значэння 1 і захоўваць яго ў наш часовы цэлай зменнай.
У наступным радку, мы захоўваем змесціва б у -
ці, хутчэй, мы захоўваем змесціва, бы паказвае на ў месца, дзе паказвае.
Калі мы прааналізуем гэтую справа налева, мы будзем разнаймення б,
Мы маем намер звярнуцца 14, мы збіраемся захватить цэлы лік, якое ёсць,
а потым мы збіраемся перайсці па адрасе 10,
і мы збіраемся кінуць вынік нашай разнаймення б у гэта прастора.
Падаваць да нашай Ipad, дзе мы можам зрабіць гэта крыху больш канкрэтным,
гэта можа дапамагчы, калі я напішу нумары на ўсе адрасы тут.
Такім чынам, мы ведаем, што пры ў, мы знаходзімся ў адрас 14, х знаходзіцца па адрасе 10.
Калі мы пачынаем на б, мы разнаймення б, мы збіраемся, каб захапіць значэнне 2.
Мы збіраемся захватить гэта значэнне, таму што гэта каштоўнасць, якая жыве па адрасе 14.
І мы збіраемся змясціць яго ў пераменны, які жыве па адрасе 10,
які тут жа, якая адпавядае нашай зменнай х.
Так што мы можам зрабіць трохі перазапісу тут
дзе мы пазбавімся ад 1 і замест гэтага напісаць 2.
Так што ўсё добра, і добрае ў свеце, хоць мы перазапісаны х цяпер.
Мы захавалі старое значэнне х у нашай TMP зменная.
Такім чынам, мы можам завяршыць своп з новага радка.
Падаваць да нашага ноўтбука.
Цяпер усё, што застаецца ўзяць змесціва з нашага часовага цэлай зменнай
і захоўваць іх у зменную, якая жыве па адрасе, што б трымае.
Так што мы збіраемся эфектыўна разнаймення б атрымаць доступ да зменнай
гэта значыць па адрасе, што б праводзіць у ім,
і мы збіраемся, каб напоўніць значэннем, TMP трымаецца ў ёй.
Падаваць назад у IPad яшчэ раз.
Я магу сцерці гэта значэнне тут, 2,
, А замест гэтага мы будзем капіяваць на 1 прама ў яго.
Тады наступная радок, якая выконвае, вядома, -
калі перавярнуць назад у ноўтбук - гэта пункт 6,
, Якая з'яўляецца кропкай, у якой мы хацелі, каб наш схема цалкам запоўненыя.
Такім чынам, гартаць назад у IPad яшчэ раз, толькі так можна ўбачыць скончаную схему,
Вы можаце бачыць, што ў нас 10 у, 14-У, 1 у TMP, 2-х і 1 у у.
Ёсць пытанні па гэтай нагоды?
Ці мае гэта сэнс, прайшоўшы праз гэта?
Зрабіць менш сэнсу? Спадзяюся, што не. Добра.
>> Паказальнікі з'яўляюцца вельмі складаны прадмет.
Адзін з хлопцаў, з якімі мы працуем мае вельмі распаўсюджаная прымаўка:
"Каб зразумець, паказальнікі, вы павінны спачатку зразумець паказальнікаў".
Які я думаю, што гэта вельмі дакладна. Гэта зойме некаторы час, каб прывыкнуць да яго.
Лёсаванне фатаграфій, малявання вялікім аб'ёмам памяці дыяграм, як гэты вельмі карысны,
і пасля таго, як вы ідзяце праз, напрыклад, пасля прыклад за прыкладам,
ён пачне рабіць трохі больш сэнсу і крыху больш сэнсу і крыху больш сэнсу.
Нарэшце, у адзін цудоўны дзень, вы будзеце мець усё гэта цалкам асвоены.
Любыя пытанні, перш чым мы пяройдзем да наступнай праблеме? Добра.
Так перавярнуць назад у ноўтбук.
Наступная праблема, у нас гэта праблема нумар 33 на файл I / O.
Павялічыць на гэта няшмат.
Задача 33 - Да?
>> [Данііл] Я толькі што быў хуткі пытанне. Гэтая зорка, або зорачкі,
гэта называецца разнаймення пры выкарыстанні зорачкі раней.
Як гэта называецца, калі вы выкарыстоўваеце амперсанда раней?
>> Амперсанда, перш чым гэта адрас-аператара.
Так што давайце пракруціць назад.
Ой. Я ў рэжым маштабавання, таму я не магу сапраўды прагорткі.
Калі мы паглядзім на гэты код вельмі хутка, прама тут,
зноў, тое ж самае адбываецца.
Калі мы паглядзім на гэты код прама тут, на гэтай лініі, дзе мы зрабіць званок, каб памяняць,
амперсанда проста кажу "атрымаць адрас, па якім пераменная х жыцця".
Калі ваш кампілятар кампілюе код,
яна мае на самой справе фізічна вылучыць месца ў памяці для ўсіх вашых зменных, каб жыць.
І тое, што кампілятар можа зрабіць, як толькі вы сабралі ўсе,
ён ведае: "О, я паклаў х у адрас 10. Я паклаў у ў адрас 14".
Ён можа запоўніць гэтыя значэння для вас.
Такім чынам, вы можаце - ён можа затым перадаць гэта ў праходзе і і ў ў а.
Гэтыя хлопцы атрымаць адрас, але яны таксама, калі вы перадаеце іх у своп функцыі,
гэты тып інфармацыі, гэты Int * прама тут, кажа кампілятару,
"Добра, мы збіраемся інтэрпрэтацыі гэты адрас у якасці адрасы цэлай зменнай".
У адрас INT, які адрозніваецца ад адраса знакавай зменнай
таму што Int займае, на 32-бітнай машыне, займае 4 байта прасторы,
у той час як характар ​​толькі займае 1 байт.
Таму вельмі важна ведаць і тое, што ёсць - тое, што жыве, які тып значэння
жыве па адрасе, які атрымаў прайшло цалі
Ці адрас, які вы маеце справу.
Такім чынам, вы ведаеце, колькі байтаў інфармацыі на самай справе загрузіць з аператыўнай памяці.
І потым, так, гэта аператар разнаймення, як вы прасілі,
ідзе і доступ да інфармацыі па вызначаным адрасе.
Так ён кажа, з гэтай зменнай тут, ставяцца змест, адрас,
пайсці на гэты адрас, і выцягнуць, загрузіць у працэсар, нагрузка ў рэгістр
Фактычныя значэння або зместу, якія жывуць па гэтым адрасе.
Ёсць яшчэ пытанні? Гэта добрыя пытанні.
Гэта шмат новай тэрміналогіі таксама.
Гэта таксама выгляд фанк, бачачы & * і ў розных месцах.
>> Добра.
Такім чынам, вернемся да задачы 33, файлавы ўвод / выснова
Гэта была адна з тых праблем, якія я думаю, што пару рэчаў адбылося.
Адзін з іх, гэта даволі новая тэма.
Ён быў прадстаўлены даволі хутка перад віктарыны,
і тады я думаю, гэта было нешта накшталт адной з тых тэкставых задач па матэматыцы
дзе яны даюць вам шмат інфармацыі, але вы на самой справе не да канца таго, каб выкарыстоўваць тоны гэтага.
У першай частцы гэтай праблеме апісання таго, што файл CSV ёсць.
Цяпер, файлаў CSV, у адпаведнасці з апісаннем, з'яўляецца значэнняў, падзеленых коскамі файл.
Прычына гэта наогул цікава, і па гэтай прычыне вы ніколі не выкарыстоўваеце іх,
гэта, таму што, як многія з вас калі-небудзь выкарыстоўвалі такія рэчы, як Excel?
Малюнак большасць з вас, напэўна, або будзе выкарыстоўваць у нейкі момант у вашай жыцця.
Вы будзеце выкарыстоўваць нешта накшталт Excel.
Для таго, каб атрымаць дадзеныя з табліцы Excel або зрабіць які-небудзь апрацоўцы з ім,
калі б вы хацелі, каб напісаць праграму C ці Python праграмы, Java праграмы,
мець справу з дадзенымі, якія захоўваюцца там,
адным з найбольш распаўсюджаных спосабаў атрымаць яго ў файл CSV.
І вы можаце адкрыць Excel і калі вы ідзяце ў "Захаваць як" дыялог,
Вы можаце выйсці з бягучага файла CSV.
>> Handy ведаць, як мець справу з гэтымі рэчамі.
Як гэта працуе ў тым, што гэта падобна на - я маю на ўвазе, яна, па сутнасці, імітуючы табліцу,
дзе, як мы бачым тут, у самым левым кавалак,
у нас ёсць усе прозвішчы.
Такім чынам, мы маем малая, то Хардисон, а затым Боуден, MacWilliam, а затым Чан.
Усе прозвішчы. І тады коска аддзяляе прозвішчаў з першых імёнаў.
Давід, Nate, Роб, Томі і Zamyla.
Я заўсёды змешваць Робі і Тома.
І вось, нарэшце, трэці слупок адрасы электроннай пошты.
Як толькі вы зразумееце, што астатняя частка праграмы даволі просты ў рэалізацыі.
Што мы зрабілі для таго, каб імітаваць гэтую ж структуру ў нашай праграме C
гэта мы выкарыстоўвалі структуру.
Мы пачнем гуляць з гэтым крыху больш, а таксама.
Мы бачылі іх у першы трохі ў праблеме набор 3, калі мы маем справу са слоўнікамі.
Але гэта супрацоўнікі структура захоўвае прозвішча, імя і электронную пошту.
Гэтак жа, як наш файл CSV быў захоўвання.
Так што гэта проста канвертавання з аднаго фармату ў іншы.
Мы павінны пераўтварыць, у гэтым выпадку, супрацоўнікі структур у лінію,
падзеленых коскамі лініі, як і што.
Ці мае гэта сэнс? Вы, хлопцы, усе прынятыя віктарыны,
так што я мяркую, вы па крайняй меры, было некаторы час, каб падумаць аб гэтым.
>> У пракат функцыі, задачы патрабуе ад нас, каб узяць у - МЫ павялічыць на гэтым крыху -
прыняць у штатную структуру, персанал структуры, з імем S,
і дадаць яго змесціва нашага файла staff.csv.
Аказваецца, што гэта даволі просты ў выкарыстанні.
Мы відаў пагуляць з гэтымі функцыямі трохі больш сёння.
Але ў дадзеным выпадку, Fprintf функцыя сапраўды з'яўляецца ключавой.
Так што з Fprintf, мы можам надрукаваць, як і вы, хлопцы, ужо выкарыстоўваюць Printf ўвесь гэты тэрмін.
Вы можаце Printf радок у файл.
Такім чынам, замест таго, каб проста зрабіць звычайную Printf выклік, дзе вы даеце яму радок фармату
, А затым замяніць усе зменныя з наступнымі аргументамі,
з Fprintf, ваш першы аргумент, замест файла, які вы жадаеце запісаць.
Калі мы паглядзім на гэта ў прыбор, напрыклад, чалавек Fprintf,
мы можам убачыць розніцу паміж Printf і Fprintf.
Я павялічыць тут няшмат.
Так што з Printf, мы даем яму радок фармату, а затым наступныя развагі
Тут усё зменныя для замены або падстаноўкі ў нашым фармаце радка.
У той час як з Fprintf, першы аргумент на самай справе гэты файл * завецца струменем.
>> Вяртаючыся сюды, каб наш пракат,
Мы ўжо атрымалі наш файл * струмень адкрыты для нас.
Гэта тое, што гэта першая лінія робіць, ён адкрывае файл staff.csv,
яно адкрываецца ў рэжыме дадання, і ўсё, што засталося для нас зрабіць, гэта
напісаць штатнай структуры ў файл.
І, давайце паглядзім, я хачу выкарыстоўваць IPad?
Я буду выкарыстоўваць iPad. У нас ёсць пустэча - Давайце паставім гэта на стол, каб я мог напісаць трохі лепш -
ануляваць арэнду і бярэ ў адзін аргумент, штатная структура называецца с.
Ёсць нашы дужкі, мы атрымалі наш файл * завецца файл,
у нас ёсць Еореп лініі нам дадзена,
а я проста пішу гэта як кропкі, так як гэта ўжо ў Pedia.
І тады на нашай наступным радку, мы збіраемся зрабіць званок у Fprintf
і мы збіраемся прайсці ў файл, які мы хочам друкаваць,
і тады наша радок фармату, які -
Я паведамлю вам, хлопцы скажыце мне, што ён выглядае.
Як наконт вас, Стэла? Вы ведаеце, што першая частка радка фармату выглядае?
[Stella] Я не ўпэўнены. >> Не саромейцеся задаваць Джымі.
Ці ведаеце вы, Джымі?
[Джымі] Ці будзе гэта проста быць у апошні раз? Я не ведаю. Я не зусім упэўнены.
>> Добра. Як наконт таго, хто-небудзь атрымаць правільнае на экзамене?
Не, усё ў парадку.
Аказваецца, што тут усё, што мы павінны зрабіць, гэта мы хочам, каб кожная частка нашай штатнай структуры
быць раздрукаваныя ў выглядзе радка ў нашым файле.
Мы проста выкарыстоўваць радок знакаў замены трох розных раз, таму што ў нас ёсць прозвішчы
з наступнай коскі, то імя варта коска,
і, нарэшце, адрас электроннай пошты, які варта - што не
ўстаноўкі на экране - але за ім варта сімвал новага радка.
Так што я збіраюся пісаць толькі там.
А потым пасля нашага фармату радкі,
мы проста павінны замены, якія мы атрымліваем доступ дапамогай кропкавай натацыі
што мы бачылі ў праблеме набору 3.
Мы можам выкарыстоўваць s.last, s.first, і s.email
замяніць у гэтых трох каштоўнасцяў у нашым фармаце радка.
Так як усё прайшло? Сэнс?
Да? Няма? Магчыма? Добра.
>> Апошняя рэч, што мы робім, пасля таго як мы друкаваных і пасля таго як мы адкрылі наш файл:
кожны раз, калі мы адкрылі файл, мы заўсёды павінны памятаць, каб закрыць яго.
Таму што інакш мы ў канчатковым выніку ўцечка памяці,
з выкарыстаннем да файлавых дэскрыптараў.
Такім чынам, каб закрыць яго, якія функцыі мы выкарыстоўваем? Дэніэл?
[Данііл] Fclose? >> Fclose, дакладна.
Такім чынам, апошняя частка гэтай праблемы было правільна зачыніць файл, выкарыстоўваючы Fclose функцыі,
які выглядае так.
Ці не занадта вар'ятам.
Cool.
Так што гэта праблема 33 на віктарыну.
Мы павінны, безумоўна, больш файлавага ўводу / вываду ідуць уверх.
Мы зробім трохі больш у сённяшняй лекцыі, або ў раздзеле сёння,
таму што гэта тое, што збіраецца складаюць асноўную частку гэтай маючай адбыцца PSET.
Давайце пяройдзем ад віктарыну ў гэтай кропцы. Да?
>> [Charlotte]] Чаму Fclose (файл), а Fclose (staff.csv)?
>> Аг. Таму што атрымліваецца, што - так што пытанне, які з'яўляецца вялікім,
Вось чаму, калі мы пішам Fclose, мы пісьмова Fclose (файла) зменнай зоркі
у адрозненне ад імёнаў файлаў, staff.csv? Хіба гэта правільна? Так.
Такім чынам, давайце паглядзім. Калі б я вярнуцца да маіх ноўтбукам,
і давайце паглядзім на Fclose функцыі.
Так Fclose функцыя закрывае паток, і ён прымае ў паказальнік на паток, што мы хочам закрыць,
у адрозненне ад фактычнага імя файла, які мы хочам закрыць.
І гэта таму, што за кулісамі, калі вы робіце выклік Еореп,
калі вы адкрываеце файл, вы на самой справе вылучэнне памяці для захоўвання інфармацыі аб файле.
Такім чынам, у вас ёсць файл паказальнік, які змяшчае інфармацыю аб файле,
такіх, як ён адкрыты, яго памер, дзе вы знаходзіцеся ў дадзены момант файла,
так што вы можаце зрабіць чытанне і запіс выклікаў, што асаблівае месца ў файле.
Вы ў канчатковым выніку закрыццё паказальніка замест закрыцця файла.
>> Да? [Данііл] Такім чынам, для таго, каб выкарыстоўваць пракат, вы скажаце, - як гэта атрымаць дадзеныя, уведзеныя карыстачом?
Хіба Fprintf дзейнічаць як GetString у тым сэнсе, што гэта будзе проста чакаць ўводу карыстальніка
і просім вас ўвесці гэты - ці чакаць, пакуль вы ўводзіце гэтыя тры рэчы?
Ці вам трэба выкарыстоўваць нешта для ажыццяўлення арэнды?
>> Так. Так што мы не - пытанне быў, як мы можам атрымаць дадзеныя, уведзеныя карыстачом
У мэтах рэалізацыі арэнду? І тое, што мы маем тут справу з выклікалым пракату,
Прайшло ў гэтым штаце структура з усімі дадзенымі, якія захоўваюцца ў структуры ўжо.
Так Fprintf можа проста напісаць, што дадзеныя непасрэдна ў файле.
Там няма чаканні ўводу карыстальніка.
Карыстальнік ужо даў ўваходны належным чынам паставіўшы яго ў гэтым штаце структуры.
І ўсё, вядома, было б зламацца, калі любы з гэтых паказальнікаў былі нулявыя,
такім чынам, мы пракруціць таму тут, і мы глядзім на нашу структуру.
У нас ёсць апошняя радок, радок па-першае, радкі электроннай пошце.
Мы цяпер ведаем, што ўсе гэтыя на самай справе, пад капотам, гэта сімвал зменных *.
Гэта можа ці не можа быць накіраваны да нуля.
Яны могуць быць накіраваны на памяць у кучы,
Можа быць, памяць на стэку.
Мы сапраўды не ведаем, але калі любы з гэтых паказальнікаў роўныя нулю, або несапраўдным,
, Што абавязкова аварыі нашым пракаце функцыі.
Гэта было нешта, што было збольшага выходзіць за рамкі іспыту.
Мы не турбавацца пра гэта.
Вялікі. Добра. Такім чынам, пераходзячы ад віктарыны.
>> Давайце закрыем гэты хлопец, і мы будзем глядзець на PSET 4.
Так што, калі вы, хлопцы, паглядзіце на спецыфікацыі PSET, як толькі вы можаце атрымаць да яго доступ, cs50.net/quizzes,
Мы збіраемся прайсці праз некалькі падзелу сённяшнія праблемы.
Я пракрутка ўніз - раздзел пытанняў пачынаецца на трэцяй старонцы PSET спец.
І першая частка просіць вас пайсці і паглядзець кароткі на перанакіраванне і труб.
Які быў збольшага халаднавата Карацей кажучы, паказвае некаторыя новыя, прахалодна каманднага радка трукаў, якія вы можаце выкарыстоўваць.
І тады ў нас ёсць некалькі пытанняў да вас.
Гэта першы пытанне аб плынях, у якіх Printf піша па змаўчанні,
мы часткова закранулі толькі трохі хвіліну таму.
Гэта Fprintf, што мы толькі што абмяркоўвалі займае ў паток файла * у якасці аргументу.
Fclose займае ў паток файла *, а таксама,
і вяртаецца значэння Еореп дае вам файл патоку *, а таксама.
Таму мы не бачылі тых, хто раней, калі мы мелі справу з Printf
Таму Printf па змаўчанні мае струмені.
І па змаўчанні паток, у які ён запісвае
Вы даведаецеся пра ў кароткатэрміновай.
Такім чынам, безумоўна, зірнем на гэта.
>> У раздзеле Сёння, мы збіраемся пагаварыць трохі аб тым, GDB,
бо чым больш вы знаёмыя з ёй, тым больш практыкі вы атрымліваеце разам з ім,
лепш вы будзеце на самай справе высачыць памылкі ва ўласным кодзе.
Гэта паскарае працэс адладкі да надзвычай.
Такім чынам, з дапамогай Printf, кожны раз, калі вы робіце, што вам давядзецца перакампіляваць ваш код,
Вы павінны запусціць яго зноў, часам вы павінны рухацца Printf выклік усяму,
закаментаваць код, ён проста займае некаторы час.
Наша мэта, каб паспрабаваць пераканаць вас, што з GDB, вы можаце істотна
Printf нічога ў любой кропцы вашага кода і вам ніколі не прыйдзецца перакампіляваць.
Вы ніколі не павінны пачынацца і гадаць, дзе Printf наступным.
Першае, што трэба зрабіць, гэта скапіяваць гэты радок і атрымаць код секцыі ад сценкі.
Я капіяванні гэты радок кода, якая кажа: "Wget http://cdn.cs50.net".
Я хачу, каб скапіяваць яго.
Я збіраюся перайсці на мой прыбор, маштаб такім чынам, вы можаце бачыць, што я раблю,
уставіўшы туды, і калі я ударыў Enter, гэтая каманда літаральна Wget з'яўляецца вэб атрымаеце.
Гэта збіраецца знесці гэты файл з сеткі Інтэрнэт,
і ён збіраецца захаваць яго ў бягучым каталогу.
Цяпер, калі я пералічваю маім бягучым каталогу вы можаце ўбачыць, што я атрымаў гэтую section5.zip файл прама там.
Каб справіцца з гэтым хлопцам, каб распакаваць яго,
Гэта можна зрабіць у камандным радку, як гэта.
Section5.zip.
Гэта будзе распакаваць яго, стварыце тэчку для мяне,
раздзімаць ўсё змесціва, пакласці іх туды.
Так што цяпер я магу пайсці ў мой профіль 5 каталогу з дапамогай кампакт-дыска каманды.
Ачысціць экран з дапамогай ясна. Такім чынам ачысціць экран.
Цяпер у мяне ёсць добры чысты тэрмінал справа.
>> Цяпер, калі я спіс усіх файлаў, якія я бачу ў гэтым каталогу,
Вы бачыце, што ў мяне ёсць чатыры файла: buggy1, buggy2, buggy3, і buggy4.
Я таксама атрымаў адпаведныя. З файламі.
Мы не збіраемся глядзець на. Файлы з на дадзены момант.
Замест гэтага, мы збіраемся выкарыстаць іх, калі мы адкрываем GDB.
Мы трымалі іх вакол так, што мы маем доступ да зыходнага кода, калі мы выкарыстоўваем GDB,
але мэта гэтай частцы падзелу важдацца вакол з GDB
і паглядзець, як мы можам выкарыстоўваць яго, каб высветліць, што адбываецца не так з кожнай з гэтых чатырох праграм багі.
Такім чынам, мы толькі збіраемся ў пакоі вельмі хутка,
і я збіраюся папрасіць каго-небудзь запусціць адну з праграм багі,
а потым мы пойдзем у групу праз GDB, і мы ўбачым, што мы можам зрабіць, каб выправіць гэтыя праграмы,
або, па крайняй меры вызначыць, што адбываецца не так у кожным з іх.
Давайце пачнем тут з Даніэлем. Ці будзеце вы балатавацца buggy1? Давайце паглядзім, што адбываецца.
[Данііл] Ён кажа, што ёсць прыкладанне віна. >> Так. Менавіта так.
Так што, калі я бягу buggy1, я атрымліваю сегменце віна.
На дадзены момант, я магу пайсці і адкрыць buggy1.c,
паспрабаваць высветліць, што адбываецца не так,
але адна з самых непрыемных рэчаў аб гэтай памылцы сегменце віна
тым, што ён не скажа вам пра тое, што радок праграмы рэчы на ​​самай справе пайшло не так і зламаўся.
Вы, здаецца, павінны глядзець на код
і высветліць, выкарыстанне здагадка і праверыць ці Printf каб убачыць, што адбываецца не так.
Адна з лепшых рэчаў пра GDB з'яўляецца тое, што гэта вельмі, вельмі лёгка
каб высветліць лінія, на якой збою праграмы.
Гэта цалкам варта таго, каб яго выкарыстоўваць, нават калі толькі для гэтага.
Такім чынам, для загрузкі GDB, я тыпу GDB, а затым я даю яму шлях да выкананага файла, што я хачу працаваць.
Тут я друкую GDB ./buggy1.
Націсніце Enter. Дае мне ўсё гэта інфармацыя аб аўтарскіх правах,
і тут вы ўбачыце гэты радок, якая кажа: "Чытанне знакаў з / Галоўная /
jharvard/section5/buggy1 ".
І калі ўсё пойдзе добра, вы ўбачыце, што выведзіце паведамленне, якое выглядае наступным чынам.
Ён будзе чытаць знакі, ён скажа: "Я чытаю знакі з выкананага файла"
, А затым яна будзе мець гэта "зроблена" паведамленне тут.
Калі вы бачыце некаторыя іншыя варыяцыі гэтага, ці вы бачыце яго не маглі знайсці сімвалы
ці нешта накшталт таго, што гэта азначае, што вы проста яшчэ не складзены выкананы файл належным чынам.
Пры кампіляцыі праграмы для працы з GDB, мы павінны выкарыстоўваць гэтую адмысловую г-сцяг,
і што робіцца па змаўчанні, калі вы компилируете вашы праграмы, проста набраўшы зрабіць
або робяць памылкі або робяць аднавіць, любы з іх.
Але калі вы збіраеце ўручную з дапамогай Clang, то вам прыйдзецца пайсці і ўключаць, што г-сцяг.
>> На дадзены момант, зараз у нас ёсць GDB радку
гэта даволі проста запусціць праграму.
Мы можам альбо ўвесці перспектыве, ці мы можам проста Type-R.
Большасць каманд GDB можа быць скарочана.
Звычайна толькі адзін ці пару літар, які з'яўляецца даволі добрым.
Так Саад, калі вы Type R і націсніце Enter, што адбываецца?
[Саад] Я атрымаў SIGSEGV, памылкі сегментацыі, а затым усё гэта абракадабра.
>> Так.
Як мы бачым на экране прама зараз, і, як Саад сказаў:
калі мы ўводзім прабегу або R і націсніце Enter, мы да гэтага часу атрымаць той жа сегмент віна.
Такім чынам, выкарыстанне GDB не вырашае нашы праблемы.
Але гэта дае нам некаторы абракадабру, і аказваецца, што гэта абракадабра
на самай справе кажа нам, дзе гэта адбываецца.
Для разбору гэтага трохі, гэта першы біт з'яўляецца функцыяй, у якой усё адбываецца не так.
Там гэтая __ strcmp_sse4_2, і ён кажа нам, што адбываецца ў гэтым файле
называецца sysdeps/i386, усё гэта, зноў жа, выгляд беспарадак - але лінія 254.
Гэта свайго роду цяжка разабраць. Звычайна, калі вы бачыце такія рэчы, як гэта,
, Што азначае, што яна сегментах разломаў ў адной з сістэмных бібліятэк.
Так што нешта рабіць з STRCMP. Вы, хлопцы, бачылі STRCMP раней.
Ці не занадта вар'ятам, але гэта значыць, што STRCMP зламаны або што ёсць праблема з STRCMP?
Як вы думаеце, Аляксандр?
[Аляксандр] Гэта што - складае 254 ліній? І - не двайковы, але гэта не іх столі,
а там іншую мову для кожнай функцыі. Хіба што 254 у гэтай функцыі, або -?
>> Гэта лінія 254. Падобна на тое, што ў гэтым няма. Файл з, так што гэта, верагодна, зборка код.
>> Але, я думаю, больш надзённыя рэчы ёсць, таму што мы атрымалі сегменце віна,
і, падобна, гэта ідзе ад STRCMP функцыі,
гэта мае на ўвазе, то, што STRCMP не працуе?
Гэта не павінна, мы спадзяемся. Такім чынам, толькі таму, што ў вас ёсць памылкі сегментацыі
У адной з функцый сістэмы, як правіла, гэта азначае, што вы проста не называць яго правільна.
Самы хуткі, што трэба зрабіць, каб высветліць, што адбываецца на самай справе
калі вы бачыце нешта вар'ят, як гэта, калі вы бачыце сегмент віна,
Асабліва, калі ў вас ёсць праграма, якая выкарыстоўвае большае, чым проста асноўны,
гэта выкарыстоўваць трасіроўку.
Я скарачаць след у пісьмовай форме BT, у адрозненне ад поўнага словы трасіроўку.
Але Шарлота, што адбываецца, калі вы набіраеце BT і націсніце Enter?
[Charlotte] Ён паказвае мне два радкі, 0 лініяй і лініяй 1.
>> Так. Такім чынам, лінія 0 і лініі 1.
Гэтыя фактычныя кадры стэка, што ў цяперашні час у гульні, калі ваша праграма разбіўся.
Пачынаючы з верхняга кадра, кадр 0 і, падышоўшы да самай ніжняй, якая з'яўляецца кадр 1.
Наша верхняя рама STRCMP кадра.
Вы можаце думаць пра гэта як жа, праблема, якую мы рабілі толькі на віктарыну з паказальнікамі,
дзе мы памяняць стэк па-над асноўнага кадра стэка,
і ў нас былі зменныя, якія падпампоўкі выкарыстоўвае ў верхняй частцы зменных, асноўным выкарыстоўваю.
Тут наша аварыі адбыліся ў нашай STRCMP функцыя, якая атрымала назву нашай асноўнай функцыі,
і трасіроўка дае нам не толькі функцыі, у якім рэчы не ўдалося,
але гэта таксама кажа нам, дзе ўсе былі выкліканы.
Так што калі я вылучыце на трохі больш правай,
мы бачым, што так, мы былі на лініі 254 гэтага STRCMP-sse4.s файл.
Але званок быў зроблены на buggy1.c, радок 6.
Такім чынам, гэта азначае, што мы можам зрабіць, - гэта мы можам проста пайсці праверыць і паглядзець, што адбываецца на
у buggy1.c, радок 6.
Зноў жа, ёсць некалькі спосабаў зрабіць гэта. Адзін з іх, каб выйсці з GDB
ці ваш код адкрыты ў іншым акне і крыжаваныя спасылкі.
Гэта, само па сабе, гэта вельмі зручна, таму што цяпер, калі вы знаходзіцеся ў офісе гадзін
і ў вас ёсць сегменты віна і ваша TF гэта цікава, дзе ўсё было ламаць,
Вы можаце проста сказаць: "О, радок 6. Я не ведаю, што адбываецца,
але нешта ў радку 6 з'яўляецца прычынай маёй праграмы зламаць ".
Іншы спосаб зрабіць гэта, вы можаце выкарыстоўваць гэтую каманду называлі спіс у GDB.
Вы таксама можаце скарачаць яго з л.
Такім чынам, калі мы трапілі л, што мы сюды трапілі?
Мы атрымліваем цэлую кучу дзіўных рэчаў.
Гэта фактычны код зборкі
, Які знаходзіцца ў strcmp_sse4_2.
Гэта выглядае роду фанкі,
і прычына, мы атрымліваем гэта таму, што цяпер,
GDB мае нас у кадры 0.
>> Так што ў любы час мы глядзім на зменныя, у любы час паглядзець на зыходны код,
мы глядзім на зыходны код, які адносіцца да кадра стэка мы ў цяперашні час цалі
Так што для таго, каб атрымаць нешта істотнае, мы павінны
перайсці ў стэку, што мае больш сэнсу.
У гэтым выпадку, асноўны фрэйм ​​стэка б зрабіць трохі больш сэнсу,
таму што гэта было на самай справе код, які мы напісалі.
Ня STRCMP код.
Тое, як вы можаце перамяшчацца паміж кадрамі, у дадзеным выпадку, таму што ў нас ёсць два,
у нас ёсць 0 і 1,
Вы робіце гэта з уверх і ўніз каманды.
Калі я пераеду адзін кадр,
Зараз я ў асноўным фрэйме стэка.
Я магу рухацца ўніз, каб вярнуцца туды, дзе я быў,
ісці зноў, зноў спусціцца, і падняцца зноў.
Калі вы калі-небудзь зрабіць сваю праграму ў GDB, вы атрымліваеце аварыі, вы атрымаеце след,
і вы ўбачыце, што гэта ў пэўным файле, які вы не ведаеце, што адбываецца.
Вы спрабуеце спісе, код выглядае не знаёмыя вам,
зірніце на вашыя кадры і высветліць, дзе вы знаходзіцеся.
Вы, напэўна, не ў тым фрэйм ​​стэка.
Ці, па крайняй меры, ты ў кадры стэка, што не адзін, што вы сапраўды можаце адладжваць.
Цяпер, калі мы знаходзімся ў адпаведным кадры стэка, мы ў асноўным,
Цяпер мы можам выкарыстоўваць каманду спісу, каб высветліць, якія лініі было.
І вы можаце бачыць яго, ён надрукаваў яго для нас прама тут.
Але мы можам стукнуць пералічыць усё тое ж самае, і спіс дае нам гэтую добрую раздрукоўку
фактычнага зыходнага кода, што адбываецца тут.
>> У прыватнасці, мы можам паглядзець на радку 6.
Мы бачым, што адбываецца тут.
І, падобна, мы робім параўнанне радкоў
паміж радкоў "CS50 пароды" і ARGV [1].
Нешта ў гэтым было збояў.
Такім чынам, місія, ці ёсць у вас думкі пра тое, што можа быць тут адбываецца?
[Missy] Я не ведаю, чаму гэта збой. >> Ты не ведаеш, чаму гэта збой?
Джымі, якія думкі?
[Джымі] я не зусім упэўнены, але ў апошні раз мы выкарыстоўвалі параўнанне радкоў,
або STRCMP, у нас былі як тры розных выпадках пад ім.
У нас не было ==, я не думаю, што прама ў першай радку.
Замест гэтага ён быў падзелены на тры, а адзін быў == 0,
адзін быў <0, я думаю, і адзін> 0.
Таму, магчыма, нешта ў гэтым родзе? >> Так. Так што гэтае пытанне
аб мы робім параўнанне правільна?
Stella? Любыя думкі?
[Stella] Я не ўпэўнены. >> Не ўпэўнены. Дэніэл? Думкі? Добра.
Аказваецца, тое, што адбываецца прама тут, калі мы запусцілі праграму
і мы атрымалі сегменце віны, калі вы запускаеце праграму ў першы раз, Данііл,
ты даць яму ніякіх аргументаў каманднага радка?
[Данііл] Няма >> Не. У такім выпадку, што з'яўляецца значэннем ARGV [1]?
>> Існуе ніякага значэння. >> Праве.
Ну, няма адпаведнага значэння радка.
Але ёсць некаторы значэнне. Што такое значэнне, якое атрымлівае захоўваецца там?
>> Смецця значэнне? >> Гэта альбо смецце кошту, ці, у дадзеным выпадку,
У канцы масіва ARGV заўсёды сканчаецца нулявым.
Так што ж на самай справе ёсць там захоўваюцца роўны нулю.
Іншага спосабу вырашыць гэтую праблему, а не думаць яго да канца,
заключаецца ў спробе друку яго.
Гэта дзе я казаў, што з дапамогай GDB з'яўляецца вялікім,
таму што вы можаце раздрукаваць ўсе зменныя, усё значэння, якія вы хочаце
з дапамогай гэтага зручнага дэндзі з камандай.
Так што калі я тыпу Р, а затым я ўводжу значэнне зменнай або імя зменнай,
кажуць, агдс, я бачу, што агдс 1.
Калі я хачу, каб раздрукаваць ARGV [0], я магу зрабіць гэта проста так.
І, як мы бачылі, ARGV [0] заўсёды з'яўляецца імем вашай праграмы,
Заўсёды імя выкананага файла.
Тут вы бачыце, ён атрымаў поўнае імя.
Я таксама можаце раздрукаваць ARGV [1] і паглядзець, што адбываецца.
>> Тут мы атрымалі такое містычнае значэнне.
Мы атрымалі гэтую 0x0.
Памятаеце, у пачатку семестра, калі мы казалі аб шаснаццатковых лікаў?
Або што мала хто сумняваецца ў канцы PSET 0 пра тое, як складаць 50 у шаснаццатковай?
Як мы пісаць шаснаццаткавыя лікі ў CS, толькі каб не блытаць сябе
з дзесятковай ліку, мы заўсёды іх з прэфіксам 0x.
Так што гэты прэфікс 0x заўсёды проста азначае, інтэрпрэтаваць наступным лік як шаснаццатковы лік,
а не як радок, а не як дзесятковы лік, а не як двайковыя ліку.
Так як лік 5-0 з'яўляецца сапраўдным лікам у шаснаццатковай.
І гэта лік у дзесятковай, 50.
Так што гэта толькі, як мы неадназначнасць.
Так 0x0 сродкаў шаснаццатковым 0, які таксама з'яўляецца дзесятковай 0, двайковы 0.
Гэта толькі значэння 0.
Аказваецца, што гэта тое, што нулявыя, уласна, у памяці.
Null проста 0.
Тут элемент захоўваецца ў ARGV [1] роўны нулю.
Такім чынам, мы спрабуем параўнаць нашы "CS50 скалы" радок пустая радок.
Так разнаймення NULL, спрабуе атрымаць доступ да рэчы ў нуль,
тыя, як правіла, збіраецца выклікаць нейкую няспраўнасць сегментацыі ці іншых дрэнных рэчаў.
І аказваецца, што STRCMP не праверыць
ці не вы прайшлі ў значэнне, якое нулявы.
Хутчэй за ўсё, ён проста ідзе наперад, спрабуе рабіць сваю справу,
і калі ён сегментах недахопы, ён сегментах недахопы, і гэта ваша праблема. Вы павінны пайсці выправіць.
Сапраўды хутка, як мы маглі б вырашыць гэтую праблему? Шарлота?
[Charlotte] Вы можаце праверыць, калі выкарыстанне.
Так што, калі ARGV [1] з'яўляецца несапраўдным, == 0, то вяртаецца 1, ці нешта ў [неразборліва].
>> Так. Так вось адзін выдатны спосаб зрабіць гэта, як мы можам праверыць,
Значэнне, якое мы збіраемся перайсці ў STRCMP, ARGV [1], яго несапраўдным?
Калі гэта нуль, то можна сказаць, добра, перапыніць.
>> Больш распаўсюджаны спосаб зрабіць гэта складаецца ў выкарыстанні агдс значэнне.
Вы можаце паглядзець прама тут, у самым пачатку галоўны,
мы апусцілі, што першы тэст, які мы звычайна робім, калі мы выкарыстоўваць аргументы каманднага радка,
якая заключаецца ў праверцы нашы агдс значэнне тое, што мы чакалі.
У гэтым выпадку, мы чакаем, па меншай меры, два аргументу,
Назва праграмы плюс адна іншую.
Таму што мы збіраемся выкарыстаць другі аргумент прама тут.
Такім чынам, па нейкай тэст загадзя, да нашага STRCMP выкліку
што тэсты, ці сапраўды ARGV па крайняй меры 2, будзе рабіць тое ж самае роду рэчы.
Мы бачым, што працуе, запусціўшы праграму зноў.
Вы заўсёды можаце перазагрузіць праграму ў GDB, які сапраўды добры.
Вы можаце запусціць, і калі вы праходзіце ў якасці аргументаў вашай праграмы,
Вы перадаеце іх, калі вы патэлефануеце працаваць, а не пры загрузцы GDB.
Такім чынам, вы можаце захаваць выкліку праграмы з рознымі аргументамі кожны раз.
Так бяжыце, ці зноў жа, я магу Type R, і давайце паглядзім, што адбудзецца, калі набраць "прывітанне".
Ён заўсёды будзе пытацца вас, калі вы хочаце, каб пачаць з самага пачатку яшчэ раз.
Як правіла, вы хочаце, каб пачаць з самага пачатку яшчэ раз.
І ў гэты момант, яна запускае яго зноў, ён друкуе
Праграма, якую мы бяжым, buggy1 з аргументам прывітанне,
і гэта выводзіць з гэтага стандарту, ён кажа: "Вы атрымліваеце D," сумны твар.
Але мы не сегментах віна. Ён сказаў, што працэс завяршыўся нармальна.
Так што выглядае даволі добра.
Няма больш сегменце віна, мы зрабілі гэта мінулае,
так што падобна, што гэта сапраўды памылка сегменце віна, што мы атрымлівалі.
На жаль, гэта кажа нам, што мы атрымліваем D.
>> Мы можам вярнуцца назад і паглядзець на зыходны код і паглядзець, што там адбываецца
каб высветліць, што было - чаму яно было казаць нам, што мы атрымалі D.
Давайце паглядзім, вось гэта было Printf кажуць, што вы атрымалі D.
Калі мы ўвядзем спіс, як вы трымаеце ўвод спісу, ён трымае ітэрацыі ўніз праз вашу праграму,
так што пакажу Вам некалькі першых радкоў праграмы.
Тады пакажу вам некалькі радкоў, а на наступны кавалак і наступны кавалак.
І ён будзе старацца ісці ўніз.
А зараз мы вернемся да "лініі нумар 16 знаходзіцца па-за дыяпазону".
Таму што ён мае толькі 15 ліній.
Калі вы дайшлі да гэтага пункту, і вашы задаўся пытаннем: "Што рабіць?" Вы можаце выкарыстоўваць каманду дапамогі.
Выкарыстоўвайце дапамогу, а затым даць яму імя каманды.
І вы бачыце, GDB дае нам усё такога роду рэчы.
Ён кажа: "Без аргументаў, пералічвае 10 радкоў пасля або ва ўсім папярэднім лістынгу.
List - спіс дзесяці радкоў раней - "
Так давайце паспрабуем выкарыстаць спіс мінус.
І ў якім пералічаныя 10 радкоў папярэдняй, вы можаце пагуляць са спісам няшмат.
Вы можаце зрабіць спіс, спіс - вы можаце нават даць пералічыць шэраг, як і спіс 8,
і яна будзе пералічыць 10 ліній вакол лініі 8.
І вы можаце бачыць, што адбываецца тут, у вас ёсць просты, калі іншае.
Калі вы набярэце ў CS50 скалы, ён друкуе "Вы атрымліваеце А."
У адваротным выпадку яна выводзіць "Вы атрымліваеце D."
Гультай горада. Добра. Да?
>> [Данііл] Таму, калі я спрабаваў рабіць CS50 парод без двукоссяў,
ён кажа: "Вы атрымліваеце D."
Я меў патрэбу ў двукоссі, каб прымусіць яго працаваць, чаму гэта?
>> Так. Аказваецца, што калі - гэта яшчэ адна пацешная прынадны кавалачак -
Пры запуску праграмы, калі мы запусцім яго, і мы ўвесці CS50 парод,
гэтак жа, як Данііл казаў ён зрабіў, і вы націснеце Enter,
ён па-ранейшаму кажа, што мы атрымаем D.
І пытанне ў тым, чаму гэта адбываецца?
І аказваецца, што абодва нашых тэрміналаў і GDB разабраць іх як два асобных аргументаў.
Таму што, калі ёсць прастора, якое мае на ўвазе як
Першы аргумент скончыўся, а на наступны аргумент вось-вось пачнецца.
Спосаб сумясціць гэтыя дзве, або прабачце, у адзін аргумент,
з'яўляецца выкарыстанне двукоссяў.
Так што цяпер, калі пакласці яго ў двукоссі і запусціць яго зноў, мы атрымаем A.
Так проста, каб рэзюмаваць, без двукоссяў, CS50 і горных парод апрацоўваюцца як два асобных аргументаў.
З двукоссямі, ён апрацоўваецца як адзін аргумент у цэлым.
>> Мы бачым гэта з кропкі супыну.
Да гэтага часу мы былі працуе наша праграма, і яна працуе ўжо
да таго часу, пакуль альбо ён сегментах няспраўнасці або памылкі хіты
або пакуль ён не завершыцца, і ўсё было ў поўным парадку.
Гэта не абавязкова самая карысная рэч, таму што часам
ў вас ёсць памылкі ў вашай праграме, але гэта не выклікае памылку сегментацыі.
Гэта не выклікае вашу праграму, каб спыніць ці што-небудзь падобнае.
Спосаб атрымаць GDB, каб прыпыніць праграму ў канкрэтнай кропцы
, Каб усталяваць кропкі супыну.
Вы можаце зрабіць гэта, усталяваўшы кропку супыну на імя функцыі
ці вы можаце ўсталяваць кропкі супыну на пэўную радок кода.
Я хацеў бы ўсталяваць кропкі супыну на функцыю імёнаў, таму што - лёгка запомніць,
і калі вы на самой справе пайсці і змяніць свой зыходны код ўверх трохі,
то ваша кропка супыну будзе фактычна заставацца на тым жа месцы ў кодзе.
Прымаючы пад увагу, калі вы выкарыстоўваеце нумара радка і нумары радкі зменіцца
таму што вы дадаць ці выдаліць частка кода, то вашы кропкі супыну усё цалкам аблажаўся.
Адзін з самых распаўсюджаных рэчаў, якія я зрабіць, гэта ўсталяваць кропкі супыну на асноўныя функцыі.
Часта я буду загружаць GDB, я тыпу У галоўнай, ударыў Enter, і што будзе ўсталяваць кропкі супыну
на галоўнай функцыяй якога проста кажа: "Паўза праграмы, як толькі вы пачынаеце бегаць"
і, такім чынам, калі я запускаю маю праграму, скажам, CS50 парод як два аргументу
і націснуць Enter, ён трапляе ў асноўныя функцыі і спыняецца прама на самай першай лініі,
Права, перш чым ён ацэньвае STRCMP функцыі.
>> Так як я спыніўся, цяпер я магу пачаць адводам вакол і бачачы, што адбываецца
з усімі розных зменных, якія перадаюцца ў маёй праграме.
Тут я магу раздрукаваць ARGC і паглядзець, што адбываецца.
Глядзіце, што агдс 3, таму што ён атрымаў 3 розныя значэнні ў ім.
Ён атрымаў назву праграмы, ён атрымаў першы аргумент, а другі аргумент.
Мы можам надрукаваць тыя з гледзячы на ​​ARGV [0], ARGV [1], і ARGV [2].
Так што цяпер вы можаце зразумець, чаму гэты выклік STRCMP збіраецца пацярпець няўдачу,
таму што вы бачыце, што ён падзелены CS50 і скалы на дзве асобныя аргументы.
На дадзены момант, як толькі вы патрапілі супыну, вы можаце працягнуць пакрокавае выкананне праграмы
радок за радком, у адрозненне ад запуску праграмы зноў.
Так што, калі вы не хочаце, каб запусціць праграму зноў і проста працягваць адсюль,
Вы можаце выкарыстоўваць каманду працягваюцца і па-ранейшаму будзе выконваць праграму да канца.
Гэтак жа, як гэта зрабіў тут.
Аднак, калі я перазапусціць праграму, CS50 скалы, ён трапляе майго пункту супыну зноў,
і на гэты раз, калі я не хачу, каб проста прайсці ўвесь шлях праз астатнюю частку праграмы,
Я магу выкарыстоўваць наступную каманду, якую я таксама скарачэння з п.
І гэта будзе крок у рамках праграмы радок за радком.
Такім чынам, вы можаце назіраць, як рэчы, выконваць, як зменныя змены, як рэчы абнаўляецца.
І гэта вельмі прыемна.
Іншыя Выдатная рэч, а не паўтараць тую ж каманду зноў і зноў, і зноў,
калі вы проста націсніце Enter - так што тут вы бачыце, што я не набраў ні ў чым -
калі я проста націсніце Enter, ён будзе паўтараць папярэднюю каманду,
або папярэдняй каманды GDB, што я проста ўставіў
Я магу трымаць удар, і менавіта буду трымаць пакрокавага свой код радок за радком.
Я хацеў бы заклікаць вас, хлопцы, каб пайсці праверыць іншыя праграмы багі, а таксама.
У нас няма часу, каб прайсці праз усе з іх сёння ў раздзеле.
Зыходны код ёсць, так што вы можаце збольшага бачыць, што адбываецца на
за кулісамі, калі Вы сапраўды затрымаліся,
але, па меншай меры, толькі практыка загрузцы GDB,
выкананне праграмы пакуль не зламаецца на вас,
атрыманне зваротнай трасіроўкі, высветліць, якія функцыі абвал адбыўся ў,
якой лініі ён быў, выводзячы некаторых значэнняў зменных,
толькі так вы адчуеце гэта, таму што сапраўды дапаможа вам у будучыні.
На дадзены момант, мы збіраемся выйсці з GDB, якой вы выкарыстаннем кінуць або проста ц.
Калі ваша праграма знаходзіцца ў сярэдзіне працуе да гэтага часу, і яна не выйшла,
ён заўсёды спытае вас: «Вы ўпэўненыя, што сапраўды жадаеце выйсці?"
Вы можаце проста націснуць так.
>> Цяпер мы будзем глядзець на наступная праблема ў нас ёсць, што кошка праграмы.
Калі вы паглядзіце на кароткі перанакіраваньні і трубы, вы ўбачыце, што Томі выкарыстоўвае гэтую праграму
, Што ў асноўным друкуе усе выходныя файла на экран.
Так што, калі я бягу кошка, гэта на самай справе убудаванай праграмы ў прыбор,
і калі ў вас ёсць Macs вы можаце зрабіць гэта на вашым Mac таксама, калі вы адкрываеце тэрмінал.
А мы - коткі, скажам, cp.c, і націсніце Enter.
Тое, што гэта зрабілі, калі б мы прагортку уверх трохі і паглядзець, дзе мы правялі лінію,
ці там, дзе мы запусцілі котку каманду, ён літаральна раздрукаваць змесціва cp.c на нашым экране.
Мы можам запусціць яго зноў, і вы можаце пакласці ў некалькіх файлах.
Такім чынам, вы можаце зрабіць котцы cp.c, і тады мы можам таксама аб'ядноўваць cat.c файл,
якая з'яўляецца праграма, якую мы збіраемся пісаць,
і ён будзе друкаваць як файлы назад, каб вярнуцца ў наш экран.
Таму, калі мы прагортку уверх трохі, мы бачым, што калі мы запусцілі гэты кот cp.c, cat.c,
Спачатку ён раздрукаваў ф файл, а затым пад ім, ён раздрукаваў cat.c файл прама тут.
Мы збіраемся выкарыстоўваць гэта, каб проста атрымаць нашы ногі мокрыя.
Пагуляйце з простай друку на тэрмінал, паглядзім, як гэта працуе.
Калі вы, хлопцы адкрываюць з Gedit cat.c, націсніце Enter,
Вы можаце ўбачыць праграмы, якія мы збіраемся пісаць.
Мы ўключылі гэта добрая пліта катла, таму мы не прыйдзецца марнаваць час на ўвод ўсё гэта.
Мы таксама правяраем колькасць аргументаў, перададзеных цалі
Мы раздрукаваць добрае паведамленне выкарыстанні.
>> Гэта такая штука, што, зноў жа, як мы ўжо казалі,
гэта амаль як цягліцавая памяць.
Толькі не забудзьцеся захаваць рабіць тое ж самае роду рэчы
і заўсёды раздрукоўку свайго роду карыснымі паведамленне
так, што людзі ведаюць, як кіраваць вашай праграмы.
З коткай, гэта даволі проста, мы проста збіраемся прайсці праз усе розныя аргументы
, Якія былі перададзеныя нашай праграмы, і мы збіраемся для друку
іх змесціва, каб на экране па адным.
Для таго, каб друкаваць файлы з да экрану, мы збіраемся зрабіць нешта вельмі падобнае
да таго, што мы зрабілі ў канцы віктарыны.
У канцы віктарыны, якія наймаюць праграмы, мы павінны былі адкрыць файл,
і тады мы павінны былі друкаваць на ім.
У гэтым выпадку, мы збіраемся адкрыць файл, і мы будзем чытаць з яго замест гэтага.
Тады мы ідзем да друку, а не ў файл, мы збіраемся друкаваць на экране.
Такім чынам, друк на экране вы ўсё рабілі з Printf.
Так што гэта не занадта вар'ятам.
Але чытанне файлаў дзіўна.
Мы будзем прайсці праз гэта трохі за адзін раз.
Калі вы, хлопцы вярнуцца да гэтай апошняй праблемы на вашай віктарыны, задачы 33,
першая лінія, што мы збіраемся тут рабіць, адкрыццё файла, вельмі падобныя на тое, што мы там рабілі.
Такім чынам, Стэла, што робіць гэтую лінію выглядаць, калі мы адкрываем файл?
[Stella] Сталіца FILE *, файл - >> Добра. >> - Роўна Еореп. >> Так.
Якія ў гэтым выпадку? Гэта ў каментары.
>> Гэта ў каментарах? ARGV [я] і г?
>> Менавіта так. Прама на. Так Stella цалкам правы.
Гэта тое, што лінія выглядае.
Мы збіраемся, каб атрымаць пераменны паток файла, захаваць яго ў файле *, так што ўсе вечка,
FILE *, і імя гэтай зменнай будзе файл.
Мы маглі б назваць гэта ўсё, што мы хацелі. Мы маглі б назваць гэта first_file, або file_i, што б мы хацелі.
І тады імя файла быў прыняты ў камандным радку гэтай праграмы.
Такім чынам, ён захоўваецца ў ARGV [я], і затым мы збіраемся адкрыць гэты файл у рэжыме чытання.
Цяпер, калі мы адкрылі файл, што тое, што мы заўсёды павінны памятаць, каб зрабіць
кожны раз, калі мы адкрылі файл? Зачыніце яе.
Такім чынам, місія, як мы зачыніць файл?
[Missy] Fclose (файл) >> Fclose (файл). Менавіта так.
Вялікі. Добра. Калі мы паглядзім на гэта, каб зрабіць каментар прама тут,
ён кажа, "Адкрытыя ARGV [я] і раздрукаваць яго змесціва на стандартны вывад".
>> Стандартны выхад гэта дзіўнае імя. Stdout гэта проста спосаб сказаць нашым
Мы хочам, каб раздрукаваць яго на тэрмінал, мы хочам, каб раздрукаваць яго ў стандартны выхадны паток.
Мы можам на самай справе пазбавіцца ад гэтага каментара прама тут.
Я збіраюся скапіяваць яго і ўставіць яго, так як гэта тое, што мы і зрабілі.
На дадзены момант, зараз у нас ёсць, каб прачытаць файл па кавалачках.
Мы абмеркавалі некалькі спосабаў чытання файлаў.
Якія вашы любімыя да гэтага часу?
Якія спосабы вы бачылі ці вы памятаеце, для чытання файлаў?
[Данііл] FREAD? >> FREAD? Так FREAD адзін. Джымі, вы ведаеце, любыя іншыя?
[Джымі] Няма >> Добра. Няма. Шарлота? Аляксандр? Любыя іншыя? Добра.
Такім чынам, астатнія з'яўляюцца fgetc, гэта той, які мы будзем выкарыстоўваць шмат.
Там таксама fscanf, вы, хлопцы, бачыць ўзор тут?
Усе яны пачынаюцца з F. Усё, што рабіць з файлам.
Там у FREAD, fgetc, fscanf. Гэтыя ўсе функцыі чытання.
Для размяшчэння ў нас ёсць FWRITE, у нас ёсць fputc замест fgetc.
Мы таксама Fprintf, як мы бачылі на віктарыну.
Так як гэта з'яўляецца праблемай, якая ўключае ў сябе чытанне з файла,
Мы збіраемся выкарыстаць адну з гэтых трох функцый.
Мы не збіраемся выкарыстоўваць гэтыя функцыі тут.
Усе гэтыя функцыі ў стандартнай бібліятэцы ўводу / высновы.
Так што, калі вы паглядзіце на верхнюю частку гэтай праграмы,
Вы можаце бачыць, што мы ужо ўключаны файл загалоўка для стандартнай бібліятэкі ўводу / высновы.
Калі мы хочам, каб высветліць, які мы хочам выкарыстоўваць,
мы заўсёды можам адкрываць чалавеку старонак.
Такім чынам, мы можа ўвесці чалавека STDIO
і прачытаць усё пра STDIO уваходны і выхадны функцыі ў C.
І мы ўжо бачым, ой, глядзі. Гэта згадка fgetc, гэта згадка fputc.
Такім чынам, вы можаце разгарнуць трохі і паглядзім на, скажам, fgetc
і паглядзіце на яго старонцы.
Вы можаце бачыць, што ён ідзе разам з цэлай кучай іншых функцый:
fgetc, ЕдеЬз, ЕОКП, GetChar атрымлівае, UNGETC, і яго ўводу знакаў і радкоў.
Так што гэта, як мы чытаем у знакі і радкі з файлаў са стандартнага ўводу,
якая з'яўляецца па сутнасці ад карыстальніка.
І гэта, як мы гэта робім у рэальнай C.
Так што гэта не выкарыстанне GetString і GetChar функцый
, Якія мы выкарысталі з CS50 бібліятэкі.
Мы збіраемся зрабіць гэтую праблему некалькімі спосабамі
так што вы можаце ўбачыць два розных спосабу зрабіць гэта.
І FREAD функцыі, што Данііл згадваецца і fgetc добрыя спосабы зрабіць гэта.
Я думаю, што fgetc крыху лягчэй, таму што гэта толькі мае, як бачыце,
адзін аргумент, FILE *, што мы спрабуем прачытаць знак з,
і яе вяртаецца значэння Int.
І гэта крыху дзіўна, ці не так?
>> Таму што мы атрымліваем характар, дык чаму б не гэта вяртанне знакаў?
Вы, хлопцы, ёсць якія-небудзь ідэі аб тым, чаму гэта не можа вярнуць знак?
[Missy адказы, неразборліва] >> Так. Так Missy цалкам правы.
Калі гэта ASCII, то гэта лік можа быць супастаўлены з фактычнымі знак.
Можа быць ASCII сімвалаў, і гэта правільна.
Гэта менавіта тое, што адбываецца.
Мы выкарыстоўваем Int проста таму, што ён мае больш бітаў.
Гэта больш, чым знак, наш сімвал мае толькі 8 біт, што 1 байт на наш 32-бітных машын.
І Int мае варта ўсё 4 байта "прастору.
І аказваецца, што шлях fgetc працуе,
калі пракруціць ўніз у нашу рэзюмэ ў гэтым чалавеку старонцы трохі,
пракруціць ўніз да ўпора. Аказваецца, што яны выкарыстоўваюць гэта адмысловае значэнне, званае EOF.
Гэта спецыяльная пастаянная, значэнне, якое вяртаецца функцыяй fgetc
кожны раз, калі вы патрапілі ў канец файла або калі вы атрымліваеце паведамленне пра памылку.
І аказваецца, што для выканання гэтых параўнанняў з EOF належным чынам,
Вы хочаце, што дадатковы аб'ём інфармацыі, якую вы маеце на Int
па параўнанні з выкарыстаннем знакаў зменнай.
Нават калі fgetc эфектыўна атрымліваць персанаж з файла,
Вы хочаце, каб памятаць, што яна вяртаецца нешта такое, што тыпу Int да вас.
Тым не менш, ён даволі просты ў выкарыстанні.
Гэта дасць нам характар, таму ўсе, што мы павінны зрабіць, гэта працягваць задаваць файл,
"Дайце мне наступны знак, дай мне наступны знак, дай мне наступную характар»,
пакуль мы не атрымаем да канца файла.
І гэта будзе цягнуць у адзін знак за адзін раз з нашага файла,
і тады мы можам рабіць усё, што мы хацелі з ёй.
Мы можам захаваць яго, мы можам дадаць яго ў радок, мы можам раздрукаваць яго.
Выканайце любое з гэтага.
>> Павелічэнне назад і вярнуцца да нашых cat.c праграмы,
калі мы збіраемся выкарыстаць fgetc,
як мы маглі б падысці да гэтай наступнага радка кода?
Мы збіраемся выкарыстаць - FREAD будзе рабіць нешта трохі адрозніваецца.
І на гэты раз, мы проста збіраемся выкарыстоўваць fgetc, каб атрымаць адзін сімвал за адзін раз.
Каб апрацаваць увесь файл, што мы маглі б рабіць?
Колькі персанажаў ёсць у файле?
Ёсць шмат. Такім чынам, вы, верагодна, хочаце, каб атрымаць адзін
, А затым атрымаць іншую і атрымаць іншую і атрымаць іншую.
Які алгарытм вы думаеце, мы маглі б выкарыстоўваць тут?
Які тып - [Аляксандр] для цыклу? >> Менавіта так.
Некаторыя тыпы цыклу.
Цыкл на самай справе вялікі, і ў гэтым выпадку.
І, як вы кажаце, гэта гучыць, як вы хочаце пятлю на ўвесь файл,
атрымаць сімвал за адзін раз.
Любыя прапановы аб тым, як гэта можа выглядаць?
[Аляксандра, неразборліва]
>> Добра, толькі скажы мне, на англійскай мове, што вы спрабуеце зрабіць? [Аляксандра, неразборліва]
Такім чынам, у дадзеным выпадку, падобна, мы проста спрабуем пятлю на ўвесь файл.
[Аляксандр] Так я <памер Int? >> Памер -?
Я мяркую, што памер файла, дакладна? Памер - МЫ проста напісаць гэта так.
Памер файла ў цяперашні час, я + +.
Вось і атрымліваецца, што тое, як вы гэта з дапамогай fgetc, і гэта новае,
у тым, што не існуе просты спосаб, каб проста атрымаць памер файла
з гэтым "SizeOf" тыпу пабудуем, што вы бачылі раней.
Калі мы выкарыстоўваем гэтую функцыю fgetc, мы ўяўляем нейкі
новы, фанк сінтаксіс для гэтага цыклу, дзе замест выкарыстання толькі асноўны лічыльнік
пайсці па адным знаку, мы збіраемся вывесці адзін знак за адзін раз,
па адным знаку за адзін раз, і тое, як мы ведаем, што мы ў канцы
Не тады, калі мы лічылі пэўную колькасць знакаў,
Але калі мы характары выцягнуць тое, што спецыяльная сімвал канца файла.
Такім чынам, мы можам зрабіць гэта, - я называю гэта гл, і мы збіраемся яго ініцыялізацыі
наш першы выклік, каб атрымаць першы знак з файла.
Такім чынам, гэтая частка прама тут, гэта будзе атрымаць знак з файла
і захоўваць яго ў зменнай гл.
Мы збіраемся працягваць рабіць гэта, пакуль мы дойдзем да канца файла,
што мы і робім, тэстуючы для персанажа не роўныя, што адмысловы сімвал EOF.
І тады замест таго, каб рабіць CH + +, якая б проста павялічыць значэнне,
таму, калі мы чытаем з файла, капітал, скажам,
CH + + дасць нам б, і тады мы атрымаем С, а затым г.
Гэта відавочна не тое, што мы хочам. Што мы хочам тут
У гэтым апошнім біт мы хочам атрымаць наступны знак з файла.
>> Так як мы можам атрымаць наступны знак з файла?
Як мы можам атрымаць першы знак з файла?
[Студэнт] fgetfile? >> Fgetc, або, прабачце, вы мелі рацыю.
Я няправільна яго прама там. Так што так.
Тут замест таго, каб рабіць CH + +,
Мы проста будзем называць fgetc (файл) зноў
і захаваць вынік у нашых жа зменнай гл.
[Студэнт пытанне, неразборліва]
>> Гэта дзе гэтыя хлопцы FILE * з'яўляюцца спецыяльнымі.
Тое, як яны працуюць, яны - пры першым адкрыцці - калі вы спачатку пераканайцеся, што Еореп выкліку,
FILE * эфектыўна служыць у якасці паказальніка на пачатак файла.
І тады кожны раз, калі вы тэлефануеце fgetc, яна рухаецца па адным знаку з дапамогай файла.
Таму, калі вы называеце гэта, вы павялічваючы паказальнік на адзін знак.
І калі вы fgetc зноў, вы рухаецеся гэта іншае персанаж
і іншы характар ​​і іншы характар ​​і іншы персанаж.
[Студэнт пытанне, неразборліва] >> А that's - так.
Гэта свайго роду гэтая чароўная пад капотам.
Вы проста працягвайце павялічваючы да канца.
На дадзены момант, вы зможаце на самай справе працаваць з характарам.
Такім чынам, як мы маглі б раздрукаваць гэта на экране, цяпер?
Мы можам выкарыстоўваць тыя ж Printf рэч, якую мы выкарысталі раней.
Тое, што мы ўжо выкарысталі ўвесь семестр.
Мы можам назваць Printf,
і мы можам перайсці ў характары проста так.
Яшчэ адзін спосаб зрабіць гэта хутчэй, чым пры выкарыстанні Printf і маюць для гэтага фармату радкі,
мы таксама можам выкарыстоўваць адну з іншых функцый.
Мы можам выкарыстоўваць fputc, якая выводзіць знак на экран,
выключэннем выпадкаў, калі мы глядзім на fputc - дазвольце мне маштаб няшмат.
Мы бачым, што прыемна, ён прымае ў характары, што мы чытаем, выкарыстоўваючы fgetc,
але тады мы павінны даць яму струмень у друк.
Мы таксама можам выкарыстоўваць риЬспаг функцыю, якая наносіцца непасрэдна на стандартны вывад.
Такім чынам, існуе цэлая куча розных варыянтаў, якія мы можам выкарыстоўваць для друку.
Яны ўсе ў стандартнай бібліятэцы ўводу / высновы.
Кожны раз, калі вы хочаце надрукаваць - так Printf, па змаўчанні, будуць друкавацца на адмысловай стандартныя з плыні,
якіх з'яўляецца тое, што стандартны вывад.
Такім чынам, мы можам проста спасылацца на яго як віду гэтай магічнае значэнне, стандартны вывад тут.
Ой. Паставіць кропку з коскай звонку.
>> Гэта шмат новага, напалоханы інфармацыяй тут.
Шмат гэта вельмі ідыёматычны, у тым сэнсе, што гэта код
што напісана такім чынам толькі таму, што гэта чыста чытаць, лёгка чытаецца.
Ёсць шмат розных спосабаў зрабіць гэта, шмат розных функцый, якія вы можаце выкарыстоўваць,
але мы, як правіла, проста выканайце гэтыя ж мадэлі зноў і зноў.
Так што не здзіўляйцеся, калі ўбачыце такі код прыдумаць зноў і зноў.
Добра. На дадзены момант, мы павінны разарваць на працягу дня.
Дзякуй, што прыйшлі. Дзякуй за прагляд, калі вы знаходзіцеся ў сеткі. І мы ўбачымся на наступным тыдні.
[CS50.TV]