[MŪZIKA ATSKAŅOTĀS]
DEIVIDS MALANS: Labi.
Šī ir CS50, un šī ir 2. nedēļa, kurā mēs aplūkosim zemāku līmeni, kā
lietas darbojas, un patiešām, starp kursa mērķiem ir šī augšupēja
izpratne, lai pēc pāris nedēļām pēc laika, pat pēc dažiem gadiem, kad
jūs saskaraties ar jaunām tehnoloģijām, jūs varēsiet cerīgi
atskatīties uz kādu no šīs nedēļas, un tie ir pamata elementi un
primitīvi, un tiešām tikai secināt, kā darbojas rītdienas
tehnoloģijas.
Bet pa ceļam šķitīs, ka, tā sakot, būs nedaudz grūti saskatīt mežu
kokiem.
Un tāpēc mērķis dienas beigās joprojām būs problēmu risināšana.
Un tāpēc mēs domājām, ka šodien sāksim ar dažām problēmām, par kurām
runāsim vai atrisināsim nākamajā nedēļā, un tāpēc mums ir daži
drosmīgi brīvprātīgie, kuri jau ir nākuši klajā.
Ja mēs varētu ieslēgt kādu dramatisku apgaismojumu un satikt mūsdienu
brīvprātīgos.
Tātad man pa kreisi šeit ir... ALEKSS: Sveiki.
Mani sauc Alekss.
Es mācos pirmajā kursā koledžā un esmu no Chapel Hill, Ziemeļkarolīnā.
DEIVIDS MALANS: Laipni lūdzam Aleksā.
Un Aleksam pa labi.
SĀRA: Es esmu Sāra.
Es esmu no Toronto, Kanādā, un esmu arī pirmā kursa students koledžā.
DEIVIDS MALANS: Brīnišķīgi.
Labi, laipni lūdzam Aleksam un Sārai.
Tāpēc viena no problēmām, ko, iespējams, atrisināsiet šonedēļ
saistībā ar 2. uzdevumu kopu, ir analizēt teksta kopas lasīšanas
līmeni, neatkarīgi no tā, vai kāds lasa pirmās klases, otrās klases,
trešās klases līmenī, līdz pat 12 vai 13 vai vairāk.
Par ko jūs, iespējams, nekad nedomājāt, protams, attiecībā uz kodu,
piemēram, kā jūs analizētu kādu tekstu, kādu grāmatu un noskaidrotu,
kādā lasīšanas līmenī tas ir.
Un tomēr mūsu skolotāji, augot, to zināja vai intuitīvi nojauta.
Tātad, aplūkosim teksta paraugu.
Piemēram, Aleks, ko tu pēdējā laikā esi lasījis?
ALEKSS: Viena zivs, divas zivis, sarkanas zivis, zilas zivis.
DEIVIDS MALANS: Brīnišķīgi.
Ņemot to vērā, kādā klasē, jūsuprāt, Alekss pašlaik lasa?
Jūtieties brīvi vienkārši izkliegt to.
Pirmais, pirmais?
Tātad patiešām šonedēļ jūs redzēsit, ka, ja palaižat kodu Aleksa
tekstam, izrādīsies, ka viņš lasa zemāk par pirmās klases lasīšanas
līmeni.
Bet kāpēc tas varētu būt?
Kāda varētu būt jūsu intuīcija, kāpēc mēs esam apsūdzējuši Aleksu par
lasīšanu šādā līmenī?
Jūtieties brīvi izkliegties.
Jā.
Tik ļoti maz zilbju, īsu vārdu, īsu teikumu.
Un tāpēc, iespējams, no šī īsā teksta mēs varam secināt, ka ir zināma
heiristika, ka tas, iespējams, nozīmē, ka tas ir vislabākais
jaunākiem bērniem.
Turpretim Sāra, ko tu esi lasījusi?
SĀRA: Dērsliju kungs un kundze.
Four Privet Drive ar lepnumu teica, ka viņi ir pilnīgi normāli, liels
paldies.
Viņi bija pēdējie cilvēki, kurus jūs varētu sagaidīt, iesaistot kaut
ko dīvainu vai noslēpumainu, jo viņi vienkārši neizturēja daudz
muļķību.
DEIVIDS MALANS: Labi.
Neatkarīgi no tā, kurā klasē jūs mācāties, kad, iespējams, lasījāt šo
tekstu, kādā klasē Sāra šķita lasījusi?
Tātad astotā klase, otrā klase.
Labi.
Tātad, dzirdot mazliet no visa, tātad ar to, vismaz pēc koda,
faktiski būtu septītā klase.
Un kāda varētu būt intuīcija?
Kāpēc tas ir augstāks atzīmes līmenis, lai gan mēs varētu nepiekrist
tieši tā atzīmei?
Mērķauditorija: Sarežģīti teikumi.
DEIVIDS MALANS: Jā.
Tik sarežģīti teikumi, garāki teikumi.
Tāpēc Sāra runāja daudz vairāk vārdu, jo lapā bija daudz vairāk.
Tāpēc mēs šīs idejas tulkosim nākamajā nedēļā 2. problēmu kopā, ja
risināsiet šo problēmu, izmantojot kodu, lai galu galā varētu
kvantitatīvi secināt šīs idejas.
Bet, lai to izdarītu, mums būs jāsaprot teksts.
Tāpēc vispirms pateiksim paldies mūsu brīvprātīgajiem, un tad mēs
iedziļināsimies šajā zemākajā līmenī.
[APLAUSI]
Atvainojiet.
Jūs varat tos paturēt.
SĀRA: Ak, labi.
DEIVIDS MALANS: Labi.
Tātad, bez tam, aplūkosim vēl vienu teksta kopumu, ko jūs, iespējams,
redzēsiet šonedēļ, proti, kaut kas līdzīgs šim.
Tas, kas man ir redzams ekrānā, ir tas, ko mēs šodien sāksim saukt
par šifrētu tekstu.
Tas ir kādas informācijas šifrēšanas rezultāts.
Un šifrēšana vai vispārīgāk, kriptogrāfijas māksla un zinātne ir mums
visapkārt.
Tas ir tas, ko jūs izmantojat tīmeklī, savos tālruņos un bankās.
Un viss, kas cenšas nodrošināt datu drošību, izmanto šifrēšanu.
Taču būs dažādi šifrēšanas līmeņi — spēcīga šifrēšana, vāja šifrēšana.
Un tas, ko jūs redzat šeit uz ekrāna, nav tik spēcīgs, taču mēs
šodien redzēsim, kā mēs varētu to atšifrēt un faktiski atklāt, kas ir
vienkāršais teksts, kas atbilst šim šifrētajam tekstam.
Bet, lai to izdarītu, mums ir jāsāk, tā teikt, noņemt dažus
treniņriteņus.
Un ticiet vai nē, lai gan jūsu laiks šo pagājušo nedēļu redzētu pirmo
reizi, iespējams, drīzāk būtu bijis nezālē.
Un šķietami daudz sarežģītāks par C, izrādās, ka pa ceļam esam
nodrošinājuši un arī turpmāk nodrošināsim noteiktus treniņriteņus.
Piemēram, CS50 bibliotēka ir viena no tām, un pat daži skaidrojumi,
ko mēs sniedzam par tēmām šajās pirmajās nedēļās, būs nedaudz
vienkāršoti — ja vēlaties, tie tiks abstrahēti.
Bet galu galā mērķis ir jums izprast katru no šīm detaļām, lai pēc
CS50 jūs patiešām varētu stāvēt viens un saprast un apdomāt arī visas
nākotnes tehnoloģijas.
Tāpēc vispirms apskatīsim pašu pirmo programmu, ar kuru sākām
pagājušajā nedēļā, kas bija šī.
Tātad "sveika, pasaule" valodā C.
Dienas beigās tā patiešām bija funkcija printf, kas veica interesanto
darba daļu, taču virs un zem tās bija daudz tehnisku lietu.
Cirtainās iekavas, iekavas, vārdi, piemēram, tukšums un ietver, un,
protams, leņķiskās iekavas un citi.
Bet dienas beigās mums vajadzēja konvertēt šo avota kodu C valodā par
mašīnkodu, 0 un 1 bināros, ko dators saprata.
Un, lai to izdarītu, mēs, protams, paskrējām — mēs apkopojām kodu.
Mēs palaidām make, un tad mēs varējām faktiski palaist šo kodu tur.
Tāpēc ļaujiet man pāriet uz VS Code un ātri izveidot šo hello.c,
pārrakstot to pašu.
Tāpēc es varētu šeit iekļaut stdio.h, int main void.
Un tad šeit man bija pavisam vienkārši, sveiki, komats, pasaule ar
manu atpakaļvērsto slīpsvītru, beigu pēdiņām un daudz ko citu.
Tagad pēdējo reizi, lai to apkopotu, es patiešām palaidu make hello,
kam sekoja Enter.
Cerams, ka jūs neredzat kļūdas, un tas ir labi.
Un, ja jūs atzīmējat punktu, slīpsvītru, sveiki, jūs redzēsit šīs
programmas rezultātus.
Bet izrādās, ka make patiesībā nav kompilators, kā es minēju
pagājušajā nedēļā.
Tā ir programma, kas nepārprotami veido jūsu programmu, bet pati
tikai automatizē faktiskā kompilatora izmantošanas procesu.
Un tur ir daudz dažādu kompilatoru, un tas, ko tas faktiski izmanto
zem pārsega, ir kaut kas tāds, ko sauc par Clang for C Language.
Un Clang mūsdienās ir diezgan populārs kompilators.
Ir vēl viens, kas pastāv jau ilgu laiku, ko sauc par GCC, taču tie ir
tikai konkrēti nosaukumi kompilatoru veidiem, kurus faktiski ir
izveidojuši dažādi cilvēki, dažādi uzņēmumi, dažādas grupas.
Bet, ja 1. nedēļā pats izmantojat kompilatoru manuāli, jums ir
jāsaprot nedaudz vairāk par notiekošo, jo tas ir vēl noslēpumaināks
par to, ko vienkārši veidojat atsevišķi.
Tātad patiesībā ļaujiet man atgriezties pie sava termināļa loga,
ļaujiet man nedaudz notīrīt ekrānu un vienkārši palaist neapstrādāto
kompilatora komandu.
Tātad tas, kas man ir automatizācija, ļaujiet man to izdarīt manuāli
tikai uz brīdi.
Tātad, ja es vēlos kompilēt hello.c izpildāmā programmā, kuru varu
palaist, es varu darīt to.
clang, atstarpe, hello.c un pēc tam Enter.
Un tagad nav izvades, kas šajā gadījumā ir laba lieta, nav kļūdu,
taču ievērojiet to.
Ja es ievadu ls, manā pašreizējā mapē pēkšņi ir izveidots fails, ko
dīvaini sauc par a.out.
Tas nozīmē Assembler Output.
Īsi sakot, tas faktiski ir noklusējuma nosaukums programmai, kas tiek
izveidota, kad jūs vienkārši palaižat Clang.
Tagad tas ir diezgan slikts programmas nosaukums, jo tajā nav
aprakstīts, ko tā dara.
Tāpēc labāk būtu, ja a.out vietā, kas, jā, joprojām drukā
hello.world, bet nav īsti skaidri nosaukta programma, būtu jauki
nosaukt šo hello.
Tātad, ko es varētu darīt?
Es varētu darīt tā, kā mēs mācījāmies pagājušajā nedēļā, es varētu
pārdēvēt a.out par hello, izmantojot Linux komandu mv.
Tāpēc es pārvācos, lai kļūtu sveiks.
Bet arī tas šķiet garlaicīgi.
Tagad man ir trīs soļi.
Piemēram, uzrakstiet savu kodu, apkopojiet manu kodu un pēc tam
pārdēvējiet to, pirms varu to palaist.
Mēs varam darīt labāk par to.
Un tā izrādās, ka noteiktas komandas, piemēram, clang, atbalsta to,
ko mēs šodien sāksim, izsaucot komandrindas argumentus.
Komandrindas arguments, atšķirībā no funkcijas argumenta, ir tikai
papildu vārds vai atslēgas frāze, ko ievadāt pēc komandas uzvednē
termināļa logā, kas tikai maina šīs komandas darbību.
Tas to konfigurē nedaudz precīzāk.
Tātad tas, ko jūs redzat šeit uz ekrāna, ir dažas no labākām
komandām, ar kurām palaist clang, lai tagad es varētu norādīt šīs
komandas izvadi atbilstoši šim o.
Tātad darīt to, ko es ar to domāju?
Ļaujiet man vēlreiz notīrīt termināļa logu un precīzāk ierakstīt
clang -o hello hello.c un pēc tam Enter.
Šķiet, ka atkal nekas nenotiek, taču tas ir labi, ja neredzat nekādas
kļūdas un tagad tikko izveidotā programma tiek saukta par Hello.
Tātad tas patiešām sasniedz tādu pašu precīzu efektu kā make, bet ko.
Man nav sakara ar make ir ierakstiet un atcerieties kaut ko tik ilgi,
kamēr šī komanda.
Un arī tas ir mazliet balti meli.
Izrādās, mēs esam iepriekš konfigurējuši VS Code mākonī, lai jūs
varētu izmantot arī dažas citas Clang funkcijas, kuru rakstīšana jums
būtu vēl apnicīgāka.
Un tāpēc mēs to destilējam kā tikai darbojošos ražojumu.
Tāpēc ļaujiet man pauzēt šeit, lai vispirms noskaidrotu, vai ir kādi
jautājumi par to, ko esmu paveicis, izmantojot savu pirmo programmu C
valodā un tikai tagad kompilējot to vispirms ar make, bet pēc tam
sāku no jauna un tagad manuāli kompilējot to ar clang ar to, ko mēs
izsauks komandrindas argumentus.
-o, atstarpe, sveiki un pēc tam faila nosaukums.
Jā?
AUDITORIJA: Kas ir a.out?
DEIVIDS MALANS: Jā.
Tātad a.out ir vēsturisks nosaukums.
Tas attiecas uz montētāja izvadi — vairāk par to drīzumā.
Un tas ir tikai noklusējuma faila nosaukums, ko iegūstat automātiski,
ja vienkārši palaižat kompilatoru jebkuram failam, lai tam būtu tikai
standarta nosaukums.
Bet tā nav īpaši labi nosaukta programma.
Tā vietā, lai Mac vai personālajā datorā palaistu Microsoft Word, tas
būtu kā dubultklikšķis uz a.out.
Tā vietā, izmantojot šos komandrindas argumentus, varat pielāgot
Clang izvadi un nosaukt to sveiki vai jebko, ko vēlaties.
Citi jautājumi par to, ko es šeit esmu darījis ar pašu Clang,
kompilatoru?
Jā?
Mērķauditorija: Kas ir -o?
DEIVIDS MALANS: Tātad -o-- un jūs to zinātu tikai pēc rokasgrāmatas
izlasīšanas un klases, kas nozīmē rezultātu.
Tātad -o nozīmē mainīt Clang izvadi uz failu ar nosaukumu hello,
nevis noklusējuma failu, kas ir a.out.
Un arī šī atkal ir detaļa, kas jums būtu jāatlasa tīmekļa lapā,
jāizlasa rokasgrāmata un jādzird kāds, piemēram, man, pastāstot par
to.
Un patiesībā ir pat vairāk nekā šīs iespējas, taču mēs šeit tikai
noskrāpēsim virsmu.
Labi.
Tātad, ja mēs tagad to zinām, kas vēl patiesībā notiek zem pārsega?
Apskatīsim tuvāk ne tikai šo mana koda versiju, bet arī manu nedaudz
sarežģītāko pagājušās nedēļas versiju, kas izskatījās apmēram šādi,
kur es pievienoju kādu dinamisku lietotāja ievadi, lai varētu
nesasveicināties. pasaule visiem, bet sveiks, Deivid vai sveiks
ikvienam, kurš patiešām vada šo programmu.
Tāpēc patiesībā ļaujiet man iet uz priekšu un mainīt savu kodu šeit
VS Code, lai tas atbilstu tam pašam kodam no pagājušās nedēļas.
Tātad jauna koda vēl nav.
Pēc brīža es to vienkārši apkopošu nedaudz citādākā veidā.
Tāpēc es izdarīju pagājušās nedēļas virkni, manuprāt, atbilde ir
vienāda ar virkni, citāts un citāts: "Kā tevi sauc?" Tāpat
kā Scratch.
Un tad šeit, tā vietā, lai darītu pasauli, es sākotnēji uzrakstīju
atbildi, bet tas neizdevās.
Ko es galu galā izdarīju, lai izdrukātu sveiki, Deivid vai sveiks, tā
un tā?
Jā?
Atvainojiet, mazliet skaļāk?
AUDITORIJA: %s?
DEIVIDS MALANS: Jā, tātad %s, tā sauktais formāta kods, ar kuru
printf vienkārši zina, kā rīkoties.
Un man bija jāpievieno vēl viena lieta.
Kāds cits, izņemot %s — jā?
AUDITORIJA: mainīgā nosaukums.
DAVID MALAN: Mainīgā nosaukums, kuru vēlos pievienot vietturim %s.
Un šajā gadījumā tā ir atbilde.
Tagad ļaujiet man veikt vienu precizējumu tikai tāpēc, ka tagad ir
2. nedēļa, un mēs sāksim rakstīt vairāk koda rindiņu, lai gan Scratch
sauca atgriešanās vērtību jautāt puzles gabalam, atbildiet vienmēr.
Un redziet, mums ir pilnīga kontrole pār to, kā tiek saukti mūsu
mainīgie.
Un tagad, ja izmantoju get_string, droši vien ir labi ne vienmēr
izsaukt savu mainīgo atbildi.
Sauksim to kā tas ir.
Tātad tas tagad ir tikai stila jautājums, ja vēlaties.
Ļaujiet man mainīt mainīgo uz nosaukumu, lai man, jums, uz TF vai TA
būtu mazliet skaidrāk, ko šis mainīgais attēlo, nevis vispārīgāku
atbildi.
Labi, ļaujiet man doties uz savu termināļa logu, un pagājušajā nedēļā
es atkal paskrēju make, lai kompilētu tieši šo pašu programmu.
Tomēr tagad ļaujiet man iet uz priekšu un vienkārši izmantot
zvanīšanu.
Tātad klan -o-- Es joprojām saukšu šo versiju hello-- space, hello.c.
Tātad tieši tāda pati komanda kā iepriekš.
Vienīgais, kas atšķiras, ir pievienojis vēl pāris koda rindiņas, lai
iegūtu lietotāja ievadi.
Ļaujiet man nospiest taustiņu Enter, un tagad, bļin, mūsu pirmā kļūda.
Tātad, izvadīt no clang and make nav laba lieta, un šeit mēs redzam
kaut ko īpaši noslēpumainu.
Tātad kaut kas funkcijā “main--” nenoteiktā atsaucē uz “get_string”,
virkni un pēc tam saistīšanas komandu neizdevās ar izejas kodu 1.
Tātad patiesībā ir daudz žargona, kas šodien kaitinās, taču mans
mājiens ir tāds, ka acīmredzami mana problēma ir galvenā, lai gan tas
nav pārsteidzoši, jo nekas cits šeit nenotiek.
get_string ir problēma, un problēma ir tā, ka tā ir nedefinēta
atsauce.
Un tomēr, ievērojiet, man bija diezgan labi.
Es pievienoju CS50 galvenes failu un pagājušajā nedēļā teicu, ka ar
to pietiek, lai iemācītu kompilatoram, ka funkcijas pastāv, taču
problēma ir tāda, ka, lai gan patiesībā tas māca Clang, ka get_string
eksistē, tā nav pietiekama informācija, lai Clang varētu darboties.
atrodiet datora cietajā diskā 0 un 1, kas faktiski ievieš pašu
get_string.
Citiem vārdiem sakot, šī iekļautā rinda pagājušajā nedēļā ir neliels
mājiens.
Tas ir īss Clang, ka jūs gatavojaties redzēt un izmantot šo funkciju
kaut kur.
Bet, ja jūs patiešām vēlaties izmantot 0 un 1, ko CS50 rakstīja pirms
kāda laika, un iekļaut tos savā programmā, lai jūsu programma tiešām
zinātu, kā iegūt ievadi no lietotāja, tad man būs jāsāk. nedaudz
atšķirīga komanda.
Tāpēc ļaujiet man to izdarīt.
Ļaujiet man notīrīt savu termināļa logu, lai atbrīvotos no šī
traucējuma, un ļaujiet man tagad ieteikt palaist šo komandu.
Gandrīz tāpat kā iepriekš, clang -o, space, hello, tad hello.c, bet
ar vienu papildu komandrindas argumentu beigās, un tas ir -l--, nevis
skaitlis 1.
Tātad -lcs bez atstarpes starp šiem diviem.
Tagad l rezultātā visas tās 0 un 1, kuras faktiski bija CS50, tiks
saistītas ar jūsu kodu, jūsu dažām koda rindiņām vai manējā šeit.
Bet tas ir otrais solis, kas kompilatoram ir nepieciešams, lai
zinātu, kā faktiski izpildīt un drīzāk apkopot savu kodu un CS50.
Un CS50 nav vienīgais, kas to dara.
Ja izmantojat kādu trešās puses bibliotēku programmā C, kas nav
iekļauta valodai, jūs to darītu - tā un tā, kur nu kurš -, tomēr viņi
ir nosaukuši savu bibliotēku.
Bet jums tas nav jādara iebūvētu lietu dēļ, kuras mēs līdz šim esam
izmantojuši.
Labi, ļaujiet man iet uz priekšu un izmēģināt šo.
Es atgriezīšos pie VS Code šeit un ļaujiet man turpināt un palaist
clang -o hello, then hello.c.
Un tagad tā vietā, lai vienkārši nospiestu taustiņu Enter, -lcs50 bez
atstarpes starp l un cs50, ievadiet taustiņu Enter.
Tagad nekas slikts nenotiek, un tagad es varu darīt ./sveiki.
kā tevi sauc?
Es ierakstīšu David, Enter, un tagad mēs redzēsim, sveiks, Deivid.
Godīgi sakot, šeit mēs patiešām iekļūstam nezālēs, un tagad tas
notiek — tas patiesībā tikai rada papildu traucējumus jūsu koda
kompilēšanas un palaišanas procesam.
Un tā realitāte ir tāda, ka, lai gan tas patiešām notiek, mēs
izmantojām pagājušajā nedēļā un turpināsim izmantot šo nedēļu, jo tas
tikai automatizē visu procesu jūsu vietā.
Taču ir ideāli, lai saprastu, kas notiek nepareizi, jo visi kļūdu
ziņojumi, ko redzējāt 1. problēmu kopai, kāds no kļūdu ziņojumiem, ko
redzat dažu nākamo nedēļu laikā, iespējams, nenāk no ražotāja, tie
nāk no Clang zem pārsega. jo make ir tikai procesa automatizācija.
Bet ar make, jūs burtiski vienkārši ierakstāt make un pēc tam
programmas nosaukumu, jums nav jāuztraucas par šiem komandrindas
argumentiem.
Vai tad ir jautājumi par kompilēšanu ar dash -lcs50 vai ko citu?
Jā?
ieguvums no [NEdzirdams]?
DEIVIDS MALANS: Atvainojiet, kāds ir labums no-- AUDITORIJA: Clang
manuāla izmantošana.
DEIVIDS MALANS: Kāds ir Clang manuālas lietošanas ieguvums?
Neviens, tiešām.
Faktiski viss galvenais, ko dara, ir tikai teikt — tas nozīmē, ka mēs
ietaupām dažus taustiņu nospiešanas.
Tomēr, ja vēlaties un vēlaties vairāk kontrolēt, varat pilnībā
palaist Clang manuāli, ja atceraties dažādus komandrindas argumentus.
Jā?
jāpaskaidro [NEdzirdams]
DEIVIDS MALANS: Tieši tā.
Kāpēc man bija jāpaskaidro, tas ir, jāsniedz mājiens uz CS50 ar
galvenes failu cs50.h, bet man tas nebija jādara ar standarto.h?
Tikai tāpēc.
Standardo.h nāk ar C, tāpat kā dažas citas bibliotēkas ir komplektā
ar C, ko mēs sāksim redzēt šodien.
Tomēr CS50 nav visur iebūvēts C, un tāpēc jums tas ir skaidri
jāpievieno.
Jā?
komandrindas arguments [NEdzirdams]?
DAVID MALAN: Komandrindas arguments ir vārds vai frāze, ko ievadāt
komandrindā — AKA — jūsu terminālis, lai ietekmētu programmas
darbību.
AUDITORIJA: Labi.
Tātad tas ir termins tam, ko jūs tam piešķirat.
DEIVIDS MALANS: Jā.
Tas maina noklusējuma iestatījumus.
Mūsu GUI pasaulē, grafiskajā lietotāja interfeisā, jūs un es,
iespējams, noklikšķināsim uz dažiem lodziņiem, mēs atlasītu dažas
izvēlnes opcijas, lai konfigurētu programmu, lai tā darbotos vienādi.
Komandrindas interfeisā jums ir vienkārši jāsaka viss uzreiz, un
tāpēc mums ir komandrindas argumenti.
Jā?
Mērķauditorija: ir [dzirdams]
DEIVIDS MALANS: Nē.
Marka ir paredzēta ne tikai CS50.
Mūsdienās tas tiek izmantots visā pasaulē jebkurā projektā,
izmantojot C, C++ un pat citas valodas.
Faktiski gandrīz visas komandas, kuras redzat šajā klasē, ja vien tās
beigās nav 5-0, tiek izmantotas globāli.
Tikai tie — sufikss ar 50 patiešām ir specifiski kursam.
Un pat tie, kuriem mēs pakāpeniski noņemsim treniņriteņus, lai arī
šīs komandas veiktu tieši to, ko dara.
Labi, ko mēs tikko izdarījām?
Viss, ko tikko esam izdarījuši, protams, es turpinu saukt par
kompilēšanu, bet nolaidīsimies uz vienu truša caurumu, lai jūs
saprastu, ka, kompilējot kodu, patiesībā notiek vesela virkne
darbību, un tas ļaus daudz ko darīt. funkcijas, piemēram, uzņēmumi
var rakstīt kodu un pēc tam pārveidot to, lai tas darbotos gan Mac
datoros, gan personālajos datoros, tālruņos vai tamlīdzīgi.
Tātad runa nav tikai par avota koda konvertēšanu mašīnkodā, patiesībā
ir četras darbības, kas saistītas ar to, ko jūs un es no pagājušās
nedēļas zinām kā kompilēšanu.
Un tie nav termini, kas jums būs pastāvīgi jāpatur prātā, jo atkal
mēs daudz ko no tā abstrahēsim.
Bet, lai mēs vienreiz būtu nokļuvuši truša bedrē, apsveriet katru no
šiem četriem soļiem, kas jums ir notikuši nedēļu automātiski, no
kuriem pirmais tiek saukts par priekšapstrādi.
Tātad, ko tas nozīmē?
Apskatīsim to pašu programmu kā iepriekš.
Tāpēc ievērojiet, ka divas no koda rindām sākas ar jaucējzīmi.
Tas ir īpašs simbols valodā C, un tā ir tā sauktā priekšprocesora
direktīva.
Jums nav jāiegaumē šādi termini, bet tas tikai nozīmē, ka tas nedaudz
atšķiras no visām pārējām rindām.
Un viss, kam šeit ir jaukšanas simbols, ir iepriekš jāapstrādā — tas
ir, vispirms jāanalizē, pirms notiek kaut kas cits.
Tātad, aplūkosim šīs divas līnijas augšpusē, kas tieši notiek.
Nu, izrādās, ka ar šīm divām rindām jums ir divi galvenes faili,
protams, cs50.h un stdio.h.
Kur ir tie faili, jo šķiet, ka tie nekad nav bijuši jūsu vietā VS
Code.
Ja ierakstāt LS — ja GUI atverat File Explorer, jūs, iespējams, nekad
neesat redzējis cs50.h vai stdio.h.
Tie vienkārši darbojas, bet tas ir tāpēc, ka kaut kur cietajā diskā
ir mape, kuru izmantojat savā Mac vai personālajā datorā, vai kaut
kur mākonī, kā tas ir mūsu gadījumā.
Un šīs mapes iekšpusē, ko tradicionāli sauc par /usr/include.
Un lietotājs ir apzināti nepareizi uzrakstīts.
Tas ir tikai nedaudz kodolīgāks, lai gan ir nedaudz dīvaini, kāpēc
mēs atmetam šo vienu burtu.
Bet usr/include ir tikai mape serverī, kurā ir cs50.h, stdio.h un vēl
daudzas citas lietas.
Tātad, ja termināļa logā ierakstāt VS kodu, kad izmantojat koda
vietas mākonī un ierakstāt LS space /usr/include, jūs varat redzēt
visus šajā mapē esošos failus.
Bet mēs esam iepriekš instalējuši visu šo saturu jūsu vietā.
Apskatīsim, kas patiesībā ir šajos failos.
Ja es izceļu šīs divas rindas, kas sākas ar jaucējvārdu, tad
pagājušajā nedēļā es devu mājienu, ka tas, kas atrodas šajā pirmajā
failā, ir mājiens par to, kādas funkcijas jums ir uzrakstījis CS50.
Tātad jūs varat uzskatīt, ka šīs rindas ir pagaidu vietturi, kas var
kļūt par globālu atradumu un aizstāšanu.
Pirmā lieta, ko clang darīs, ir šī faila priekšapstrāde.
Tas meklēs jebkuru rindiņu, kas sākas ar hash include.
Un, ja tas to pamana, tas būtībā nonāks šajā failā, piemēram, cs50.h,
un pēc tam vienkārši kopēs un maģiski ielīmēs šī faila saturu.
Jūs to vizuāli neredzat ekrānā.
Bet tas notiek aizkulisēs.
Un patiesībā ar šo pirmo rindiņu notiek tas, ka kaut kur failā cs50.h
ir getString deklarācija, kā mēs runājām pagājušajā nedēļā, un,
iespējams, tas izskatās nedaudz līdzīgs šim.
Un pagājušajā nedēļā mēs tam vēl netērējām daudz laika, bet ar laiku
mēs to darīsim.
Ņemiet vērā, ka funkcija tiek deklarēta šādi.
Tas ir, tas ir nolemts pastāvēt.
Funkcijas nosaukums, protams, ir getString.
Iekavās ir tā argumenti.
Šajā gadījumā ir viens arguments getString, es apgalvoju šodien, taču
jūs to zinājāt netieši.
Un tas ir pamudinājums.
Tas ir uzvedne, ko cilvēks redz, kad izmantojat getString.
Kas tas par uzvedni?
Nu, tā ir teksta virkne, piemēram, citāts bez pēdiņām, "kā tevi
sauc?" vai kaut kas cits, ko es jautāju pagājušajā nedēļā.
Tikmēr getString, kā mēs zinām no pagājušās nedēļas, ir atgriešanās
vērtība.
Tas jums kaut ko atgriež.
Un arī tā ir virkne.
Tātad atkal to sauc arī par funkciju prototipu.
Tā ir lieta, ko pagājušās nedēļas beigās es tikko nokopēju un
ielīmēju no sava faila apakšas uz augšdaļu, lai tas būtu kā šis
tīzeris, lai aprunātos par to, kas pastāvēs vēlāk.
Tātad jūs varat domāt, ka tajās ir iekļautas rindas kā visu šo
funkciju deklarāciju apvienošana atsevišķā failā cs50.h, lai jums
pašam tās nebūtu jāievada katru reizi, kad izmantojat bibliotēku vai
sliktāk, lai tev pašam šīs rindas nav jākopē un jāielīmē.
Tas ir tas, ko clang dara jūsu labā pirmajā priekšapstrādes posmā.
Otrkārt un pēdējais šajā piemērā, kas notiek, ja clang iepriekš
apstrādā šo otro iekļaušanas rindiņu?
Vienīgā cita funkcija, kas mums rūp šajā stāstā, protams, ir printf,
kas nāk kopā ar C.
Tātad būtībā jūs varat iedomāties printf prototipu vai deklarāciju kā
tādu.
Printf ir funkcijas nosaukums.
Tam nepieciešama virkne, kuru vēlaties formatēt, piemēram, Hello
Comma world vai Hello Comma %s.
Un tad ar punktu, punktu, punktu tam faktiski ir tehniska nozīme.
Tas, protams, nozīmē, ka varat pievienot 0 mainīgo, 1 mainīgo, 2
Tātad punkts, punkts, punkts nozīmē noteiktu mainīgo skaitu.
Tagad mēs par to vēl neesam runājuši.
Un kopumā mēs to nedarīsim.
printf faktiski atgriež vērtību, skaitli, kas ir vesels skaitlis.
Bet par to vairāk varbūt citreiz.
Parasti programmētājs to neskatās.
Bet tas ir viss, ko mēs domājam ar priekšapstrādi, lai šī procesa
beigās, lai gan failos cs50.h un stdio.h ir vairāk koda rindiņu,
patiesībā notiek tikai tas, ka faila pirmapstrādes laikā tiek
nokopēts un ielīmēts šo failu saturu savā kodā, lai tagad jūsu kods
zinātu par visu — getString, printf un jebko citu.
Vai ir kādi jautājumi par šo pirmo soli, priekšapstrādi?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Labs jautājums.
Ja iekļaujat failu, vai tajā ir iekļauts tikai tas, kas jums
nepieciešams, vai arī viss?
Padomājiet par to, ka tas ietver visu.
Tātad, ja tas ir liels fails, tas ir daudz koda pašā augšpusē.
Un tieši tāpēc, ja padomājat uz visām nullēm un vieniniekiem, ko
rādīju pirms neilga laika, kā arī pagājušajā nedēļā, ekrānā ir daudz
nulles un vieninieku, kas tiek parādīti, vienkārši ierakstot: Sveiki!
pasaule.
Daudzas no šīm nullēm un vieniniekiem, iespējams, nāk no koda, kas
patiesībā jums nebija vajadzīgs.
Bet daži no tiem, iespējams, ir, taču ir veidi, kā arī to optimizēt.
Labi, tāpēc otro kompilēšanas soli mulsinoši sauc par kompilēšanu.
Vienkārši šo terminu visi izmanto, lai aprakstītu visu procesu, nevis
tikai šo vienu posmu.
Bet, kad kompilators aizkulisēs ir iepriekš apstrādājis programmu,
tagad tā izskatās apmēram šādi.
Un es ievietoju punktu, punktu, punktu, lai norādītu, ka, jā, uz jūsu
jautājumu, virs tā ir vairāk lietu.
Zem tā ir vairāk lietu.
Mums tas vienkārši šobrīd nav interesanti.
Tātad tagad mums ir tikai C kods.
Nav vairs nekādu priekšapstrādātāja direktīvu.
Šobrīd visi jaucējsimboli un šīs koda rindas ir iepriekš apstrādāti
un pārveidoti par kaut ko citu.
Un tā tagad — un šeit lietas izskatās nedaudz spokainas.
Lūk, kas notiek, kad clang vai jebkurš kompilators burtiski apkopo
šādu kodu.
Tas pārvērš to no šī C uz šo montāžas kodā.
Tātad šī ir viena no baisākajām valodām.
Man pašam īsti nav patīkamu atmiņu.
Šī nav valoda, kurā daudzi cilvēki programmējas.
Ja jūs mācāties nākamajā datorzinātnē, sistēmās, augstāka līmeņa
klasē, jūs patiešām varētu apgūt šo vai kādu no tā variantiem.
Taču ir vismaz daži cilvēki, kuriem šīs lietas ir jāzina, jo tas ir
tuvāk tam, ko mūsdienās saprot paši datori.
Intel CPU vai AMD CPU, mūsdienu datoru un tālruņu smadzenes saprot
lietas, kas vairāk izskatās šādi un mazāk līdzinās C.
Tagad tas ir pilnīgi ezotērisks, bet ļaujiet man tikai izcelt dažas
frāzes.
Ir dažas lietas, kas ir mazliet pazīstamas.
Tur augšpusē dzeltenā krāsā ir minēts galvenais.
Apakšā ir minēts getString.
Zemāk ir minēts printf.
Tātad šī ir tikai vēl viena programmēšanas valoda, ko sauc par
montāžas valodu un kurā pirms gadu desmitiem cilvēki — arī es skaitot
viņu skolā — rakstīja kodu.
Un noteikti, daži cilvēki joprojām raksta šo kodu, jo īpaši tāpēc, ka
jūs varat uzrakstīt ļoti, ļoti efektīvu kodu.
Bet tas ir daudz noslēpumaināks.
Tas ir daudz mazāk lietotājam draudzīgs.
Tātad jūs tagad redzēsiet dzeltenā krāsā, tās ir tā saucamās
instrukcijas, ko saprot datora smadzenes vai centrālais procesors,
bīdot vērtības, pārvietojot tās, atņemot vērtības, izsaucot funkcijas
un pārvietojot, pārvietojot, pārvietojot.
Tātad patiesībā zemā līmeņa darbības, ko saprot datori, parasti ir
aritmētiskas darbības — atņemšana, saskaitīšana un tamlīdzīgi — lietu
pārvietošana atmiņā un no tās.
Tādiem cilvēkiem kā mēs ir daudz apnicīgāk rakstīt šādu kodu.
Tāpēc mēs ar jums mēdzam rakstīt šādas lietas.
Un ideālā gadījumā tādiem cilvēkiem kā jūs un es mēdzam vilkt un
nomest puzles gabalus, kas to visu veido abstrakti tālāk.
Bet pagaidām to atkal sauc par montāžas valodu.
Tas notiek, kad kompilators burtiski apkopo jūsu kodu.
Bet, protams, šis, joprojām nav nulles un vieninieki.
Tātad mums ir jāveic divi soļi.
Tātad, kad kompilators pāriet uz trešo darbību, šeit lietas tiek
pārveidotas mašīnkodā.
Un, kad kompilators apkopo jūsu kodu, tas pārvērš to, ko mēs tikko
redzējām šeit ekrānā, par faktiskajām nullēm un vieniniekiem — tā
sauktajā mašīnkodā, ko saprot jūsu tālrunis vai dators.
Taču ir vērts atzīmēt, ka šīs ne vienmēr ir visas jūsu programmas
nulles un vieninieki.
Jā, tās ir nulles un vieninieki, kas atbilst programmai Hello vai
printf un getString un tamlīdzīgi, taču ņemiet vērā, ka šeit ir
nepieciešams pēdējais solis.
Tajās nulles un vieninieki ir tikai jūsu koda rindas.
Bet kā ir ar CS50 koda rindām, kuras mēs rakstījām, lai ieviestu
getString?
Kā ir ar koda rindām, kuras cilvēki rakstīja pirms gadu desmitiem,
lai ieviestu printf?
Tie atrodas kaut kur šajā cietajā diskā, piemēram, manā Mac datorā,
datorā vai kaut kur mākonī, taču mums ir jāapvieno visas šīs nulles
un vieninieki un jāsaista mans kods ar CS50 kodu ar standarta I/O
kodu. .
Un tas, kas notiek pēdējā solī, galu galā ir tāds, ka, ja mums šeit
ir mans kods dzeltenā krāsā un pēc tam kods, ko uzrakstīja CS50, un
kods, ko uzrakstīja paši C autori, patiesībā notiek tas, ka kaut kur
mēs ir ne tikai hello.c, ko, protams, es rakstīju un rakstīju kopā ar
mums šeit, bet arī, pieņemsim, kaut kur datorā ir fails cs50.c, kuru
nejauši es un CS50 darbinieki rakstījām pirms gadiem.
Un arī kaut kur datorā ir vēl viens fails.
Ļaujiet man pārāk vienkāršot, vienkārši nosaucot to par stdio.c.
Praksē to droši vien īpaši sauc par printf.c.
Bet tie ir kaut kur, šie divi citi faili.
Un tāpēc šis pēdējais solis, ko sauc par saistīšanu, paņem manas
nulles un vienus no tikko ierakstītā koda, proti, šī koda ekrānā.
Pēc tam tas satver nulles un vieniniekus, ko ierakstīja CS50.
Un tas satver nulles un vieniniekus, ko rakstīja C autori, lai
ieviestu standarta I/O bibliotēku.
Un visbeidzot, voila, saista tos visus kopā.
Un tas ir tas pats nulles un vieninieku lāse, ko mēs redzējām
iepriekš.
Tas tikai tagad ir jūsu koda priekšapstrādes, koda kompilēšanas, koda
salikšanas, koda saistīšanas rezultāts, un, mans Dievs, šobrīd,
piemēram, ja programmēšana jums vēl būtu bijusi jautra, mēs to visu
esam atņēmuši. , mēs vienkārši saucam visu šo procesu par
kompilēšanu.
Kāpēc?
Tā kā tagad, kad mēs zinām, ka šie soļi pastāv — un gudri cilvēki šo
problēmu atrisina mūsu vietā, jūs un es varam darboties šādā
abstrakcijas līmenī un pieņemt, ka kompilēšana pārvērš pirmkodu
mašīnkodā.
Vai jums ir jautājumi par kādu no šiem starpposmiem?
Jā?
dažādas daļas, piemēram, [dzirdams]?
DEIVIDS MALANS: Labs jautājums.
Tātad, kur tiek glabātas visas šīs nulles un viens?
Tā kā jūs un es, mēs esam izmantojuši pārlūkprogrammu, vai ne?
code.cs50.io, protams, ir šī tīmekļa lietotāja saskarne.
Bet atkal atcerieties no pagājušās nedēļas, lai gan jūs izmantojat
tīmekļa pārlūkprogrammu, lai piekļūtu VS kodam, šī VS koda tīmekļa
versija ir savienota ar faktisku serveri kaut kur mākonī.
Un šajā serverī jums ir savs konts un savi faili, un patiešām savs
cietais disks, praktiski mākonī.
Padomājiet par to mazliet kā Dropbox vai Box, vai Google disku,
OneDrive vai kaut ko tamlīdzīgu.
Tātad jums kaut kur ir cietais disks, ko esam jums nodrošinājuši.
Un tieši šajā cietajā diskā ir jūsu kods, ko tikko ierakstījāt vai es
tikko uzrakstīju, cs50.c, stdio.c un viss pārējais kods, kas ievieš
matemātikas funkcijas un visu pārējo, ko atbalsta C.
Labs jautājums.
Jā?
bibliotēka, rinda [dzirdams]
precīza lieta [NEdzirdams]
kopēt un ielīmēt tos līdz galam?
DEIVIDS MALANS: Labs jautājums.
Šajā hash ietver cs50.h rindiņu mana koda augšpusē.
Ja es to vienkārši aizstātu ar cs50.c saturu, vai tas darbotos?
Īsa atbilde, jā, tas derētu.
Tur varētu nokopēt visu kodu.
Tomēr var būt zināma darbību secība.
Un tāpēc tas, iespējams, nav tik vienkārši, kā kopēt, ielīmēt.
Bet konceptuāli, jā, tā tas notiek.
Tagad, ņemot vērā to, cs50.h ir tikai funkciju prototipi, padomi par
to, kā funkcijas izskatās, kāds ir to atgriešanas veids, kāds ir to
nosaukums un kādi ir to argumenti.
Faktiskais kods parasti tiek rakstīts dot c failā.
Un tas tagad ir nedaudz mulsinoši, jo jūs un es esam ierakstījuši
kodu tikai c punkta failos.
Taču dažu nākamo nedēļu laikā jūs faktiski sāksit rakstīt arī dažus
savus dot h failus, tāpat kā CS50, tāpat kā standarta I/O.
Bet būtībā šī koda rindiņa tikai atvieglo jau uzrakstītā koda
lietošanu un atkārtotu izmantošanu.
Un tā ir visa bibliotēkas būtība.
AUDITORIJA: vai to saistīšana ir [NEdzirdama]?
DEIVIDS MALANS: Sakiet to nedaudz skaļāk.
AUDITORIJA: Vai saistīšana notiek, kad izmantojat kompilatoru?
DEIVIDS MALANS: Jā.
Vai saistīšana notiek, kad apkopojat kodu?
Jā.
Palaižot make, kā mēs to darām pagājušajā nedēļā, notiek visas četras
šīs darbības.
Iepriekšēja apstrāde pārvērš iekļaušanas jaucējrindas par kaut ko
citu.
Kompilēšana tehniski pārvērš to montāžas kodā, ko Mac, PC, serveris
saprot tuvāk.
Assembly pārvērš šo valodu binārā mašīnkodā, ko šis dators faktiski
saprot.
Un tad saistīšana apvieno visu kopā.
Un patiesībā, ja padomājat pirms dažām minūtēm, kad es to izdarīju
-lcs50, iemesls, kāpēc man tas bija jāpievieno, un iemesls, kāpēc
mans kods sākumā netika kompilēts, bija tāpēc, ka es aizmirsu pateikt
clang to link CS50. nulles un vieninieki šajā pēdējā solī.
Man nav jādara -lstdio, jo tas nāk kopā ar C, tāpēc tas būtu
vienkārši nogurdinoši ikvienam pasaulē.
Bet CS50 nav komplektā ar C, tāpēc mēs to saistām.
Un, lai būtu skaidrs, mēs ne vienmēr izmantosim CS50 bibliotēku.
Tas būs vēl viens treniņriteņu pāris, ko mēs noņemsim tuvāko nedēļu
laikā.
Bet pagaidām tas padara dažas lietas vienkāršākas.
Jā?
AUDITORIJA: Kas ir [dzirdams]?
DEIVIDS MALANS: Īsa atbilde, jā.
Tātad, ko nozīmē nulles un vieninieki, mašīnas kods?
Jā, pastāv savstarpēja saistība starp mašīnas kodu un montāžas kodu.
Montāžas kods, tas nav īsti angļu valodā, bet vismaz es atpazīstu tos
simbolus.
Tās nav nulles un vieninieki.
Mašīnkods, protams, ir tikai nulles un vieninieki.
Tātad tajā laikā, pirms C pastāvēja, cilvēki programmēja tikai
montāžas kodā.
Pirms montāžas koda pastāvēšanas cilvēki kodēja ar nullēm un
vieniniekiem.
Un jūs varat iedomāties, cik tas bija sāpīgi, un tāpēc katra no šīm
valodām padara mūsu dzīvi vieglāku un vieglāku.
Pēc dažām nedēļām mēs pāriesim uz Python, kas savukārt padarīs C vēl
vienkāršāku — vai arī kodēšanu kopumā būs vienkāršāku.
Labi, tātad, ko mēs tagad varam darīt – kas šajā gadījumā varētu
noiet greizi?
Nu, izrādās, ka bez kompilēšanas, tehniski runājot, ir arī
dekompilēšana.
Un mēs to neesam darījuši, un mēs to nedarīsim.
Bet ir vērts to padomāt tikai uz brīdi.
Ja jūs nevis kompilējat savu kodu, bet gan dekompilējat — kā norāda
vārds, tas nozīmē tikai procesa apvēršanu, ideālā gadījumā to
pārveidojot no mašīnas koda — nullēm un vieniniekiem — varbūt atpakaļ
uz C.
Tagad tas būtu forši, iespējams, ja viss, kas jums ir, ir programma,
varat to konvertēt un redzēt faktisko pirmkodu.
Kāds varētu būt mīnuss, ja kāds internetā var dekompilēt kodu savā
datorā?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Labi, tāpēc kodā ir vieglāk atrast kļūdas, kuras var
izmantot.
Tāpēc varētu būt vieglāk uzlauzt programmatūru, atrodot kļūdas, kuras
jūs un es pieļāvām, jo burtiski viņi skatās uz jums kodā, savukārt
nulles un vieninieki padara to mazāk acīmredzamu.
Citi negatīvie aspekti, ko es saucu par dekompilēšanu?
Jā?
Mērķauditorija: ja lietas ir aizsargātas ar autortiesībām vai jūs pat
nezināt, kā to iegūt - DEIVIDS MALANS: Jā.
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Jā, ja jūsu kods, jūsu darbs ir jūsu intelektuālais
īpašums, ar autortiesībām vai citādi, tas ir nepatīkami, ka kāds var
vienkārši palaist komandu, un viņš var redzēt oriģinālo kodu, ko jūs
uzrakstījāt.
Tagad izrādās, ka tas nav tik vienkārši.
Un tāpēc, lai gan, jā, jūs varētu paņemt tādu programmu kā Hello vai
pat Microsoft Word un pārvērst to no nullēm un vieniniekiem atpakaļ
uz kāda veida avota kodu — vai tas būtu C vai Java, Python vai kaut
kas cits, neatkarīgi no tā. sākotnēji tika uzrakstīts — iespējams, ka
tas būs pilnīgs haoss.
Kāpēc?
Tā kā lietu mainīgo nosaukumi parasti netiek saglabāti nullēs un
vieniniekos.
Funkciju nosaukumi var netikt saglabāti nullēs un vieniniekos.
Kods ir, loģika ir, bet datoram ir vienalga, kādus skaistos mainīgos
jūs izvēlējāties un cik skaisti nosauktas jūsu funkcijas, tam tikai
jāzina tās kā nulles un vieninieki.
Turklāt, ja domājat par pagājušo nedēļu, mēs ieviesām tādas lietas kā
cilpas C.
Un bez cilpām ir, piemēram, kāda cita veida cilpa?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Tātad, kamēr cilpa — un, lai gan tie izskatās
atšķirīgi un jums ir jāraksta cits kods, tie sasniedz tieši tādu pašu
funkcionalitāti, proti, kad jūs kompilējat for cilpu vai kompilējat
while cilpu, ja loģiski, ka viņi dara to pašu, viņi var izskatīties
identiski kā nulles un vieninieki.
Tāpēc nav iespējams paredzēt, ka atgūsit sākotnējo kodu, kāpēc?
Jo nulles un vieninieki var nezināt, tā teikt, vai tā bija for cilpa
vai while cilpa, tāpēc varbūt kompilēšana parādīs vienu vai otru.
Un, godīgi sakot, dekompilēšana, ja vien iespējams, un tas ir viens
no veidiem, kā apgrieztā veidā pārveidot lietotāja produktu.
Izredzes ir tādas, ka, ja esat pietiekami labs, lai sāktu lasīt kodu,
kas ir dekompilēts, un izlasot tā nekārtības, iespējams, jums ir
talants, lai pats vienkārši uzrakstītu to pašu programmu no nulles.
Tas, iespējams, ir pārspīlēts, taču tas nav tik viegli vai draudīgi,
kā varētu šķist.
Tātad kopumā, tiklīdz kods ir apkopots, tā reversā inženierija ir
diezgan sarežģīti, laikietilpīgi un dārgi, līdzīgi kā tas būtu
reālajā pasaulē, vai ne?
Kā jau mums visiem, iespējams, mūsdienās kabatā ir kāds telefons.
Nekas neliedz jums to kaut kā atvērt, pabāzt apkārt, atjaunot to, kas
tur ir.
Tas, visticamāk, ir milzīgs piepūles apjoms.
Un tajā brīdī, iespējams, jums vajadzētu vienkārši izgudrot tālruni,
nevis mēģināt to mainīt.
Tātad tāda pati ideja fiziskajā pasaulē.
Vai ir kādi jautājumi par apkopošanu vai pat dekompilēšanu šajās
veidlapās?
Labi, iespējams, ka šobrīd ne tikai es, bet arī jūs esat pieļāvuši
kļūdas.
Un jūs esat uzrakstījis kļūdainu kodu — kļūda kodā ir tikai kļūda,
loģiska kļūda vai citādi, ja kods vienkārši nedarbojas pareizi, kā
jūs plānojat.
Un līdz šim, iespējams, jūsu atkļūdošanas paņēmieni ir bijuši tādi,
lai varētu atskatīties uz to, ko es darīju stundā, varbūt uzdot
jautājumu tiešsaistē vai klātienē.
Bet galu galā būtu jauki, ja jums būtu daži savi rīki, ar kuriem
atkļūdot kodu.
Un šī, godīgi sakot, ir mūža prasme.
Jūs neizkļūsit no CS50 — un pat pēc 20 gadiem jūs nerakstīsit, ja
vispār rakstīsit kodu, visu laiku labojiet kodu.
Tāpat kā mēs visi darbinieki turpinām rakstīt kļūdas.
Cerams, ka tie kļūs nedaudz izsmalcinātāki, nevis līdzīgi, ak, es
palaidu garām semikolu.
Bet pat šādas kļūdas pieļaujam arī mēs.
Taču ir pieejami rīki un paņēmieni, kas var atvieglot jūsu dzīvi, kad
runa ir par šo problēmu risināšanu.
Tagad termins bug faktiski ir pastāvējis gadu desmitiem.
Taču interesants stāsts ir tāds, ka pirmā dokumentētā faktiskā kļūda
patiesībā bija kaut kādā veidā saistīta ar Hārvardu.
Faktiski šis ir žurnāls, kas attiecas uz Harvard Mark II datoru no
1947. gada, un, ja jūs izlasiet piezīmes šeit — un es pietuvināšu —
šī bija īsts kode, kas tika atklāta šī lielā lieldatora iekšpusē, kas
izraisīja veida problēmas.
Un toreizējiem inženieriem šķita smieklīgi, ka, oh, fiziska kļūda
patiesībā izskaidro šo problēmu.
Un tas ir uz visiem laikiem pielīmēts uz šīs papīra lapas, kas,
manuprāt, tagad ir izstādīta Smitsona izdevumā.
Ņemot to vērā, arī šī ir tikai loģiska kļūda.
Un šis stāsts patiesībā ir - šo stāstu bieži pārstāstīja slavens
matemātiķis, toreizējais datorzinātnieks, Dr.
Greisa Hopere, kura faktiski strādāja ne tikai ar Harvard Mark II
datoru, bet arī tā priekšteci Harvard Mark I.
Un, ja jūs kādreiz esat pavadījis laiku, tomēr inženiertehniskajā ēkā
pāri upei jūs varat redzēt lielu daļu no šī datora, kas atrodas pie
sienas, kad pirmo reizi ieejat Zinātnes un inženierzinātņu kompleksā.
Un patiešām, kā jūs droši vien esat dzirdējuši, pieaugot, šis ir
lieldators.
Šādi izskatījās Mac un personālie datori, tā sakot, ar ļoti fiziskiem
elementiem, kas būtībā ieviesa nulles un vieniniekus, kurus mēs ar
jums uzskatām par pašsaprotamu, tagad mūsu klēpjdatoros un tālruņos
ir miniaturizēti.
Tātad tur ir gabals vēstures.
Ja kādreiz apmeklējat šo pilsētiņas pusi, ieskatieties.
Bet tad padomāsim, kā mēs, protams, risinām nevis fiziskās, bet
loģiskās kļūdas.
Un ņemsim vērā kaut ko līdzīgu no pagājušās nedēļas, kad mēs ļoti
vienkārši mēģinājām izdrukāt kā šo trīs ķieģeļu kolonnu, izmantojot
sava veida tēmturus.
Tāpēc ļaujiet man pēc brīža pāriet uz VS Code.
Un es iešu uz priekšu un atvēršu programmu, kuru es uzrakstīju
iepriekš.
Un es to atnesu uz nodarbību, jo tajā ir kļūda, un es vēlētos
izdomāt, kā šo kļūdu novērst.
Tāpēc ļaujiet man atvērt buggy0.c, kas ir mana koda 0. versija.
Un īsi ieskatīsimies, kas šeit ir.
Tas ir diezgan īss.
Tas ietver tikai stdio.h, tas izmanto printf, izmanto for cilpu, un
mērķis, gluži vienkārši, ir izdrukāt šo trīs ķieģeļu kolonnu.
Tagad tas ir pietiekami īss, lai daži no jums, ja jūs jau jūtaties
ērti, izmantojot C, jūs jau varētu redzēt loģisko kļūdu.
Tā nav sintakses kļūda, piemēram, tā tiks apkopota un palaistu.
Bet tur ir kāda kļūda.
Un pieņemsim, ka es esmu ļoti iesācējs C, es jūtos ļoti neērti ar C,
pulkstenis ir 2:00 un es vienkārši neredzu kļūdu. Kādi šeit ir mani
līdzekļi, lai atrastu šādu kļūdu?
Pirmkārt, apskatīsim simptomu.
Ļaujiet man doties uz termināļa logu.
Es izmantošu make buggy0, jo atkal faila nosaukums ir buggyo.c.
Es netaisos lietot klangu.
Patiesībā es nekad īsti neizmantošu zvanīšanu manuāli.
Es tikai izmantošu make, jo tas atvieglo mūsu dzīvi.
Tas apkopo.
Nav kļūdu, tāpēc tā nav sintakse.
Tas nav kaut kas muļķīgs, piemēram, trūkstošs semikolu.
Bet, kad es palaižu ./buggy0, es, protams, redzu vienu, divus, trīs,
četrus, un tas, protams, neatbilst vienam, diviem, trīs ķieģeļiem, ko
es patiesībā paredzēju šai kolonnai.
Un tomēr es sāku skaitīt no 0, kā es to parasti daru.
Man ir trīs.
Es eju līdz trijiem.
Tātad, kur ir mana loģiskā kļūda?
Ja tas jums acīmredzami jau nav ienācis prātā, kā es varu to
atrisināt?
Pirmkārt un galvenokārt, iespējams, labākais paņēmiens kļūdu
risināšanai, vismaz agrīnā stadijā, ir izmantot printf.
Tāpat kā līdz šim, mēs esam izmantojuši sprintu, sakot, Sveiki, un
citas ekrānā redzamās lietas.
Bet printf ir tikai funkcija jebko drukāt.
Un nav nekāda iemesla, lai īslaicīgi nevarētu izmantot printf, lai
izdrukātu mainīgo saturu, kas notiek jūsu programmā, lai tikai
noskaidrotu, kur ir jūsu kļūda.
Un pēc tam vēlāk varat izdzēst šo koda rindiņu.
Tam nav jāpaliek tur mūžīgi.
Tāpēc ļaujiet man to izdarīt.
Tā vietā, lai VS kodā vienkārši izdrukātu jaukšanas simbolu, ļaujiet
man veikt nelielu drošības pārbaudi un izdrukāt i vērtību.
Ļaujiet man iet uz priekšu un pateikt kaut ko līdzīgu: es esmu...
tagad es gribu teikt, ka es esmu tas.
Bet, protams, šādi es neizdruku i vērtību.
Ja es vēlos izdrukāt i vērtību, ko man šeit ievietot?
Tātad %i veselam skaitlim, nevis %s virknei.
Tātad tie joprojām ir vietturi.
Bet mēs izmantojam %s veseliem skaitļiem.
Un tagad, ja es gribu izdrukāt i, man vienkārši vajag komatu kā otro
argumentu, un tad i.
Labi, ļaujiet man doties uz priekšu un atgriezties pie sava termināļa
loga.
Ļaujiet man pārkompilēt programmu, jo esmu to mainījis.
Tas joprojām darbojas labi, ./buggy0.
Un tagad ļaujiet man šeit palielināt sava termināļa loga izmēru.
Ja vēlaties, jūs vienkārši redzat kādu diagnostikas informāciju.
Tas nav mērķis.
Tas nav tas, kas jums būtu jāiesniedz mājasdarbam, ja tāds būtu.
Bet tas palīdz mums diagnostiski zināt, ka, ja es ir nulle, šeit ir
jaukts.
Kad man ir 1, šeit ir hash.
Kad man ir divi, šeit ir hash.
Kad man ir 3, šeit ir hash.
Nu, pagaidiet minūti.
Tas ir viens, divi, trīs, četri.
Skaidrs, ka es to drukāju pārāk daudz reižu.
Tāpēc ļaujiet man atskatīties uz kodu, samazinot termināļa logu.
Un ļaujiet man vienkārši pajautāt grupai, kur patiesībā ir kļūda?
Vai arī kāds būtu risinājums?
Jā, pa vidu.
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Jā, tā vietā, lai mazāk par vai vienāds ar,
izmantojiet tikai mazāk nekā.
Tātad jums šeit ir jāizvēlas josla.
Ja plānojat sākt skaitīt no 0, parasti izmantojat mazāk nekā un
palielināsiet līdz, bet ne caur vērtību.
Vai arī, ja vēlaties, piemēram, cilvēku pasaulē, skaitot no 1 uz
augšu, varat izmantot mazāku vai vienādu ar, bet jums ir jābūt
konsekventam.
Un vispār, kā programmētājs, vienkārši vienmēr sāciet skaitīt no 0,
ja darāt kaut ko tādu, kas ir līdzīgs šim.
Bet risinājums patiešām ir tikai to mainīt, mainot lielāko mazāku vai
vienādu ar mazāku.
Ja es pārkompilēju šo programmu ar make buggy0 un pēc tam vēlreiz
veicu .buggy0 un ļaujiet man palielināt sava termināļa loga izmēru.
Tagad, redzi, labi, gandrīz tāda pati izvade.
Bet patiešām, es sāku ar 0 un eju līdz trim, bet ne līdz.
Labi, tāpēc printf, īsi sakot, var būt jūsu pirmais diagnostikas rīks.
Tā vietā, lai vienkārši skatītos uz ekrānu vai paceltu roku — es
domāju, izmantojiet printf, lai burtiski redzētu, kas notiek jūsu
programmā, vienkārši izdrukājot interesējošās lietas.
Kad esat atrisinājis problēmu, varat atgriezties savā kodā, kā es to
darīšu šeit, samazinot savu termināļa logu.
Es izdzēsīšu printf rindiņu.
Un tagad esmu gatavs dalīties ar šo programmu ar pasauli vai iesniegt
to kā mājasdarbu vai tamlīdzīgi.
Tas ir tikai domāts, lai tas būtu īslaicīgs.
Vai jums ir jautājumi par printf kā atkļūdošanas rīku?
Nē?
Labi, tas mūs noved tikai tik tālu.
Un, godīgi sakot, jūsu programmām augot, augot un augot, būs ļoti
kaitinoši sākt ieiet un pievienot printf, pēc tam tos noņemt un
noskaidrot, ja jums ir vairāki printf, tad kurš no tiem ko izdrukā?
Galu galā paļauties tikai uz printf kļūst sarežģīti.
Tā kā datorzinātnieki ir datorzinātnieki, viņi ir uzrakstījuši
programmatūru, lai atvieglotu koda atkļūdošanu.
Šo programmatūru mēs parasti saucam par atkļūdotāju, kas būtu otrais
tirdzniecības rīks, ko varat izmantot, lai faktiski atrisinātu
problēmas savā kodā.
Tagad VS koda pasaulē faktiski ir iebūvēts atkļūdotājs.
Tātad grafiskais lietotāja interfeiss, ko redzēsit programmā VS Code,
nav raksturīgs CS50, tas faktiski tiek piegādāts kopā ar VS kodu.
Un tas atbalsta C, C++, Java un Python, kā arī daudzas citas valodas.
Taču, protams, ir nedaudz sarežģīti vienkārši sākt lietot atkļūdotāju.
Jums ir jāizveido konfigurācijas fails un jāveic dažas kaitinošas
darbības, kas tikai traucē atrisināt reālas problēmas.
Tāpēc mēs esam automatizējuši atkļūdotāja palaišanas procesu.
Un pēc tam tas ir sava veida nozares standarts, kā jūs to izmantojat.
Taču mēs ietaupīsim jums galvassāpes, kas saistītas ar šo
konfigurācijas failu izveidi.
Tātad, pieņemsim, ka es gribu to darīt.
Pieņemsim, ka es vēlos mēģināt soli pa solim atkļūdot šo programmu,
izmantojot īpašu programmatūru.
Nu kā es to varu izdarīt?
Ļaujiet man ierosināt, ka, ja es to atgriezīšu atpakaļ uz sākotnējo
versiju, kurā es biju mazāks vai vienāds ar 3, esmu diezgan
pārliecināts, ka es drukāju pārāk daudz jaucējzīmju.
Tāpēc es darīšu to — un jūs, iespējams, to izdarījāt nejauši vai arī
nekad.
Bet ņemiet vērā, ja virzāt kursoru virs, tā sakot, VS Code, tās
daļas, kas atrodas pa kreisi no redaktora, jūs redzat šādu pelēku
sarkanu punktu.
Noklikšķinot tur, tas kļūst par spilgtāku sarkanu punktu.
Un tas atspoguļo to, ko mēs sauksim par pārtraukuma punktu.
Un tas ir tikai vizuāls rādītājs, ka esat tur ievietojis kā
apstāšanās zīmi ekvivalentu un pēc brīža sakāt atkļūdotājam,
pārtrauciet tur palaist manu kodu.
Kāpēc?
Tāpēc, ka man labāk patīk iziet cauri savam kodam cilvēka ātrumā,
nevis datora ātrumā, kur tas darbojas uzreiz.
Tāpēc esmu iestatījis savu pārtraukuma punktu, kas ir pirmais solis.
Un tad otrais solis ir pavisam vienkāršs.
Tā vietā, lai palaistu pašu programmu, palaidiet komandu debug50 un
pēc tam ./buggy0.
Un tagad tas sāks jūsu programmu, bet atkļūdotāja iekšpusē, kas ir
īpaša programma, ko ir uzrakstījuši gudri cilvēki un kas dos jums
iespēju tagad rindiņu pa rindiņai un vēlreiz savā ērtā tempā iziet
cauri savam kodam.
Es nospiedīšu taustiņu Enter, ekrānā parādīsies dažas lietas — ak.
Ņemiet vērā, ka šī ir izplatīta kļūda, ko es šeit pieļāvu nejauši.
Šķiet, ka esmu mainījis savu kodu.
Es to izdarīju, jo es iegāju un nomainīju mazāku vai vienādu zīmi.
Ļaujiet man turpināt un atkārtoti palaist make buggy0-- Enter.
Labi, tagad ļaujiet man atkārtoti palaist debug50 — Enter.
Tagad dažas lietas tikko notika ekrānā, un ir nepieciešams brīdis,
lai sāktu darbu, taču, tiklīdz tas būs sākts, jūs to redzēsit, jūs
joprojām redzēsit savu kodu.
Bet jūs redzēsit šo dzelteno izcēlumu, ko, iespējams, vēl neesat
redzējis.
Un ievērojiet, ka tas īpaši izceļ to pašu līniju, kurā es iestatīju
pārtraukuma punktu.
Kāpēc?
Tas tikai nozīmē, ka atkļūdotājs ir izpildījis visas šīs rindas,
izņemot 7. rindu.
Tas ir salūzis — ne sliktā nozīmē.
Bet tas ir apturējis izpildi 7. rindā, tāpēc tas vēl nav izdrukājis
nevienu jaucēju.
Un jūs to redzat — termināļa logā vēl nav jauktu.
Tā izpilde ir apturēta.
Bet kas ir interesanti ar atkļūdotāju, ir sīkumi šeit, kreisajā pusē.
Šeit esošajā atkļūdotāja sadaļā mainīgie redzēsit visus tā sauktos
vietējos mainīgos.
Un mēs neesam īsti nošķīruši lokālo un kaut ko, ko sauc par globālo.
Bet pagaidām vietējie mainīgie nozīmē tikai visus mainīgos, kas
pastāv jūsu funkcijā.
Tātad man pašlaik ir vērtība 0.
Labi, un tam ir jēga.
Tātad, kā es varu iziet cauri savam kodam un redzēt, ko tas dara?
Šeit ekrāna augšdaļā redzēsit dažas atskaņošanas ikonas, kas ir
līdzīgas video atskaņotājam, taču tām ir īpaša nozīme.
Šī pirmā atskaņos visu pārējo programmu līdz beigām.
Tātad jūs noklikšķiniet uz tā tikai tad, ja esat atrisinājis problēmu
un vienkārši vēlaties to palaist līdz beigām tāpat kā iepriekš.
Bet nākamie trīs vai nākamie divi tiešām ir sulīgākie.
Otrais šeit, ja novietosit kursoru virs tā, galu galā redzēsit, ka to
sauc par Step Over.
Step Over nozīmē, ka atkļūdotājs izpildīs šo pašlaik izcelto koda
rindiņu, taču tas tajā neiedziļinās.
Tātad, ja tā ir funkcija, piemēram, printf, tā nesāks iet cauri
printf rindiņai pa rindiņai.
Kāpēc?
Tā kā es diezgan lielā mērā varu pieņemt, ka printf, kas rakstīts
pirms gadu desmitiem, ir pareizs.
Problēma droši vien ir manī.
Bet šajā nākamajā rindiņā, ja es patiešām vēlos iedziļināties printf
kodā, lai noskaidrotu, kā tas darbojas, vai visus šos gadus vēlāk
atrastu tajā kādu problēmu, varat ieiet printf, un tad ekrāns
mainītos, un jūs skatiet katru no printf rindiņām pa rindiņai —
vismaz tad, ja ir instalēts printf avota kods.
Labi, es izmantošu pirmo, Step Over.
Un skatieties, kā pārvietojas dzeltenais izgaismojums.
Un skatieties, kā termināļa logā ir hash simbols.
Lūk.
Ir viens hash.
Tagad paziņojuma 5. rindiņa ir iezīmēta.
Tas nozīmē, ka tas ir apturēts 5. rindā.
5. rinda vēl nav izpildīta.
Tātad, ko tas nozīmē?
i vērtība augšējā kreisajā stūrī joprojām ir 0.
Bet, tiklīdz es vēlreiz noklikšķinu uz Step Over, skatieties, kas
notiek augšējā kreisajā stūrī, kur i ir ekrāna mainīgais.
Tagad i — un tas īsi mirgoja — ir vērtība 1.
Un tagad, ja es atkal piekāpšos, skatieties termināļa logu.
Šeit ir mans otrais hash.
Tagad ļaujiet man noklikšķināt uz Step Over, lai atvērtu cilpu,
skatīties mainīgo augšējā kreisajā stūrī.
Tagad 1 pāriet uz 2.
Tagad ļaujiet man vēlreiz noklikšķināt uz tā.
Trešais sajaukums — un šeit, iespējams, atklājas loģiskā kļūda.
Ļaujiet man iet uz priekšu un pārkāpt cilpu.
Tagad man ir 3.
Pagaidiet, es joprojām izdrukāšu hash.
Tur tas ir.
Tur ir ceturtais hash.
Un šajā brīdī, cerams, spuldze, sakāmvārdā, ir nodzisusi.
Es saprotu, ak, es sapucējos.
Es varu vai nu pilnībā apturēt programmu, izmantojot sarkano
kvadrātu, vai arī varu vienkārši ļaut tai darboties līdz beigām, kas
vienkārši pārtrauc visu.
Šobrīd es tikai vēlos atgriezties savā kodā un sākt labot lietas.
Un jūs varat aizvērt, piemēram, kā es šeit darīšu, failu pārlūku, lai
tikai paslēptu atvērto paneli.
Tātad tas ir debug50.
Taču tā nav CS50 lieta, kas tikai palaiž jūsu vietā atkļūdotāju, ko
mūsdienās var atrast gandrīz jebkurā programmēšanas vidē.
Vai jums ir jautājumi par atkļūdošanu?
Jautājumi?
Jā?
AUDITORIJA: Kur ir norādīts, kur nogāja greizi?
DEIVIDS MALANS: Labs jautājums.
Kur ir teikts, kur tas nogāja greizi?
Tāpēc diemžēl tas jums par to neko nepasaka.
Jums, cilvēkam, joprojām ir pienākums produktīvi izmantot šo rīku,
lai saprātīgākā tempā ievadītu kodu.
Bet jūsu smadzenes ir tās, kurām tas joprojām ir jāatrisina.
Un es nešaubos, ka, izmantojot mākslīgo intelektu un daudz ko citu,
šādas programmas kļūs vēl noderīgākas un sāks mums atbildēt uz šādiem
jautājumiem.
Un ir arī citi rīki, kurus mēs jūs iepazīstināsim šajā semestrī un
kuri ir vēl jaudīgāki par šo.
Bet pagaidām tas ir tikai rīks, lai palēninātu darbību un nav jāmaina
kods.
Tas, ka man bija panelis kreisajā pusē, kas tikko rādīja man mainīgo
vērtību, ir tikai alternatīva printf, un es varu to pārvietot nedaudz
lēnāk.
Citi jautājumi par atkļūdošanu?
Nē?
Ļaujiet man parādīt vienu pēdējo piemēru ar šo atkļūdotāju šeit.
Un arī šo es uzrakstīju iepriekš.
Ļaujiet man aizvērt buggy0.c.
Un ļaujiet man atvērt buggy1.c, manu otro versiju.
Ļaujiet man uz sekundi aizvērt termināļa logu un sniegt jums īsu šīs
programmas apskatu, kurā tāpat ir kļūda.
Tagad šīs programmas augšdaļā daži pazīstami ietver cs50.h un stdio.h.
Mēs to neesam redzējuši iepriekš.
Tas ir raksturīgs šim piemēram — funkcijai getNegativeInt.
Neņem vērā argumentus, un tas atgriež veselu skaitli.
Ko tas dara?
Ideālā gadījumā tas burtiski saņem no lietotāja negatīvu veselu
skaitli.
Interesants fakts, tomēr tas nav pareizi.
Tā ir kļūda.
getNegativeIntis šobrīd ir bojāts.
Tātad, ko dara galvenais?
Nu, galvenais vienkārši izsauc šo funkciju, neko neieliekot iekavās,
bez ievades.
Un tas saglabā atgriešanās vērtību i.
Un tad tas vienkārši izdrukā i uz ekrāna.
Godīgi sakot, tikai paskatoties uz šo, es jūtos pietiekami ērti,
programmējot C valodā, un es domāju, ka galvenais ir pareizi.
Ļaujiet man tikai noteikt, galvenais ir pareizi.
Bet šeit būs kāda kļūda.
Kas te ir par kļūdu?
Ļaujiet man apskatīt getNegativeInt ieviešanu.
Ievērojiet, šī pirmā rinda, 12, ir identiska šeit esošajam prototipam.
Prototips šeit ir muļķīgi vajadzīgs, jo C lasa lietas no augšas uz
leju, no kreisās uz labo pusi — kompilators tehniski to dara.
Tātad, ja šeit atsaucaties uz getNegativeInt, bet neieviešat to līdz
šeit un neesat iepriekš teicis C, ka tas pastāvēs, atkal tiek
parādīta kļūda, ko redzējām pagājušajā nedēļā.
Labi, kā darbojas getNegativeInt?
Mēs deklarējam mainīgo, ko sauc par n.
Mums ir jādara kamēr cilpa, kas dara ko?
Pagājušajā nedēļā tas izmanto getInt, kas tiek piegādāts kopā ar cs50
bibliotēku.
Tas pieprasa lietotājam ievadīt negatīvu veselu skaitli, pēdiņās un
saglabā vērtību n.
Pēc tam es to visu daru, kamēr n ir mazāks par 0, vai ne?
Atcerieties, ka pagājušajā nedēļā mēs izmantojām while loop, lai
pārliecinātos, ka cilvēks sadarbojas un nepiešķir mums nepareizu
vērtību, vai tā būtu pozitīva vai negatīva, vai kaut kas cits.
Un tad mēs atgriežamies n.
Un tur ir daži smalkumi.
Ikviens atceras — vai viņam ir intuīcija, kāpēc es esmu norādījis n
14. rindā, nevis 17. rindā?
Šī ir C specifiska lieta.
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Tieši tā.
Šis darbības jomas jēdziens ir C.
Un mēs turpināsim to redzēt laika gaitā, līdz ar to mainīgais pastāv
tikai jaunākajās cirtainajās iekavās, kuras esat atvēris.
Tātad, ja esmu norādījis n šeit 14. rindiņā, es varu to izmantot
jebkur starp 13. un 21. rindu, jo tās ir tuvākās krokainās lencēs.
Ja turpretī, kā jūs atzīmējat, ja es tā vietā teiktu, int n ir getInt
un tā tālāk, un tai nebūtu pašreizējās 14. rindiņas, tad n būtu šo
cirtaini iekavās, bet ne šeit, kas arī ir. vēlu, un noteikti ne šeit.
Tātad jums tas vispirms ir jādeklarē un pēc tam jāizmanto un
atkārtoti jāizmanto kā tāds.
Tagad ļaujiet man tikai parādīt, kā es varu to atkļūdot.
Bet ļaujiet man vispirms parādīt simptomus.
Ļaujiet man atvērt savu termināļa logu.
Ļaujiet man palaist make buggy1.
Sastāda OK, tāpēc tas nav kaut kas muļķīgs kā semikolu.
./buggy1, un man tiek prasīts negatīvs vesels skaitlis.
Labi, ļaujiet man dot negatīvu 1 — Ievadiet.
Nu, galvenajai funkcijai ir paredzēts izdrukāt to, ko es ierakstīju,
bet tas acīmredzami neizdarīja.
Tas mani atkal mudina.
Labi, tāpēc, iespējams, patiks 2. negatīvais.
Nē?
Varbūt negatīvs 3.
Labi, tātad tas noteikti ir bojāts, vai ne?
Šķiet loģiski, ka rīkojas pretēji.
Tagad jūs, iespējams, redzat, kāpēc tas jau notiek.
Tās ir apzināti vienkāršas programmas demonstrāciju nolūkos.
Bet darīsim tā.
Ļaujiet man iet uz priekšu un iestatīt pārtraukuma punktu galvenajā,
lai gan esmu diezgan pārliecināts, ka galvenais ir pareizs.
Bet tas tikai palīdz man sākt manu domāšanas procesu — sāciet ar
galveno un pēc tam pārņemiet to no turienes.
Ļaujiet man palaist tūlīt, debug50 ./buggy1-- Enter.
Un paskatīsimies.
Ar šo pārtraukuma punktu tagad GUI pārkonfigurēs sevi.
Tas tiks apturēts 8. rindā, jo tā ir pirmā interesantā līnija
galvenajā rindā.
Tāpēc es varētu vienkārši ievietot pārtraukuma punktu arī 8. rindā.
Tas ir pietiekami gudrs, lai zinātu, ka, iestatot to uz 6, jūs
patiešām domājat 8. rindiņu, jo tā ir pirmā faktiskā koda rinda.
Un tagad skatieties, kas notiek.
Ja es kāpju pāri šai līnijai, ievērojiet, ka i, kurai šobrīd šķiet
noklusējuma vērtība 0 — vairāk par to citreiz.
Bet, ja es tāpat kā iepriekš noklikšķinu uz Step Over, man tiek
prasīts ievadīt negatīvu veselu skaitli.
Ļaujiet man ierakstīt negatīvu 1 — Enter.
Un tagad, ievērojiet, nav papildu dzeltenā izcēluma.
Kāpēc?
Kur es šobrīd esmu iestrēdzis, loģiski?
Mērķauditorija: [NEdzirdams]
DEIVIDS Malans: Jā, tikai loģiski, ka man ir jābūt tajā do, while
cilpā.
Un pat ja jūs to nesaprotat, tas ir vienīgais izskaidrojums.
Ja jūs pastāvīgi saņemat uzvedni, noteikti notiek cilpa.
Manā kodā ir tikai viena cilpa, tāpēc, iespējams, tur ir problēma.
Tāpēc es nevaru vienkārši iestatīt pārtraukuma punktu galvenajā un
pēc tam gaidīt, kamēr tas darbosies.
Tāpēc ļaujiet man vienkārši pārtraukt to ar sarkano kvadrātu.
Un ļaujiet man padomāt, labi, tā vietā, lai es joprojām varu iestatīt
pārtraukuma punktu galvenajā, bet tā vietā ļaujiet man atkārtoti
palaist atkļūdotāju.
Un šoreiz, nepārkāpjiet šo koda rindiņu, ļaujiet man ieiet šajā koda
rindā.
Tāpēc skatieties, kas notiek tagad.
Tā vietā, lai šeit noklikšķinātu uz otrās ikonas, ļaujiet man
noklikšķināt uz trešās, kuras nosaukums patiešām ir Step Into.
Un skatieties, kā dzeltenais izgaismojums nepāriet uz 9. rindiņu.
Tas iekļaujas 8. rindā — funkcija 8. rindā, tādējādi nolaižot mani
līdz 17. rindiņai.
Tas kaut kā iet uz nākamo funkciju.
Tagad tas netraucēja apstāties 12. vai 13. vai 14. līnijā, jo tur vēl
nekas intelektuāli interesants nenotiek.
Sūdīgā daļa tiešām sākas, šķiet, 17. rindā.
Tātad, tagad ievērojiet, n ir mans mainīgais augšējā kreisajā stūrī.
Ja es noklikšķinu, es nevēlos noklikšķināt uz Step Into tagad.
Kas notiktu nepareizi, ja es noklikšķinātu uz Step Into — vai ko tas
darītu, ko es nedomāju, ka vēlos darīt?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Jā, tas iekļausies getInt.
Bet es gribētu domāt, ka personāla getInt versija ir pareiza, un tā
nav mūsu šodienas problēma, tāpēc es vēlos tai pārvarēt.
Un skatieties augšā pa kreisi, ka nekas vēl nenotiek ar n vērtību,
līdz es tagad pāreju uz termināļa logu un ierakstu kaut ko līdzīgu
negatīvam 1.
Tagad ievērojiet, tas pāriet uz 19. rindu, kas ir nākamā interesantā
rinda.
Augšējā kreisajā pusē n patiešām ir negatīvs 1.
Un šeit es tagad varu apstāties kā cilvēks un padomāt, labi, kamēr n
ir mazāks par 0.
Labi, n augšējā kreisajā stūrī ir negatīvs 1.
Tātad, labi, lai gan negatīvais 1 ir mazāks par 0, protams,
matemātiski tā ir taisnība.
Kas tad notiks?
Tas ir do while cilpa.
Tātad, kad es vēlreiz noklikšķināšu uz Step Over, tā pāries uz šo
rindiņu, jo tā atrodas šīs cilpas iekšpuses galā.
Un tagad šeit, tas atkal un atkal tiek cauri.
Labi, ļaujiet man to izdarīt vēlreiz.
Es iešu pāri, labi?
Es ierakstīšu negatīvo 2, un tas ir tieši tas pats.
Tagad ir mana iespēja uz dzeltenās līnijas... Labi, pagaidi.
Negatīvs 2 acīmredzami ir mazāks par 0.
Ļaujiet man izmēģināt šo vēl vienu reizi.
Noklikšķiniet uz tā vienu reizi šeit.
Labi, ļaujiet man dot 50.
Un tagad, labi, lai gan 50 ir mazāks par 0, tā nav taisnība, tāpēc
cilpa ir beigusies, jo tas netiks darīts, kamēr 50 ir mazāks par 0.
Tā nav taisnība.
Tagad skatieties, kad es vēlreiz noklikšķinu uz Step Over, tas
pabeidz cilpu, lai gan nekas vairāk nav jādara.
Tas tagad gatavojas atgriezties n.
Tas pāriet atpakaļ uz galveno, kur es pārtraucu 9. līniju.
Tagad manā termināļa logā tiek drukāts skaitlis 50.
Un, cerams, šajā brīdī, uz jūsu jautājumu, manas cilvēka smadzenes ir
sapratušas: ak, es esmu idiots, it kā es būtu pagriezusi savu zīmi.
Tāpēc es droši vien ļaujiet man to pārtraukt.
Es droši vien vēlos kaut ko tādu izdarīt.
Ja mērķis ir iegūt negatīvu veselu skaitli, es droši vien vēlos
teikt, ka n, piemēram, ir lielāks par vai vienāds ar 0, darbotos.
Tātad, kamēr n ir lielāks vai vienāds ar 0, turpiniet to darīt.
Un tā ir loģika, ko es gribēju izteikt.
Tāpēc atkļūdotājs vienkārši pasargā mani no skatīšanās uz ekrānu,
rokas pacelšanas, kā arī jautāšanas kādam citam.
Vismaz šajā gadījumā tas man ļauj iet cauri veselīgākā tempā.
Jautājumi tagad par debug50, kuram vajadzētu būt jūsu jaunajam
draugam, pat ja tas nav jūsu pirmais instinkts pēc printf?
Vai ir kādi jautājumi par debug50?
Nē?
Labi, ir vēl viens pēdējais paņēmiens, ar kuru mēs varam jūs aprīkot.
Un tas ir, papildus printf un atkļūdotājs, bez jokiem, gumijas pīle
patiesībā ir saprātīgi ieteicams risinājums kļūdu atrašanai kodā.
Uz jūsu iepriekš uzdoto jautājumu, pīle divi neatrisinās problēmu
jūsu vietā.
Bet, ja esat prātojies, kāpēc šis mazais puisis šeit ir tik ilgi, tur
ir šī tehnika, kurai ir savs Wikipedia raksts par gumijas pīļu
atkļūdošanu.
Tās ideja ir tāda, ka, ja atrodaties mājās savā kopmītņu istabā un
cīnāties ar kļūdu savā kodā, printf jums īsti neatklāja avotu,
atkļūdotājs īsti nepalīdz, godīgi sakot, varbūt tas palīdzētu
noskaidro, kāda problēma tev ir.
Līdzīgi kā došanās uz darba laiku, runājot ar TA vai profesoru,
vienkārši izstaigājot savas problēmas, jo tādā veidā runājot ar pīli
par to, ka jūs to darāt, kamēr n ir mazāks par 0, un tad, ja tā ir...
- pagaidi minūti.
Es esmu idiots, ne tikai runājot ar gumijas pīli.
Jūs saprotat, cerams, ka, izsakoties burtiski verbāli, jūs,
iespējams, dzirdēsit ar varbūtību, kas nav nulle, kā kādu neloģiku
savā paziņojumā.
Un, vienkārši izklausot lietas, jūs sapratīsit, ka tā ir mana
problēma.
Un tā, atklāti sakot, ja jums ir istabas biedri, varat izmantot arī
istabas biedru.
Bet gumijas pīle ir tikai sava veida piemērs, kad jūsu istabas biedri
neinteresējas par jūsu C problēmu kopumu, runājot par to kā tādu.
Un šī ir nenovērtējama tehnika.
Jāatzīst, ka sliecos to nedarīt tik daudz ar gumijas pīli, bet ideālā
gadījumā ar kolēģiem, cilvēku kolēģiem.
Bet tikai bieža pārrunāšana palīdzēs jums saprast, ak, es teicu kaut
ko neloģisku.
Tagad es varu atgriezties pie koda.
Tāpēc neatrisiniet problēmas, bezgalīgi skatoties ekrānā minūtes,
stundas.
Tajā brīdī ir pienācis laiks pārtraukumam, laiks doties prom, laiks
parunāt ar pīli, ja jau esat izsmēlis dažus citus rīkus.
Starp citu, šodien, nodarbību beigās, izejot ārā, mums ir skaidrs, ka
jums ir daudz gumijas pīļu.
Un gadu gaitā, vismaz dažu vidū, ir kļuvis ierasts ņemt līdzi pīli,
kad viņi ceļo un sūta mums fotogrāfijas.
Šeit, piemēram, ir CS50 gumijas pīļu atkļūdotājs, AKA
DDB, par Duck Debugger, kas ir vārdu spēle par gudrāku programmu, ko
sauc par GDB, GNU atkļūdotāju, kas ir īsta programmatūra
atkļūdošanai.
Šis ir CS50 atkļūdotājs Puertoriko kalnos, arī pie jūras.
Šeit viņš devās uz Sanfrancisko.
Arī lejā pie Fisherman's Wharf pie jūras lauvām.
Pazīstams?
Šeit, Stenfordā, kur atrodas Viljama Geitsa datorzinātņu ēka
datorzinātnēm, Google SF.
Un šī ir Trevi strūklaka Romā.
Un visbeidzot, Kolizejs.
Tāpēc mēs būsim ziņkārīgi, lai tuvāko gadu laikā redzētu, kur jūsu
pīle ceļo.
Tātad tas bija diezgan maz.
Kāpēc gan nepaņemt īsu 5 minūšu pārtraukumu?
Uzkodas vēl nav.
Jūs esat laipni aicināti piecelties vai apsēsties.
Mēs atgriezīsimies apmēram pēc pieciem.
Labi, mēs esam atpakaļ.
Un, ja galu galā šodienas mērķis ir labāk izprast tādas lietas kā
virknes, lai mēs varētu atrisināt problēmas ar tekstu, vispirms
apsvērsim dažus vienkāršākus datu veidus, kā mēs tos varētu attēlot,
un tad pārbaudīsim, vai tas tā nav. noved mūs pie atklājuma par to,
kā virknes, un tieši mūsdienu modernā programmatūra izmanto tādas
lietas.
Tātad, kad mēs nulles nedēļā runājām par datu attēlošanu, mums bija
dažādi veidi, kā to izdarīt — bināro un decimāldaļu, un pat unāros.
Kad mēs sākām runāt par to pašu pagājušajā nedēļā kodā, mēs sākām
runāt par datu veidiem.
Un šie datu veidi bija veids, kā pateikt datoram, piemēram, vai
vēlaties veselu skaitli, vai vēlaties rakstzīmi, vai vēlaties peldošā
komata vērtību, piemēram, reālu skaitli, vai pat virkni, kā mēs esam
redzējuši?
Bet izrādās, ka datoriem, protams, ir tikai ierobežots resursu
daudzums.
Jūsu datoram ir tikai noteikts atmiņas vai RAM apjoms.
Un tam patiesībā ir ļoti reālas sekas pasaulē.
Piemēram, šeit ir daži no datu veidiem, ko esam redzējuši līdz šim.
Un izrādās, ka katram no tiem C ir piešķirts noteikts bitu skaits.
Tagad, protams, tas var atšķirties atkarībā no sistēmas.
Mūsdienās tas tā nav tik daudz, bet daudzus gadus, gadu desmitiem
datori kļuva arvien labāki un labāki.
Agrākie datori dažiem no šiem datu veidiem varēja izmantot mazāk bitu.
Mūsdienīgāki datori varētu izmantot vairāk bitu.
Tātad skaitļi, kurus jūs drīz redzēsit, ir gandrīz tādi paši, kā mēs
šobrīd atrodamies.
Tātad, runājot par šiem datu tipiem, īsts vai nepatiess īsts baits,
kaut arī dīvainā kārtā, izmanto veselu baitu, lai gan tas ir
pārspīlēti, jo, lai iegūtu patiesu vai nepatiesu būtību, jums,
protams, ir nepieciešams tikai viens bits.
Bet izrādās, lai gan ir izšķērdīgi izmantot astoņus bitus vai vienu
baitu, lai tikai attēlotu patiesumu vai nepatiesu, datoriem tas ir
vienkārši vieglāk.
Tātad bools parasti ir viens baits.
Int, ko mēs esam daudz izmantojuši, parasti izmanto 4 baitus vai
32 bitus.
Un, ja es veicu ātru matemātiku no nulles nedēļas ar 32 bitiem, jums
ir aptuveni 4 miljardi iespējamo vērtību.
Bet, ja vēlaties attēlot pozitīvo un negatīvo, tas nozīmē, ka varat
attēlot aptuveni negatīvus 2 miljardus, līdz pat pozitīvajiem 2
miljardiem.
Tātad tas ir diapazons, parasti ar ints.
Ja jums tas ir pārāk maz skaitļu, izrādās, ka ir lietas, ko sauc par
garajiem skaitļiem.
Un gari izmanto 64 bitus, kas ļauj jums iegūt kā kvintiljonu skaitu
iespēju, kas, protams, ir daudz vairāk nekā 4 miljardi.
Tāpēc dažreiz jūs varētu izmantot garu.
Bet pat tas ir galīgs.
Un, kā mēs apspriedām pagājušās nedēļas beigās, var notikt sliktas
lietas, ja veicat noteiktus pieņēmumus par datiem, piemēram, veselu
skaitļu pārpildes vai tamlīdzīgu iemeslu dēļ, kur lietas notiek
apkārt.
Tad ir pludiņš, kas ir reāls skaitlis, kaut kas ar komatu.
Pēc vienošanās tas ir 4 baiti vai 32 biti, kas, īsi sakot, nodrošina
tikai noteiktu precizitāti.
Tas ne vienmēr nosaka, cik skaitļu ir pa kreisi vai pa labi.
Tomēr kopumā jums joprojām ir 4 miljardi iespējamo permutāciju.
Ja jums nepieciešama lielāka precizitāte zinātniskiem, medicīniskiem
vai finanšu lietojumiem, varat izmantot 8 baitus, AKA
dubultā, kas tikai nodrošina lielāku precizitāti.
Tie galu galā kļūst neprecīzi saskaņā ar piemēru, ko apskatījām
pagājušajā nedēļā, taču tas vismaz noved pie jums tālāk.
Starp citu, patiešām, ļoti svarīgās lietojumprogrammās, finansēs,
medicīnā, militārās operācijās un tamlīdzīgās jomās, kur patiešām
nevar būt noapaļošanas kļūdas — īsi sakot, cilvēki ir izstrādājuši
bibliotēkas C un citās valodās, kurās tiek izmantotas vairāk, pat,
nekā 8 baiti.
Tāpēc šīm problēmām ir risinājumi, taču tie vienmēr ir ierobežoti.
Jums ir jāizvēlas augšējā robeža.
Pēc tam ir char, ko mēs īsi redzējām pagājušajā nedēļā, kad es
jautāju lietotājam y vai n, jā vai nē.
Un tad ir virkne, kuru es piedāvāšu kā jautājuma zīmi, jo virkne ir
pilnībā atkarīga.
Patīk, Sveiki!
HI, izsaukuma zīme, šķiet, ir trīs baiti.
DĀVIDS, šķiet, ir pieci.
Tātad virknes, protams, ir mainīgas atkarībā no tā, ko jūs vai
cilvēks ievadāt.
Tātad mēs redzēsim, ko tas nozīmē, tikai pēc brīža.
Tomēr tas ir jūsu Mac datorā, datorā un tālrunī.
Tas varētu neizskatīties tieši šādi, bet tas ir mūsdienu datora
atmiņas modulis.
Un ejam uz priekšu un izmantosim šo.
Patiešām, tas tikai parāda ierobežoto atmiņas apjomu, kas patiešām ir
jebkuram datoram.
Pietuvināsim vienu no šīm mazajām melnajām mikroshēmām uz shēmas
plates šeit.
Tuviniet un ļaujiet man ierosināt, lai šis taisnstūris patiešām
attēlo noteiktu baitu skaitu, piemēram, šīs mazās melnās ķēdes
iekšpusē uz tāfeles ir varbūt, es nezinu, gigabaits, miljards baitu,
varbūt tas ir 100 baiti... kādu baitu skaitu.
Tas ir pilnībā atkarīgs no datora un tā, cik maksājāt par atmiņas
karti.
Bet, ja šajā aparatūrā ir ierobežots skaits baitu, kas ir kaut kādā
veidā digitāli ieviesti, tad ir pašsaprotami, ka mēs varētu numurēt
šos baitus.
Mēs varam vienkārši patvaļīgi izlemt, ka augšējais kreisais stūris ir
baits numur viens vai tiešām nulle baits.
Blakus ir numur viens, tad numur divi, cipars 3, punkts, punkts,
punkts, cipars 2 miljardi vai kas tas ir, lai cik liela šī atmiņa
būtu.
Tātad, ja izmantojat mainīgo C programmā, tas ir tikai viens baits.
Tāpat kā rakstzīme, tā burtiski var tikt saglabāta atmiņas augšējā
kreisajā stūrī.
Praksē jums ir vienalga, kur tas ir fiziski.
Bet patiesībā mākslinieka atveidojums būtu šāds — rakstzīme varētu
izmantot vienu no šiem atsevišķiem baitiem kaut kur datora atmiņā.
Ja izmantojat int, kas ir 4 baiti, tas dotu 4 baitus, kas ir blakus —
tas ir no kreisās puses uz labo, no augšas uz leju.
Bet visi 32 biti būtu blakus viens otram, lai dators zinātu, ka tie
patiešām pieder vienai un tai pašai int.
Ja jums ir nepieciešams garš vai dubults, šajā gadījumā varat
izmantot pilnus 8 baitus.
Un jūs vienkārši turpiniet izmantot un izmantot šo atmiņu, piemēram,
audekls, gandrīz programmā Photoshop vai izklājlapu, kurā varat
vienkārši pārvietot pikseļus vai pārvietot datus, tā patiešām ir jūsu
datora atmiņa, audekls informācijas glabāšanai vienībās. baiti vai 8
biti.
Tagad mums nav jāturpina aplūkot šīs shēmas plates.
Mēs varam to abstrahēt, kā mēs to bieži darām.
Un ejam uz priekšu un tuvināsim šo režģi, lai apsvērtu dažus ļoti
specifiskus mainīgos.
Tāpēc ļaujiet man tuvināt, un tagad ekrānā redzu mazāk, bet lielākus
lodziņus, no kuriem katrs atkal ir baits.
Un tagad ļaujiet man ierosināt spēlēt ar kādu reālu kodu.
Tātad šeit C, lai gan bez pilnas programmas, ir trīs ints — score1,
score2, score3.
Nejauši esmu sev piešķīris divus punktus ap 72 un 73, un pēc tam
diezgan zemu punktu skaitu — 33.
Protams, pagājušajā nedēļā vai pirms divām nedēļām tas būtu bijis
augsts.
Bet tagad mums ir darīšana ar faktiskiem veseliem skaitļiem.
Tātad šie ir trīs manas viktorīnas, testu vai tamlīdzīgi rezultāti.
Tāpēc ļaujiet man doties uz VS Code šeit.
Un izveidosim programmu scores.c.
Tāpēc es rakstīšu, kods scores.c.
Tas man iedos manu jauno failu.
Un ļaujiet man iet uz priekšu un īstenot kaut ko līdzīgu šim.
Iekļaujiet stdio.h, int main(void), un tad šeit, ļaujiet man darīt,
int score1 būs 72.
Int score2 būs 73.
Un int score3 būs 33.
Un tad ļaujiet man vienkārši izdarīt kaut ko tādu, piemēram,
uzrakstīt programmu, lai kopā izveidotu trīs pārbaudes rezultātus,
kaut kas līdzīgs tam.
Tāpēc ļaujiet man izdarīt printf, citējot bezcitātā, mans vidējais
rādītājs ir-- un es turpināšu darīt, teiksim, %i, /n.
Un tagad ļaujiet man pievienot rezultātus.
Un šī tagad ir sava veida pamatskolas matemātika.
Kā aprēķināt vidējo no trim vērtībām?
Nu, tāpat kā uz papīra, es varu izdarīt punktu 1 plus punktu 2 plus
punktu 3 iekavās, ņemot vērā darbību secību, dalītu ar 3, jo ir trīs
kopējie punkti.
Labi, tāpēc es domāju, ka tas tiek pārbaudīts.
Un patiešām, jūs varat izmantot iekavas un operatorus, piemēram, plus
savā kodā, piemēram, C valodā.
Ļaujiet man tagad doties uz priekšu un gūt punktus.
Nav sintakses kļūdu.
Tas ir labi, tur nekā netrūkst.
Un tagad ļaujiet man izdarīt ./scores un redzēt, kāds ir mans testa
vidējais rādītājs.
Labi, tas nav lieliski, bet es domāju, ka es tomēr izturēju.
Un tiešām, mans vidējais rādītājs šeit ir 59.
Vai tas ir tieši 59?
Nu paskatīsimies.
Patiesībā, tā vietā, lai izmantotu int, kā būtu, ja mēs tur izmantotu
kaut ko līdzīgu peldošā komata vērtībai?
Un ļaujiet man iet uz priekšu un darīt to.
Tāpēc ļaujiet man pārkompilēt savu kodu un iegūt punktus.
Nu labi, man ir problēma.
Ļaujiet man tuvināt savu termināļa logu.
Mēs noteikti šo neesam redzējuši iepriekš.
Bet kļūda 9. rindā.
Formāts norāda tipu double, kas ir ļoti precīzs, bet argumentam ir
tips int.
Tātad, ko tas nozīmē?
Nu, tas man parāda, ka starp %f un šo lietu šeit kaut kas nav kārtībā.
Kreisajā pusē es domāju pludiņu vai dubultu.
Tomēr labajā pusē ir norādīts, kāds datu tips ir score1, score2,
score3?
Labi, tāpēc tie ir ints.
Tātad klanam šis nepatīk.
Kompilatoram vienkārši nepatīk, ka es izmantoju ints labajā pusē, bet
es gribu pludiņus pa kreisi.
Tāpēc būs dažādi veidi, kā to atrisināt.
Viens veids būtu vienkārši ignorēt problēmu, kā es to darīju
sākotnēji, un vienkārši atgriezties pie %i.
Vai arī, piemēram, %d bieži ir alternatīva %i decimālskaitļam.
Bet mēs izmantojam %i, jo tas izklausās pēc int, tāpēc arī %i šeit ir
labi.
Bet es nevēlos vienkārši izvairīties no problēmas.
Es vēlos faktiski parādīt peldošā komata vērtību.
Tātad, kā es varu to labot?
Izrādās, ka es to varu atrisināt dažādos veidos.
Vienkāršākais ir tikai pārliecināties, ka vismaz viens skaitlis
labajā pusē ir peldošā komata vērtība, piemēram, 3,0, nevis tikai 3.
Tagad domāju, ka klangāšana būs priecīgāka.
Ļaujiet man gūt punktus — Ienāc.
Un tiešām, viss ir kārtībā.
Kāpēc?
Tiklīdz labajā pusē ir vēl vismaz viens precīzāks datu veids, tajā
brīdī viss tiek apstrādāts kā peldošā komata vērtība, lai matemātika
izdotos.
Tātad ./scores, ievadiet — un tagad mēs ejam, vai ne?
Daži no mums patiešām varētu vēlēties šo 1/3 punkta.
Mūsu vidējais rādītājs nebija 59.
Tas ir 59 1/3, kā šajā gadījumā.
Labi, tāpēc mēs to esam atrisinājuši.
Tomēr šeit ir jāparāda vēl viena tehnika.
Ja jūs nevēlaties to mainīt uz 3.0, jo tas ir nedaudz dīvaini, jo
bija burtiski trīs punkti, nav tā, ka tam ir jābūt komatam, jūs
varētu arī nepārprotami pārvērst 3 par peldošu, iekavās pasakot ,
peldēt.
To sauc par tipa apraidi.
Un tas vienkārši pārveidos lietu uzreiz pēc tās uz šo datu tipu, ja
tas būs iespējams.
Tātad, ja es to daru vēlreiz, iegūstiet punktus, tagad bez kļūdām.
./rezultātus, un es iegūstu tādu pašu rezultātu.
Šeit ir neliela noapaļošanas problēma, taču mēs zinām, ka noapaļošana
ir saistīta ar pagājušās nedēļas neprecizitāti.
Pagaidām ļaujiet man būt apmierinātam ar savu 59,3 kaut ko.
Pagaidām to ņemšu.
Bet šī man tagad ir tikpat tuvu pietiekami labai pareizai atbildei.
Bet kā es tagad domāju par to, kas notiek datora atmiņā?
Nu, padomāsim.
Šeit ir tas pats atmiņu režģis.
Katrs lodziņš apzīmē baitu.
Kur manā atmiņā ir score1, score2 un score3?
Labi, score1, ļaujiet man tikai ierosināt, ir augšējā kreisajā stūrī.
Bet tas aizņem četras kastes 4 baitiem.
Iespējams, ka Score2 atmiņā paliek tieši blakus, lai gan tas ne
vienmēr tā būs, bet es izvēlējos vienkāršus piemērus.
73 ir blakus, kas arī aizņem 4 baitus.
Un, visbeidzot, 33 ir 3. punktā, apakšā.
Tagad, ja mēs patiešām skatāmies uz datora atmiņu, paskatāmies uz to
ar kaut kādu mikroskopu vai tamlīdzīgi, patiesībā katrā no šīm četrām
četru baitu grupām ir 32 biti, 32 biti, 32 biti, kas atspoguļo šīs
vērtības.
Bet atkal, šodienas nolūkos mums nav īsti jādomā atkal un atkal
bināri.
Tiešām, šie decimālskaitļi tur tiek glabāti.
Bet tagad es apgalvoju, ka šis nav labākais dizains.
Pat ja jūs nekad neesat programmējis pirms CS50, ko jūs skatāties
šeit uz ekrāna, kā fragmentu, kādā ziņā šis varbūt ir slikts dizains,
lai gan tas ir pareizs veids, kā saglabāt trīs pārbaudes rezultātus?
Kas te slikts?
Jā?
ir, jo vairāk jūs [dzirdams]..
DEIVIDS MALANS: Jā, vienmēr dariet tieši to, ko darījāt —
ekstrapolējiet uz 4 ballēm, 5 ballēm 50 ballēm.
Tas nevar būt tik labi izstrādāts, jo tagad jums būs 4 koda rindiņas,
5 koda rindiņas, 50 koda rindiņas, kas ir gandrīz identiskas, izņemot
šo, piemēram, patvaļīgo numuru, ko mēs atjauninām beigās. no mainīgā
lieluma.
Tātad patiešām, iespējams, būs labāks veids, lai gan vismaz C mēs vēl
neesam redzējuši šo tehniku.
Bet šodien risinājums būs kaut kas, ko sauc par masīvu.
Masīvs ir veids, kā saglabāt datus datora atmiņā, lai jūs varētu
viegli piekļūt katram atsevišķam dalībniekam.
Citiem vārdiem sakot, ar masīvu jūs varat darīt kaut ko līdzīgu šim.
Tā vietā, lai teiktu int score1, int score2, int score3, piešķirot
katram vērtību, vispirms varat pateikt datoram, lūdzu, iedodiet man
mainīgo, ko sauc par scores — daudzskaitlī, lai gan jūs varat to
saukt jebko, ko vēlaties — katra izmēra trīs. no kuriem būs vesels
skaitlis.
Tas ir, šādi jūs deklarējat masīvu C, kurā būs pietiekami daudz
vietas, lai saglabātu trīs veselus skaitļus.
Citiem vārdiem sakot, šis ir tehniskais veids, kā pateikt datoram,
lūdzu, dodiet man kopā 12 baitus — 3 reizes 4 katrs par int, tāpēc
dodiet man kopā 12 baitus.
Un tas, ko darīs dators, garantēs, ka tie atrodas datora atmiņā.
Un tas noderēs pēc brīža.
Tāpēc ļaujiet man darīt ar to kaut ko noderīgu.
Ļaujiet man saglabāt trīs faktiskos punktus.
Lūk, kā es tagad varētu saglabāt tos pašus skaitliskos rādītājus šajā
masīvā.
Sintakse ir nedaudz atšķirīga, taču ir viens mainīgais, ko sauc par
rādītājiem.
Bet, ja vēlaties doties uz tās pirmo atrašanās vietu, sākot no
šodienas, jūs izmantojat kvadrātiekavas un vispirms dodieties uz
vietu 0, kas, tā kā lietas C ir indeksētas ar 0, tā teikt, jūs sākat
skaitīt no 0.
Pirmais int ir [0].
Otrais int ir [1].
Trešais int ir [2].
Tātad tas nav viens, divi, trīs.
Tas ir burtiski 0, 1, 2.
Un tas nav kaut kas, ko jūs kontrolējat.
Jums jāsāk ar 0.
Tātad šīs rindas tagad izveido masīvu ar trīs lielumu un pēc tam
ievieto vienu, divas, trīs vērtības šajā masīvā.
Bet tagad ir tas, ka jums ir jāatceras tikai viens mainīgā nosaukums.
To sauc tikai par rādītājiem.
Jā, jums jāiedziļinās masīvā, lai iegūtu atsevišķas vērtības.
Jums ir jāindeksē tajā, izmantojot šīs kvadrātiekavas.
Bet vismaz jums nav šīs dīvainās pieejas deklarēt atsevišķu mainīgo
katrai no šīm vērtībām.
Ļaujiet man atgriezties pie scores.c šeit.
Un ļaujiet man ierosināt to darīt.
Ļaujiet man izmantot to pašu ideju, lai veiktu tālāk norādītās
darbības.
Ļaujiet man atbrīvoties no šiem trim atsevišķiem veseliem skaitļiem.
Ļaujiet man sniegt sev 3. izmēra int punktu masīvu.
Un tad rezultāti[0]
tāpat kā iepriekš būs 72.
Rezultāti[1] būs 73.
Un rezultāti[2] būs 33.
Un ļaujiet man atbrīvoties no mazā punkta.
Labi, tāpēc tagad, ja es turpināšu un palaižu šo vēlreiz ar iegūto
punktu skaitu - ievadiet.
Ah, ko es šeit izdarīju nepareizi?
Man šķiet, ka esmu mazliet pārāk apsteidzis sevi.
Ļaujiet man palielināt savu termināļa logu.
Vispirms pievērsīsimies 10. rindiņai.
Kļūda, nedeklarēta identifikatora izmantošana, rezultāts1.
Ko es te stulbu izdarīju?
Jā?
Mērķauditorija: Jūs to nenorādījāt kā mainīgo.
DEIVIDS MALANS: Pareizi, tāpēc es nepaziņoju rezultātu 1.
Man ir vecs kods.
Tātad, godīgi sakot, es šeit apsteidzu sevi, pat ne apzināti.
Tāpēc ļaujiet man turpināt un atkal samazināt termināļa logu.
Šeit man jāpabeidz sava doma.
Tāpēc ļaujiet man notīrīt savu termināli.
būt scores[0] plus scores[1] plus
punktu skaits[2].
Tāpēc tas ir nedaudz runīgāks, jo man ir šīs kvadrātiekavas, tā sakot.
Bet es domāju, ka tagad mans kods ir konsekvents.
Tāpēc ļaujiet man tagad gūt punktus.
Tagad tas tiek apkopots.
./scores man patiešām parāda to pašu aptuveno vidējo rādītāju ar tām
pašām vērtībām.
Labi, tāpēc ļaujiet man turpināt un, iespējams, to nedaudz uzlabot.
Ir nedaudz muļķīgi rakstīt īpašu programmu, lai pārbaudītu vidējos
trīs pārbaudes rezultātus, piemēram, 72, 73, 33.
Kāpēc es nepadara programmu dinamisku un neprasu cilvēkam šos punktus?
Tā vietā ļaujiet man to izdarīt.
Kā būtu, ja mēs atbrīvotos no 72 un mainītu šo uz getInt.
Un es vienkārši pamudināšu lietotāju novērtēt rezultātu.
Ļaujiet man atbrīvoties no 73 un panākt, lai tas būtu getInt
rezultāts, citāts bez pēdiņām.
Un, visbeidzot, atbrīvojieties no 33 un aizstājiet to ar getInt,
citējiet un citējiet, novērtējiet.
getInt pagaidām ir CS50 lieta, tāpēc man, kā vienmēr, jāiekļauj
cs50.h.
Bet es domāju, ka tagad tā ir sava veida labāka programma, jo tagad
es varu to vienreiz sastādīt un pat dalīties ar draugiem.
Un tagad ikviens no mums dažu nodarbību pārbaudē var iegūt vidēji
trīs punktus.
Viņiem nav jāzina kods vai jāpārraksta kods, lai tikai ierakstītu
savus rezultātus.
Lai rezultāti būtu nostrādāti.
./scores, tagad varu rakstīt visu, ko vēlos — varbūt tas ir 72, 73,
33, joprojām saņemu to pašu atbildi.
Vai varbūt man ir labāks semestris, 100, 100, varbūt 99, un tagad mēs
tur joprojām iegūstam diezgan augstu rezultātu.
Bet tagad tas ir dinamisks.
Tagad jums nav nepieciešams avota kods.
Programma nav jāpārkompilē.
Tas tikai strādās atkal un atkal.
Bet arī šis.
Ļaujiet man ieteikt, ka šis kods ir pareizs, ja es vēlos saņemt trīs
punktus no lietotāja.
Bet vai šīs tagad izceltās līnijas, no 6 līdz 9, ir labi izstrādātas,
vai jūs teiktu?
Jā?
Mērķauditorija: Vai jūs varat cilpu?
DEIVIDS MALANS: Jā, vai ne?
Tas ir-- mēs varam izmantot cilpu, šeit ir spoileris.
Kāpēc?
Es domāju, mans Dievs, tas ir kā viens un tas pats kods atkal un
atkal un atkal.
Vienīgais, kas mainās, ir numurs.
Un tam atkal vajadzēja būt koda smaržai, jo, ja es turpinu rakstīt
vienu un to pašu atkal un atkal, tā noteikti ir iespēja kaut ko labāk
noformēt.
Tāpēc ļaujiet man to izdarīt.
Ļaujiet man turpināt un joprojām izveidot savu trešā izmēra masīvu.
Bet ļaujiet man izmantot mūsu veco draugu for cilpu, jo int i ir
vienāds ar 0, i ir mazāks par 3, i++.
Un tad šeit, ļaujiet man veikt punktu skaitu — mēs to vēl neesam
redzējuši, bet kāda intuīcija?
Rezultātu grupa — AUDITORIJA: i.
DEIVIDS MALANS: i, jo tas iterācijā izmantos visu, kas ir i,
neatkarīgi no tā, vai tas ir 0 vai 1, vai 2.
Un tad es varu saņemt int, prasot lietotājam punktu skaitu,
neatkārtojoties atkal un atkal.
Cerams, ka, ja es nepieļāvu nekādas drukas kļūdas, sasniegšu punktus,
viss ir labi.
./scores, 72, 73, 33, un mēs atkal esam biznesā.
Bet kods, iespējams, tagad ir labāk izstrādāts, jo tagad es faktiski
neesmu iekodējis punktu skaitu un faktiski neesmu kopējis un
ielīmējis nevienu no šī koda.
Ja tagad ņemam vērā, kas notiek datora atmiņā, vērtību ziņā tas ir
gandrīz vienāds.
Bet tā vietā, lai mainīgie burtiski būtu score1, score2, score3, ir
tikai viens mainīgais.
Tas ir masīvs, ko sauc par rādītājiem.
atrašanās vietas, izmantojot punktu skaitu[0], lai iegūtu
pirmais, rezultāti[1], lai iegūtu
Bet tas ir galvenais.
Atmiņa ir blakus.
Ekrāns ir tikai tik liels, tāpēc tas tiek apvilkts.
Bet fiziski, digitāli atmiņa ir blakus - no augšas uz leju, no
kreisās uz labo pusi.
Un tas ir svarīgi, kāpēc?
Tā kā iekavas norāda 0, 1, 2, ka katrs no šiem veselajiem skaitļiem
ir tikai viena vesela skaitļa attālumā no nākamā.
Tas nevar būt nejauši šeit, pēkšņi.
Tam ir jāatrodas mugurā.
Labi, tagad ir aprīkots ar šo paradigmu, ko mēs vēl varētu šeit darīt?
Nu, izrādās, ir vērts zināt, ka kodā ir iespējams pat nodot masīvus
kā argumentus.
Ļaujiet man šo programmu nedaudz ātri papildināt, lai jūs to redzētu
jau sen.
Bet ļaujiet man iet uz priekšu un darīt to.
Ļaujiet man ierosināt izveidot funkciju, kas veic šo vidējo rādītāju
manā vietā.
Tāpēc es izveidošu funkciju, ko sauc par vidējo, kas atgriež pludiņu.
Un argumenti, ko šī lieta pieņems - redzēsim, tas būs masīvs.
Tātad izrādās, ja vēlaties iekļaut skaitļu masīvu, varat to saukt par
visu, ko vēlaties.
Tādā veidā jūs sakāt C, ka funkcijai ir nepieciešams nevis vesels
skaitlis, bet gan veselu skaitļu masīvs.
Un jums tas nav jāsauc par masīvu.
Es to daru tikai diskusijas dēļ.
To var saukt par x.
Tie var būt cipari.
Tas var būt jebkas cits.
Es vienkārši izsaucu masīvu, lai būtu ļoti skaidrs, kas tas tur ir.
Tagad, kā es varu mainīt savu kodu šeit?
Tas, ko es domāju, ka šobrīd darīšu, ir tikai šis.
Es atbrīvošos no šī koda šeit, kur es manuāli aprēķināju vidējo.
Un ļaujiet man šeit nosaukt vidējo funkciju, nododot visu punktu
skaitu.
Tātad šis ir tikai abstrakcijas piemērs, piemēram, tagad man ir
funkcija, ko sauc par vidējo.
Man vienalga.
Man nav jāatceras, kā tas darbojas, kad esmu to ieviesis.
Tas tikai nedaudz pastiprina manu galveno kodu.
Bet man tas joprojām ir jāīsteno.
Tāpēc vēlāk manā failā — ļaujiet man atkārtot sevi iepriekš, vienīgo
reizi, kad C valodā ir pareizi atkārtot sevi atkal un atkal, vēlreiz
ierakstot vidējo vērtību un pēc tam iekšējā masīva atvērto iekavu —
bet tagad ne semikolu.
Tagad man šī lieta ir jāīsteno.
Un es varu to īstenot daudzos dažādos veidos, bet es nezinu
iepriekš — es nevaru to vienkārši izdarīt.
Es nevaru vienkārši veikt masīvu[0]
ja vien šī programma nedarbosies tikai ar trim cipariem.
Tāpēc ļaujiet man iet uz priekšu un darīt to.
Vispirms ļaujiet man ierosināt, ka šeit ir slikts dizains.
Kādu vērtību savā galvenajā funkcijā esmu atkārtojis divas reizes?
Kas starp izceltajām līnijām tev uzkrīt divreiz?
Mērķauditorija: masīva garums?
DEIVIDS MALANS: Jā, masīva garums ir tikai trīs.
Tagad tas nav nekas liels, ka es ierakstīju ciparu trīs 8. un 9.
rindiņā, taču tas ir tieši tāds īsinājumtaustiņš, kas galu galā
sagādās jums nepatikšanas.
Kāpēc?
Jo galu galā jūs vai kāds cits ieiesiet un padarīsiet masīvu lielāku
vai mazāku, un jūs nesapratīsit, ka tas pats skaitlis ir divās
vietās.
Un patiešām, programmētājs to bieži sauc par burvju numuru.
Maģisks skaitlis ir tāds, kas tikai kā maģiski parādās.
Un jūs esat goda sistēmā, lai to mainītu šeit, ja jūs to maināt šeit,
un tad jūs to maināt šeit.
Tas labi nebeigsies, ja programmētājam ir pienākums atcerēties, kur
viņi ir iekodējuši, tas ir, skaidri uzrakstīja trīs.
Tātad, kad jūs atkārtoti izmantojat šādu vērtību, jūs zināt ko?
Mums, iespējams, vajadzētu darīt to, ko darījām pagājušajā nedēļā,
proti, deklarēt mainīgo, iespējams, manas programmas pašā augšdaļā,
tāpēc ir ļoti skaidrs, kas tas ir, ko sauc, varbūt n, un iestatiet to
vienādu ar 3.
Vēl labāk, ko es darīju pagājušajā nedēļā, lai pārliecinātos, ka
nevaru sabojāt un nejauši mainīt šo vērtību?
Jā, pastāvīgi.
Un atslēgvārds tur bija tikai saīsināts const.
Un tagad man ir globāls mainīgais — globāls tādā nozīmē, ka varu tam
piekļūt jebkur — to sauc par n.
Tas ir int.
Un tas vienmēr būs 3.
Un tagad es varu nedaudz uzlabot savu galveno funkciju, vienkārši
mainot 3 uz n, tāpēc tagad, ja es, ja kolēģis sapratu, ak, pagaidiet,
šogad ir četri testi.
Jūs nomaināt n uz četriem, pārkompilē kodu, un tas vienkārši darbojas
visur citur, izņemot manu vidējo funkciju.
Ļaujiet man mainīt to atpakaļ uz 3, lai nodrošinātu konsekvenci.
Tas tagad nedarbosies, lai vienkārši summētu, piemēram, šādas lietas,
un pēc tam atgrieztu to dalītu ar 3.
Kāpēc tas nedarbosies tagad, kā es to definēju?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Labi, iespējams, es atgriežu veselu skaitļa vērtību,
kad plānoju atgriezt peldošo vērtību.
Bet es domāju, ka ar mani viss ir kārtībā, jo es izmantoju šo mazo
triku, lai pārliecinātos, ka vismaz viens no skaitļiem manā
aritmētiskajā izteiksmē faktiski ir peldošā komata vērtība.
Un, vienkārši pievienojot punktu 0, pārliecinieties, ka viss tiek
uzskatīts par pludiņu.
Tāpēc es domāju, ka tas ir labi.
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Es atvainojos, mazliet skaļāk.
it kā tu būtu [NEdzirdams]..
DEIVIDS MALANS: Tieši tā.
Tātad kreisā roka šeit nerunā ar labo roku, jo mana pašreizējā vidējā
ieviešanā joprojām tiek pieņemts, ka būs tikai trīs testi vai kas
cits.
Bet pagaidiet, es tikko piedzīvoju problēmas, pārveidojot to par n,
vispārīgi.
Un, ja es mainīšu šo uz 4, es, iespējams, nebūšu apmierināts ar savu
vidējo, jo tagad es ignorēšu vienu no saviem pārbaudes rezultātiem.
Tāpēc ļaujiet man to mainīt atpakaļ uz 3.
Un diemžēl, ja tas ir mainīgais tagad, n, un tāpēc man burtiski ir
mainīgs punktu skaits, kā es varu ņemt vidējo no mainīga skaita
lietu?
Es domāju, kāds tur ir mans celtniecības bloks?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Jā.
Kāpēc es neizmantoju cilpu, kas iet cauri masīvam un saskaita lietas,
ejot?
Es domāju, līdzīgi kā pamatskolā, kad jūs ņemat vidējo rādītāju uz
kalkulatora vai papīra un zīmuļa, jūs vienkārši turpinat saskaitīt
skaitļus un beigās dalāt ar kopējo lietu skaitu.
Tātad, kā es varu to izdarīt?
Ļaujiet man mainīt vidējo vērtību, lai vispirms deklarētu mainīgo, ko
sauc par summu vai citu, iestatītu to vienādu ar 0.
Tātad tas ir tāpat kā es uz papīra lapas, kas gatavojas skaitīt, vai,
protams, mans kalkulators, kad to ieslēdzat, parasti pēc noklusējuma
ir nulle.
Un tagad, ļaujiet man darīt, int i ir vienāds ar 0.
es esmu mazāks par — nu, nē, es to nedarīju.
i ir mazāks par n, i++.
Un tagad šeit, ļaujiet man iet uz priekšu un pievienot pašreizējai
summai neatkarīgi no tā, kas atrodas masīva atrašanās vietā, t.
Un tad šeit, es domāju, ka varu atgriezt dažus dalītus ar 3,0, nevis
3,0, n, iespējams, šeit.
Un patiesībā es domāju, ka es saņemšu... pārliecināsimies, ka tas ir
pludiņš.
Izmantosim veidu liešanas triku, lai pārliecinātos, ka es kādu
nejauši nesaīsinu un neizmetu visu pēc komata.
Tātad tas vienkārši saasinājās ātri, vai ne?
Vidējais tikko iesaistījās daudz vairāk.
Tā nav tikai viena koda rindiņa, bet tagad tā ir dinamiska.
Es inicializēju mainīgo, ko sauc par summu, uz 0.
viss, kas ir masīvā [i]--
vai īpaši masīvs[0],
Tas man dod kopējo summu, ko es atdodu, dalītu ar kopējo lietu skaitu.
Tagad es varu nedaudz pievilkt.
Atcerieties, ka tas ir sintaktiskais cukurs, kas paredzēts tikai
lietu pievienošanai.
Es nevaru izmantot plus plus, jo tas tikai burtiski pievieno vienu.
Bet es varu izmantot šeit plus vienāds.
Vai jums ir jautājumi par šo ieviešanu?
Patiešām, vienīgais izņēmums — vai vissvarīgākais ir tas, ka šī ir
sintakse funkcijai pateikt, ka tā sagaida veselu masīvu, nevis vienu
mainīgo, piemēram, int vai tamlīdzīgi.
Jūs burtiski izmantojat kvadrātiekavas, bet tur nenorādiet garumu.
Jā?
[NEdzirdams] augšpusē?
DEIVIDS MALANS: Kā ar mainīgo augšpusē?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Labs jautājums.
Kā man tas ir definēts kā augšpusē?
Šim mainīgajam N ir jābūt veselam skaitlim, ja jūs to izmantosit
masīvu iekšpusē kvadrātiekavās.
Tātad šajā 10. rindiņā, ievērojiet, vairs nav rakstīts 3, bet gan N.
Un tā, lai kāds N būtu 3 vai 4 vai kaut kas cits, tik daudz veselu
skaitļu es iegūšu šajā masīvā.
Un pēc masīva definīcijas tam ir jābūt veselam skaitlim, kas atrodas
šajās kvadrātiekavās.
Un šeit ir izplatīts neskaidrību avots.
Kad veidojat masīvu, tas ir, deklarējat to, jūs izmantojat
kvadrātiekavas, piemēram, šo, kur ievietojat kopējo vajadzīgo
elementu skaitu.
Kad jūs pēc tam izmantojat masīvu, kā es to daru šeit, jūs vairs
nepieminat int — tāpat kā jūs nepieminat int atkal un atkal, kad
pastāv mainīgais.
Jūs joprojām izmantojat kvadrātiekavas, bet neizmantojat N.
Jūs izmantojat 0 vai 1 vai 2 vai vispārīgi šeit, t.i.
Tātad, kad C tika izstrādāts, viņi dažreiz izmantoja vienu un to pašu
sintaksi divām dažādām idejām vai kontekstiem.
Jā?
Iekļaut 6. rindiņu [NEdzirdams]?
DEIVIDS MALANS: Labs jautājums.
Vai man ir jāiekļauj 6. rinda?
Īsa atbilde, jā, iemesla dēļ, ar kuru mēs saskārāmies pagājušajā
nedēļā.
C jeb tiešām zvana, nolasa jūsu kodu no augšas uz leju, no kreisās uz
labo pusi.
Tātad, ja kompilators 16. rindiņā redz šīs funkcijas vidējo
pieminējumu, bet jūs neesat teicis kompilatoram, ka pastāv vidējais
rādītājs, ekrānā tiks parādīta kļūda.
Tātad parastais veids, kā to izdarīt, ir vienkārši nokopēt un ielīmēt
pirmās koda rindiņas no funkcijas, tas ir tā sauktais prototips vai
deklarācija.
Jā?
Mērķauditorija: Vai ir kāda bibliotēka, ja nezināt masīva lielumu?
DEIVIDS MALANS: Tiešām labs jautājums un ideāls pārejas veids.
Vai ir kāda bibliotēka, kuru varat izmantot, ja nezināt masīva
lielumu?
Nē.
Tātad, ja kāds no jums ir ieprogrammējis Java vai Python vai citās
valodās, jūs faktiski varat vienkārši pajautāt masīvam, cik tas ir
liels?
C valodā jums un man, programmētājiem, tas ir jāatceras.
Un tik īsa atbilde, nē, nav nevienas funkcijas, kas to automātiski
paveiktu mūsu vietā.
Un patiesībā ļaujiet man izteikt smalkāku apgalvojumu, ka ir pareizi
izmantot šādus globālos mainīgos, ja tie patiešām ir paredzēti
konfigurācijas opcijām.
Kāpēc?
Vienkārši ir ērti tos ievietot faila pašā augšdaļā, jo visi, jūs,
jūsu kolēģi, jūsu TA redzēs tos koda augšdaļā.
Bet jums tiešām nevajadzētu tos izmantot visur visā kodā.
Būtu labāk, ja pati vidējā funkcija būtu neatkarīga no šī īpašā
mainīgā.
Tātad ar to es domāju šo.
Vai jūs zināt, kas man būtu jādara, ja es patiešām vēlos būt labi
izstrādāts?
Masīva garums jānodod vidējai funkcijai.
Man vajadzētu dot vidējai funkcijai otru argumentu — es to nosaukšu,
piemēram, par garumu, bet es to varētu saukt par visu, ko vien vēlos.
Tāpēc tā vietā, lai noliktu N līdz galam šeit, mana faila apakšā,
ļaujiet man dinamiski nosaukt garumu.
Un tas ir smalkums — un par to nav nepieciešams pārāk paklupt.
Bet šis tagad ir tikai piemērs tam, kā viena un tā pati funkcija var
izmantot nevis vienu, bet divus argumentus.
Bet patiešām C valodā jums pašam jāatceras, kāds ir masīva garums.
Jūs nevarat vienkārši jautāt masīvam, izmantojot kādu sintaksi,
piemēram, tie no jums, kas iepriekš ir programmējuši Java vai Python.
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Labs jautājums.
Vai būtu labāk izveidot funkciju, kas aprēķina izmēru?
Īsa atbilde, to nevar izdarīt C.
Tiklīdz jūs nododat masīvu funkcijai C, jūs nevarat noteikt tā
lielumu, ja tas ir vispārējs masīvs, piemēram, veselu skaitļu masīvs.
Ir īpaši gadījumi, kad to var izdarīt.
Bet kopumā nē, tas vienkārši nav iespējams C.
Un, ja tas rada zināmu vilšanos, godīgi sakot, tāpēc modernākās
valodas pievieno šo funkciju.
Kāpēc?
Jo tas bija patiešām kaitinoši, jo es šeit atsaucos uz to, ka man nav
šīs informācijas.
Tagad, lai pārliecinātos, ka es nekur neesmu saplēsis, ļaujiet man
apkopot šo partitūras galīgo versiju.
Spriedze.
Viss labi.
./scores, 72, 73, 33, un mēs joprojām esam atpakaļ biznesā.
Tātad šī versija ir sarežģītāka.
Un kā vienmēr, šī versija būs pieejama kursa tīmekļa vietnē uzziņai.
Bet patiesībā būtība ir tāda, ka masīvus var izmantot ne tikai kā
konteinerus vairāku vērtību glabāšanai — šajā gadījumā trīs vai
vairāk — jūs varat arī nodot tos kā argumentus kā tādus.
Labi, tagad, bez tam, uz mirkli vienkāršosim un tagad apskatīsim
rakstzīmju pasauli.
Ja mums ir tikai atsevišķi baiti, kur tas mūs ved?
Un kā tas galu galā mūs noved pie virknēm, lai atrisinātu tādas
problēmas kā lasāmība, kriptogrāfija un tamlīdzīgi?
Piemēram, šeit ir trīs koda rindiņas, kas ir ārpus konteksta un kurās
vienkārši ir saglabātas trīs rakstzīmes.
Un jūs jau varat redzēt, kur tas virzās.
Trīs mainīgie, ko sauc par c1, c2, c3, noteikti beigsies ar sliktu
dizainu visas muļķīgās atlaišanas dēļ.
Bet ievērojiet, es izmantoju vienas pēdiņas, piemēram, pagājušajā
nedēļā, jo tās ir vienas rakstzīmes.
Kā tas izskatās datora atmiņā?
Nu, tas izskatās kaut kas līdzīgs šim.
Ja mēs dzēšam veco atmiņu, c1, c2, c3, iespējams, nonāks šeit, varbūt
ne burtiski augšējā kreisajā stūrī.
Tas ir tikai mākslinieka atveidojums.
Bet c1, c2, c3 laikam tā arī beigsies.
Tagad, kas tur īsti ir?
Tie tiešām ir tie paši trīs skaitļi — 72, 73, 33.
Bet cik bitu ir baitam?
Tikai astoņi.
Tātad, ja mēs aplūkotu šo rakstzīmju bināro attēlojumu, katrs tas
būtu tikai astoņi biti.
Tas ir pietiekami, lai saglabātu mazus skaitļus, piemēram, 72, 73, 33.
Mēs nenodarbojamies ar Unicode un emocijzīmēm un tamlīdzīgi.
Bet būtība ir tā pati.
Lai saglabātu šos skaitļus, jums nav jāizmanto četri baiti.
Varat izmantot citu datu tipu, piemēram, rakstzīmes, un zem pārsega
katram tiks izmantoti tikai atsevišķi baiti.
Bet tas ir kaut kas līdzīgs — tas nav īsti veids, kā mēs ieviešam
virknes, vai ne?
Kad jūs gribējāt teikt, sveiki, pagājušajā nedēļā vai šajā, mēs
izmantojām dubultpēdas.
Un mēs rakstījām visas lietas kopā un izmantojām vienu mainīgo, nevis
trīs, vai ne?
Kad es ierakstīju Deividu, man nebija Dāvida mainīgā.
Man bija viens mainīgais ar nosaukumu nosaukums, kas saglabāja visu.
Tātad C valodā mēs turpinām runāt par šīm lietām, ko sauc par virknēm.
Galu galā mēs redzēsim, ka stīgas ne vienmēr ir tādas, kādas tās
šķiet.
Bet pagaidām galvenais virknēs ir tas, ka tās ir mainīga garuma, tā
sakot, vai ne?
Tās var būt trīs rakstzīmes, Hi, vai piecas rakstzīmes, Deivids vai
kaut kas mazāks vai lielāks.
Tātad, kā īstenot virknes, ja dienas beigās mums ir tikai mana atmiņa?
Šeit ir piemērs, kā vienkārši izveidot, deklarēt un definēt virkni ar
nosaukumu s.
jo tā ir tikai vienkārša virkne un citējiet bezpēdiņās, HI!,
dubultpēdiņās.
Kā tas izskatās datora atmiņā?
Nu, noskaidrosim vēlreiz.
Un šeit, tagad, jo tas ir tehniski saglabāts vienā mainīgajā, s, lūk,
kā es varētu to uzzīmēt kā mākslinieks.
Kopā tas ir trīs baiti — HI izsaukuma zīme.
Bet nav c1, c2, c3, vienkārši viss ir s.
Bet izrādās, ka tas ir jautrs fakts, kas patiesībā slēpjas zem
pārsega?
Savā veidā noved pie tā — kas ir virkne, ja tā ir izkārtota atmiņā?
Mērķauditorija: masīvs.
DEIVIDS MALANS: Burtiski tas ir tikai rakstzīmju klāsts.
Un pagājušajā nedēļā mums nebija jāzina par masīviem, lai izmantotu
virknes.
Šeit atkal sāk atdalīties treniņriteņi.
Bet virkne ir tikai rakstzīmju masīvs.
Piemēram, HI izsaukuma zīme.
s[0], ja vēlaties - s[1], s[2].
Jūs varat burtiski iegūt atsevišķas rakstzīmes, vienkārši apstrādājot
s tā, it kā tas būtu masīvs, kas šajā gadījumā patiesībā atrodas zem
pārsega.
Bet tur ir āķis.
Kā jūs zināt, kur stīgas beidzas?
Agrāk, kad es zīmēju dažus veselus skaitļus uz ekrāna, es zinu, es
apgalvoju, ka tie vienmēr aizņem 4 baitus.
Ja es būtu zīmējis garu, tas vienmēr aizņem 8 baitus.
Ja es būtu uzzīmējis rakstzīmi, tas vienmēr aizņem 1 baitu.
Bet cik baitus aizņem virkne?
Jā, es domāju, tā ir sava veida pareizā atbilde.
Šajā gadījumā, šķiet, trīs.
Bet, ja tas ir Deivids, tie ir labi pieci varoņi.
Bet kur mēs liekam skaitli trīs?
Kur tu liec ciparu pieci, vai ne?
Tas ir burtiski viss, kas atrodas jūsu datorā.
Tie ir visi mūsu celtniecības bloki mūsu priekšā.
Tātad, kā mēs varam... kur tie trīs iet?
Kur paliek piecinieks?
Izrādās, ka to var atrisināt vairākos dažādos veidos.
Bet veids, kā cilvēki pirms gadiem nolēma ieviest virknes, patiešām
ir masīvs, taču viņi katra šāda virkņu masīva beigās pievienoja vienu
papildu baitu, lai ar tā saukto kontrolvērtību būtu skaidrs, ka
virkne beidzas šeit. .
Kāpēc?
Ja datora atmiņā ir divas virknes, piemēram, HI!
un čau, jūs zināt, kur ir barjera starp viena izsaukuma zīmi un burtu
B nākamajā, vai ne?
Jums ir nepieciešams sava veida norobežotājs.
Un tas, kas patiesībā atrodas zem pārsega, ir šis.
Saglabājot virkni atmiņā, ievadot virkni — ja ievadāt 3 rakstzīmes kā
lietotājs, tas izmantos 3 plus 1, kopā ar 4 baitiem.
Ja ierakstāt David, tas izmantos 5 plus 1, kas kopā ir vienāds ar 6
baitiem.
Kāpēc?
Jo C automātiski pievieno šo īpašo 0 virknes beigās.
Es to uzzīmēju ar slīpsvītru 0, jo šādi jūs attēlojat 0 kā rakstzīmi,
kā rakstzīmi.
Bet tas burtiski ir tikai 0, kā mēs drīz redzēsim.
Tāpēc ikreiz, kad atmiņā ir virkne, tā vienmēr aizņem par vienu baitu
vairāk, nekā jūs pats, programmētājs vai cilvēks ierakstījis.
Faktiski, ja mēs to vēlreiz pārveidosim, tikai diskusijas labad, uz
šiem veseliem skaitļiem, datora atmiņā burtiski saglabātais būs 72,
73, 33 un tagad 0.
Un dators, pateicoties C un tam, kā tas tika izgudrots, ir pietiekami
gudrs, lai zinātu, ka, izdrukājot virkni, tas izdrukā katru
rakstzīmi, līdz redz 0, un tad tas vienkārši pārtrauc drukāšanu.
It īpaši printf zina, kā tas darbojas.
Un tāpēc printf zina, kad pārtraukt drukāšanu.
Decimālskaitļi nav tik izglītojoši.
Parasti rakstzīmes rakstīsim šādi.
Un atkal slīpsvītra 0 ir tikai īpaša simbolika.
Tas ir tas, ko programmētājs ieraksta, lai skaidri norādītu, ka jūs
nesakot, HI!, 0.
Jūs sakāt HI!, un tad tas ir īpašs 0.
Konkrēti, astoņi 0 biti norāda, ka tas ir virknes beigas.
Tehniski šo slīpsvītru nulle, ja vēlaties būt iedomātā, to sauc par
nulli, NULL.
Un izrādās, ka jūs to jau esat redzējis, lai gan mēs to nesaucām.
Šeit ir tā pati ASCII diagramma no pēdējām pāris nedēļām.
Ja es to izceļu, kāda ir decimālskaitļa 0 kartēšana?
NUL, kas ir tikai programmētājs, runā par īpašo nulles rakstzīmi.
Visi 0 biti, kas nozīmē, ka virkne beidzas šeit.
Tas viss notiek automātiski.
Jums nav jāizveido šīs nulles rakstzīmes vai šīs nulles.
Vai ir kādi jautājumi par šo ieviešanu līdz šim?
Vai šeit ir kādi jautājumi?
Nē?
Nu, ļaujiet man to izdarīt.
Ļaujiet man pēc sekundes atgriezties pie VS Code.
Un patiesībā apstiprināsim to ar kādu kodu.
Ļaujiet man izveidot nelielu programmu ar nosaukumu hi.c.
Un kā būtu, ja mēs to darītu?
Ļaujiet man iekļaut stdio.h.
Ļaujiet man iekļaut — ļaujiet man ierakstīt galveno tukšumu, kā
vienmēr.
Un tagad ļaujiet man izdarīt kaut ko vienkāršu un kaut ko sliktu, bet
char c1 vienāds ar citātu unquote, h, atsevišķās pēdiņās.
Char c2 ir vienāds ar pēdiņām un pēdiņām, I, atsevišķās pēdiņās.
Un visbeidzot, char c3 vienāds ar izsaukuma zīmi atsevišķās pēdiņās.
Un tagad ļaujiet man to izdrukāt.
Es nevaru izmantot %s, jo tā nav virkne.
Tas ir burtiski trīs rakstzīmes, jo tādu dizaina lēmumu es pieņēmu.
Bet es varētu darīt tā — %c, %c, %c, ko mēs vēl neesam redzējuši, bet
%s ir virkne, %i ir int, %c patiešām ir char.
Tāpēc ļaujiet man tīrības labad beigās ievietot slīpsvītru n, un
tagad dariet: c1, c2, c3.
Tātad šī ir kā uz char balstīta drukas virknes versija.
Tāpēc ļaujiet man pasveicināties!
Un tad ļaujiet man izdarīt ./hi, un izskatās, ka es izmantoju printf
ar %s.
Bet es darīju lietas ļoti manuāli, izdrukājot katru atsevišķu
rakstzīmi.
Tomēr tagad forši ir tas, ka, tiklīdz jūs zināt, ka rakstzīmes ir
tikai skaitļi un virknes ir tikai rakstzīmes, varat kaut kā pabāzt
apkārt.
Ļaujiet man mainīt visus trīs vietturus uz %i.
Un arī tas ir pilnīgi labi.
Ļaujiet man to atkārtot, sveiki.
Patiesībā ļaujiet man veikt vienu izmaiņu, lai mēs to redzētu.
Ļaujiet man pievienot atstarpes, tikai estētikas dēļ, ļaujiet man
izdarīt hi, ./hi, Enter, un, piemēram, tagad jūs faktiski varat
redzēt skaitļus, par kuriem es apgalvoju nulles nedēļā, patiesībā
notika zem pārsega. .
Nu, tas nav veids, kā jūs veidotu stīgas.
Būtu neticami garlaicīgi, ja trīs burtu vārdiem būtu trīs mainīgie,
bet piecu burtu vārdiem - pieci mainīgie.
Mēs, protams, esam izmantojuši virknes kopš pagājušās nedēļas, tāpēc
tā vietā darīsim to.
Virkne s ir vienāda ar pēdiņām un pēdiņām, dubultpēdiņām
"HI!" Šim nolūkam nē, šo treniņriteņu dēļ man ir jāiekļauj
CS50 bibliotēka.
Bet mēs pie tā atgriezīsimies tuvāko nedēļu laikā.
Bet pagaidām es iešu uz priekšu un izveidošu virkni, ko sauc par
citātu uncitētu: "HI!" Un tagad es mainīšu šo, lai tas būtu
mans pazīstamais %s, un tagad vienkārši izdrukāšu pašu s.
Tas, protams, ir tas pats, kas pagājušajā nedēļā, ./hi, man sniedz
tieši to pašu, bet tagad mēs, protams, nodarbojamies ar stīgām.
Bet kā mēs varam redzēt mazliet tālāk?
Nu, kā ar šo?
Pabāzīsimies tālāk ar mūsdienu primitīviem.
rakstzīmi ar %c, veicot s[0].
otrā rakstzīme ar %c, izpildot s[1].
ar %c un izdrukājot s[2].
Tātad atkal tas tikai loģiski izriet no manas izpratnes, ka virknes
ir masīvi, kā jūs atzīmējat.
Ļaujiet man uztaisīt — ļaujiet man uztaisīt sveiki, ./čau.
Un nekādu vizuālu izmaiņu, bet es vienkārši tagad čaloju.
Un patiesībā, ja jūs patiešām interesē, ļaujiet man to izdarīt.
Ļaujiet man tos mainīt atpakaļ uz i, atpakaļ uz i---o, atpakaļ uz i.
paskatīsimies, kas ir s[3].
Šis ir ceturtais baits.
Un, lai gan pati virkne ir HI, es domāju, ka mēs varam apstiprināt
visu šo nulles lietu.
Nospiediet hi, ./hi, Enter, un tas ir.
Jūs to varējāt izdarīt pagājušajā nedēļā, ja patiešām vēlējāties
izklaidēties.
Bet pagaidām tas tikai atklāj, kas notiek zem pārsega.
Jautājumi, kas ir šīs stīgas?
Jā?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Kāpēc mums ir vajadzīgs kronšteins?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Kāpēc jums nav vajadzīgas iekavas?
Labs jautājums.
Kāpēc man nav vajadzīgas iekavas 6. rindā?
Jo s ir virkne.
Mēs redzēsim pēc pāris nedēļām, ka s būtībā ir ieviests zem pārsega,
patiešām kā masīvs, taču tas notiek automātiski.
Varat uzskatīt s tikai kā mainīgā nosaukumu bez kvadrātiekavām.
Kvadrātiekavas izmantosit, ja jums ir int masīvi vai manuāli
izveidojat rakstzīmju vai dubulto zīmju masīvus, pludiņus vai jebko
citu.
Bet stīgas ir īpašas.
Kāpēc?
Es domāju, ka katra jūsu rakstītā programma kaut kādā veidā izmanto
virknes, tekstu.
Mēs esam cilvēki, mums patīk teksts, ne tikai cipari un tamlīdzīgi.
Tāpēc tas ir nedaudz īpaši apstrādāts C un daudzās citās valodās.
Citi jautājumi par šo šeit?
Nē?
Pēc tam pievienosim maisījumam vēl vienu virkni.
Tā vietā, lai vienkārši pateiktu: HI!, kāpēc gan mēs neapsveram
programmas versiju, kurā ir teikts abi: HI!
un AČU!!
Un tagad es apgalvoju, ka šī slīpsvītra nulle, šī nulles rakstzīme
tagad būs arvien svarīgāka, ja mums ir divas virknes atmiņā, lai C
zinātu, kā atšķirt vienu no otra.
Tāpēc ļaujiet man iet uz priekšu un pagaidām vienkārši atbrīvoties no
šīm divām līnijām.
Ļaujiet man atkārtoti izveidot virkni s vienāds, citēt dubultpēdiņas
bez pēdiņām: "HI!" Ļaujiet man dot sev vēl vienu.
Un, tā kā es vienkārši spēlējos, es izvēlēšos ļoti īsus mainīgo
nosaukumus.
Virkne t ir vienāda ar citātu un citātu, "BYE!" Un tad
ļaujiet man tos abus izdrukāt.
Ļaujiet man izdrukāt %s, slīpsvītru n, komatu s un pēc tam izdrukāt f
%s slīpsvītru n un pēc tam t.
Tik ļoti vienkārša šo divu mainīgo demonstrācija.
Izveidojiet hi, ./hi, un, protams, tas izdrukā divas rindas vienu pēc
otras.
Kas patiesībā notiek zem pārsega?
Nu, atgriezīsimies pie datora atmiņas.
Sveiki! Es domāju, ka tas būs gandrīz tāds pats.
Tātad s, es apgalvošu, atrodas augšējā kreisajā stūrī, kam seko
slīpsvītra nulle.
Un tas ir svarīgi tagad, jo BYE!
droši vien tur beigsies.
Un vizuāli tas aptver tikai pēc būtības, kā esmu uzzīmējis šo baitu
režģi, taču tas ir blakus.
AČU-!
null, AKA
atpakaļvērstā slīpsvītra nulle, tagad tas ir noderīgi printf, jo
tagad printf zina, kur sākas un kur beidzas, izmantojot šo īpašo
nulles rakstzīmi.
Bet mēs varam arī tagad pabāzt apkārt.
Ko vēl es varu šeit darīt?
Kā ar šo?
Kā būtu, ja es iedziļināšos savā kodā šeit, atpakaļ uz VS kodu un
ļautu man iet uz priekšu un pateikt kaut ko līdzīgu: labi, ja man ir
divas no šīm virknēm, ziniet, ievietosim tās masīvā.
Veidosim šāda veida masīvus masīvos, šeit sava veida sākuma stilā.
Tātad virknē vārdus[2].
Tātad, dodiet man divu virkņu masīvu, ko es saku šeit kodā, lai gan
mēs to vēl neesam izdarījuši ar virknēm.
Mēs to darījām tikai ar ints.
Un tagad ļaujiet man to izdarīt.
Pirmais vārds AKA vārdi[0]
tāpat kā iepriekš, HI!
Un tagad vārdi[1] būs
vienāds citāts un citāts, "BYE!" Un tagad es esmu darījis
tieši to pašu, bet atkal es vienkārši izvairos no s, t, q, r un
visiem šiem dažādajiem mainīgajiem savā kodā.
Es tikai tagad tos uztveru kā vienu virkņu masīvu.
Kā šeit nomainīt savu kodu?
pirmais vārds, es daru vārdus[0].
otrais vārds, es daru vārdus[1].
Šobrīd tas nav noderīgs uzdevums, jo es tikai sarežģīju savu kodu.
Bet atkal, tas ļauj mums pabāzt apkārt un redzēt, kas notiek, jo ir
tas HI!
un AČU!.
Bet skaties šo.
Ja es patiešām vēlos būt foršs, es varu to izdarīt.
Izdrukāsim %c, %c, %c, slīpsvītru n un tad šeit, %c, %c, %c, %c,
tātad četras no tām.
Un tagad šeit lietas kļūst interesantas.
Vārdi ir virkņu masīvs.
Atkal, ja drīkst, kas ir virkne?
Rakstzīmju masīvs.
Tāpēc izmantojiet to pašu loģiku.
nokļūt pie pirmās virknes ar vārdiem[0].
Kā tikt pie pirmās rakstzīmes pirmajā virknē?
0. iekava, vārdi[0][1],
Un tagad šeit lejā, vārdi[1], bet
pirmais varonis ir tur.
Vārds[1], otrā rakstzīme ir šeit.
Vārdi[1], trešā rakstzīme ir šeit--
ak, trešais varonis ir klāt.
Un vārdi[1], ceturtais
raksturs ir šeit.
Cilvēki neprogrammē šādi.
Tas ir tikai demonstrāciju dēļ.
Dievs, tas jau ir tik garlaicīgi un daudzvārdīgi.
Bet, ja es sveicu tagad, ./čau, tagad, es manuāli izgudroju %s no
jauna, ja esmu aizmirsis, ka tas pastāv, izmantojot tikai %c.
Bet jūs patiešām varat manipulēt ar masīviem šādā veidā.
Taču, tā kā virknes ir rakstzīmju masīvi, ar virknēm var manipulēt
arī šādā veidā.
Vai jums ir jautājumi par šo sintaksi?
Vai šeit ir kādi jautājumi?
Nē?
Labi, iesim uz priekšu un ierosināsim atrisināt pāris citas
problēmas, kuras, iespējams, nav bijušas kā agrāk.
Bet vispirms īss vizuālais ieskats par to, kas šeit notiek zem
pārsega.
Ja šeit atkal ir vieta, kur mēs atstājām ekrānu, HI!
un BYE atpakaļ, lūk, kā es tikko izturējos pret šīm lietām.
s iekava 0, 1, 2, 3 un pēc tam t 0, 1, 2, 3, 4.
Bet tiešām, kad es tos ievietoju masīvā, attēls kļūst par šādu.
Words[0] ir viss HI!.
Words[1] ir viss BYE!.
Bet, ja es patiešām nonāku nezālēs un sāku indeksēt atsevišķas
rakstzīmes šajās virknēs, es izmantoju tikai jaunu sintaksi, lai šeit
attēlotu šīs pašas vērtības.
Vai tad ir jautājumi par šiem attēlojumiem, pirms mēs virzāmies uz
priekšu?
Nē?
Jā?
personāžs nav [NEdzirdams]?
DEIVIDS MALANS: Vai jaunās līnijas varonis — to saka vēlreiz?
Mērķauditorija: vai jaunais rindas varonis aizņem vietu?
DEIVIDS MALANS: Ak, tiešām labs jautājums.
Vai jaunais rindas raksturs aizņem vietu?
Tā ir, ciktāl tas attiecas uz printf.
Bet es savās virknēs neglabāju slīpsvītru n, tā vietā šī lieta tiek
manuāli nodota printf.
Labi, tad ejam uz priekšu un apsvērsim, kā mēs varētu atrisināt dažas
problēmas, kas tagad ir radušās ar šīm virknēm, kā norādīts šeit.
Pieņemsim, ka es... darīsim to.
Ļaujiet man atgriezties pie VS Code šeit.
Un ļaujiet man atvērt jaunu failu, ko sauc par, garums.c.
Un uz brīdi padomāsim, kā es varētu izdomāt, kāds ir virknes garums,
kas atšķiras no masīva garuma.
Es apgalvoju iepriekš, jūs nevarat dinamiski noskaidrot, kāds ir
masīva garums.
Bet es varu noskaidrot virknes garumu, jo īpaši šīs nulles rakstzīmes
ieviešanas detaļās.
Tāpēc ļaujiet man iet uz priekšu un darīt to.
Ļaujiet man iekļaut cs50.h šajā otrajā programmā.
Ļaujiet man iekļaut stdio.h, tāpat kā iepriekš.
Un ļaujiet man to izdarīt, un pirmā lieta, ko es darīšu, ir vienkārši
iegūt virkni no lietotāja.
Es prasīšu lietotājam, kā vienmēr, viņu vārdu.
Tāpēc es piezvanīšu getString un pateikšu, kā jūs sauc, jautājuma
zīme, kā vienmēr.
Un tad šeit, lejā, ja es gribu izdomāt šīs virknes garumu un izdrukāt
garumu uz ekrāna, es varu darīt to pēc būtības līdzīgi kā vidēji, kur
es kaut ko uzkrāju.
Ļaujiet man iet uz priekšu un inicializēt N uz 0.
Ļaujiet man atdot sevi — tā nav for cilpa, jo man nav — es jau
iepriekš nezinu, cik tas ir.
Bet ja es to daru?
Kamēr vērtība pie name[n]
pašlaik nav vienāds ar '/0'-- traka sintakse, bet tā ir tikai
šo dažādo elementu kulminācija.
Ļaujiet man tikai pabeigt domu šeit, n++.
Un tad šeit, izdrukāsim ar printf un %i šo N vērtību.
Tāpēc es apgalvoju, ka tas man parādīs jebkuras ievadītās virknes
garumu neatkarīgi no tā, vai tā ir sveiks vai čau, Deivids vai jebkas
cits.
Es inicializēju mainīgo uz nulli, un tas ir labi, jo tieši tur jūs
sākat skaitīt kopumā.
Lai gan nosaukums[0] nav
vienāda slīpsvītra nulle.
Kas tas par teicienu?
vārds[0] gatavojas
esi pirmais varonis.
Un es uzdodu jautājumu, vai pirmā rakstzīme nav vienāda ar slīpsvītru
nulli?
Un, ja es ierakstu Deivids, D, tas tā nav, tāpēc es turpinu un N
pievienoju 1.
Tad es pārbaudīšu vārdu[1].
vārds[1] būs A.
A nav vienāds ar slīpsvītru nulli, un tāpēc tas atkārtosies atkal un
atkal un atkal.
Bet kopā piecus soļus vēlāk, tas nonāks līdz baitam pēc DAVID,
saprotiet, pagaidiet, tā ir slīpsvītra n.
Cilpa beidzas, un es izdruku kopējo garumu.
Masīviem kopumā nav šīs nulles rakstzīmes.
Tomēr stīgas dara.
Atkal, virknes ir īpašas salīdzinājumā ar visiem citiem datu veidiem,
par kuriem esam runājuši līdz šim.
Bet kā es, piemēram, to varētu darīt savādāk?
Nu, pieņemsim to faktiski kā funkciju, kā es to parasti daru.
Bet tā vietā, lai to īstenotu pats, jūs zināt ko?
Izrādās, kas ir jauks tajā, ka stīgas ir tik izplatītas, ir daudzi
citi cilvēki, kas šīs problēmas ir atrisinājuši jau iepriekš.
Un patiesībā C valodā ir vesela stīgu bibliotēka.
To izmanto kā galvenes failu ar nosaukumu string.h.
Un kas ir string.h, ir ar virknēm saistītu funkciju bibliotēka.
Faktiski CS50 rokasgrāmatās varat redzēt C funkcijas string.h, vismaz
tās, kuras mēs iesakām kā visnoderīgākās, un jo īpaši, ja pamēģināsit
tur, jūs redzēsit, ka ir funkcija, ko sauc par strlen.
Tas nozīmē virknes garumu.
Tas tika nosaukts ļoti īsi, tikai tāpēc, ka to ir nedaudz vieglāk
rakstīt nekā virknes garumu.
Bet strlen stāsta virknes garumu.
Tātad, kā es varu to izmantot savā kodā šeit?
Nu, izrādās, es varu to diezgan vienkāršot.
Ļaujiet man atbrīvoties no savas cilpas, atbrīvoties no manas
grāmatvedības manuāli un darīt kaut ko līdzīgu šim — int n ir vienāds
ar cilvēka vārda, vārda strlen.
Un tagad es vienkārši izmantošu printf, tāpat kā iepriekš, ar %i
slīpsvītru n un izvadīšu n vērtību.
Bet šobrīd ir kāda kļūda.
Ko es esmu aizmirsis izdarīt?
Jā, man ir jāiekļauj galvenes fails ekrāna augšdaļā, tāpēc ļaujiet
man — koda augšdaļā.
Tāpēc ļaujiet man faila augšdaļā iekļaut arī string.h, lai C zinātu,
ka strlen patiešām pastāv.
Ļaujiet man iet uz priekšu un padarīt garumu, tāpat kā iepriekš.
./length — vai tiešām pirmo reizi, kā tevi sauc?
DĀVIDS.
Un, cerams, es redzēsim, patiesībā, 5.
Turpretim, ja es to palaistu vēlreiz un ierakstu HI!, tagad es redzu
trīs.
Tātad strlen ir tikai viena no šīs bibliotēkas funkcijām.
Un ir vēl tik daudz.
Faktiski vēl viena bibliotēka, kas varētu būt noderīga, ir šī
bibliotēka ctype, kas attiecas uz C datu tipiem un daudzām tajā
esošajām funkcijām, kas var būt noderīgas.
Piemēram, pārskatot tās dokumentāciju rokasgrāmatu lapās tiešsaistē,
jūs redzēsit, ka ir funkcijas, ar kurām mēs varam atrisināt līdzīgas
problēmas.
Ļaujiet man iet uz priekšu un piedāvāt šeit — ļaujiet man redzēt.
Pieņemsim piemēru, kas ietver — kā pārbaudīt, vai kaut kas ir ar
lielajiem vai mazajiem burtiem, un pārvērst to tikai par lielajiem
burtiem.
Ļaujiet man atgriezties pie VS Code un iekodēt programmu ar nosaukumu
largecase.c.
Šajā failā es sākšu, kā vienmēr, iekļaujot cs50.h.
Es iekļaušu stdio.h.
Un es pievienošu vēl vienu maisījumam, kas tagad ir arī string.h, lai
pēc vajadzības varētu piekļūt lietu garumam.
Nākamais ir galvenais tukšums.
Un tad savas galvenās funkcijas ietvaros es iešu uz priekšu un
paziņošu virkni ar nosaukumu s.
Es tāpat kā iepriekš izsaukšu getString.
Un es iešu uz priekšu un vienkārši palūgšu lietotājam iepriekš
izsaukto virkni.
Es gribu darīt pirms un pēc.
Neatkarīgi no tā, ko lietotājs ieraksta, tas ir iepriekš.
Bet es vēlos pēc tam visu likt lielajiem burtiem.
Ļaujiet man tagad šajā cilpā izdarīt to.
Ļaujiet man citēt bez citātu "Pēc", lai mēs to redzētu
ekrānā.
Un ļaujiet man darīt četras int i saņem 0, i ir mazāks par strlen no
s, i++.
Ko es grasos darīt?
Es gatavojos atkārtot katru rakstzīmi virknē no kreisās puses uz
labo, no 0 līdz s garumam, bet ne cauri.
Un kā pārbaudīt, vai kaut kas ir rakstīts ar mazajiem burtiem, lai es
varētu to piespiest uz lielajiem burtiem?
Nu, izrādās, es to varētu izdarīt burtiski.
agrāk s[i] ir mazāks par
vai vienāds ar mazo z, tas angļu valodā loģiski nozīmē, ka tas
patiešām ir mazais burts.
Kā tagad pārvērst to par lielajiem burtiem, šo rakstzīmi?
Es varētu burtiski izdrukāt to pašu varoni.
Bet tā šeit nebūtu atbilde, jo tas nemaina vērtību.
Bet ko es varētu darīt tā vietā?
Ļaujiet man patiešām ātri pacelt ASCII diagrammu tāpat kā iepriekš,
un paskatīsimies, vai mēs nevaram gūt ieskatu.
Ja es izvelku to pašu ASCII diagrammu un pieņemu, ka cilvēks ir
ierakstījis mazo burtu a, tas ir 97.
Kāds burts — es vēlos to pārvērst par lielajiem burtiem A, tad kādu
skaitli es vēlos konvertēt 97 uz nulli nedēļā?
Tātad 65, mēs turpinām atgriezties pie tā.
Ko darīt, ja lietotājs raksta ar mazajiem burtiem b?
Es vēlos mainīt 98 vērtību uz 66 utt.
Un kāda ātra matemātika, cik tālu tās ir viena no otras?
Tātad tas vienmēr ir 32, piemēram, lielie burti uz mazajiem burtiem
vienmēr ir, brīnišķīgi, labs dizains, 32 attālumā viens no otra.
Tātad, ko tas nozīmē?
Es domāju, ka mēs jau iepriekš redzējām, ka zem pārsega ogle ir tikai
skaitlis.
Jūs noteikti varat veikt aritmētiku par to.
Un atkal, ja jūs saprotat šos zemākā līmeņa primitīvus, ko darīt, ja
es to darīšu?
Neatkarīgi no tā, kas ir s[i], ja es to zinu
13. rindiņa, ka tas ir mazais burts, vai es vēlos pievienot vai
atņemt 32?
Mērķauditorija: Atņemiet.
DEIVIDS MALANS: Tāpēc es vēlos atņemt, jo es vēlos pāriet no 97 uz 65
vai 98 uz 66, tāpēc patiešām, ja jūs veicat ātru matemātiku, jūs
saņemsit 32.
Tāpēc pietiek tikai uztvert rakstzīmes kā skaitļus, atņemt 32, un,
manuprāt, drukājot to ar %c, mazie burti tiks pārvērsti par lielajiem
burtiem.
Ja tagad ātri pārejat uz reālo pasauli, Microsoft Word vai Google
dokumentiem, ja kādreiz esat izvēlējies izvēlnes opciju, kas laiku pa
laikam liek lietā lielos vai mazos burtus, tas ir tas, ko Microsoft
un Google ir izdarījuši.
Viņi atkārto katru dokumenta rakstzīmi, pārbauda, vai tie ir mazie
burti, un, ja tā, viņi no tā atņem 32 un parāda jauno vērtību.
Ko darīt, ja tas tomēr nav mazais burts?
tad būtu s[i].
Tāpēc ļaujiet man tagad iet uz priekšu un ievadīt lielos burtus,
cerams, bez kļūdām.
./lielie burti, un tagad es ierakstīšu David ar lielo D, bet visu
pārējo ar mazajiem burtiem.
Bet tagad pēc versija ir DAVID — estētiska kļūda.
Ievērojiet šeit, es aizmirsu, lai skaistuma labad, beigās iekļautu
slīpsvītru n.
Nav problēmu, es piebildīšu.
Ļaujiet man izlabot savu kļūdu.
Ierakstiet lielos burtus, ./lielos burtus, Enter.
DEIVIDS, Enter un voila.
Un es apzināti pēc tam pievienoju vēl vienu atstarpi, lai tie būtu
skaisti, lai gan pirms un pēc ir atšķirīgs burtu skaits.
Pēc tam jautājumi par šo ieviešanu, kad kaut ko piespiežot lietot
lielos burtus, kas pats par sevi nav tik izglītojošs, bet tagad ir
reprezentatīvs tam, kā jūs varat izmantot šos zemā līmeņa primitīvus.
Jautājums?
Nē?
Labi, godīgi sakot, tas ir nogurdinoši.
Dievs, tāpat kā Microsoft, Google, visiem, jums ir burtiski
jāizraksta šis kods, lai izdarītu kaut ko vienkāršu?
Nu, nē, tāpēc mums ir tādas lietas kā bibliotēkas.
Un arvien biežāk problēmu kopām, projektiem un ne tikai jūs vienkārši
izmantojat bibliotēkas biežāk, lai atrisinātu problēmas, kas noteikti
ir bijušas citiem cilvēkiem pirms jums.
Tātad, kā es varu izmantot šo bibliotēku ctype.h?
Nu, ļaujiet man atgriezties pie sava koda.
Ļaujiet man to iekļaut starp maniem galvenes failiem.
Lai es varētu viegli pārmeklēt lietas, es mēdzu sakārtot savas
galvenes alfabēta secībā.
Bet tas nav absolūti nepieciešams, bet tas ļauj man, īsumā, saprast,
vai es iekļāvu kaut ko, kas man vajadzīgs?
Tagad ļaujiet man iet uz priekšu un darīt to.
arguments, būtībā, tāpēc s[i].
Un, ja tas atgriež patiesību, Būla vērtību, ja vēlaties, es
piespiedīšu to rakstīt ar mazajiem burtiem.
Bet man šī matemātika vairs nav jādara.
kā ievade, piemēram, s[i],
un tas vienkārši izdara matemātiku jūsu vietā.
Lai jūs varētu abstrahēt 32 lietu un zināt, ka kāds cits ir
atrisinājis šo problēmu jūsu vietā.
Pretējā gadījumā es varu atstāt savu kodu nemainītu zemāk, jo es
nemainu neko citu.
Tātad, ja es tagad izveidoju lielos burtus un pēc tam ./lielo burtu,
David, tikai ar lielo D, un tagad tas joprojām darbojas.
Bet, ja palasa dokumentāciju tālāk, izrādās, ka augšā ir gudri.
Ja ievadāt rakstzīmi uz lielo burtu, tas ir mazais burts, tas
acīmredzami pārvērš to par lielajiem burtiem, veicot šo matemātiku.
Bet, ja ievadāt rakstzīmi uz lielajiem burtiem, kas jau ir lielie
burti, dokumentācijā, ko jūs redzēsit, tiek norādīts, ka tas paliek
nemainīgs.
Tāpēc es varu to visu nostiprināt.
Es varu atbrīvoties no visa pārējā.
Es varu atbrīvoties no visa, ja un, iespējams, tagad, ieviesīšu
programmu, kas ir tikpat pareiza, bet labāk izstrādāta.
Kāpēc?
Mazāks koda rindiņu skaits ir vieglāk lasāms, mazāka kļūdu
iespējamība, pieņemot, ka bibliotēka ir pareiza.
Tas tikai atvieglo un ātrāk man tagad rakstīt kodu.
Tātad, ja es tagad daru, pēdējo reizi ierakstiet lielos burtus,
ievadiet Enter, ./lielo burtu un ierakstiet savu vārdu, joprojām
strādājot.
Bet tagad ievērojiet, ka mēs esam to samazinājuši līdz daudz mazākam
koda rindiņu skaitam, lai gan tagad izmantojot šo papildu bibliotēku.
Vai tad ir jautājumi par to, kā mēs to izdarījām?
Lai gan šis kods, es uzdrošinos teikt, ir pareizs, tas vēl ne vienmēr
ir labi izstrādāts.
Patiesībā šajā pašreizējā implementācijā ir viena koda rindiņa, viens
funkcijas izsaukums, kas ir neefektīvāks, nekā nepieciešams.
Un ļaujiet man pievērst jūsu uzmanību šim 10. rindiņai, kurā mēs
saucam strlen.
Bet mēs to saucam šīs for cilpas iekšpusē, īpaši nosacījuma iekšpusē.
Un kāpēc tā var nebūt labākā ideja?
Nu, vai virknes garums vienmēr mainās?
Es domāju, noteikti ne šīs cilpas ietvaros.
Un tāpēc mēs atrodamies mūsu for cilpas ietvaros 10., 11., 12. un 13.
rindā, katrā iterācijā uzdodot to pašu jautājumu.
Kāds ir s garums?
Un, savukārt, mēs katru reizi zvanām strlenam, lai gan saņemam to
pašu atbildi.
Tāpēc es uzdrošinos pieņemt, ka labāks risinājums šeit būtu varbūt
izdomāt s garumu agrāk savā kodā un varbūt deklarēt mainīgo.
Vai varbūt dariet kaut ko, kas sintaktiski ir nedaudz elegantāks, un
patiesībā ļoti izplatīts dizains šādā ciklā būtu deklarēt ne tikai
vienu mainīgo, piemēram, i, bet faktiski deklarēt otru mainīgo, ko
sauc, piemēram, kur n ir tikai kāds skaitlis, kas n ir vienāds ar s
garumu.
Bet pēc tam šajā stāvoklī, tā vietā, lai atkal un atkal un atkal
sauktu strlen no s, ko es tagad varētu darīt?
Tā vietā es varētu vienkārši salīdzināt i ar pašu n, jo tagad n tiks
aprēķināts tikai vienreiz, kad tas ir inicializēts, tāpat kā i
inicializē līdz nullei.
Un pēc tam mēs salīdzināsim i, kas mainās, ar n, kas nemainās.
Tātad pēc konstrukcijas tas būs nedaudz efektīvāks.
Tagad, ņemot vērā to, labs kompilators varētu arī atpazīt, ka ir šāda
optimizācijas iespēja, un varbūt to izdarīt mūsu vietā.
Bet pagaidām vislabāk ir apgūt ieradumu, vislabāk attīstīt muskuļu
atmiņu, lai paši pieņemtu labākus dizaina lēmumus.
Vai tad ir jautājumi par to, kā mēs to izdarījām?
Nē?
Labi, daži pēdējie šīs dienas celtniecības bloki.
Mēs sākām, runājot par tiem komandrindas argumentiem, kurus izmanto
clang, tādējādi jebkas pēc komandas, ko ierakstāt uzvednē, neatkarīgi
no tā, vai tas ir make vai clang, vai pat CD operētājsistēmā Linux,
jebkurš vārds pēc tam vai kaut kas noslēpumains, piemēram, -o
komandrindas arguments.
Tā ir komandas ievade.
Tas atšķiras no funkcijas argumenta, jo funkcijas arguments, protams,
ir funkcijas ievade.
Bet tā ir tā pati ideja.
Tā ir tikai cita sintakse pēc dolāra zīmes uzvednē.
Izrādās, ka komandrindas argumentus tagad varat izmantot savās
programmās, piekļūstot vārdiem pēc uzvednes.
Un ļaujiet man ierosināt to izdomāt šādi.
Ļaujiet man ierosināt šeit pārslēgties atpakaļ uz VS Code, un es šeit
atvēršu jaunu failu ar nosaukumu greet.c.
Tātad greet.c tā būs programma, kas ļoti vienkārši sveic lietotāju.
Ja mēs to būtu rakstījuši pagājušajā nedēļā, mēs to būtu izdarījuši.
Iekļaujiet cs50.h, pēc tam iekļaujiet stdio.h un pēc tam int main
void, un tad mēs varētu darīt kaut ko vienkāršu, piemēram, virknes
nosaukums ir vienāds ar getString, citējot un citējot: "Kāds ir
jūsu vārds?" Un tad mēs, kā vienmēr, būtu izdrukājuši sveiki, %s
un pēc tam pievienojuši šo vārdu.
Tātad šī ir tā pati programma, ko esam ieviesuši daudzas reizes, lai
pārliecinātos, ka tā darbojas, lai gan, nē, tā nav gluži tā pati
programma.
Semikols ir nepareizā vietā.
Tagad šī ir tā pati programma.
Tāpēc izveidojiet sveicināt, dot ./greet, un es ierakstīšu savu vārdu.
sveiks, Deivid, mēs esam atpakaļ tur.
Tagad, kas, iespējams, ir nedaudz kaitinošas šajā programmā, ja es
ierakstu kaut ko citu, piemēram, Carter, Enter, man ir jāpalaiž
programma, jāgaida uzvedne, ierakstiet savu vārdu un nospiediet
taustiņu Enter.
Un tas ir labi, bet iedomājieties, ja katra programma darbotos šādi.
Piemēram, pieņemsim, ka varat ierakstīt tikai make, tad gaidāt
uzvedni, pēc tam ierakstāt tās programmas nosaukumu, kuru vēlaties
izveidot, un pēc tam nospiediet taustiņu Enter.
Vai vēl ļaunāk, operētājsistēmā Linux, kad jums ir jāmaina
direktoriji, kā tas varētu būt problēmas iestatīšanas gadījumā, kā
būtu, ja jums būtu jāievada CD, Enter, tagad ierakstiet mapes
nosaukumu, kuru vēlaties mainīt, Enter - es domāju, tas tikai
palēnina dzīvi.
Un tāpēc tas ātri kļūst kaitinoši.
Tātad komandrindas argumenti ļauj jums izteikt visu domu uzreiz.
Tātad, kā es varu to izdarīt?
Nu, ja es vēlos savā kodā izteikt komandrindas argumentu jēdzienu, es
varētu darīt kaut ko līdzīgu šim.
Es pirmo reizi varēju pacelties un atbrīvoties no šī tukšuma, kas
šodien nozīmē, ka šī programma neizmanto komandrindas argumentus.
Un es varu to mainīt tieši uz šo.
Int argc, string argv, ar iekavām.
Tagad tas ir noslēpumaini, jāatzīst.
Un ļaujiet man pietuvināt.
Bet es domāju, ka mēs varbūt tagad varam secināt, kas notiek.
Ja main tagad nav void kā ievade, kas nozīmē, ka tam nav nepieciešami
argumenti, protams, spoileris šeit ir tāds, ka tagad main kaut kā
ņems komandrindas argumentus.
Vai ir minējumi par to, kas argv ir vai būs?
Ko tas varētu attēlot?
Tas ir virkņu masīvs, pareizi, pēc sintakses.
Jā?
Mērķauditorija: Visas rakstzīmes tiks izdrukātas.
DEIVIDS MALANS: Tieši tā.
Tas būs visas rakstzīmes vai tiešām visi vārdi, ko ierakstāt uzvednē.
Argc, kā int, kāds minējums?
Argumentu skaits ir tas, ko tas parasti apzīmē, lai gan tehniski šīs
lietas varētu saukt jebko.
Bet tāda ir konvencija.
Tā kā es iepriekš apgalvoju, ka masīvi neseko savam garumam, ja
vēlaties uzzināt, cik vārdus cilvēks ierakstīja uzvednē aiz jūsu
programmas nosaukuma, jums ir jāpasaka ne tikai vārdu masīvs, bet arī
šī masīva garums.
Virknes, jūs varat izdomāt strlen izmantošanas garumu, bet nevarat
noskaidrot virkņu masīva garumu, vārdu kopumu, ko cilvēks ierakstīja.
Tātad, kā es tagad varu to izmantot?
Nu, ļaujiet man iet uz priekšu un darīt to.
"sveiki, %2 /n", pēc tam argv[1].
Tātad šī vēl nav mana koda labākā versija, taču tā ir mana pirmā.
Sveicini, un tagad ļaujiet man darīt ./greet, Deivid visu uzreiz.
Ienāc, sveiks, Deivid.
Tagad ļaujiet man to palaist vēlreiz, ./sveicināt, Kārter.
Ienāc, sveiks, Kārter.
Tas ir neliels uzlabojums, taču man nav jāgaida, līdz getString liks
man nospiest taustiņu Enter.
Tas tikai paātrina lietas, divreiz ātrāk.
Par vienu komandu mazāk jāievada.
Bet es apzināti darīju [1], bet
kāds ir argv sākums?
Tas būtu [0].
Nu, kas tas ir?
Dažreiz tas ir noderīgi, lai gan pagaidām tā nav.
Pieņemsim, ka es pārkompilēju savu kodu un palaižu šo programmu
tagad, sveiciniet Deividu.
Kāds vēlas uzminēt, kas ir argv[0]?
Mērķauditorija: [NEdzirdams]
DEIVIDS MALANS: Saki vēlreiz?
Mērķauditorija: Sveicināti, sveiki.
DEIVIDS MALANS: Sveicināties, ieiet, sveiks, ./sveicināt.
var apskatīt argv[0].
lai sāktu aplūkot [1], kas bija
pirmais vārds pēc programmas nosaukuma.
dariet to argv[2],
ļaujiet man pievienot otro %s.
Ļaujiet man pārkompilēt sveicienu.
Ļaujiet man darīt ./sveicināt Deividu Malanu, Enter, un arī tas tagad
darbojas, izmantojot divus vārdus pēc uzvednes.
Ja es tiešām tagad gribu būt gudrs, es varētu darīt kaut ko līdzīgu
šim.
Kā būtu, ja argumentu skaits, AKA
%s /n un pēc tam argv[1].
Citādi, ja cilvēks nenorādīja tieši divus argumentus, programmas
nosaukumu un savu nosaukumu, vienkārši izdrukāsim noklusējuma
vērtību, lai netiktu aizmirsts vārds vai nav ierakstīti divi vai trīs
vārdi.
Let's just do, sveiki komats pasaule kā noklusējuma.
Un mēs vienkārši ignorēsim to, ko cilvēks ierakstījis.
Ja es to pārkompilēšu, izveidoju sveicienu, es varu darīt ./greet un
vēlreiz Deivids, Enter.
Atvainojiet, ko es palaidu garām?
Jā, tik iesācēju kļūda.
Citādi, labi, sveicini vēlreiz.
./sveicināti, Deivid, ienāc, sveiks, Deivid.
Bet, ja es izlaižu savu vārdu, es vienkārši iegūstu vispārīgo vārdu,
piemēram, noklusējuma vērtību.
Un, ja man kļūst mazliet ziņkārīgs un es ierakstu abus vārdus, tad
arī mani ignorē.
Kāpēc?
Jo es vienkārši neesmu izveidojis atbalstu argc of three.
Es varētu darīt visu, ko vēlos, bet tagad mums ir pieejami šāda veida
celtniecības bloki.
Labi, ko es vēl varu šeit darīt?
Izrādās, ka mums varētu būt dažas pēdējās funkcijas, kas tagad
jāizpilda.
Tomēr ņemiet vērā, ka C valodā, neskatoties uz to, ko jūs varētu
redzēt grāmatās vai tiešsaistes pamācībās, mūsdienās divi oficiālie
galvenās funkcijas definēšanas formāti ir vai nu šis, ko mēs
izmantojam jau divas nedēļas vai tagad šis. , jūs maināt tukšumu uz
int argc un pēc tam pagaidām virkni argv un pēc tam tukšas iekavas.
Un mēs redzēsim, ka arī tas ir vienkāršojums, daži treniņriteņi, ja
vēlaties.
Bet pagaidām šīs ir divas formas, lai gan tiešsaistes pamācībās un
pat grāmatās redzēsit, daži cilvēki izmanto galveno dažādos veidos.
Tie ir divi, kas tagad jāpatur prātā.
Un es atzīmēšu, ka šie komandrindas argumenti ir visur.
Droši vien negaidīju, ka ieraudzīsim šo vārdu šeit ekrānā.
Un ko tas nozīmē?
Nu, izrādās, ka gadu desmitiem ir šī programma, kas ir īpaši aprīkota
ar Linux sistēmām, ko sauc par cowsay.
Kāpēc?
Iespējams, tāpēc, ka kādam kādreiz bija pārāk daudz brīva laika un
viņš nolēma uzrakstīt programmu, kas no govs, kas tekstuāli pasaka uz
ekrāna, izveido ASCII mākslu.
Bet jūs izmantojat cowsay, tikai prieka pēc, komandrindas argumentu
veidā.
Tā, piemēram, ļaujiet man ieteikt atgriezties pie VS Code šeit, nevis
tāpēc, ka vēlos rakstīt kādu kodu, bet es vienkārši vēlos izmantot
savu termināļa logu.
Un ļaujiet man palielināt savu termināļa logu šeit.
Un ļaujiet man ierakstīt kaut ko līdzīgu, kā būtu ar cowsay, space
moo?
Tātad cowsa nav programma, kuru es rakstīju.
Tas pastāv jau vairākus gadu desmitus.
Bet mēs to instalējām VS Code jums mākonī.
Tam nepieciešams vismaz viens komandrindas arguments.
Ko jūs vēlaties, lai govs saka?
Es varu teikt: “Cowsay moo” un nospiediet taustiņu Enter, un var, ir
mana ASCII māksla ar govs, kas saka uz ekrāna “moo”.
Tas var pateikt vairākus vārdus.
Tāpēc es varu teikt: Sveika, pasaule, ienāc.
Un tagad tas saka: Sveika, pasaule.
Tātad šis ir tikai piemērs muļķīgai programmai, kas izmanto
komandrindas argumentus, taču tai ir nepieciešami arī citi.
Tāpat kā zvana, izmantojiet šo defises, lai mainītu programmas izvadi.
Dash kaut ko ir tikai ļoti izplatīta vienošanās ar komandrindas
argumentiem, ja vēlaties ļoti īsu apzīmējumu kādai opcijai, piemēram,
izvadei.
Cowsay valodā es izlasīju dokumentāciju, un izrādās, ka tur ir
domuzīme f komandrindas arguments, kas ļauj mainīt govs izskatu, ja
vēlaties.
Tātad, ja es lietoju cowsay dash f, pīle un pēc tam kādu citu vārdu,
piemēram, čukst, tā vairs nav govs.
Šis komandrindas arguments pārvērš to par niecīgu, burvīgu pīli.
Un visbeidzot, tikai prieka pēc, jo pārāk daudz laika pavadīju
spēlējoties ar komandrindas argumentiem.
Cowsay dash f, pūķis, un kā būtu, rawr, Enter, jūs pat varat to iegūt
ekrānā šeit.
Tātad arī šis ir tikai piemērs tam, ko varat darīt ar šiem
komandrindas argumentiem tagad, kad mums ir šis veidošanas bloks.
Un tagad ir vēl viena lieta, ko mēs varam darīt ar kodu.
Šodien ir vēl viena funkcija, ko mēs iepazīstināsim, pirms mēs tagad
savienosim visus šos punktus ar lasāmību un šifrēšanu, runājot par
to, ko sauc par izejas statusu.
Izrādās, ka ikreiz, kad jūsu galvenā funkcija iziet, tā atgriež
slepenu veselu skaitli, ko jūs kā programmētājs vai pieredzējis
lietotājs varat noskaidrot, kas tas bija.
Un šie izejas kodi, izejas statusi, parasti tiek izmantoti, lai
norādītu uz kļūdām.
Piemēram, ja pēdējo pāris gadu laikā esat izmantojis tālummaiņu un
kādreiz esat saskāries ar kļūdu, iespējams, esat redzējis šādu
ekrānu.
Parasti tas nav tik noderīgi, iespējams, liek noklikšķināt uz Ziņot
par problēmu vai Sazināties ar atbalsta dienestu.
Taču ļoti bieži mūsu cilvēku pasaulē Mac datoros, personālajos
datoros un tālruņos jūs redzat noslēpumainus kļūdu kodus, piemēram,
burtiski skaitļus, kurus, iespējams, zina tikai Zoom, vai Microsoft
vai Google, vai kāds cits uzņēmums ir uzrakstījis jūsu izmantoto
programmatūru.
Bet šis skaitlis atbilst konkrētai kļūdai, par kuru kāds cilvēks kaut
kur zina, ka tā var notikt.
Tie tiek izmantoti līdzīgi, lai gan ar citu nosaukumu, par kuru mēs
runāsim vēlāk, arī tīmeklī.
Vai esat kādreiz redzējis šo — varbūt nevis raksturu, bet gan skaitli?
Tātad, ko nozīmē 404?
AUDITORIJA: Kļūda.
DEIVIDS MALANS: Tātad kļūda, jā, bet patiesībā tā nav atrasta.
Tātad, kāpēc?
Es domāju, šī ir visslēptākā lieta.
Un mēs runāsim pēc dažām nedēļām par to, ko nozīmē šis un citi
skaitļi, taču skaitļi ir mums visapkārt tehnoloģijās, un tie ļoti
bieži kaut ko nozīmē tehniskajiem cilvēkiem, kuri uzrakstīja
programmatūru, mazāk tādiem cilvēkiem kā jūs un es.
Tas, kāpēc tik daudzi no mums atpazīst 404, ir dīvaini, jo tas ir
pastāvējis pietiekami ilgi, lai mēs visi to zinām.
Bet tas tiešām ir tikai īpašs skaitlis, kas apzīmē sava veida kļūdu.
Tātad izrādās, pēdējā lieta, ko mēs šodien atklāsim par to, ko mēs
divas nedēļas esam uzskatījuši par pašsaprotamu, ir tas, kas ir
galvenais.
Mēs redzējām tikai pirms brīža, ka iekavās esošā lieta, kas līdz šim
ir bijusi nederīga, kas nozīmē, ka nav komandrindas argumentu.
tagad int argc string argv iekavas nozīmē tikai, jā, komandrindas
argumentus.
Un mēs esam redzējuši, kā tiem piekļūt.
Tātad pēdējais mīklas gabals, godīgi sakot, no visas slepenās
sintakses pēdējo divu nedēļu laikā, ir tieši tas, ko nozīmē int.
Int vienmēr ir norādīts galvenajam, un tas norāda, ka galvenais
vienmēr atgriezīs veselu skaitli, lai gan jūs un es nekad to
nepārprotami darījām.
Parasti galvenais pēc noklusējuma atgriež 0.
Bet būtu dīvaini, ja redzētu kļūdas ziņojumu ar 0, tāpēc 0 ir
vienkārši paslēpts.
Jūs to nekad neredzētu ekrānā.
Bet tas notiek automātiski atkarībā no tā, kā C ir izstrādāts.
Tāpēc ļaujiet man šeit uzrakstīt vienu pēdējo programmu.
Es to nosaukšu, piemēram, status.c, lai parādītu šos izejas statusus.
arguments. int argc, virkne argv[],
tātad kopēt, ielīmēt.
Bet tagad darīsim to.
Ja argc nav vienāds ar -- kāpēc mēs nedarām kaut ko līdzīgu šim?
Neizmantosim tikai noklusējumu sveiks, pasaule kā pagājušajā reizē.
Kliedzam uz lietotāju.
Pieņemsim, ka trūkst komandrindas argumenta, piemēram, printf, lai
viņi zinātu, ka ir sabojājušies un programma ir jāpalaiž vēlreiz
pareizi.
un pēc tam pievienojiet argv[1], tāpēc
cilvēka vārds no uzvednes.
Tagad šajā brīdī ļaujiet man iet uz priekšu un palaist statusu
./status, un es vispirms neko neievadīšu.
Uz mani kliedz.
Šoreiz es to ierakstīšu vēlreiz.
./status David, un tas darbojas pareizi.
Bet tagad ļaujiet man jums parādīt nedaudz slepenu, noslēpumainu
komandu.
Varat to ierakstīt pēc uzvednes, un tā ir tikai sakritība, ka ir vēl
viena dolāra zīme.
Echo $?, pilnīgi noslēpumains, taču tas ļauj jums redzēt, ar kādu
izejas statusu jūsu programma ir beigusies.
Tāpēc ļaujiet man palaist to vēlreiz nepareizā veidā.
./status, tiek parādīts kļūdas ziņojums.
Kas tika slepeni atgriezts?
Es to neredzu.
Acīmredzot nav kļūdu ekrāna, taču, ierakstot echo $?, es redzu, ka
mana programma automātiski pēc noklusējuma atgriež nulli.
Tomēr, ja es to palaistu vēlreiz pareizi, ./status David, Enter, šī
ir pareizā versija.
Bet ja es palaistu echo $?
statuss, tas joprojām ir ievadīts ar 0.
Īsāk sakot, šī ir tikai palaist garām iespēja.
Ja kaut kas noiet greizi, kāpēc es neatgriežu vērtību, kas nav 0?
0 pēc noklusējuma nozīmē panākumus.
Un tas vienmēr ir automātiski.
Bet jūs varat to kontrolēt.
Šeit es varu ievadīt savu kodu un atgriezt 1, pretējā gadījumā, ja
kaut kas darbojas labi, pēc noklusējuma varu atgriezt 0.
Godīgi sakot, ja es izlaižu atgriešanās nulli, atkal automātiski tiek
atgriezta nulle.
Tāpēc ļaujiet man būt skaidram, lai es zinātu, kas notiek.
Atkal izveidojiet statusu, ./status, un darīsim to pareizi ar Deividu.
Ienāc, sveiks, Deivid.
Atbalss $?, nulle.
Tātad viss ir labi.
Bet tagad, ja es daru ./status un neko, vai vairākas lietas, bet ne
tikai Deivids, Enter, tiek parādīts kļūdas ziņojums.
Bet tagad, ja es atbalsoju $?, var, tagad ir viens.
Tātad, ko tas tagad nozīmē?
Tas ir, grafiskajā pasaulē mēs vienkārši parādītu kaut ko līdzīgu
ekrānā, kas ir nedaudz informatīvāks lietotājam.
Bet pat Linux pasaulē, kur jums nav GUI, noteikti, pat mūsu
rakstītajām programmām, varat pārbaudīt šos izejas statusus.
Un patiesībā ērtāki, progresīvāki programmētāji, rakstot kodu, kas
izsauc programmas, neatkarīgi no tā, vai tas ir cowsay vai jebkas
cits, jūs varat iekodēt, pārbaudīt, kāds ir programmas izejas
statuss, un pēc tam izlemt, vai mana programma darbojās vai darīja.
vai ne?
Un tagad savienosim pēdējos punktus, pirms pārtraucam augļu uzkodas.
Kriptogrāfija, proti, viena no šīs nedēļas lietojumprogrammām, ar
kuru jūs varēsiet nosūtīt slepenus ziņojumus, ja vēlaties, un, vēl
labāk, atšifrēt slepenās ziņas.
Tas būs papildus, iespējams, teksta lasāmības analīzei, izmantojot
heiristiku, kā mēs identificējām otrās klases sākumā.
Tātad kriptogrāfija ir tikai māksla, zinātne par informācijas
šifrēšanu, informācijas šifrēšanu, lai, ja jums ir slepens ziņojums,
kas jānosūta tā sauktajā vienkāršajā tekstā, jūs varat to palaist ar
kādu algoritmu un pārvērst to par tā saukto šifrētu tekstu, tādējādi
to šifrējot. .
Un tikai tas, kurš zina, kādu algoritmu esat izmantojis un kādu
ievadi esat izmantojis algoritmam, teorētiski var atšifrēt šo procesu
un pārvērst to atpakaļ sākotnējā ziņojumā.
Tātad, ja mēs izmantojam mūsu pagājušās nedēļas garīgo modeli, šeit
ir problēma.
Šeit ir ievade un izvade.
Mērķis, ko es šeit apgalvoju, ir paņemt vienkāršu tekstu, piemēram,
ziņu, kuru vēlaties nosūtīt, un padomāt par skolas gaitu, ja kādreiz
esat nodevis draugam vai savai simpātijai piezīmi, sakot: Es tevi
mīlu, ir nedaudz neērti, ja skolotājs vai kāds cits pārtver papīru.
Un angļu valodā tas vienkārši saka: I love you, vai kas tas ir.
Būtu jauki, ja jūs to vismaz kaut kādā veidā šifrētu.
Bet otrai personai ir jāzina, kādu algoritmu jūs izmantojāt un kādus
ievades datus izmantojat šim algoritmam, lai galu galā viņi varētu
atšifrēt tā saukto šifrēto tekstu, kas ir izvade.
Tātad, kas šodien atrodas kastē?
Algoritmu, kas attiecas uz kriptogrāfiju, sauc par šifru.
Un šifrs ir izdomāts nosaukums algoritmam, kas šifrē tekstu no
vienkārša teksta uz šifrētu tekstu.
Galvenais ir tas, ka ir jābūt ne tikai algoritmam, bet arī tam ir
jābūt ievadei.
Un tā, piemēram, jūs varētu šodien pirmo reizi uzzīmēt šādu attēlu.
Un mēs to esam redzējuši kodā.
Funkcijām varat dot vairākus ievades datus vai argumentus.
Tātad, vai varat iedomāties šajā melnajā kastē nosūtīt ziņojumu, kuru
vēlaties nosūtīt, un pēc tam kādu noslēpumu.
Piemēram, pieņemsim, ka visvienkāršākā lieta, ko es varētu iedomāties
bērnībā, bija tā vietā, lai nosūtītu burtu A. Kāpēc es nerakstu burtu
B?
Kāpēc es nerakstu C burta vietā?
Tāpēc es varu pārbīdīt angļu alfabētu par vienu atstarpi.
Tātad A kļūst par B, B kļūst par C, punkts, punkts, punkts, Z kļūst
par A.
Beigās varat aptīties.
Un pieņemsim, ka šajā stāsta daļā nav pieturzīmju.
Tātad tas ir ļoti vienkāršs algoritms — pievienojiet vērtību katram
burtam un nosūtiet vērtību kā šifrētu tekstu.
Un tagad skolotājam, klasesbiedram, viņiem ir jāzina, ka jūs
izmantojat, ne tikai šis rotācijas algoritms, kas pazīstams arī kā
Cēzara šifrs, bet arī jāzina, kādu numuru jūs izmantojat.
Vai katram burtam pievienojāt 1, katram burtam 2, katram burtam 25?
Tagad, ja viņi ir ļoti gudri un, iespējams, nav jauni šajā stāstā,
viņi varētu arī vienkārši izmēģināt visas iespējas.
Un tas būtu uzbrukums algoritmam.
Tas nav sarežģīts algoritms, taču ar to pietiek, lai stundā nosūtītu
ziņojumu.
Tātad, ja abas ievades tagad ir HI!
kā vienkāršu īsziņu un 1 kā tā saukto atslēgu — slepeno numuru, ko
zināt tikai jūs un otra persona, iespējams, varēsit šifrēt ziņojumu
no viena veida uz otru.
Un tā šajā gadījumā, piemēram, HI!
kļūtu par IJ-!.
Šajā algoritma versijā mēs neuztraucamies ar cipariem vai pieturzīmēm.
Mēs darbosimies tikai ar burtiem A līdz Z neatkarīgi no tā, vai tie
ir lielie vai mazie burti.
Tātad tagad, ja jūs stundā saņemtu lapiņu ar IJ, jūs, saņēmējs,
zinātu, kas tas ir, ja vien zinātu, ka sūtītājs to izmantoja, jo jūs
vienkārši apgriežat algoritmu un atņemat vienu. .
Skolotāj, viņi, iespējams, nezina, ko tas nozīmē, un viņi netērēs
laiku, lai uzlautu ziņojumu, tāpēc viņiem tas vienkārši šķiet
apmulsis.
Un tas ir tas, ko mēs iegūstam no šifrēšanas.
Kāds, kurš to pārtver klasē vai reālajā pasaulē, internetā vai jebkur
citur, ideālā gadījumā nevar saprast, ko jūs esat nosūtījis.
Pretējo, protams, patiešām sauc par atšifrēšanu, taču process ir tāds
pats.
Tagad mēs nododam negatīvā 1.
Un kā ar šo?
Kāpēc mēs šeit nepabeigsim ar demonstrāciju?
UIJT XBT DT50 — tur ir mazliet pastāstīts.
Ja mēs to nododam tālāk un izdarām negatīvu 1, tad kā mēs sākotnēji
izņemam vienkāršu tekstu?
Nu, ja tas ir šifrētais teksts un mēs no katra burta atņemam 1, es
domāju, ka U kļūst par T, es kļūst par H, J kļūst par I, T kļūst par
S, X kļūst par W, B kļūst par A, T kļūst par S, D kļūst par C, T
kļūst par S, un tas patiešām bija CS50.
Paņemiet pīli, dodoties ārā, un uzkodas vestibilā.
[APLAUSI]
[FILMAS RITOŠANA]
[MŪZIKA ATSKAŅOTĀS]