Fortran - Guide rapide

Fortran, dérivé de Formula Translating System, est un langage de programmation impératif à usage général. Il est utilisé pour le calcul numérique et scientifique.

Fortran a été initialement développé par IBM dans les années 1950 pour des applications scientifiques et d'ingénierie. Fortran a longtemps gouverné ce domaine de programmation et est devenu très populaire pour le calcul haute performance, car.

Il prend en charge -

  • Analyse numérique et calcul scientifique
  • Programmation structurée
  • Programmation par baie
  • Programmation modulaire
  • Programmation générique
  • Calcul haute performance sur supercalculateurs
  • Programmation orientée objet
  • Programmation simultanée
  • Degré raisonnable de portabilité entre les systèmes informatiques

Faits sur Fortran

  • Fortran a été créé par une équipe dirigée par John Backus chez IBM en 1957.

  • Au départ, le nom était écrit en majuscules, mais les normes et implémentations actuelles n'exigent que la première lettre en majuscule.

  • Fortran signifie FORmula TRANslator.

  • Développé à l'origine pour les calculs scientifiques, il avait un support très limité pour les chaînes de caractères et autres structures nécessaires à la programmation à usage général.

  • Les extensions et développements ultérieurs en ont fait un langage de programmation de haut niveau avec un bon degré de portabilité.

  • Les versions originales, Fortran I, II et III sont désormais considérées comme obsolètes.

  • La plus ancienne version encore utilisée est Fortran IV et Fortran 66.

  • Les versions les plus couramment utilisées aujourd'hui sont: Fortran 77, Fortran 90 et Fortran 95.

  • Fortran 77 a ajouté des chaînes comme type distinct.

  • Fortran 90 a ajouté divers types de threading et de traitement direct par matrice.

Configurer Fortran sous Windows

G95 est le compilateur multi-architecturale GNU Fortran, utilisé pour configurer Fortran sous Windows. La version Windows émule un environnement unix en utilisant MingW sous Windows. Le programme d'installation s'occupe de cela et ajoute automatiquement g95 à la variable PATH de Windows.

Vous pouvez obtenir la version stable de G95 d' ici

Comment utiliser G95

Pendant l'installation, g95est automatiquement ajouté à votre variable PATH si vous sélectionnez l'option «RECOMMANDÉ». Cela signifie que vous pouvez simplement ouvrir une nouvelle fenêtre d'invite de commandes et taper «g95» pour faire apparaître le compilateur. Trouvez quelques commandes de base ci-dessous pour vous aider à démarrer.

Sr.Non Commande et description
1

g95 –c hello.f90

Compile hello.f90 dans un fichier objet nommé hello.o

2

g95 hello.f90

Compile hello.f90 et le lie pour produire un exécutable a.out

3

g95 -c h1.f90 h2.f90 h3.f90

Compile plusieurs fichiers source. Si tout se passe bien, les fichiers objets h1.o, h2.o et h3.o sont créés

4

g95 -o hello h1.f90 h2.f90 h3.f90

Compile plusieurs fichiers sources et les lie ensemble à un fichier exécutable nommé «bonjour»

Options de ligne de commande pour G95

-c Compile only, do not run the linker.
-o Specify the name of the output file, either an object file or the executable.

Plusieurs fichiers source et objet peuvent être spécifiés à la fois. Les fichiers Fortran sont indiqués par des noms se terminant par ".f", ".F", ".for", ".FOR", ".f90", ".F90", ".f95", ".F95", ". f03 "et" .F03 ". Plusieurs fichiers source peuvent être spécifiés. Les fichiers objets peuvent également être spécifiés et seront liés pour former un fichier exécutable.

Un programme Fortran est constitué d'un ensemble d'unités de programme comme un programme principal, des modules et des sous-programmes ou procédures externes.

Chaque programme contient un programme principal et peut contenir ou non d'autres unités de programme. La syntaxe du programme principal est la suivante -

program program_name
implicit none      

! type declaration statements      
! executable statements  

end program program_name

Un programme simple à Fortran

Écrivons un programme qui ajoute deux nombres et imprime le résultat -

program addNumbers

! This simple program adds two numbers
   implicit none

! Type declarations
   real :: a, b, result

! Executable statements
   a = 12.0
   b = 15.0
   result = a + b
   print *, 'The total is ', result

end program addNumbers

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

The total is 27.0000000

Veuillez noter que -

  • Tous les programmes Fortran commencent par le mot-clé program et terminez par le mot-clé end program, suivi du nom du programme.

  • le implicit noneL'instruction permet au compilateur de vérifier que tous vos types de variables sont déclarés correctement. Vous devez toujours utiliserimplicit none au début de chaque programme.

  • Les commentaires dans Fortran commencent par le point d'exclamation (!), Car tous les caractères après cela (sauf dans une chaîne de caractères) sont ignorés par le compilateur.

  • le print * La commande affiche les données à l'écran.

  • L'indentation des lignes de code est une bonne pratique pour garder un programme lisible.

  • Fortran autorise les lettres majuscules et minuscules. Fortran est insensible à la casse, sauf pour les chaînes littérales.

Basiques

le basic character set de Fortran contient -

  • les lettres A ... Z et a ... z
  • les chiffres 0 ... 9
  • le caractère de soulignement (_)
  • les caractères spéciaux =: + vide - * / () [],. $ '! "% &; <>?

Tokenssont constitués de caractères du jeu de caractères de base. Un jeton peut être un mot-clé, un identifiant, une constante, une chaîne littérale ou un symbole.

Les instructions de programme sont constituées de jetons.

Identifiant

