• No results found

2.4. Teckenstr¨ angar och logiska uttryck

N/A
N/A
Protected

Academic year: 2021

Share "2.4. Teckenstr¨ angar och logiska uttryck"

Copied!
20
0
0

Loading.... (view fulltext now)

Full text

(1)

2.4. Teckenstr¨ angar och logiska uttryck

I Fortran sparar man text i variabler av typen CHARACTER. F¨or varje tecken reserveras normalt 1 byte i minnet. F¨or att deklarera en teckenvariabel TEXT och samtidigt reservera 30 tecken f¨or den, anv¨ander man deklarationen CHARACTER (LEN=30) :: TEXT. Om man reserverar olika mycket utrymme f¨or flere teck- envariabler, kan detta g¨oras med en enda sats, t.ex. CHARACTER :: a*10, b*20, c*30, som reserverar 10 tecken f¨or variabeln a, 20 tecken f¨or variabeln b och 30 tecken f¨or variabeln c.

En teckenvariabel kan definieras genom att s¨atta den lika med ett uttryck, vars v¨arde ¨ar en teckenstr¨ang.

Ett s˚adant uttryck kan t.ex. vara en teckenstr¨ang omgiven av apostrofer, s˚a att t.ex. TEXT = ’ABCDE’

definierar v¨ardet av en teckenvariabel TEXT med 5 tecken. Om man skriver en teckenstr¨ang med mindre antal tecken ¨an vad som har reserverats f¨or teckenvariabeln ifr˚aga, kommer den att utfyllas med mellanrum (blanka tecken) till sin fulla l¨angd. Detta inneb¨ar, att om f¨or en teckenvariabel TEXT reserverats 10 tecken, och den har definierats som TEXT = ’tecken’, s˚a betyder detta detsamma som TEXT = ’tecken ’.

Om man ˚a andra sidan skriver en teckenstr¨ang med flere tecken ¨an vad som reserverats, s˚a kommer str¨angen att stympas, s˚a att den f˚ar den r¨atta l¨angden. Om vi t.ex. definierar variabeln TEXT i exemplet ovan som TEXT =’teckenstr¨ang’, s˚a kommer detta att betyda detsamma som TEXT =’teckenstr¨a’.

(2)

Som vi tidigare omn¨amnt i samband med utskrift av text, g¨aller ocks˚a f¨or teckenvariabler att apostrofer dubbleras, om s˚adana f¨orekommer i teckenstr¨angen. S˚alunda skriver man t.ex.

TEXT = ’Descartes’’ filosofi’. Man kan ocks˚a utf¨ora en operation p˚a teckenstr¨angar, n¨amligen sammanl¨ankning (eng.: concatenation) med sammanl¨ankningsoperatorn //. Ett exempel p˚a sammanl¨ank- ning ¨ar TEXT = ’tec’//’ken’.

Ocks˚a understr¨angar kan definieras genom att man skriver tv˚a heltalsuttryck efter variabelnamnet innanf¨or parentes, samt ˚atskilda av ett kolon, t.ex. TEXT(2:4), som i ovanst˚aende fall betecknar str¨angen ’eck’.

Om man bara vill ¨andra en del av en str¨ang, kan man ocks˚a ge ett v¨arde ˚at en understr¨ang. Ett exempel p˚a detta ¨ar t.ex. instruktionerna

CHARACTER (6) :: str str = ’fyrtio’

str(2:3) = ’em’

som f¨orvandlar ’fyrtio’ till ’femtio’.

Som ett exempel p˚a manipulation av teckenstr¨angar kan vi se p˚a f¨oljande program, som skriver ut en h¨alsning p˚a sk¨armen:

(3)

PROGRAM goddag

! Exempel p˚a manipulation av textstr¨angar IMPLICIT NONE

CHARACTER :: titel*10, fornam*20, tilnam*20 CHARACTER (52) :: fulnam

! Fr˚aga namnet:

PRINT *, ’Var god skriv fullst¨andigt namn i ¨onskad form’

PRINT *, ’Titel (herr, fru, fr¨oken, etc...):’

READ *, titel

PRINT *, ’F¨ornamn:’

