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

C Discussion :

Macro récursives en C


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Par défaut Macro récursives en C
    Salut à tous,

    Je me demandais comment faire une macro récursive en C.

    J'ai pas mal cherché mais je n'ai pas trouvé d'exemple clair qui marchait.
    Si quelqu'un pouvait me donner un exemple clair.

    Est-il possible de faire des boucles en macro préprocesseur ? par exemple de générer x fois une ligne de code.

    Merci d'avance

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 299
    Par défaut
    Salut, tu peux faire ceci comme macro :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #define MAMACRO \
    do{\
     
    ici tu écris tout ton code et tu rajoute un "\" à la fin de chaque ligne
    }\
    while(0)
    J'utilise quotidiennement 2 macros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #define FREE(p) \  /* liberation de la memoire et remise a NULL du pointeur */
    do{\
      free(p);\
      p = NULL;\
    }\
    while(0)
     
    #define FCLOSE(fid) \ /* fermeture d'un fichier et remise a NULL du pointeur */
    do{\
      fclose(fid); \
      fid = NULL; \
    }\
    while(0)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Par défaut
    Oui, mais ce genre de macro va seulement remplacer l'appel de la macro par la boucle à la compilation.
    Ce que je cherche à faire, c'est une boucle ou une macro récursive qui permettrait d'écrire x lignes de codes à la compilation.

    Je voudrais que la boucle (ou la récursion) soit exécutée à la compilation.

    Je sais que c'est possible mais je n'ai toujours pas trouvé d'exemple.

    PS : J'ai conscience de la "non propreté" de ce genre de code, mais là n'est pas la question.

  4. #4
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par Mikediten
    Je voudrais que la boucle (ou la récursion) soit exécutée à la compilation.
    Cette phrase est un peu confuse.
    écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    puts("Hello");
    puts("Hello");
    puts("Hello");
    puts("Hello");
    puts("Hello");
    Donnera le même résultat que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    unsigned i;
    for(i=0; i<5; i++)
    	puts("Hello");
    tu pourrais donc tout simplement faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #define FOO(n) do{ \
    size_t i;
    for(i=0; i<n; i++)
    {	/* Traitement */
    	puts("Hello\n");
    }
    while(0)
    Citation Envoyé par Mikediten
    Je sais que c'est possible mais je n'ai toujours pas trouvé d'exemple.
    J'en doute, une macro du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define MACRO puts("Hello"); MACRO
    Donnera
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    puts("Hello"); MACRO
    et non
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    puts("Hello");  puts("Hello");  puts("Hello");  puts("Hello"); ...
    La récursion n'est donc pas possible et c'est tant mieux !
    Citation Envoyé par ISO/IEC 9899:TC3 / 6.10.3.4 Rescanning and further replacement
    If the name of the macro being replaced is found during this scan of the replacement list
    (not including the rest of the source file’s preprocessing tokens), it is not replaced.
    Furthermore, if any nested replacements encounter the name of the macro being replaced,
    it is not replaced. These nonreplaced macro name preprocessing tokens are no longer
    available for further replacement even if they are later (re)examined in contexts in which
    that macro name preprocessing token would otherwise have been replaced.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    A ma connaissance, c'est pas possible.

    C'est quoi qui est gênant avec une boucle classique ??? Car au final, ça revient au même. Que tu exécutes 5 fois une même instruction ou qu'une boucle la fasse exécuter 5 fois, je ne vois pas la différence, mis à part l'utilisation d'une variable supplémentaire (pour le compteur), d'instructions servant à gérer le test de la condition et le saut conditionnel.

    Si c'est un soucis de simplification d'écriture, tu peux même feinter de cette façon par exemple :
    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
    #include<stdio.h>
    #include <stdlib.h>
     
    #define LOOP(nombre) { int compteur=0; \
    while (compteur<nombre) {
    #define ENDLOOP \
    compteur++; \
    } }
     
    int main(void)
    {
     
        LOOP(10)
        printf("hello\n"); /* instruction à exécuter X fois */
        ENDLOOP
     
        return EXIT_SUCCESS;
    }
    EDIT : Mince, grilled... lol

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Par défaut
    Je me suis mal faire comprendre.

    Quand je dis :

    Je voudrais que la boucle (ou la récursion) soit exécutée à la compilation.
    Je veux dire que les macros sont exécutées à la compilation, ce qui n'est pas le cas du code C (exemple : while, puts etc.) qui est exécuté à l'exécution du binaire.
    Toutes les solutions que vous me proposez sont exécutées à l'exécution et non à la compilation.

    Par exemple en C++, on peut faire des templates récursifs, tous les calculs se feront à la compilation.

    Moi je voudrais faire une boucle (ou une récursion) qui génère des lignes de code (par exemple : puts("Hello"); 50 fois ). Mais que ces 50 lignes de code soient générées au moment de la compilation, pas à l'exécution par une simple boucle while.
    Par exemple, si j'ai oublié de mettre Hello entre guillemets dans la boucle de ma macro, je voudrais avoir 50 erreurs de compilation.

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Je me suis mal faire comprendre.
    Non, non. C'est très clair depuis le début.
    Mais je crains qu'en C, ça ne soit pas possible. En tout cas, à ma connaissance. En outre, le C est beaucoup plus soft que le C++.

    Mais que reproches-tu à la méthode de la boucle classique ? Au final, ça fera la même chose. Car quelle différence trouves-tu entre :
    1) Ecrire 50 instructions similaires, et donc exécutées 50 fois;
    2) Ecrire une seule instruction, mais bouclée 50 fois
    ??

    Lors de l'exécution, ça fait la même chose, on n'y voit que du feu...

    Par exemple, si j'ai oublié de mettre Hello entre guillemets dans la boucle de ma macro, je voudrais avoir 50 erreurs de compilation.
    Je ne vois pas en quoi en quoi c'est mieux d'avoir 50 erreurs au lieu d'une. Dans tous les cas, il suffit d'une seule erreur pour que la compilation s'arrête.

    Qu'est-ce que tu veux faire concrètement ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Par défaut
    Le point de départ de cette réflexion, c'était un défi, faire le plus grand nombre d'erreurs de compilation avec un code source en C de moins de 100 caractères.

    J'avais donc pensé aux macros récursives qui "gonfleraient" mon code, en copiant x fois une ligne avec une erreur.

    Enfin vous avez peut être d'autres idées pour y arriver.

    PS : c'est stupide comme jeu, mais bon ça demande plus de réflexions que ça en a l'air. J'ai des amis qui arrivent à faire plus de 350 000 lignes d'erreurs de compilation, enfin je connais pas leurs méthodes, chacun expérimente la sienne.

  9. #9
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Citation Envoyé par Mikediten
    ...c'est stupide comme jeu...
    Tu m'étonnes

    Citation Envoyé par Mikediten
    ...J'ai des amis qui arrivent à faire plus de 350 000...
    C'est tout ? Voilà ce que tu peux faire pour avoir des erreurs à l'infini (testé sous gcc version 4.3.2 )

    Code ouch.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /* en DEUX lignes */
    #include "ouch.c"
    #include "ouch.c"

    je n'ai pas envie de griller mon processeur pour prouver quoi que ce soit, je te laisse donc compiler ce code et faire le compte

Discussions similaires

  1. Macro - balayer cellules tableau et fonction récursive
    Par juliette32 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 09/05/2014, 00h59
  2. Procédure Récursives
    Par DocCoinCoin dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 30/10/2002, 19h27
  3. [VBA-E] [Excel] Lancer une macro à une heure donnée
    Par Lysis dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 16/10/2002, 12h15
  4. Qu'est-ce qu'une macro ?
    Par karli dans le forum Assembleur
    Réponses: 2
    Dernier message: 01/09/2002, 03h38
  5. Réponses: 2
    Dernier message: 22/07/2002, 12h13

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