[Powered by Google Translate] [ЦС50 Библиотека]
[Нејт Хардисон] [Универзитет Харвард]
[Ово је ЦС50. ЦС50.ТВ]
Тхе ЦС50 библиотека је корисна алатка која смо инсталирали на уређају
да би се лакше за вас да напишете програме који брзе корисници за улаз.
У овом видеу, ми ћемо повући завесу и погледајте шта је тачно у ЦС50 библиотеци.
>> У споту о Ц библиотека, говоримо о томе како си # инцлуде заглавља датотеке
библиотеке у вашем изворном коду,
и онда се повежете са бинарном фајлу библиотеке током повезује фазе
на компилацији процеса.
Заглавље датотеке одредити интерфејс библиотеке.
То јест, они детаљно све ресурсе да библиотека има на располагању за вас да користите,
као функција декларацијама, константи и типова података.
Бинарни библиотека фајл садржи примену библиотеке,
која је састављена из заглавља библиотеке фајлова и библиотека је Ц изворног кода. фајлови.
>> Бинарни библиотека датотека није веома интересантно да погледамо, јер то је, добро, у бинарном.
Дакле, хајде да погледамо заглавља датотеке за библиотеку уместо.
У овом случају, постоји само један хеадер фајл под цс50.х.
Ми смо га инсталирали у упутству укључују директоријум
заједно са другом систему библиотека заглавља датотека.
>> Једна од првих ствари које ћете приметити јесте да цс50.х # укључује заглавља датотека из других библиотека -
плутају, границе, стандардни Боол и стандардни либ.
Опет, након принцип не прекрајањем точак,
смо изградили смо се у ЦС0 библиотеку помоћу алатки које друге прописане за нас.
>> Следећа ствар коју ћете видети у библиотеци је да дефинишемо нову врсту под именом "стринг".
Ова линија заиста само ствара псеудоним за цхар * типа,
па не магично прожимати нови тип стринг са атрибутима
обично повезује са гудачке објеката у другим језицима,
као што су дужине.
Разлог што смо урадили јесте да заштити нових програмера из гори детаља
од показивача док смо спремни.
>> Следећи део заглавља датотеке је декларација функција
да је ЦС50 библиотека обезбеђује заједно са документацијом.
Обратите пажњу на ниво детаља у коментарима овде.
Ово је супер важно да људи знају како да користе ове функције.
Ми изјављујемо, заузврат, функционише како би подстакао корисника и вратили цхарс, дубл, плута, Интс,
дуго чезне, и гудаче, користећи сопствену стринг тип.
Након принципу информација крије,
ми смо ставили нашу дефиницију у посебан фајл Ц имплементације. - цс50.ц--
налази у директоријуму корисника извора.
Смо навели тај фајл тако да можете да погледате на њега,
учити од њега и компајлирате га на различитим машинама, ако желите,
иако ми мислимо да је боље да се ради на апарату за ову класу.
У сваком случају, хајде да сада погледамо.
>> Функције гетцхар, ГетДоубле, ГетФлоат, ГетИнт, и ГетЛонгЛонг
Сви изграђена на врху ГетСтринг функције.
Испоставило се да су сви они прате суштини исти образац.
Они користе вхиле петљу да подстакне корисника за једну линију улаза.
Они врати посебну вредност ако корисник улази празну линију.
Они покушавају да парсира улаз корисниково као одговарајућег типа,
било да је знак, дупли, плутају, итд
И онда они или вратити резултат ако је улаз је успешно анализирати
или су репромпт корисника.
>> На високом нивоу, овде нема ничег заиста лукав.
Можда сте написали сличне структуре кода себе у прошлости.
Можда највише криптичан изгледа део је ссцанф позив да анализира допринос корисника.
Ссцанф је део улазног породице формату конверзије.
Она живи у стандардној ио.х, а његов посао је да анализирамо царски стринг,
према одређеном формату, памтећи рашчланити резултате у променљива
обезбеђује позиваоца.
Пошто су улазни формат конверзије функције су веома корисни, широко коришћеним функцијама
који нису супер интуитивно на први поглед,
ићи ћемо преко колико ссцанф ради.
>> Први аргумент је ссцанф цхар * - показивач на карактер.
За функција ради исправно,
тај лик би требало да буде први карактер ниске Ц,
престаје са нултим \ 0 карактера.
Ово је стринг да анализирамо
Други аргумент ссцанф је формат стринг,
обично прошао у као стринг константа,
а можда сте видели овако ниску пре када се користи принтф.
Посто знак у формату стрингу указује на конверзију задавач.
Карактер одмах након знак за проценат,
означава Ц тип који желимо ссцанф да конвертујете.
У ГетИнт, видиш да постоји% д и% д.
То значи да ће покушати да ссцанф децимални ИНТ - је% д - и цхар - је% ц.
За сваку конверзију пројектанта у формату ниске,
ссцанф очекује касније одговарајући аргумент у свом листе аргумената.
Тај аргумент мора да укаже на одговарајуће локације куцани
у којима се складишти резултат конверзије.
>> Типичан начин да то урадите је да се створи променљиву на стек пре ссцанф позива
за сваку ставку коју желите да изузме из стринга
а затим користите оператор адреса - амперсанд - да прође показиваче
тих променљивих до ссцанф позива.
Можете видети да је у ГетИнт смо управо урадили.
Право пред ссцанф позива, изјављујемо инт н зове и цхар позива ц на стек,
и ми проћи показиваче на њих у ссцанф позив.
Стављање ове променљиве на стек је предност у односу на коришћење простора додељеног
на гомили са маллоц, пошто сте избегло изнад главе у маллоц позива,
а ви не морате да бринете о цури меморију.
Карактери не префиксом стране одсто знак не подстакне конверзију.
Напротив, они само додају на формату спецификацији.
>> На пример, ако је формат стринг у ГетИнт су уместо% д
ссцанф ће тражити писмо једног уследио инт,
и док би покушати да конвертујете инт, то не би ништа друго са наведеним.
Једини изузетак је размак.
Бели простор ликови у формату ниске одговара било који износ од белине -
чак ни уопште.
Дакле, то је разлог зашто је коментар помиње евентуално са водећим и / или пратеће белине.
Дакле, у овом тренутку изгледа као наша ссцанф позив ће покушати да анализирамо стринг унос корисников
провером за могућу водећих размака,
следи инт који ће бити конвертован и складишти у инт променљиве н
праћено неком износу од белине, а потом знака
чувају у цхар променљиве ц.
>> Шта је повратак вредности?
Ссцанф ће анализирати линију за унос од почетка до краја,
заустављајући се када дође до краја, или када је карактер улазне
не одговара карактер формата или када не може да направи конверзију.
То је повратак вредност се користи да издвојим када је заустављен.
Ако је заустављен, јер је стигла до краја улазног стринга
пре доношења било какве конверзије и пре не успева да одговара део формату ниске,
онда специјални константа ЕОФ враћа.
У супротном, враћа број успешних конверзија,
што би могло да буде 0, 1 или 2, јер смо тражили два конверзије.
У нашем случају, желимо да се уверите да је корисник откуцао у инт и само инт.
>> Дакле, желимо да се врати ссцанф 1. Погледајте зашто?
Ако ссцанф вратио 0, онда нема конверзије су направљене,
тако да корисник откуцао нешто друго него интег на почетку улаза.
Ако ссцанф врати 2, онда корисник није исправно да откуцате у на почетку улаз,
али су потом уписали у неком не-Белина карактера касније
Од% ц конверзија успео.
Вау, то је прилично дугачак објашњење за једног позива функције.
У сваком случају, ако желите више информација о ссцанф и његових браће и сестара,
проверите ман странице, Гоогле, или оба.
Постоји много опција формата гудачке,
а то може да вам уштеди пуно мануелног рада када покушава да изузме конце у Ц.
>> Коначна функција у библиотеци да погледамо ГетСтринг.
Испоставило се да је ГетСтринг је незгодно функција правилно писати,
иако изгледа као да тако једноставан, заједничком задатку.
Зашто је ово тако?
Па, хајде да размишљамо о томе како ћемо да сачувате линију да корисник укуцава ин
Пошто стринг је низ карактера,
можемо да га сачувате у низу на стек,
али би требало да знају колико дуго се низ ће бити када га прогласи.
Исто тако, ако желимо да га стави на гомилу,
морамо да прође да маллоц број бајтова желимо да резерве,
али ово је немогуће.
Немамо појма колико слова корисник ће куцали
пре корисник заправо их откуцате.
>> Наивно решење овог проблема је да се само резервише велики комад простора, рецимо,
блок 1000 цхарс за унос корисника,
под претпоставком да је корисник никада не би откуцајте у низу тако дуго.
То је лоша идеја из два разлога.
Прво, под претпоставком да корисници обично не куцате у жицама толико дуго,
бисте могли да троше много меморије.
На савременим машинама, ово не може бити проблем ако то радите
у једној или две изоловане случајеве,
али ако узимаш улаз корисника у петљу и чување за каснију употребу,
можете брзо да сиса до тону меморије.
Поред тога, ако програм који пишете је за мањи рачунар -
уређај као што је смартпхоне или нешто друго са ограниченом меморијом -
ово решење ће изазвати проблеме много брже.
Други, озбиљнији разлог да не урадите ово јесте да оставља свој програм рањива
да оно што се зове бафера напад.
У програмирању, бафер меморије се користи за привремено чување улаза или излаза података,
која је у овом случају је наша 1000-знак блок.
Бафера се јавља када се подаци написано прошлост крају блока.
>> На пример, ако корисник заправо ради тип у више од 1000 карактера.
Можда сте искусили ово случајно, када програмирања са низовима.
Ако имате низ од 10 Интс, ништа вас зауставља од покушаја да читају и пишу
15. инт.
Нема компилатор упозорења или грешке.
Програм само греске равно и приступа меморију
где он мисли 15. инт ће бити, а то може заменити своје друге варијабле.
У најгорем случају, можете заменити неким од интерних вашег програма
контролни механизми, изазивајући свој програм да заиста изврши различите инструкције
него што сте намеравали.
>> Сада, није уобичајено да се то уради случајно,
али ово је прилично уобичајена техника која лоши момци користе да се пробије програме
и стави злонамерног кода на рачунарима других људи.
Дакле, не можемо да користимо само наше наивно решење.
Морамо начин да се спречи наше програме од тога рањиви
у нападу бафера.
Да бисте то урадили, морамо да осигурамо да наша бафер расте као што смо прочитали
више улаз од корисника.
Решење? Ми користимо гомилу додељеног бафер.
Пошто можемо величину то користећи промените величину реаллоц функцију,
и ми смо пратили два броја - индекс следећег празан слот у бафер
и дужина или капацитет бафера.
Читамо у цхарс од корисника једном у времену помоћу фгетц функцију.
Тхе аргумент на фгетц функција траје - стдин - је референца на стандардном стринг унос
који је прецоннецтед улазни канал који се користи за пренос улаз корисников
од терминала до програма.
>> Кад год корисник упише у нови лик, ми смо проверили да ли је индекс
од следећег слободног слота, плус 1 је већи од капацитета бафера.
Тхе +1 долази у, јер ако је следећи слободан индекс 5,
Онда је наш Буффер је дужина мора да буде 6 захваљујући 0 индексирање.
Ако смо понестане простора у баферу, онда ћемо покушати да га промените величину,
удвостручење је тако да смо смањи број пута да смо величину
ако корисник куца у заиста дугом низу.
Уколико стринг је стечен предуго или ако понестане хеап меморије,
ослободимо нашу бафер и повратка нулл.
>> Коначно, можемо додати знак у бафер.
Када корисник уђе хитова или вратити, сигнализирајући нову линију,
или специјални карактер - контрола д - који означава крај улаза,
ми чек да видим да ли корисник заиста уписали у било уопште.
Ако не, враћамо нулл.
Иначе, јер наш бафер је вероватно већа него што нам је потребно,
У најгорем случају то је скоро дупло већа од морамо
јер смо два пута сваки пут кад промените величину,
правимо нову копију стринга помоћу само количину простора који нам је потребан.
Ми додајемо додатни 1 до маллоц позив,
тако да постоји простор за специјалне нулте ТЕРМИНАТОР карактера - \ 0,
које смо додати на ниску када смо копирали у осталим ликовима,
коришћењем стрнцпи уместо стрцпи
тако да можемо навести тачно колико слова желимо да копирате.
Стрцпи копира док не удари у \ 0.
Онда смо ослободили наш бафер и враћа копију позиваоца.
>> Ко је знао такав једноставан привидна функција може бити толико компликовано?
Сада знате шта иде у ЦС50 библиотеци.
>> Моје име је Нејт Хардисон, а ово је ЦС50.
[ЦС50.ТВ]