[Powered by Google Translate] [CS50 bibliotēka] [Nate Hardison] [Hārvarda] [Tas ir CS50. CS50.TV] The CS50 bibliotēka ir noderīgs instruments, kas mums ir uzstādītas uz ierīces lai būtu vieglāk, lai jūs varētu rakstīt programmas, kas liks lietotājiem par ieejas. Šajā video, mēs pull atpakaļ aizkaru un apskatīt ko tieši atrodas CS50 bibliotēkā. Šajā video par C bibliotēku, mēs runājam par to, kā jūs # ietvert galvenes faili no bibliotēkas jūsu avota kodu, un tad jūs saistīt ar bināro bibliotēkas failu laikā savieno posmā apkopošanas process. Header failus norādīt interfeisu bibliotēku. Tas ir, tie dati visus resursus, kas bibliotēkā ir pieejami, lai jūs varētu izmantot, piemēram funkciju deklarācijām, konstanšu, un datu tipi. Binārā bibliotēkas fails satur īstenošanu bibliotēkas, kurā tiek apkopota no bibliotēkas header failiem un bibliotēkas. c pirmkods failus. Binārā bibliotēkas fails nav ļoti interesanti aplūkot, jo tas ir, labi, jo bināro. Tātad, pieņemsim apskatīt header failus bibliotēkā vietā. Šajā gadījumā, tur ir tikai viens header failu sauc cs50.h. Mēs esam uzstādītas tā, lai lietotājs ietver direktoriju Kopā ar citiem sistēmu bibliotēku header failus. Viena no pirmajām lietām, jūs ievērosiet, ka cs50.h # ietver header failus no citām bibliotēkām - peldēt, ierobežojumi, standarta bool un standarta lib. Atkal pēc principa ne izgudrot riteni, mēs esam izveidojuši CS0 bibliotēkā, izmantojot rīkus, kas cita paredzētos mums. Nākamā lieta, jūs redzēt bibliotēkā ir, ka mēs definējam jauna veida sauc par "virkne." Šī līnija tiešām tikai rada alias par char * tipa, lai tas nav maģiski piesūcināt jauno stīgu tipu ar atribūtiem parasti tiek saistīts ar stīgu objektiem citās valodās, piemēram, garumu. Iemesls, kāpēc mēs esam darījuši, ir, lai pasargātu jaunos programmētājus no asiņains detaļas gada norādes, līdz tie gatavi. Nākamā daļa no header failu, ir deklarācija par funkcijām ka CS50 bibliotēka nodrošina kopā ar dokumentāciju. Paziņojums precizitātes līmeni komentārus šeit. Tas ir super svarīgi, lai cilvēki zina, kā izmantot šīs funkcijas. Mēs paziņojam, savukārt, darbojas, lai nekavējoties lietotājam un atgriešanās chars, dubultlikmes, pludiņiem, Ints, garš ilgojas, un stīgas, izmantojot mūsu pašu stīgu veidu. Pēc principa informācijas slēpšanās, Mēs esam mūsu definīciju atsevišķā c ieviešanas failu -. cs50.c-- kas atrodas lietotāja avota direktorijā. Mēs esam ja šo failu, lai jūs varētu to apskatīt to, mācīties no tā, un recompile to uz dažādām mašīnām, ja vēlaties, pat ja mēs domāju, ka labāk strādāt uz ierīces šīs klases. Anyway, pieņemsim to apskatīt to tagad. Funkcijas getchar, GetDouble, GetFloat, GetInt, un GetLongLong visas ir būvētas uz augšu GetString funkcijas. Izrādās, ka viņi visi seko būtībā to pašu modeli. Viņi izmanto, kamēr cilpa, lai nekavējoties lietotājam par vienu līniju ievadi. Viņi atgriezīsies īpašu vērtību, ja lietotājs izejvielas tukšu līniju. Viņi mēģinās parsēt lietotāja ievadi kā piemērotu veidu, vai tas būtu palija, dubultā, peldēt, uc Un tad viņi vai nu atgriezties rezultātu, ja ieeja ir veiksmīgi parsēt vai tie reprompt lietotājam. Augstā līmenī, nekas patiešām grūts šeit. Jums varētu būt rakstīts tamlīdzīgos kodu sevi pagātnē. Iespējams, visvairāk noslēpumains izskata daļa ir sscanf zvans, kas parses lietotāja ievadi. Sscanf ir daļa no ieejas formāta konversijas ģimeni. Tā dzīvo standarta io.h, un tās uzdevums ir parsēt C virkni, saskaņā ar īpašu formātu, uzglabāšanu parsēt rezultātus mainīgs sniedz zvanītāja. Tā kā ievades formāts konversijas funkcijas ir ļoti noderīgas, plaši lietotās funkcijas ka nav super intuitīvu sākumā, mēs iet pār to, kā sscanf darbi. Pirmais arguments, lai sscanf ir char * - rādītājs, lai raksturu. Lai funkcija darbotos pareizi, ka raksturs būtu pirmais raksturs ir C virknes, izbeigt ar nulles \ 0 raksturu. Tas ir virkne parsēt Otrs arguments, lai sscanf ir formāta virkne, parasti pieņemts kā string konstantes, un jūs varētu būt redzējis virkni līdzīgu pirms lietojot printf. Procenti zīme formāta virknes norāda konversijas noteicēju. Raksturs uzreiz pēc procentu zīmi, norāda C tipa ka mēs vēlamies sscanf konvertēt uz. Jo GetInt, jūs redzēsiet, ka tur ir% d un% c. Tas nozīmē, ka sscanf mēģinās decimālskaitlis int - Par% D - un char - THE% c. Par katru pārveides apzīmētājs uz formāta virknes, sscanf sagaida atbilstošs arguments vēlāk tās argumentu sarakstā. Šis arguments ir jānorāda uz attiecīgi drukātā vietā , kuros uzglabāt rezultātu pārveidošanu. Tipisks veids, kā to panākt, ir izveidot mainīgo uz skursteņa pirms sscanf zvana par katru posteni, ka jūs vēlaties, lai parsēt no virknes un pēc tam izmantot adrešu operators - zīme & - nodot norādes tiem mainīgie sscanf zvanu. Jūs varat redzēt, ka GetInt mēs darīt tieši to. Tiesības pirms sscanf zvana, mēs paziņojam int sauc n un char zvanu C uz steku, un mums iet norādes uz tām uz sscanf zvanu. Liekot šiem mainīgajiem uz skursteņa ir priekšroka pār izmantojot piešķirto telpu uz kaudzes ar malloc, jo jūs izvairītos pieskaitāmās malloc zvanu, un jums nav jāuztraucas par noplūdi atmiņu. Rakstzīmes nav prefiksu procentu zīmi nevaicāt konversiju. Drīzāk viņi vienkārši pievienot formāta specifikāciju. Piemēram, ja formāta virknes GetInt bija% d vietā, sscanf varētu meklēt burtu A, kam seko int, un kamēr tas varētu mēģināt pārveidot int, tas nav jādara kaut kas cits ar a. Vienīgais izņēmums ir atstarpes. Balta telpa rakstzīmes formāta virknes atbilstu jebkuru summu tukšumiem - pat nav vispār. Tātad, tāpēc komentārs piemin iespējams ar vadošajiem un / vai tukšumus. Tātad, šajā brīdī tas izskatās mūsu sscanf aicinājumu mēģinās parsēt lietotāja ieejas virknes , pārbaudot iespējamo vadošo atstarpi, seko int kas tiks konvertēta un uzglabā int mainīgo n seko kādu summu atstarpes, un seko rakstura uzglabā char mainīgā c. Kas par atgriešanās vērtību? Sscanf parsēt ieejas līniju no sākuma līdz beigām, apstāšanās, kad tā sasniedz beigām vai ja rakstzīmi ievades nesakrīt formāta raksturs vai ja tas nevar veikt konversiju. Tas ir atgriešanās vērtība tiek izmantota, lai izdalīt, kad tas apstājās. Ja tas apstājās, jo tas sasnieguši ieejas virknes Pirms jebkādu konvertēšanu un pirms nespēj saskaņot daļu no formāta virknes, tad īpaša pastāvīga EOF tiek atgriezta. Pretējā gadījumā tas atgriež vairākas veiksmīgas konvertēšanu, kas varētu būt 0, 1, 2 vai, jo mēs esam lūdza divus reklāmguvumiem. Mūsu gadījumā, mēs vēlamies pārliecināties, ka lietotājs ievadījis int un tikai Int. Tātad, mēs vēlamies sscanf atgriezties 1. Redzēt, kāpēc? Ja sscanf atgriezās 0, tad nav pārrēķināšana tika veikta, lai lietotājs drukāti kaut ko citu nekā int sākumā ieejas. Ja sscanf atgriež 2, tad lietotājs nebija pareizi ierakstiet to sākumā ieejas, bet pēc tam viņi drukāti dažās bez atstarpēm raksturs vēlāk kopš% c konversija izdevās. Wow, tas ir diezgan garš skaidrojums par vienu funkciju zvanu. Anyway, ja jūs vēlaties vairāk informācijas par sscanf un tās vecvecākus, izbraukšana cilvēks lapas, google, vai abus. Ir daudz formāta stīgu opcijas, un tie var ietaupīt daudz roku darba, mēģinot apstrādāt virknes C. Galīgo funkcija bibliotēkā apskatīt ir GetString. Izrādās, ka GetString ir grūts uzdevums rakstīt pareizi, pat ja tas šķiet tik vienkāršs, kopīgu uzdevumu. Kāpēc tas notiek? Nu, pieņemsim domāt par to, kā mēs spēsim saglabāt līniju, ka lietotājs iekšā Tā virkne ir secība chars, mēs varētu vēlēties, lai saglabātu to masīvā uz skursteņa, bet mums būtu nepieciešams zināt, cik ilgi masīvs būs, kad mēs par to ziņo. Tāpat, ja mēs gribam, lai tā uz kaudzes, Mums nepieciešams nodot lai malloc baitu skaitu mēs vēlamies, lai rezervē, bet tas ir neiespējami. Mums nav ne jausmas, cik daudz simb lietotājs tips pirms lietotājs faktiski nav rakstīt tos. Naivs risinājums šai problēmai ir tikai rezervēt lielu rieciens vietas, teiksim, bloks 1000 chars uz lietotāja ievadītajiem datiem, pieņemot, ka lietotājs nekad ierakstiet virkni, kas ilgi. Tas ir slikta ideja divu iemeslu dēļ. Pirmkārt, pieņemot, ka lietotāji parasti nav rakstīt stīgas, ka ilgi, jūs varētu atkritumu daudz atmiņas. Uz mūsdienu mašīnām, tas varētu būt jautājums, ja jūs šo vienā vai divos atsevišķos gadījumos, bet, ja jūs lietojat lietotāja ievadi ar cilpu un uzglabāšanai vēlākai izmantošanai, Jūs varat ātri uzsūkt ton atmiņas. Turklāt, ja programma jūs esat rakstiski ir mazāku datoru - ierīci, piemēram, viedtālrunis vai kaut kas cits ar ierobežotu atmiņu - šis risinājums radīs problēmas daudz ātrāk. Otrā, daudz nopietnu iemeslu to darīt, ir, ka tas atstāj savu programmu neaizsargāti , ko sauc bufera pārpildes uzbrukumu. Programmēšanā, buferis ir atmiņas izmanto uz laiku uzglabāt ievades vai izvades datus, kas šajā gadījumā ir mūsu 1000-char bloks. Bufera pārpildes notiek tad, kad dati ir rakstīts pagātnes beigām bloku. Piemēram, ja lietotājs tiešām veidu vairāk nekā 1000 simboli. Jums varētu būt pieredzējuši šo nejauši plānojot ar masīviem. Ja jums ir masīvs 10 Ints, nekas jūs no mēģinot lasīt un rakstīt 15 int. Nav kompilators brīdinājumi vai kļūdas. Programmā tikai Blunders taisni un piekļūst atmiņas ja tā domā 15 int būs, un tas var pārrakstīt savu citi mainīgie. Sliktākajā gadījumā, jūs varat pārrakstīt dažas no jūsu programmas iekšējās kontroles mehānismi, kas izraisa jūsu programmu, lai reāli izpildīt dažādas instrukcijas nekā paredzēts. Tagad, tas nav bieži to darīt nejauši, bet tas ir diezgan izplatīta metode, kas slikti puiši izmanto, lai izjauktu programmas un nodot ļaunprātīgu kodu uz citu cilvēku datoriem. Tāpēc, mēs varam ne tikai izmantot savu naivo risinājumu. Mums ir nepieciešams veids, lai novērstu mūsu programmas no neaizsargāti uz bufera pārpildes uzbrukumu. Lai to izdarītu, mums ir nepieciešams, lai pārliecinātos, ka mūsu bufera var augt kā mēs lasām vairāk ieeja no lietotāja. Risinājums? Mēs izmantojam kaudze piešķirti buferi. Tā kā mēs varam mainīt to, izmantojot mainītu realloc funkciju, un mēs sekot divu skaitļu - indeksu nākamā slotā buferī un garums vai bufera kapacitāte. Mēs lasīt chars no lietotāja pa vienam, izmantojot fgetc funkciju. The argumentu fgetc funkcija tiek - stdin - ir atsauce uz standarta ieejas virkni, kas ir preconnected ieejas kanālu, kas tiek izmantots, lai pārsūtītu lietotāja ievadi no termināla programmu. Ikreiz, kad lietotājs veidiem jaunu raksturu, mēs pārbaudām, ja indekss par nākamo brīvās slota plus 1 ir lielāks nekā spēju bufera. +1 Nāk, jo, ja nākamais bezmaksas indekss ir 5, tad mūsu bufera sistēmas garums jābūt 6 pateicoties 0 indeksācija. Ja mēs esam pietrūkt vietas buferī, tad mēs mēģināsim, lai mainītu to, dubultojot to tā, ka mēs samazināt par to, cik reizes mēs mainīt ja lietotājs ir rakstīt patiešām ilgu virknes. Ja virkne ir gotten pārāk ilgi, vai ja mēs izsīkšanai kaudze atmiņas, mēs atbrīvotu mūsu buferis un atgriezties null. Visbeidzot, mēs pievienot char uz bufera. Kad lietotājs hits ienākt vai atgriezties, signalizē par jaunu līniju, vai īpašu CHAR - kontrole d - kas liecina galu ievadi, mēs pārbaudi, lai redzētu, ja lietotājs faktiski drukāti neko. Ja ne, mēs atgriežamies null. Citādi, jo mūsu buferis ir iespējams lielāks nekā mums vajag, sliktākajā gadījumā tas ir gandrīz divas reizes lielāka kā mums vajag jo mēs divreiz katru reizi, kad mēs mainīt izmērus, mēs jaunu kopiju virknes, izmantojot tikai vietas daudzumu, kas mums ir nepieciešams. Mēs pievienot papildu 1 līdz malloc zvanu, tāpēc, ka tur ir vietas īpašo null terminatora raksturs - \ 0, kas mums pievienot uz virkni reiz mēs kopēt pārējās rakstzīmes, izmantojot strncpy nevis strcpy lai mēs varētu precīzi norādīt, cik daudz simb mēs vēlamies, lai kopētu. Strcpy kopē līdz tas hits \ 0. Tad mēs atbrīvotu mūsu buferis un eksemplāru atdod atpakaļ zvanītāju. Kurš zināja šāda vienkārša-šķietams funkciju varētu tik sarežģīti? Tagad jūs zināt, kas iet uz CS50 bibliotēkā. Mans vārds ir Nate Hardison, un tas ir CS50. [CS50.TV]