Un identificateur est un nom utilisé pour identifier une variable, une procédure ou tout autre élément défini par l'utilisateur. Un nom dans Fortran doit suivre les règles suivantes -

  • Il ne peut pas comporter plus de 31 caractères.

  • Il doit être composé de caractères alphanumériques (toutes les lettres de l'alphabet et les chiffres de 0 à 9) et de traits de soulignement (_).

  • Le premier caractère d'un nom doit être une lettre.

  • Les noms sont insensibles à la casse

Mots clés

Les mots clés sont des mots spéciaux, réservés à la langue. Ces mots réservés ne peuvent pas être utilisés comme identifiants ou noms.

Le tableau suivant répertorie les mots-clés Fortran -

Les mots-clés non E / S
attribuable allouer attribuer affectation bloquer les données
appel Cas personnage commun complexe
contient continuer cycle Les données désallouer
défaut faire double precision autre sinon si
autre part données de bloc de fin fin faire fonction de fin fin si
interface de fin module de fin programme de fin fin sélectionner fin du sous-programme
type d'extrémité fin où entrée équivalence sortie
externe fonction aller à si implicite
dans inout entier intention interface
intrinsèque gentil len logique module
liste de nom annuler seulement opérateur optionnel
en dehors paramètre pause aiguille privé
programme Publique réel récursif résultat
revenir enregistrer sélectionner le cas Arrêtez sous-programme
cible puis type type() utilisation
Tandis que
Les mots-clés liés aux E / S
retour arrière Fermer endfile format renseigner
ouvert impression lis rembobiner Écrire

Fortran fournit cinq types de données intrinsèques, mais vous pouvez également dériver vos propres types de données. Les cinq types intrinsèques sont -

  • Type entier
  • Type réel
  • Type complexe
  • Type logique
  • Type de caractère

Type entier

Les types entiers ne peuvent contenir que des valeurs entières. L'exemple suivant extrait la plus grande valeur qui peut être contenue dans un entier habituel de quatre octets -

program testingInt
implicit none

   integer :: largeval
   print *, huge(largeval)
   
end program testingInt

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

2147483647

Notez que le huge()La fonction donne le plus grand nombre que peut contenir le type de données entier spécifique. Vous pouvez également spécifier le nombre d'octets à l'aide dukindprescripteur. L'exemple suivant illustre ceci -

program testingInt
implicit none

   !two byte integer
   integer(kind = 2) :: shortval
   
   !four byte integer
   integer(kind = 4) :: longval
   
   !eight byte integer
   integer(kind = 8) :: verylongval
   
   !sixteen byte integer
   integer(kind = 16) :: veryverylongval
   
   !default integer 
   integer :: defval
        
   print *, huge(shortval)
   print *, huge(longval)
   print *, huge(verylongval)
   print *, huge(veryverylongval)
   print *, huge(defval)
   
end program testingInt

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647

Type réel

Il stocke les nombres à virgule flottante, tels que 2.0, 3.1415, -100.876, etc.

Traditionnellement, il existe deux types réels différents, la valeur par défaut real type et double precision type.

Cependant, Fortran 90/95 offre plus de contrôle sur la précision des types de données réels et entiers via le kind spécificateur, que nous étudierons dans le chapitre sur les nombres.

L'exemple suivant montre l'utilisation d'un type de données réel -

program division   
implicit none  

   ! Define real variables   
   real :: p, q, realRes 
   
   ! Define integer variables  
   integer :: i, j, intRes  
   
   ! Assigning  values   
   p = 2.0 
   q = 3.0    
   i = 2 
   j = 3  
   
   ! floating point division
   realRes = p/q  
   intRes = i/j
   
   print *, realRes
   print *, intRes
   
end program division

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

0.666666687    
0

Type complexe

Ceci est utilisé pour stocker des nombres complexes. Un nombre complexe comprend deux parties, la partie réelle et la partie imaginaire. Deux unités de stockage numériques consécutives stockent ces deux pièces.

Par exemple, le nombre complexe (3,0, -5,0) est égal à 3,0 - 5,0i

Nous discuterons plus en détail des types complexes dans le chapitre Nombres.

Type logique

Il n'y a que deux valeurs logiques: .true. et .false.

Type de caractère

Le type de caractère stocke des caractères et des chaînes. La longueur de la chaîne peut être spécifiée par le spécificateur len. Si aucune longueur n'est spécifiée, elle vaut 1.

For example,

character (len = 40) :: name  
name = “Zara Ali”

L'expression, name(1:4) donnerait la sous-chaîne «Zara».

Typage implicite

Les anciennes versions de Fortran permettaient une fonctionnalité appelée typage implicite, c'est-à-dire que vous n'avez pas à déclarer les variables avant utilisation. Si une variable n'est pas déclarée, la première lettre de son nom déterminera son type.

Les noms de variables commençant par i, j, k, l, m ou n sont considérés comme des variables entières et les autres sont des variables réelles. Cependant, vous devez déclarer toutes les variables car c'est une bonne pratique de programmation. Pour cela, vous démarrez votre programme avec la déclaration -

implicit none

Cette instruction désactive le typage implicite.

Une variable n'est rien d'autre qu'un nom donné à une zone de stockage que nos programmes peuvent manipuler. Chaque variable doit avoir un type spécifique, qui détermine la taille et la disposition de la mémoire de la variable; la plage de valeurs pouvant être stockées dans cette mémoire; et l'ensemble des opérations qui peuvent être appliquées à la variable.

Le nom d'une variable peut être composé de lettres, de chiffres et du caractère de soulignement. Un nom dans Fortran doit suivre les règles suivantes -

  • Il ne peut pas comporter plus de 31 caractères.

  • Il doit être composé de caractères alphanumériques (toutes les lettres de l'alphabet et les chiffres de 0 à 9) et de traits de soulignement (_).

  • Le premier caractère d'un nom doit être une lettre.

  • Les noms ne sont pas sensibles à la casse.

Sur la base des types de base expliqués dans le chapitre précédent, voici les types de variables -

Sr.Non Type et description
1

Integer

Il ne peut contenir que des valeurs entières.

2

Real

Il stocke les nombres à virgule flottante.

3

Complex

Il est utilisé pour stocker des nombres complexes.

4

Logical

Il stocke des valeurs booléennes logiques.

5

Character

Il stocke des caractères ou des chaînes.

Déclaration de variable

Les variables sont déclarées au début d'un programme (ou sous-programme) dans une instruction de déclaration de type.

La syntaxe de la déclaration de variable est la suivante -

type-specifier :: variable_name

Par exemple

integer :: total  	
real :: average 
complex :: cx  
logical :: done 
character(len = 80) :: message ! a string of 80 characters

Plus tard, vous pouvez attribuer des valeurs à ces variables, comme,

total = 20000  
average = 1666.67   
done = .true.   
message = “A big Hello from Tutorials Point” 
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i

Vous pouvez également utiliser la fonction intrinsèque cmplx, pour affecter des valeurs à une variable complexe -

cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i 
cx = cmplx (x, y) ! cx = x + yi

Exemple

L'exemple suivant illustre la déclaration, l'affectation et l'affichage des variables à l'écran -

program variableTesting
implicit none

   ! declaring variables
   integer :: total      
   real :: average 
   complex :: cx  
   logical :: done 
   character(len=80) :: message ! a string of 80 characters
   
   !assigning values
   total = 20000  
   average = 1666.67   
   done = .true.   
   message = "A big Hello from Tutorials Point" 
   cx = (3.0, 5.0) ! cx = 3.0 + 5.0i

   Print *, total
   Print *, average
   Print *, cx
   Print *, done
   Print *, message
   
end program variableTesting

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

20000
1666.67004    
(3.00000000, 5.00000000 )
T
A big Hello from Tutorials Point

Les constantes font référence aux valeurs fixes que le programme ne peut pas modifier lors de son exécution. Ces valeurs fixes sont également appeléesliterals.

Les constantes peuvent être de l'un des types de données de base comme une constante entière, une constante flottante, une constante de caractère, une constante complexe ou une chaîne littérale. Il n'y a que deux constantes logiques:.true. et .false.

Les constantes sont traitées comme des variables régulières, sauf que leurs valeurs ne peuvent pas être modifiées après leur définition.

Constantes et littéraux nommés

Il existe deux types de constantes -

  • Constantes littérales
  • Constantes nommées

Une constante littérale a une valeur, mais pas de nom.

Par exemple, voici les constantes littérales -

Type Exemple
Constantes entières 0 1 -1 300 123456789
Constantes réelles 0,0 1,0 -1,0 123,456 7,1E + 10-52,715E-30
Constantes complexes (0,0, 0,0) (-123,456E + 30, 987,654E-29)
Constantes logiques .vrai. .faux.
Constantes de caractère

"PQR" "a" "123'abc $% # @!"

" une citation "" "

'PQR' 'a' '123 "abc $% # @!'

'une apostrophe' ''

Une constante nommée a une valeur ainsi qu'un nom.

Les constantes nommées doivent être déclarées au début d'un programme ou d'une procédure, tout comme une déclaration de type de variable, en indiquant son nom et son type. Les constantes nommées sont déclarées avec l'attribut de paramètre. Par exemple,

real, parameter :: pi = 3.1415927

Exemple

Le programme suivant calcule le déplacement dû au mouvement vertical sous gravité.

program gravitationalDisp

! this program calculates vertical motion under gravity 
implicit none  

   ! gravitational acceleration
   real, parameter :: g = 9.81   
   
   ! variable declaration
   real :: s ! displacement   
   real :: t ! time  
   real :: u ! initial speed  
   
   ! assigning values 
   t = 5.0   
   u = 50  
   
   ! displacement   
   s = u * t - g * (t**2) / 2  
   
   ! output 
   print *, "Time = ", t
   print *, 'Displacement = ',s  
   
end program gravitationalDisp

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Time = 5.00000000    
Displacement = 127.374992

Un opérateur est un symbole qui indique au compilateur d'effectuer des manipulations mathématiques ou logiques spécifiques. Fortran propose les types d'opérateurs suivants -

  • Opérateurs arithmétiques
  • Opérateurs relationnels
  • Opérateurs logiques

Examinons tous ces types d'opérateurs un par un.

Opérateurs arithmétiques

Le tableau suivant présente tous les opérateurs arithmétiques pris en charge par Fortran. Supposons une variableA détient 5 et variable B détient 3 alors -

Afficher des exemples

Opérateur La description Exemple
+ Opérateur d'addition, ajoute deux opérandes. A + B donnera 8
- Opérateur de soustraction, soustrait le deuxième opérande du premier. A - B donnera 2
* Opérateur de multiplication, multiplie les deux opérandes. A * B donnera 15
/ Opérateur de division, divise le numérateur par le de-numérateur. A / B donnera 1
** Opérateur d'exponentiation, élève un opérande à la puissance de l'autre. A ** B donnera 125

Opérateurs relationnels

Le tableau suivant présente tous les opérateurs relationnels supportés par Fortran. Supposons une variableA détient 10 et variable B détient 20, alors -

Afficher des exemples

Opérateur Équivalent La description Exemple
== .eq. Vérifie si les valeurs de deux opérandes sont égales ou non, si oui, la condition devient vraie. (A == B) n'est pas vrai.
/ = .ne. Vérifie si les valeurs de deux opérandes sont égales ou non, si les valeurs ne sont pas égales, la condition devient vraie. (A! = B) est vrai.
> .gt. Vérifie si la valeur de l'opérande gauche est supérieure à la valeur de l'opérande droit, si oui, la condition devient vraie. (A> B) n'est pas vrai.
< .lt. Vérifie si la valeur de l'opérande gauche est inférieure à la valeur de l'opérande droit, si oui, la condition devient vraie. (A <B) est vrai.
> = .ge. Vérifie si la valeur de l'opérande gauche est supérieure ou égale à la valeur de l'opérande droit, si oui, la condition devient vraie. (A> = B) n'est pas vrai.
<= .le. Vérifie si la valeur de l'opérande gauche est inférieure ou égale à la valeur de l'opérande droit, si oui, la condition devient vraie. (A <= B) est vrai.

Opérateurs logiques

Les opérateurs logiques de Fortran ne fonctionnent que sur des valeurs logiques .true. et .false.

Le tableau suivant présente tous les opérateurs logiques pris en charge par Fortran. Supposons que la variable A contienne .true. et la variable B vaut .false. , alors -

Afficher des exemples

Opérateur La description Exemple
.et. Opérateur logique ET appelé. Si les deux opérandes sont différents de zéro, la condition devient vraie. (A. Et. B) est faux.
.ou. Opérateur OU logique appelé. Si l'un des deux opérandes est différent de zéro, la condition devient vraie. (A. Ou. B) est vrai.
.ne pas. Opérateur PAS logique appelé. Utilisez pour inverser l'état logique de son opérande. Si une condition est vraie, l'opérateur NOT logique rendra faux. ! (A. Et. B) est vrai.
.eqv. Appelé opérateur EQUIVALENT logique. Utilisé pour vérifier l'équivalence de deux valeurs logiques. (A .eqv. B) est faux.
.neqv. Opérateur logique NON-ÉQUIVALENT appelé. Utilisé pour vérifier la non-équivalence de deux valeurs logiques. (A .neqv. B) est vrai.

Priorité des opérateurs à Fortran

La priorité des opérateurs détermine le regroupement des termes dans une expression. Cela affecte la manière dont une expression est évaluée. Certains opérateurs ont une priorité plus élevée que d'autres; par exemple, l'opérateur de multiplication a une priorité plus élevée que l'opérateur d'addition.

Par exemple, x = 7 + 3 * 2; ici, x est attribué à 13, et non à 20 car l'opérateur * a une priorité plus élevée que +, il est donc d'abord multiplié par 3 * 2, puis ajouté en 7.

Ici, les opérateurs avec la priorité la plus élevée apparaissent en haut du tableau, ceux avec la priorité la plus basse apparaissent en bas. Dans une expression, les opérateurs de priorité supérieure seront évalués en premier.

Afficher des exemples

Catégorie Opérateur Associativité
NON logique et signe négatif .ne pas. (-) De gauche à droite
Exponentiation ** De gauche à droite
Multiplicatif * / De gauche à droite
Additif + - De gauche à droite
Relationnel <<=>> = De gauche à droite
Égalité == / = De gauche à droite
ET logique .et. De gauche à droite
OU logique .ou. De gauche à droite
Affectation = De droite à gauche

Les structures de prise de décision exigent que le programmeur spécifie une ou plusieurs conditions à évaluer ou à tester par le programme, ainsi qu'une ou plusieurs instructions à exécuter, si la condition est jugée vraie, et éventuellement d'autres instructions à exécuter si le condition est considérée comme fausse.

Voici la forme générale d'une structure de prise de décision typique trouvée dans la plupart des langages de programmation -

Fortran fournit les types suivants de constructions de prise de décision.

Sr.Non Déclaration et description
1 Si… alors construisez

Un if… then… end if instruction se compose d'une expression logique suivie d'une ou plusieurs instructions.

2 Si ... alors ... else construit

Un if… then l'instruction peut être suivie d'une instruction facultative else statement, qui s'exécute lorsque l'expression logique est fausse.

3 if ... else if ... else Déclaration

Un if La construction d'instruction peut avoir un ou plusieurs else-ifconstructions. Quand leif la condition échoue, le suivi immédiatement else-ifest exécuté. Quand leelse-if échoue aussi, son successeur else-if instruction (le cas échéant) est exécutée, et ainsi de suite.

4 imbriqué si construction

Vous pouvez en utiliser un if ou else if déclaration dans un autre if ou else if déclaration (s).

5 sélectionner la construction de cas

UNE select case L'instruction permet à une variable d'être testée pour l'égalité par rapport à une liste de valeurs.

6 construction de cas de sélection imbriquée

Vous pouvez en utiliser un select case déclaration dans un autre select case déclaration (s).

Il peut arriver que vous deviez exécuter un bloc de code plusieurs fois. En général, les instructions sont exécutées de manière séquentielle: la première instruction d'une fonction est exécutée en premier, suivie de la seconde, et ainsi de suite.

Les langages de programmation fournissent diverses structures de contrôle qui permettent des chemins d'exécution plus compliqués.

Une instruction de boucle nous permet d'exécuter une instruction ou un groupe d'instructions plusieurs fois et voici la forme générale d'une instruction de boucle dans la plupart des langages de programmation -

Fortran fournit les types suivants de constructions de boucle pour gérer les exigences de boucle. Cliquez sur les liens suivants pour vérifier leurs détails.

Sr.Non Type de boucle et description
1 faire une boucle

Cette construction permet à une instruction, ou à une série d'instructions, d'être exécutée de manière itérative, alors qu'une condition donnée est vraie.

2 faire une boucle while

Répète une instruction ou un groupe d'instructions tant qu'une condition donnée est vraie. Il teste la condition avant d'exécuter le corps de la boucle.

3 boucles imbriquées

Vous pouvez utiliser une ou plusieurs constructions de boucle dans n'importe quelle autre construction de boucle.

Déclarations de contrôle de boucle

Les instructions de contrôle de boucle modifient l'exécution de sa séquence normale. Lorsque l'exécution quitte une étendue, tous les objets automatiques qui ont été créés dans cette étendue sont détruits.

Fortran prend en charge les instructions de contrôle suivantes. Cliquez sur les liens suivants pour vérifier leurs détails.

Sr.Non Déclaration de contrôle et description
1 sortie

Si l'instruction exit est exécutée, la boucle est quittée et l'exécution du programme se poursuit à la première instruction exécutable après l'instruction end do.

2 cycle

Si une instruction de cycle est exécutée, le programme continue au début de l'itération suivante.

3 Arrêtez

Si vous souhaitez que l'exécution de votre programme s'arrête, vous pouvez insérer une instruction stop

Les nombres dans Fortran sont représentés par trois types de données intrinsèques -

  • Type entier
  • Type réel
  • Type complexe

Type entier

Les types entiers ne peuvent contenir que des valeurs entières. L'exemple suivant extrait la plus grande valeur qui pourrait être contenue dans un entier habituel de quatre octets -

program testingInt
implicit none

   integer :: largeval
   print *, huge(largeval)
   
end program testingInt

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

2147483647

Veuillez noter que le huge()La fonction donne le plus grand nombre que peut contenir le type de données entier spécifique. Vous pouvez également spécifier le nombre d'octets à l'aide dukindprescripteur. L'exemple suivant illustre ceci -

program testingInt
implicit none

   !two byte integer
   integer(kind = 2) :: shortval
   
   !four byte integer
   integer(kind = 4) :: longval
   
   !eight byte integer
   integer(kind = 8) :: verylongval
   
   !sixteen byte integer
   integer(kind = 16) :: veryverylongval
   
   !default integer 
   integer :: defval
        
   print *, huge(shortval)
   print *, huge(longval)
   print *, huge(verylongval)
   print *, huge(veryverylongval)
   print *, huge(defval)
   
end program testingInt

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647

Type réel

Il stocke les nombres à virgule flottante, tels que 2.0, 3.1415, -100.876, etc.

Traditionnellement, il y avait deux real types: le type réel par défaut et double precision type.

Cependant, Fortran 90/95 offre plus de contrôle sur la précision des types de données réels et entiers via le kind prescripteur, que nous étudierons sous peu.

L'exemple suivant montre l'utilisation d'un type de données réel -

program division   
implicit none

   ! Define real variables   
   real :: p, q, realRes 
   
   ! Define integer variables  
   integer :: i, j, intRes  
   
   ! Assigning  values   
   p = 2.0 
   q = 3.0    
   i = 2 
   j = 3  
   
   ! floating point division
   realRes = p/q  
   intRes = i/j
   
   print *, realRes
   print *, intRes
   
end program division

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

0.666666687    
0

Type complexe

Ceci est utilisé pour stocker des nombres complexes. Un nombre complexe comprend deux parties: la partie réelle et la partie imaginaire. Deux unités de stockage numériques consécutives stockent ces deux pièces.

Par exemple, le nombre complexe (3,0, -5,0) est égal à 3,0 - 5,0i

La fonction générique cmplx()crée un nombre complexe. Il produit un résultat dont les parties réelles et imaginaires sont en simple précision, quel que soit le type des arguments d'entrée.

program createComplex
implicit none

   integer :: i = 10
   real :: x = 5.17
   print *, cmplx(i, x)
   
end program createComplex

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

(10.0000000, 5.17000008)

Le programme suivant démontre l'arithmétique des nombres complexes -

program ComplexArithmatic
implicit none

   complex, parameter :: i = (0, 1)   ! sqrt(-1)   
   complex :: x, y, z 
   
   x = (7, 8); 
   y = (5, -7)   
   write(*,*) i * x * y
   
   z = x + y
   print *, "z = x + y = ", z
   
   z = x - y
   print *, "z = x - y = ", z 
   
   z = x * y
   print *, "z = x * y = ", z 
   
   z = x / y
   print *, "z = x / y = ", z 
   
end program ComplexArithmatic

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)

La gamme, la précision et la taille des nombres

La plage des nombres entiers, la précision et la taille des nombres à virgule flottante dépendent du nombre de bits alloués au type de données spécifique.

Le tableau suivant affiche le nombre de bits et la plage des nombres entiers -

Nombre de bits Valeur maximum Raison
64 9 223 372 036 854 774 807 (2 ** 63) –1
32 2 147 483 647 (2 ** 31) –1

Le tableau suivant affiche le nombre de bits, la valeur la plus petite et la plus grande et la précision des nombres réels.

Nombre de bits La plus grande valeur La plus petite valeur Précision
64 0,8E + 308 0,5E – 308 15 à 18
32 1,7E + 38 0,3E – 38 6-9

Les exemples suivants le démontrent -

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e+40
   y = 3.73e+40
   z = x * y 
   print *, z
   
end program rangePrecision

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

x = 1.5e+40
          1
Error : Real constant overflows its kind at (1)
main.f95:5.12:

y = 3.73e+40
           1
Error : Real constant overflows its kind at (1)

Utilisons maintenant un nombre plus petit -

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e+20
   y = 3.73e+20
   z = x * y 
   print *, z
   
   z = x/y
   print *, z
   
end program rangePrecision

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Infinity
0.402144760

Maintenant regardons le sous-flux -

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e-30
   y = 3.73e-60
   z = x * y 
   print *, z
   
   z = x/y
   print *, z

end program rangePrecision

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

y = 3.73e-60
           1
Warning : Real constant underflows its kind at (1)

Executing the program....
$demo 

0.00000000E+00
Infinity

Le spécificateur aimable

En programmation scientifique, il est souvent nécessaire de connaître la portée et la précision des données de la plate-forme matérielle sur laquelle le travail est effectué.

La fonction intrinsèque kind() vous permet d'interroger les détails des représentations de données du matériel avant d'exécuter un programme.

program kindCheck
implicit none
   
   integer :: i 
   real :: r 
   complex :: cp 
   print *,' Integer ', kind(i) 
   print *,' Real ', kind(r) 
   print *,' Complex ', kind(cp) 
   
end program kindCheck

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Integer 4
Real 4
Complex 4

Vous pouvez également vérifier le type de tous les types de données -

program checkKind
implicit none

   integer :: i 
   real :: r 
   character :: c 
   logical :: lg 
   complex :: cp 
   
   print *,' Integer ', kind(i) 
   print *,' Real ', kind(r) 
   print *,' Complex ', kind(cp)
   print *,' Character ', kind(c) 
   print *,' Logical ', kind(lg)
   
end program checkKind

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Integer 4
Real 4
Complex 4
Character 1
Logical 4

Le langage Fortran peut traiter les caractères comme des caractères uniques ou des chaînes contiguës.

Les caractères peuvent être n'importe quel symbole tiré du jeu de caractères de base, c'est-à-dire des lettres, des chiffres décimaux, du trait de soulignement et 21 caractères spéciaux.

Une constante de caractère est une chaîne de caractères à valeur fixe.

Le type de données intrinsèque characterstocke des caractères et des chaînes. La longueur de la chaîne peut être spécifiée parlenprescripteur. Si aucune longueur n'est spécifiée, elle est 1. Vous pouvez faire référence à des caractères individuels dans une chaîne faisant référence par position; le caractère le plus à gauche est en position 1.

Déclaration de caractère

La déclaration d'une donnée de type caractère est la même que les autres variables -

type-specifier :: variable_name

Par exemple,

character :: reply, sex

vous pouvez attribuer une valeur comme,

reply = ‘N’ 
sex = ‘F’

L'exemple suivant illustre la déclaration et l'utilisation du type de données caractère -

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 25)::greetings
   
   title = 'Mr. ' 
   firstname = 'Rowan ' 
   surname = 'Atkinson'
   greetings = 'A big hello from Mr. Bean'
   
   print *, 'Here is ', title, firstname, surname
   print *, greetings
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here is Mr. Rowan Atkinson       
A big hello from Mr. Bean