READ *, fornam

PRINT *, ’Tillnamn:’

READ *, tilnam

! Konstruera hela namnet:

fulnam = TRIM(titel)//’ ’//TRIM(fornam)//’ ’//TRIM(tilnam)

! Skriv en h¨alsning:

PRINT *, ’Goddag, ’,TRIM(fulnam), ’ !’

PRINT *, ’Eller f˚ar jag s¨aga ’,TRIM(fornam),’ ?’

END PROGRAM goddag

(4)

Observera, att teckenstr¨angarna utfylls till sin fulla l¨angd. D¨arf¨or har TRIM-funktionen, som putsar bort extra mellanrum anv¨ants i programmet.

Vi skall nu diskutera logiska variabler, som ¨ar av betydelse speciellt i villkorssatser. En logisk variabel test deklareras med en instruktion av formen LOGICAL :: test, och definieras med ett logiskt uttryck, som antingen kan vara sant (.TRUE.), eller falskt (.FALSE.). Logiska uttryck (eller booleska uttryck) kan konstrueras med relationsoperatorer. Det finns sex relationsoperatorer i Fortran 90, som har varsin motsatta operator:

Relationsoperator Motsatt operator

< (mindre ¨an) >= (st¨orre el. lika med)

<= (mindre el. lika med) > (st¨orre ¨an)

== (lika med) /= (inte lika med)

>= (st¨orre el. lika med) < (mindre ¨an)

> (st¨orre ¨an) <= (mindre el. lika med) /= (inte lika med) == (lika med)

(5)

Om a och b ¨ar tv˚a reella variabler, s˚a kan vi t.ex. konstruera logiska uttryck av formen a > b och a <=

b, som ¨ar varandras motsatser. F¨or att ange motsatsen till ett logiskt uttryck kan man ocks˚a anv¨anda den logiska operatorn .NOT., vilket t.ex. betyder att a <= b ¨ar detsamma som .NOT. ( a > b). Dessutom finns det fyra andra logiska operatorer, n¨amligen .AND. (”och”), .OR. (”eller”), .EQV. (”ekvivalent med”) och .NEQV. (”inte ekvivalent med”). Med hj¨alp av dessa logiska (eller booleska) operatorer ¨ar det m¨ojligt att konstruera mer komplicerade logiska uttryck.

Logiska operatorer f˚ar endast verka p˚a logiska uttryck, vilket inneb¨ar att om t.ex. a, b och c ¨ar reella variabler, s˚a ¨ar a > b .OR. a < c ett korrekt konstruerat logiskt uttryck, medan a .OR. b < c ¨ar felaktigt. De logiska operatorerna f¨oljer en prioritetsordning, enligt vilken .NOT. har den h¨ogsta prioriteten, d¨arp˚a f¨oljer .AND., sedan .OR., och sist .EQV. och .NEQV., som allts˚a har den l¨agsta prioriteten. Denna prioritetsordning kan givetvis f¨or¨andras med hj¨alp av parenteser.

F¨or att best¨amma v¨ardet av ett logiskt uttryck anv¨ander man en sanningstabell:

(6)

Log. uttryck Logisk Log. uttryck Logiskt

A operator B resultat

.NOT. .TRUE. .FALSE .FALSE. .TRUE.

.TRUE. .AND. .TRUE. .TRUE.

.TRUE. .FALSE. .FALSE.

.FALSE. .TRUE. .FALSE.

.FALSE. .FALSE. .FALSE.

.TRUE. .OR. .TRUE. .TRUE.

.TRUE. .FALSE. .TRUE.

.FALSE. .TRUE. .TRUE.

.FALSE. .FALSE. .FALSE.

.TRUE. .EQV. .TRUE. .TRUE.

.TRUE. .FALSE. .FALSE.

.FALSE. .TRUE. .FALSE.

.FALSE. .FALSE. .TRUE.

.TRUE. .NEQV. .TRUE. .FALSE.

.TRUE. .FALSE. .TRUE.

.FALSE. .TRUE. .TRUE.

.FALSE. .FALSE. .FALSE.

(7)

