Utilisation correcte des modules, fonctions et sous-routines en Fortran
J'ai récemment appris à propos de l'interface des blocs lors de l'ajout d'une fonction de mon programme Fortran. Tout fonctionne belle et bien, mais maintenant je veux ajouter une deuxième fonction dans le bloc d'interface.
Voici mon bloc d'interface:
interface
function correctNeighLabel (A,i,j,k)
integer :: correctNeighLabel
integer, intent(in) :: i,j,k
integer,dimension(:,:,:),intent(inout) :: A
end function
function correctNeighArray (B,d,e,f)
character :: correctNeighArray
integer, intent(in) :: d,e,f
character, dimension(:,:,:),intent(inout) :: B
end function
end interface
Il me semble que cela peut ne pas être la meilleure option.
J'ai regardé dans les sous-routines, mais je ne suis pas très convaincu que c'est la bonne solution. Ce que je suis en train de faire est relativement simple, et j'ai besoin de passer des arguments à la sous-routine, mais tous les sous-programmes, j'ai vu sont a) compliqué (c'est à dire trop compliqué pour une fonction), et b) ne prennent pas les arguments. Ils se comportent comme s'ils manipuler les variables sans leur passé pour eux.
Je n'ai pas vraiment regardé dans les modules correctement, mais de ce que j'ai vu c'est pas la bonne chose à utiliser.
Qui dois-je utiliser quand et comment dois-je faire mieux?
- En Fortran, c'est de 'caractère' non 'char'
Vous devez vous connecter pour publier un commentaire.
Modules sont toujours de la bonne chose à utiliser 😉
Si vous avez un très simple F90 programme, vous pouvez inclure des fonctions et sous-routines dans la "contient" bloc:
Puis l'interface avec les fonctions/sous-programmes seront connus dans le programme et n'ont pas besoin d'être définie dans un bloc d'interface.
Pour des programmes plus complexes, vous devez garder toutes les fonctions/sous-routines dans les modules et de les charger lorsque requis. Si vous n'avez pas besoin de définir des interfaces, soit:
Le module et le programme peut (devrait) être dans des fichiers séparés, mais le module doit être compilé avant le programme.
mysub
, mais vous le fermez. Est-ce possible? Vous faites la même chose dans le deuxième bloc de codage. Sont ces supposés êtreend function myfunc
lignes? Donc, je peux décaler mes fonctions dans un nouveau module et il devrait fonctionner comme ça, et je peux appeler les fonctions que s'ils sont dans le programme principal? Je crois que je vois comment cela fonctionne. Merci beaucoup.implicit none
nécessaire dans chaque contenues procédure si le module contenant ces procédures a égalementimplicit none
?Pour l'appuyer et l'extension de ce qui a déjà été dit. Il est préférable de mettre vos procédures (fonctions et sous-routines) dans les modules et les "utilisent" parce que eux, vous obtenez automatiquement la vérification de la cohérence des interfaces avec peu d'effort. Les autres méthodes ont des inconvénients. Si vous définissez l'interface avec un bloc d'interface, alors vous avez trois choses à conserver au lieu de deux: l'interface, la procédure elle-même et de l'appel. Si vous faites un changement, puis tous les trois doivent être modifiés pour être compatibles. Si vous utilisez un module, seulement deux ont à être changé. Une raison de l'utilisation d'un bloc d'interface est si vous n'avez pas accès au code source (par exemple, pré-compilés de la bibliothèque) ou le code source est dans une autre langue (par exemple, vous utilisez le code en C via l'ISO C Contraignant).
L'inconvénient de la "contient" est que contenait des procédures d'hériter de toutes les variables locales du programme parent ... ce qui n'est pas très modulaire et peut être très déroutant si vous oubliez cette "fonctionnalité".
alexurba et ESM réponses sont correctes et utiles, comme d'habitude; permettez-moi seulement de chair un peu plus de détails sur un seul point, si les modules sont la voie à suivre (et ils le sont), ce sont des interfaces pour tous?
Pour les fonctions et sous-routines dans les modules, tout ce qui
use
s qui module automatiquement voir ces interfaces; les interfaces sont générés lorsque le module est compilé (que des informations, entre autres choses, va dans l' .mod fichier qui est généré lors de la compilation d'un module). Si vous n'avez pas besoin de l'écrire vous-même. De même, lorsque vous utilisez unCONTAIN
ed sous-programme (qui, d'accord avec le MSB, je trouve plus de confusion, alors utile - ils sont beaucoup mieux pensé que fermetures ou imbriquée des sous-routines de sous-programmes externes), le programme principal peut déjà "voir" l'interface de façon explicite et il n'a pas besoin de vous l'écrire pour elle.Interface blocs sont pour vous ne peut pas ce faire, lorsque le compilateur n'est pas capable de générer l'interface explicite pour vous, ou si vous voulez quelque chose de différent que ce qui est donné. Un exemple est lorsque vous utilisez C-Fortran interopérabilité en Fortran 2003. Dans ce cas, le code Fortran est un lien à l'encontre de certains de la bibliothèque C (dire) et n'a aucun moyen de générer une bonne interface fortran pour la routine C pour vous-que vous avez à faire vous-même, en écrivant votre propre bloc d'interface.
Un autre exemple est lorsque vous ne le savez déjà les interfaces des sous-routines, mais lorsque vous souhaitez créer une nouvelle interface pour "masquer" les sous-routines derrière - par exemple, lorsque vous avez une routine qui fonctionne sur la base (dire) des entiers, et l'autre sur des réels, et que vous voulez être en mesure d'appeler la routine même nom sur les deux et laisser le compilateur faire le tri en fonction sur les arguments. De telles constructions sont appelés routines génériques et ont été autour depuis le Fortran 90. Dans ce cas, vous créez une interface explicite de ce nouveau générique de la routine, et la liste des interfaces à la "vraie" routines au sein de ce bloc d'interface.