[Powered by Google Translate] [CS50 Llyfrgell] [Nate Hardison] [Harvard University] [Mae hyn yn CS50. CS50.TV] Mae'r llyfrgell CS50 yn offeryn buddiol yr ydym wedi'u gosod ar y peiriant i'w gwneud yn haws i chi i ysgrifennu rhaglenni bod defnyddwyr yn brydlon ar gyfer mewnbwn. Yn y fideo, byddwn yn tynnu yn ôl y llenni ac edrych ar beth yn union sydd yn y llyfrgell CS50. Yn y fideo ar lyfrgelloedd C, rydym yn siarad am sut yr ydych # cynnwys ffeiliau penawdau y llyfrgell yn eich cod ffynhonnell, ac yna rydych yn cysylltu gyda ffeil ddeuaidd llyfrgell yn ystod y cyfnod cysylltu o'r broses casglu. Mae'r ffeiliau pennawd yn nodi y rhyngwyneb y llyfrgell. Hynny yw, maent yn manylu ar yr holl o'r adnoddau sydd gan y llyfrgell ar gael i chi eu defnyddio, fel datganiadau swyddogaeth, cysonion, a mathau o ddata. Mae'r ffeil ddeuaidd llyfrgell yn cynnwys gweithrediad y llyfrgell, sy'n cael ei lunio o ffeiliau pennawd y llyfrgell a'r llyfrgell. c ffeiliau cod ffynhonnell. Nid yw'r ffeil ddeuaidd llyfrgell yn ddiddorol iawn i edrych ar gan ei fod yn, wel, yn deuaidd. Felly, gadewch i ni edrych ar y ffeiliau pennawd ar gyfer y llyfrgell yn lle hynny. Yn yr achos hwn, dim ond un ffeil pennawd enw cs50.h. Rydym wedi gosod yn y cyfeiriadur defnyddiwr yn cynnwys ynghyd â ffeiliau pennawd llyfrgelloedd system arall '. Un o'r pethau cyntaf y byddwch yn sylwi arno yw fod cs50.h # yn cynnwys ffeiliau pennawd o lyfrgelloedd eraill - arnofio, terfynau, safon bool, a lib safonol. Unwaith eto, yn dilyn yr egwyddor o beidio â ailddyfeisio'r olwyn, rydym wedi adeiladu y llyfrgell CS0 defnyddio offer sy'n eraill a ddarperir i ni. Y peth nesaf y byddwch yn gweld yn y llyfrgell yw ein bod yn diffinio math newydd o'r enw "llinyn." Mae'r llinell hon yn wir yn unig yn creu alias ar gyfer y math * torgoch, felly nid yw'n sydyn yn trwytho yn y math llinyn newydd gyda nodweddion gysylltiedig yn aml â gwrthrychau llinyn mewn ieithoedd eraill, megis hyd. Y rheswm rydym wedi gwneud hyn yw i darian rhaglenwyr newydd o'r manylion gwaedlyd o arwyddion nes eu bod yn barod. Mae rhan nesaf y ffeil pennawd yn y datganiad o swyddogaethau bod y llyfrgell yn darparu CS50 ynghyd â dogfennau. Sylwch ar y lefel o fanylder yn y sylwadau yma. Mae hyn yn super bwysig fel bod pobl yn gwybod sut i ddefnyddio swyddogaethau hyn. Yr ydym yn datgan, yn ei dro, swyddogaethau i annog y defnyddiwr a chars dychwelyd, dyblau, arnofio, ints, hir hiraethu, a llinynnau, gan ddefnyddio ein math llinyn hunain. Dilyn yr egwyddor o cuddio gwybodaeth, rydym wedi rhoi ein diffiniad yn ar wahân ffeil gweithredu c -. cs50.c-- lleoli yn y ffynhonnell defnyddiwr cyfeiriadur. Rydym wedi darparu y ffeil fel y gallwch fwrw golwg arno, dysgu oddi wrtho, ac yn ail-grynhoi ar beiriannau gwahanol os ydych yn dymuno, er ein bod yn meddwl ei bod yn well i weithio ar y peiriant ar gyfer y dosbarth. Beth bynnag, gadewch i ni edrych arno yn awr. Mae'r swyddogaethau GetChar, GetDouble, GetFloat, GetInt, a GetLongLong yn cael eu hadeiladu i gyd ar ben y swyddogaeth GetString. Mae'n troi allan eu bod i gyd yn dilyn y bôn yr un patrwm. Maent yn defnyddio dolen amser i annog y defnyddiwr i un llinell o fewnbwn. Maent yn dychwelyd gwerth arbennig os yw'r defnyddiwr mewnbynnau llinell wag. Maent yn ceisio gramadegu mewnbwn y defnyddiwr fel y math priodol, boed yn torgoch, a dwbl, arnofio, ac ati Ac yna maent yn naill ai ddychwelyd y canlyniad os y mewnbwn cael ei dosrannu yn llwyddiannus neu maent yn reprompt y defnyddiwr. Ar lefel uchel, nid oes dim anodd iawn eu datrys yma. Efallai eich bod wedi ysgrifennu cod yn yr un modd strwythuredig eich hun yn y gorffennol. Efallai mai'r rhan mwyaf cryptig-edrych yw'r alwad sscanf sy'n parses fewnbwn y defnyddiwr. Sscanf yn rhan o'r teulu trosi fformat mewnbwn. Mae'n byw yn safon io.h, ac mae ei gwaith yw dosrannu yn llinyn C, yn ôl fformat penodol, storio y canlyniadau gramadegu yn amrywio a ddarperir gan y galwr. Ers y mewnbwn swyddogaethau fformat trosi yn ddefnyddiol iawn, swyddogaethau a ddefnyddir yn eang nad ydynt yn super 'n athrylithgar ar y dechrau, byddwn yn mynd dros y ffordd y sscanf yn gweithio. Mae'r ddadl gyntaf i sscanf yn * torgoch - pwyntydd i gymeriad. Ar gyfer y swyddogaeth i weithio'n iawn, dylai cymeriad fod y nod cyntaf mewn llinyn C, derfynu gyda'r null \ 0 cymeriad. Mae hyn yn y llinyn i dosrannu Yr ail ddadl i sscanf yn llinyn fformat, pasio fel arfer yn gyson fel llinyn, ac efallai y byddwch wedi gweld llinyn fel hyn o'r blaen wrth ddefnyddio printf. Mae arwydd y cant yn y llinyn fformat yn dangos rhagnodwr trosi. Mae cymeriad yn syth ar ôl arwydd y cant, yn dangos y math C yr ydym am sscanf i drosi i. Yn GetInt, byddwch yn gweld bod yna d% a% c. Mae hyn yn golygu y bydd sscanf ceisio i int degol - y d% - a golosg - y c%. Ar gyfer pob rhagnodwr trosi yn y llinyn fformat, sscanf yn disgwyl dadl cyfatebol yn ddiweddarach yn ei restr ddadl. Rhaid i'r ddadl bwyntio at leoliad priodol deipio lle i storio canlyniad y trawsnewid. Y ffordd nodweddiadol o wneud hyn yw i greu newidyn ar y simnai cyn i'r alwad sscanf ar gyfer pob eitem yr ydych am ei gramadegu o'r llinyn ac yna defnyddiwch y gweithredwr cyfeiriad - y ampersand - i basio awgrymiadau i'r rhai newidynnau i'r alwad sscanf. Gallwch weld bod GetInt rydym yn ei wneud yn union hynny. Hawl cyn i'r alwad sscanf, rydym yn datgan int o'r enw n a c galwad torgoch ar y simnai, ac rydym yn pasio awgrymiadau iddynt i mewn i'r alwad sscanf. Rhoi newidynnau hyn ar y pentwr yn cael ei ffafrio dros ddefnyddio gofod a ddyrannwyd ar y domen gyda malloc, ers i chi osgoi'r uwchben yr alwad malloc, ac nid oes rhaid i chi boeni am gollwng cof. Nid yw Cymeriadau nad rhagddodi gan arwydd y cant yn annog trosi. Yn hytrach maent ond yn ychwanegu at y fanyleb fformat. Er enghraifft, os yw'r llinyn fformat GetInt oedd d% yn lle hynny, Byddai sscanf chwilio am y llythyr a ddilynir gan int, ac er y byddai'n ymdrechu i drawsnewid y int, ni fyddai'n gwneud unrhyw beth arall gyda'r a. Yr unig eithriad i hyn yw gofod. Cymeriadau gofod gwyn yn y llinyn fformat yn cyd-fynd unrhyw swm o whitespace - hyd yn oed ddim o gwbl. Felly, dyna pam y sylw yn sôn o bosibl arwain a / neu llusgo whitespace. Felly, bydd ar y pwynt hwn mae'n edrych fel ein galwad sscanf ceisio gramadegu llinyn mewnbwn y defnyddiwr drwy edrych am blaenllaw posibl gofod, wedi'i ddilyn gan int fydd yn cael ei drosi a'i storio mewn amrywiol int y n dilyn gan rai faint o gofod, a ddilynir gan gymeriad storio yn y c amrywiol torgoch. Beth am y gwerth dychwelyd? Bydd Sscanf dosrannu'r llinell mewnbwn o'r dechrau i'r diwedd, rhoi'r gorau pan fydd yn cyrraedd y diwedd neu pan fydd cymeriad yn y mewnbwn yn cyfateb cymeriad fformat neu pan na all wneud trosi. Gwerth dychwelyd Mae'n cael ei ddefnyddio i ddadlau pryd y rhoes heibio. Os caiff ei stopio, oherwydd ei fod yn cyrraedd diwedd y llinyn mewnbwn cyn gwneud unrhyw addasiadau a chyn methu i gyd-fynd yn rhan o'r llinyn fformat, yna bydd y EOF cyson arbennig yn cael ei ddychwelyd. Fel arall, mae'n dychwelyd y nifer o addasiadau llwyddiannus, a allai fod yn 0, 1, neu 2, gan ein bod wedi gofyn am ddau drosiad. Yn ein hachos ni, rydym eisiau gwneud yn siŵr bod y defnyddiwr deipio mewn int a dim ond int. Felly, rydym am sscanf i ddychwelyd 1. Gweler pam? Os sscanf dychwelyd 0, yna nid oes addasiadau yn cael eu gwneud, felly mae'r defnyddiwr deipio rhywbeth ar wahân i int ar ddechrau'r mewnbwn. Os sscanf yn dychwelyd 2, yna bydd y defnyddiwr yn briodol ei deipio i mewn ar ddechrau'r mewnbwn, ond maent yn teipio ac yna mewn rhyw nodwedd di-nod gofod wedyn ers y% llwyddo c trosi. Wow, mae hynny'n dipyn o esboniad hir am un alwad swyddogaeth. Beth bynnag, os ydych am fwy o wybodaeth am sscanf a'i brodyr a chwiorydd, edrychwch ar y tudalennau dyn, Google, neu'r ddau. Mae llawer o opsiynau llinyn fformat, a gall y rhain arbed llawer o lafur llaw wrth geisio gramadegu llinynnau yn C. Mae'r swyddogaeth olaf yn y llyfrgell i edrych arno yw GetString. Mae'n troi allan y GetString yn swyddogaeth anodd i ysgrifennu'n iawn, er ei fod yn ymddangos fel y fath syml, tasg gyffredin. Pam mae hyn yn wir? Wel, gadewch i ni feddwl am sut rydym yn mynd i storio y llinell y mae'r defnyddiwr mathau mewn Gan fod llinyn yn ddilyniant o chars, efallai y byddwn eisiau ei storio mewn arae ar y simnai, ond byddai angen i ni wybod pa mor hir y casgliad yn mynd i fod pan fyddwn yn datgan ei. Yn yr un modd, os ydym am ei roi ar y domen, angen i ni roi i malloc y nifer o bytes ydym am i gronfa wrth gefn, ond mae hyn yn amhosibl. Nid oes gennym unrhyw syniad faint o chars bydd y defnyddiwr deipio i mewn cyn i'r defnyddiwr mewn gwirionedd yn eu teipio. Mae ateb naïf i'r broblem hon ydy at jyst cadw darn mawr o ofod, yn dweud, bloc o 1000 chars ar gyfer mewnbwn y defnyddiwr, gan dybio na fyddai byth y defnyddiwr deipio llinyn sy'n hir. Mae hwn yn syniad gwael am ddau reswm. Yn gyntaf, gan dybio bod defnyddwyr nad ydynt fel arfer yn teipio mewn llinynnau hynny hir, gallech wastraffu llawer o gof. Ar beiriannau modern, efallai na fydd hyn fod yn broblem os byddwch yn gwneud hyn mewn un neu ddau o achosion ynysig, ond os ydych yn cymryd mewnbwn defnyddiwr mewn cylch a storio ar gyfer defnydd yn ddiweddarach, gallwch chi yn gyflym sugno i fyny tunnell o gof. Yn ogystal, os bydd y rhaglen ydych yn ysgrifennu ar gyfer cyfrifiadur llai - dyfais fel smartphone neu rywbeth arall gyda cof cyfyngedig - Bydd yr ateb hwn yn achosi problemau yn llawer cyflymach. Yr ail, rheswm mwy difrifol i beidio â gwneud hyn yw ei fod yn gadael eich rhaglen sy'n agored i niwed i hyn a elwir yn byffer ymosodiad gorlifo. Mewn rhaglennu, byffer o gof a ddefnyddir i storio dros dro data mewnbwn neu allbwn, sydd yn yr achos hwn yw ein 1000-torgoch bloc. Mae gorlif byffer yn digwydd pan fydd data yn cael ei ysgrifennu ar ôl diwedd y bloc. Er enghraifft, os yw defnyddiwr yn ei wneud fath mewn mwy na 1000 o chars. Efallai eich bod wedi cael profiad o hyn yn ddamweiniol wrth raglennu gyda arrays. Os oes gennych amrywiaeth o 10 ints, nid oes dim yn eich atal rhag ceisio i ddarllen neu ysgrifennu y int 15fed. Nid oes unrhyw rybuddion compiler neu wallau. Mae'r rhaglen yn unig blunders yn syth ymlaen ac yn cael gafael cof lle mae'n credu y bydd y int 15 fod, a gall hyn trosysgrifo eich newidynnau eraill. Yn yr achos gwaethaf, gallwch trosysgrifo rhai mewnol fydd eich rhaglen mecanweithiau rheoli, gan achosi eich rhaglen i mewn gwirionedd yn gweithredu cyfarwyddiadau gwahanol nag oeddech yn bwriadu. Nawr, nid yw'n gyffredin i wneud hyn yn ddamweiniol, ond mae hyn yn dechneg eithaf cyffredin sy'n guys ddrwg yn eu defnyddio i dorri rhaglenni a rhoi côd maleisus ar gyfrifiaduron pobl eraill. Felly, ni allwn ddefnyddio dim ond ein ateb naïf. Rydym angen ffordd i atal ein rhaglenni o fod yn agored i niwed i byffer ymosodiad gorlifo. I wneud hyn, mae angen i ni wneud yn siŵr y gall ein byffer dyfu wrth i ni ddarllen mwy o fewnbwn gan y defnyddiwr. Yr ateb? Rydym yn defnyddio tomen glustog a ddyrannwyd. Ers y gallwn newid maint gan ddefnyddio'r resize swyddogaeth realloc, ac rydym yn cadw golwg ar ddau rif - y mynegai y slot gwag nesaf yn y byffer a hyd neu allu y byffer. Rydym yn darllen yn chars gan y defnyddiwr un ar y tro gan ddefnyddio'r swyddogaeth fgetc. Mae'r ddadl y swyddogaeth fgetc cymryd - stdin - yn gyfeiriad at y llinyn mewnbwn safonol, sydd yn sianel mewnbwn preconnected sy'n cael ei ddefnyddio i drosglwyddo cyfraniad y defnyddiwr oddi wrth y derfynell i'r rhaglen. Pryd bynnag y defnyddiwr mathau mewn cymeriad newydd, rydym yn gwirio i weld a yw'r mynegai y slot rhad ac am ddim nesaf ac 1 yn fwy nag y gall y byffer. Mae'r 1 yn dod i mewn oherwydd os bydd y mynegai rhad ac am ddim nesaf yw 5, yna mae'n rhaid i hyd ein byffer fod yn 6 Diolch i 0 mynegeio. Os ydym wedi rhedeg allan o le yn y byffer, yna rydym yn ceisio newid maint iddo, dyblu fel bod rydym yn torri i lawr ar y nifer o weithiau ein bod yn newid maint os yw'r defnyddiwr yn teipio mewn llinyn hir iawn. Os yw'r llinyn wedi gotten yn rhy hir, neu os ydym yn rhedeg allan o gof domen, ein rhyddhau ein clustogi a null dychwelyd. Yn olaf, rydym yn atodi y torgoch at y byffer. Unwaith y bydd y hits defnyddiwr fynd i mewn neu ddychwelyd, gan nodi llinell newydd, neu 'r torgoch arbennig - rheoli d - sy'n arwydd o ddiwedd y mewnbwn, rydym yn ei wneud gwiriad i weld os yw'r defnyddiwr yn teipio mewn gwirionedd yn unrhyw beth o gwbl. Os na, byddwn yn dychwelyd null. Fel arall, oherwydd ein byffer yn ôl pob tebyg yn fwy nag sydd ei angen, yn yr achos gwaethaf ei fod bron ddwywaith mor fawr gan fod angen ers i ni ddyblu bob tro y byddwn yn newid maint, rydym yn gwneud copi newydd o'r llinyn gan ddefnyddio dim ond faint o le sydd ei angen arnom. Rydym yn ychwanegu 1 yn ychwanegol i'r alwad malloc, fel bod o le ar gyfer y cymeriad terminator arbennig null - y \ 0, yr ydym yn atodi i'r llinyn ar ôl i ni eu copïo yng ngweddill y cymeriadau, defnyddio strncpy yn hytrach na strcpy fel y gallwn nodi yn union faint o chars ydym yn awyddus i'w efelychu. Strcpy copļau nes ei fod yn taro \ 0. Yna, rydym yn rhyddhau ein clustogi a dychwelyd y copi i'r galwr. Pwy sy'n gwybod y gallai swyddogaeth o'r fath syml-ymddangosiadol fod yn gymhleth felly? Nawr eich bod yn gwybod beth sy'n mynd i mewn i'r llyfrgell CS50. Fy enw i yw Nate Hardison, ac mae hyn yn CS50. [CS50.TV]