Operatorerna .EQV. och .NEQV., som ¨ar mer speciella, ger till resultat sanna v¨arden om operanderna

¨ar ekvivalenta, resp. icke-ekvivalenta (dvs har samma logiska v¨arden, resp. motsatta). Med hj¨alp av dessa operatorer kan man f¨orenkla endel komplicerade uttryck. S˚alunda inneb¨ar t.ex. (a < b .AND. c < d) .OR. ( a >= b .AND. c >= d) detsamma som a < b .EQV. c < d.

Den viktigaste anv¨andningen av logiska uttryck ¨ar i villkorssatser, som har den allm¨anna strukturen IF ( logiskt uttryck ) THEN

...

ELSE ...

END IF

Om det logiska uttrycket i ovanst˚aende villkorssats har v¨ardet .TRUE., utf¨ors satserna mellan THEN och ELSE, i motsatt fall utf¨ors satserna mellan ELSE och ENDIF. Om ELSE fattas, kommer exekveringen att forts¨atta efter ENDIF, ifall det logiska uttrycket ¨ar osant.

(8)

Man kan ocks˚a placera flera s˚adana IF-block innanf¨or varandra:

IF ( villkor 1 ) THEN ...

ELSE IF ( villkor 2 ) THEN ...

ELSE IF ( villkor 3 ) THEN ...

ELSE ...

END IF

I detta fall kommer satserna mellan det sista ELSE och END IF att utf¨oras endast om inte ett enda av villkoren 1, 2 eller 3 g¨aller. Endast ett av blocken kommer att utf¨oras.

Som ett exempel p˚a anv¨andningen av villkorssatser skall vi v¨alja ett program, som ber¨aknar kubikroten ur ett givet tal med formeln a1/3 = eln a/3, (a > 0). Programmet testar, om talet till sitt absoluta v¨arde

¨ar s˚a litet, att roten kan anses vara noll, och beaktar dessutom, att kubikroten ur ett negativt tal f˚as genom att byta f¨ortecken framf¨or kubikroten ur det motsvarande positiva talet.

(9)

PROGRAM root3

! Program som ber¨aknar tredje roten av ett givet tal IMPLICIT NONE

REAL :: a, eps, x, sign eps = 1.E-20

! L¨as in talet

PRINT *, ’Skriv in talet:’

READ *, a

! Kontrollera att talet inte ¨ar noll:

IF (ABS(a) < eps) THEN x = 0.

ELSE

sign = 1.

IF (a < 0.) THEN sign = -1.

END IF

x = sign*EXP(LOG(ABS(a))/3.0) END IF

! Skriv ut resultatet:

PRINT *, ’Kubikroten ur ’,a,’ ¨ar ’,x STOP

END PROGRAM root3

Detta program inneh˚aller tv˚a IF-block innanf¨or varandra. Kubikroten ber¨aknas med instruktionen

x = sign*EXP(LOG(ABS(a))/3.0), d¨ar absoluta v¨ardet av argumentet anv¨ants f¨or att man ocks˚a skall kunna korrekt behandla kubikroten ur negativa tal.

(10)

Vi skall nu studera ett mera komplicerat IF-block. Vi ska unders¨oka, om en given punkt (x, y) ing˚ar i rektangeln A: {0 ≤ x ≤ 2, 0 ≤ y ≤ 1}, rektangeln B: {1 ≤ x ≤ 2, 0 ≤ y ≤ 2} eller i b¨agge tv˚a.

Programmet ser ut s˚ah¨ar:

PROGRAM punkter IMPLICIT NONE

LOGICAL rektangel_A, rektangel_B REAL x,y

PRINT *, ’Skriv ett talpar x, y:’

READ *, x, y

rektangel_A = (x>=0 .AND. x<=2 .AND. y>=0 .AND. y<=1) rektangel_B = (x>=1 .AND. x<=2 .AND. y>=0 .AND. y<=2) IF(rektangel_A .AND. rektangel_B) THEN

PRINT *, ’Punkten finns i b˚ada rektanglarna!’

ELSE IF(rektangel_A) THEN

PRINT *, ’Punkten finns i rektangel A’

ELSE IF(rektangel_B) THEN