Concaténation de caractères

L'opérateur de concaténation //, concatène les caractères.

L'exemple suivant illustre ceci -

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 40):: name
   character(len = 25)::greetings
   
   title = 'Mr. ' 
   firstname = 'Rowan ' 
   surname = 'Atkinson'
   
   name = title//firstname//surname
   greetings = 'A big hello from Mr. Bean'
   
   print *, 'Here is ', name
   print *, greetings
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here is Mr.Rowan Atkinson       
A big hello from Mr.Bean

Quelques fonctions de caractère

Le tableau suivant montre quelques fonctions de caractères couramment utilisées avec la description -

Sr.Non Description de la fonction
1

len(string)

Il renvoie la longueur d'une chaîne de caractères

2

index(string,sustring)

Il trouve l'emplacement d'une sous-chaîne dans une autre chaîne, renvoie 0 s'il n'est pas trouvé.

3

achar(int)

Il convertit un entier en caractère

4

iachar(c)

Il convertit un caractère en un entier

5

trim(string)

Il renvoie la chaîne avec les blancs de fin supprimés.

6

scan(string, chars)

Il recherche la "chaîne" de gauche à droite (à moins que back = .true.) Pour la première occurrence de tout caractère contenu dans "chars". Il renvoie un entier donnant la position de ce caractère, ou zéro si aucun des caractères de "chars" n'a été trouvé.

sept

verify(string, chars)

Il scanne la "chaîne" de gauche à droite (à moins que back = .true.) Pour la première occurrence de tout caractère non contenu dans "chars". Il renvoie un entier donnant la position de ce caractère, ou zéro si seuls les caractères de "chars" ont été trouvés

8

adjustl(string)

Il à gauche justifie les caractères contenus dans la "chaîne"

9

adjustr(string)

Il justifie à droite les caractères contenus dans la "chaîne"

dix

len_trim(string)

Il renvoie un entier égal à la longueur de "string" (len (string)) moins le nombre de blancs de fin

11

repeat(string,ncopy)

Il renvoie une chaîne de longueur égale à "ncopy" multipliée par la longueur de "string" et contenant "ncopy" des copies concaténées de "string"

Exemple 1

Cet exemple montre l'utilisation du index fonction -

program testingChars
implicit none

   character (80) :: text 
   integer :: i 
   
   text = 'The intrinsic data type character stores characters and   strings.'
   i=index(text,'character') 
   
   if (i /= 0) then
      print *, ' The word character found at position ',i 
      print *, ' in text: ', text 
   end if
   
end program testingChars

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

The word character found at position 25
in text : The intrinsic data type character stores characters and strings.

Exemple 2

Cet exemple illustre l'utilisation du trim fonction -

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 25)::greetings
   
   title = 'Mr.' 
   firstname = 'Rowan' 
   surname = 'Atkinson'
   
   print *, 'Here is', title, firstname, surname
   print *, 'Here is', trim(title),' ',trim(firstname),' ', trim(surname)
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here isMr.   Rowan          Atkinson       
 Here isMr. Rowan Atkinson

Exemple 3

Cet exemple illustre l'utilisation de achar fonction -

program testingChars
implicit none

   character:: ch
   integer:: i
   
   do i = 65, 90
      ch = achar(i)
      print*, i, ' ', ch
   end do
   
end program testingChars

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

65  A
66  B
67  C
68  D
69  E
70  F
71  G
72  H
73  I
74  J
75  K
76  L
77  M
78  N
79  O
80  P
81  Q
82  R
83  S
84  T
85  U
86  V
87  W
88  X
89  Y
90  Z

Vérification de l'ordre lexical des caractères

Les fonctions suivantes déterminent la séquence lexicale des caractères -

Sr.Non Description de la fonction
1

lle(char, char)

Compare si le premier caractère est lexicalement inférieur ou égal au second

2

lge(char, char)

Compare si le premier caractère est lexicalement supérieur ou égal au second

3

lgt(char, char)

Compare si le premier caractère est lexicalement plus grand que le second

4

llt(char, char)

Compare si le premier caractère est lexicalement inférieur au second

Example 4

La fonction suivante montre l'utilisation -

program testingChars
implicit none

   character:: a, b, c
   a = 'A'
   b = 'a'
   c = 'B'
   
   if(lgt(a,b)) then
      print *, 'A is lexically greater than a'
   else
      print *, 'a is lexically greater than A'
   end if
   
   if(lgt(a,c)) then
      print *, 'A is lexically greater than B'
   else
      print *, 'B is lexically greater than A'
   end if  
   
   if(llt(a,b)) then
      print *, 'A is lexically less than a'
   end if
   
   if(llt(a,c)) then
      print *, 'A is lexically less than B'
   end if
   
end program testingChars

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

a is lexically greater than A
B is lexically greater than A
A is lexically less than a
A is lexically less than B

Le langage Fortran peut traiter les caractères comme des caractères uniques ou des chaînes contiguës.

Une chaîne de caractères peut ne comporter qu'un seul caractère, ou même être de longueur nulle. Dans Fortran, les constantes de caractères sont données entre une paire de guillemets doubles ou simples.

Le type de données intrinsèque characterstocke des caractères et des chaînes. La longueur de la chaîne peut être spécifiée parlen specifier. Si aucune longueur n'est spécifiée, elle est 1. Vous pouvez faire référence à des caractères individuels dans une chaîne faisant référence par position; le caractère le plus à gauche est en position 1.

Déclaration de chaîne

La déclaration d'une chaîne est la même que les autres variables -

type-specifier :: variable_name

Par exemple,

Character(len = 20) :: firstname, surname

vous pouvez attribuer une valeur comme,

character (len = 40) :: name  
name = “Zara Ali”

L'exemple suivant illustre la déclaration et l'utilisation du type de données caractère -

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 25)::greetings
   
   title = 'Mr.' 
   firstname = 'Rowan' 
   surname = 'Atkinson'
   greetings = 'A big hello from Mr. Beans'
   
   print *, 'Here is', title, firstname, surname
   print *, greetings
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here isMr.   Rowan          Atkinson       
A big hello from Mr. Bean

Concaténation de chaînes

L'opérateur de concaténation //, concatène les chaînes.

L'exemple suivant illustre ceci -

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 40):: name
   character(len = 25)::greetings
   
   title = 'Mr.' 
   firstname = 'Rowan' 
   surname = 'Atkinson'
   
   name = title//firstname//surname
   greetings = 'A big hello from Mr. Beans'
   
   print *, 'Here is', name
   print *, greetings
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here is Mr. Rowan Atkinson       
A big hello from Mr. Bean

Extraction de sous-chaînes

Dans Fortran, vous pouvez extraire une sous-chaîne d'une chaîne en indexant la chaîne, en donnant l'index de début et de fin de la sous-chaîne dans une paire de crochets. C'est ce qu'on appelle le spécificateur d'étendue.

L'exemple suivant montre comment extraire la sous-chaîne 'world' de la chaîne 'hello world' -

program subString

   character(len = 11)::hello
   hello = "Hello World"
   print*, hello(7:11)
   
end program subString

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

World

Exemple

L'exemple suivant utilise le date_and_timefonction pour donner la chaîne de date et d'heure. Nous utilisons des spécificateurs d'étendue pour extraire séparément les informations sur l'année, la date, le mois, l'heure, les minutes et la seconde.

program  datetime
implicit none

   character(len = 8) :: dateinfo ! ccyymmdd
   character(len = 4) :: year, month*2, day*2

   character(len = 10) :: timeinfo ! hhmmss.sss
   character(len = 2)  :: hour, minute, second*6

   call  date_and_time(dateinfo, timeinfo)

   !  let’s break dateinfo into year, month and day.
   !  dateinfo has a form of ccyymmdd, where cc = century, yy = year
   !  mm = month and dd = day

   year  = dateinfo(1:4)
   month = dateinfo(5:6)
   day   = dateinfo(7:8)

   print*, 'Date String:', dateinfo
   print*, 'Year:', year
   print *,'Month:', month
   print *,'Day:', day

   !  let’s break timeinfo into hour, minute and second.
   !  timeinfo has a form of hhmmss.sss, where h = hour, m = minute
   !  and s = second

   hour   = timeinfo(1:2)
   minute = timeinfo(3:4)
   second = timeinfo(5:10)

   print*, 'Time String:', timeinfo
   print*, 'Hour:', hour
   print*, 'Minute:', minute
   print*, 'Second:', second   
   
end program  datetime

Lorsque vous compilez et exécutez le programme ci-dessus, il donne des informations détaillées sur la date et l'heure -

Date String: 20140803
Year: 2014
Month: 08
Day: 03
Time String: 075835.466
Hour: 07
Minute: 58
Second: 35.466

Couper les chaînes

le trim function takes a string, and returns the input string after removing all trailing blanks.

Example

program trimString
implicit none

   character (len = *), parameter :: fname="Susanne", sname="Rizwan"
   character (len = 20) :: fullname 
   
   fullname = fname//" "//sname !concatenating the strings
   
   print*,fullname,", the beautiful dancer from the east!"
   print*,trim(fullname),", the beautiful dancer from the east!"
   
