[MŪZIKA SKAN]
DAGS LOIDS: Labi.
Dīvaina tēma, vai ne?
Maģiskie skaitļi.
Ko viņš domā, runājot par maģiskajiem skaitļiem?
Dažās programmās, kuras līdz šim esam rakstījuši CS50 valodā, ir
bijuši dīvaini skaitļi.
Varbūt tādu iemeslu dēļ, kurus mēs šobrīd līdz galam neizprotam.
Piemēram, Mario uzdevumā mēs ierobežojām piramīdas augstumu ar 23.
Mēs skaidri pateicām, ka nevar pārsniegt 23.
Bet ko nozīmē 23?
Ja jūs uzmanīgi izlasījāt specifikācijas, iespējams, esat pamanījuši,
ka iemesls, kāpēc mēs ierobežojām to ar 23, ir tāpēc, ka termināļa
loga standarta augstums ir 24.
Un tāpēc, ja piramīdai jābūt garākai par šo, tā var radīt šo dīvaino
parādību, kad tā nokrīt no ekrāna.
Un jūs zināt, ko tas nozīmē kontekstā, vai ne?
Vai 23 nozīme uzreiz ir acīmredzama kādam, kurš skatās uz jūsu
programmu, un varbūt viņam ir cita izmēra termināļa logs?
Visticamāk, ka ne.
Tas izskatās ok., labi.
Nu, kāpēc tad tikai tas ir mazāks par 23?
Kopumā rakstīt konstantes savā kodā ir slikts ieradums.
Tā darot, kad jūs faktiski savā kodā ierakstāt konstanti, to dažreiz
sauc par maģisko skaitļu izmantošanu, no kā mēs parasti vēlamies
izvairīties.
Piemēram, apskatīsim šeit šo vienkāršo funkciju.
Acīmredzot C valodā nav datu tipa, ko sauc par kārti vai kavu
Tāpēc vienkārši pacietieties ar mani.
Šeit mazliet ir iejaukts pseidokods.
Šī ir funkcija, ko sauc par deal card . Tā šķietami izmanto kavu kā
parametru un izvada man vienu karti.
Un es šeit daru kaut ko tādu, kur man ir cilpa, kas iet no 0 līdz 52,
un es izdalu kārti.
Nu, mums šeit ir maģiskais skaitlis, pareizi.
Vai redzat, kas ir maģiskais skaitlis?
Vai vēl svarīgāk: vai jūs redzat, kur ir problēma?
It īpaši, ja šī ir vienīgā datnes funkcija mapē, kurā ir virkne
dažādu datņu, katra no kurām veic savu darbību kāršu komplektā.
Varbūt tā tās sajauc vai izdala piecas kārtis, nevis vienu kārti.
Vai redzat, kāda šeit varētu būt problēma?
Vai redzat maģisko skaitli, ko esmu ievadījis kodā?
Tas ir 52, pareizi.
Tāpat kā intuitīvi jūs droši vien zināt, labi.
Ka standarta kāršu komplektā ir 52 kārtis.
Bet mūsu programmā tas vienkārši tur peld.
It kā pēkšņi tur ir 52.
Viens veids, kā atrisināt šo problēmu - ir to darīt.
Mēs ļoti skaidri tagad sakām, ka kāršu komplektā ir 52 kārtis.
Tas piešķir tam nedaudz intuitīvāku nozīmi, kad for cilpā vēlāk mēs
sakām: i ir mazāks par kavas izmēru.
Tas vienkārši šķiet labāk nekā teikt 52.
Tagad tas faktiski atrisina problēmu.
Konstantei tas piešķir simbolisku nozīmi.
Bet tas faktiski rada citu problēmu, kas var nebūt uzreiz pamanāma.
Pat ja šis mainīgais ir deklarēts globāli. Vai atceraties, ko tas
nozīmē, ja mēs deklarējam mainīgo globāli pret lokāli?
Pat ja mēs deklarējam mainīgo globāli, kā būtu, ja mūsu funkciju
komplektā ir cita funkcija, kas nodarbojas ar manipulācijām ar
kārtīm? Kas netīšām maina kavas izmēru vai palielina to par 1 vai
samazina par 1?
Tas varētu radīt problēmas, vai ne?
It īpaši, ja mums ir darīšana ar kāršu komplektu, kurā ir jāsajauc
visa kava.
Ja kavas izmērs tiek samazināts par 1, piemēram, līdz 51, mēs,
iespējams, nesajaucam visas kārtis.
Mēs atstājam vienu no tām ārpusē.
Un šo vērtību varbūt varētu paredzēt vai izmantot slikts aktors.
C valoda nodrošina tā saukto priekšprocesora direktīvu, ko simbolisku
konstantu izveidošanā sauc arī par makro.
Un patiesībā jūs jau esat redzējuši priekšprocesora direktīvu, pat ja
neesat dzirdējuši to saucam ar #include.
Tas ir vēl viens makro vai priekšprocesora direktīvas piemērs.
Veids, kā izveidot simboliskas konstantes vai piešķirt konstantei
nosaukumu, lai tai būtu lielāka nozīme, ir šāds:
#define, name, replacement.
Tiešām svarīgs komentārs ļoti ātri.
#defines beigās nelieciet semikolu.
Tātad tas ir #define, name, replacement.
Kad jūsu programma ir kompilēta, tas, kas patiesībā notiek, ir
sekojošs: kompilators if iet cauri jūsu kodam un aizstāj katru vārda
name gadījumu ar to, ko ievietojat kā replacement.
Līdzīgi, ja #include ir līdzīga kopēšanai un ielīmēšanai, tad #define
ir līdzīga meklēšanai un aizstāšanai, ja, piemēram, kādreiz esat
izmantojis šo līdzekli tekstapstrādes programmā.
Piemēram, ja es #define pi kā 3.14159265, ja jums ir labamatemātiskā
nosliece un pēkšņi savā kodā redzat lidojam 3.14159265, jūs droši
vien zināt, ka runa iet par pi.
Bet varbūt mēs tam varam piešķirt mazliet simboliskāku nozīmi.
Tā vietā mēs varam teikt #define pi kā skaitļu gabalu, ko es netaisos
lasīt atkal un atkal.
Un tas, kas notiks pēc tam - kompilēšanas laikā, tad, kad programma
tiks kompilēta: pirmā lieta, kas notiks, ir tas, ka katru reizi ejot
cauri un redzot lielo P, lielo I burtu, tā tos aizstās, tā burtiski
aizstās tos ar 3.14 un tā tālāk.Tā, lai jums tie nebūtu jāievada
katru reizi, jo programmai ir funkcionalitāte, ko jūs sagaidāt, kamēr
jūs strādājat ar manipulācijām, reizināšanu, dalīšanu, jebko kas ir
ar pi.
Jūs neaprobežojaties tikai ar šo skaitļu aizstāšanu.
Piemēram, es varētu #define KURSU kā VIRKNI CS50.
Šajā gadījumā, kad programma ir kompilēta, #define izies cauri kodam,
katru reizi, redzot KURSU,tas aizstās to ar VIRKNI CS50.
Šeit jūs arī pamanīsiet, ka es bieži #define visas savas definētās
simboliskās konstantes, tā sakot, vienmēr ar lielajiem burtiem.
Tā ir konvencija.
Tas nav obligāti.
Iemesls, kāpēc cilvēki, #definējot, parasti izmantos lielos burtus,
ir tikai tāpēc, lai būtu tiešām skaidrs, ka šis konkrētais mana koda
elements ir definētā konstante.
Ja tas bija ar mazajiem burtiem, iespējams, to var sajaukt ar mainīgo.
Un tas, iespējams, nav labi.
Tātad šis konkrētais risinājums ir daudz labāks, nekā jebkurš no
iepriekšējiem.
Ja es vispirms #define kavas izmēru 52, tad tagad mana 52 vai kavas
izmēra izmantošana šeit ir daudz intuitīvāka un daudz drošāka.
Jūs nevarat manipulēt ar konstanti.
Nevar teikt, ka 52 plus plus.
Tas nepārvērsīs to par 53.
Jūs nevarat mainīt 52 uz kaut ko.
Varat mainīt mainīgo, kura vērtība ir 52. Tas bija pirmais labojums,
kas mums bija iepriekš.
Un jūs varētu palielināt šo mainīgo līdz 53.
Bet jūs nevarat teikt, ka 52 plus plus, un tas pēkšņi pārvērš 52 par
53.
52 vienmēr ir 52.
Un tāpēc jūs nevarat nejauši mainīt kāršu kavas izmēru, manipulējot
ar to. Tomēr vēl viena laba blakusparādība ir tāda, ka jūs zināt, ka
ne visās pasaules valstīs tiek izmantots 52kāršu komplekts?
Piemēram, Vācijā patiešām ir ierasts izmantot 32 kāršu kavu, kurā
tiek noņemtas dažas no zemākas vērtības kārtīm.
Un šajā gadījumā es gribēju pārnest savu funkciju komplektu, kas
nodarbojas ar kāršu manipulācijām, uz Vāciju.
Pirmajā reizē, ko mēs parādījām, savā kodā es varētu ņemt un aizstāt
visus 52 gadījumus ar 32.
Bet šeit, ja es sava koda pašā augšdaļā #define kavas izmēru kā 32,
ja man tas ir jāmaina, tad es varu vienkārši ņemt un mainīt to.
Pārkompilēju manu kodu, un pēkšņi tas tiek pavairots.
Faktiski mēs varam mainīt kavas izmēru uz jebkuru vēlamo vērtību.
Vai varu jūs ieinteresēt ar kavas izmēra pick-up spēli?
Es esmu Dags Loids.
Un tas ir CS50.