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 :

programme simple et makefile


Sujet :

Fortran

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut programme simple et makefile
    Salut tous,

    je viens vous voir car je suis totalement novice en Fortran et j'aimerais commencer mon premier programme avec votre aide.

    Pourriez vous me montrer, svp, comment faire:
    - definir deux variables réelles A et B dans mon programme principal
    - une fonction (dans un autre fichier) qui fait l'opération A/B
    - renvoyer le résultat dans le programme principal et l'écrire dans la console
    - le makefile qui permet de lancer ce programme

    J'espère qu'une bonne âme pourra me montrer comment faire ceci, ensuite je pense que je pourrais me débrouiller seul avec fortran

    merci beaucoup

    ps: je ne souhaite pas utiliser d'EDI juste des fichiers textes et un makefile

  2. #2
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Bonjour,

    Un example qui fait juste le job (en écriture séparée). Pas de garde-fou sur les intentions de modifier ou non les arguments (fortran passe les arguments par référence) etc. mais ça fait le job. Je ne mets pas de makefile car il est inutile ici, ce n'est pas de la compilation séparée, mais juste de l'écriture séparée (gfortran main.f compile le programme complet). Je mets juste une "function" et une "subroutine" en exemple car tu demandes une fonction et j'utilise plus les sous-routines.

    functions.f
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    subroutine sub_div_a_b(a,b,res)
        implicit none
        double precision :: a, b, res
        res=a/b
        return
    end subroutine sub_div_a_b
     
    double precision function func_div_a_b(a,b)
        implicit none
        double precision :: a, b
        func_div_a_b=a/b
        return
    end function func_div_a_b
    main.f
    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
     
    include "functions.f"
    program main
        implicit none
        double precision :: ad, bd, resd
        double precision :: func_div_a_b
     
        ad=3.d0
        bd=2.d0
     
        call sub_div_a_b(ad,bd,resd)
        print *, "double(sub)  : ",ad,"/",bd,"=",resd
        resd=func_div_a_b(ad,bd)
        print *, "double(func) : ",ad,"/",bd,"=",resd
     
    end program main
    Mais fortran est beaucoup plus riche que cela, et dans ses moutures post-90, il peut devenir assez élégant (l'élégance, c'est subjectif).
    Un exemple plus structuré suit avec un makefile et dont les sources contiennent qques mots clefs supplémentaires qui apportent qques avantages en programmation moderne (polymorphisme de types simples ou de tableaux de types simples, allocation dynamique, programmation modulaire...).
    Il sait aussi gérer les pointeurs, au moins certains aspects de POO, etc...

    module de sous-routines sub_div.f
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    module sub_div
     
        private
        public:: sub_div_a_b
        interface sub_div_a_b
            module procedure sub_div_a_b_i, sub_div_a_b_f, sub_div_a_b_d, sub_div_a_b_c
        end interface
     
        contains
            !INTEGER
            elemental subroutine sub_div_a_b_i(a,b,res)
                implicit none
                integer, intent(in)  :: a, b
                integer, intent(out) :: res
                res=a/b
                return
            end subroutine sub_div_a_b_i
            !REAL SIMPLE PRECISION
            elemental subroutine sub_div_a_b_f(a,b,res)
                implicit none
                real, intent(in)  :: a, b
                real, intent(out) :: res
                res=a/b
                return
            end subroutine sub_div_a_b_f
            !REAL DBLE PRECISION
            elemental subroutine sub_div_a_b_d(a,b,res)
                implicit none
                double precision, intent(in)  :: a, b
                double precision, intent(out) :: res
                res=a/b
                return
            end subroutine sub_div_a_b_d
            ! COMPLEX
            elemental subroutine sub_div_a_b_c(a,b,res)
                implicit none
                complex, intent(in)  :: a, b
                complex, intent(out) :: res
                res=a/b
                return
            end subroutine sub_div_a_b_c
     
    end module sub_div
    programme principal main.f
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    program main
        use sub_div
        implicit none
        integer          :: ai, bi, resi
        real             :: af, bf, resf
        double precision :: ad, bd, resd
        complex          :: ac, bc, resc
        double precision, dimension(:), allocatable :: at, bt, rest
     
        allocate (at(2),bt(2),rest(2))
     
        ai=3
        bi=2
        af=3.0
        bf=2.0
        ad=3.d0
        bd=2.d0
        ac=(3.0,0.0)
        bc=(0.0,2.0)
     
        at(1)=acos(-1.d0)
        bt(1)=2.d0
        at(2)=3.d0
        bt(2)=2.d0
     
        call sub_div_a_b(ai,bi,resi)
        print *, "integer: ",ai,"/",bi,"=",resi
        call sub_div_a_b(af,bf,resf)
        print *, "float    : ",af,"/",bf,"=",resf
        call sub_div_a_b(ad,bd,resd)
        print *, "double : ",ad,"/",bd,"=",resd
        call sub_div_a_b(ac,bc,resc)
        print *, "complex: ",ac,"/",bc,"=",resc
        call sub_div_a_b(at(:),bt(:),rest(:))
        print *, "dptable: ",at(1),"/",bt(1),"=",rest(1)
        print *, "dptable: ",at(2),"/",bt(2),"=",rest(2)
     
        deallocate (at,bt,rest)
     
    end program main
    et makefile:
    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
    comp=gfortran
    cflags=-Wall -Wextra -ffree-form -std=f2003 -pedantic 
     
    all: prog execute
     
    sub_div.o: sub_div.f
    	$(comp) $(cflags) -o $@ -c $^
     
    main.o: main.f
    	$(comp) $(cflags) -o $@ -c $^
     
    prog: sub_div.o main.o
    	$(comp) $(lflags) -o $@ $^
     
    clean:
    	rm sub_div.o sub_div.mod main.o
     
    execute:
    	./prog

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    merci énormément !!!!!

    Puis je profiter un tout petit peu encore de ta gentillesse et te poser 2 questions sur ce que tu m'as envoyé ?

    - pourquoi as tu mis "double precision ::", dans les programmes que j'ai vu je n'ai jamais vu ceci mais plutôt des trucs style REAL*8 ? (je crois que c'est du vieux fortran que j'ai besoin pour faire des subroutines sous le logiciel abaqus)

    - et si je veux utiliser que des REAL*8 (car c'est ce que je vois en général dans les programmes déjà existant que je dois comprendre) comment le définir pour les fonctions ?

  4. #4
    Membre averti
    Homme Profil pro
    [SciComp]
    Inscrit en
    Août 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : [SciComp]

    Informations forums :
    Inscription : Août 2013
    Messages : 134
    Points : 323
    Points
    323
    Par défaut
    Bonsoir,

    real*8 code les entiers sur 8 octets, soit l'équivalent de la double précision sur de nombreuses machines (peut-être toutes, je ne sais pas). Ce mode de déclaration (::) et la double precision sont utilisées dans les nouvelles moutures du langages, alors que REAL*8 est vraiment legacy f77.

    En mode héritage f77 justement, l'exemple simple donnerait :
    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
    23
    24
           SUBROUTINE sub_div_a_b(a,b,res)
           IMPLICIT NONE
           REAL*8 a, b, res
           res=a/b
           END
     
           REAL*8 FUNCTION func_div_a_b(a,b)
           IMPLICIT NONE
           REAL*8 a, b
           func_div_a_b=a/b
           END
     
           PROGRAM main
    C je ne pense pas que IMPLICIT NONE soit stdf77 mais bon
           IMPLICIT NONE 
           REAL*8 ad, bd, resd
           REAL*8 func_div_a_b
           ad=3.d0
           bd=2.d0
           CALL sub_div_a_b(ad,bd,resd)
           PRINT *, "double(sub)  : ",ad,"/",bd,"=",resd
           resd=func_div_a_b(ad,bd)
           PRINT *, "double(func) : ",ad,"/",bd,"=",resd
           END
    Cordialement,
    xflr6

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2010
    Messages
    2 051
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 2 051
    Points : 877
    Points
    877
    Par défaut
    merci beaucoup !!!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. programme simple mais besoin d'aide
    Par newvo dans le forum Windows
    Réponses: 15
    Dernier message: 07/03/2007, 16h56
  2. Réponses: 11
    Dernier message: 12/12/2006, 00h53
  3. Quel langage de programmation pour des programmes simples ?
    Par Pierre.g dans le forum Langages de programmation
    Réponses: 18
    Dernier message: 22/11/2006, 14h22
  4. Programme "simple" devient très lent ?
    Par Invité dans le forum Delphi
    Réponses: 8
    Dernier message: 18/09/2006, 22h32
  5. Création de programme simple
    Par mz-hacker dans le forum Windows
    Réponses: 1
    Dernier message: 06/08/2006, 00h34

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