end program trimString

When you compile and execute the above program it produces the following result −

Susanne Rizwan      , the beautiful dancer from the east!
 Susanne Rizwan, the beautiful dancer from the east!

Left and Right Adjustment of Strings

The function adjustl takes a string and returns it by removing the leading blanks and appending them as trailing blanks.

The function adjustr takes a string and returns it by removing the trailing blanks and appending them as leading blanks.

Example

program hello
implicit none

   character(len = 15) :: surname, firstname 
   character(len = 6) :: title 
   character(len = 40):: name
   character(len = 25):: greetings
   
   title = 'Mr. ' 
   firstname = 'Rowan' 
   surname = 'Atkinson'
   greetings = 'A big hello from Mr. Beans'
   
   name = adjustl(title)//adjustl(firstname)//adjustl(surname)
   print *, 'Here is', name
   print *, greetings
   
   name = adjustr(title)//adjustr(firstname)//adjustr(surname)
   print *, 'Here is', name
   print *, greetings
   
   name = trim(title)//trim(firstname)//trim(surname)
   print *, 'Here is', name
   print *, greetings
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Here is Mr. Rowan  Atkinson           
A big hello from Mr. Bean
Here is Mr. Rowan Atkinson    
A big hello from Mr. Bean
Here is Mr.RowanAtkinson                        
A big hello from Mr. Bean

Recherche d'une sous-chaîne dans une chaîne

La fonction index prend deux chaînes et vérifie si la deuxième chaîne est une sous-chaîne de la première chaîne. Si le deuxième argument est une sous-chaîne du premier argument, alors il retourne un entier qui est l'index de départ de la deuxième chaîne de la première chaîne, sinon il retourne zéro.

Exemple

program hello
implicit none

   character(len=30) :: myString
   character(len=10) :: testString
   
   myString = 'This is a test'
   testString = 'test'
   
   if(index(myString, testString) == 0)then
      print *, 'test is not found'
   else
      print *, 'test is found at index: ', index(myString, testString)
   end if
   
end program hello

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

test is found at index: 11

Les tableaux peuvent stocker une collection séquentielle de taille fixe d'éléments du même type. Un tableau est utilisé pour stocker une collection de données, mais il est souvent plus utile de considérer un tableau comme une collection de variables du même type.

Tous les tableaux sont constitués d'emplacements de mémoire contigus. L'adresse la plus basse correspond au premier élément et l'adresse la plus élevée au dernier élément.

Numéros (1) Numéros (2) Numéros (3) Numéros (4)

Les tableaux peuvent être unidimensionnels (comme des vecteurs), bidimensionnels (comme des matrices) et Fortran vous permet de créer jusqu'à 7 tableaux de dimensions.

Déclaration de tableaux

Les tableaux sont déclarés avec le dimension attribut.

Par exemple, pour déclarer un tableau à une dimension nommé nombre, de nombres réels contenant 5 éléments, vous écrivez,

real, dimension(5) :: numbers

Les éléments individuels des tableaux sont référencés en spécifiant leurs indices. Le premier élément d'un tableau a un indice de un. Le tableau des nombres contient cinq variables réelles: les nombres (1), les nombres (2), les nombres (3), les nombres (4) et les nombres (5).

Pour créer un tableau bidimensionnel 5 x 5 d'entiers nommé matrice, vous écrivez -

integer, dimension (5,5) :: matrix

Vous pouvez également déclarer un tableau avec une limite inférieure explicite, par exemple -

real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix

Attribution de valeurs

Vous pouvez attribuer des valeurs à des membres individuels, comme,

numbers(1) = 2.0

ou, vous pouvez utiliser une boucle,

do i  =1,5
   numbers(i) = i * 2.0
end do

Les éléments de tableau unidimensionnel peuvent être directement affectés à des valeurs à l'aide d'un symbole abrégé, appelé constructeur de tableau, comme,

numbers = (/1.5, 3.2,4.5,0.9,7.2 /)

please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’

Exemple

L'exemple suivant illustre les concepts décrits ci-dessus.

program arrayProg

   real :: numbers(5) !one dimensional integer array
   integer :: matrix(3,3), i , j !two dimensional real array
   
   !assigning some values to the array numbers
   do i=1,5
      numbers(i) = i * 2.0
   end do
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
   !assigning some values to the array matrix
   do i=1,3
      do j = 1, 3
         matrix(i, j) = i+j
      end do
   end do
   
   !display the values
   do i=1,3
      do j = 1, 3
         Print *, matrix(i,j)
      end do
   end do
   
   !short hand assignment
   numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
end program arrayProg

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

2.00000000    
 4.00000000    
 6.00000000    
 8.00000000    
 10.0000000    
         2
         3
         4
         3
         4
         5
         4
         5
         6
 1.50000000    
 3.20000005    
 4.50000000    
0.899999976    
 7.19999981

Quelques termes relatifs aux baies

Le tableau suivant donne quelques termes relatifs aux tableaux -

Terme Sens
Rang C'est le nombre de dimensions d'un tableau. Par exemple, pour le tableau nommé matrice, le rang est 2 et pour le tableau nommé nombres, le rang est 1.
Le degré C'est le nombre d'éléments le long d'une dimension. Par exemple, les numéros de tableau ont une étendue 5 et le tableau nommé matrice a une étendue 3 dans les deux dimensions.
Forme La forme d'un tableau est un tableau d'entiers à une dimension, contenant le nombre d'éléments (l'étendue) dans chaque dimension. Par exemple, pour la matrice de tableau, la forme est (3, 3) et les numéros du tableau sont (5).
Taille C'est le nombre d'éléments qu'un tableau contient. Pour la matrice de tableau, c'est 9, et pour les nombres de tableau, c'est 5.

Passage de tableaux à des procédures

Vous pouvez passer un tableau à une procédure en tant qu'argument. L'exemple suivant illustre le concept -

program arrayToProcedure      
implicit none      

   integer, dimension (5) :: myArray  
   integer :: i
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      

   integer, dimension (5), intent (out) :: a
   
   ! local variables     
   integer :: i     
   do i = 1, 5         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)

   integer, dimension (5) :: a  
   integer::i
   
   do i = 1, 5
      Print *, a(i)
   end do
   
end subroutine printArray

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

1
2
3
4
5

Dans l'exemple ci-dessus, les sous-programmes fillArray et printArray ne peuvent être appelés qu'avec des tableaux de dimension 5. Cependant, pour écrire des sous-programmes pouvant être utilisés pour des tableaux de toute taille, vous pouvez le réécrire en utilisant la technique suivante -

program arrayToProcedure      
implicit  none    

   integer, dimension (10) :: myArray  
   integer :: i
   
   interface 
      subroutine fillArray (a)
         integer, dimension(:), intent (out) :: a 
         integer :: i         
      end subroutine fillArray      

      subroutine printArray (a)
         integer, dimension(:) :: a 
         integer :: i         
      end subroutine printArray   
   end interface 
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      
   integer,dimension (:), intent (out) :: a      
   
   ! local variables     
   integer :: i, arraySize  
   arraySize = size(a)
   
   do i = 1, arraySize         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)
implicit none

   integer,dimension (:) :: a  
   integer::i, arraySize
   arraySize = size(a)
   
   do i = 1, arraySize
     Print *, a(i)
   end do
   
end subroutine printArray

Veuillez noter que le programme utilise le size fonction pour obtenir la taille du tableau.

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

1
2
3
4
5
6
7
8
9
10

Sections de tableau

Jusqu'à présent, nous avons fait référence à l'ensemble du tableau, Fortran fournit un moyen facile de référencer plusieurs éléments, ou une section d'un tableau, en utilisant une seule instruction.

Pour accéder à une section de tableau, vous devez fournir la limite inférieure et supérieure de la section, ainsi qu'une foulée (incrément), pour toutes les dimensions. Cette notation s'appelle unsubscript triplet:

array ([lower]:[upper][:stride], ...)

Lorsqu'aucune limite inférieure et supérieure n'est mentionnée, la valeur par défaut est celle que vous avez déclarée et la valeur de la foulée est par défaut de 1.

L'exemple suivant illustre le concept -

program arraySubsection

   real, dimension(10) :: a, b
   integer:: i, asize, bsize
   
   a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
   a(8:) = 0.0  ! rest are 0.0 
   b(2:10:2) = 3.9
   b(1:9:2) = 2.5
   
   !display
   asize = size(a)
   bsize = size(b)
   
   do i = 1, asize
      Print *, a(i)
   end do
   
   do i = 1, bsize
      Print *, b(i)
   end do
   
end program arraySubsection

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010

Fonctions intrinsèques du tableau

Fortran 90/95 fournit plusieurs procédures intrinsèques. Ils peuvent être divisés en 7 catégories.

  • Multiplication vectorielle et matricielle

  • Reduction

  • Inquiry

  • Construction

  • Reshape

  • Manipulation

  • Location

UNE dynamic array est un tableau dont la taille n'est pas connue au moment de la compilation, mais sera connue au moment de l'exécution.

Les tableaux dynamiques sont déclarés avec l'attribut allocatable.

Par exemple,

real, dimension (:,:), allocatable :: darray

Le rang du tableau, c'est-à-dire les dimensions doivent être mentionnés cependant, pour allouer de la mémoire à un tel tableau, vous utilisez le allocate fonction.

allocate ( darray(s1,s2) )

Une fois le tableau utilisé, dans le programme, la mémoire créée doit être libérée en utilisant le deallocate fonction

deallocate (darray)

Exemple

L'exemple suivant illustre les concepts décrits ci-dessus.

program dynamic_array 
implicit none 

   !rank is 2, but size not known   
   real, dimension (:,:), allocatable :: darray    
   integer :: s1, s2     
   integer :: i, j     
   
   print*, "Enter the size of the array:"     
   read*, s1, s2      
   
   ! allocate memory      
   allocate ( darray(s1,s2) )      
   
   do i = 1, s1           
      do j = 1, s2                
         darray(i,j) = i*j               
         print*, "darray(",i,",",j,") = ", darray(i,j)           
      end do      
   end do      
   
   deallocate (darray)  
end program dynamic_array

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

Enter the size of the array: 3,4
darray( 1 , 1 ) = 1.00000000    
darray( 1 , 2 ) = 2.00000000    
darray( 1 , 3 ) = 3.00000000    
darray( 1 , 4 ) = 4.00000000    
darray( 2 , 1 ) = 2.00000000    
darray( 2 , 2 ) = 4.00000000    
darray( 2 , 3 ) = 6.00000000    
darray( 2 , 4 ) = 8.00000000    
darray( 3 , 1 ) = 3.00000000    
darray( 3 , 2 ) = 6.00000000    
darray( 3 , 3 ) = 9.00000000    
darray( 3 , 4 ) = 12.0000000

Utilisation de la déclaration de données

le data L'instruction peut être utilisée pour initialiser plus d'un tableau, ou pour l'initialisation de section de tableau.

La syntaxe de l'instruction de données est -

data variable / list / ...

Exemple

L'exemple suivant illustre le concept -

program dataStatement
implicit none

   integer :: a(5), b(3,3), c(10),i, j
   data a /7,8,9,10,11/ 
   
   data b(1,:) /1,1,1/ 
   data b(2,:)/2,2,2/ 
   data b(3,:)/3,3,3/ 
   data (c(i),i = 1,10,2) /4,5,6,7,8/ 
   data (c(i),i = 2,10,2)/5*2/
   
   Print *, 'The A array:'
   do j = 1, 5                
      print*, a(j)           
   end do 
   
   Print *, 'The B array:'
   do i = lbound(b,1), ubound(b,1)
      write(*,*) (b(i,j), j = lbound(b,2), ubound(b,2))
   end do

   Print *, 'The C array:' 
   do j = 1, 10                
      print*, c(j)           
   end do      
   
end program dataStatement

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

The A array:
           7
           8
           9
          10
          11
 The B array:
           1           1           1
           2           2           2
           3           3           3
 The C array:
           4
           2
           5
           2
           6
           2
           7
           2
           8
           2

Utilisation de la déclaration Where

le whereL'instruction vous permet d'utiliser certains éléments d'un tableau dans une expression, en fonction du résultat d'une condition logique. Il permet l'exécution de l'expression, sur un élément, si la condition donnée est vraie.

Exemple

L'exemple suivant illustre le concept -

program whereStatement
implicit none

   integer :: a(3,5), i , j
   
   do i = 1,3
      do j = 1, 5                
         a(i,j) = j-i          
      end do 
   end do
   
   Print *, 'The A array:'
   
   do i = lbound(a,1), ubound(a,1)
      write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
   end do
   
   where( a<0 ) 
      a = 1 
   elsewhere
      a = 5
   end where
  
   Print *, 'The A array:'
   do i = lbound(a,1), ubound(a,1)
      write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
   end do   
   
end program whereStatement

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

The A array:
           0           1           2           3           4
          -1           0           1           2           3
          -2          -1           0           1           2
 The A array:
           5           5           5           5           5
           1           5           5           5           5
           1           1           5           5           5

