IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Fortran Discussion :

Retour de valeur d'une subroutine


Sujet :

Fortran

  1. #1
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut Retour de valeur d'une subroutine
    Bonjour,
    Gros trou :
    comment récupérer "une_valeur" calculée dans "machin" dans le prog principal
    Merci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    program truc
    integer valeur
    .
    .
    call machin(avec ou sans parametres)
    valeur=une_valeur
    .
    .
    end
     
    subroutine machin(...)
    une_valeur=f(variable interne ou externe)
    end

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    98
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 98
    Points : 107
    Points
    107
    Par défaut
    Salut,

    Je te propose les 2 méthodes suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    program truc
    implicit none
    integer :: valeur, une_valeur
    .
    call machin(avec ou sans parametres)
    valeur=une_valeur
    .
    contains
     
    subroutine machin(...)
    implicit none
    une_valeur=f(variable interne ou externe)
    end
     
    end program
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    program truc
    implicit none
    integer :: valeur, une_valeur
    .
    call machin(une_valeur)
    valeur=une_valeur
    .
    end program
     
    subroutine machin(une_valeur)
    implicit none
    integer, intent(out) :: une_valeur
    une_valeur=f(variable interne ou externe)
    end

  3. #3
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Merci.
    Cependant, c'est du 77? J'utilise gfortran. DE ce que je comprends de ton code tu déclare une_valeur comme globale mais tu la passes comme parametre quant même.
    Et intent(out), je ne connais pas, mais apparemment cela permet de la renvoyer ?
    Merci.

  4. #4
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    alors, les intent, c'est du F90 cela permet de déclarer une variable paramètre d'une subroutine/fonction comme entrante sortante ou les deux...

    cela dit, si tu est en 77 tu peux utiliser la seconde solution de afransico sans les intent et ce devrai être bon...

    sinon troisième solution, tu transforme ta subroutine en fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    program truc
    implicit none
    integer valeur
    .
    .
    valeur= machin(avec ou sans parametres)
     
    .
    .
    end
     
    function machin(...)
    impliciti none
    integer machin
    une_valeur=f(variable interne ou externe)
    machin=une_valeur
    return
    end
    il est préférable, de mettre return en fin de fonction, mais aussi de subroutine...
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  5. #5
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Merci.
    Le :: ce n'est pas du 77 il me semble ? Et désigne quoi? J'ai déjà vu cela en c++ mais je ne pense pas que cela fasse la même chose puisque c'est dans le contexte de la création d'objet à partir d'une classe (évidemment).
    Donc, je retiens qu'en 77 ma question n'a pas de réponse, et qu'une façon est de transformer la routine en fonction.
    Il est vrai que si je n'ai qu'une valeur à ressortir cela paraît le choix logique.
    A confirmer, je vais essayer.
    Merci.

  6. #6
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par nyme92 Voir le message
    Donc, je retiens qu'en 77 ma question n'a pas de réponse, et qu'une façon est de transformer la routine en fonction.
    Tu peux passer par un COMMON BLOCK, mais c'est moche. Sinon, il semble en effet assez logique de passer la valeur que tu souhaites retourner en argument d'une subroutine ou en valeur retournee par une fonction.

  7. #7
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    passer la valeur que tu souhaites retourner en argument d'une subroutine ou en valeur retournee par une fonction.
    la question d'origine concerne le retour d'un ou plusieur valeur(s) à partir d'un subroutine : comment ?
    La fonction est plus logique mais ne permet qu'une seule valeur.

  8. #8
    Membre éclairé Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Points : 825
    Points
    825
    Par défaut
    et bien tu peux tout à fait renvoyé un tableau par une fonction.

    et pour le ::, c'est juste pour séparé le type (+option) du/des noms de variables exemple:
    est équivalent à ces :: deviennent indispensable quand tu mets des options sur ta variable exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    integer,dimension(N) :: a
    de plus tu peux aussi passer un tableau par paramètre dans une fonction ou une subroutine. il me semble qu'en 77 il n'y a pas les tableaux dynamique (ALLOCATABLE) mais bon tu defini un tableau suffisament grand pour tes différents cas et hop!

    si j'essaye de le faire en 77 cela donnerai un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    C234567
           program toto
           implicit none
           parameter (N=100)
           integer valeur
           dimension valeur(N)
         ....
           call titi(valeur,N)
         ....
           end
     
           subroutine titi(valeur,N)
           implicit none
           integer valeur,N
           dimension valeur(*)
         ....
           valeur(1)=...
           valeur(8)=...
         ....
           return
           end
    il n'y a que ceux qui savent qui ne savent pas qu'ils savent...
    Libere-toi hacker, GNU's Not Unix!!!

  9. #9
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par nyme92 Voir le message
    la question d'origine concerne le retour d'un ou plusieur valeur(s) à partir d'un subroutine : comment ?
    Ben, c'est trivial. Une routine accepte des arguments pour communiquer avec le code appelant.
    En Fortran 77:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
          program toto
          implicit none
     
          real a, b
     
          call set_a_and_b(a, b)
          print *, a, b 
          end
     
          subroutine set_a_and_b(a, b)
          real a, b
     
          a = 42.0
          b = 53.0
          end

  10. #10
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par genteur slayer Voir le message
    et bien tu peux tout à fait renvoyé un tableau par une fonction.

    et pour le ::, c'est juste pour séparé le type (+option) du/des noms de variables exemple:
    est équivalent à ces :: deviennent indispensable quand tu mets des options sur ta variable exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    integer,dimension(N) :: a
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    integer,dimension(N) :: a    = integer a(N)
    de plus tu peux aussi passer un tableau par paramètre dans une fonction ou une subroutine. il me semble qu'en 77 il n'y a pas les tableaux dynamique (ALLOCATABLE) mais bon tu defini un tableau suffisament grand pour tes différents cas et hop!

    si j'essaye de le faire en 77 cela donnerai un truc du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    C234567
           program toto
           implicit none
           parameter (N=100)
           integer valeur
           dimension valeur(N)
         ....
           call titi(valeur,N)
         ....
           end
     
           subroutine titi(valeur,N)
           implicit none
           integer valeur,N
           dimension valeur(*)
         ....
           valeur(1)=...
           valeur(8)=...
         ....
           return
           end
    Donc cela veut bien dire que les valeurs calculées dans la subroutine doivent être déclarées en global ET dans la subroutine.

  11. #11
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par nyme92 Voir le message
    Donc cela veut bien dire que les valeurs calculées dans la subroutine doivent être déclarées en global ET dans la subroutine.
    Il n'y a pas de variables globales en Fortran. Quand aux declarations, chaque variable doit etre definie au point d'utilisation (point d'entree, sous-routines, et fonctions).
    Quel est ton niveau en Fortran? Cela permettra de donner des reponses plus adaptees.

  12. #12
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Il n'y a pas de variables globales en Fortran. Quand aux declarations, chaque variable doit etre definie au point d'utilisation (point d'entree, sous-routines, et fonctions).
    Quel est ton niveau en Fortran? Cela permettra de donner des reponses plus adaptees.
    Intéressant.
    Effectivement, les variables sont toutes locales. J'ai confondu sans doute avec un autre langage, Pascal peut-être (à force d'utiliser des langages on y perd son latin).
    Pour répondre à ta question, j'en fait depuis 92 mais je ne me suis jamais posé la question. Ce n'est que parce que je suis en train de reprendre un prog laissé de côté depuis longtemps que je me suis posé la question.

    Alors, si j'utilise A dans le prog principal, puis A dans une sub mais pour autre chose, ce seront deux A différents. Sans doute pointent-ils vers des adresses différentes.
    Donc la valeur de A obtenue dans la sub ne sera pas repercutée dans le prog principal.

  13. #13
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par nyme92 Voir le message
    Alors, si j'utilise A dans le prog principal, puis A dans une sub mais pour autre chose, ce seront deux A différents. Sans doute pointent-ils vers des adresses différentes.
    Non. Le Fortran passe les variables par reference (comme le & du C++) et non par valeur comme le C. Mais cela ne veut pas dire qu'on n'a pas a definir les variables dans chaque sous-programme. Du point de vue du compilateur, les blocs definis par program...end, subroutine...end et function...end sont des entites independantes (heureusement, sinon on aurait du mal a faire de la compilation separee).

    Donc la valeur de A obtenue dans la sub ne sera pas repercutée dans le prog principal.
    Si, c'est le but. Voir l'exemple que j'ai poste precedemment.

  14. #14
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Non. Le Fortran passe les variables par reference (comme le & du C++) et non par valeur comme le C. Mais cela ne veut pas dire qu'on n'a pas a definir les variables dans chaque sous-programme. Du point de vue du compilateur, les blocs definis par program...end, subroutine...end et function...end sont des entites independantes (heureusement, sinon on aurait du mal a faire de la compilation separee).


    Si, c'est le but. Voir l'exemple que j'ai poste precedemment.
    Donc le but des subs et fns est uniquement du déplacement de code afin d'en faciliter la visibilité. Il n'y a aucune fioriture de portée de variables.
    Celles-ci doivent être déclarées où elles sont utilisées.

  15. #15
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par nyme92 Voir le message
    Donc le but des subs et fns est uniquement du déplacement de code afin d'en faciliter la visibilité.
    Et la factorisation du code. C'est comme dans la plupart des autres langages.

    Il n'y a aucune fioriture de portée de variables.
    Par rapport au C, le Fortran ne possede pas les portees globales et de bloc. Mais il y a evidemment la portee locale. Une variable locale a une fonction ou une sous-routine n'existe que jusqu'au retour de celle-ci. Pour les arguments, puisqu'ils sont passes par references, toute modification est passee a l'appelant, sauf si on utilise les intent dont on t'a parle plus haut.

    Celles-ci doivent être déclarées où elles sont utilisées.
    Oui. Le compilateur a besoin de connaitre le type et le nombre d'element de tous les objets qu'il manipule. Jadis, il etait courant d'utiliser un typage implicite, via la premiere lettre du nom de la variable. Ce n'est plus conseille aujourd'hui, et on precise souvent implicit none au debut de chaque sous-unite du programme (point d'entree, fonctions, sous-routines, modules).

  16. #16
    Rédacteur

    Homme Profil pro
    Comme retraité, des masses
    Inscrit en
    Avril 2007
    Messages
    2 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comme retraité, des masses
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 2 978
    Points : 5 179
    Points
    5 179
    Par défaut
    Salut!
    Il est évident qu'il existe une solution: sinon des subroutines qui ne permettraient pas de renvoyer des résultats au programme principal ne serviraient à rien. Mais tu dois être conscient qu'en Fortran "classique", il n'y a aucun lien entre le nom d'une variable dans le programme principal et celui de la même variable dans le sous-programme; seul compte la position dans la séquence des paramètres. Je te propose donc la solution suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
          Program Main
          Implicit None
          Integer a,b,c,d
          a=53
          b=34
          Call Sous(a,b,c,d)
          Write (*,*) c,d
          Stop
          End
    C
          Subroutine Sous(w,x,y,z)
          Implicit None
          Integer w,x,y,z
          y=w+x
          z=w-x
          Return
          End
    Si je ne me suis pas trompé, ça devrait marcher.

    Maintenant, il peut arriver que ta subroutine existe déjà. Dans ce cas, il te suffit d'ajouter à la liste des paramètres la variable locale à laquelle tu veux accéder.

    Jean-Marc Blanc
    Calcul numérique de processus industriels
    Formation, conseil, développement

    Point n'est besoin d'espérer pour entreprendre, ni de réussir pour persévérer. (Guillaume le Taiseux)

  17. #17
    Débutant
    Inscrit en
    Juillet 2007
    Messages
    386
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 386
    Points : 119
    Points
    119
    Par défaut
    je ne penses pas que tu as besoin d un stop a la fin de ton programme Jean Marc

  18. #18
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par DaZumba Voir le message
    Et la factorisation du code. C'est comme dans la plupart des autres langages.


    Par rapport au C, le Fortran ne possede pas les portees globales et de bloc. Mais il y a evidemment la portee locale. Une variable locale a une fonction ou une sous-routine n'existe que jusqu'au retour de celle-ci. Pour les arguments, puisqu'ils sont passes par references, toute modification est passee a l'appelant, sauf si on utilise les intent dont on t'a parle plus haut.


    Oui. Le compilateur a besoin de connaitre le type et le nombre d'element de tous les objets qu'il manipule. Jadis, il etait courant d'utiliser un typage implicite, via la premiere lettre du nom de la variable. Ce n'est plus conseille aujourd'hui, et on precise souvent implicit none au debut de chaque sous-unite du programme (point d'entree, fonctions, sous-routines, modules).
    Ok, merci de ce rappel!

  19. #19
    Membre du Club Avatar de nyme92
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    177
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 177
    Points : 53
    Points
    53
    Par défaut
    Citation Envoyé par FR119492 Voir le message
    Salut!
    Il est évident qu'il existe une solution: sinon des subroutines qui ne permettraient pas de renvoyer des résultats au programme principal ne serviraient à rien. Mais tu dois être conscient qu'en Fortran "classique", il n'y a aucun lien entre le nom d'une variable dans le programme principal et celui de la même variable dans le sous-programme; seul compte la position dans la séquence des paramètres. Je te propose donc la solution suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
          Program Main
          Implicit None
          Integer a,b,c,d
          a=53
          b=34
          Call Sous(a,b,c,d)
          Write (*,*) c,d
          Stop
          End
    C
          Subroutine Sous(w,x,y,z)
          Implicit None
          Integer w,x,y,z
          y=w+x
          z=w-x
          Return
          End
    Si je ne me suis pas trompé, ça devrait marcher.

    Maintenant, il peut arriver que ta subroutine existe déjà. Dans ce cas, il te suffit d'ajouter à la liste des paramètres la variable locale à laquelle tu veux accéder.

    Jean-Marc Blanc
    Effectivement, je me souviens de cette histoire d'ordre de position des variables. Merci à toi aussi.

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/02/2011, 16h39
  2. [MySQL] Retour de valeur pour une requête "select"
    Par Truebison dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 05/09/2008, 16h57
  3. Retour de valeur d'une fonction
    Par guigouz dans le forum SQL
    Réponses: 5
    Dernier message: 10/06/2008, 15h21
  4. [Tableaux] Retour de valeur d'une fonction
    Par Trebor_ dans le forum Langage
    Réponses: 5
    Dernier message: 10/03/2008, 14h24
  5. [Mail] Retour de valeur d'une fonction
    Par pat06 dans le forum Langage
    Réponses: 3
    Dernier message: 14/12/2007, 11h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo