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

Langage Pascal Discussion :

Procédure avec un nombre variable d'arguments [FAQ]


Sujet :

Langage Pascal

  1. #1
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut Procédure avec un nombre variable d'arguments
    Salut à tout le monde !
    Je voudrais faire une procédure dont les composants (ça s'appelle comme ça ?)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure nom( composant : variable)
    sont en nombre variable.
    C'est possible ?
    6*8 =42

  2. #2
    Membre éclairé
    Avatar de hachesse
    Inscrit en
    Mars 2002
    Messages
    189
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 189
    Points : 651
    Points
    651
    Par défaut
    salut


    en general on appel ca des parametres mais on avait compris quand meme

    par contre, qu'est ce que entant par variable
    le nombre, le type, l'ordre .....

  3. #3
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    je suis pas d'accord il a demandé que le nombre de composant soit variable
    donc la a mon avis pascal ne le permet pas mais tu peux t'arrager si ces coposants sont de certain type pour pouvoir les faire passer a ta procedure par exemple en les mettant dans un fichier texte pui en les récupérant un a un dans des variables mais c'est plutot du bidouillage il existe peut etre un autre moyen ou bien tu peux les faire passer dans un tableau c plus simple mais ca exige qu'ilsoiet tous du meme type
    quoique la aussi j'ai une solution mail moi si tu veux

    voila je pense avoir répondu a ta question

  4. #4
    Membre éclairé
    Avatar de hachesse
    Inscrit en
    Mars 2002
    Messages
    189
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 189
    Points : 651
    Points
    651
    Par défaut
    je ne sais plus si le type variant existe en pascal (l'habitude de delphi ) mais si il y a un type comparable on doit pouvoir l'utiliser pour passer tout les parametres

  5. #5
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    si je pense que c est possible beaucoup plus simplemment ! il y a des pocedures comme blockwrite et reset dans lesquelle on peut metre 1 composant (appelont sa comme sa ) ou 2 ! c est sa que je vouderait faire en tous cas ! sinon je peu demmander a l utilisateur de metre comme valeur 0 a la variable et la procedure n en tient pas compte mais je vouderait quelque chose de moin ... de plus correct en faite
    6*8 =42

  6. #6
    Membre actif

    Profil pro
    Inscrit en
    Mars 2002
    Messages
    107
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 107
    Points : 279
    Points
    279
    Par défaut
    Alors, on va appeler ça des procedure paramétrés en fait !
    Si g bien compris, tu veux pouvoir faire un truc comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure maths(param : real, param2 : integer ) ;
    et que si l'utilisateur ne veut rien entrer en param2, qu'il laisse vide ???

    Bien, si c bien ça, je pense que c pas possible , histoire de compilateur.

    j'aime bien ne pas avori d'enmerdes avec hdd34, donc, je vais dire que c'est possible mais qua je ne sais pas comment faire !!!!!
    Mais a mon avis on ne peu pas tout faire en tp sauf ...
    Mais désolé, chalres , je ne peux pas te répondre.

    @+ Mathiey
    Chaque jour, l'homme crée des choses plus grandes, meilleures et sûres, et chaque jour, la nature crée des idiots plus performants. Pour l'instant, je pense que la nature gagne.

  7. #7
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    j'en suis pratiquement sur maintenant c'est absolument impossible donc la seule methode c'est passer par un tableau d'enregistrements avec un enregistrement de données qui peuvent avoir un type variable grace a un case das la déclaration du type (ya un post précédent qui en traite tu vas pouvoir trouver ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    type param=record
                    typ:string;
                    case typ of
                    ....
                    end;
             tabpar=array[1..10]of param;
     
    var tab:tabpar

  8. #8
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    moui mais c est du bricolage et je vais me perdre dans mon code .... pourtant blockwrite a un parametre variable ... sa m etonne qu on puisse pas reproduire sa ...
    6*8 =42

  9. #9
    Membre expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Points : 3 369
    Points
    3 369
    Par défaut
    Tadaa ! Me voilà !

    Bon, Charly, c'est bien beau de se référer à Write et autres procédures du même genre, mais... il ne faut pas !

    Write, tout comme Read, sont intégrées au compilateur. En fait, toutes les procédures et fonctions de l'unité System n'en sont pas réellement. Elles ont été codées en assembleur, et c'est le compilateur qui ajoute la touche finale : le nombre de paramètres.

    En effet, si on regarde la déclaration de Write, il n'y a aucun paramètre ! Un comble si on peut dire... Et pourtant ! Tu en ajoutes bien.

    En fait, et c'est malheureusement une limitation de Turbo Pascal (comblée par Delphi 3 et suivants) que l'on ne peut détourner de façon aisée.

    En fait, tu as plusieurs solutions pour arriver à tes fins.

    Soit tu te sers d'un tableau, à condition que tous tes paramètres soient du même type en faisant comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    procedure Proc(Params: array of Type);
    Tu connaîtras ensuite à l'intérieur de la procédure le nombre de paramètres à l'aide la fonction High, en prenant soin d'observer que le tableau de paramètres est à base zéro (le premier à le numéro zéro) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for i := 0 to High(Params) do ...


    La deuxième solution consiste à donner à la procédure le nombre de paramètres qu'elle est sensée recevoir, et de lui fournir l'adresse d'une zone tampon dans laquele tu stockeras tous tes paramètres en bloc, les uns derrières les autres.

    Ou bien alors, troisième solution qui est en fait la même que la deuxième, pendant que tu donnes le nombre de paramètres à prendre, tu fournis un pointeur vers ces paramètres.

    Tout ceci est évidemment peut réjouissant, et la seule réelle manière de passer outre consiste à se servir de l'assembleur.

    Tu déclareras alors ta procédure comme n'ayant aucun paramètre, mais il faudra les fournir manuellement, et appeler ta procédure à l'aide du mnémonique "call", tout en nettoyant la pile en sortie.
    Inutile de préciser que la procédure devra être écrite en assembleur pur.


    Je te laisse donc réfléchir à l'art et à la manière dont tu voudras te débrouiller pour passer tes paramètres. A moins que tu ne trouves une solution plus intéressante...


    A+
    Règles du forum
    F.A.Q Pascal

    Pour me joindre (aucune question technique, merci)

  10. #10
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    la solutions un peu plus évoluée est le tableau de types variables avec un tableau d'enregistrement!!!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    type param=record
            typ:string[10];
            CASE typ OF 
                     'int' : (par:integer); 
                     'str' : (par:string);
                     .....
            END; 
    END;

    pour utiliser ta procedure tu repli un tableau

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type
    tab=array of param;
    end;
    var tabparam:tab;
    et tu récupère tes paramètres dans ta procedure c'est tout simple
    si t'a un pb mail moi

    je suis persuadé que c'est une des solutions les pus simples

  11. #11
    Membre expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Points : 3 369
    Points
    3 369
    Par défaut
    Oui, éventuellement Régis, mais ce n'est pas parfait. Il faudrait de plus passer par les pointeurs car comme ta structure est faite, ça va peser plus de 256 octets par paramètre !

    A+
    Règles du forum
    F.A.Q Pascal

    Pour me joindre (aucune question technique, merci)

  12. #12
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    hdd la taille des varaible c'est mon gros probleme j'ai apris le pascal de façon tres scolaire et sans avoir a me soucier de ca j'ai déja faire des programme qui demandait 1000 fois plus de memoire que necessaire a cause des tableau des structure de tableau donc fo pas tro m'en vouloir la dessus j'ai pas encore les connaissances necessaires

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2002
    Messages : 35
    Points : 42
    Points
    42
    Par défaut
    et en faisant une liste chainée ?
    tu passes une liste chainée en parametre et dedans tu peux mettre 1 element ou 2 ou 10 ou 2023 etc etc ... ca pourrait ptete t'aider
    Karuto
    MCSA, MSCE (Win2K), MCDBA (SQL 2K)

  14. #14
    Membre du Club
    Inscrit en
    Mai 2002
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 47
    Points : 52
    Points
    52
    Par défaut
    tu pourrait donner un exemple je ne connais pas l'utilisation des listes chainée dans l'exemple tu pourrait mettre la décalration et le passage en parametre dans un procedure
    merci a+

  15. #15
    Membre expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Points : 3 369
    Points
    3 369
    Par défaut
    On peut en effet passer par une liste chaïnée. Donc par des pointeurs, ce que j'avais suggéré, sans évoquer le nom.

    Bonne remarque !

    A+
    Règles du forum
    F.A.Q Pascal

    Pour me joindre (aucune question technique, merci)

  16. #16
    Membre émérite

    Homme Profil pro
    Urbaniste
    Inscrit en
    Mars 2002
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Mars 2002
    Messages : 255
    Points : 2 717
    Points
    2 717
    Par défaut
    Oui, virer vos images.

    Pour passer un nombre variable d'arguments, en langage C ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void fct (const char *format, ...)
    {
      va_arg Args;
      va_start (format,Args);
      ...
      va_end (Args);
    }
    où on peut utilise va_arg (Args,<type>); dans "...".

    Format est une chaîne de caractère contenant des identifiants débutant par "%" : "%u" = nombre entier non signé par exemple.

    Reprogrammer ça en Pascal ne serait pas difficile, or la limitation : "procedure fct (format: String; ...)" : le "..." n'est pas autorisé pour des arguments d'une fonction.

    En gros : ce n'est pas possible de passer un nombre variable d'arguments. Je vais voir dire : c'est normal! Ormis l'affichage d'une chaîne à l'écran, aucune fonction n'a besoin d'un nombre variable d'argument.

    Ex: Somme de 14,9,34 -> On créer la liste {14,9,34} et on appelle "procedure Somme (L: Liste);" avec L=notre liste.

    Ex: Joindre les chaînes "a", "b", "c" : on appelle Joindre(Joindre("a,"b"),"c").

    Ex: Créer une matrice NxM où N et M sont variables -> on créer une liste de taille N qui contient des listes de taille M ;-)

    Si vous ne savez pas programmer des listes : retourner à l'école! Pour ceux qui sont trop vieux : je veux bien vous donner des cours du soir :
    Liste statique :
    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
     
    const TAILLE_MAX_LISTE = 50;
    type TypeElement = Word;
    type Liste: record
      Nbr: Word;
      Element: Array[0..TAILLE_MAX_LISTE-1] of TypeElement;
      end;
    var L: Liste;
    begin
      { Créer la liste 9, 14, 5 }
      L.Nbr := 3;
      L.Element[0] := 9;
      L.Element[1] := 14;
      L.Element[2] := 5;
      ...
    end.
    Gros problème : ça bouffe beaucoup de mémoire, il y a toujours TAILLE_MAX_LISTE éléments alloués, alors qu'on en utilise que 3, 4 ou 20 ...

    Il y a alors les listes chaînes : chaque élément pointe sur le suivant, et le dernier pointe sur rien (valeur 0 = NIL en Pascal, NULL en C). Faut savoir bien maitriser l'allocation/libération de mémoire pour faire ça.

    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
     
    { plus de maximum }
    type TypeElement = record
    val: Word;
    Suivant: ^TypeElement; { ^nom = pointeur sur un élement de type nom }
    end;
    type Liste: ^TypeElement;
    var L,P: Liste;
    begin
      { Créer la liste 9, 14, 5 }
      GetMem (P,sizeof(TypeElement));
      P^.val := 5; { var^ = accès aux données d'un pointeur, ne jamais l'oublier le "^" !!! }
      P^.suiv := NIL;
      L = P;
     
      GetMem (P,sizeof(TypeElement));
      P^.val := 14;
      P^.suiv := L;
      L := P;
     
      GetMem (P,sizeof(TypeElement));
      P^.val := 9;
      P^.suiv := L; 
      L := P;
     
      etc.
     
      { on lièbre la mémoire }
      while L<>NIL do
      begin 
       P := L^.suiv;
        Dispose (L);
        L := P;
      end;
    end.
    Problème :
    * Comme vous le voyez, on entre les nombre dans le sens inverse, car on fait toujours des "ajouts en tête" (ajout au début de la liste). Solution : on peut stocker un pointeur sur l'élément précédent plutôt que l'élément suivant. Ou bien : pour une liste, avoir un pointeur sur le premier élément, et un sur le dernier.
    * Autre problème : pour accéder à l'élément numéro 3, il faut faire :
    P := L;
    for i := 1 to 3-1 do begin
    P := P^.Suivant;
    end;
    Et si on prend 10000 plutôt que 3, je vous laisse imaginer le temps que ça prend :-/

    Astuce :
    Ecrire des listes "doublement chaînées" = pour chaque élément, avoir un pointeur sur l'élément suivant ET l'élément précédent, ça permet de facilement effacer un élément en plein millieux de la liste, ou bien d'en insérer un quelque part.

    Je vais laisse potasser ça, si vous voulez je pourrai vous écrire le code pour l'insertion d'un élément, l'ajout en queue, etc.

    Allez @+ Haypo

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/03/2013, 11h16
  2. fct avec un nombre variable d'argument.
    Par hpfx dans le forum Débuter
    Réponses: 3
    Dernier message: 11/01/2009, 21h46
  3. [Fortran 90] Nombre variable d'arguments
    Par Zoera dans le forum Fortran
    Réponses: 2
    Dernier message: 08/03/2005, 13h08

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