Bruker:Ketil3/Programmering
Programmering er det å sette opp program over hvordan en oppgave skal utføres, vanligvis av en datamaskin. Denne teksten skal bli ei lærebok i programmering for nybegynnere. Språket som brukes er Visual Basic (kan bli utvidet).
En programmerer er en som driver programmering av maskinen, gjerne som yrke, men også som hobby. Jon Lech Johansen (født i 1983) var en som likte å programmere som liten. Da han var 17 år og selvlært programmerer, knekket han DVD-koden med ett av programmene sine og fikk tilnavnet DVD-Jon. De som lager nettleseren Opera jobber for Oslo-bedriften Opera Software og har programmering som yrke. De fleste har gått høyskole eller universitet, men en og annen selvlært finnes nok i næringslivet også.
Et program er en liste over hvordan oppgaven skal utføres, som rekkefølge og hva som skal være med. Det er en slags oppskrift, og på fagspråket kalles det gjerne for en algoritme. For at den skal kunne brukes, må den skrives på en spesiell måte (et språk) som forstås av den som skal gjøre arbeidet. For å få en italiener til å lage norsk kjøttsuppe må italieneren få en oppskrift skrevet på ... italiensk. Og omvendt: For å programmere en nordmann til å lage pasta carbonara må italieneren formulere algoritmen (oppskriften) på ... norsk.
Mange har i dag hørt om Java fordi det brukes mye til programmering av PC, mobiltelefon og dataspill. Det må jo bety at PC og mobiltelefon forstår program skrevet i Java. Andre språk som brukes endel er C (som DVD-Jon brukte) og Visual Basic. For å lære programmering er det greit å bruke ett språk, her vil dette være Visual Basic. Senere kan man jo lære seg andre språk, og det går stort sett raskt å sette seg inn i. For eksempel kan en jo lære seg Java for å bli kjent med hvordan mobiltelefonene programmeres, eller hvordan avanserte algoritmer skal lages.
Innholdet i dette "kurset" vil være
- behandling og lagring (intern) av data
- variabler og tilordning,
- datatyper (tall, strenger, tabeller, hash, objekt), typekasting
- sammenligning av data, logiske uttrykk (enkel boolsk algebra) og valg,
- oppdeling av programmer (modularisering)
- gjentagelser (løkker),
- prosedyrer og funksjoner, overføring av parametre
- algoritmer
- sortering, fletting og søking
- rekursjon
- objekt-orientert programmering
- klasser og metoder
- arv, polymorfi
- kommunikasjon
- henting av data (fra brukere, filer og eksterne kilder)
- vising av data (i grafiske og tekstlige former)
- lagring av data på fil, database
Et program for å summere noen tall
[rediger]Vil man summere alle heltallene fra for eksempel 14 til 99 blir det litt jobb. Det vil ta tid, og mange (mennesker) vil gjøre feil og sikkert kontroll-regne et par ganger før de blir trygge på svaret.
Noen få tall
[rediger]Fra barneskolen vet vel alle summen av tallene fra 3 til 11 skrives slik: . Har man matte på videregående skole vet man kanskje at det kan skrives slik: I de fleste programmeringsspråk skrives summen som et uttrykk, akkurat som i matematikken:
3+4+5+6+7+8+9+10+11
Men, uansett hvordan summen uttrykkes (skrives), så må man også utføre utregningen. De fleste som gjør dette (i hodet eller med blyant og papir) må plusse to tall av gangen, omtrent slik:
- 3+4 (blir 7)
- 7+5 (blir 12)
- 12+6 (blir 18)
- 18+7 (blir 25)
- 25+8 (blir 33)
- 33+9 (blir 42)
- 42+10 (blir 52)
- 52+11 (blir 63)
Svaret fant man etter 8 steg. Skulle man lage et program for dette kunne det være
- legg sammen 3 og 4; det blir 7
- legg til 5; det blir 12
- legg til 6; det blir 18
- legg til 7; det blir 25
- legg til 8; det blir 33
- legg til 9; det blir 42
- legg til 10; det blir 52
- legg til 11; det blir 63
Det man har i hodet (for å gjøre dette) er en "huskeplass". Den husker delsummen underveis. U ten den ville dette blitt vanskelig (tror du ikke?). Denne plassen kan vi kalle "SUM" og da blir programmet:
- sett SUM til 3+4
- øk SUM med 5
- øk SUM med 6
- øk SUM med 7
- øk SUM med 8
- øk SUM med 9
- øk SUM med 10
- øk SUM med 11
Alle datamaskiner har minne der man kan huske ting, og de fleste språk lar en sette navn på plassene. For å legge en verdi i en plass må en gjøre en tilordning. Den skrives
<navn> = <uttrykk>
Et dataprogram med flere slike tilordninger blir utført sekvensielt, ovenfra og ned. Så, et program som summerer disse tallene er da:
sum = 3 + 4 sum = sum + 5 sum = sum + 6 sum = sum + 7 sum = sum + 8 sum = sum + 9 sum = sum + 10 sum = sum + 11
Her er "sum" et hjelpetall (et sted i maskinens minne, hukommelse). I tabellen under vises hvordan denne utvikles.
steg | kommando | innhold i "sum" |
---|---|---|
1 | sum = 3 + 4 | 7 |
2 | sum = sum + 5 | 12 |
3 | sum = sum + 6 | 18 |
4 | sum = sum + 7 | 25 |
5 | sum = sum + 8 | 33 |
6 | sum = sum + 9 | 42 |
7 | sum = sum + 10 | 52 |
8 | sum = sum + 11 | 63 |
Maskinen kan vanligvis bare regne med to tall av gangen. Så, også den må gjøre 8 steg. Men, programmet er litt langt (syns noen), så en kan skrive dette litt enklere på en linje:
sum = 3+4+5+6+7+8+9+10+11
Selv om det er en linje, må nok maskinen gjøre 8 steg likevel, fordi den kan bare summere to tall av gangen. Men det er altså lettere å skrive.
Summen av ganske mange tall
[rediger]Summen av alle heltall fra 1 til 199 kan skrives som et langt program med 198 korte linjer, eller som 1 veldig lang linje. Først det lange programmet med 198 korte linjer:
sum = 1 + 2 sum = sum + 3 sum = sum + 4 ... sum = sum + 198 sum = sum + 199
Så, det korte programmet med en (1) enkelt veldig lang linje:
sum = 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+ ... (puh) ... 33+34+35+36 ... (svette) ... + 198+199
I de fleste programmerings-språk kan dette skrives mye lettere som en gjentakelse omtrent slik:
sum = 0 for i = 1 to 199: sum = sum + i
Det man gjentar er
sum = sum + i
.
Ressursbruk
[rediger]For å lære å programmere må en vite hvordan maskinens ressurser vil bli brukt. Det er to viktige "ressurser". Man har minnet (for å lagre) og prosessor (for å utføre). På en PC eller en mobiltelefon måles disse i Byte og Hertz. En PC kan ha 6 GB minne og 4,5 Ghz prosessor, og mere er det ikke.
Over er "i" nok et slags hjelpetall som først er 1, så 2. Et slikt program er fint og kompakt, men trenger altså to hjelpere: "sum" og "i". Disse kalles variabler, fordi de varierer mens programmet blir utført. Mange synes at variabler er vanskelige å forstå, men de er plasser man kan "legge unna" tall mens man arbeider. En hukommelse. Alle som driver og regner må av og til huske ting til senere. Det kalles gjerne mellomlagring, og fordelen er at man slipper å regne alt ut om igjen. Ulempen er at det tar plass i maskinens minne. Men, en kan godt bruke to plasser for å slippe all regningen, så det er greit.
Prosessorbruk
[rediger]Dette var en sekvensiell algoritme som det tok 198 steg å utføre, uansett om det var skrevet langt, kort eller med en gjentakelse. Hvert steg tar tid å gjøre, og det er maskinens prosessor som gjør dette arbeidet. Det kan jo hende at noen kan regne dette ut på en raskere måte. Da har man en raskere algoritme. Tyskeren Carl Friedrich Gauss laget i sin tid en slik algoritme. Den sier at summen er 199 ganger 200 delt på to. Et dataprogram for dette er:
sum = 199 * 200 / 2
Dette programmet tar jo bare 2 steg å utføre (selv om det er skrevet på en linje). Da har man spart 196 steg (som kan brukes til noe annet). Det er vanskelig å lage lure program, og i dette "kurset" skal en mest lære det å skrive program for datamaskin. Det handler ikke om å lære hvordan man lager raske algoritmer (selv om det også er viktig).
Øvelser
[rediger]I følgende oppgaver må du også forklare hva du har tenkt, vise programmet og anslå ressursbehovet, altså hvor mye minneplasser og hvor mange steg som kreves.
Eksempel
[rediger]Oppgave (som lærer har laget): Lag et program som summerer alle hundretallene mellom 0 og 887. Svar (som eleven har gitt): Med "hundretall" forstår jeg tall som er delelig med 100. Mellom 0 og 887 finnes følgende "hundretall": 100, 200, 300, 400, 500, 600, 700 og 800. Disse kan summeres med dette programmet:
sum = 100 + 200 + 300 + 400 + 500 + 600 + 700 + 800 + 900
Dette krever en variabel som heter "sum" og tar 8 steg å utføre.
Oppgaver
[rediger]- Lag et program som summerer annethvert heltall fra 17 til 33
- Lag et program som summerer alle heltallene fra 345 til 1
- Lag et program som regner ut omkretsen av en sirkel med diameter 44,3
Skatteberegning
[rediger]Mange lærebøker i programmering har eksempler med skatt. Ikke diamanter og gull, men skatt som en må betale til staten og sånt.
Inntektsskatt
[rediger]Omtrent sånn vil gangen bli:
- finn ut inntekten
- finn ut skatteprosenten for denne inntekten
- regn ut skatten, den er inntekt ganger skatteprosent
For eksempel: Man har tjent en halv million og da skal prosenten være 27.5. Følgende program regner ut skatten i 1 steg og bruker en variabel:
skatt = 500000 * 0.275
Selv om resultatet over blir rett utregnet, synes mange erfarne programmerere at følgende program er litt bedre, fordi den uttrykker det man vil, altså semantikken:
inntekt = 500000 skatteprosent = 0.275 skatt = inntekt * skatteprosent
Det kan så være, men det bruker tre variabler og to steg.
Formueskatt
[rediger]Hvis en er i skatteklasse 1 og 2:
if formue > 700000 then formuesats = 0.007 else formuesats = 0.000 formueskatt = inntekt * formuesats
Regelverket er faktisk som følger:
Datatyper
[rediger]I minnet ligger bare 0 og 1. Akkurat hva disse brukes er opptil programmet, men det er vanligvis tall og tekst.
Elementære datatyper=
[rediger]I Visual Basic har man en del elementære datatyper:
Heltall
[rediger]- Byte: 1 Byte (8 bit), heltall fra 0 til 255
- SByte: 1 Byte (i bit), heltall fra -128 til +127
- Short: 2 Byte (16 bit), heltall mellom -32 768 og 32 767
- UShort: 2 Byte (16 bit), heltall mellom 0 og 65 535
- Integer: 4 Byte (32 bit), heltall mellom -2.1 til +2.1 milliarder
- UInteger: 4 Byte (32 bit), heltall mellom 0 og 4.2 milliarder
- Long: 8 Byte (64 bit), heltall mellom to meget store tall, -9.2 og +9.2 trilliarder
- ULong: 8 Byte (64 bit), heltall mellom 0 og 18.4 trilliarder
Desimaltall
[rediger]- Single: 4 Byte (32 bits), flyttall mellom plus/minus 3.4E38
- Double: 8 Byte (64 bits), flyttall mellom plus/minus 1.8E308
- Decimal: 16 Byte (128 bits), flyttall mellom plus/minus 7.9E28
Tekst og tegn
[rediger]- Char: 2 Byte (16 bit), tall fra 0 til 65 535. Brukes til å representere tegn (bokstaver, tall, andre tegn)
- String: variabel lengde, en rekke med tegn i Unicode format (ikke mer enn 2 billioner)
Annet
[rediger]- Boolean: To mulige verdier: True og False (sann eller usann)
- Date: 8 Byte (64 bits), alle datoene fra kl. 0 den 1.1. i år 1 (rett etter Jesu fødsel) til kl. 23.59.59 den 31.12. i år 9999 (en gang i fremtiden, ja)
Tilordning
[rediger]For å sette verdien i en variabel skriver en
<var> = <uttrykk>
Først må høyre side (uttrykk) regnes ut til et resultat. Så kan dette resultatet kopieres inn i variabelen var. Det kan være så enkelt som
skatt = 70000
Her blir tallet 70000 kopiert inn i variabel skatt Eller, litt mer innfløkt:
skatt = inntekt * 0.028
Her blir først variabel inntekt ganget med tallet 0.028, før resultatet blir kopiert inn i variabel skatt.
Aritmetikk
[rediger]Det fins to typer tall i Visual Basic: Heltall og desimaltall. Regning med tall kalles aritmetikk. Følgende fins i Visual Basic.
- addisjon: a+b
- subtraksjon: a-b
- pluttifikasjon: a*b (samme som ab a.b eller a×b)
- divisjon
- desimaltall: a/b (samme som a:b eller )
- heltall: a\b for heltallsdelen og "a Mod b" for restdelen
- potensiering: a^b (samme som
- negativisering (?): -a (samme som -1*a)
Typeblanding
[rediger]En aritmetisk operasjon har to operander og en operator. I a*b eller 3*4 er operatoren * (pluttifikasjon). Hvis operatorene er av ulik type (som heltall og desimaltall) må ett av de types om (typekastes) før operasjonen kan utføres.
For pluttifikasjon (operator *):
- 3*4 har to heltall og trenger ikke typekasting. Svaret blir heltall. Likens for 3.2*4.9 (svaret blir desimaltall)
- 3*4.1 derimot: Skal en regne 3.0*4.1 (svaret blir desimaltallet 12.3) eller avrunde 4.1 til 4 og regne ut 3*4 (svaret blir heltallet 12)? Ja, hva synes du?
Usikkerheten i resultatet skyldes at eventuelle desimaltall mister presisjon, fordi de må omtypes og derfor avrundes.
Anta at vi har "Dim d as Double" og "Dim h as Integer" (d er et desimaltall og h er heltall).
- d=3*4 betyr at resultatet SKAL bli et desimaltall. Operasjonen blir 3.0*4.0.
- d=3.1*4 ... her vil vel 4 omtypes til 4.0 før operasjonen 3.1*4.0 utføres.
- h=3*4 er greit. Ingen omtyping. Operasjonen blir 3*4
- h=3.4*4, her skal resultatet bli et heltall. To muligheter:
- omtype 4 til 4.0, utføre utregning av 3.4*4.0=13.2, omtype resultatet ETTERPÅ; h blir 13
- omtype 3.4 til 3 FØR utregning av 3*4=12; h blir 12
Hva synes du?
Divisjon av desimaltall (operator /):
- 35 / 4 er to heltall som hver for seg omtypes og det blir 35.0 / 4.0 = 8.75
- 35 / 4.1, her blir det 35.0 / 4.1 som er litt mindre enn 8.75
Deling av desimaltall går greit, fordi eventuelle heltall ikke mister presisjon hvis de omtypes. Hva med litt heltallsdivisjon (operatorene \ og Mod):
- 35 \ 4 gir 8 (antall hele er 8, og 35 Mod 4 gir 3, altså resten).
- 35.7 \ 4 gir ...? Her er 35.7 et desimaltall, egentlig et "fremmedelement". Hvis det avrundes blir det 36 \ 4 som er 9 (ikke 8 som over).
- 35 \ 4.2 gir ...? Her må vel 4.2 avrundes og en får 35 \ 8 = 4.
Her er operatoren en heltalls-operator og operandene MÅ være heltall. Eventuelle desimaltall må derfor omtypes og eventuelt avrundes.
Paranteser og rekkefølge
[rediger]Som sagt hundre ganger: Maskinen kan gjøre en operasjon samtidig, den har to operander og en operator, som i a+7. Anta at a er 3, b er 5 og c er 10.
Pluss og minus
[rediger]I et sammensatt uttrykk som a+b+4 gjøres først a+b (3+5 gir 8), så blir resultatet (8) påplusset 4 (svaret blir 12). I matematikken brukes paranteser for å si hva som skal "regnes sammen". En må FØRST regne ut parantesene. Dette lærer man i barneskolens syvende år (2011). Så, a+b+4 kan skrives som:
- (a+b)+4
- a+(b+4)
Svaret blir likt uansett hva hvilken parantes gjør først. Hva med a-b-4? Svaret skal bli 3-5-4=-6.
- (a-b)-4 er greit: Først a-b som er 3-5=-2. Deretter -2-4=-6. Rett.
- a-(b-4) er litt tricky:
- a-(b-4): Først: b-4 som er 5-4=-1. Deretter a- -1 som er 3- -1 som er 3+1=4. Feil.
- a+(-b-4): Først: -b-4 som er -5-4=-9. Deretter 3+ -9 = 3-9 = -6. Rett.
Hva med b-4+c:
- (b-4)+c: Først: b-4 er 5-4=1. Deretter 1+c er 1+10=11.
- b-(4+c): To snublete muligheter her:
- b-(4+c): Først: 4+c er 4+10=14. Deretter: b-14 er 5-14 = -11. Feil.
- b+(-4+c): Først: -4+c er -4+10=6. Deretter: b+6 er 5+6 = 11. Rett.
Gange og dele
[rediger]a*b*4 kan gjøres
- (a*b)*4, altså først a*b som er 3*5=15, deretter 15*4=60
- a*(b*4) altså først b*4 som er 5*4=20, deretter a*20 som er 3*20=60
Deling, da? a/b/4, altså 3/5/4? Anta at a, b og c er desimaltall (bruker operatoren /).
- (a/b)/4. Først a/b som er 3/5=0.8. Deretter 0.8/4=0.2.
- a/(b/4): Først b/4 som er 5/4=1.25. Deretter a/1.25 som er 3/1.25=2.4.
Vanskelig å si hva som er rett her. De fleste ville kanskje valgt den første som ga 0.2 fordi man jobber "fra venstre mot høyre", ledd for ledd (operasjon for operasjon). Det er absolutt vanligst at datamaskinen jobber fra venstre mot høyre.
Hva med b/4*c:
- (b/4)*c: Først b/4 som er 5/4=1.25. Deretter 1.25*10=12.5.
- b/(4*c): Først 4*c som er 4*10=40. Deretter b/40 som er 5/40=0.125.
Også her ville de fleste valgt den øverste, som jobber som en er vant, altså fra venstre mot høyre. Ville en hatt den nederste, følte en vel at en måtte puttet på paranteser. Oppgave: Hva med b*4/c?
Presedens
[rediger]Med presedens menes: Hva skjer først i store uttrykk? Reglene er ganske enkle.
- Viktigst er parantesene, innerste først!
- Nest viktigst er potensiering (operatoren ^)
- Tredje viktigst er gange og dele (operatorene * og /)
- Og minst viktig er pluss og minus (+ og -)
Anta at en vil ha regnet ut noe så meningsløst som:
som (a=3, b=5 og c=10) er:
I Visual Basic uttrykkes dette a*c-(b/4+2)^(a*b-12) som utføres i følgende rekkefølge:
- parantes (b/4+2)
- dele: b/4 er 5/4=1.25
- pluss: 1.25+2=3.25
- parantes (a*b-12)
- gange: a*b er 3*5=15
- subtraksjon: 15-12=3
- potensiering: 3.253 = 3.25*3.25*3.25 = 34.328125
- gange: a*c er 3*10=30
- subtraksjon: 30 - 34.328125 = -4.328125
Innerste paranteser først
[rediger]Et annet eksempel med nøstede paranteser er regnestykket:
som (a=3, b=5 og c=10)
Usikker på hva det representerer, men: I Visual Basic uttrykkes det: a+(b-3*(c/(a-4)) / (2*a))
- parantes (b-3*(c/(a-4)) / (2*a)) blir 8:
- parantes (c/(a-4)) blir -10:
- parantes (a-4) blir -1:
- addisjon: a-4 er 3-4=-1
- divisjon: c/-1 er 10/-1=-10
- parantes (a-4) blir -1:
- parantes (2*a) blir 6:
- ganging: 2*a er 2*3=6
- [ står igjen med b-3*-10/6 ]
- ganging: 3*-10=-30 [ står igjen med b- -30/6 ]
- deling: -30/6 = -5 [ står igjen med b- -5 ]
- plussing: b- -5 er 3- -5 = 3+5=8
- parantes (c/(a-4)) blir -10:
- plussing: a+8 er 3+8=11.
Svaret er 11. Håper det er rett.
Heltall
[rediger]I matematikken er heltallene "de som ikke har desimaler", altså 1, 2, 3 og oppover, men også 0, -1, -2 og nedover. Med en enkelt bit kan en representere to heltall; for eksempel kan 0 bety 14 og 1 bety 324. Med to bit kan man representere fire heltall, fordi det er fire ulike kombinasjoner: 00, 01, 10 og 11. Med 3, 4, 5, 6, 7 eller 8 bit er det 8, 16, 32, 64, 128 eller 256 ulike kombinasjoner. Med 1 Byte (altså 8 bit) er det vanlig å enten representere tallene fra 0 til 255 (såkalt unsigned), eller de fra -127 til +127 (signed, det vil si med fortegn. Med 2 Byte (16 bit) er det = 65 536 ulike kombinasjoner, så de kan representere tallene fra 0 til 65 535 (signed) eller fra -32 676 til +32 676 (signed, med fortegn). Med 4 Byte er det over 4.2 milliarder ulike kombinasjoner, som brukes (vanligvis) til å representere tallene fra -2.1 milliard til +2.1 milliard. Sånn der omkring.
I Visual Basic har man flere datatyper: Short er 8-bits heltall, Integer er 16-bits, mens Long er 32-bits. Vil man for eksempel sette av en plass til et heltall der det skal ligge en inntekt, kan en i VB skrive:
Dim inntekt as Integer
og
Sammensatte typer
[rediger]En sammensatt type består av enklere typer. Disse lages etter behov, og vil utvikle seg etter hvert som man forstår problemets datastruktur (mer om datastruktur etter hvert). En god datastruktur gir ofte mer lettleste program som er lettere å vedlikeholde.
Structure
[rediger]En structure kan inneholde hva som helst. Den har et navn og brukes som type der det trengs.
Struktur av enkle typer
[rediger]Adresser består av gate og sted, stort sett. Det er lurt å lage en adressetype når man har mange adresser i programmet. Derfor:
Structure adresse Dim gatenr as UShort Dim gatenavn as String Dim postnr as UShort Dim poststed as String End Structure
En kan nå lage variabler av type adresse.
Dim hjemmeadr as adresse Dim jobbadr as adresse Dim ferieadr as adresse
Og manipulere disse som man vil:
hjemmeadr.gatenr = 16 hjemmeadr.gatenavn = "Storgata" ferieadr.poststed = "Costa del Sol"
Oi, vi har jo hytta i Spania. Hvis man også vil ha nasjon med, er det enkelt å utvide strukturen:
Structure adresse Dim gatenr as UShort Dim gatenavn as String Dim postnr as UShort Dim poststed as String Dim land as String End Structure
Egne typer må ha et passende navn ("adresse") og må bestå av passende ting som har passende navn ("gatenr", "gatenavn"). Programmet som helhet blir lettere å lese fordi det har navn med mening og det er lettere å vedlikeholde.
Struktur med struktur
[rediger]En structure kan godt inneholde en annen structure. Adresser kan, om man vil deles opp som følger:
Structure postadresse Dim nr as UShort Dim navn as String End Structure Structure gateadresse Dim navn as String Dim nr as UShort End Structure Structure adresse Dim gate as gateadresse Dim sted as postadresse Dim land as String End Structure
Så kan man innvende at også et land har et nummer (nasjonskode) og et navn. Det er kanskje bedre å innføre "landadresse" og endre "adresse":
Structure landadresse Dim navn as String Dim kode as UShort End Structure Structure adresse Dim gate as gateadresse Dim sted as postadresse Dim land as landadresse End Structure
Det ser greit ut, men nå er det tre adressetyper (gate, sted, land) som egentlig er veldig like: De har et navn og et nummer/kode. Derfor kan man forenkle til
Structure deladresse Dim navn as String Dim nr as UShort End Structure Structure adresse Dim gate as deladresse Dim sted as deladresse Dim land as deladresse End Structure
Struktur med struktur med struktur
[rediger]Hvem trenger egentlig disse adressene? Jo, alle som ... har en adresse. Derfor tar vi "adresse" i bruk der det trengs, som i:
Structure person Dim navn as String Dim bopel as adresse End Structure Dim jeg as person Dim mamma as person
Dette gir en ganske fin datastruktur. Med "Dim" sier en hva noe skal VÆRE, det gir ER-relasjoner. Med "Structure" sier en hva noe skal INNEHOLDE, det gir HAR-relasjoner. Altså: Både jeg og mamma" ER en person. En person HAR navn (som ER en String) og bopel (som ER en adresse). En adresse HAR en gate, sted og et land. Hvert av disse tre ER deladresse. En deladresse HAR et nummer (som ER en UShort) og et navn (som ER en String).
Øvinger
[rediger]- Hvor stor plass tar mamma? Gi svaret i Byte og vis utregningen.
- Hvor stor plass tar jeg? Gi svaret i Byte, du skal ikke trenge regne dette ut hvis du svarte på forrige.
- Det viser seg at hvert land har en to-bokstavs nasjonskode, som "NO" for Norge og "US" for USA. Vis hvor du vil legge dette inn og forklar hvorfor.
- Svarforslag 1: En kan lage (gjeninnføre) strukturen "landadresse" som HAR adr (ER "deladresse") og HAR "nasjonskode" (String). Hvorfor? Fordi dette er den eneste som egentlig trenger en utvidelse.
- Svarforslag 2: En kan utvide "deladresse" slik at den også HAR kode (String). Hvorfor? Det kan jo tenkes at gateadresser og stedsadresser også har behov for slike koder.
Tabell
[rediger]En tabell (array på engelsk) kan lagre flere av samme sort. De egner seg for massebehandling.
1-dimensjonal
[rediger]Har man tre farger, kan man jo si
Dim farge1 as String = "gul" Dim farge2 as String = "rød" Dim farge3 as String = "blå"
men det er like greit å bli vant til å bruke tabell:
Dim farge(2) as String farge(0) = "gul" farge(1) = "rød" farge(2) = "blå"
Tabellen har tre plasser. Den første fargen har plass 0 og refereres ("indekseres") som farge(0). Den siste fargen er da farge(2).
Det er litt drøyt å snakke om massebehandling med bare tre plasser, men vil en for eksempel blanke alle fargene (nullstille de) brukes en løkke:
For i = 0 to 2 farge(i) = "" Next
Dette gjentas med "i" som plassnummer, gående fra 0 til og med 2. Fordi vi (den som programmerer) vet at dette er plassnumrene.
Nå kan faktisk en tabell lages med andre plassnummer og da må en justere yttergrensene:
Dim farge(13 to 15) as String farge(13) = "gul" farge(14) = "rød" farge(15) 0 "blå" ... For i = 13 to 15 farge(i) = "Ubestemt" Next
Vet en ikke yttergrensene kan en (med fordel) spørre tabellen om grensene i dimensjon null (0):
For i = farge.getlowerbound(0) to farge.getupperbound(0) farge(i) = "Ingenting" Next
Eller, man kan bruke "For Each", en litt annen gjentakelse:
For Each f as String in farge f = "Ingenting" Next
Den bruker ikke en "i" for å peke til plassen, men en "f" som er det som ligger på hver plass (en String).
Øvinger
[rediger]- Hvor mange plasser gir "Dim a(5)" og "Dim a(-3 to 7)"?
- Hva må "y" være for at "Dim a(1, <y>)" skal gi 11 plasser?
- Anta "Dim a(7) as Integer". Hva skjer hvis:
- For i = a.getupperbound(0) to a.getlowerbound(0) + 1 // a(i) = a(i-1) // Next
- For i = 0 to 5 // a(i+1) = a(i+1) + a(i) // Next
- For i = 0 to 6 // a(i) = i // Next
- For Each t in a // t = 2*t // Next
Vanlige gjøremål
[rediger]Telling
[rediger]Vil en telle antallet som passer med et gitt kriterium:
Dim antTreff as Integer = 0 For each e in a If "e passer med kriterium" Then antTreff += 1 End If Next
Leting
[rediger]Vil en finne høyeste:
høyest = typens "lavest mulige verdi" For Each e in a If e > høyest Then høyest = e End If Next
Vil en vil vite hvor i tabellen den høyeste ligger, er det
høyest = typens "lavest mulige verdi" For i = a.getlowerbound(0) to a.getupperbound(0) If a(i) > høyest Then høyest = a(i) høyestePos = i End If Next
Øving
[rediger]- Hva skjer hvis det fins flere med høyeste verdi?
- Skriv om slik at den istedet finner den laveste
Leting og telling
[rediger]Vil en telle hvor mange som har beste verdi:
best = typens "dårligste verdi" For Each e in a If e bedre enn best Then best = e antBest = 1 ElseIf e = best Then antBest += 1 End If Next
Kåring av de de to beste
[rediger]Vil en finne høyeste og nest høyeste verdi:
best = nestBest = dårligst mulig verdi (max. pessimisme) For Each e in a If e "er bedre enn" best Then nestBest = best best = e Else If e "er bedre enn" nestBest Then nestBest = e End If Next
Hva som er dårligst og best bestemmes av situasjonen.
- Å finne høyeste verdi betyr at "dårligst mulig verdi" er noe usannsynlig lavt (-1 trilliard?), og at "er bedre enn" er en ">", altså en "større-enn".
- Å finne laveste verdi snur alt om: "dårligste" er noe usannsynlig høyt og "bedre enn" er "mindre-enn".
Øvinger
[rediger]- Hva skjer hvis alle er like?
- Hva skjer hvis ingen er like?
Finne de tre beste
[rediger]best = nestBest = tredjeBest = typens "dårligste verdi" For Each e in a If e "er bedre enn" best Then tredjeBest = andreBest andreBest = best best = e Else If e "er bedre enn" nestBest Then tredjeBest = andreBest andreBest = e Else If e "er bedre enn" tredjeBest Then tredjeBest = e End If Next
Det som gjøres er å skyve ut den dårligste (tredje beste) til fordel for den nye beste Men, det må gjøres i rett rekkefølge. Så, vi forsøker å holde en liste på 3 elementer sortert (stigende eller synkende). Hvis listen blir lang (f.eks. de N=50 beste) blir programmet uhåndterlig. Det er allerede litt langt, vil de fleste programmerere nok mene.
Sortering ved innstikk
[rediger]Her vil ideen generalisere metoden til N. Vi trenger en liste med N. Kall den "de_beste". I starten er den tom. Etterhvert fylles den med elementer. Den skal holdes sortert.
For each e in a settInn (e, de_beste) Next program settInn (ny, liste) mål: elementet "ny" skal inn i "liste" på rett plass for hver E i liste hvis ny "er bedre enn" E sett ny inn foran E i liste fjern den siste i listen hvis den ikke får plass (den blir "skjøvet" ut) ferdig, avslutt søket; ny er nå "stukket inn" på rett plass kommer vi hit ble ikke ny satt inn i listen (ikke "bra" nok)
Metoden kalles innstikks-sortering fordi nye blir stukket inn på rett plass i listen. De som er "like gode" blir liggende etter hverandre i den rekkefølge de ble lagt inn.
En måte å skrive dette på i VB er (pseudokode) ved hjelp av en tabell (array).
Dim allerBeste (N-1) as <type> ' initielt: rang(i) = typens "dårligst mulige verdi" for alle i For each ny in a settInn (a, allerBeste) Next Sub settInn (ny, liste) Dim N as Integer = liste.getupperbound(0) For i = 0 to N - 1 If ny "bedre enn" liste(i) then ' operator er enten > eller < For i = N-2 to i step -1 ' gå baklengs liste(i) = liste(i-1) ' flytt verdi en "lenger ned" ("til høyre") Next liste(i) = ny End If Next End Sub
For å også telle antallet som har de ulike besteverdiene:
Structure deltaker Dim verdi as <type> Dim antall as Integer End Structure Dim rang(N-1) As deltaker rang(0) = typens "dårligst mulige verdi" For Each e in a For i = rang.getlowerbound(0) to rang.getupperbound(0) If e "er bedre enn" rang(i) Then For i = rang.getupperbound(0) to 1 step -1 rang(i) = rang(i-1) Next rang(0).verdi = e rang(0).antall = 1 ElseIf e "er like god som" rang(i) Then rang(i).antall += 1 EndIf Next Next
Endring av størrelse
[rediger]Vil en endre størrelsen skrives
ReDim [ preserve ] <tabellnavn> ( <rad> )
En tar med "preserve" hvis innholdet i hver plass skal beholdes.
Øvinger
[rediger]Anta at en har "Dim a(7) as Integer" også her og at innholdet er { 1, 2, 1, 0, 7, -1, 9 }.
2-dimensjonal
[rediger]Mangt i verden har to dimensjoner, kanskje fordi det passer best på papir der vi har skrevet ned tabellene i århundrer? En 2D tabell kan man tenke seg har R rader og K kolonner. En "liga" med 5 lag med 11 spillere kan lagres:
Dim alleLag(4,11) as String
(4,11) er størrelsen (rad, kolonne). Med 4 blir det 5 rader (0 til 4). Med 11 blir det 12 kolonner (0 til 11).
Kolonne 0 er lagets navn. Kolonne 1-11 gir plass til 11 spillere.
Unnlater en størrelsen gjøres det slik:
Dim alleLag(,) as String
Vil en endre plassen:
ReDim [ preserve ] <tabellnavn> ( <rad>, <kol> )
Men "preserve" går kun hvis det er "rad" som endres.
3-dimensjonal
[rediger]Den geografiske verden er 3-D. En posisjon er (x,y,z) der (x,y) er posisjon på landjorda og z er hvor høyt vi måtte befinne oss (over landjorda, men egentlig: Over havet). 3D-spill bruker ofte 3-dimensjonale tabeller for å representere 3D-objekter. Det blir for vanskelig i dette "kurset", men nevnes likevel.
Collection
[rediger]I stedet for en tabell (array) kan man lagre ting i en Collection som lar en tillegge og fjerne elementer uten å vite akkurat hvor dette blir liggende. Sentrale metoder er: c.Add(), c.Delete(), c.Count() og c.Clear().