For/While en récursif

For/While en récursif - C - Programmation

Marsh Posté le 04-04-2022 à 16:14:29    

Bonjour,
 
  Je recherche la syntaxe pour substituer mes boucles while (et accessoirement les boucles for) par des fonction récursive.
  Par contre je ne sais pas trops comment faire pour rendre le truc le plus générique possible
  notamment pour les valeurs de retour, et pour le test
 

Code :
  1. ...
  2.   int a = 0;
  3.   int b = 0;
  4.   while(a != 10)
  5. {
  6.    a++:
  7.    b+=10;
  8. }
  9. ...


 
 

Code :
  1. ...
  2. int b;
  3. func_while(10,&b)
  4. ...
  5. int func_while(int a, int *b)
  6. {
  7.    if (a == 10)
  8.       return;
  9.    *b += 10;
  10.    func_while(a++, b);
  11. }


Message édité par une IA le 04-04-2022 à 16:15:11
Reply

Marsh Posté le 04-04-2022 à 16:14:29   

Reply

Marsh Posté le 04-04-2022 à 16:23:55    

Quel est l'intérêt de la chose? :??:

Reply

Marsh Posté le 04-04-2022 à 16:48:57    

rat de combat a écrit :

Quel est l'intérêt de la chose? :??:


 
Uniformiser la notion d'enveloppe  :o  pour tenter un truc meta  :D

Reply

Marsh Posté le 04-04-2022 à 17:46:25    

Code :
  1. void
  2. f (int *a, int *b)
  3. {
  4.   if ((*a)++ >= 10)
  5.     return;
  6.   *b += 10;
  7.   f (a, b);
  8. }


 
S'appelle par :

Code :
  1. int a = 0, b = 0;
  2. f (&a, &b);

Reply

Marsh Posté le 04-04-2022 à 18:02:11    

Tiens, changement de langage ? Plus de programmation en Ada ?
 
Mais on reconnait entre mille le style de question et le pseudo qui tourne autour de l'IA.
 
Ravi de te revoir ici ! :)


---------------
On n'est jamais très fort pour ce calcul !
Reply

Marsh Posté le 04-04-2022 à 18:07:38    

J'ai pensé la même chose, mais je pense que tu fais erreur. "une IA" est sur le forum depuis longtemps si on regarde son profil, ce n'est pas une nouvelle inscription de Jo...

Reply

Marsh Posté le 05-04-2022 à 15:19:37    

J'ai simplifié de la sorte :)  
 

Code :
  1. #include <stdio.h>
  2. enum boolean{false,true};
  3. enum boolean GoEThan(int a, int *b)
  4. {
  5. return (a >= *b);
  6. }
  7. enum boolean addToValue(int *b, int *v)
  8. {
  9. *b = *b + *v;
  10. }
  11. enum boolean  fwhile(int *a, int *aa, enum boolean (*fc)(int ,int *),int *b,  enum boolean (*fa)(int *,int *), int *c)
  12. {
  13.   !((*fc)((*a)++,aa)) && (*fa)(b,c) && fwhile(a,aa,fc,b,fa,c);
  14. }
  15. int main(int argc, char *argv[])
  16. {
  17. int a = 0,  aa = 10,b = 0, c= 10;
  18. fwhile (&a,&aa,  &GoEThan, &b, &addToValue, &c);
  19. printf("%d\n",b);
  20. }


 
le compilo me refuse l'écriture de &((*a)++)
pour pouvoir faire en sorte  GoEThan(int a, int *b) prennent un int *a en premier paramère..
 
une idée ?

Message cité 1 fois
Message édité par une IA le 05-04-2022 à 15:25:37
Reply

Marsh Posté le 05-04-2022 à 15:48:21    

une IA a écrit :

J'ai simplifié de la sorte :)

Ah oui, c'est très simple à comprendre en effet. :o  
 
Nan, sérieusement, il y des languages de prog très différents du C, peut-être tu peux trouver ton bonheur avec un autre language plus adapté à ce que tu veux faire? Parce que là c'est presque digne du Obfuscated C Contest. :o

Reply

Marsh Posté le 05-04-2022 à 16:11:27    

et hop !!!
 