PRINT *, ’Punkten finns i rektangel B’

ELSE

PRINT *, ’Punkten ¨ar utanf¨or rektanglarna!’

END IF

END PROGRAM punkter

Som vi ser, kan logiska variabler l¨att konstrueras med hj¨alp av logiska uttryck.

(11)

2.5. DO-slingor och programkontroll

I Fortran 90 finns en s¨arskild satskonstruktion f¨or att v¨alja ett av flere m¨ojliga alternativ, beroende av v¨ardet f¨or ett uttryck. Denna konstruktion kallas CASE, och har f¨oljande allm¨anna form:

SELECT CASE ( uttryck ) CASE ( selektor )

( Fortran-satser ) CASE ( selektor )

( Fortran-satser ) ...

END SELECT

Den f¨orsta satsen i CASE-konstruktionen har formen SELECT CASE (uttryck), d¨ar uttrycket kan vara ett heltalsuttryck, teckenuttryck eller logiskt uttryck (observera: inte reellt uttryck!). V¨ardet av detta uttryck ber¨aknas, varp˚a satserna som f¨oljer efter den l¨ampligaste CASE-satsen utf¨ores. En CASE-sats har antingen formen CASE (selektor) eller CASE DEFAULT (ifall inte n˚agon av de ¨ovriga CASE-satserna g˚ar att till¨ampa).

(12)

En selektor kan se ut p˚a fyra olika s¨att:

a) ett enkelt v¨arde. I detta fall utf¨ors de efterf¨oljande Fortran-satserna endast om det ovann¨amnda uttrycket

¨ar lika med detta v¨arde.

b) ett v¨arde efterf¨oljt av kolon (:). I detta fall utf¨ors de efterf¨oljande Fortran-satserna endast om detta v¨arde ¨ar mindre eller lika med ovann¨amnda uttryck.

c) ett v¨arde som f¨oreg˚as av kolon (:). I detta fall utf¨ors de efterf¨oljande Fortran-satserna endast om det ovann¨amnda uttrycket ¨ar mindre eller lika med detta v¨arde.

d) tv˚a v¨arden, ˚atskiljda av ett kolon. I detta fall utf¨ors de efterf¨oljande satserna endast om det mindre v¨ardet ¨ar mindre eller lika med uttrycket och uttrycket ¨ar mindre eller lika med det st¨orre v¨ardet.

Som ett enkelt exempel p˚a anv¨andningen av en dylik CASE-konstruktion skall vi studera ett program, som svarar ”Gomorron”, ”Goddag”, ”Goafton” eller ”Gonatt”, beroende p˚a vad klockan ¨ar:

(13)

PROGRAM dagstid IMPLICIT NONE

CHARACTER (LEN=5) :: klockan CHARACTER (LEN=2) :: timmen

! Fr˚aga tiden:

PRINT *, "Vad ¨ar klockan (skriv tiden som xx:yy)"

READ *, klockan

! Ta reda p˚a timmen:

timmen = klockan(1:2)

! Skriv ett svar SELECT CASE (timmen) CASE ("06":"11")

PRINT *, "Gomorron!"

CASE ("12":"17") PRINT *, "Goddag!"

CASE ("18":"23")

PRINT *, "Goafton!"

CASE ("00":"05") PRINT *, "Gonatt!"

CASE DEFAULT

PRINT *, "Om¨ojligt!"

END SELECT STOP

END PROGRAM dagstid

(14)

Ett annat exempel ¨ar ett program som l¨oser en andragradsekvation, och anv¨ander en SELECT-konstruktion f¨or att skilja mellan de olika fallen (tv˚a reella r¨otter, tv˚a sammanfallande r¨otter, eller ingen reell rot).

PROGRAM kvadekv IMPLICIT NONE

REAL, PARAMETER :: eps=1.E-7 REAL :: a,b,c,d,d1,x1

INTEGER :: selektor

PRINT *, "Ge koefficienterna a, b och c:"

READ *, a,b,c

! R¨akna ut diskriminanten d = b*b - 4*a*c

! Dividera med eps (mindre tal r¨aknas som noll) selektor = d/eps

x1 = -b/(a+a)

