[Powered by Google Translate] [CS50 Maktaba]
[Nate Hardison] [Chuo Kikuu cha Harvard]
[Hii ni CS50. CS50.TV]
Maktaba CS50 ni chombo inasaidia kwamba sisi kuwa imewekwa juu ya appliance
ili iwe rahisi kwa wewe kuandika mipango ya haraka kwa watumiaji wa pembejeo.
Katika video hii, tutaweza kuvuta nyuma ya pazia na kuangalia nini hasa ni katika maktaba CS50.
>> Katika video ya maktaba C, sisi majadiliano kuhusu jinsi wewe ni pamoja na files # headers
ya maktaba katika chanzo code yako,
na kisha wewe zilizounganishwa na faili binary maktaba wakati wa awamu ya kuunganisha
ya mchakato wa kutungwa.
files header bayana interface ya maktaba.
Hiyo ni, wao undani yote ya rasilimali kwamba maktaba ina inapatikana kwa wewe kutumia,
kama kazi maazimio, constants, na aina ya data.
binary maktaba faili ina utekelezaji wa maktaba,
ambayo ni compiled kutoka files maktaba header na wa maktaba. c chanzo code files.
>> binary maktaba faili si ya kuvutia sana kuangalia tangu ni vizuri, katika binary.
Kwa hivyo, hebu tuangalie files header kwa ajili ya maktaba badala yake.
Katika kesi hiyo, kuna moja tu header faili inayoitwa cs50.h.
Tumekuwa imewekwa katika user ni pamoja saraka
pamoja na header mengine mfumo maktaba 'files.
>> Moja ya mambo ya kwanza utasikia taarifa ni kwamba cs50.h # inajumuisha faili header kutoka maktaba nyingine -
kuelea, mipaka, kiwango bool, na lib standard.
Tena, kufuatia kanuni ya si reinventing gurudumu,
tumekuwa kujengwa maktaba CS0 kutumia zana nyingine zinazotolewa kwa ajili yetu.
>> Jambo la pili utaona katika maktaba ni kwamba sisi kufafanua aina mpya inayoitwa "kamba."
Mstari huu kweli tu inajenga pak kwa ajili ya aina Char *,
hivyo hana magically imbue mpya string aina na sifa
huhusishwa na vitu string katika lugha nyingine,
kama vile urefu.
sababu tumefanya hii ni ngao programmers mpya kutoka maelezo gory
ya kuyatumia mpaka wao uko tayari.
>> sehemu ya pili ya faili header ni tangazo la kazi
kwamba maktaba CS50 hutoa pamoja na nyaraka.
Angalia kiwango cha zaidi katika maoni hapa.
Hii ni super muhimu ili watu kujua jinsi ya kutumia kazi hizi.
Tunatangaza, kwa upande wake, kazi kwa haraka na mtumiaji chars kurudi DOUBLES, ikifungwa, ints,
muda mrefu hutamani, na masharti, kwa kutumia kamba yetu wenyewe aina.
Kufuatia kanuni ya mafichoni habari,
sisi kuweka ufafanuzi wetu katika faili tofauti c utekelezaji -. cs50.c--
iko katika saraka chanzo mtumiaji.
Tumekuwa zinazotolewa kwamba faili ili uweze kuangalia ni,
kujifunza kutoka hayo, na recompile kwenye mashine mbalimbali kama unataka,
ingawa sisi nadhani ni bora kufanya kazi katika appliance darasa hili.
Anyway, hebu kuangalia ni sasa.
>> kazi GetChar, GetDouble, GetFloat, GetInt, na GetLongLong
wote umejengwa juu ya kazi GetString.
Ni zinageuka kuwa wao wote kufuata kimsingi mfano huo.
Wao kutumia kitanzi wakati kuchochea mtumiaji kwa mstari mmoja wa pembejeo.
Wao hurudi thamani maalum kama mtumiaji pembejeo line tupu.
Wao kujaribu kuchanganua pembejeo mtumiaji kama aina sahihi,
iwe Char, mbili, kuelea, nk
Na kisha kurudi ama matokeo kama pembejeo mara kwa mafanikio parsed
au wao reprompt mtumiaji.
>> Katika ngazi ya juu, kuna kitu kweli Tricky hapa.
Unaweza kuwa imeandikwa vile vile muundo code mwenyewe katika siku za nyuma.
Pengine sehemu ya cryptic-kuangalia ni wito sscanf kwamba parses pembejeo mtumiaji.
Sscanf ni sehemu ya familia pembejeo format uongofu.
Ni maisha katika io.h kiwango, na kazi yake ni kuchanganua string C,
kulingana na muundo fulani, hifadhi matokeo Hazrat katika variable
zinazotolewa na mpigaji.
Tangu format pembejeo uongofu kazi ni muhimu sana, sana kutumika kazi
ambayo si super Intuitive mara ya kwanza,
tutaweza kwenda juu ya jinsi sscanf kazi.
>> Hoja ya kwanza ni sscanf * char - pointer tabia.
Kwa kazi ya kufanya kazi vizuri,
tabia kwamba wanapaswa kuwa tabia ya kwanza ya string C,
terminated na tabia null \ 0.
Hii ni string kuchanganua
Hoja ya pili ni sscanf string format,
kawaida kupita katika mara kwa mara kama kamba,
na wewe aliyoiona string kama hii kabla ya wakati wa kutumia printf.
ishara asilimia katika string format inaonyesha specifier uongofu.
tabia mara moja kufuatia ishara asilimia,
inaonyesha aina C kwamba tunataka sscanf kubadilisha na.
Katika GetInt, unaweza kuona kwamba kuna d% na c%.
Hii ina maana kwamba sscanf watajaribu int decimal - d% - na char - c%.
Kwa kila specifier uongofu katika string format,
sscanf anatarajia hoja sambamba baadaye katika hoja orodha yake.
Hoja hiyo ya lazima uhakika na mahali ipasavyo typed
ambayo kuhifadhi matokeo ya uongofu.
>> njia ya kawaida ya kufanya hii ni kujenga juu ya kutofautiana stack kabla wito sscanf
kwa kila bidhaa kwamba unataka kuchanganua kutoka string
na kisha kutumia operator anwani - ampersand - kupita kuyatumia
kwa wale vigezo wito sscanf.
Unaweza kuona kwamba katika GetInt sisi kufanya hasa hili.
Haki kabla ya wito sscanf, sisi kutangaza int kuitwa n na Char c wanamwomba stack,
na sisi kupita kuyatumia na kuwatia katika wito sscanf.
Kuweka vigezo haya juu ya stack inapendelewa zaidi kutumia nafasi zilizotengwa
juu ya lundo na malloc, tangu wewe kuepuka Rudia ya wito malloc,
na huna na wasiwasi kuhusu kinachovuja kumbukumbu.
Nyingine si prefixed kwa ishara ya asilimia si kuchochea uongofu.
Badala yake wao tu kuongeza vipimo format.
>> Kwa mfano, kama string format katika GetInt walikuwa d% badala yake,
sscanf bila kuangalia kwa barua ikifuatiwa na int,
na wakati itakuwa jaribio kubadilisha int, itakuwa si kufanya kitu kingine chochote kwa a.
isipokuwa tu kwa hii ni whitespace.
White nafasi wahusika katika string format mechi yoyote ya kiasi cha whitespace -
hata hakuna kabisa.
Hivyo, hiyo ndiyo maoni inataja uwezekano kwa kuongoza na / au trailing whitespace.
Hivyo, katika hatua hii inaonekana kama sscanf wito wetu kujaribu kuchanganua pembejeo mtumiaji string
kwa kuangalia kwa whitespace iwezekanavyo kuongoza,
ikifuatiwa na int kwamba itabadilishwa na kuhifadhiwa katika int variable n
ikifuatiwa na baadhi ya kiasi cha whitespace, na kufuatiwa na tabia
kuhifadhiwa katika c Char kutofautiana.
>> Je kuhusu thamani ya kurudi?
Sscanf itakuwa Hazrat line pembejeo kutoka mwanzo hadi mwisho,
kuacha wakati unafikia mwisho au wakati tabia katika pembejeo
hailingani na tabia format au wakati hawezi kufanya uongofu.
Kurudi thamani yake ni kutumika kwa moja wakati ni kusimamishwa.
Kama ni kusimamishwa, kwa sababu ni kufikiwa mwisho wa kamba pembejeo
kabla ya kufanya wongofu yoyote na kabla ya kushindwa mechi sehemu ya kamba format,
kisha maalum EOF mara kwa mara ni kurudi.
Vinginevyo, ni anarudi idadi ya wongofu mafanikio,
ambayo inaweza kuwa 0, 1, au 2, tangu tumekuwa aliuliza kwa wongofu mbili.
Katika kesi yetu, tunataka kuhakikisha kwamba mtumiaji typed katika int na tu int.
>> Hivyo, tunataka sscanf kurudi 1. Angalia kwa nini?
Kama sscanf akarudi 0, basi hakuna wongofu yalifanywa,
hivyo user typed kitu kingine zaidi ya int katika mwanzo wa pembejeo.
Kama sscanf anarudi 2, basi mtumiaji hawakuwa vizuri unapoandika katika wakati wa mwanzo wa pembejeo,
lakini wao kisha typed katika baadhi ya tabia zisizo whitespace baadaye
tangu% c uongofu imefanikiwa.
Wow, kwamba ni kabisa maelezo marefu kwa moja wito kazi.
Anyway, kama unataka taarifa zaidi juu ya sscanf na ndugu zake,
angalia kurasa mtu, Google, au wote wawili.
Kuna kura ya chaguzi string format,
na hizi zinaweza kuokoa mengi ya kazi za mikono wakati akijaribu Hazrat masharti katika C.
>> kazi ya mwisho katika maktaba ya kuangalia ni GetString.
Ni zinageuka kuwa GetString ni kazi gumu kuandika vizuri,
ingawa inaonekana kama kazi hiyo rahisi, ya kawaida.
Kwa nini hii ni kesi?
Naam, hebu fikiria jinsi sisi ni kwenda kuhifadhi mstari kwamba mtumiaji aina in
Tangu string ni mlolongo wa chars,
sisi kutaka kuhifadhi katika safu juu ya stack,
lakini tunataka haja ya kujua jinsi ya muda mrefu safu ni kwenda kuwa wakati sisi kuyatangaza.
Aidha, kama tunataka kuweka kwenye chungu,
sisi haja ya kupita kwa malloc idadi ya ka tunataka hifadhi,
lakini hii ni vigumu.
Sisi hatuna wazo jinsi wengi chars mtumiaji aina katika
kabla ya mtumiaji kweli haina aina yao.
>> ufumbuzi naive tatizo hili ni kubwa tu ya kuwaweka chunk wa nafasi, kusema,
block ya chars 1000 kwa ajili ya pembejeo ya mtumiaji,
kuchukua kwamba mtumiaji kamwe aina katika string kwamba kwa muda mrefu.
Hii ni wazo mbaya kwa sababu mbili.
Kwanza, kuchukua kwamba watumiaji kawaida hawana aina katika masharti kwamba kwa muda mrefu,
unaweza kupoteza mengi ya kumbukumbu.
Kwenye mashine ya kisasa, hii inaweza kuwa suala kama kufanya hivyo
katika moja au mbili mara moja pekee,
lakini kama wewe ni kuchukua pembejeo mtumiaji katika kitanzi na kuhifadhi kwa matumizi ya baadaye,
unaweza haraka nwa tani ya kumbukumbu.
Zaidi ya hayo, ikiwa mpango wewe ni kuandika ni kwa ajili ya kompyuta ndogo ndogo -
kifaa kama smartphone au kitu kingine na kumbukumbu mdogo -
ufumbuzi hii kusababisha matatizo mengi kwa kasi zaidi.
pili, mbaya zaidi sababu si kufanya hii ni kwamba majani ya mpango wako hatarini
kwa nini inaitwa kufurika buffer mashambulizi.
Katika programu, buffer ni kumbukumbu kutumika kwa muda kuhifadhi data pembejeo au pato,
ambayo katika kesi hii ni yetu 1000-char block.
kufurika buffer hutokea wakati data imeandikwa zamani mwisho ya kuzuia.
>> Kwa mfano, kama mtumiaji kweli haina aina katika chars zaidi ya 1000.
Unaweza kuwa uzoefu huu wakati ajali na programu arrays.
Kama una safu ya ints 10, ataacha kitu kutoka kujaribu kusoma wala kuandika
Int 15.
Kuna maonyo compiler hakuna au makosa.
mpango tu blunders sawa mbele na grossistledet kumbukumbu
ambapo inafikiri int 15 itakuwa, na hii inaweza overwrite yako vigezo vingine.
Katika kesi mbaya zaidi, unaweza overwrite baadhi ya ndani ya mpango wako
kudhibiti taratibu, na kusababisha mpango wako kwa kweli nitafanya maelekezo mbalimbali
kuliko wewe lengo.
>> Sasa, ni si kawaida kufanya hili ajali,
lakini hii ni mbinu ya haki ya kawaida kwamba watu wabaya kutumia kuvunja mipango
na kuweka malicious code kwenye kompyuta ya watu wengine.
Kwa hiyo, hatuwezi tu kutumia ufumbuzi yetu naive.
Tunahitaji njia ya kuzuia mipango yetu kutoka kuwa katika mazingira magumu
kwa mashambulizi buffer kufurika.
Ili kufanya hivyo, tunahitaji kuhakikisha kuwa buffer yetu inaweza kukua kama sisi kusoma
zaidi pembejeo kutoka kwa mtumiaji.
suluhisho? Sisi kutumia zilizotengwa lundo buffer.
Tangu tunaweza resize hilo kutumia resize kazi realloc,
na sisi kuweka wimbo wa namba mbili - index ya yanayopangwa ijayo tupu katika buffer
na urefu au uwezo wa buffer.
Tunasoma katika chars kutoka kwa mtumiaji mmoja wakati kutumia kazi fgetc.
Hoja kazi fgetc inachukua - stdin - ni kumbukumbu ya string kiwango pembejeo,
ambayo ni preconnected pembejeo channel ambayo hutumiwa kwa kuhamisha pembejeo mtumiaji
kutoka terminal kwa mpango.
>> Kila mara mtumiaji aina katika tabia mpya, sisi kuangalia kuona kama index
ya yanayopangwa ijayo bure plus 1, ni mkubwa kuliko uwezo wa buffer.
1 huja katika sababu kama ijayo index bure ni 5,
kisha urefu buffer wetu lazima 6 shukrani kwa Indexing 0.
Kama tumekuwa kukimbia nje ya nafasi katika buffer, basi sisi kujaribu resize yake,
kutaka kuongezwa ili sisi kupunguza idadi ya nyakati kwamba sisi resize
kama mtumiaji ni kuandika katika string kweli kwa muda mrefu.
Kama string imenipatia muda mrefu sana au kama sisi kukimbia nje ya kumbukumbu chungu,
sisi huru buffer yetu na kurudi null.
>> Hatimaye, sisi ambatisha Char kwa buffer.
Mara hits mtumiaji kuingia au kurudi kumuashiria line mpya,
au maalum char - kudhibiti d - ambayo ishara ya mwisho wa pembejeo,
sisi kufanya kuangalia ili kuona kama kweli mtumiaji typed katika chochote wakati wote.
Kama siyo, sisi kurudi null.
Vinginevyo, kwa sababu buffer yetu pengine ni kubwa kuliko sisi haja,
katika hali mbaya ni kama mara mbili kubwa kama tunahitaji
tangu sisi mara mbili kila wakati sisi resize,
sisi kufanya nakala mpya wa kamba kwa kutumia tu ya kiasi cha nafasi ya kuwa tunahitaji.
Sisi kuongeza 1 ziada wito malloc,
hivyo kwamba kuna nafasi kwa ajili ya tabia maalum null Terminator - \ 0,
ambayo sisi ambatisha kwa kamba mara moja sisi nakala katika mapumziko ya wahusika,
kutumia strncpy badala ya strcpy
ili tuweze kubainisha hasa jinsi wengi chars tunataka nakala.
Strcpy nakala mpaka hits \ 0.
Kisha sisi huru buffer yetu na kurudi nakala kwa mpigaji.
>> Nani alijua kazi vile rahisi-Wanajidai inaweza ngumu hivyo?
Sasa unajua yale yanayoendelea ndani ya maktaba CS50.
>> Jina langu ni Nate Hardison, na hii ni CS50.
[CS50.TV]