Code :
  1. #include <stdio.h>
  2. enum boolean{false,true};
  3. struct s_func
  4. {
  5. int *a;
  6. int *b;
  7. enum boolean (*f)(int *,int *);
  8. } ;
  9. enum boolean    GoEThan(int *nbr1, int  *nbr2){return (*nbr1 >= *nbr2);}
  10. enum boolean addToValue(int *nbr1, int  *nbr2){*nbr1 += *nbr2;}
  11. enum boolean fwhile(struct s_func *it,
  12.     struct s_func *cm,
  13.     struct s_func *ad)
  14. {
  15.   !((cm->f)(cm->a,cm->b)) && (it->f)(it->a,it->b) && (ad->f)(ad->a,ad->b) && fwhile(it,cm,ad);
  16. }
  17. int main(int argc, char *argv[])
  18. {
  19. struct s_func f[3] = {{&((int){0}),&((int) {1}),&addToValue},
  20.        {f[0].a,    &((int){10}),&GoEThan},
  21.        {&((int){0}),&((int){20}),&addToValue}};
  22. fwhile (&f[0], &f[1], &f[2]);
  23. printf("%d\n",*(f[2].a));
  24. }

Message cité 3 fois
Message édité par une IA le 06-04-2022 à 10:44:18
Reply

Marsh Posté le 05-04-2022 à 17:14:33    

rat de combat a écrit :

Ah oui, c'est très simple à comprendre en effet. :o  
 
Nan, sérieusement, il y des languages de prog très différents du C, peut-être tu peux trouver ton bonheur avec un autre language plus adapté à ce que tu veux faire? Parce que là c'est presque digne du Obfuscated C Contest. :o


 
Tu manques de diversité, peut être.
 
Regardes :) j'ai un while qui est lui même une expression logique, n'est ce pas génial ?  :bounce:  
 
Et là avec ma dernière itération youp ! je suis trop content :)
 


Message édité par une IA le 05-04-2022 à 17:15:29
Reply

Marsh Posté le 05-04-2022 à 17:14:33   

Reply

Marsh Posté le 06-04-2022 à 10:47:38    

Farian a écrit :

Tiens, changement de langage ? Plus de programmation en Ada ?
 
Mais on reconnait entre mille le style de question et le pseudo qui tourne autour de l'IA.
 
Ravi de te revoir ici ! :)


j'ai pensé la même chose, mais c'est pas lui :D


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-04-2022 à 10:49:07    

une IA a écrit :

et hop !!!
 
enum boolean fwhile(struct s_func *it,
     struct s_func *cm,
     struct s_func *ad)
{
  !((cm->f)(cm->a,cm->b)) && (it->f)(it->a,it->b) && (ad->f)(ad->a,ad->b) && fwhile(it,cm,ad);
}


 
y aurait-il moyen de rendre cette partie générique ?  
le motif while c'est un comparateur (cm), un itérateur (it) , un pointeur vers du travail a faire (ici ad) , et un goto (ici le rappel de function);
 
garder le motif, et faire la mise en lien en amont...


Message édité par une IA le 06-04-2022 à 10:49:33
Reply

Marsh Posté le 06-04-2022 à 10:54:00    

mais arrête, c'est juste illisible ton truc  [:fegafobobos:2]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-04-2022 à 11:12:39    

Harkonnen a écrit :

mais arrête, c'est juste illisible ton truc  [:fegafobobos:2]


 
non non non  :o  
je veux ma séparation radicale le plus bas possible, entre (la partie donnée) et (la logique) et (la modification de la donnée).  
par contre le choix du sujet n'est peut être pas pertinent  :whistle:
 
 
->  à haut niveau c'est comme les gens qui mettent toutes leur variables en BDD,  permettant ainsi de freezer l'état de la machine a tout moment, et reléguer la partie structuration de la donnée au moteur de BDD.  

Reply

Marsh Posté le 07-04-2022 à 20:55:50    

Harkonnen a écrit :

mais arrête, c'est juste illisible ton truc  [:fegafobobos:2]

C'est du lisp, non ? mais en C
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 08-04-2022 à 08:36:14    

gilou a écrit :

C'est du lisp, non ? mais en C
A+,


c'est carrément la fête du lisp :o


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 10-04-2022 à 22:33:30    

Harkonnen a écrit :


j'ai pensé la même chose, mais c'est pas lui :D


Pareil, pseudo en rapport avec l'IA + topic au but barré = grosse proba de penser au retour de qui on sait :D


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 10-04-2022 à 22:37:51    

une IA a écrit :

et hop !!!
 

