[Powered by Google Translate] [CS50 библиотека]
[Нејт Hardison] [Универзитетот Харвард]
[Ова е CS50. CS50.TV]
Во библиотеката CS50 е корисна алатка која ние инсталиран на уредот
да се направи полесно за вас да пишуваат програми кои брза корисници за влез.
Во ова видео, ќе се повлечат завесата и се погледне во што точно е во CS50 библиотека.
>> Во видео на C библиотеки, ние зборуваме за тоа како можете # вклучуваат заглавија датотеки
на библиотеката во вашиот изворен код,
а потоа ќе се поврзе со бинарен библиотека датотеката во текот на поврзување фаза
на компилацијата процес.
Насловот датотеки наведете интерфејс на библиотеката.
Тоа е, тие детално сите ресурси кои библиотеката има на располагање за да го користиш,
како функција декларации, константи, и типови на податоци.
На бинарни библиотека датотека содржи спроведувањето на библиотеката,
која е составена од насловот датотеки на библиотеката и на библиотеката. Со изворниот код датотеки.
>> На бинарни библиотека датотека не е многу интересно да се погледне, бидејќи тоа е, добро, во бинарна.
Значи, ајде да ги разгледаме во насловот датотеки за библиотеката наместо тоа.
Во овој случај, има само еден хедер датотека наречена cs50.h.
Ние го инсталирани во на корисникот вклучуваат директориум
заедно со насловот датотеки на други системски библиотеки.
>> Една од првите работи што ќе забележите е дека cs50.h # вклучува насловот датотеки од други библиотеки -
плови, граници, стандард bool, и стандардни lib.
Повторно, по принципот на не reinventing на тркалото,
ние сме изградиле CS0 библиотека користење алатки кои други предвидени за нас.
>> Следното нешто што ќе видите во библиотеката е дека ние се дефинира нов вид наречен "стринг."
Оваа линија навистина само создава алијас за char * тип,
па тоа не магично насаждам новиот стринг тип со атрибути
обично се поврзуваат со низа објекти во други јазици,
како што се должината.
Причината ние го направивме ова е да се заштити нови програмери од крвави детали
на покажувачи се додека не завршиш.
>> Следниот дел од хедер датотека е декларацијата на функции
дека CS50 библиотека обезбедува заедно со документација.
Обрнете внимание на нивото на детали во коментари тука.
Ова е супер важно, така што луѓето знаат како да ги користат овие функции.
Изјавуваме, пак, функционира за да го извести корисникот и враќање карактери, двојки, плови, ints,
долго копнее, и стрингови, користејќи свој стринг тип.
По принципот на информации крие,
имаме стави нашата дефиниција во посебен в имплементација датотека -. cs50.c--
се наоѓа во на корисникот изворниот директориум.
Ние сме под услов датотека, па можете да ги погледне во него,
учат од неа, и прекомпајлирате тоа на различни машини ако сакате,
иако ние мислиме дека е подобро да се работи на апаратот за оваа класа.
Како и да е, ајде да ги разгледаме во тоа сега.
>> Функциите GetChar, GetDouble, GetFloat, GetInt и GetLongLong
сите се изградени на врвот на GetString функција.
Се испоставува дека сите тие следат истите шема.
Тие ги користат додека јамка за да го извести корисникот за една линија на влез.
Ќе се вратат посебна вредност, ако на корисникот влезови празна линија.
Тие се обидуваат да го анализирам влез на корисникот како соодветен вид,
било да е тоа знак, двојно, плови, итн
А потоа тие или врати резултатот ако влезот е успешно разложени
или тие reprompt на корисникот.
>> На високо ниво, не постои ништо навистина незгодно тука.
Може да го имаат напишано слично структурирани кодот себе во минатото.
Можеби повеќето криптичната изглед дел е sscanf повик дека parses влез на корисникот.
Sscanf е дел од внесување формат конверзија семејство.
Таа живее во стандард io.h, а неговата работа е да го анализирам низа Ц,
според одреден формат, чување анализирам резултати во променлива
обезбедени од страна на повикувачот.
Од влез формат конверзија функции се многу корисни, широко користените функции
кои не се супер интуитивен во прв,
ќе одиме околу тоа како sscanf работи.
>> Првиот аргумент да sscanf е char * - покажувач кон карактер.
За функцијата за да работи правилно,
дека карактерот треба да биде првиот карактер на стрингот Ц,
престанува со нула \ 0 карактер.
Ова е стринг за да се анализира
Вториот аргумент да sscanf е формат стринг,
обично донесен во како стринг константа,
и може да се гледа низа како тоа порано кога користите printf.
А знакот за процент во формат стринг укажува на конверзија назначувач.
Ликот веднаш по знакот за процент,
укажува на типот Ц што сакаме sscanf да го конвертирате во.
Во GetInt, ќе видите дека има% d и% c.
Ова значи дека sscanf ќе се обиде да една децимална int -% d - и знак - на% c.
За секоја пренамена назначувач во формат стринг,
sscanf очекува соодветен аргумент подоцна во својот аргумент листа.
Тој аргумент да се укаже на соодветно внесе локација
во која за чување резултат на реализација.
>> Типичен начин за тоа е да се создаде променлива на магацинот пред повикот sscanf
за секоја ставка што сакате да го анализирам од низа
и потоа користете адреса оператор - на симболот - да помине совети
на овие променливи на повикот sscanf.
Можете да видите дека во GetInt правиме токму тоа.
Непосредно пред повикот sscanf, ние прогласи int нарекува n и знак повик в на магацинот,
и ние помине совети како да ги во повикот sscanf.
Ставањето на овие променливи на магацинот се препорачува пред користење на просторот распределени
на грамада со Примерок, бидејќи ќе се избегне над глава на Примерок повик,
а вие не мора да се грижите за протекување меморија.
Знаци не префикс знакот за процент не поттикне реализација.
А тие само го додадете во формат спецификација.
>> На пример, ако формат стринг во GetInt беа% d наместо тоа,
sscanf ќе изгледа за писмо проследено со int,
и додека тоа ќе се обиде да го конвертирате int, тоа не би сторил ништо друго со еден.
Единствен исклучок на ова е празни места.
Белата простор на знаци во формат стринг одговара на ниеден количината на празни места -
дури нема воопшто.
Значи, тоа е зошто коментар споменува евентуално со водечките и / или Аргументот.
Значи, во овој момент изгледа нашата sscanf повик ќе се обиде да го анализирам внесување гудачки на корисникот
со проверка за можни водечки празни места,
проследено со int кој ќе се конвертира и се чуваат во int променлива n
проследено со некои количината на празни места, и по карактер
чуваат во знак променлива в.
>> Што е повратната вредност?
Sscanf ќе го анализира влезни линија од почеток до крај,
запирање кога го достигне крајот или кога некој лик во влез
не се поклопува формат карактер или кога тоа не може да се направи конверзија.
Тоа е повратната вредност се користи за да издвојат кога тој престана.
Ако го запре, бидејќи до крајот на внесување гудачки
пред да направите било конверзии и пред неуспехот да одговара на дел од формат стринг,
тогаш специјален постојан EOF се враќа.
Во спротивно, го враќа бројот на успешни имплементацијата,
која може да биде 0, 1 или 2, бидејќи ние сме праша за две конверзии.
Во нашиот случај, ние сакаме да се осигураме дека корисникот ја внеле во int и само int.
>> Значи, ние сакаме sscanf да се врати 1. Погледнете зошто?
Ако sscanf врати 0, тогаш нема конверзии биле направени,
па така корисниците внеле нешто друго од int на почетокот на влез.
Ако sscanf враќа 2, тогаш корисникот не правилно да го напишете во почетокот на влез,
но тие потоа ја внеле во некои карактер не-празни места потоа
од% c конверзија успеа.
Леле, тоа е прилично долга објаснување за еден повик на функција.
Впрочем, ако сакате повеќе информации за sscanf и нејзините браќа и сестри,
проверете на човекот страници, Гугл, или и двете.
Постојат многу формат низа опции,
и овие може да ве спаси многу физичка работа, кога се обидуваат да го анализирам жици во C.
>> Конечниот функција во библиотеката да се погледне е GetString.
Излегува дека GetString е слабо функција да се напише правилно,
иако ми се чини дека таквата едноставна, заедничка задача.
Зошто е тоа така?
Па, ајде да размислиме за тоа како ние ќе ја зачувате линијата која на корисникот видови внатре
Од низа е низа од карактери,
ние можеби ќе сакате да се чува во низа на магацинот,
но ние ќе треба да се знае колку долго низа ќе биде кога ќе се изјасни.
Исто така, ако сакаме да го стави на куп,
ние треба да помине Примерок бројот на бајти сакаме да ги резервирате,
но тоа е невозможно.
Ние немаме идеја како многу знаци на корисникот ќе тип во
пред корисникот всушност не ги напишете.
>> А наивниот решение за овој проблем е само да резервирам голем дел од просторот, да речеме,
блок од 1000 карактери за внесување на корисникот,
претпоставувајќи дека корисникот никогаш не би тип во низа која долго време.
Ова е лоша идеја за две причини.
Прво, претпоставувајќи дека корисниците обично не напишете стрингови кои долго,
можете да отпад многу меморија.
На современи машини, ова не може да биде проблем ако го направите тоа
во една или две изолирани случаи,
но ако сте земајќи влез корисникот во јамка и чување за подоцнежна употреба,
ќе можете брзо да си го цица до еден тон на меморија.
Покрај тоа, ако програмата сте пишување е за помал компјутер -
уред како паметен телефон или нешто друго со ограничена меморија -
ова решение ќе предизвика проблеми многу побрзо.
Вториот, посериозни причина да не го направите ова е дека тоа остава вашата програма ранливи
на она што се нарекува buffer overflow напад.
Во програмирање, тампон е меморијата се користи за привремено чување влез или излез на податоци,
кој во овој случај е нашата 1000-знак блок.
А buffer overflow се случува кога податоците се напишани изминатите крајот на блок.
>> На пример, ако корисникот всушност не тип во повеќе од 1000 карактери.
Може да ги искусиле ова случајно кога програмирање со низи.
Ако имате низа од 10 ints, ништо не ви запира од обидот да се прочита или запише
15 int.
Нема компајлерот предупредувања или грешки.
Програмата исто грешки право напред и пристапи на меморија
каде што смета дека 15 int ќе биде, а тоа може да го изгубите Вашиот другите варијабли.
Во најлош случај, може да се запише некои од внатрешните вашата програма
контролни механизми, предизвикувајќи вашиот програмата за всушност извршување различни инструкции
отколку што се наменети.
>> Сега, тоа не е заеднички да го направите ова случајно,
но ова е прилично заеднички техника која лошите момци го користите да се пробие програми
и го стави малициозен код на компјутери на други луѓе.
Затоа, ние не може само да ги користат нашите наивни решение.
Ние треба начин да се спречат нашите програми од се ранливи
на buffer overflow напад.
За да го направите ова, ние треба да бидете сигурни дека нашите тампон може да расте како што се чита
повеќе влез од корисникот.
Решението? Ние ги користиме на грамада распределени тампон.
Бидејќи можеме да големината на тоа со помош на големината на realloc функција,
и ние ги пратите на два броја - индексот на следната празен слот во тампон
и должината или капацитетот на тампон.
Читаме во карактери од корисникот едно по едно време со користење на fgetc функција.
Аргументот на fgetc функција потребно - stdin - е повикување на стандарден влез стринг,
која е preconnected внесување на канал кој се користи за пренос на внесување на корисникот
од терминалот на програмата.
>> Секогаш кога корисник видови во нов лик, ние се провери да се види дали на индексот
на следниот слободен слот плус 1 е поголем од капацитетот на тампон.
На 1 доаѓа во затоа што ако следниот слободен индекс е 5,
тогаш должината нашите тампон мора да биде 6 благодарение 0 индексирање.
Ако ние сме снема простор во тампон, а потоа ќе се обиде да ја промени големината,
удвојување на тоа, така што можеме да го намали бројот на пати, што ние ја промените големината
ако корисникот пишува во едно навистина долга низа.
Ако стрингот има добивано и премногу долго или ако снема на грамада меморија,
ние ослободи нашите тампон и враќање нула.
>> Конечно, ние додаваат знак на тампон.
Откако на корисникот хитови влезат или да се вратат, сигнализирајќи нова линија,
или посебен знак - контрола г - кој сигнализира крајот на влез,
ние направи проверка за да види дали на корисникот всушност ја внеле во нешто во сите.
Ако не, ќе се вратиме нула.
Инаку, бидејќи нашите тампон е веројатно поголема отколку што треба,
во најлош случај тоа е речиси двапати поголем како што треба
бидејќи ние двојно секој пат кога големината,
правиме нова копија на стринг со користење само на износот на просторот што ни е потребно.
Ние додаваме дополнителни 1 до Примерок повик,
така што има простор за специјални null терминаторот карактер - на \ 0,
кои додаваат до низа еднаш сме го копирате во остатокот од ликовите,
користење strncpy наместо strcpy
така што може да се определи точно колку карактери сакаме да го копирате.
Strcpy копии, додека таа хитови \ 0.
Тогаш ние ослободи нашите тампон и се врати на копија на повикувачот.
>> Кој не знаеше како едноставна-навидум функција може да биде толку комплицирано?
Сега знаеш што оди во CS50 библиотека.
>> Моето име е Нејт Hardison, и ова е CS50.
[CS50.TV]