Appendix 11. Parameteröverföring

A 11.1 Grundbegrepp

Formell parameter (eng. dummy argument) är en storhet som finns i specifikationen (deklarationen) av en procedur, funktion eller subrutin.

Aktuell parameter (eng. actual argument) är en storhet som användes i anropet av en procedur, funktion eller subrutin från den överordnade (anropande) proceduren eller programenheten (ofta huvudprogrammet).

A 11.2 Pascal

Då en parameter ej är specificerad som var kommer vid anropet en kopiering att utföras av innehållet i det minnesutrymme, i vilket den aktuella parameterns värde ligger, till ett nytt minnesutrymme. Detta innebär att den aktuella parametern i anropande procedur (huvudprogrammet) ej kan ändras av den anropade proceduren. En sådan parameter kallas för värdeparameter. Med Fortran 90 begrepp skulle den ha attributet INTENT(IN). Däremot är det i Pascal helt tillåtet att i den anropade proceduren tilldela den ett nytt värde, men detta nya värde återförs dock aldrig till den anropande proceduren (huvudprogrammet).

Då en parameter är specificerad som var kommer både den aktuella och den formella parametern att ange samma minnesutrymme. Detta innebär att den aktuella parametern i anropande procedur (huvudprogram) kan ändras av den anropade proceduren. En sådan parameter kallas variabel parameter. Med Fortran 90 begrepp skulle den ha attributet INTENT(INOUT).

I nedanstående lilla programs procedur sub är x invariabel, y både invariabel och misslyckad utvariabel, samt z utvariabel. Här är de formella parametrarna x, y och z, medan de aktuella är a, b och c.

program bosse;
var a, b, c : real;
procedure sub(x, y : real; var z : real);
        begin
        y := y*y;
        z := x + y;
        end;
begin
        a := 1;
        b := 10;
        sub(a,b,c);
        writeln(' a = ', a);    (*    Blir 1     *)
        writeln(' b = ', b);    (*    Blir 10    *)
        writeln(' c = ', c);    (*    Blir 101   *)
end. 

A 11.3 Fortran

En formell parameter, som i Fortran 90 deklarerats INTENT(IN) i den anropade programenheten (funktionen eller subrutinen), bör ge en felutskrift om parametern tilldelas ett nytt värde i den anropade programenheten.

I nedanstående lilla programs subrutin SUB är X invariabel, Y både invariabel och utvariabel, samt Z utvariabel. Avsiktsdeklarationen genom INTENT är dock frivillig. För att den skall ha någon verkan bör ett INTERFACE vara med. Notera att jag där valt att ha en tredje uppsättning namn på variablerna, men samma namn som de i huvudprogrammet och/eller subrutinen är tillåtna. Oftast väljer man samma namn på alla tre ställena. Här är de formella parametrarna X, Y och Z, medan de aktuella är A, B och C. De formella parametrarna i gränssnittet är S, T och U.

PROGRAM BOSSE
        IMPLICIT NONE
        INTERFACE
            SUBROUTINE SUB(S, T, U)
            REAL, INTENT(IN)    :: S
            REAL, INTENT(INOUT) :: T
            REAL, INTENT(OUT)   :: U
            END SUBROUTINE SUB
        END INTERFACE
        REAL :: A, B, C
        A = 1
        B = 10
        CALL SUB(A,B,C)
        WRITE(*,*) ' A = ', A     !      Blir 1     
        WRITE(*,*) ' B = ', B     !      Blir 100
        WRITE(*,*) ' C = ', C     !      Blir 101
END PROGRAM BOSSE
SUBROUTINE SUB(X, Y, Z)
        IMPLICIT NONE
        REAL, INTENT(IN)    :: X
        REAL, INTENT(INOUT) :: Y 
        REAL, INTENT(OUT)   :: Z
        Y = Y**2
        Z = X + Y
END SUBROUTINE SUB 
I Fortran finns egentligen bara ett slags användning av parametrar (på engelska kallad för argument association), men det blir trots detta två fall. Om parametern är en skalär kan vid anropet ske en kopiering av värdet i en minnescell i den anropande programenheten (huvudprogrammet) till en cell i den anropade programenheten, och vid återhoppet kan, om värdet ändrats, en motsvarande kopiering ske från den anropade programenheten till den anropande programenheten (huvudprogrammet). Observera dock att den första kopieringen oftast sker på registernivå och ej säkert till verkliga minnesceller i RAM-minnet. Kopieringen tillbaks till anropande programenhet (huvudprogrammet) misslyckas om den aktuella parametern är en konstant eller ett uttryck, t ex 249 eller SIN(X) eller X+2, och ej ett variabelnamn. Normalt erhålles i detta fall ingen felutskrift vid fel.

Notera att om F(X) är en funktion som anropas så är A i F(A) ett variabelnamn men (A) i F((A)), dvs ett variabelnamn inom parentes, är ett allmännare uttryck. Implementeringen av denna egenskap är dock dålig, varför det är något som ej bör utnyttjas för "trick-programmering".

Om den formella parametern är ett fält skulle denna kopiering kunna ta upp ett väldigt stort lagringsutrymme i båda programenheterna. Detta löses därför så att fältet i den anropande programenheten (huvudprogrammet) utnyttjas direkt. Det aktuella fältet skall vara av samma typ, slag och mönster som den formella parametern. Det finns ett antal undantag från detta krav, Fortran fungerar nämligen så att systemet antar att det aktuella fältet har de egenskaper som specificerats för det formella fältet i den anropade programenheten, och räknar därför ut positionen för de olika elementen utgående från detta antagande. Om den aktuella parametern är ett fält som ser annorlunda ut i verkligheten kommer "fel" element att refereras, vilket kan få katastrofala följder, men ibland fungerar bra.

Om parametrarna är pekare eller namn på funktioner eller subrutiner gäller inte ovanstående resonemang bokstavligt, eftersom det då inte är fråga om några värden.

IBM talade förr i tiden (1977 om FORTRAN IV för IBM 360, en utvidgning av Fortran 66) om att en variabel är received by value vad gäller det som ovan beskrivits som gällande för skalärer, och received by location vad gäller fält. Det fanns även en metod att tvinga fram received by location. Skillnaden var faktiskt förr ganska viktig, men är det inte längre. Det var nämligen tidigare problem med viss synkronisering, till exempel av indexvariabler och variabler i COMMON-block.

A 11.4 Lagringsregler

För Fortran gäller vissa regler för lagring av variabler, dels för fält som måste lagras i en väl specificerad ordning, där första index varierar snabbast, dels för sådana storheter som till exempel placerats i COMMON och/eller EQUIVALENCE. Den modell som Fortran arbetar med när det gäller lagring är som bekant rent linjär, med ett visst utrymmesbehov för heltal och flyttal, och dubbelt för tal i dubbel precision.

Man talar i Fortran om lagringsassociering (eng. storage association) och ordningsassociering (eng. sequence association). Fortranstandarden säger i (14.6.3) att lagringsassociering är den associering av två eller flera dataobjekt som förekommer när två eller flera följder av data delar en eller flera lagringsenheter, och i (12.4.1.4) att ordningsassociering avser den ordning för fältelement som Fortran kräver då ett fältuttryck associeras med ett formellt argument: Mönstret (dvs rang och omfång) hos det aktuella argumentet behöver inte överensstämma med mönstret hos det formella argumentet.

Ordförklaringar Innehåll Laborationer


Senast modifierad: 1 september 2000
boein@nsc.liu.se