Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

(je suis débutant en c) je ne vois d'instruction pour boucler

156 réponses
Avatar
bpascal123
Bjr,sr,
Voici une fonction tr=E8s simple qui r=E9agit comme s'il y avait une
boucle alors qu'en apparence il n'y en a pas :

#include <stdio.h>

void f2(int b);
void f1(int a);

int main(void)
{
f1(30);

return 0;
}

void f1(int a)
{
if( a )
f2( a - 1 );
printf("%d ", a);
}

void f2(int b)
{
printf(" . ");
if(b)
f1( b - 1 );
}

http://www.java2s.com/Code/C/Function/Functioncalleachother.htm

Merci,
Pascal

10 réponses

Avatar
candide
Marc Espie a écrit :
In article ,



d'apprentissages de la programmation structuree: il n'y a rien de
naturel dans une construction telle que
i = i + 1;



absolument mais ta "programmation structurée" (je sais pas trop ce que
ça recouvre à vrai dire, c'est un truc que je lis de temps en temps) n'a
rien à voir là dedans. Pose la question à un, deux, dix débutants (mais
en vois-tu dans ton école ?) qui _découvre_ une expression comme i=i+1
et tu auras la réponse.

mais bon, des annees d'explications de comment ca marche, des petites
cases memoire, et tout ca, conduisent a une vision etriquee de l'informatique
et du fonctionnement des machines.



Quand on programme, y compris en C, a-t-on nécessairement besoin de
connaître le fonctionnement des machines. Les variables sont des
abstractions.



Et entre devoir ecrire explicitement mes invariants de boucle et mes
conditions d'arret, ou avoir du recursif qui se prouve "naturellement" avec
une belle equation, le recursif c'est souvent plus simple.




Exemple ?



Juste un petit bout de point de vue.

Les variables du procedural, les boucles qui vont avec, c'est une vision
tres proche de la machine.



Non, c'est juste chez toi de la déformation professionnelle.




Oublier un peu tout ca, faire du fonctionnel propre, avec de la recursion,
c'est souvent une bonne facon de s'elargir les horizons.




Ah ben oui mais faut savoir ce qu'on veut : apprendre à programmer en C
ou se faire un culture G pour discuter devant la machine à café ;)



Allez, une petite fonction recursive pour la route.

unsigned int
pgcd(unsigned int a, unsigned int b)
{
if (a < b)
return pgcd(b, a);
else if (b == 0)
return a;
else
return pgcd(b, a % b);
}




"Peut mieux faire", j'ai envie de dire car un détail dans l'algorithme
d'Euclide t'a échappé : ta première ligne ne sert à rien car si a<b
alors, dans ton appel récursif pgcd(b, a%b), le deuxième argument sera
a. Et cette cascade de trois return, c'est pas très C.


Le code plus ou moins standard du pgcd récursif est :

int pgcd(int a, int b)
{
return b ? pgcd(b, a % b) : a ;
}
Avatar
Richard Delorme
Le 29/11/2009 14:01, candide a écrit :

Une fois de plus, si on dit que l'itération est humaine et la récursion
divine, ce n'est pas pour rien : il y a vraiment une difficulté à
_vraiment_ comprendre la récursivité.



On apprend plus les suites en Mathématiques à l'école ?

Suites arithmétiques :
a_(0)
a_(n+1) = a_(n) + r

Suites géométriques :
q_(0)
q_(n+1) = q_(n) * r

etc.

Si l'on a compris ça, on a compris la récursivité.

