• No results found

if (x>0)

disp(’x ¨ar st¨orre ¨an noll’) elseif(x<0)

disp(’x ¨ar mindre ¨an noll’) else

disp(’x ¨ar lika med noll’) end

Man kan ocks˚a kombinera ihop tv˚a tester med hj¨alp av logiska operatorer, som kan skrivas p˚a tv˚a s¨att, operator eller funktion:

operator funktion logikfunktion

& and(A,B) och a & b ¨ar sann om b˚ade a och b ¨ar sanna

| or(A,B) eller a|b ¨ar sann om minst en av a och b ¨ar sann

∼ not(A) icke d = ∼a: d ¨ar sann om a ¨ar falsk och omv¨ant.

xor(A,B) exklusiv eller a xor b ¨ar sann om exakt en av a och b ¨ar sann Ett exempel p˚a en s˚adan kombinerad test ¨ar if ((a < b) & (b<c)) som allts˚a ¨ar sann om a < b < c. Om vi anv¨ander oss av funktionsformen kan vi skriva samma test if (and(a<b,b<c)). Den viktigaste orsaken till att funktionsformen finns ¨ar att den g¨or det l¨attare att definiera en boolsk variabel, vi kan t.ex. skriva C=and(a<b, b<c) d¨ar C ¨ar en variabel som har v¨ardet true om villkoret a < b < c ¨ar uppfyllt och v¨ardet false om det inte ¨ar sant.

6.3 Slingor

En mycket viktig komponent i datorprogram ¨ar slingor, d¨ar monotona repetitiva moment upprepas p˚a ett automatiskt s¨att. Tag som exempel serieutvecklingen av cosinus-funktionen:

cos(x) =

X

i=0

(−1)i x2i

(2i)! = 1 −x2 2! +x4

4! −x6 6! . . .

Skall vi f¨or hand g¨ora denna utr¨akning p˚a en minir¨aknare m˚aste vi r¨akna ut varje term f¨or sig och sedan summera alla termer i ett register. Men allt som kan skrivas som en summa p˚a ett s˚a regelbundet s¨att som den h¨ar formeln kan ocks˚a kodas p˚a ett enkelt s¨att i datorprogram genom att anv¨anda s˚a kallade slingor (engelska loop). Det finns tv˚a typer av slingor i Octave:

for-slingor och while-slingor.

6.3.1 for-slingor For-slingor har formen

for index=start:stop ....

....

end

Namnet p˚a den variabel som man anv¨ander som loop-index, i exemplet ovan index ¨ar godtyckligt. Dock b¨or man kanske undvika att anv¨anda i eftersom det ¨ar namnet p˚a en inbyggd funktion. Koden mellan f¨orsta och sista raden utf¨ors en g˚ang f¨or varje v¨arde p˚a

52 KAPITEL 6. PROGRAMMERING index som anges i f¨orsta raden. Ett mycket enkelt exempel som visar principen ¨ar f¨oljande lilla loop, som l¨oser ¨ovningsuppgift 6 i kapitel 2 p˚a ett kompakt s¨att:

for index=1:5 disp(index) pause(3) end

En utr¨akning av de f¨orsta tio termerna i serieutvecklingen av cosinus kan skrivas som:

x=pi/4;

cosinus=0;

for index=0:9

cosinus = cosinus + (-1)∧index * x∧(2*index) / prod(1:2*index);

end

(F¨or att ber¨akna fakulteten anv¨ander vi funktionen prod(x) som ber¨aknar produkten av alla element i en vektor x. Som ett specialfall g¨aller prod(1:0)=1).

H¨ar ser vi det f¨orsta exemplet p˚a en litet speciell typ av algebra som ¨ar vanligt just n¨ar man programmerar, samma variabel kan f¨orekomma i b˚ade h¨oger- och v¨ansterled i en tilldel-ningssats. Vill vi skriva en kodrad som adderar 4 till den variabel som vi kallar X kan vi g¨ora det genom att helt enkelt skriva X = X + 4. Om X har v¨ardet 2 innan den h¨ar raden utf¨ors s˚a har den v¨ardet 6 efter att raden utf¨orts. Den h¨ar konstruktionen anv¨ands mycket ofta, inte minst i slingor d¨ar man summerar ett antal termer som i exemplet ovan.

Att det h¨ar ¨ar ett fantastiskt ekonomiskt s¨att att koda framg˚ar av att det enda vi beh¨over g¨ora om vi vill tiofaldiga antalet termer i summan ¨ar att ¨andra index=0:9 till index=0:99. Vari-abeln i slingan, i det h¨ar fallet ”index”, beh¨over inte delta i de matematiska operationerna, man kan till exempel r¨akna till tio genom att anv¨anda slingan

summa = 0;

for index=1:10

