[Powered by Google Translate] [CS50 Library]
[Nate Hardison] [Harvardin yliopisto]
[Tämä on CS50. CS50.TV]
CS50 kirjasto on hyödyllinen työkalu, joka meillä on asennettu laitteeseen
helpottaa voit kirjoittaa ohjelmia nopeasti käyttäjien panos.
Tässä videossa me vetää verhot ja katsoa mitä on CS50 kirjastossa.
>> Vuonna video C-kirjastot, puhumme miten # include otsikot tiedostot
ja kirjaston lähdekoodia,
ja sitten linkittää binary kirjastotiedosto aikana yhdistää vaiheen
laatimisen prosessin.
Header tiedostot määrittää käyttöliittymän kirjastosta.
Eli ne yksityiskohtaisesti kaikki resurssit kirjastossa on saatavilla voit käyttää,
kuten funktio ilmoitukset, vakiot, ja tietotyyppejä.
Binary kirjasto tiedosto sisältää täytäntöönpanoa kirjasto,
joka on koottu kirjaston header tiedostot ja kirjaston. c lähdekooditiedostoja.
>> Binary Kirjasto tiedostoa ei ole kovin mielenkiintoista tarkastella, koska se on hyvin, binary.
Joten, nyt katsomaan header tiedostot kirjaston sijaan.
Tässä tapauksessa on vain yksi otsikko tiedosto nimeltä cs50.h.
Olemme asentanut sen käyttäjä ovat hakemistossa
yhdessä muiden järjestelmän kirjastojen header-tiedostot.
>> Yksi ensimmäisistä asioista, huomaat että cs50.h # sisältää header tiedostoja muista kirjastoista -
float, rajoja, vakio bool ja standardi lib.
Jälleen, sen jälkeen periaatetta ei pyörän keksimistä uudelleen,
olemme rakentaneet CS0 kirjaston työkaluja, että muut säädetyt meille.
>> Seuraava asia näet kirjastossa on, että me määrittelemme uudentyyppinen nimeltään "merkkijono".
Tämä linja oikeastaan ​​vain luo alias char * tyyppi,
joten se ei taianomaisesti kyllästää uusi merkkijono tyyppiä määritteitä
yleisesti liittyvät merkkijono esineiden muilla kielillä,
kuten pituus.
Syy olemme tehneet tätä on suojata uudet ohjelmoijat verinen tiedot
osoittimia, kunnes ne ovat valmiita.
>> Seuraava osa header tiedosto on ilmoitus toimintojen
että CS50 kirjasto tarjoaa mukana dokumentointi.
Huomaa kuinka yksityiskohtaisia ​​kommentteja täällä.
Tämä on erittäin tärkeää, jotta ihmiset tietävät, miten käyttää näitä toimintoja.
Me julistamme, puolestaan ​​toimii pyytää käyttäjältä ja paluu merkkiä, tuplaa, kellukkeet, Ints,
pitkä kaipaa, ja jouset, omilla merkkijono tyyppi.
Periaatteen mukaisesti tiedonpiilotus,
me olemme asettaneet määritelmä erilliseen. C täytäntöönpanosta file - cs50.c--
sijaitsevat käyttäjän lähdehakemistoon.
Olemme kunhan tiedosto, jotta voit vilkaista sitä,
opiksi, ja kääntää sen eri koneilla jos haluatte,
vaikka mielestämme on parempi työskennellä laitteen tämän luokan.
Anyway, katsotaanpa katsomaan sitä nyt.
>> Toiminnot GetChar, GetDouble, GetFloat, GetInt, ja GetLongLong
ovat kaikki rakennettu päälle GetString toiminnon.
On käynyt ilmi, että ne kaikki noudattavat samaa kaavaa.
He käyttävät taas silmukka pyytää käyttäjältä yhden rivin panos.
He palaavat erityinen arvo, jos käyttäjä syöttää tyhjän rivin.
He yrittävät jäsentää käyttäjän syöttää kuin sopivaa tyyppiä,
olla se char, double, float, jne.
Ja sitten he joko palauttaa tuloksen, jos tulo onnistuneesti jäsentää
tai ne reprompt käyttäjälle.
>> Korkealla tasolla, ei ole mitään todella hankala täällä.
Olet ehkä kirjoittanut samanlainen rakenne koodin itse aikaisemmin.
Ehkä kaikkein salaperäinen näköinen osa on sscanf puhelu, joka jäsentää käyttäjän syöttää.
Sscanf on osa tulon muuntaminen perheeseen.
Se elää standardin io.h, ja sen tehtävänä on jäsentää C merkkijono,
mukaan tiettyyn muotoon, tallennetaan parse tulokset muuttuja
edellyttäen, että soittajan.
Koska tulo muuntaminen toiminnot ovat erittäin hyödyllisiä, laajasti käytettyihin toimintoihin
jotka eivät ole erittäin intuitiivinen aluksi,
menemme yli miten sscanf toimii.
>> Ensimmäinen argumentti sscanf on char * - osoitin merkin.
Jotta toiminto toimisi oikein,
että merkki olisi ensimmäinen merkki C merkkijono,
Päätetään null \ 0 luonnetta.
Tämä on merkkijono jäsentää
Toinen argumentti sscanf on muotomerkkijonoa,
tyypillisesti kulunut niin string vakio,
ja olet ehkä nähnyt merkkijono kuten tämä ennen kun käytät printf.
Prosentin merkki muotomerkkijonoa ilmaisee muunnostarkennin.
Merkki heti prosenttimerkki,
ilmaisee C tyypin että haluamme sscanf muuntaa.
Vuonna GetInt, näet, että on olemassa% d ja% c.
Tämä tarkoittaa sitä, että sscanf pyrkii desimaalin int -% d - ja char -% c.
Kunkin muunnostarkennin muotomerkkijonoa,
sscanf odottaa vastaavaa väitettä myöhemmin parametrilistaus.
Tämä väite pitää viitata asianmukaisesti kirjoitetaan sijainti
jossa tallentaa muunnon seurauksena.
>> Tyypillinen tapa tehdä tämä on luoda muuttuja pinoon ennen sscanf puhelun
kunkin kohteen, jonka haluat jäsentää alkaen merkkijono
ja sitten käyttää osoitetta operaattori - et-- siirtää osoittimia
kuin muuttujia sscanf puhelun.
Voit nähdä, että GetInt teemme juuri tätä.
Juuri ennen sscanf puhelua, me julistamme int kutsutaan n ja char puhelu c pinoon,
ja ohitamme osoittimia ne sscanf puhelun.
Putting nämä muuttujat pinoon on parempana käyttää varattuun tilaan
kasaan kanssa malloc, koska voit välttää overhead malloc puhelun
ja sinun ei tarvitse murehtia vuotaa muistia.
Hahmot eivät edeltää prosenttimerkkiä Älä pyydä muuntamista.
Pikemminkin ne vain lisäävät muotomäärittelyä.
>> Esimerkiksi jos muotomerkkijonoa vuonna GetInt oli% d sijaan,
sscanf olisi etsittävä kirjeen jälkeen int-
ja vaikka se yrittää muuntaa int, se ei tee mitään muuta kanssa.
Ainoa poikkeus tähän on välilyönnit.
Valkoinen merkkien muotomerkkijonoa vastaa mitään määrää välilyönti -
jopa ei ollenkaan.
Niin, siksi kommentti mainitsee mahdollisesti johtavien ja / tai perään välilyönnit.
Joten tässä vaiheessa näyttää siltä, ​​että meidän sscanf puhelu yrittää jäsentää käyttäjän syötemerkkijonon
tarkistamalla mahdollista välilyönnillä,
seurasi int, joka muunnetaan ja tallennetaan int muuttuja n
seurasi jonkin verran välilyönnit, ja sitä seurasi merkin
tallennettu char muuttuja c.
>> Entä paluuarvon?
Sscanf jäsentää panos linja alusta loppuun,
pysähtyy, kun se loppuu tai kun merkin syöttö
ei vastaa muotoa merkin tai kun se ei voi tehdä muuntaminen.
Se paluu arvoa käytetään erotella, kun se pysähtyi.
Jos se pysähtynyt, koska sen lopussa syötemerkkijonon
ennen kuin teet mitään tuloksia ja ennen jättämällä vastaamaan osaan muotomerkkijonoa,
Sitten erityinen vakio EOF palautetaan.
Muuten, se palauttaa useita onnistuneita tuloksia,
joka voi olla 0, 1 tai 2, koska olemme pyytänyt kahta tuloksia.
Meidän tapauksessa haluamme varmistaa, että käyttäjä kirjoittamaasi int ja vain int.
>> Joten haluamme sscanf palata 1. Katso miksi?
Jos sscanf tuotti 0, niin ei muunnoksia tehtiin
joten käyttäjä kirjoittaa jotain muuta kuin int alussa tulon.
Jos sscanf palauttaa 2, niin käyttäjä ei kunnolla kirjoittaa sen alussa tulo,
mutta ne sitten kirjoitettu joitakin ei-välilyönti merkin jälkeen
koska% c konversio onnistui.
Vau, se on aika pitkä selitys yksi toiminto puhelun.
Joka tapauksessa, jos haluat lisätietoja sscanf ja sen sisarukset,
tutustu man sivut, Google, tai molemmat.
On olemassa paljon muotomerkkijonoa vaihtoehtoja,
ja näitä voi säästää paljon käsityötä kun yrittää jäsentää jousille C
>> Lopullinen toiminto kirjaston tarkastella on GetString.
On käynyt ilmi, että GetString on hankala funktio kirjoittaa oikein,
vaikka se tuntuu niin yksinkertainen, yhteinen tehtävä.
Miksi näin on?
No, mieti, miten aiomme säilyttää linja, että käyttäjä tyypit sisään
Koska merkkijono on sekvenssi merkkiä,
saatamme haluta tallentaa sen array pinoon,
mutta meidän olisi tiedettävä, kuinka kauan array tulee olemaan kun julistaa sen.
Samoin, jos haluamme laittaa sen kasaan,
meidän täytyy kulkea malloc tavujen haluamme varaukseen,
mutta tämä on mahdotonta.
Meillä ei ole aavistustakaan, kuinka monta merkkiä käyttäjä kirjoittaa
ennen kuin käyttäjä itse ei kirjoita ne.
>> Naiivi ratkaisu tähän ongelmaan on vain varata iso kimpale tilaa, eli
lohko 1000 merkkiä varten käyttäjän syötteen mukaisesti,
olettaen, että käyttäjä ei koskaan kirjoita merkkijono pitkä.
Tämä on huono idea kahdesta syystä.
Ensinnäkin, olettaen, että käyttäjät eivät yleensä kirjoita jouset niin kauan,
voisit tuhlata paljon muistia.
On nykyaikaiset koneet, tämä ei välttämättä ole ongelma, jos teet tämän
yksi tai kaksi yksittäistä tapauksissa,
mutta jos olet ottaen käyttäjän panos silmukka ja tallentaa myöhempää käyttöä varten,
voit nopeasti imeä ton muistin.
Lisäksi, jos ohjelma olet kirjoittamassa on pienempi tietokone -
laite, kuten älypuhelin tai jotain muuta vähän muistia -
tämä ratkaisu aiheuttaa ongelmia paljon nopeammin.
Toinen, vakavampi syy tehdä tämä on, että se jättää ohjelman haavoittuvia
mitä kutsutaan puskurin ylivuoto hyökkäys.
Ohjelmoinnissa puskuri on käytettävä muisti tallentaa väliaikaisesti tulo tai lähtö dataa,
joka tässä tapauksessa on meidän 1000-char lohko.
Puskurin ylivuoto tapahtuu, kun tiedot on kirjoitettu pään ohi lohkon.
>> Esimerkiksi, jos käyttäjä itse ei kirjoita yli 1000 merkkiä.
Olet ehkä kokenut tätä vahingossa ohjelmoinnissa paneelit.
Jos sinulla on joukko 10 ints, mikään ei estä sinua yrittää lukea tai kirjoittaa
15. int.
Ei ole kääntäjän varoituksia tai virheitä.
Ohjelma vain kömmähdyksiä suoraan eteenpäin ja avaa muisti
jos se katsoo 15. int tulee, ja tämä voi korvaa muita muuttujia.
Pahimmassa tapauksessa voit korvata joitakin ohjelman sisäinen
valvontamekanismeja, mikä ohjelma todella suorittaa erilaisia ​​ohjeita
kuin tarkoitit.
>> Nyt se ei ole yhteisiä tehdä tämän vahingossa,
mutta tämä on melko yleinen tekniikka, että pahat pojat käyttävät rikkoa ohjelmia
ja laittaa haitallista koodia muiden ihmisten tietokoneita.
Siksi emme voi vain käyttää naiivi ratkaisu.
Meidän tapa estää meidän ohjelmia alttiita
on puskurin ylivuoto hyökkäys.
Voit tehdä tämän, meidän täytyy varmistaa, että puskuri voi kasvaa, kun luemme
Lisää tietoa käyttäjältä.
Ratkaisu? Käytämme kasaan Allokoidun puskuri.
Koska emme voi muuttaa sen käyttämällä resize realloc toiminto,
ja me seurata kaksi numeroa - indeksi seuraavaan tyhjään puskurissa,
ja pituus tai kapasiteettia puskuria.
Luemme merkkiä käyttäjältä yksi kerrallaan käyttämällä fgetc toimintoa.
Argumentti fgetc toiminto käynnistyy - stdin - on viittaus vakiosyötteestä merkkijono,
joka on esikytketty tulokanava, jota käytetään siirtämään käyttäjän syöttämän
päätelaitteelta ohjelman.
>> Aina käyttäjä tyypit uusi hahmo, tarkistamme onko indeksin
Seuraavan vapaa paikka plus 1 on suurempi kuin kapasiteetti puskuria.
+1- Tulee koska jos seuraava vapaa indeksi on 5,
Sitten meidän puskurin pituus on 6 kiitos 0 indeksointi.
Jos olemme loppuu tilaa puskurin, niin yritämme muuttaa sitä,
kaksinkertaistaa niin, että me leikata, kuinka monta kertaa, että me kokoa
jos käyttäjä on kirjoittamalla todella pitkä jono.
Jos merkkijono on mennyt liian kauan tai jos loppuu Heap muisti,
me vapauttaa meidän puskurin ja return.
>> Lopuksi, me liittää char että puskuriin.
Kun käyttäjä painaa syöttää tai palata, signalointi uusi rivi,
tai erityinen char - ohjaus d - joka viestittää lopussa tulon,
teemme tarkistaa, jos käyttäjä itse kirjoittanut yhtään mitään.
Jos ei, palaamme null.
Muuten, koska meidän puskuri on todennäköisesti suurempi kuin meidän,
pahimmassa tapauksessa se on lähes kaksi kertaa niin suuri kuin meidän
koska meillä kaksinkertaistuu joka kerta kokoa,
teemme uuden kopion merkkijono käyttäen vain paljon tilaa, että me tarvitsemme.
Lisäämme ylimääräinen 1 malloc puhelun
niin että siellä on tilaa erityistä null terminaattori merkki - \ 0,
jota liittää merkkijonon kerran me kopioida muualla merkkiä,
käyttämällä strncpy sijasta strcpy
jotta voimme määritellä tarkasti, kuinka monta merkkiä haluamme kopioida.
Strcpy kopioi kunnes se osuu \ 0.
Sitten vapauttaa meidän puskurin ja palautettava kappale soittajalle.
>> Kuka tiesi tällaisen yksinkertaisen näennäisestä toiminto voisi olla niin monimutkaista?
Nyt tiedät mitä menee CS50 kirjastoon.
>> Nimeni on Nate Hardison, ja tämä on CS50.
[CS50.TV]