--
Richard
Avatar
espie
In article <4b127610$0$21957$,
candide wrote:
absolument mais ta "programmation structurée" (je sais pas trop ce que
ça recouvre à vrai dire, c'est un truc que je lis de temps en temps) n'a
rien à voir là dedans. Pose la question à un, deux, dix débutants (mais
en vois-tu dans ton école ?) qui _découvre_ une expression comme i=i+1
et tu auras la réponse.



Je n'en ai pas vu depuis pas mal d'annees, tout betement parce qu'ils sont
trop ages. Mais j'ai des souvenirs de club d'info d'il y a pas mal d'annees,
avec des collegiens, ou c'etait pas du tout naturel pour eux au depart.

mais bon, des annees d'explications de comment ca marche, des petites
cases memoire, et tout ca, conduisent a une vision etriquee de l'informatique
et du fonctionnement des machines.



Quand on programme, y compris en C, a-t-on nécessairement besoin de
connaître le fonctionnement des machines. Les variables sont des
abstractions.



... mais i=i+1, c'est deja un biais important sur le fonctionnement des
machines. Et on peut programmer sans variables modifiables !

Et entre devoir ecrire explicitement mes invariants de boucle et mes
conditions d'arret, ou avoir du recursif qui se prouve "naturellement" avec
une belle equation, le recursif c'est souvent plus simple.






Exemple ?



Tu m'emmerdes. Va chercher dans la biblio. J'emploie des termes precis. Tu
peux trouver autant d'exemples que tu veux dans toute la litterature qui
traite de semantique et de preuves de programmes.


Les variables du procedural, les boucles qui vont avec, c'est une vision
tres proche de la machine.





Non, c'est juste chez toi de la déformation professionnelle.



... Et des oeilleres persistantes chez toi. C'est pas parce que tu ne
connais QUE C ou assimile qu'il n'existe que ca. C'est pas parce que 90%
des gens programment en procedural pur qu'il n'y a pas autre chose dans
la nature.

Oublier un peu tout ca, faire du fonctionnel propre, avec de la recursion,
c'est souvent une bonne facon de s'elargir les horizons.






Ah ben oui mais faut savoir ce qu'on veut : apprendre à programmer en C
ou se faire un culture G pour discuter devant la machine à café ;)



"Apprendre a programmer en C", ca implique entre autres "d'apprendre a
programmer", ce qui veut dire connaitre toutes les techniques utiles, et ca
inclut la recursion !


unsigned int
pgcd(unsigned int a, unsigned int b)
{
if (a < b)
return pgcd(b, a);
else if (b == 0)
return a;
else
return pgcd(b, a % b);
}






"Peut mieux faire", j'ai envie de dire car un détail dans l'algorithme
d'Euclide t'a échappé : ta première ligne ne sert à rien car si a<b
alors, dans ton appel récursif pgcd(b, a%b), le deuxième argument sera
a. Et cette cascade de trois return, c'est pas très C.



M'a echappe ? mais va te faire foutre ! C'est pas parce que tu veux
ecrire les choses autrement en te focalisant sur un detail que ma version
est incorrecte.

Cascade de 3 return, pas tres C ? Euh, la-encore, enleve tes oeilleres.
C'est parfaitement valide, et extremement classique.


Le code plus ou moins standard du pgcd récursif est :


"plus ou moins". c'est juste une autre facon d'ecrire la meme chose.
Tu l'as recopie de quelque part, pour dire que c'est standard ? ou tu arrives
encore a inventer trois lignes de code sans les repiquer ailleurs ?

int pgcd(int a, int b)
{
return b ? pgcd(b, a % b) : a ;
}




La j'avoue, la coupe est pleine. J'en ai plus que marre de tes frasques.

A force de jouer au "candide" qui reprend tout et tout le monde en jouant
ta mouche du coche, et en voulant imposer aux gens ta vision etriquee du
monde, tu as finalement reussi a m'enerver un peu.

M'en fous, a troll, troll-et-demi. J'ai la peau plus solide que toi. Si tu
cherches la bagarre...
Avatar
candide
> La "tarte à la crème" c'est de faire croire qu'on peut se dispenser de
comprendre la récursivité quand on est programmeur. Ceci est totalement
faux.



Non, au contraire, le "informatiquement correct" c'est de parler tout le
temps de récursivité, fonction récursive par-ci, fonction récursive par
là. Ça me fait penser à des discussions sur le forum du site du zéro où
des intervenants te sortent "et ben t'as le coder en récursif" comme si
la récursivité était un algorithme ...


Tout algorithme qui requiert un automate à pile est souvent beaucoup
plus facile à coder de façon récursive (exemple : la reconnaissance
syntaxique des expressions arithmétiques).




ben je vais poser la question à un vrai programmeur C, Emmanuel Delahaye
: dis-nous, tu avais dit que tu avais programmé dans ta bibliothèque
perso un automate à piles si je ne m'abuse. L'as tu codé en récursif ?


Et puis nombre d'algorithmes sur les arbres, voire les listes, sont bien
plus faciles à programmer de façon récursive.



Ça d'abord, c'est une tarte à la crème. Quelques algorithmes sur les
graphes (dont les arbres) sont codés récursivement. La cas typique est
le parcours en profondeur (DFS). Mais il est courant qu'il n'y ait
aucune implémentation récursive adaptée (le BFS est typique). Encore
récemment, j'ai codé le codage de Prufer d'un arbre ; rien de récursif
pourtant c'est un arbre. Et même pour le parcours en profondeur, il
n'est pas dit que l'algo récursif soit adapté. J'avais récemment à coder
en Python un problème de parcours de labyrinthe, j'ai donc opté pour un
DFS : et bien j'ai eu une "maximum recursion depth error". Chose qui
pourrait arriver aussi en C, parce que si ton graphe est très profond,
tu vas empiler les appels et si la récursion n'est pas terminale ce qui
est courant, t'exploseras ta pile.


La récursivité est un concept clé de la programmation (et de
l'informatique et des mathématiques en général).




Pour le concept-clef, je veux bien mais souvent ça reste au stade du
concept, quand il s'agit d'implémenter, il y a plus grand monde (sauf
pour une récursivité de type factorielle qui est complètement factice).
On n'a pas toujours besoin de tout verbaliser ni de tout
intellectualiser, tu crois que le singe a pris des cours de récursivité
pour monter dans son arbre ? ;)
Avatar
Erwan David
(Marc Espie) écrivait :

In article ,
Erwan David wrote:

ça c'est mon historique de développeur embarqué qui parle...



Ca veut juste dire que tu optimises la recursion terminale a la main
en presence de compilateurs deficients...



oui, parceque des compilateurs efficaces en dehors des cas simples sont
rares dans ce domaine.

--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
Avatar
Wykaaa
candide a écrit :
Marc Espie a écrit :
In article <4b0e4cc7$0$9187$,
candide wrote:
Il y a plein de programmeurs C (C ou autre) qui n'ont jamais rien
compris à la récursivité donc te crois pas obligé de passer par ce
pensum (qui est aussi une belle tarte à la crème).


Si c'est pour donner des conseils aussi mauvais, tu peux aussi fermer
ta gueule.



Visiblement, ça ne te fait pas plaisir que je te dise la réalité mais,
oui, un grand nombre de programmeurs n'ont pas compris la récursivité.
Comprendre la récursivité, ce n'est pas avoir compris la tarte à la
crème de la factorielle.

Une fois de plus, si on dit que l'itération est humaine et la récursion
divine, ce n'est pas pour rien : il y a vraiment une difficulté à
_vraiment_ comprendre la récursivité.


Le cote "chercher la petite bete dans la norme", ca tu sais faire.

Le cote "expliquer la programmation aux gens", par contre c'est moins
au point...



Je n'en suis pas si sûr justement. Question d'empathie.


Meme s'il y a des gens qui se pretendent programmeurs qui sont nuls, ca
n'est pas une raison pour inciter les nouveaux a faire pareil...



On n'est pas un programmeur nul si on ne maitrise pas la récursivité.



Bin si, justement. Tiens, écrit un éditeur de lien sans utiliser la
récursion, juste pour voir...
Avatar
Wykaaa
candide a écrit :
Wykaaa a écrit (en plus tu cotes comme un goret) :
La récursivité est un concept clé de la programmation (et de
l'informatique et des mathématiques en général).




Pour le concept-clef, je veux bien mais souvent ça reste au stade du
concept, quand il s'agit d'implémenter, il y a plus grand monde (sauf
pour une récursivité de type factorielle qui est complètement factice).
On n'a pas toujours besoin de tout verbaliser ni de tout
intellectualiser, tu crois que le singe a pris des cours de récursivité
pour monter dans son arbre ? ;)





Je te donne un autre exemple encore :
Ecris un évaluateur de lambda-expressions de façon non récursive...

