[Powered by Google Translate] [CS50 biblioteka]
[Nate Hardison] [Harvardo universiteto]
[Tai CS50. CS50.TV]
CS50 biblioteka yra naudingas įrankis, kad mes turime įdiegti prietaiso
, kad būtų lengviau, kad galėtumėte rašyti programas, kad paskatins vartotojus Žaliavos.
Šiame vaizdo, mes atsitraukti užuolaidą ir pažvelgti, kas tiksliai yra CS50 bibliotekoje.
>> Vaizdo apie C bibliotekų, mes kalbame apie tai, kaip # include antraštes failus
per kodo bibliotekos,
ir tada jūs susieti su dvejetainiu susiejimo etapo metu bibliotekos failą
rengimo procesą.
Header files nurodyti bibliotekos sąsaja.
Tai yra, jie visus išteklius, kad bibliotekoje yra jums naudoti,
kaip funkcija deklaracijas, konstantų, ir duomenų tipai.
Dvejetainis biblioteka failas yra bibliotekoje įgyvendinimą,
kuris sudaromas iš bibliotekos header files ir c kodą failus biblioteka.
>> Nėra labai įdomu pažvelgti, nes tai gerai, dvejetainis dvejetainis bibliotekos failą.
Taigi, tegul bent antraščių failus į biblioteką, o ne išvaizdą.
Šiuo atveju, antraštė yra tik vienas failas, kuris vadinamas cs50.h.
Mes įdiegti jį į vartotojo katalogą
kartu su kita sistema bibliotekų header files.
>> Vienas iš pirmųjų dalykų, jūs pastebėsite, kad cs50.h # antraštės failus iš kitų bibliotekų -
plūdės, ribos, standartinė bool, ir standartas lib.
Vėlgi, ne dviračio išradinėjimo principą,
mes pastatė CS0 biblioteką, naudojant įrankius, kad kiti numatytas mus.
>> Kitas dalykas, jūs pamatysite bibliotekoje yra, kad mes apibrėžti naujo tipo vadinamas "string".
Ši eilutė tikrai tik sukuria char * tipo alias,
, todėl ji nėra stebuklingai Piesūcināt naujos eilutės tipą su atributais
paprastai būna susijęs su virvele objektų kitomis kalbomis,
kaip antai ilgis.
Priežastis, mes padarėme tai yra apsaugoti naujų programuotojų Kalnai informacijos
patarimų, kol jie pasiruošę.
>> Kitas dalis antraštės faile yra funkcijų deklaracija
CS50 bibliotekoje kartu su dokumentacija.
Pranešimas išsamumo lygį komentarų.
Tai yra super svarbu, kad žmonės žino, kaip naudoti šias funkcijas.
Mes pareiškiame, savo ruožtu, veikia greitai vartotojo ir grąžinimo simbolių, dviviečiai, plūdes, int,
seniai trokšta, ir styginiams, naudodami mūsų pačių string tipas.
Informacijos slapstytis principo,
turime įdėti mūsų atskiras c įgyvendinimo failo apibrėžimą - cs50.c -
įsikūręs vartotojo šaltinio katalogą.
Mes pateikiame šį failą, kad jūs galite pažvelgti į jį,
iš jos pasimokyti, ir perkompiliuoti jį ant įvairių mašinų, jei norite,
nors mes manome, kad geriau dirbti šios klasės prietaiso.
Bet kokiu atveju, tegul dabar į jį pažvelgti.
>> Funkcijos GetChar, GetDouble, GetFloat, GetInt, ir GetLongLong
yra pastatytas ant GetString funkcija.
Pasirodo, kad visi jie iš esmės tą patį modelį.
Jie naudoja while cikle paskatinti vartotoją vienos linijos įvesties.
Jie grįžta ypatingą vertę, jei vartotojas įėjimai tuščią eilutę.
Jie bando išanalizuoti vartotojo įvestį kaip atitinkamo tipo,
char, dvigubas, plūdės, ir tt
Ir tada jie turi grąžinti rezultatą, jei įėjimo buvo sėkmingai apdoroti
ar jie reprompt vartotoją.
>> Aukštu lygiu, nėra nieko tikrai sudėtinga čia.
Jūs panašios struktūros galėjo parašyti kodą save praeityje.
Turbūt labiausiai paslaptingas išvaizdos dalis yra sscanf skambučio, kad analizuoja vartotojo įvestį.
Sscanf yra dalis įvesties formato konvertavimo šeimos.
Jis gyvena standartinio io.h ir jo darbas yra apdoroti C eilutę,
pagal tam tikru formatu, saugoti Analizės rezultatai kintamojo
numatyta skambintojui.
Nuo įvesties formato konvertavimo funkcijos yra labai naudinga, plačiai naudojamas funkcijas
kurie yra ne super intuityvus, pirmiausia,
mes pereiti kaip sscanf veikia.
>> Pirmasis argumentas sscanf char * - rodyklė į simbolį.
Funkcija veiktų tinkamai,
kad charakteris turėtų būti pirmasis simbolis C kalboje,
nutraukta su nulinės \ 0 pobūdžio.
Tai yra eilutė, išanalizuoti
Antrasis argumentas sscanf yra format string,
paprastai perduodamos kaip styginių konstantos,
ir jūs galėjote pastebėti, kaip šis eilutę prieš naudojant printf.
Procento ženklas formato eilutę rodo konversijos specyfikator.
Pobūdis iš karto po procento ženklą,
rodo C tipo, kad mes norime sscanf konvertuoti į.
Be GetInt, jūs pamatysite, kad yra% d ir% c.
Tai reiškia, kad sscanf bandys dešimtainis LC -% d ir char -% c.
Kiekvienam konversijos specyfikator formato eilutę,
sscanf tikisi atitinkantis argumentas vėliau jos argumentų sąrašą.
Šis argumentas turi atkreipti dėmesį į tinkamai įvedėte vietoje
laikyti konvertavimo rezultatą.
>> Tipiškas būdas tai padaryti yra sukurti kintamąjį kamino iki sscanf skambučio
už kiekvieną elementą, kurį norite apdoroti eilutę
ir tada naudokite adresų operatorių - Ampersand - perduoti patarimų
šių kintamųjų sscanf skambučio.
Jūs galite pamatyti, kad GetInt mes darome būtent tai.
Prieš pat sscanf skambučio mes pareiškiame vadinamos N int ir char skambučių C temperatūroje ant kamino,
ir mes pereiname į juos patarimų į sscanf skambučio.
Išleisti šiuos kintamuosius kamino pirmenybė naudojant vietos skirtos
su malloc krūvą, nes jums išvengti važtaraščius malloc pokalbį,
ir jūs neturite jaudintis dėl nesandarus atminties.
Simboliai, priešdėliu procento ženklas NEPASAKINĖTI konversiją.
O jie tiesiog pridėkite su formatavimo specifikacijos.
>> Pavyzdžiui, jei buvo% d, o ne, format string GetInt
sscanf atrodytų už laišką, po int
ir nors ji bandyti konvertuoti int, tai nebūtų daryti nieko kito, su A.
Vienintelė išimtis yra tai, tarpus.
White Space simbolių formato eilutę neatitinka jokių tarpų kiekį -
net iš viso nėra.
Taigi, štai kodėl komentaras minima galbūt pirmaujančių ir / tarpus pradžioje arba pabaigoje.
Taigi, šiuo metu jis panašus į mūsų sscanf skambučio stengsis išanalizuoti vartotojo įvestą eilutę,
tikrinant galimą Tarpas,
int, kad bus konvertuotas ir saugomi int kintamojo n
kai kurių tarpų dydžio, ir po simbolį
saugomas char kintamojo a.
>> Ką apie sugrįžimo vertę?
Sscanf bus apdoroti įvesties linijos nuo pradžios iki pabaigos,
sustabdyti, kai jis pasiekia galutinį arba simbolį įvesties
neatitinka formato pobūdžio arba kai jis negali padaryti konversiją.
Tai sugrįžimas vertė yra naudojamas išskirti, kai jis sustojo.
Jei jis sustojo, nes ji pasiekė įvesties stringo pabaigos
prieš priimant bet kokį konversijas ir prieš nesugeba suderinti dalį formato eilutę
tada speciali konstanta EOF yra grąžinamas.
Priešingu atveju, ji grąžina sėkmingų konversijų skaičių,
kuri galėtų būti 0, 1 arba 2, nes mes paprašėme dvi konversijų.
Mūsų atveju, mes norime įsitikinti, kad vartotojas turi įvesti int ir tik int.
>> Taigi, mes norime sscanf return 1. Suprasti, kodėl?
Jei sscanf grįžo 0, tada buvo padaryti, jokios konversijos
todėl vartotojas turi įvesti ką nors kitą, nei prie įėjimo pradžioje int.
Jei sscanf grąžina 2, tada vartotojas nebuvo tinkamai įveskite jį įvesties pradžioje,
bet tada jie įvestas po to kai ne tarpais pobūdžio
nuo% c konversijos pavyko.
Oho, tai gana ilgas paaiškinimas vieną skambinimo funkcijos.
Bet kokiu atveju, jei norite daugiau informacijos apie sscanf ir jo broliai ir seserys,
patikrinti Man puslapiai, "Google", arba abu.
Format string variantų yra daug,
ir jie gali jums sutaupyti daug rankų darbo, bandant apdoroti eilutes C.
>> Galutinis bibliotekoje funkcija pažvelgti į tai, GetString.
Pasirodo, kad GetString yra sudėtinga funkcija tinkamai rašyti,
nors atrodo, kad toks paprastas, bendrą užduotį.
Kodėl tai atveju?
Na, galime galvoti apie tai, kaip mes ketiname saugoti liniją, kad vartotojas įveda in
Kadangi eilutė yra simbolių seka,
mes norime laikyti jį masyvo kamino,
bet mums reikia žinoti, kiek bus masyvo, kai mes paskelbti ją suderinama su bendrąja rinka.
Taip pat, jei mes norime įdėti jį į krūvą,
turime pereiti į malloc baitų skaičių, norime rezervą,
bet tai neįmanoma.
Mes neturime jokio supratimo, kiek simbolių vartotojas turės įvesti
kol vartotojas iš tikrųjų įveskite juos.
>> , Naivus šios problemos sprendimas yra tiesiog rezervuoti didelė riekė erdvėje, tarkim,
1000 simbolių vartotojo įvestį blokas,
, darant prielaidą, kad vartotojas niekada įvesti į eilutę, kad ilgai.
Tai yra bloga idėja dėl dviejų priežasčių.
Pirma, darant prielaidą, kad vartotojai paprastai nereikia įvesti stygos, kad ilgai,
jums gali gaišti daug atminties.
Modernios mašinos, tai gali būti problema, jei jums tai padaryti
vieno ar dviejų pavienių atvejų,
tačiau, jei jūs vartojate vartotojo indėlį į kilpą ir saugoti vėlesniam naudojimui,
galite greitai įsisiurbti atminties toną.
Be to, jei programa rašote už mažesnę kompiuteryje
kaip išmaniojo telefono arba kažkas su ribotos atminties įrenginys -
šis sprendimas sukels problemų daug greičiau.
Antra, daugiau rimtų priežasčių to padaryti, kad jis palieka savo programą pažeidžiami
tai, kas vadinama buferio perpildymo ataka.
Programavimą, atminties buferis yra naudojami laikinai saugoti įvesties arba išvesties duomenis,
, kuri šiuo atveju yra mūsų 1000-char blokas.
Buferio atsiranda tada, kai duomenys įrašomi praeities bloko pabaigos.
>> Pavyzdžiui, jei vartotojas iš tiesų tipo daugiau nei 1000 simbolių.
Galbūt patyrėte tai atsitiktinai, kai programavimo su matricomis.
Jei turite 10 int masyvas, nieko sustabdo jus nuo bando skaityti ir rašyti
15-oji vid.
Yra jokių kompiliavimo įspėjimo ar klaidos.
Programą tik suklydimų tiesiai į priekį, ir gauti prieigą prie atminties
, kai, jos nuomone, 15 int bus, o tai gali perrašyti savo kitus kintamuosius.
Blogiausiu atveju, galite perrašyti kai savo programą vidaus
kontrolės mechanizmai, todėl savo programą faktiškai vykdyti skirtingas instrukcijas
nei manėte.
>> Dabar, tai neturi nieko bendro, tai padaryti netyčia,
tačiau tai yra gana įprastas gydymo būdas, kad blogi vaikinai naudoti nutraukti programas
ir įdėti kenksmingą kodą į kitų žmonių kompiuterius.
Taigi, mes galime ne tik naudoti mūsų naivus sprendimą.
Mes turime būdas užkirsti kelią savo programas yra pažeidžiami
buferio perpildymo atakos.
Norėdami tai padaryti, mes turime įsitikinti, kad mūsų buferis gali augti kaip mes skaitome
daugiau įvestis iš vartotojo.
Sprendimas? Mes naudojame krūvos Paskirti buferio.
Kadangi mes galime pakeisti jo dydį naudodami Resize realloc funkciją,
ir mes sekti du skaičiai - kitą tuščią lizdą indeksą į buferį
o ilgis arba buferio talpa.
Mes skaityti simbolių iš vartotojo viena vienu metu naudojant fgetc funkciją.
Į fgetc funkcija priima stdin - argumentas yra nuoroda į standartinio įvesties eilutę,
kuris yra užtikrintai įvesties kanalas, kuris yra naudojamas perduoti vartotojo indėlį
iš terminalo į programą.
>> Kai vartotojas įveda į naują pobūdį, mes tikriname, ar, jei indeksas
kitą laisvą plyšį, plius 1 yra didesnis nei buferinės talpos.
"+1 Ateina, nes jei kitas Laisvą indeksas yra 5,
tada mūsų Slopintuvų ilgis turi būti 6 dėka 0 indeksavimo.
Jei mes paleisti iš vietos buferyje, tada mes bandome pakeisti jo dydį,
padvigubinti, kad galėtume sumažinti, kiek kartų, kad mes dydį
jei vartotojas yra rašyti tikrai ilgą eilutę.
Jei eilutė turi Dotarłeś per ilgas arba jei mes paleisti iš krūvos atminties,
mes nemokamai mūsų buferis ir grąžina NULL.
>> Galiausiai, mes pridėti char į buferį.
Kai naudotojas paspaus įvesti arba grįžti, signalizacijos naują eilutę,
arba specialus simbolis - valdymas D - kokie signalai galą įvesties,
mes patikrinti, norėdami pamatyti, jei vartotojas iš tikrųjų įvedėte ką nors ne visi.
Jei ne, mes grąžina NULL.
Kitaip, nes mūsų buferis yra tikriausiai didesnis nei mums reikia,
blogiausiu atveju, tai beveik du kartus didesnis, kaip mes turime
nes mes du kartus kiekvieną kartą, dydį,
eilutę, naudojant tik kiek vietos, kad mes turime naują kopiją.
Mes pridėti papildomą 1 malloc skambutį,
taip, kad specialios null terminatoriaus pobūdžio erdvė - \ 0
kurios mes pridėti į eilutę, kai mes kopijuoti kitų veikėjų,
naudojant strncpy vietoj strcpy
taip, kad mes galime nurodyti tiksliai, kiek simbolių norite kopijuoti.
Strcpy kopijuoja, kol ji hitai \ 0.
Tada mes nemokamai mūsų buferio ir grąžina kopiją skambinančiajam.
>> Kas žinojo, kad toks paprastas tariamas funkcija gali būti taip sudėtinga?
Dabar jūs žinote, kas patenka į CS50 bibliotekoje.
>> Mano vardas yra Nate Hardison, ir tai yra CS50.
[CS50.TV]