Neste del, vil nødvendigvis måtte gå litt mer inn i C-koding før vi hopper over på IB og Obj-C, rett og slett fordi man trenger å forstå noen konsepter som er felles for begge programmeringsspråk, før man kan få noe særlig ut av Obj-C og IB. Siden jeg ennå ikke har fått satt av tid til å filme og ta screenshots til del 2, så poster jeg en "liten" smakebit på de grunnleggende C-tingene vi kommer til å gå gjennom i neste del nå, med forbehold om at disse blir revidert før Del 2 kommer.
Og ja, Del 2 blir ca dobbelt så lang som det jeg har skrevet her, hvor vi da først skal lage et helt enkelt GUI-program i IB, og demonstrere dette, noe som vil gi masse bilder, og forhåpentligvis noe videodemonstrasjon.
Men siden teoribiten er litt tyngre å fordøye, poster jeg utkastet mitt i tråden her, så dere kan få litt tid til å fordøye det til dere trenger det, og jeg da kanskje kan få noe feedback på uklarheter før den offisielle versjonen blir postet. Det KAN også hende at noe materiale herifra blir forskjøvet til Del 3.
prøvesmak på Del 2:
Mer CVariablerVi har allerede lært hva variabler er; merkelapper eller bokser, som kan holde en verdi, som vi senere kan bruke, og endre. Vi kjenner kanskje disse fra matematikkens algebra, men algebraens variabler skiller seg litt fra våre, der gir nemlig ikke X = X + Y mening med mindre Y er 0, mens her betyr uttrykket at X sin neste verdi skal være det X var + Y. Det er greit å vite at en variabel kan ha et vilkårlig navn, så lenge dette ikke starter med et tall, eller har mellomrom i seg, variabler bør ikke starte med _.
DatatyperDet vi ikke gikk gjennom, var "int" biten foran variablen, denne står for "integer" og betyr at variablen kan inneholde positive og negative helltallsverdier. Det jeg ikke forklarte, er at vi har andre datatyper vi kan velge å bruke, de to mest interessante av disse, er
float og
bool.
float står for floating point, og kan inneholde desimalverdier, som 3,14, her er det viktig å merke seg at presisjonen på desimalene ikke nødvendigvis er perfekt ned til minste desimal, så å sjekke likhet mellom to floats, kan fort by på problemer, sjekk heller hvor stort avviket mellom dem er (x-y istedenfor x==y).
bool står for boolean, og kan inneholde to verdier, sann, og usann, eller true og false, denne kan dermed brukes som "bryter" for å slå av og på funksjonalitet, tenk f.eks. "bool playMusic=false", hvor man da kan sjekke playMusic hver gang man skal justere musikken i et program, og dermed oppfatte at man ikke trenger å gjøre noe som helst, da programmet ikke vil ha lyd.
I tillegg har vi varianter av disse, som er større enn int og float, nemlig long og double, som vanligvis kan romme dobbelt så store verdier. Long er den større utgaven av int, og double er den større utgaven av float. Disse trenger du stort sett ikke bruke, med mindre du skal jobbe med veldig store verdier, eller trenger høy presisjon på desimaltallene dine.
CastingEr et tricky konsept, så først må vi forklare "hvorfor", før vi forklarer "hva", i C er det slik at datatyper ikke bør blandes, (selv om de til en viss grad kan det), de forskjellige datatypene håndterer nemlig enkelte ting litt forskjellig.
Kanskje det beste eksempelet er deling med integers, siden integers er heltall, vil resultatet også måtte bli et heltall, og datamaskinen har ikke fått beskjed om å bry seg med detaljer som avrunding, så 5/2 = 2, og ikke 3. Bruker man derimot flyttall, så vil man ende opp med 2,5.
Gitt at vi da har en rekke heltall, som vi vil dele, og vi er interessert i å få resultatet med desimaldel, hvordan kan vi få C til å behandle heltallene våre som desimaltall? Jo, det er her casting kommer inn i bildet.
Casting, er enkelt å greit det å be C behandle en variabel som om den hadde en annen datatype enn det den har, castingen gjelder bare i det uttrykket man bruker den, og variabelen vil altså ikke skifte type permanent.
casting ser slikt ut (datatype) variabel.
Eksempel:
- Kode: Merk alt
int x=5;
int y=2;
int testint = x/y;
printf("%d/%d=%d\n",x,y,testint);
float testflyt = x/y;
printf("%d/%d=%f\n",x,y,testflyt);
float testcast = (float)x/(float)y;
printf("%d/%d=%f\n",x,y,testcast);
Når du kjører dette programmet, vil du se at de to første resultatene er 2 og 2,0, mens det siste er 2,5, dette fordi vi der ikke lenger bruker heltallsdivisjon, men flyttalsdivisjon, som håndterer desimalresten. Som en liten ekstrainformasjon, kan jeg nevne at du strengt tatt ikke trenger å caste begge sidene av deletegnet, siden C automatisk bruker flyttalsdivisjon hvis en av leddene i uttrykket er flyttall (men vær obs på sammensatte uttrykk som (x+y/z*(w/k)), hvor det kan være litt uklart om et "ledd" i utregningen har minst ett flyttalsuttrykk.
Vi har forøvrig også en operator dere kanskje ikke har sett så mye til tidligere, i tillegg til +,-,*,/, nemlig %, modulo-operatoren. Denne er nært beslektet med deling, og gir deg heltallsresten av delingen, altså, for 5/2, vil vi ha at heltallsdelingen gir 2, vi ganger tilbake, og ser at 2*2 = 4, og at vi dermed har en rest på 1, 5%2 er derfor 1. Dette trenger du ikke å tenke så nøye på akkurat nå, vi kommer til å komme tilbake til dette, da det kan være en veldig nyttig operator i enkelte sammenhenger.
Funksjoner Hva om du har laget deg en nyttig løsning på noe, som du kunne tenke deg å bruke om igjen, uten å måtte kopiere den inn overalt? Vel, det er her funksjoner kommer inn, en nyttig analogi er matematiske funksjoner som sin(x), log(x) osv. Som du kanskje har gjettet, er printf() en slik funksjon, denne følger med C, og er således ikke noe vi trenger å lage, men hva om vi vil lage oss en snarvei for å skrive "Tallet er %d", vel, det er rimelig enkelt, følgende kode må da skrives foran linja som begynner med
int main i fila di:
- Kode: Merk alt
void skrivTall(int x)
{
printf("Tallet er %d\n",x);
}
Nå kan du skrive skrivTall(x) (eller for den del y, x-en i skrivTall er en annen x enn den du evt har i main, dette kommer av noe som kalles scope, som vi kommer tilbake til om litt.)
Men, hva om du vil forenkle uttrykk med funksjoner? Det går selvfølgelig ann, funksjoner kan "returnere" et resultat, f.eks. slik:
- Kode: Merk alt
int rektangelAreal(int hoyde, int bredde)
{
return hoyde * bredde;
}
da kan du bruke linjer som følgende i main:
int z = rektangelAreal(x,y);
eller
printf("Arealet av et rektangel %d",rektangelAreal(2,2));
Funksjoner kan også bruke andre funksjoner inni seg, (eller for den del, seg selv, noe som kalles rekursjon, men det kommer vi ikke til å se noe på ennå), da må funksjonen man bruker være skrevet over den funksjonen man skal bruke den i. (Derfor skriver vi alle funksjonene våre over main i grunnlaget).
ScopeScope er en tricky liten sak, som sier noe om "levetiden" til variablene våre, kort fortalt betyr det at en variabel du har laget, bare eksisterer fra forrige {-krøllparentes, til den matchende }-krøllparentesen, finnes det flere nivåer med parenteser, vil den også eksistere inni disse:
- Kode: Merk alt
{
int x = 2
if(x==2)
{
// X finnes her.
}
// X finnes fortsatt her.
} // X forsvinner her.
Det er derfor skrivTall over, har en annen X-variabel, enn den vi sender inn når vi bruker X i main, dette er kanskje litt forvirrende, men det som skjer når vi bruker "skrivTall(2)", er f.eks. at x i skrivTall settes til å være 2, skriver vi "skrivTall(x)", vil x i skrivTall være hva nå enn x-en i main var da vi kalte den. (Men, når funksjonen er ferdig, vil ikke x-en DER eksistere lenger).
Betingelser Vi har lært om if, såvidt i Del 1, jeg forklarte derimot ikke hvorfor det heter X==Y og ikke X=Y. Grunnen til dette er ganske enkelt at det første er en sammenligning, mens det andre er en tilordning, siden resultatet av X=Y, er at X blir lik Y, vil dette alltid medføre likhet mellom X og Y, og dermed gi oss en verdiløs betingelses-test (som dessverre fungerer uten å gi feil, så vær OBS på dette).
Prøv følgende, og se hva som skjer.
- Kode: Merk alt
int x=2;
int y=3;
if(x==y)
{
printf("De er like: X:%d Y:%d\n",x,y);
}
printf("X:%d Y:%d\n",x,y);
if(x=y)
{
printf("De er like: X:%d Y:%d\n",x,y);
}
printf("X:%d Y:%d\n",x,y);
LøkkerJeg fortalte om while i del 1, som er en helt enkel løkke-variant av if, det jeg ikke fortalte om, var
do-while, og
for.
While, vil alltid sjekke om betingelsen er sann før den gjør noe som helst, med andre ord gjør den "sjekk, så kjør", do-while, er en variant som gjør det motsatte, den vil alltid kjøre en gang, og sjekke etterpå, denne skrives på formen
- Kode: Merk alt
do
{
// something
}while(betingelse);
Til slutt har vi for-løkker, som er beregnet på å kjøres n-antall ganger, disse har en litt spesiell start:
- Kode: Merk alt
int i;
for(i=0;i<10;i++)
{
printf("I=%d",i);
}
Dette ser helt sikkert ut som svart magi, men det er egentlig ganske enkelt:
- Kode: Merk alt
for( sett initialverdi ; betingelse ; endring)
Vi setter utgangspunktet til å være at i er 0, betingelsen til at vi kjører så lenge i er mindre enn 10, og endringen til å være "øk i med 1". Det er på sin plass å nevne ++, i++ er kortform for "i = i + 1", for ordens skyld finnes det også en ++i, men denne er sjeldnere, og fungerer på en litt annen måte, som vi ikke ennå trenger å forklare helt.
Her kan vi forøvrig demonstrere modulo-operatoren(%) i full vigør:
- Kode: Merk alt
int i;
for(int i=0;i<25;i++)
{
printf("Tall: %d Rest ved 5-deling: %d\n",i,i%5);
}
Legg merke til at vi dermed teller til 5, 5 ganger, dvs nesten, vi teller fra 0 til 4, 5 ganger, dette kan være nyttig hvis vi f.eks. skal behandle tabeller med n-rader, og m kolonner. Men intill videre tar jeg det bare med så dere har sett at den finnes.
SmåtingSom du kanskje har lagt merke til, slutter ALLE linjer med semikolon i C, dette er viktig, og skulle du glemme disse, kan du få mange mystiske feil, siden linjeslutt markeres med semikolon, har du også muligheten til å bryte opp linjene dine som du vil, da C bryr seg relativt lite om enter-tasten, f.eks:
- Kode: Merk alt
printf(
"%d",
2
);
er lov, selv om det er ganske stygt, dette er i all hovedsak en detalj som blir viktigere når vi kommer til Objective-C.
Ellers har du kanskje lagt merke til at jeg har brukt // noen steder, dette er linjekommentarer, som forteller C at det som står bak disse skal ignoreres, dermed kan du skrive forklarende tekst der. En annen variant, er løpende kommentarer, som starter med /* , og ber C ignorere alt frem til du skriver */.
Så, til slutt, indentering, for å kunne gjøre koden din leselig, er det viktig at du bruker saklig indentering, indentering betyr innrykk, og gjøres fortrinnsvis med tab-tasten. En generell grunnregel er at innrykket skal øke med 1 hver gang du skriver {, og synke med èn hver gang du skriver }
- Kode: Merk alt
{
{
{
}
}
}
Der, da kan vi det mest grunnleggende i C, og har de fleste byggeklossene vi trenger for å lære oss det vi er ute etter, nemlig Objective-C.