Il y a quantité d'algorithme qu'il est EXTREMEMENT plus simple d'écrire
en récursif, même et surtout si on élimine les algos sur les arbres, les
listes, etc. qui pourtant, ne sont pas que des exercices de style
puisqu'ils sont utilisés dans les optimiseurs des compilateurs, les
systèmes d'exploitation, etc.

En disant aux débutants qu'ils n'ont pas besoin de connaître la
récursivité pour programmer, tu les trompes en faisant d'eux des singes
"pousseurs de caractères".
Avatar
candide
Marc Espie a écrit :

Tu m'emmerdes. Va chercher dans la biblio. J'emploie des termes precis. Tu
peux trouver autant d'exemples que tu veux dans toute la litterature qui
traite de semantique et de preuves de programmes.




"traité de sémantique", "preuves de programmes" connais rien à ça, je
suis pas du sérail mais je sais que mes étudiants de L3 font ça (et même
avec du Coq je crois).



... Et des oeilleres persistantes chez toi. C'est pas parce que tu ne
connais QUE C ou assimile qu'il n'existe que ca. C'est pas parce que 90%
des gens programment en procedural pur qu'il n'y a pas autre chose dans
la nature.





On est d'accord sur ce point.


Ah ben oui mais faut savoir ce qu'on veut : apprendre à programmer en C
ou se faire un culture G pour discuter devant la machine à café ;)



"Apprendre a programmer en C", ca implique entre autres "d'apprendre a
programmer", ce qui veut dire connaitre toutes les techniques utiles, et ca
inclut la recursion !



Je dis pas le contraire, je fais des TP de C en première année et le
dernier TP est sur la récursivité.


M'a echappe ? mais va te faire foutre ! C'est pas parce que tu veux
ecrire les choses autrement en te focalisant sur un detail que ma version
est incorrecte.

Cascade de 3 return, pas tres C ? Euh, la-encore, enleve tes oeilleres.
C'est parfaitement valide, et extremement classique.




J'ai pas dit que c'était pas valide mais il est par exemple plus courant
pour un pratiquant du C d'écrire

int max(int a, int b)
{
return a > b ? a : b;
}


plutot que


int max(int a, int b)
{
if (a > b)
return a;
else
return b;
}




Le code plus ou moins standard du pgcd récursif est :


"plus ou moins". c'est juste une autre facon d'ecrire la meme chose.
Tu l'as recopie de quelque part, pour dire que c'est standard ? ou tu arrives
encore a inventer trois lignes de code sans les repiquer ailleurs ?



Je ne l'ai pas inventé car c'est classique (cf. le code de Wikipedia à
"Algorithme d'Euclide"). C'est pas vous les informaticiens qui êtes tout
le temps en train de dire qu'il faut pas réinventer la roue ? Et puis le
coup de ne pas distinguer le cas où a et b ne sont pas dans l'ordre
naturel, je dois reconnaitre que je n'y avais pas pensé la première fois
(et donc j'avais écrit comme toi).



La j'avoue, la coupe est pleine.




Et bien ta coupe n'est pas très profonde ...
Avatar
candide
Wykaaa a écrit :

Bin si, justement. Tiens, écrit un éditeur de lien sans utiliser la
récursion, juste pour voir...





Et tu crois que tout programmeur C a le background pour écrire un
éditeur de liens ? Le programmeur qui écrit un compilateur ou des outils
de ce genre n'est pas le programmeur lambda.

Mais je veux bien examiner un code-source d'éditeur de liens, histoire
de voir si justement la récursivité est aussi utilisée que tu le dis.
T'as un lien vers les sources de ld ou un truc du genre ?
Avatar
Benoit Izac
Bonjour,

le 29/11/2009 à 15:42, candide a écrit dans le
message <4b128857$0$11205$ :

Et tu crois que tout programmeur C a le background pour écrire un
éditeur de liens ? Le programmeur qui écrit un compilateur ou des outils
de ce genre n'est pas le programmeur lambda.

Mais je veux bien examiner un code-source d'éditeur de liens, histoire
de voir si justement la récursivité est aussi utilisée que tu le dis.
T'as un lien vers les sources de ld ou un truc du genre ?



<http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/?cvsroot=src>
<http://www.openbsd.org/cgi-bin/cvsweb/src/gnu/usr.bin/ld/>

Bon courage. ;-)
--
Benoit Izac