SELECT CASE (selektor) CASE (1:) ! Tv˚a r¨otter

d1 = SQRT(d)/(a+a)

PRINT *, "Ekvationen har r¨otterna: ",x1+d1," och ",x1-d1 CASE (0) ! En rot

PRINT *, "Ekvationen har roten ",x1 CASE (:-1) ! Inga r¨otter

PRINT *, "Ekvationen har inga reella r¨otter!"

END SELECT STOP

END PROGRAM kvadekv

(15)

Numeriska ber¨akningar g¨ors mycket ofta iterativt, dvs man upprepar en viss sekvens av instruktioner m˚an- ga g˚anger tills ¨onskat resultat uppn˚as. I Fortran sker detta med hj¨alp av DO-slingor, som inleds av DO- instruktion DO n ind = i1, i2, i3. H¨ar betecknar ind den s.k. DO-variabeln (vanligen en heltalsvari- abel), som best¨ammer hur m˚anga g˚anger slingan upprepas. Uttrycket i1 anger DO-variabelns begynnel- sev¨arde, i2 dess slutv¨arde, och i3 ¨okningen (som b¨or vara olika 0). Om i3 l¨amnas bort, antas ¨okningen vara 1.

N¨ar en DO-sats utf¨ors, kommer DO-variabelns begynnelsev¨arde, slutv¨arde och tillskott f¨orst att r¨ak- nas ut, varefter den antar sitt begynnelsev¨arde i1. D¨arp˚a ber¨aknas iterationstalet enligt formeln max[int(i2−i1+i3

i3 ), 0], d¨ar int anger en heltalsdivision. Om iterationstalet blir lika med 0, avbryts utf¨orandet av slingan, och kontrollen flyttas ¨over till den f¨orsta instruktionen efter slingan, som blir in- aktiv. Slingan DO i=1,42,5 kommer s˚aledes att utf¨oras max[int(42−1+55 ), 0] = 9 g˚anger. Som vi ser, kommer inga iterationer att utf¨oras, om i1 > i2 och i3 > 0 eller i1 < i2 och i3 < 0.

S˚a l¨ange iterationstalet ¨ar positivt utf¨ors instruktionerna i DO-slingan ¨anda till den sista satsen, som har satsnumret n (i kolumnerna 1-5). I Fortran 77 var denna sats vanligen CONTINUE, men kunde ocks˚a vara n˚agon annan sats, som inte f¨or¨andrar programfl¨odets riktning. I Fortran 90 avslutas en DO-slinga av kommandot END DO, som ocks˚a godk¨anns av m˚anga kompilatorer som f¨oljer den ¨aldre standarden. Detta kommando beh¨over inte n˚agot satsnummer.

(16)

Den allm¨anna formen av en programslinga ¨ar d¨arf¨or enklare i Fortran 90:

DO ind = i1, i2, i3 ...

( Programsatser ) ...

END DO

H¨ar b¨or DO-variabeln ind b¨or vara en heltalsvariabel, och dess begynnelsev¨arde, slutv¨arde och tillskott ¨ar heltalsuttryck.

Sedan programfl¨odet n˚att slutet av slingan, ¨okas DO-variabeln med v¨ardet av i3, och iterationstalet minskas med 1, varp˚a iterationstalet testas. P˚a grund av DO-variabelns speciella betydelse f¨or DO-slingan, ¨ar det inte till˚atet att f¨or¨andra dess v¨arde i n˚agon sats inom slingan. Man b¨or ytterligare observera, att det inte

¨ar DO-variabelns v¨arde som best¨ammer vad som h¨ander, utan ist¨allet iterationstalet, vars v¨arde minskar med 1 f¨or varje genomg˚ang av slingan. N¨ar alla iterationer har utf¨orts, kommer DO-variabeln att anta det v¨arde den skulle ha f˚att ifall slingan skulle ha genomg˚atts en g˚ang till.

(17)

Som ett exempel skall vi studera ett program, som skriver ut multiplikationstabellerna fr˚an 2 till 10 i formen

2:ans tabell

2 x 1 = 2

2 x 2 = 4

2 x 3 = 6