Fortran vous permet de définir des types de données dérivés. Un type de données dérivé est également appelé une structure et peut être constitué d'objets de données de différents types.

Les types de données dérivés sont utilisés pour représenter un enregistrement. Par exemple, vous souhaitez garder une trace de vos livres dans une bibliothèque, vous voudrez peut-être suivre les attributs suivants pour chaque livre -

  • Title
  • Author
  • Subject
  • ID du livre

Définition d'un type de données dérivé

Pour définir une donnée dérivée type, le type et end typedes instructions sont utilisées. . L'instruction de type définit un nouveau type de données, avec plus d'un membre pour votre programme. Le format de l'instruction de type est le suivant -

type type_name      
   declarations
end type

Voici la façon dont vous déclareriez la structure Book -

type Books
   character(len = 50) :: title
   character(len = 50) :: author
   character(len = 150) :: subject
   integer :: book_id
end type Books

Accès aux membres de la structure

Un objet d'un type de données dérivé est appelé une structure.

Une structure de type Books peut être créée dans une instruction de déclaration de type comme -

type(Books) :: book1

Les composants de la structure sont accessibles à l'aide du caractère de sélection de composant (%) -

book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%book_id = 6495407

Note that there are no spaces before and after the % symbol.

Exemple

Le programme suivant illustre les concepts ci-dessus -

program deriveDataType

   !type declaration
   type Books
      character(len = 50) :: title
      character(len = 50) :: author
      character(len = 150) :: subject
      integer :: book_id
   end type Books
   
   !declaring type variables
   type(Books) :: book1 
   type(Books) :: book2 
   
   !accessing the components of the structure
   
   book1%title = "C Programming"
   book1%author = "Nuha Ali"
   book1%subject = "C Programming Tutorial"
   book1%book_id = 6495407 
   
   book2%title = "Telecom Billing"
   book2%author = "Zara Ali"
   book2%subject = "Telecom Billing Tutorial"
   book2%book_id = 6495700
  
   !display book info
   
   Print *, book1%title 
   Print *, book1%author 
   Print *, book1%subject 
   Print *, book1%book_id  
   
   Print *, book2%title 
   Print *, book2%author 
   Print *, book2%subject 
   Print *, book2%book_id  

end program deriveDataType

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

C Programming                                     
 Nuha Ali                                          
 C Programming Tutorial            
   6495407
 Telecom Billing                                   
 Zara Ali                                          
 Telecom Billing Tutorial            
   6495700

Tableau de structures

Vous pouvez également créer des tableaux d'un type dérivé -

type(Books), dimension(2) :: list

Les éléments individuels du tableau peuvent être accédés comme -

list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407

Le programme suivant illustre le concept -

program deriveDataType

   !type declaration
   type Books
      character(len = 50) :: title
      character(len = 50) :: author
      character(len = 150) :: subject
      integer :: book_id
   end type Books
   
   !declaring array of books
   type(Books), dimension(2) :: list 
    
   !accessing the components of the structure
   
   list(1)%title = "C Programming"
   list(1)%author = "Nuha Ali"
   list(1)%subject = "C Programming Tutorial"
   list(1)%book_id = 6495407 
   
   list(2)%title = "Telecom Billing"
   list(2)%author = "Zara Ali"
   list(2)%subject = "Telecom Billing Tutorial"
   list(2)%book_id = 6495700
  
   !display book info
   
   Print *, list(1)%title 
   Print *, list(1)%author 
   Print *, list(1)%subject 
   Print *, list(1)%book_id  
   
   Print *, list(1)%title 
   Print *, list(2)%author 
   Print *, list(2)%subject 
   Print *, list(2)%book_id  

end program deriveDataType

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

C Programming                                     
Nuha Ali                                          
C Programming Tutorial               
   6495407
C Programming                                     
Zara Ali                                          
Telecom Billing Tutorial                                      
   6495700

Dans la plupart des langages de programmation, une variable de pointeur stocke l'adresse mémoire d'un objet. Cependant, dans Fortran, un pointeur est un objet de données qui a plus de fonctionnalités que le simple stockage de l'adresse mémoire. Il contient plus d'informations sur un objet particulier, comme le type, le rang, les étendues et l'adresse mémoire.

Un pointeur est associé à une cible par allocation ou affectation de pointeur.

Déclaration d'une variable de pointeur

Une variable de pointeur est déclarée avec l'attribut pointer.

Les exemples suivants montrent la déclaration de variables de pointeur -

integer, pointer :: p1 ! pointer to integer  
real, pointer, dimension (:) :: pra ! pointer to 1-dim real array  
real, pointer, dimension (:,:) :: pra2 ! pointer to 2-dim real array

Un pointeur peut pointer vers -

  • Une zone de mémoire allouée dynamiquement.

  • Un objet de données du même type que le pointeur, avec le target attribut.

Allocation d'espace pour un pointeur

le allocateL'instruction vous permet d'allouer de l'espace pour un objet pointeur. Par exemple -

program pointerExample
implicit none

   integer, pointer :: p1
   allocate(p1)
   
   p1 = 1
   Print *, p1
   
   p1 = p1 + 4
   Print *, p1
   
end program pointerExample

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

1
5

Vous devez vider l'espace de stockage alloué par le deallocate instruction lorsqu'elle n'est plus requise et évite l'accumulation d'espace mémoire inutilisé et inutilisable.

Cibles et association

Une cible est une autre variable normale, avec un espace réservé pour elle. Une variable cible doit être déclarée avec letarget attribut.

Vous associez une variable de pointeur à une variable cible à l'aide de l'opérateur d'association (=>).

Réécrivons l'exemple précédent, pour démontrer le concept -

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1 
   
   p1=>t1
   p1 = 1
   
   Print *, p1
   Print *, t1
   
   p1 = p1 + 4
   
   Print *, p1
   Print *, t1
   
   t1 = 8
   
   Print *, p1
   Print *, t1
   
end program pointerExample

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

1
1
5
5
8
8

Un pointeur peut être -

  • Undefined
  • Associated
  • Disassociated

Dans le programme ci-dessus, nous avons associatedle pointeur p1, avec la cible t1, utilisant l'opérateur =>. La fonction associée teste l'état d'association d'un pointeur.

le nullify L'instruction dissocie un pointeur d'une cible.

Nullify ne vide pas les cibles car il peut y avoir plus d'un pointeur pointant vers la même cible. Cependant, vider le pointeur implique également l'annulation.

Exemple 1

L'exemple suivant montre les concepts -

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1 
   integer, target :: t2
   
   p1=>t1
   p1 = 1
   
   Print *, p1
   Print *, t1
   
   p1 = p1 + 4
   Print *, p1
   Print *, t1
   
   t1 = 8
   Print *, p1
   Print *, t1
   
   nullify(p1)
   Print *, t1
   
   p1=>t2
   Print *, associated(p1)
   Print*, associated(p1, t1)
   Print*, associated(p1, t2)
   
   !what is the value of p1 at present
   Print *, p1
   Print *, t2
   
   p1 = 10
   Print *, p1
   Print *, t2
   
end program pointerExample

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

1
1
5
5
8
8
8
T
F
T
952754640
952754640
10
10

Veuillez noter que chaque fois que vous exécutez le code, les adresses mémoire seront différentes.

Exemple 2

program pointerExample
implicit none

   integer, pointer :: a, b
   integer, target :: t
   integer :: n
   
   t = 1
   a => t
   t = 2
   b => t
   n = a + b
   
   Print *, a, b, t, n 
   
end program pointerExample

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

2  2  2  4

Nous avons jusqu'à présent vu que nous pouvons lire des données à partir du clavier en utilisant le read * et affichez la sortie à l'écran à l'aide de print*déclaration, respectivement. Cette forme d'entrée-sortie estfree format I / O, et il est appelé list-directed entrée sortie.

Les E / S simples au format libre ont la forme -

read(*,*) item1, item2, item3...
print *, item1, item2, item3
write(*,*) item1, item2, item3...

Cependant, les E / S formatées vous offrent plus de flexibilité sur le transfert de données.

Sortie d'entrée formatée

La sortie d'entrée formatée a la syntaxe suivante -

read fmt, variable_list 
print fmt, variable_list 
write fmt, variable_list

Où,

  • fmt est la spécification de format

  • variable-list est une liste des variables à lire à partir du clavier ou à écrire à l'écran

La spécification de format définit la manière dont les données formatées sont affichées. Il se compose d'une chaîne contenant une liste deedit descriptors entre parenthèses.

Un edit descriptor spécifie le format exact, par exemple la largeur, les chiffres après la virgule décimale, etc., dans lequel les caractères et les nombres sont affichés.

Par exemple

Print "(f6.3)", pi

Le tableau suivant décrit les descripteurs -

Descripteur La description Exemple
je

Ceci est utilisé pour la sortie entière. Cela prend la forme «rIw.m» où les significations de r, w et m sont données dans le tableau ci-dessous. Les valeurs entières sont justi fi ées correctement dans leurs champs. Si la largeur du champ n'est pas assez grande pour accueillir un entier, le champ est rempli d'astérisques.

imprimer "(3i5)", i, j, k
F

Ceci est utilisé pour la sortie de nombres réels. Cela prend la forme «rFw.d» où les significations de r, w et d sont données dans le tableau ci-dessous. Les vraies valeurs sont justi fi ées dans leurs domaines. Si la largeur du champ n'est pas assez grande pour accueillir le nombre réel, alors le champ est rempli d'astérisques.

imprimer "(f12.3)", pi
E

Ceci est utilisé pour la sortie réelle en notation exponentielle. L'énoncé du descripteur «E» prend la forme «rEw.d» où les significations de r, w et d sont données dans le tableau ci-dessous. Les vraies valeurs sont justi fi ées dans leurs domaines. Si la largeur du champ n'est pas assez grande pour accueillir le nombre réel, alors le champ est rempli d'astérisques.

Veuillez noter que, pour imprimer un nombre réel avec trois décimales, une largeur de champ d'au moins dix est nécessaire. Un pour le signe de la mantisse, deux pour le zéro, quatre pour la mantisse et deux pour l'exposant lui-même. En général, w ≥ d + 7.

print "(e10.3)", 123456.0 donne '0.123e + 06'
ES

Ceci est utilisé pour la sortie réelle (notation scientifique). Cela prend la forme «rESw.d» où les significations de r, w et d sont données dans le tableau ci-dessous. Le descripteur «E» décrit ci-dessus diffère légèrement de la «notation scientifique» traditionnelle bien connue. La notation scienti fi que a une mantisse comprise entre 1,0 et 10,0 contrairement au descripteur E qui a une mantisse comprise entre 0,1 et 1,0. Les vraies valeurs sont justi fi ées dans leurs domaines. Si la largeur du champ n'est pas assez grande pour accueillir le nombre réel, alors le champ est rempli d'astérisques. Ici aussi, le champ width doit satisfaire l'expression w ≥ d + 7

print "(es10.3)", 123456.0 donne '1.235e + 05'
UNE

Ceci est utilisé pour la sortie de caractères. Cela prend la forme «rAw» où les significations de r et w sont données dans le tableau ci-dessous. Les types de caractères sont justi fi és dans leurs champs. Si la largeur du champ n'est pas assez grande pour accueillir la chaîne de caractères, alors le champ est rempli avec les premiers caractères «w» de la chaîne.

imprimer "(a10)", str
X

Ceci est utilisé pour la sortie d'espace. Cela prend la forme «nX» où «n» est le nombre d'espaces souhaités.

imprimer "(5x, a10)", str
/

Descripteur de barre oblique - utilisé pour insérer des lignes vides. Cela prend la forme «/» et force la sortie de données suivante à être sur une nouvelle ligne.

imprimer "(/, 5x, a10)", str

Les symboles suivants sont utilisés avec les descripteurs de format -

Sr.Non Symbole et description
1

c

Numéro de colonne

2

d

Nombre de chiffres à droite de la décimale pour l'entrée ou la sortie réelle

3

m

Nombre minimum de chiffres à afficher

4

n

Nombre d'espaces à ignorer

5

r

Nombre de répétitions - le nombre de fois où utiliser un descripteur ou un groupe de descripteurs

6

w

Largeur du champ - le nombre de caractères à utiliser pour l'entrée ou la sortie

Exemple 1

program printPi

   pi = 3.141592653589793238 
   
   Print "(f6.3)", pi 
   Print "(f10.7)", pi
   Print "(f20.15)", pi 
   Print "(e16.4)", pi/100 
   
end program printPi

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

3.142
3.1415927
3.141592741012573
0.3142E-01

Exemple 2

program printName
implicit none

   character (len = 15) :: first_name
   print *,' Enter your first name.' 
   print *,' Up to 20 characters, please'
   
   read *,first_name 
   print "(1x,a)",first_name
   
