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 |
Où | 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. |