summa = summa + 1;

end

En annan sak vi noterar ¨ar att variabeln inte beh¨over r¨aknas upp med ett f¨or varje varv i slingan, index=0:2:10 ¨ar en legitim konstruktion. Vi beh¨over inte ens anv¨anda heltal, index=0.2:0.1:0.7 ¨ar ocks˚a en m¨ojlig sling-konstruktion.

6.3.2 while-slingor While slingor har formen

while (test) ....

....

end

D¨ar test ¨ar n˚agot villkor som kan utv¨arderas, som till exempel index<4, sqrt(x)>sin(x) osv.

Koden i en while-slinga utf¨ors s˚a l¨ange villkoret i test ¨ar sant. Det h¨ar betyder f¨or det f¨orsta att vi m˚aste initialisera de variabler som ing˚ar i testen innan while-slingan startar, och f¨or det andra att det ¨ar v˚art eget ansvar att de variabler som ing˚ar i testen f¨or¨andras inuti den

6.3. SLINGOR 53 kod som utf¨ors mellan while och end. Tag till exempel slingan

clear all;

x=2;

sum=0 while (x<4)

sum=sum+1;

end

Denna slinga kommer aldrig att ta slut! Eftersom x ¨ar mindre ¨an fyra n¨ar slingan b¨orjar s˚a g˚ar vi in i slingan. Men eftersom x inte ¨andras inuti slingan kommer villkoret alltid att vara uppfyllt s˚a slingan kommer bara att forts¨atta i all o¨andlighet. Vi m˚aste allts˚a t¨anka oss f¨or n¨ar vi anv¨ander while-slingor s˚a vi inte f˚ar programmet att h¨anga. (Skulle du n˚agon g˚ang beh¨ova avbryta Octave i en ber¨akning som sp˚arat ut, t ex genom att fastna i en o¨andlig loop s˚a g¨or man det genom att g˚a till kommandof¨onstret och d¨ar trycka p˚a ctrl-c, dvs control och c samtidigt. Programmet avbryter d˚a vad det h˚aller p˚a med och l¨amnar tillbaka kontrollen till kommandof¨onstret). While-slingor ¨ar anv¨andbara i situationer d¨ar vi inte i f¨orv¨ag kan f¨oruts¨aga hur m˚anga varv vi m˚aste l¨opa igenom en slinga. En sak som g¨or while-slingor s˚a anv¨andbara ¨ar att villkoret inte beh¨over vara ett villkor p˚a en enstaka variabel, utan kan vara mer komplext. Antag till exempel att vi vill unders¨oka hur m˚anga termer vi m˚asta ta med i summan ovan f¨or cosinus innan skillnaden mellan summan och det verkliga v¨ardet ¨ar mindre ¨an n˚agot givet v¨arde epsilon. Detta kan vi koda p˚a f¨oljande s¨att:

x= pi/4; epsilon=1*10∧-6;

cosinus=0;

index=0;

while (abs(cos(x)-cosinus) > epsilon)

cosinus = cosinus + (-1)∧index * x∧(2*index) / prod(1:2*index);

index=index+1;

end

out= ’Serien konvergerade efter’;

disp(out); index disp(’ termer’)

6.3.3 Att hoppa ut ur en slinga - kommandot break

Ibland vill man hoppa ur en slinga innan den n˚att det slut som angivits. Antag till exempel att vi skriver en rutin som skall kontrollera om ett tal ¨ar primtal eller inte. Vi vet att den minsta faktorn inte kan vara st¨orre ¨an roten ur talet sj¨alvt. Vi beh¨over d¨arf¨or bara testa att dividera med alla heltal upp till roten ur talet om ingen division g˚ar j¨amnt upp ¨ar talet ett primtal. Men om vi n˚agonstans p˚a v¨agen hittar en primfaktor s˚a beh¨over vi ju inte forts¨atta till det bittra slutet, finns det en faktor s˚a ¨ar talet i fr˚aga inte ett primtal. Att dividera med alla heltal upp till det tal som ¨ar kvadratroten ur talet ¨ar urtypen f¨or en uppgift som vi l¨oser i en slinga. Men om vi hittar en faktor vill vi hoppa ur slingan med en g˚ang ist¨allet f¨or att utf¨ora en massa on¨odiga divisioner och tester. H¨ar kan vi anv¨anda kommandot break, som n¨ar det utf¨ors hoppar till den del av koden som st˚ar efter ”end” kommandot f¨or slingan. En s˚adan kod kan se ut s˚a h¨ar (vi bortser h¨ar ifr˚an att vi egentligen inte beh¨over testa andra j¨amna tal ¨an 2):

54 KAPITEL 6. PROGRAMMERING

disp(’ ar ej ett primtal, det gar att dela med ’) disp(index)

end