Vous êtes sur la page 1sur 22

2.

 Les  fonc+ons  
Une  fonc(on  dispose  d'arguments  qui  correspondent  à  des  informa(ons  qui  lui  sont  
transmises  et  elle  fournit  un  résultat  unique,  désigné  par  le  nom  même  de  la  fonc(on  
(y  =  f(x))  
Exemple.    créa(on  d'une  unité  de  compila(on  (FUNCTION)    
             FUNCTION  polynome(a,b,c,x)  
                   IMPLICIT  NONE  
                   REAL,  INTENT(IN)    ::  a,b,c,x  
                   REAL                                                ::  polynome  
                   polynome  =  a*x*x+b*x+c  
             END  FUNCTION  polynome  
Ici    polynome  sert  au  nom  de  la  fonc(on  et  pour  désigner  le  résultat.  
 
Appel  d'une  fonc-on.  
             y  =  polynome(a,b,c,x)  
est  équivalent  à  y  =  ax2  +  bx  +  c  .  Bien  sûr  y  et  polynome  sont  des  réels.  
Il  est  nécessaire  que  le  compilateur  connaisse  le  type  de  la  fonc(on  c-­‐à-­‐d  le  type  du  
résultat  qu'elle  fournit.    
On  peut  déclarer  dans  le  programme  principal  :  
real  ::    polynome  
mais  dans  ce  cas  le  compilateur  ne  vérifie  pas  le  type  d'argument  fourni  par  la  
fonc(on.  Pour  remédier  à  cet  inconvénient  on  peut  u(liser  une  interface.  
3.  Les  interfaces  
La  no(on  d'interface  permet  de  fiabiliser  les  appels  de  procédures  et  fonc(ons.  Elle  
est  également  indispensable  pour  exploiter  les  possibilités  de  créa(on  de  modules,  de  
procédures  génériques.  
 
       PROGRAM  fiable  
             IMPLICIT  NONE  
             REAL    ::  a  =  1.,  b  =  2.  ,c  =  5.  ,x  =  33.,  y,  z  
             INTERFACE    
                 FUNCTION  polynome(a,b,c,x)  
                         IMPLICIT  NONE  
                           REAL,  INTENT(IN)    ::  a,b,c,x  
                           REAL                            ::  polynome  
                 END  FUNCTION  polynome  
             END  INTERFACE  
             y  =  polynome(x,a,c,b)                                            
             z  =  2.  *  y  +  polynome(a+1.,2.*c  ,b,y+0.5)    
             PRINT*,y,z  
       END  PROGRAM  fiable  
L'interface  fournira  alors  non  seulement  le  type  de  la  fonc(on,  mais  aussi  le  type  de  
ses  arguments,  ce  qui  signifie  qu'elle  perme]ra  en  outre  un  contrôle  de  ses  
arguments.  Ainsi  le  compilateur  renvoît  un  message  d'erreur  si  a,  b,  c  ,  x  ne  sont  pas  
des  réels.  
4.  Les  fonc+ons  récursives  
C'est  une  fonc(on  comportant  dans  sa  défini(on  au  moins  un  appel  à  elle-­‐même.  
Exemple.  calcul  de  n!  
 
   
             RECURSIVE  FUNCTION  factorielle  (n)  RESULT  (res)  
                   IMPLICIT  NONE  
                   INTEGER,  INTENT(IN)    ::  n  
                   REAL                                  ::  res  
 
                   IF  (  n<=  1)  THEN  
                         res  =  1  
                   ELSE  
                       res  =  factorielle(n-­‐1)*n  
                   ENDIF  
             END  FUNCTION  factorielle  
L'u(lisa(on  du  mot  clé  RESULT  est  indispensable  pour  dis(nguer  le  résultat  du  nom  de  
la  fonc(on.  Bien  sûr  l'interface  doit  être  explicite.  
5.  Tableaux  transmis  en  argument  
Un  tableau  peut  apparaître  en  argument  d'une  procédure.  Problème  comment  
connaitre  le  profil  au  sein  de  la  procédure.  Deux  situa(ons  envisagables  :  
•   Le  profil  du  tableau  est  connu  et  fixe.  
•   Le  profil  du  tableau  n'est  pas  connu.  Deux  cas  pour  traiter  ce  problème  :  
 ENTRÉE  transme]re  en  argument,  le  tableau  et  ses  argument  
 ENTRÉE  déclarer  (en  argument  muet)  un  tableau  de  profil  implicit.  
5.1.  Profil  du  tableau  est  connu  
 SUBROUTINE  connu  (T)  
                   real,  dimension  (10,20)  ::  T  
                   ...  
           END  SUBROUTINE  connu  
La  dimension  du  tableau  est  figé.  Evidemment,  il  y  a  beaucoup  d'inconvénient  dans  
ce]e  démarche.  Par  exemple,  imaginons  qu'on  souhaite  changer  la  taille  du  tableau,  
alors  il  faut  parcourir  tous  les  fichiers  où  le  tableau  apparaît  et  changer  ce  qu'il  faut.  
5.2.  Transmission  explicite  des  étendues  en  argument.  
SUBROUTINE  explicite  (t,  n,p)  
                   IMPLICIT  NONE  
                   !-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  
                   !  declara(ons  des  arguments  
                   INTEGER,  INTENT(IN)                                    ::  n,p  
                   REAL,  DIMENSION  (n,p),  INTENT(INOUT)  ::  t  
                   !-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  
                   !  declara(ons  des  variables  locales  
                   !-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  
                   INTEGER  ::  i  
                   !-­‐-­‐-­‐-­‐-­‐-­‐debut  du  programme-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐  
                   DO  i  =1,n  
                       t(i,:)  =  i  
                   ENDDO  
                   PRINT*,t  
             END  SUBROUTINE  explicite  
Naturellement,  les  appels  de  la  subrou(ne  explicite  doit  être  fait  dans  le  programme  
principal  une  fois  que  le  tableau    a  été  alloué.  
5.3.  Tableau  de  profil  implicite  
On  souhaite  écrire  une  procédure  générique,  on  suppose  que  le  profil  de  notre  
tableau  n'est  pas  connu  par  avance.  
   
             SUBROUTINE  implicite  (t)  
                     IMPLICIT  NONE  
                     REAL,  DIMENSION  (:,:),  INTENT(INOUT)  ::  t  
                     INTEGER  ::  i  
                     DO  i  =  1,  SIZE(t,1)  
                             t(i,:)  =  i  
                     ENDDO  
                     PRINT*,t  
             END  SUBROUTINE  implicite  
DIMENSION(:,:)  précise  que  t  est  un  tableau  de  rang  2  et  que  son  profil  est  implicite  c-­‐
à-­‐d  qu'il  sera  fourni  à  la  subrou(ne  implicite  lors  de  l'appel.  
 
SIZE  :  Ce]e  fonc(on  intrinseque  fournit  l'étendue  d'un  tableau  suivant  une  direc(on,  
ainsi  
•   SIZE(t,1)  fournit  l'étendue  de  t  suivant  la  première  dimension  
•   SIZE(t,2)  fournit  l'étendue  de  t  suivant  la  deuxième  dimension  
q   Pour  u(liser  une  procédure  recevant  en  argument  un  tableau  de  profil  implicit,  
son  interface  doit  être  connue.  
Exemple  u-lisant  les  subrou-nes  explicite  et  implicite  
             PROGRAM  affiche_tableau  
                     IMPLICIT  NONE  
                     REAL,  DIMENSION  (4,0:9)        ::  t1  
                     REAL,  DIMENSION  (4:10,3:7)  ::  t2  
     
                     INTERFACE  
                             SUBROUTINE  implicite  (t)  
                                     IMPLICIT  NONE  
                                     REAL,  DIMENSION  (:,:),  INTENT(INOUT)  ::  t  
                             END  SUBROUTINE  implicite  
                     END  INTERFACE  
 
                     CALL  implicite  (t1)  
                       CALL  implicite  (t2)  
                     !  -­‐-­‐-­‐-­‐-­‐  De  meme  on  peut  faire  la  meme  chose  avec-­‐-­‐-­‐-­‐  
                       CALL  explicite  (t1,SIZE(t1,1),  SIZE(t1,2))  
                                     CALL  explicite  (t2,SIZE(t2,1),  SIZE(t2,2))  
             END  PROGRAM  affiche_tableau  
L'interface  pour  la  subrou(ne  est  obligatoire  sinon  erreur  d'exécu(on.    
La  correspondance  entre  tableau  effec(f  et  tableau  muet  est  uniquement  basée  sur  le  profil.  Les  
bornes  exactes  des  indices  n'ont  aucune  incidence  sur  le  déroulement  des  opéra(ons.  Si  nous  
faisons  appel  à    t(1,1)  dans  la  subrou(ne  implicite,  il  s'agirait  de    t1(1,0)  pour  le  premier  et  de  t2
(4,3)  pour  le  second.    
Il  est  plus  prudent  d'appeler  explicite  en  u(lisant  la  fonc(on  SIZE  
Les  tableaux  automa+ques  
Les  tableaux  automa(ques  voient  leurs  emplacements  alloués  à  chaque  appel.  
Exemple.  Echange  les  valeurs  de  deux  tableaux.  
   
             SUBROUTINE  Echange  (Ta,  Tb)  
                   IMPLICIT  NONE  
                   !-­‐-­‐-­‐-­‐-­‐-­‐  arguments  :  tableaux  de  profil  implicite  -­‐-­‐-­‐-­‐  
                   INTEGER,  DIMENSION  (:),  INTENT(INOUT)  ::  Ta,  Tb    
                   !  tableau  automa(que  :  tableau  local  de  taille  variable  
                   INTEGER,  DIMENSION  (SIZE(Ta))                                ::  Temp          
     
                   Temp  =  Ta  
                   Ta  =  Tb  
                   Tb  =  Temp  
             END  SUBROUTINE  Echange  
Bien  entendu,  il  est  nécessaire  que  l'interface  de  ce]e  subrou(ne  soit  explicité  
dans  le  programme  principal.  
q   Le  profil  d'un  tableau  automa(que  doit  être  donné  en  fonc(on  des  profils  
des  arguments.  
Les  tableaux  allouables  
Il  arrive  parfois  que  la  dimension  d'un  tableau  ne  peut  être  déterminée  qu'après  la  
lecture  d'une  donnée.  Ainsi  la  dimension  d'un  tableau  ne  peut  être  connue  lors  de  la  
séquence  des  déclara(ons  des  variables  dans  le  programme  principal.  Pour  remédier  à  
ceci,  Fortran  offre  la  possibilité  de  décaler  l'alloca(on  de  la  place  mémoire.  
   
             PROGRAM  Alloue  
                   IMPLICIT  NONE  
                   INTEGER    ::  N  
                   REAL,  DIMENSION  (:,:),  ALLOCATABLE  ::  Talloc  
 
                   READ*,N  
                   ALLOCATE(Talloc(N,0:N+1))      !  alloca(on  de  la  place  memoire  
                   TEMP(2,2)  =  1.  
                   DEALLOCATE  (Talloc)                  !  rendre  la  place  memoire  disponible  
             END  PROGRAM  Alloue  
 
ALLOCATABLE  :  précise  que  le  tableau  doit  être  alloué  ultérieurement,  par  contre  le  
rang  du  tableau  doit  être  figé  par  avance.    
ALLOCATE  :  réserve  la  place  mémoire  et  le  profil  du  tableau  est  explicité.    
DEALLOCATE  :  libére  la  place  mémoire,  et  après  ce]e  instruc(on  on  ne  peut  plus  
u(liser  le  tableau  en  ques(on.  
Les  modules  et  la  généricité  
La  no(on  de  module  ouvre  de  nombreuses  perspec(ves  :  
 
 
v   Défini(on  des  types  structures  communs  à  plusieurs  unités  de  
programme.  
 
v   Partage  de  données  entre  plusieurs  unités  de  programme.  
 
v   bibliothèques  de  procédures.  
 
v   Créa(on  de  types  abstraits  de  données.  
No+on  de  module  
Les  modules  perme]ent  d'améliorer  la  fiabilité  des  programmes  en  évitant  la  duplica(on  de  
déclara(ons  iden(ques.  
Exemple  1.  Nous  créons  une  unité  de  compila-on  nommée  'MODULE’  
             MODULE  typtmod  
                   IMPLICIT  NONE  
                   TYPE  point  
                         INTEGER  ::  num  
                         REAL        ::  x,  y  
                   END  TYPE  point  
             END  MODULE  typtmod  
Pour  u(liser  ce  module,  il  suffit  de  men(onner  une  instruc(on  USE  (  ici  USE  typtmod)  au  sein  
d'un  programme,  d'une  procédure  ou  d'une  fonc(on.  Par  exemple  
             PROGRAM  exemple_module  
                   USE  typtmod  
                   IMPLICIT  NONE  
                   TYPE(point)      ::  a  =  point(3,2,0,5.)  
                   PRINT*,a  
             END    PROGRAM  exemple_module  
Tout  se  passe  alors  comme  si  les  instruc(ons  contenues  dans  le  module  typtmod  avaient  été  
introduites  dans  le  programme  principale.  
Exemple  2.  Dépendances  entre  modules  et  procédure.  Un  module  peut  faire  appel  à  
son  tour  à  un  autre  module.  
             MODULE  symmod  
                   USE  typtmod  
                   IMPLICIT  NONE  
                   CONTAINS  
                   FUNCTION  symetrique  (p)  
                         TYPE(point),  INTENT(IN)  ::  p  
                         TYPE(point)                          ::  symetrique  
                         symetrique%x  =  -­‐p%x  
                 END    FUNCTION  symetrique  
             END  MODULE  symmod  
le  mot  clé  CONTAINS  indique  que  la  fonc(on  symetrique  est  une  fonc(ons  interne  à  
l'unité  de  compila(on  (MODULE  symmod)  et  ainsi  le  type  point  n'a  pas  besoin  d'être  
déclaré  à  l'intérieur  de  la  fonc(on  symetrique.  
               
 
PROGRAM  exple_sym  
                   USE  typtmod  
                   USE  symmod  
                   IMPLICIT  NONE  
                   TYPE(point)      ::  a  =  point(3,2,0,5.),  b  
                   b  =  symetrique  (a)  
                   PRINT*,a,b  
             END  PROGRAM  exple_sym  
Noter  que  L'INTERFACE  d'une  fonc(on  (ou  d'une  prodédure)  n'est  pas  exigée  si  celle-­‐ci  
est  définie  dans  un  module.  
 
Exemple3.  Partage  des  données.  
   
             MODULE  tabmod  
                   IMPLICIT  NONE  
                   INTEGER,  PARAMETER            ::  n  =  10  
                   INTEGER,  DIMENSION  (n)    ::  T  
             END  MODULE  tab  
Voici  une  subrou(ne  qui  u(lise  ce  module  
   
             SUBROUTINE  init  
                   USE  tabmod  
                   IMPLICIT  NONE  
                   INTEGER        ::  I  
       
                   T=(/  (i,  i=1,n)  /)  
             END  SUBROUTINE  init  
Ce]e  subrou(ne  n'a  pas  d'argument,  mais  par  contre  le  tableau  T  est  connu  via  le  module  tabmod.  
   
             PROGRAM  exple_tab    
                   USE  tabmod  
                   IMPLICIT  NONE  
 
                   CALL  init  
                   PRINT*,T  
             END  PROGRAM  exple_tab  
D'une  maniére  générale,  le  seul  type  de  dépendance  soit  interdit  est  celui  où  un  module  s'appelle  lui-­‐même  
directement  ou  indirectement  :  A  u(lise  B  qui  u(lise  C  qui  u(lise  A.  
Les  procédures  génériques  (MODULE  PROCEDURE)  
Le  principe  est  de  regrouper  sous  un  seul  nom  (nom  générique  )  de  procédures  en  laissant  le  compilateur  
décider  de  la  bonne  procédure  à  appeler  en  fonc(on  du  type  des  arguments.  
Par  exemple,  on  propose  d'écrire  une  famille  de  sous-­‐procédures  dont  le  nom  générique  sera  AFFICHE  
des(nées  à  écrire  les  valeurs  de  leurs  arguments  de  type  en(er,  réel  ou  tableau.  
           MODULE  genemod  
                 IMPLICIT  NONE  
                 INTERFACE  affiche  
                           MODULE  PROCEDURE  aff_int,  aff_real,aff_tab  
                 END  INTERFACE  
                 CONTAINS  
                           SUBROUTINE  aff_integer(n)  
                                 integer,  intent(in)  ::  n  
                                 Print*,'en(er  :',  n  
                           END  SUBROUTINE  aff_integer  
                           SUBROUTINE  aff_real(r)  
                                 real,  intent(in)  ::  r  
                                 Print*,'reel  :',  r  
                           END  SUBROUTINE  aff_real  
                           SUBROUTINE  aff_tab(T)  
                                 real,  dimension(:),  intent(in)  ::  T  
                                 Print*,'tableau  :',  T  
                           END  SUBROUTINE  aff_tab  
           END  MODULE  genemod  
les  procédures  qu'on  appellera  sous  le  nom  generique  affiche  sont  affinteger,  
affreal  ou  arab.  Le  compilateur  choisira  d'appeler  la  subrou(ne  affinteger  si  
l'argument  de  la  subrou(ne  affiche  est  un  en(er.  Voici  un  programme  
d'u(lisa(on  de  ce  module  :  
             PROGRAM  imprime  
                   USE  genemod  
                   IMPLICIT  NONE  
                   integer  ::  n,i  
                   real        ::  x  
                   real,  dimension  (15)  ::  T1=(/  (25.*i,i  =  1,15)  \)  
   
                 n  =  25    
                 x  =  5.25  
                 CALL  affiche  (n)  
                 CALL  affiche  (x)  
                 CALL  affiche  (T1)  
           END  PROGRAM  imprime  
Selon  le  type  d'argument,  en(er,  réel  ou  tableau  l'interface  générique  choisit  
alors  d'exécuter  l'une  des  trois  subrou(ne  affinteger,  affreal  ou  arab  
Interface  Operator  
Considérons  l'instruc(on:  x  =  a  +  b  
le  même  symbole  +  peut  désigner  suivant  le  type  de  a  et  b  des  opéra(ons  différentes  :  
x  est  un  en(er  si  a  et  b  sont  des  en(ers  
x  est  un  réel  si  a  et  b  sont  des  réels  ou  a  en(er  et  b  réel  ...  
x  est  un  tableau  du  même  profil  que  a  si  a  et  b  sont  deux  tableaux  de  même  profil.  
L'opéra(on  +  (  -­‐,/  ou  *)  est  déjà  prédéfinie,  et  selon  le  type  des  opérandes  elle  fournit  
un  résultat  différent.  
Fortran  offre  la  possibilité  de  :  

•   donner  une  significa(on  à  tout  autre  symbole(+,  -­‐,  /,  *,...)  lorsqu'il  porte  sur  des  
types  différents  de  ceux  pour  lesquels  il  est  déjà  défini.  
         Exemple.  Interface  operator  (+)    
         Interface  operator  (-­‐)  
 
•   créer  de  nouveaux  opérateurs  de  la  forme  .op.  où  op  désigne  une  suite  
quelconque  de  caractères.  
         Exemple.  Interface  operator  (.SOMME.)  
Exemple  de  Surdéfini+on  de  l'opérateur  +  
Ce]e  technique  est  u(lisée  pour  doter  d'opérateurs  simples  des  types  dérivées,  afin  d'en  
simplifier  la  manipula(on.  
             MODULE    opplusmod  
                   IMPLICIT  NONE  
                   TYPE  point  
                         INTEGER  ::  num  
                         REAL        ::  x,y  
                   END  TYPE  point  
                   INTERFACE  OPERATOR(+)  
                         MODULE  PROCEDURE  point_plus_point,  point_plus_en(er  
                   END  INTERFACE  
                   CONTAINS  
   
                 FUNCTION    point_plus_point(  p1,  p2)  RESULT(ppp)  
                         TYPE(point),  INTENT(IN)  ::  p1,p2  
                         TYPE(point)                          ::  ppp  
               
                         ppp  =  point(p1%num+p2%num,  p1%x+p2%y,  p1%y+p2%y)  
                   END  FUNCTION    point_plus_point  
 
.  
 FUNCTION    point_plus_en(er(  p,  n)  RESULT(ppn)  
                         TYPE(point),  INTENT(in)  ::  p  
                         INTEGER        ,  INTENT(in)  ::  n    
                         TYPE(point)                          ::  ppn  
                         ppn  =  point(p%num+n,  p%x,  p%y)  
                 END  FUNCTION    point_plus_en(er  
           END  MODULE  opplusmod  
Ce  module  a  permis  de  définir  la  somme  de  deux  structures  comme  on  le  souhaite  par  
l'interface  operator  (+)  
 
Voici  un  exemple  d'u(lisa(on  de  ce  module  :  
             Program  operateur  
                   USE  opplusmod  
                   IMPLICIT  NONE  
                   TYPE(point)  ::  a,b,c  
   
                   a  =  point(3,  2.,  3.)    
                   b  =  point(2,  4.,  5.2)  
                   c  =  a+b    
                   PRINT*,'a+b  =',c  
                   PRINT*,'c+14  =',c+14  

Vous aimerez peut-être aussi