<< Array

Indice

Utilizzo dei file >>

 

Sottoprogrammi

 

  • Funzioni standard
  • FUNCTION
  • SUBROUTINE
  • Uso degli array nelle FUNCTION e nelle SUBROUTINE
  •  

    Scrivendo un programma può essere utile suddividere il problema principale in vari sottoproblemi. In FORTRAN è possibile definire un'azione o un gruppo di azioni come FUNCTION o SUBROUTINE, contrassegnate da degli identificatori.

     

    Funzioni standard

    Le funzioni standard sono dei sottoprogrammi già pronti, che possono essere richiamati all'interno del programma principale in qualsiasi momento. Di seguito è riportato un elenco delle principali funzioni:

    Nome funzione

    Azione

    Esempio

    INT

    Converte da REAL a INTEGER

    N=INT(X)

    REAL

    Converte da INTEGER a REAL

    X=REAL(N)

    ABS

    Restituisce il valore assoluto di un numero

    Y=ABS(X)

    MOD

    È l'operazione modulo (restituisce il risultato della divisione di due INTEGER)

    M=MOD(I,J)

    MAX

    Restituisce il massimo di almeno due numeri (gli argomenti devono essere dello stesso tipo)

    X=MAX(A,B,C,D)

    MIN

    Restituisce il minimo di almeno due numeri (gli argomenti devono essere dello stesso tipo)

    X=MIN(A,B,C,D)

    SQRT

    Restituisce la radice quadrata di un numero

    Y=SQRT(X)

    EXP

    Restituisce l'esponenziale di un numero

    Y=EXP(X)

    LOG

    Restituisce il logaritmo naturale di un numero

    Y=LOG(X)

    LOG10

    Restituisce il logaritmo in base 10 di un numero

    Y=LOG10(X)

    COS

    Calcola il coseno (argomento in radianti)

    Y=COS(X)

    SIN

    Calcola il seno (argomento in radianti)

    Y=SIN(X)

    TAN

    Calcola la tangente (argomento in radianti)

    Y=TAN(X)

    ACOS

    Calcola l'arcocoseno

    Y=ACOS(X)

    ASIN

    Calcola l'arcoseno

    Y=ASIN(X)

    ATAN

    Calcola l'arcotangente

    Y=ATAN(X)

    ATAN2

    Calcola l'arcotangente del rapporto di due numeri

    Z=ATAN2(X,Y)

    INDEX

    Restituisce la posizione iniziale di una sottostringa in una stringa

    I=INDEX(STR,SUBSTR)

    ICHAR

    Restituisce il codice ASCII di un carattere

    I=ICHAR(CAR)

    CHAR

    Restituisce un carattere a partire dal suo codice ASCII

    CAR=CHAR(I)

    LLE

    Verifica se una stringa è lessicamente minore o uguale ad un'altra

    BOOL=LLE(S1,S2)

    LGE

    Verifica se una stringa è lessicamente maggiore o uguale ad un'altra

    BOOL=LGE(S1,S2)

    LLT

    Verifica se una stringa è lessicamente minore di un'altra

    BOOL=LLT(S1,S2)

    LGT

    Verifica se una stringa è lessicamente maggiore di un'altra

    BOOL=LGT(S1,S2)

    I nomo di funzioni standard non possono essere adoperati come identificatori.

     

    FUNCTION

    Le funzioni sono sottoprogrammi che, se necessario, possono essere richiamati più volte all'interno di un programma per fornire dei calcoli particolari. Le funzioni, a differenza delle funzioni standard, vengono scritte dal programmatore stesso in quanto non è resa disponibile dal compilatore una funzione standard adatta allo scopo del programmatore.
    Le funzioni sono dei blocchi di istruzioni identificate da:
          tipo_del_risultato FUNCTION nome_funzione(id1,id2,...,idn)
    tipo_del_risultato è uno dei tipi INTEGER, REAL, CHARACTER, LOGICAL, e definisce il tipo di dati restituito dalla funzione chiamata nome_funzione. È tramite nome_funzione che si richiama la funzione all'interno del programma principale. Gli argomenti id1,id2,...,idn sono gli identificatori su cui la funzione opera. Esempio:
          REAL FUNCTION F(N,X,Y,Z)
          ...............................                                            blocco di istruzioni del sottoprogramma
          END

    Le funzioni lavorano sui valori memorizzati negli argomenti e restituiscono un risultato del tipo specificato. L'elenco degli identificatori costituisce un insieme di oggetti fittizi, ai quali, quando il sottoprogramma viene richiamato, vengono rimpiazzati i valori degli argomenti dell'istruzione chiamante.

    Dopo la definizione di una funzione, come di vede dall'esempio, segue il blocco di istruzioni che costituiscono il sottoprogramma. Tra queste vi deve essere almeno un'istruzione di assegnazione con il nome della funzione a sinistra di = (nell'esempio ci dovrà quindi essere F=), che assegna un valore a questa variabile e che viene quindi restituito al programma chiamante al termine della funzione, che come tutti i programmi deve terminare con END. Esempio:
          INTEGER FUNCTION NFATT(N)
          NFATT=1
          DO 10 I=1,N
          NFATT=NFATT*I
    10  CONTINUE
          END

    Per richiamare una funzione nel programma principale si adoperano istruzioni del tipo:
          identificatore=nome_funzione(ID1,ID2,...,IDn)
    ID1,ID2,...,IDn sono gli argomenti della funzione che corrispondono in numero e tipo (se sono degli array anche nelle dimensioni) a id1,id2,...,idn rispettivamente. Per richiamare la funzione dell'esempio precedente:
          N=NFATT(NUM)
    Non appena nel programma princiale si incontra il nome della funzione l'esecuzione passa alla funzione con quel nome, e ad ognuno degli argomenti viene assegnato il valore corrispondente. Terminata l'esecuzione della funzione si torna al programma principale. Si intende che prima di poter richiamare una funzione dal programma principale è necessario assegnare ad ogni variabile che compare tra gli argomenti della funzione un valore.

     

    SUBROUTINE

    Le SUBROUTINE sono sottoprogrammi che, se necessario, possono essere richiamati più volte all'interno di un programma per fornire dei calcoli particolari. Le SUBROUTINE, come le funzioni, a differenza delle funzioni standard, vengono scritte dal programmatore stesso in quanto non è resa disponibile dal compilatore una funzione standard adatta allo scopo del programmatore.
    Le SUBROUTINE sono dei blocchi di istruzioni identificate da:
          SUBROUTINE nome_sottoprogramma(id1,id2,...,idn)
    nome_sottoprogramma attribuisce un nome alla SUBROUTINE, è tramite questo che si fa riferimento al sottoprogramma all'interno del programma principale, come avveniva per le funzioni. A differenza delle funzioni, nome_sottoprogramma non è una variabile passante (variabile che viene restituita al programma chiamante), per questo non si deve specificare il tipo. Gli argomenti id1,id2,...,idn sono gli identificatori su cui la SUBROUTINE opera. Esempio:
          SUBROUTINE SUB(N,X,Y,Z)
          ...............................                                            blocco di istruzioni del sottoprogramma
          END

    Le SUBROUTINE lavorano sui valori memorizzati negli argomenti e possono restituire dei risultati. L'elenco degli identificatori costituisce un insieme di oggetti fittizi, ai quali, quando il sottoprogramma viene richiamato, vengono rimpiazzati i valori degli argomenti dell'istruzione chiamante.

    Si è detto che le SUBROUTINE possono restituire dei risultati, in quanto possono restituire al programma chiamante uno o più risultati, o nessuno, a differenza delle funzioni che restituivano sempre un solo valore. Il compito di restituire il risultato al programma chiamante, non essendo nome_sottoprogramma una variabile passante, è affidato a uno o più elementi id1,id2,...,idn, o anche a nessuno, in tal caso la SUBROUTINE non restituisce alcun risultato. Quindi sono gli identificatori che restituiscono il risultato a trovarsi a sinistra delle istruzioni di assegnazione all'interno del blocco di istruzioni che costituisce la SUBROUTINE. Come tutti i programmi anche le SUBROUTINE devono essere terminate con END. Riscriviamo il precedente esempio di funzione come SUBROUTINE:
          SUBROUTINE FATTORIALE(N,NFATT)
          NFATT=1
          DO 10 I=1,N
          NFATT=NFATT*I
    10  CONTINUE
          END
    FATTORIALE è il nome della SUBROUTINE. Il tipo di FATTORIALE non ha ne importanza ne effetti, a differenza delle funzioni. Diversamente dalla funzione NFATT, che aveva come argomento solo N, la SUBROUTINE FATTORIALE ha come argomenti N e NFATT, e proprio a quest'ultimo è assegnato il compito di restituire il valore al programma chiamante.

    La dichiarazione di una SUBROUTINE non causa l'esecuzione del suo corpo, perché ciò avvenga è necessario chiamare la SUBROUTINE dal programma principale con la seguente istruzione:
          CALL nome_sottoprogramma(ID1,ID2,...,IDn)
    ID1,ID2,...,IDn sono gli argomenti della SUBROUTINE che corrispondono in numero e tipo (se sono degli array anche nelle dimensioni) a id1,id2,...,idn rispettivamente, come per le funzioni. Per richiamare la SUBROUTINE dell'esempio precedente si usa:
          CALL FATTORIALE(NUM,NRIS)
    Non appena nel programma princiale si incontra il nome della SUBROUTINE l'esecuzione passa alla SUBROUTINE con quel nome, e ad ognuno degli argomenti viene assegnato il valore corrispondente. Terminata l'esecuzione della SUBROUTINE si torna al programma principale. Si intende che prima di richiamare una SUBROUTINE dal programma principale è necessario assegnare dei valori ad ogni variabile che compare tra gli argomenti della SUBROUTINE necessaria per i calcoli, non è necessario assegnare dei valori alle variabili passanti.

    La precedente SUBROUTINE può anche essere scritta nel seguente modo:
          SUBROUTINE FATTORIALE(N)
          INTEGER APP
          APP=1
          DO 10 I=1,N
          APP=APP*I
    10  CONTINUE
          N=APP
          END
    In questo caso la variabile N ha il compito di portare i dati all'interno della SUBROUTINE prima e quello di restituire il risultato della SUBROUTINE al programma chiamante. In questo caso, dopo l'esecuzione della SUBROUTINE, non si potrà più far riferimento al precedente valore della N. La variabile APP è una variabile locale della SUBROUTINE.

    Di seguito è riportato un'altra variante della stessa SUBROUTINE come esempio di SUBROUTINE che non restituiscono valori al programma chiamante:
          SUBROUTINE FATTORIALE(N)
          NFATT=1
          DO 10 I=1,N
          NFATT=NFATT*I
    10  CONTINUE
          PRINT*,NFATT
          END

    Per quanto riguarda gli ultimi due esempi visti, l'istruzione di chiamata è la seguente:
          CALL FATTORIALE(NUM)

    È di seguito riportato un esempio di SUBROUTINE che restituisce più valori:
          SUBROUTINE ORDINA(X,Y)
          IF (X.GT.Y) THEN
          Z=X
          X=Y
          Y=Z
          ENDIF
          END
    nel precedente esempio X,Y sono le variabili di ingresso-uscita, mentre Z è una variabile di appoggio che non torna al programma chiamante.

    In conclusione si noti che una SUBROUTINE può richiamare un'altra SUBROUTINE, ma non ricorsivamente (non può richiamare se stessa).

     

    Uso degli array nelle FUNCTION e nelle SUBROUTINE

    Come è già stato detto, tra gli argomenti di SUBROUTINE e FUNCTION  ci possono essere degli array, come si vede dall'esempio seguente:
          SUBROUTINE ORDINA(X)
          INTEGER X
          DIMENSION X(100)
          DO 10 I=1,99
          DO 10 J=I+1,100
          IF (X(I).GT.X(J)) THEN
          NAPP=X(I)
          X(I)=X(J)
          X(J)=NAPP
          ENDIF
    10  CONTINUE
          END
    con il relativo comando di richiamo:
          CALL ORDINA(A)

    Il FORTRAN permette nei sottoprogrammi il dimensionamento variabile degli array. Così il precedenteesempio diventa:
          SUBROUTINE ORDINA(X,N)
          INTEGER X
          DIMENSION X(N)
          DO 10 I=1,N-1
          DO 10 J=I+1,N
          IF (X(I).GT.X(J)) THEN
          NAPP=X(I)
          X(I)=X(J)
          X(J)=NAPP
          ENDIF
    10  CONTINUE
          END
    con il relativo comando di richiamo:
          CALL ORDINA(A,M)
    È ovvio che M (assegnato con un'istruzione di assegnazione, o con un input) non deve superare la dimensione di A dichiarata una volta per tutte nel programma principale.

    Segue un esempio di uso errato del dimensionamento variabile:
          SUBROUTINE SOMMA(X,Y,N)
          DIMENSION X(N),Y(N),Z(N)
          DO 10 I=1,N
          Z(I)=X(I)+Y(I)
    10  CONTINUE
          PRINT*,(Z(I),I=1,N)
          END
    l'errore è nel dimensionamento di Z, che non è una variabile passante, ma una variabile locale della SUBROUTINE e quindi deve essere dimensionata con una costante e non con una variabile.

    È ovvio che non è neanche permesso aumentare le dimensioni di un array oltre il limite dato con l'istruzione DIMENSION nel programma principale.

    Il FORTRAN permette una scrittura come la seguente:
          SUBROUTINE PRODOTTO(X,Y,Z,N)
          DIMENSION X(N),Y(N),Z(*)
          DO 10 I=1,N
          Z(I)=0
    10  CONTINUE
          DO 20 I=1,N
          DO 20 J=1,N
          Z(I)=Z(I)+X(I)*Y(J)
    20  CONTINUE
          END
    l'asterisco (*) sostituisce la variabile nel DIMENSION e può essere utilizzato quando la dimensione dell'array è il risultato delle operazioni effettuate nella SUBROUTINE.

    Quanto detto per le SUBROUTINE si intende valido anche per le funzioni.

     

    << Array

    Indice

    Utilizzo dei file >>