9. Common▲
9-1. L'instruction COMMON▲
L'instruction COMMON permet le regroupement de zones mémoire pouvant être partagées par différentes unités de programme (fonctions, procédures).
La syntaxe d'une instruction COMMON est la suivante :
COMMON [/[nom common]/] liste variablesLe COMMON est dit étiqueté si nom_common est précisé. S'il n'a pas de nom, on l'appelle COMMON blanc.
Les différentes zones regroupées au sein du bloc COMMONsont adressées via des variables dont les noms sont indiqués dans la partie liste_variables de l'instruction COMMON. Pour qu'une unité de programme ait accès à ces zones, il est nécessaire qu'elle contienne l'instruction COMMON les référençant.
9-2. Common blanc▲
Lors de la déclaration d'un COMMON blanc nom_common est omis et les deux slashes / sont alors optionnels. Ses particularités sont :
- un
COMMONblanc est permanent (il hérite de l'attributSAVE) ; -
les variables apparaissant dans un
COMMONblanc ne peuvent pas être initialisées lors de leur déclaration. Ce type de bloc est initialement constitué de bits à 0. En conséquence :- les données numériques sont initialisées à 0,
- les données logiques sont initialisées à la valeur
.FALSE., - les données de type chaîne de caractères représentent des chaînes vides ;
- un
COMMONblanc peut ne pas avoir la même taille d'une unité de programme à une autre, c'est alors la taille maximum qui sera retenue pour l'ensemble du programme.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
PROGRAM common_blanc
INTEGER :: i
INTEGER, DIMENSION(6) :: itab
LOGICAL, DIMENSION(3) :: ltab
COMMON itab,ltab
DO i=1,6
itab(i) = i
END DO
ltab(1) = .true.
ltab(2) = .false.
ltab(3) = .true.
CALL sub
END PROGRAM common_blanc
!*************************************
SUBROUTINE sub
INTEGER :: i
INTEGER, DIMENSION(6) :: itab
LOGICAL, DIMENSION(3) :: ltab
COMMON itab,ltab
PRINT*,'Tableau entier = ', itab
PRINT*,'Tableau logique = ', ltab
END SUBROUTINE sub
9-3. Common étiqueté▲
Un COMMON est dit étiqueté lorsque nom_common est précisé entre caractères /.
Ses particularités sont :
- il peut être initialisé par l'intermédiaire d'une unité de programme de type
BLOCKDATA; - un bloc
COMMONdéfini dans le programme principal reçoit implicitement l'attributSAVE. S'il ne l'est pas, l'attributSAVEest nécessaire si on désire le rendre permanent.
2.
3.
4.
INTEGER, DIMENSION(6) :: itab
REAL, DIMENSION(12) :: rtab
COMMON /TAB/itab, rtab
9-3-1. Initialisation : BLOCK DATA▲
BLOCK DATA est une unité de programme qui permet d'initialiser des objets déclarés dans des COMMONs étiquetés :
2.
3.
BLOCK DATA [nom_block_data]
[bloc init]
END BLOCK DATA [nom_block_data]
- nom_block_data est le nom du
BLOCKDATA; -
bloc_init est une suite :
- de déclarations de type (
INTEGER,REAL…), - de déclarations de zones communes (
COMMON), - d'initialisations statiques (
DATA).
- de déclarations de type (
Un bloc COMMON ne peut apparaître que dans un seul BLOCK DATA.
On peut se définir plusieurs unités BLOCK DATA, chacune regroupant les COMMON qui ont un lien logique entre eux.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
BLOCK DATA INIT
REAL :: A, B, C, D
REAL, DIMENSION(10,15) :: MATRICE
INTEGER, DIMENSION(20) :: VECTEUR
COMMON /BLOC1/ MATRICE, A, B
COMMON /BLOC2/ VECTEUR, C, D
DATA A /-1./, B /3.14/, C /0./, D /7.1/
DATA MATRICE /150 * 50.0/, VECTEUR /20 * 4/
END BLOCK DATA INIT
9-3-2. Instruction SAVE et COMMON▲
Les valeurs des variables d'un COMMON étiqueté deviennent indéfinies quand une procédure se termine (retour à l'unité appelante) sauf s'il existe une autre unité de programme active le référençant.
Le cas échéant, on lui appliquera l'instruction SAVE pour conserver son contenu :
SAVE /nom_common/- un
COMMONqui reçoit l'attributSAVEdans une fonction ou procédure devra toujours être déclaré avec ce même attribut dans toutes les autres unités de programme ; - il est inutile de spécifier l'attribut
SAVEsi leCOMMONa été déclaré dans le programme principal.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
PROGRAM common_save
call first
call second
END PROGRAM common_save
!*************************************
SUBROUTINE first
REAL, DIMENSION(6) :: rtab
LOGICAL :: drapeau
COMMON/BLOC/ rtab,drapeau
SAVE /BLOC/
CALL random_number(rtab)
PRINT*,'Afficher le tableau (true/false)'
READ(*,*) drapeau
END SUBROUTINE first
!*************************************
SUBROUTINE second
REAL, DIMENSION(6) :: rtab
LOGICAL :: drapeau
COMMON /BLOC/ rtab,drapeau
SAVE /BLOC/
IF (drapeau) PRINT*,'Tableau de réels = ', rtab
END SUBROUTINE second
9-4. Règles et restrictions▲
-
Un
COMMONne peut pas contenir :- les noms de procédures (sous-programmes, fonctions),
- les arguments de procédures,
- les constantes symboliques (ayant l'attribut
PARAMETER) ;
- une même variable ne peut pas apparaître dans 2
COMMONs de noms différents ; - la taille d'un bloc
COMMONétiqueté doit être la même dans chaque unité de programme le référençant ; - Fortran 90 permet désormais le mélange de données numériques et caractères au sein d'un bloc
COMMON; - d'une unité de programme à une autre, les variables de la liste peuvent porter des noms différents ;
- au sein d'une même unité de programme, un bloc
COMMON(étiqueté ou non) peut être référencé plusieurs fois : les différentes listes de variables sont alors ajoutées les unes aux autres ; - un bloc
COMMONpeut être découpé différemment d'une unité de programme à une autre, c'est-à-dire référencé à l'aide de variables de types différents à condition que ce découpage soit cohérent (les zones numériques doivent correspondre à des zones numériques et de même pour les zones caractères) ; -
une instruction
EQUIVALENCEne peut pas :- associer des variables déclarées dans des blocs
COMMONdifférents, - avoir pour effet de prolonger le
COMMONà sa gauche. Dans l'exemple suivant, on ne peut pas associer la variable scalaire A au scalaire B(2) :
- associer des variables déclarées dans des blocs
2.
3.
4.
5.
6.
REAL :: A
REAL, DIMENSION(2) :: B
COMMON /X/A
EQUIVALENCE (A,B(2)) ! INVALIDE
EQUIVALENCE (A,B(1)) ! VALIDE
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
program common_mixte
complex, dimension(10) :: c
character(len=100) :: chaine
COMMON/MIXTE/c, chaine
. . .
call sub
end program common_mixte
subroutine sub
real, dimension(20) :: tab_reels
character(len=1), dimension(100) :: tab_car
COMMON/MIXTE/tab_reels, tab_car
. . .
! impression des parties réelles
print *,tab_reels(1:20:2)
print *,tab_car(1), tab_car(10)
end subroutine sub
Recommandations :
- Il est préférable de déclarer un bloc
COMMONde la même façon dans les différentes unités de programme et donc d'employer la technique de l'exemple précédent avec modération ; - L'instruction
INCLUDEci-après favorise le bon emploi des blocsCOMMON.