Code :
  1. #include <stdio.h>
  2. enum boolean{false,true};
  3. struct s_func
  4. {
  5. int *a;
  6. int *b;
  7. enum boolean (*f)(int *,int *);
  8. } ;
  9. enum boolean    GoEThan(int *nbr1, int  *nbr2){return (*nbr1 >= *nbr2);}
  10. enum boolean addToValue(int *nbr1, int  *nbr2){*nbr1 += *nbr2;}
  11. enum boolean fwhile(struct s_func *it,
  12.     struct s_func *cm,
  13.     struct s_func *ad)
  14. {
  15.   !((cm->f)(cm->a,cm->b)) && (it->f)(it->a,it->b) && (ad->f)(ad->a,ad->b) && fwhile(it,cm,ad);
  16. }
  17. int main(int argc, char *argv[])
  18. {
  19. struct s_func f[3] = {{&((int){0}),&((int) {1}),&addToValue},
  20.        {f[0].a,    &((int){10}),&GoEThan},
  21.        {&((int){0}),&((int){20}),&addToValue}};
  22. fwhile (&f[0], &f[1], &f[2]);
  23. printf("%d\n",*(f[2].a));
  24. }



J'aime beaucoup le côté maintenabilité :o Logique imbitable sans le moindre commentaire, j'adorerais voir la tronche du mec qui devrait débogger dans 1 an ce genre de fonction. Je ne pense pas exagérer en disant qu'il te maudira sur 99 générations juste avant de partir en dépression :pt1cable:
 
Edit : toi qui kiffe le récursif, il faut absolument que tu te mettes au Prolog ;)

Message cité 2 fois
Message édité par rufo le 10-04-2022 à 22:39:04

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 11-04-2022 à 02:30:30    

une IA a écrit :

et hop !!!
 

Code :
  1. #include <stdio.h>
  2. enum boolean{false,true};
  3. struct s_func
  4. {
  5. int *a;
  6. int *b;
  7. enum boolean (*f)(int *,int *);
  8. } ;
  9. enum boolean    GoEThan(int *nbr1, int  *nbr2){return (*nbr1 >= *nbr2);}
  10. enum boolean addToValue(int *nbr1, int  *nbr2){*nbr1 += *nbr2;}
  11. enum boolean fwhile(struct s_func *it,
  12.     struct s_func *cm,
  13.     struct s_func *ad)
  14. {
  15.   !((cm->f)(cm->a,cm->b)) && (it->f)(it->a,it->b) && (ad->f)(ad->a,ad->b) && fwhile(it,cm,ad);
  16. }
  17. int main(int argc, char *argv[])
  18. {
  19. struct s_func f[3] = {{&((int){0}),&((int) {1}),&addToValue},
  20.        {f[0].a,    &((int){10}),&GoEThan},
  21.        {&((int){0}),&((int){20}),&addToValue}};
  22. fwhile (&f[0], &f[1], &f[2]);
  23. printf("%d\n",*(f[2].a));
  24. }



 
Un bon moyen d'éclater le cul de ta stack en un appel [:ocube]


---------------
"I can cry like Roger. It's just a shame I can't play like him" - Andy Murray, 2010
Reply

Marsh Posté le 14-12-2022 à 17:17:54    

rufo a écrit :


J'aime beaucoup le côté maintenabilité :o Logique imbitable sans le moindre commentaire, j'adorerais voir la tronche du mec qui devrait débogger dans 1 an ce genre de fonction. Je ne pense pas exagérer en disant qu'il te maudira sur 99 générations juste avant de partir en dépression :pt1cable:
 
Edit : toi qui kiffe le récursif, il faut absolument que tu te mettes au Prolog ;)


Pluzin ... surtout qu'un an après le nom de l'auteur sera toujours connu et que ça finira sur son bureau.  
Il pourra alors s’ auto-flageller avec des orties. :D


---------------
"Mieux vaut demander à un qui sait plutôt qu'à deux qui cherchent." ... "Le plus dur, c'est de faire simple.", TNZ
Reply

Marsh Posté le 19-12-2022 à 15:14:51    

rufo a écrit :


J'aime beaucoup le côté maintenabilité :o Logique imbitable sans le moindre commentaire, j'adorerais voir la tronche du mec qui devrait débogger dans 1 an ce genre de fonction. Je ne pense pas exagérer en disant qu'il te maudira sur 99 générations juste avant de partir en dépression :pt1cable:


Moi j'adorerais voir sa tronche à l'instant où il comprendra que tout ce bordel infâme sert à émuler une boucle dont la condition d'interruption est le fait de dépasser un seuil sur une valeur qu'on incrémente.
Je trouve ça un peu dommage de le faire en C par contre, je suis sûr qu'il y a moyen de faire encore plus imbitable avec un petit effort.  