end program printName

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant: (supposons que l'utilisateur entre le nom Zara)

Enter your first name.
Up to 20 characters, please
Zara

Exemple 3

program formattedPrint
implicit none

   real :: c = 1.2786456e-9, d = 0.1234567e3 
   integer :: n = 300789, k = 45, i = 2
   character (len=15) :: str="Tutorials Point"
   
   print "(i6)", k 
   print "(i6.3)", k 
   print "(3i10)", n, k, i 
   print "(i10,i3,i5)", n, k, i 
   print "(a15)",str 
   print "(f12.3)", d
   print "(e12.4)", c 
   print '(/,3x,"n = ",i6, 3x, "d = ",f7.4)', n, d
   
end program formattedPrint

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

45
045
300789 45  2
300789 45  2
Tutorials Point
123.457
0.1279E-08

n = 300789 d = *******

La déclaration de format

L'instruction de format vous permet de mélanger et de faire correspondre les caractères, les entiers et les résultats réels dans une seule instruction. L'exemple suivant illustre ceci -

program productDetails 
implicit none 

   character (len = 15) :: name
   integer :: id 
   real :: weight
   name = 'Ardupilot'
   id = 1
   weight = 0.08
   
   print *,' The product details are' 
   
   print 100
   100 format (7x,'Name:', 7x, 'Id:', 1x, 'Weight:')
   
   print 200, name, id, weight 
   200 format(1x, a, 2x, i3, 2x, f5.2) 
   
end program productDetails

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

The product details are
Name:       Id:    Weight:
Ardupilot   1       0.08

Fortran vous permet de lire et d'écrire des données dans des fichiers.

Dans le dernier chapitre, vous avez vu comment lire et écrire des données sur le terminal. Dans ce chapitre, vous étudierez les fonctionnalités d'entrée et de sortie de fichier fournies par Fortran.

Vous pouvez lire et écrire dans un ou plusieurs fichiers. Les instructions OPEN, WRITE, READ et CLOSE vous permettent d'y parvenir.

Ouverture et fermeture de fichiers

Avant d'utiliser un fichier, vous devez ouvrir le fichier. leopenLa commande est utilisée pour ouvrir des fichiers en lecture ou en écriture. La forme la plus simple de la commande est -

open (unit = number, file = "name").

Cependant, l'instruction ouverte peut avoir une forme générale -

open (list-of-specifiers)

Le tableau suivant décrit les spécificateurs les plus couramment utilisés -

Sr.Non Spécificateur et description
1

[UNIT=] u

Le numéro d'unité u peut être n'importe quel nombre compris entre 9 et 99 et il indique le fichier, vous pouvez choisir n'importe quel nombre, mais chaque fichier ouvert dans le programme doit avoir un numéro unique

2

IOSTAT= ios

Il s'agit de l'identificateur d'état des E / S et doit être une variable entière. Si l'instruction open réussit, la valeur ios renvoyée est zéro, sinon une valeur différente de zéro.

3

ERR = err

C'est une étiquette vers laquelle le contrôle saute en cas d'erreur.

4

FILE = fname

Nom de fichier, une chaîne de caractères.

5

STATUS = sta

Il montre l'état antérieur du fichier. Une chaîne de caractères et peut avoir l'une des trois valeurs NEW, OLD ou SCRATCH. Un fichier de travail est créé et supprimé lorsqu'il est fermé ou lorsque le programme se termine.

6

ACCESS = acc

C'est le mode d'accès aux fichiers. Peut avoir l'une des deux valeurs, SEQUENTIAL ou DIRECT. La valeur par défaut est SEQUENTIAL.

sept

FORM = frm

Il donne l'état de formatage du fichier. Peut avoir l'une des deux valeurs FORMATTED ou UNFORMATTED. La valeur par défaut est UNFORMATTED

8

RECL = rl

Il spécifie la longueur de chaque enregistrement dans un fichier à accès direct.

Une fois le fichier ouvert, il est accessible par des instructions de lecture et d'écriture. Une fois terminé, il doit être fermé à l'aide duclose déclaration.

L'instruction close a la syntaxe suivante -

close ([UNIT = ]u[,IOSTAT = ios,ERR = err,STATUS = sta])

Veuillez noter que les paramètres entre parenthèses sont facultatifs.

Example

Cet exemple montre l'ouverture d'un nouveau fichier pour écrire des données dans le fichier.

program outputdata   
implicit none

   real, dimension(100) :: x, y  
   real, dimension(100) :: p, q
   integer :: i  
   
   ! data  
   do i=1,100  
      x(i) = i * 0.1 
      y(i) = sin(x(i)) * (1-cos(x(i)/3.0))  
   end do  
   
   ! output data into a file 
   open(1, file = 'data1.dat', status = 'new')  
   do i=1,100  
      write(1,*) x(i), y(i)   
   end do  
   
   close(1) 
   
end program outputdata

Lorsque le code ci-dessus est compilé et exécuté, il crée le fichier data1.dat et y écrit les valeurs des tableaux x et y. Et puis ferme le fichier.

Lecture et écriture dans le fichier

Les instructions de lecture et d'écriture sont respectivement utilisées pour lire et écrire dans un fichier.

Ils ont la syntaxe suivante -

read ([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
write([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)

La plupart des prescripteurs ont déjà été discutés dans le tableau ci-dessus.

Le spécificateur END = s est une étiquette d'instruction où le programme saute, lorsqu'il atteint la fin du fichier.

Example

Cet exemple illustre la lecture et l'écriture dans un fichier.

Dans ce programme, nous lisons à partir du fichier, nous avons créé dans le dernier exemple, data1.dat, et l'affiche à l'écran.

program outputdata   
implicit none   

   real, dimension(100) :: x, y  
   real, dimension(100) :: p, q
   integer :: i  
   
   ! data  
   do i = 1,100  
      x(i) = i * 0.1 
      y(i) = sin(x(i)) * (1-cos(x(i)/3.0))  
   end do  
   
   ! output data into a file 
   open(1, file = 'data1.dat', status='new')  
   do i = 1,100  
      write(1,*) x(i), y(i)   
   end do  
   close(1) 

   ! opening the file for reading
   open (2, file = 'data1.dat', status = 'old')

   do i = 1,100  
      read(2,*) p(i), q(i)
   end do 
   
   close(2)
   
   do i = 1,100  
      write(*,*) p(i), q(i)
   end do 
   
end program outputdata

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant -

0.100000001  5.54589933E-05
0.200000003  4.41325130E-04
0.300000012  1.47636665E-03
0.400000006  3.45637114E-03
0.500000000  6.64328877E-03
0.600000024  1.12552457E-02
0.699999988  1.74576249E-02
0.800000012  2.53552198E-02
0.900000036  3.49861123E-02
1.00000000   4.63171229E-02
1.10000002   5.92407547E-02
1.20000005   7.35742599E-02
1.30000007   8.90605897E-02
1.39999998   0.105371222    
1.50000000   0.122110792    
1.60000002   0.138823599    
1.70000005   0.155002072    
1.80000007   0.170096487    
1.89999998   0.183526158    
2.00000000   0.194692180    
2.10000014   0.202990443    
2.20000005   0.207826138    
2.29999995   0.208628103    
2.40000010   0.204863414    
2.50000000   0.196052119    
2.60000014   0.181780845    
2.70000005   0.161716297    
2.79999995   0.135617107    
2.90000010   0.103344671    
3.00000000   6.48725405E-02
3.10000014   2.02930309E-02
3.20000005  -3.01767997E-02
3.29999995  -8.61928314E-02
3.40000010  -0.147283033    
3.50000000  -0.212848678    
3.60000014  -0.282169819    
3.70000005  -0.354410470    
3.79999995  -0.428629100    
3.90000010  -0.503789663    
4.00000000  -0.578774154    
4.09999990  -0.652400017    
4.20000029  -0.723436713    
4.30000019  -0.790623367    
4.40000010  -0.852691114    
4.50000000  -0.908382416    
4.59999990  -0.956472993    
4.70000029  -0.995793998    
4.80000019  -1.02525222    
4.90000010  -1.04385209    
5.00000000  -1.05071592    
5.09999990  -1.04510069    
5.20000029  -1.02641726    
5.30000019  -0.994243503    
5.40000010  -0.948338211    
5.50000000  -0.888650239    
5.59999990  -0.815326691    
5.70000029  -0.728716135    
5.80000019  -0.629372001    
5.90000010  -0.518047631    
6.00000000  -0.395693362    
6.09999990  -0.263447165    
6.20000029  -0.122622721    
6.30000019   2.53026206E-02
6.40000010   0.178709000    
6.50000000   0.335851669    
6.59999990   0.494883657    
6.70000029   0.653881252    
6.80000019   0.810866773    
6.90000010   0.963840425    
7.00000000   1.11080539    
7.09999990   1.24979746    
7.20000029   1.37891412    
7.30000019   1.49633956    
7.40000010   1.60037732    
7.50000000   1.68947268    
7.59999990   1.76223695    
7.70000029   1.81747139    
7.80000019   1.85418403    
7.90000010   1.87160957    
8.00000000   1.86922085    
8.10000038   1.84674001    
8.19999981   1.80414569    
8.30000019   1.74167395    
8.40000057   1.65982044    
8.50000000   1.55933595    
8.60000038   1.44121361    
8.69999981   1.30668485    
8.80000019   1.15719533    
8.90000057   0.994394958    
9.00000000   0.820112705    
9.10000038   0.636327863    
9.19999981   0.445154816    
9.30000019   0.248800844    
9.40000057   4.95488606E-02
9.50000000  -0.150278628    
9.60000038  -0.348357052    
9.69999981  -0.542378068    
9.80000019  -0.730095863    
9.90000057  -0.909344316    
10.0000000  -1.07807255

UNE procedureest un groupe d'instructions qui exécutent une tâche bien définie et peuvent être appelées à partir de votre programme. Les informations (ou données) sont transmises au programme appelant, à la procédure sous forme d'arguments.

Il existe deux types de procédures -

  • Functions
  • Subroutines

Fonction

Une fonction est une procédure qui renvoie une seule quantité. Une fonction ne doit pas modifier ses arguments.

La quantité retournée est appelée function value, et il est indiqué par le nom de la fonction.

Syntax

La syntaxe d'une fonction est la suivante -

function name(arg1, arg2, ....)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

L'exemple suivant illustre une fonction nommée area_of_circle. Il calcule l'aire d'un cercle de rayon r.

program calling_func

   real :: a
   a = area_of_circle(2.0) 
   
   Print *, "The area of a circle with radius 2.0 is"
   Print *, a
   
end program calling_func


! this function computes the area of a circle with radius r  
function area_of_circle (r)  

! function result     
implicit none      

   ! dummy arguments        
   real :: area_of_circle   
   
   ! local variables 
   real :: r     
   real :: pi
   
   pi = 4 * atan (1.0)     
   area_of_circle = pi * r**2  
   
end function area_of_circle

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

The area of a circle with radius 2.0 is
   12.5663710

Veuillez noter que -

  • Vous devez spécifier implicit none tant dans le programme principal que dans la procédure.

  • L'argument r dans la fonction appelée est appelé dummy argument.

L'option résultat

Si vous souhaitez que la valeur renvoyée soit stockée sous un autre nom que le nom de la fonction, vous pouvez utiliser le result option.

Vous pouvez spécifier le nom de la variable de retour comme -

function name(arg1, arg2, ....) result (return_var_name)  
   [declarations, including those for the arguments]   
   [executable statements] 
end function [name]

Sous-programme

Un sous-programme ne renvoie pas de valeur, mais il peut modifier ses arguments.

Syntax

subroutine name(arg1, arg2, ....)    
   [declarations, including those for the arguments]    
   [executable statements]  
end subroutine [name]

Appel d'un sous-programme

You need to invoke a subroutine using the call statement.

The following example demonstrates the definition and use of a subroutine swap, that changes the values of its arguments.

program calling_func
implicit none

   real :: a, b
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
end program calling_func


subroutine swap(x, y) 
implicit none

   real :: x, y, temp   
   
   temp = x  
   x = y 
   y = temp  
   
end subroutine swap

When you compile and execute the above program, it produces the following result −

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000

Specifying the Intent of the Arguments

The intent attribute allows you to specify the intention with which arguments are used in the procedure. The following table provides the values of the intent attribute −

Value Used as Explanation
in intent(in) Used as input values, not changed in the function
out intent(out) Used as output value, they are overwritten
inout intent(inout) Arguments are both used and overwritten

The following example demonstrates the concept −

program calling_func
implicit none

   real :: x, y, z, disc
   
   x = 1.0
   y = 5.0
   z = 2.0
   
   call intent_example(x, y, z, disc)
   
   Print *, "The value of the discriminant is"
   Print *, disc
   
end program calling_func


subroutine intent_example (a, b, c, d)     
implicit none     

   ! dummy arguments      
   real, intent (in) :: a     
   real, intent (in) :: b      
   real, intent (in) :: c    
   real, intent (out) :: d   
   
   d = b * b - 4.0 * a * c 
   
end subroutine intent_example

When you compile and execute the above program, it produces the following result −

The value of the discriminant is
   17.0000000

Recursive Procedures

Recursion occurs when a programming languages allows you to call a function inside the same function. It is called recursive call of the function.

When a procedure calls itself, directly or indirectly, is called a recursive procedure. You should declare this type of procedures by preceding the word recursive before its declaration.

When a function is used recursively, the result option has to be used.

Following is an example, which calculates factorial for a given number using a recursive procedure −

program calling_func
implicit none

   integer :: i, f
   i = 15
   
   Print *, "The value of factorial 15 is"
   f = myfactorial(15)
   Print *, f
   
end program calling_func

! computes the factorial of n (n!)      
recursive function myfactorial (n) result (fac)  
! function result     
implicit none     

   ! dummy arguments     
   integer :: fac     
   integer, intent (in) :: n     
   
   select case (n)         
      case (0:1)         
         fac = 1         
      case default    
         fac = n * myfactorial (n-1)  
   end select 
   
end function myfactorial

Internal Procedures

When a procedure is contained within a program, it is called the internal procedure of the program. The syntax for containing an internal procedure is as follows −

program program_name     
   implicit none         
   ! type declaration statements         
   ! executable statements    
   . . .     
   contains         
   ! internal procedures      
   . . .  
end program program_name

The following example demonstrates the concept −

program mainprog  
implicit none 

   real :: a, b 
   a = 2.0
   b = 3.0
   
   Print *, "Before calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
   
   call swap(a, b)
   
   Print *, "After calling swap"
   Print *, "a = ", a
   Print *, "b = ", b
 
contains   
   subroutine swap(x, y)     
      real :: x, y, temp      
      temp = x 
      x = y  
      y = temp   
   end subroutine swap 
   
end program mainprog

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Before calling swap
a = 2.00000000    
b = 3.00000000    
After calling swap
a = 3.00000000    
b = 2.00000000

Un module est comme un paquet où vous pouvez conserver vos fonctions et sous-programmes, au cas où vous écrivez un très gros programme, ou vos fonctions ou sous-programmes peuvent être utilisés dans plus d'un programme.

Les modules vous permettent de diviser vos programmes entre plusieurs fichiers.

Les modules sont utilisés pour -

  • Emballage des sous-programmes, des données et des blocs d'interface.

  • Définition de données globales pouvant être utilisées par plusieurs sous-programmes.

  • Déclarer des variables qui peuvent être rendues disponibles dans toutes les routines de votre choix.

  • Importer un module entièrement, pour utilisation, dans un autre programme ou sous-programme.

Syntaxe d'un module

Un module se compose de deux parties -

  • une partie de spécification pour la déclaration des déclarations
  • a contient une partie pour les définitions de sous-programmes et de fonctions

La forme générale d'un module est -

module name     
   [statement declarations]  
   [contains [subroutine and function definitions] ] 
end module [name]

Utilisation d'un module dans votre programme

Vous pouvez incorporer un module dans un programme ou un sous-programme par l'instruction use -

use name

Veuillez noter que

  • Vous pouvez ajouter autant de modules que nécessaire, chacun sera dans des fichiers séparés et compilé séparément.

  • Un module peut être utilisé dans différents programmes.

  • Un module peut être utilisé plusieurs fois dans le même programme.

  • Les variables déclarées dans une partie de spécification de module, sont globales au module.

  • Les variables déclarées dans un module deviennent des variables globales dans n'importe quel programme ou routine où le module est utilisé.

  • L'instruction use peut apparaître dans le programme principal, ou dans tout autre sous-programme ou module qui utilise les routines ou les variables déclarées dans un module particulier.

Exemple

L'exemple suivant illustre le concept -

module constants  
implicit none 

   real, parameter :: pi = 3.1415926536  
   real, parameter :: e = 2.7182818285 
   
contains      
   subroutine show_consts()          
      print*, "Pi = ", pi          
      print*,  "e = ", e     
   end subroutine show_consts 
   
end module constants 


program module_example     
use constants      
implicit none     

   real :: x, ePowerx, area, radius 
   x = 2.0
   radius = 7.0
   ePowerx = e ** x
   area = pi * radius**2     
   
   call show_consts() 
   
   print*, "e raised to the power of 2.0 = ", ePowerx
   print*, "Area of a circle with radius 7.0 = ", area  
   
end program module_example

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Pi = 3.14159274    
e =  2.71828175    
e raised to the power of 2.0 = 7.38905573    
Area of a circle with radius 7.0 = 153.938049

Accessibilité des variables et des sous-programmes dans un module

Par défaut, toutes les variables et sous-programmes d'un module sont mis à disposition du programme qui utilise le code du module, par le use déclaration.

Cependant, vous pouvez contrôler l'accessibilité du code du module à l'aide du private et publicles attributs. Lorsque vous déclarez une variable ou un sous-programme comme privé, il n'est pas disponible en dehors du module.

Exemple

L'exemple suivant illustre le concept -

Dans l'exemple précédent, nous avions deux variables de module, e et pi. Rendons-les privés et observons la sortie -

module constants  
implicit none 

   real, parameter,private :: pi = 3.1415926536  
   real, parameter, private :: e = 2.7182818285 
   
contains      
   subroutine show_consts()          
      print*, "Pi = ", pi          
      print*, "e = ", e     
   end subroutine show_consts 
   
end module constants 


program module_example     
use constants      
implicit none     

   real :: x, ePowerx, area, radius 
   x = 2.0
   radius = 7.0
   ePowerx = e ** x
   area = pi * radius**2     
   
   call show_consts() 
   
   print*, "e raised to the power of 2.0 = ", ePowerx
   print*, "Area of a circle with radius 7.0 = ", area  
   
end program module_example

Lorsque vous compilez et exécutez le programme ci-dessus, il donne le message d'erreur suivant -

ePowerx = e ** x
   1
Error: Symbol 'e' at (1) has no IMPLICIT type
main.f95:19.13:

   area = pi * radius**2     
   1
Error: Symbol 'pi' at (1) has no IMPLICIT type

Depuis e et pi, les deux sont déclarés privés, le programme module_example ne peut plus accéder à ces variables.

Cependant, d'autres sous-programmes de module peuvent y accéder -

module constants  
implicit none 

   real, parameter,private :: pi = 3.1415926536  
   real, parameter, private :: e = 2.7182818285 
   
contains      
   subroutine show_consts()          
      print*, "Pi = ", pi          
      print*, "e = ", e     
   end subroutine show_consts 
   
   function ePowerx(x)result(ePx) 
   implicit none
      real::x
      real::ePx
      ePx = e ** x
   end function ePowerx
    
   function areaCircle(r)result(a)  
   implicit none
      real::r
      real::a
      a = pi * r**2  
   end function areaCircle
    
end module constants 


program module_example     
use constants      
implicit none     

   call show_consts() 
   
   Print*, "e raised to the power of 2.0 = ", ePowerx(2.0)
   print*, "Area of a circle with radius 7.0 = ", areaCircle(7.0)  
   
end program module_example

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

Pi = 3.14159274    
e = 2.71828175    
e raised to the power of 2.0 = 7.38905573    
Area of a circle with radius 7.0 = 153.938049

Les fonctions intrinsèques sont des fonctions courantes et importantes fournies dans le cadre du langage Fortran. Nous avons déjà discuté de certaines de ces fonctions dans les chapitres Arrays, Characters et String.

Les fonctions intrinsèques peuvent être classées comme suit:

  • Fonctions numériques
  • Fonctions mathématiques
  • Fonctions d'interrogation numérique
  • Fonctions de manipulation en virgule flottante
  • Fonctions de manipulation de bits
  • Fonctions de caractères
  • Fonctions Kind
  • Fonctions logiques
  • Fonctions de tableau.

Nous avons discuté des fonctions de tableau dans le chapitre Arrays. Dans la section suivante, nous fournissons de brèves descriptions de toutes ces fonctions à partir d'autres catégories.

Dans la colonne du nom de la fonction,

  • A représente tout type de variable numérique
  • R représente une variable réelle ou entière
  • X et Y représentent des variables réelles
  • Z représente une variable complexe
  • W représente une variable réelle ou complexe

Fonctions numériques

Sr.Non Description de la fonction
1

ABS (A)

Il renvoie la valeur absolue de A

2

AIMAG (Z)

Il renvoie la partie imaginaire d'un nombre complexe Z

3

AINT (A [, KIND])

Il tronque une partie fractionnaire de A vers zéro, renvoyant un nombre entier réel.

4

ANINT (A [, KIND])

Il renvoie une valeur réelle, l'entier ou le nombre entier le plus proche.

5

CEILING (A [, KIND])

Il renvoie le plus petit entier supérieur ou égal au nombre A.

6

CMPLX (X [, Y, KIND])

Il convertit les variables réelles X et Y en un nombre complexe X + iY; si Y est absent, 0 est utilisé.

sept

CONJG (Z)

Il renvoie le conjugué complexe de tout nombre complexe Z.

8

DBLE (A)

Il convertit A en un nombre réel à double précision.

9

DIM (X, Y)

Il renvoie la différence positive de X et Y.

dix

DPROD (X, Y)

Il renvoie le produit réel double précision de X et Y.

11

FLOOR (A [, KIND])

Il fournit le plus grand entier inférieur ou égal au nombre A.

12

INT (A [, KIND])

Il convertit un nombre (réel ou entier) en entier, tronquant la partie réelle vers zéro.

13

MAX (A1, A2 [, A3,...])

Il renvoie la valeur maximale des arguments, tous étant du même type.

14

MIN (A1, A2 [, A3,...])

Il renvoie la valeur minimale des arguments, tous étant du même type.

15

MOD (A, P)

Il renvoie le reste de A divisé par P, les deux arguments étant du même type (A-INT (A / P) * P)

16

MODULO (A, P)

Il renvoie A modulo P: (A-FLOOR (A / P) * P)

17

NINT (A [, KIND])

Il renvoie l'entier le plus proche du nombre A

18

REAL (A [, KIND])

Il se convertit en type réel

19

SIGN (A, B)

Il renvoie la valeur absolue de A multipliée par le signe de P. Fondamentalement, il transfère le signe de de B à A.

Exemple

program numericFunctions
implicit none  

   ! define constants  
   ! define variables
   real :: a, b 
   complex :: z
   
   ! values for a, b 
   a = 15.2345
   b = -20.7689
    
   write(*,*) 'abs(a): ',abs(a),' abs(b): ',abs(b)   
   write(*,*) 'aint(a): ',aint(a),' aint(b): ',aint(b) 
   write(*,*) 'ceiling(a): ',ceiling(a),' ceiling(b): ',ceiling(b)   
   write(*,*) 'floor(a): ',floor(a),' floor(b): ',floor(b)  
    
   z = cmplx(a, b)
   write(*,*) 'z: ',z   
   
end program numericFunctions

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

abs(a): 15.2344999   abs(b): 20.7688999    
aint(a): 15.0000000  aint(b): -20.0000000    
ceiling(a): 16  ceiling(b): -20
floor(a): 15  floor(b): -21
z: (15.2344999, -20.7688999)

Fonctions mathématiques

Sr.Non Description de la fonction
1

ACOS (X)

Il renvoie le cosinus inverse dans la plage (0, π), en radians.

2

ASIN (X)

Il renvoie le sinus inverse dans la plage (-π / 2, π / 2), en radians.

3

ATAN (X)

Elle renvoie la tangente inverse dans l'intervalle (-π / 2, π / 2), en radians.

4

ATAN2 (Y, X)

Elle renvoie la tangente inverse dans l'intervalle (-π, π), en radians.

5

COS (X)

Il renvoie le cosinus de l'argument en radians.

6

COSH (X)

Il renvoie le cosinus hyperbolique de l'argument en radians.

sept

EXP (X)

Il renvoie la valeur exponentielle de X.

8

LOG (X)

Il renvoie la valeur logarithmique naturelle de X.

9

LOG10 (X)

Il renvoie la valeur logarithmique commune (base 10) de X.

dix

SIN (X)

Il renvoie le sinus de l'argument en radians.

11

SINH (X)

Il renvoie le sinus hyperbolique de l'argument en radians.

12

SQRT (X)

Il renvoie la racine carrée de X.

13

TAN (X)

Il renvoie la tangente de l'argument en radians.

14

TANH (X)

Il renvoie la tangente hyperbolique de l'argument en radians.

Exemple

Le programme suivant calcule respectivement la position horizontale et verticale x et y d'un projectile après un temps, t -

Où, x = ut cos a et y = ut sin a - g t2 / 2

program projectileMotion  
implicit none  

   ! define constants  
   real, parameter :: g = 9.8  
   real, parameter :: pi = 3.1415927  
   
   !define variables
   real :: a, t, u, x, y   
   
   !values for a, t, and u 
   a = 45.0
   t = 20.0
   u = 10.0
   
   ! convert angle to radians  
   a = a * pi / 180.0  
   x = u * cos(a) * t   
   y = u * sin(a) * t - 0.5 * g * t * t  
   
   write(*,*) 'x: ',x,'  y: ',y   
   
end program projectileMotion

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

x: 141.421356  y: -1818.57861

Fonctions d'interrogation numérique

Ces fonctions fonctionnent avec un certain modèle d'arithmétique en nombres entiers et en virgule flottante. Les fonctions renvoient des propriétés de nombres du même type que la variable X, qui peuvent être réels et dans certains cas entiers.

Sr.Non Description de la fonction
1

DIGITS (X)

Il renvoie le nombre de chiffres significatifs du modèle.

2

EPSILON (X)

Il renvoie le nombre qui est presque négligeable par rapport à un. En d'autres termes, il renvoie la plus petite valeur telle que REAL (1.0, KIND (X)) + EPSILON (X) n'est pas égal à REAL (1.0, KIND (X)).

3

HUGE (X)

Il renvoie le plus grand nombre du modèle

4

MAXEXPONENT (X)

Il renvoie l'exposant maximum du modèle

5

MINEXPONENT (X)

Il renvoie l'exposant minimum du modèle

6

PRECISION (X)

Il renvoie la précision décimale

sept

RADIX (X)

Il renvoie la base du modèle

8

RANGE (X)

Il renvoie la plage d'exposants décimaux

9

TINY (X)

Il renvoie le plus petit nombre positif du modèle

Fonctions de manipulation en virgule flottante

Sr.Non Description de la fonction
1

EXPONENT (X)

Il renvoie la partie exposant d'un numéro de modèle

2

FRACTION (X)

Il renvoie la partie fractionnaire d'un nombre

3

NEAREST (X, S)

Il renvoie le numéro de processeur différent le plus proche dans une direction donnée

4

RRSPACING (X)

Il renvoie l'inverse de l'espacement relatif des numéros de modèle près du nombre donné

5

SCALE (X, I)

Il multiplie un réel par sa base en une puissance entière

6

SET_EXPONENT (X, I)

il renvoie la partie exposante d'un nombre

sept

SPACING (X)

Il renvoie l'espacement absolu des numéros de modèle près du nombre donné

Fonctions de manipulation de bits

Sr.Non Description de la fonction
1

BIT_SIZE (I)

Il renvoie le nombre de bits du modèle

2

BTEST (I, POS)

Test de bits

3

IAND (I, J)

ET logique

4

IBCLR (I, POS)

Effacer le bit

5

IBITS (I, POS, LEN)

Extraction de bits

6

IBSET (I, POS)

Définir le bit

sept

IEOR (I, J)

OU exclusif

8

IOR (I, J)

OU inclusif

9

ISHFT (I, SHIFT)

Changement logique

dix

ISHFTC (I, SHIFT [, SIZE])

Décalage circulaire

11

NOT (I)

Complément logique

Fonctions de caractères

Sr.Non Description de la fonction
1

ACHAR (I)

Il renvoie le caractère I de la séquence de classement ASCII.

2

ADJUSTL (STRING)

Il ajuste la chaîne à gauche en supprimant tous les blancs de début et en insérant des blancs de fin

3

ADJUSTR (STRING)

Il ajuste la chaîne à droite en supprimant les blancs de fin et en insérant les blancs de début.

4

CHAR (I [, KIND])

Il renvoie le caractère I dans la séquence de classement spéci fi que de la machine

5

IACHAR (C)

Il renvoie la position du caractère dans la séquence de classement ASCII.

6

ICHAR (C)

Il renvoie la position du caractère dans la séquence de classement spéci fi que de la machine (processeur).

sept

INDEX (STRING, SUBSTRING [, BACK])

Il renvoie la position de départ la plus à gauche (la plus à droite si BACK est .TRUE.) De SUBSTRING dans STRING.

8

LEN (STRING)

Il renvoie la longueur d'une chaîne.

9

LEN_TRIM (STRING)

Il renvoie la longueur d'une chaîne sans caractères vides de fin.

dix

LGE (STRING_A, STRING_B)

Lexicalement supérieur ou égal

11

LGT (STRING_A, STRING_B)

Lexicalement supérieur à

12

LLE (STRING_A, STRING_B)

Lexicalement inférieur ou égal

13

LLT (STRING_A, STRING_B)

Lexiquement inférieur à

14

REPEAT (STRING, NCOPIES)

Concaténation répétée

15

SCAN (STRING, SET [, BACK])

Il renvoie l'index du caractère le plus à gauche (le plus à droite si BACK est .TRUE.) De STRING qui appartient à SET, ou 0 si aucun n'appartient.

16

TRIM (STRING)

Supprime les caractères vides de fin

17

VERIFY (STRING, SET [, BACK])

Vérifie le jeu de caractères dans une chaîne

Fonctions Kind

Sr.Non Description de la fonction
1

KIND (X)

Il renvoie la valeur du paramètre de type kind.

2

SELECTED_INT_KIND (R)

Il renvoie le type de paramètre de type pour la plage d'exposants spécifiée.

3

SELECTED_REAL_KIND ([P, R])

Valeur du paramètre de type réel, précision et plage données

Fonction logique

Sr.Non Description de la fonction
1

LOGICAL (L [, KIND])

Conversion entre objets de type logique avec différents paramètres de type kind

Nous avons déjà discuté du fait que, dans les anciennes versions de Fortran, il y avait deux real types: le type réel par défaut et double precision type.

Cependant, Fortran 90/95 offre plus de contrôle sur la précision des types de données réels et entiers via le kind spécifie.

L'attribut aimable

Différents types de nombres sont stockés différemment à l'intérieur de l'ordinateur. lekindL'attribut vous permet de spécifier comment un nombre est stocké en interne. Par exemple,

real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n

Dans la déclaration ci-dessus, les variables réelles e, f et g ont plus de précision que les variables réelles a, b et c. Les variables entières l, m et n peuvent stocker des valeurs plus grandes et avoir plus de chiffres à stocker que les variables entières i, j et k. Bien que cela dépende de la machine.

Exemple

program kindSpecifier
implicit none

   real(kind = 4) :: a, b, c
   real(kind = 8) :: e, f, g
   integer(kind = 2) :: i, j, k
   integer(kind = 4) :: l, m, n
   integer :: kind_a, kind_i, kind_e, kind_l
   
   kind_a = kind(a)
   kind_i = kind(i)
   kind_e = kind(e)
   kind_l = kind(l)
   
   print *,'default kind for real is', kind_a
   print *,'default kind for int is', kind_i
   print *,'extended kind for real is', kind_e
   print *,'default kind for int is', kind_l
   
end program kindSpecifier

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4

Recherche de la taille des variables

Il existe un certain nombre de fonctions intrinsèques qui vous permettent d'interroger la taille des nombres.

Par exemple, le bit_size(i)fonction intrinsèque spécifie le nombre de bits utilisés pour le stockage. Pour les nombres réels, leprecision(x) fonction intrinsèque, renvoie le nombre de chiffres décimaux de précision, tandis que le range(x) fonction intrinsèque renvoie la plage décimale de l'exposant.

Exemple

program getSize
implicit none

   real (kind = 4) :: a
   real (kind = 8) :: b
   integer (kind = 2) :: i
   integer (kind = 4) :: j

   print *,'precision of real(4) =', precision(a)
   print *,'precision of real(8) =', precision(b)
   
   print *,'range of real(4) =', range(a)
   print *,'range of real(8) =', range(b)
   

   print *,'maximum exponent of real(4) =' , maxexponent(a)
   print *,'maximum exponent of real(8) =' , maxexponent(b)
  
   print *,'minimum exponent of real(4) =' , minexponent(a)
   print *,'minimum exponent of real(8) =' , minexponent(b)
   
   print *,'bits in integer(2) =' , bit_size(i)
   print *,'bits in integer(4) =' , bit_size(j)
   
end program getSize

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

precision of real(4) = 6
precision of real(8) = 15
range of real(4) = 37
range of real(8) = 307
maximum exponent of real(4) = 128
maximum exponent of real(8) = 1024
minimum exponent of real(4) = -125
minimum exponent of real(8) = -1021
bits in integer(2) = 16
bits in integer(4) = 32

Obtention de la valeur aimable

Fortran fournit deux autres fonctions intrinsèques pour obtenir la valeur kind pour la précision requise des entiers et des réels -

  • selected_int_kind (r)
  • selected_real_kind ([p, r])

La fonction selected_real_kind renvoie un entier correspondant à la valeur du paramètre de type kind nécessaire pour une précision décimale p donnée et une plage d'exposants décimaux r. La précision décimale est le nombre de chiffres significatifs et la plage d'exposants décimaux spécifie le plus petit et le plus grand nombre représentable. La plage est donc de 10-r à 10 + r.

Par exemple, selected_real_kind (p = 10, r = 99) renvoie la valeur kind nécessaire pour une précision de 10 décimales et une plage d'au moins 10-99 à 10 + 99.

Exemple

program getKind
implicit none

   integer:: i
   i = selected_real_kind (p = 10, r = 99) 
   print *,'selected_real_kind (p = 10, r = 99)', i
   
end program getKind

Lorsque vous compilez et exécutez le programme ci-dessus, il produit le résultat suivant -

selected_real_kind (p = 10, r = 99) 8

Il existe différents outils et bibliothèques Fortran. Certains sont gratuits et certains sont des services payants.

Voici quelques bibliothèques gratuites -

  • RANDLIB, générateurs de nombres aléatoires et de distribution statistique
  • BLAS
  • EISPACK
  • Guide GAMS – NIST des logiciels mathématiques disponibles
  • Quelques routines statistiques et autres du NIST
  • LAPACK
  • LINPACK
  • MINPACK
  • MUDPACK
  • Bibliothèque mathématique NCAR
  • La collection Netlib de logiciels, articles et bases de données mathématiques.
  • ODEPACK
  • ODERPACK, un ensemble de routines de classement et de classement.
  • Expokit pour le calcul des exponentielles matricielles
  • SLATEC
  • SPECFUN
  • STARPAC
  • Bibliothèque statistique StatLib
  • TOMS
  • Tri et fusion de chaînes

Les bibliothèques suivantes ne sont pas gratuites -

  • La bibliothèque numérique NAG Fortran
  • La bibliothèque IMSL de Visual Numerics
  • Recettes numériques

Le style de programmation consiste à suivre certaines règles lors du développement de programmes. Ces bonnes pratiques transmettent des valeurs telles que la lisibilité et l'absence d'ambiguïté dans votre programme.

Un bon programme doit avoir les caractéristiques suivantes -

  • Readability
  • Une structure logique appropriée
  • Notes et commentaires explicites

Par exemple, si vous faites un commentaire comme celui-ci, cela ne vous aidera pas beaucoup -

! loop from 1 to 10 
do i = 1,10

Cependant, si vous calculez le coefficient binomial et que vous avez besoin de cette boucle pour nCr, un commentaire comme celui-ci sera utile -

! loop to calculate nCr 
do i = 1,10
  • Blocs de code en retrait pour rendre les différents niveaux de code clairs.

  • Codes d'auto-vérification pour s'assurer qu'il n'y aura pas d'erreurs numériques comme la division par zéro, la racine carrée d'un nombre réel négatif ou le logarithme d'un nombre réel négatif.

  • Y compris des codes qui garantissent que les variables ne prennent pas de valeurs illégales ou hors plage, c'est-à-dire la validation d'entrée.

  • Ne pas mettre de chèques là où cela serait inutile et ralentit l'exécution. Par exemple -

real :: x 
x = sin(y) + 1.0

if (x >= 0.0) then
   z = sqrt(x)
end if
  • Code clairement écrit en utilisant des algorithmes appropriés.
  • Fractionnement des expressions longues à l'aide du marqueur de continuation «&».
  • Créer des noms de variables significatifs.

Un outil de débogage est utilisé pour rechercher des erreurs dans les programmes.

Un programme de débogage parcourt le code et vous permet d'examiner les valeurs des variables et d'autres objets de données pendant l'exécution du programme.

Il charge le code source et vous êtes censé exécuter le programme dans le débogueur. Les débogueurs déboguent un programme en -

  • Définition des points d'arrêt,
  • Parcourir le code source,
  • Définition des points de surveillance.

Les points d'arrêt spécifient où le programme doit s'arrêter, en particulier après une ligne de code critique. Exécutions de programme après vérification des variables à un point d'arrêt.

Les programmes de débogage vérifient également le code source ligne par ligne.

Les points de surveillance sont les points où les valeurs de certaines variables doivent être vérifiées, en particulier après une opération de lecture ou d'écriture.

Le débogueur gdb

Le débogueur gdb, le débogueur GNU est fourni avec le système d'exploitation Linux. Pour le système X Windows, gdb est livré avec une interface graphique et le programme est nommé xxgdb.

Le tableau suivant fournit quelques commandes dans gdb -

Commander Objectif
Pause Définition d'un point d'arrêt
courir Démarre l'exécution
cont Continue l'exécution
prochain Exécute uniquement la ligne suivante de code source, sans passer par aucun appel de fonction
étape Exécutez la ligne suivante de code source en accédant à une fonction en cas d'appel de fonction.

Le débogueur dbx

Il existe un autre débogueur, le débogueur dbx, pour Linux.

Le tableau suivant fournit quelques commandes dans dbx -

Commander Objectif
arrêter [var] Définit un point d'arrêt lorsque la valeur de la variable var change.
arrêter dans [proc] Il arrête l'exécution quand une procédure proc est entrée
arrêtez-vous à [ligne] Il définit un point d'arrêt sur une ligne spécifiée.
courir Démarre l'exécution.
cont Continue l'exécution.
prochain Exécute uniquement la ligne suivante de code source, sans passer par aucun appel de fonction.
étape Exécutez la ligne suivante de code source en accédant à une fonction en cas d'appel de fonction.