2 x 4 = 8

2 x 5 = 10

2 x 6 = 12

2 x 7 = 14

2 x 8 = 16

2 x 9 = 18

2 x 10 = 20

3:ans tabell

3 x 1 = 3

3 x 2 = 6

3 x 3 = 9

3 x 4 = 12

3 x 5 = 15

3 x 6 = 18

3 x 7 = 21

3 x 8 = 24

3 x 9 = 27

3 x 10 = 30

...

(18)

Programmet, som anv¨ander tv˚a DO-slingor ser ut s˚ah¨ar:

PROGRAM tabula IMPLICIT NONE

! Ett program f¨or att skriva ut multiplikationstabeller INTEGER :: i,j

DO i=2,10

PRINT *, ’ ’

PRINT *, i, ’:ans tabell’

DO j=1,10

PRINT *, i, ’ x ’, j, ’ = ’,i*j END DO

END DO STOP

END PROGRAM tabula

I detta exempel ligger de b˚ada DO-slingorna i sin helhet innanf¨or varandra. Observera, att det inte ¨ar till˚atet att l˚ata tv˚a slingor korsa varandra.

Vi skall se p˚a ett annat exempel, som visar hur man kan ber¨akna en fakultet (t.o.m. 12!) med en DO-slinga, d¨ar tillskottet ¨ar negativt.

(19)

PROGRAM fakult

! Program f¨or att ber¨akna fakulteter IMPLICIT NONE

INTEGER :: n, fac, i

PRINT *, ’Ge ett positivt heltal:’

READ *, n

! Bilda produkten n*(n-1)*...*2*1 fac = 1

DO i=n,2,-1 fac = fac*i END DO

! Skriv resultat:

PRINT *, ’Fakulteten ¨ar ’,fac STOP

END PROGRAM fakult

(20)

Som ett ytterligare exempel p˚a anv¨andningen av DO-slingor skall vi se p˚a ett program, som ber¨aknar ett nollst¨alle av f (t) = cos(t) − 1/t med Newtons metod:

Program newt

! Programmet s¨oker ett nollst¨alle av f(t)=cos(t)-1/t

! med Newtons metod IMPLICIT NONE

REAL :: t INTEGER :: i

PRINT *, ’Ange ett begynnelsev¨arde f¨or t:’

READ *, t DO i=1,20

t = t-(cos(t)-1./t)/(-sin(t)+1./(t*t)) PRINT *, ’it = ’,i,’ t = ’, t

END DO

END PROGRAM newt

Denna funktion har m˚anga nollst¨allen, som vi l¨att kan se.

References

Related documents

Vad som d¨ armed f¨ oljer ¨ ar redo- g¨ orelse av p-v¨ ardenas f¨ ordelningar utan och med medveten bias, kombinerade p-v¨ arde f¨ ordelningar utan och med medveten bias, j¨

F¨ or att formatera teckenstr¨angar anv¨ands i Fortran ett s¨arskilt format, som allm¨ant kan uttryckas kAn, d¨ar k anger antalet upprepningar, och n ¨ar antalet tecken i

P˚ a grund av det h¨ar kan vi endast f¨ors¨akra oss om (2.1) givet att dess sanningsv¨arde ¨ar beroende endast av en begr¨ansad m¨angd information, ett inledande segment av, α och

Och f¨or att bevisa detta r¨acker det i sin tur att bevisa att f faktiskt antar ett minsta v¨arde i D, f¨or vi har redan konstaterat att max-v¨ardet ¨ar noll och antas i varje

D¨arf¨or ¨ar 2X exponentialf¨ordelad, med v¨antev¨arde 2a, vilket ¨ar samma f¨ordelning som f¨or Y.. Uppgiften ¨ar egentligen felformulerad; det ¨ar signifikansnniv˚an 1%

[r]

Resonemang, ekvationslös- ningar och uträkningar för inte vara så knapphändigt presenterade att de blir svåra att följa.. Efter varje uppgift anges maximala antalet

I en simbass¨ang finns ett halvcirkelformat f¨onster D med radie R och vars medelpunkt befinner sig p˚a djupet h, d¨ar h &gt; R, en-