---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
Reply

Marsh Posté le 19-12-2022 à 16:02:21    

Ben, suffit de déclarer dans ce programme en C une section écrite en ASM :o


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 26-12-2022 à 01:19:09    

gilou a écrit :

C'est du lisp, non ? mais en C
A+,


Plus du λ-calculus (pas spécifique à Lisp), mais pas fini, et en C parce-que pourquoi ne pas maximiser la douleur après tout?
 
En exploration c'est pas inintéressant, je re-lis régulièrement programming with nothing, une exploration du lambda-calcul et de l'encodage de Church en Ruby (qui fini avec un fizzbuzz n'utilisant que des constantes et des procs — des fonctions de première classe)

WiiDS a écrit :

Un bon moyen d'éclater le cul de ta stack en un appel [:ocube]


La récursion est terminale, avec un bon compilateur ça passe.
 
En mettant le bordel dans goldbot, clang a l'air d'y arriver en -O (je vois pas de rappel de fwhile, juste des appels sur les callbacks)

fwhile:
        push    r15
        push    r14
        push    rbx
        mov     r14, rdx
        mov     rbx, rsi
        mov     r15, rdi
.LBB2_1:
        mov     rdi, qword ptr [rbx]
        mov     rsi, qword ptr [rbx + 8]
        call    qword ptr [rbx + 16]
        test    eax, eax
        jne     .LBB2_4
        mov     rdi, qword ptr [r15]
        mov     rsi, qword ptr [r15 + 8]
        call    qword ptr [r15 + 16]
        test    eax, eax
        je      .LBB2_4
        mov     rdi, qword ptr [r14]
        mov     rsi, qword ptr [r14 + 8]
        call    qword ptr [r14 + 16]
        test    eax, eax
        jne     .LBB2_1
.LBB2_4:
        pop     rbx
        pop     r14
        pop     r15
        ret


GCC est tristesse par contre:

fwhile:
        push    r12
        push    rbp
        push    rbx
        mov     r12, rdi
        mov     rbx, rsi
        mov     rbp, rdx
        mov     rsi, QWORD PTR [rsi+8]
        mov     rdi, QWORD PTR [rbx]
        call    [QWORD PTR [rbx+16]]
        test    eax, eax
        jne     .L4
        mov     rsi, QWORD PTR [r12+8]
        mov     rdi, QWORD PTR [r12]
        call    [QWORD PTR [r12+16]]
        test    eax, eax
        je      .L4
        mov     rsi, QWORD PTR [rbp+8]
        mov     rdi, QWORD PTR [rbp+0]
        call    [QWORD PTR [rbp+16]]
        test    eax, eax
        jne     .L6
.L4:
        pop     rbx
        pop     rbp
        pop     r12
        ret
.L6:
        mov     rdx, rbp
        mov     rsi, rbx
        mov     rdi, r12
        call    fwhile
        jmp     .L4


faut monter en -O3 pour qu'il se réveille:

fwhile:
        push    r12
        mov     r12, rdx
        push    rbp
        mov     rbp, rdi
        push    rbx
        mov     rbx, rsi
        jmp     .L6
.L12:
        mov     rsi, QWORD PTR [rbp+8]
        mov     rdi, QWORD PTR [rbp+0]
        call    [QWORD PTR [rbp+16]]
        test    eax, eax
        je      .L5
        mov     rsi, QWORD PTR [r12+8]
        mov     rdi, QWORD PTR [r12]
        call    [QWORD PTR [r12+16]]
        test    eax, eax
        je      .L5
.L6:
        mov     rsi, QWORD PTR [rbx+8]
        mov     rdi, QWORD PTR [rbx]
        call    [QWORD PTR [rbx+16]]
        test    eax, eax
        je      .L12
.L5:
        pop     rbx
        pop     rbp
        pop     r12
        ret


TotalRecall a écrit :


Moi j'adorerais voir sa tronche à l'instant où il comprendra que tout ce bordel infâme sert à émuler une boucle dont la condition d'interruption est le fait de dépasser un seuil sur une valeur qu'on incrémente.
Je trouve ça un peu dommage de le faire en C par contre, je suis sûr qu'il y a moyen de faire encore plus imbitable avec un petit effort.  


Tu peux le faire en Iota ou Unlambda mais c'est un peu facile vu que c'est plus ou moins déjà ça (enfin techniquement ils sont bien pires)


Message édité par masklinn le 26-12-2022 à 01:23:40

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed