OVH Cloud OVH Cloud

(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
Wykaaa
candide a écrit :
Marc Espie a écrit :



[snip]

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.



Oui mais pas comme en mathématique car, malgré ce que dit Marc, il faut
effectivement garder à l'esprit qu'elles sont "attachés" à de la mémoire.
Un débutant, s'il ne connaît rien aux machines et si on ne lui a pas
expliqué la représentation mémoire, que va-t-il penser la première fois
qu'il va rencontrer un overflow ?

Dès le premier cours d'informatique (c'était au début des années 70), on
m'a dit à peu près ceci : vous pouvez demander quasiment tout à un
ordinateur sauf de stocker racine de 2.
Cette phrase m'est resté et je la pense importante car elle montre que
l'informatique est un monde d'approximation (je veux dire par rapport à
la notion de "continu" en mathématique).
La conclusion c'est qu'une variable dans un programme informatique "ne
peut pas tout" contrairement à une variable en mathématique.
Le x des mathématiques n'est pas la variable x d'un programme. Ce ne
sont pas les mêmes 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 ?



www.irisa.fr/celtique/genet/VVF/Biblio/Simonot_Preuve_Prog_Imp.pdf
Et un outil pour C afin de certifier du code critique :
http://frama-c.cea.fr/features.html

[snip]
Avatar
espie
In article <4b1793c9$0$933$,
Wykaaa wrote:
Dès le premier cours d'informatique (c'était au début des années 70), on
m'a dit à peu près ceci : vous pouvez demander quasiment tout à un
ordinateur sauf de stocker racine de 2.



Marrant, quand je demande a Mathematica de me stocker racine de 2,
il me stocke racine de 2.

Cette phrase m'est resté et je la pense importante car elle montre que
l'informatique est un monde d'approximation (je veux dire par rapport à
la notion de "continu" en mathématique).



L'informatique manipule des concepts, les maths aussi.

T'as qu'a voir la difficulte a exhiber qu'il existe des nombres
transcendants en maths (par exemple, montrer que e n'est pas solution
d'une equation polynomiale).

Apres, si tu veux faire des calculs precis, ben c'est complique, tu le
sais aussi bien que moi. Voire impossible, et ca c'est plus drole
(savoir que les equations diophantiennes, c'est mort, par exemple, c'est
toujours amusant).

(desole, a la bourre, je detaillerai ce dont je parle si on me demande).
Avatar
Wykaaa
Marc Espie a écrit :
In article <4b1793c9$0$933$,
Wykaaa wrote:
Dès le premier cours d'informatique (c'était au début des années 70), on
m'a dit à peu près ceci : vous pouvez demander quasiment tout à un
ordinateur sauf de stocker racine de 2.



Marrant, quand je demande a Mathematica de me stocker racine de 2,
il me stocke racine de 2.



C'était juste une façon de dire qu'un ordinateur n'a pas une mémoire
infinie. Donc que racine de 2 est forcément tronqué ou alors c'est
l'algorithme qui est stocké et avec la patience nécessaire (et un algo
sophistiqué) tu vas pouvoir le recalculer jusqu'à, mettons, la
milliardième décimale :-)

[snip]
Avatar
Antoine Leca
Samuel Devulder a écrit :
Marc Boyer a écrit :

Là, on parle d'attitudes, c'est pas vraiment du C.



C'est juste.

Est-ce que dire
qu'on programme ne respecte pas la norme c'est décourager les gens ?



En tout cas, sortir la norme quand c'est hors de propos est plutôt une
mauvaise idée vis a vis du problème de l'OP.



Bonne remarque.


Ainsi quand quelqu'un énonce avoir des problèmes avec son implémentation
d'un truc équivalent à strstr() et qu'on commence à lui dire sorti la
norme parce que ceci ou cela au niveau des I/O alors que cela n'a
strictement, mais strictement rien à voir avec le soucis d'origine, je
trouve cela affligeant et propre à décourager ceux qui viennent chercher
des infos sur le NG.



Mais là je me pose des questions.
Parmi les gens qui lisent un fil sur Usenet, nous avons :
a) celui qui a ouvert le fil, avec une question précise ;
b) ceux qui répondent directement à la dite question, qui donne donc
des réponses ;
c) ceux qui commentent les réponses, en général parce qu'il ne sont
pas d'accord avec leur contenu ; cela peut dériver ;
d) ceux qui lisent avec plus ou moins d'intérêt le fil sans y
participer directement, peut-être parce qu'ils ont une problématique
similaire à résoudre ; et comme les messages sont archivés et indexés
par les moteurs de recherche, ce dernier groupe est infini.

Je crois comprendre que tu considères que le groupe c) comme nuisible,
en tous cas à partir d'un certain point de dérive.


Mon point de vue est que lorsque c'est l'intérêt prévisible du groupe d)
on est fondé à dériver et donc à entrer dans le groupe c). Évidemment,
il faut agir avec discernement, ce que je reconnais volontiers ne pas
toujours faire.
Je trouve en particulier que lorsqu'on change le sujet, il devrait être
clair que l'on ne s'intéresse plus vraiment au problème original (sinon
pourquoi changer le titre). Et à ce moment-là, je ne comprend plus bien
la dispute sur d'éventuelles citations de références.

Et après tout, Usenet ou les /news/ sont généralement traduit en
français (avec le recul) par « groupes de discussion ». Ce qui me paraît
clair, c'est que les groupes avec peu de trafic sont considérés comme
morts et donc peu consultés donc peu utiles, tandis qu'au contraire les
posts type groupe c) représentent au total une grande part de la
/vitalité/ des groupes ; le problème réel est de conserver un bon
rapport signal/bruit.


L'OP vient chercher une explication à un défaut dans son code/snippet et
on lui sort des trucs qui n'ont rien a voir avec son pb, c'est pas
génial comme attitude. Sortir la norme à ce moment là est
particulièrement hors-sujet à mon avis.



Ce qui est surtout gênant à mon sens, c'est qu'on fasse un procès quand
après 5 jours de dérive suivis de 5 autres jours de silence, le PO
relance le débat au bout du fil (donc en répondant à une question qui
n'a plus qu'un lointain rapport avec le problème initial), en démontrant
clairement qu'il n'a pas compris la réponse qui a été donnée dès le départ.
Je ne dis pas qu'il est du devoir du PO d'avoir compris la réponse
initiale : bien au contraire, c'est tout à son honneur que de se
manifester pour demander un supplément d'explications, qui lui seront
fournies d'autant plus vite que plusieurs personnes ont suivi le fil
précédent, que le sujet est chaud, et que la problématique réelle est en
général bien appréhendée par ceux qui répondent à défaut de l'être par
celui qui interroge. Je dis seulement que dans ce cas-là, il est plus
clair de reposer la question (et d'ignorer les commentaires désagréables
du genre « je ne t'ai déjà dit dans mon message <news:machin(à)truc> »).
Et en fait, il est parfaitement possible (et probablement plus
productif) de reposer la question en même temps que la discussion
continue à faire rage dans le premier fil (qui ne _sert_ plus à rien du
point de vue du PO.)


Le mieux étant bien entendu d'expliquer ce qu'elle
raconte plutôt que de recopier "in extenso" le paragraphe en anglais
sans le traduire (hierarchie fr.* pourtant).



Je n'ai pas l'impression que ce soit un problème (ici) ; en général, si
à une question d'interprétation de la norme il y a une réponse lapidaire
en anglais, c'est parce que celui qui répond connait parfaitement le
niveau technique de celui qui interroge, et donc court-circuite
l'explication détaillée en lui donnant directement les clés pour aller
chercher lui-même les détails ; en fait, il y a souvent un aspect « t'as
loupé une évidence, mon vieux » sous-tendu ; d'ailleurs, ceux qui posent
ce genre de question prennent en général des précautions, par exemple en
donnant leurs lignes de raisonnement, pour éviter de se faire moucher.
Mais je dérive.


<snip code avec une variable non initialisée>
Ca dépend de ce que t'entends par marcher.



Celui-ci ne devrait pas rentrer dans la catégorie, pour personne.

Normalement si le code marche, personne ne postera ici pour s'en
plaindre.



Pourtant un grnad nombre de fils commencent par « mon code ci-dessous
marche sur XYZ, et bogue quand duchmol essaye sur ABC ». Marchent ou
marchent pas ?


Quant à la variable non initialisée, le moindre compilo sort un warning,
donc on est averti que ca peut ne pas marcher



Bzzz. Pas d'accord. Si un compilo te sort un avertissement avec une
solution aussi évidente pour le corriger, ne pas le corriger et laisser
le code tel quel « même si ça peut ne pas marcher » n'est PAS la bonne
attitude, surtout en C où le code a une grande tendance à être réutilisé
et où il y a beaucoup de chausses-trappes et peu de garde-fous.


Il y a très peu de gens qui croient encore qu'un code source ne doit
plus évoluer une fois écrit.



Je ne travaille pas dans une boîte d'informatique, et j'ai donc
évidemment le point de vue opposé. En particulier, je ne suis pas
d'accord sur l'obligation de payer (après la recette) une rente de
situation à mon informaticien pour lui permettre de corriger au fil de
l'eau ses erreurs de programmation, quelles que soient leurs causes,
internes ou externes. Sans compter qu'il peut y avoir des différences
d'interprétation substantielles entre les évolutions que je peux désirer
et celles que mon informaticien est disposé à écrire...

Bien sûr, il est des cas où c'est économiquement plus intéressant de
faire comme cela : ainsi une équipe qui dispose de compétences stables
dans le temps peut montrer qu'il est plus rentable de mettre en place le
programme dès qu'il remplit à peu près les objectifs, et qu'ensuite on
corrige les erreurs au fur et à mesure de leurs diagnostics ; cela
suppose entre autres qu'un système efficace a été mis en place pour
détecter puis corriger les dites erreurs, et que tout le monde (à
commencer par ceux qui financent) est bien conscient de cette situation
et l'accepte dans son principe ; je dois aussi dire que j'ai peu souvent
rencontré des cas où tous ces préceptes s'appliquent... ;-)

Il est aussi des cas où ce n'est pas une bonne idée. Quand tu envoies
une fusée dans l'espace, ou même si tu diffuses un produit grand public
à des millions d'exemplaires, il n'est pas encore admis par tout le
monde que le code devra peut-être évoluer dans le futur... En fait,
cette idée de fiabilité intrinsèque des produits livrés, en plus d'être
une obligation plus ou moins légale pour de nombreux produits, est la
norme plutôt que l'exception en matière industrielle. Certes, un avion
de ligne par exemple est un produit vivant ; mais bon, les programmes en
C ne sont pas TOUS dotés de l'infrastructure de documentation et de
suivis des modifications d'un avion de ligne... et coûtent parfois moins
cher !


On raconte dans le métier qu'un prog sans bug est juste un prog mort
(ou non utilisé, c'est synonyme).



Ce qui évident, c'est que c'est un programme qui ne rapportera plus rien
à son auteur. Seule chose qui semble importer « au métier ».

Question de point de vue, donc.


Antoine
Avatar
Marc Boyer
Le 02-12-2009, Samuel Devulder a écrit :
Marc Boyer a écrit :
Est-ce que dire
qu'on programme ne respecte pas la norme c'est décourager les gens ?



En tout cas, sortir la norme quand c'est hors de propos est plutôt une
mauvaise idée vis a vis du problème de l'OP.



Je n'ai lu qu'en diagonale la discussion, donc, je m'abstiendrais
de juger.

Ainsi quand quelqu'un énonce avoir des problèmes avec son implémentation
d'un truc équivalent à strstr() et qu'on commence à lui dire sorti la
norme parce que ceci ou cela au niveau des I/O alors que cela n'a
strictement, mais strictement rien à voir avec le soucis d'origine, je
trouve cela affligeant et propre à décourager ceux qui viennent chercher
des infos sur le NG.



Voui.
Je me souviens que parfois, quand un étudiant avait un problème
un peu subtil, je lui disais "vous voulez la vraie explication longue
ou juste que je vous dise ce qu'il ne faut pas faire ?".

A toi de voir. Quoi qu'il en soit, que le code suivant fonctionne
avec gcc en mode debug me semble une bétise.

int sum( int val[], size_t size ){
int lsum;
for( size_t i= 0 ; i < size ; ++i )
lsum+= val[i];
return lsum;
}



Ca dépend de ce que t'entends par marcher. Normalement si le code
marche, personne ne postera ici pour s'en plaindre.



Sauf qu'un jour, il ne va plus marcher...

Quant à la variable non initialisée, le moindre compilo sort un warning,
donc on est averti que ca peut ne pas marcher (même si ca marche parce
que le prologue de la fonction a utilisé un registre qui vaut 0 et qui
est réutilisé plus tard pour la variable lsum). De toute façon je
recommande toujours une passe dans un lint/splint et autres qa-c quand
le code semble marcher[*]. Ensuite on corrige jusqu'a ce qu'il n'y ait
plus de warnings ni de grognement de gcc/lint/splint/qac.. A ce moment
là le code ne fait plus ce qui était prévu (il est correct, mais faux
car ne rempli plus le CdC), on re-corrige, on rejoue les tests, en cycle
et a un moment ca se stabilise et on est heureux: le travail est fini,
on peut sortir le produit et faire la recette :)



Je suppose que quand Marc Espie se plaignait du fait que gcc initialisait
à 0, c'est qu'il avait du code avec des variables non initialisées.
Et peut-être même du code qui génère tant de warning qu'on envisage
pas de tous les corriger.

Sinon, je te suis.

C'est chiant, mais c'est la vie. A ce niveau là, avoir choisi
un découpage de son logiciel de sorte à faciliter les portages, aide
beaucoup à la maintenance plus tard.



Oui, et sur la partie C, écrire du code conforme aide aussi, non ?

Marc Boyer
--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0
Avatar
Marc Boyer
Le 03-12-2009, Wykaaa a écrit :
Marc Espie a écrit :
In article <4b1793c9$0$933$,
Wykaaa wrote:
Dès le premier cours d'informatique (c'était au début des années 70), on
m'a dit à peu près ceci : vous pouvez demander quasiment tout à un
ordinateur sauf de stocker racine de 2.



Marrant, quand je demande a Mathematica de me stocker racine de 2,
il me stocke racine de 2.



C'était juste une façon de dire qu'un ordinateur n'a pas une mémoire
infinie.



Les mathémacients non plus, et ils manipulent parfois racine de deux,
ils l'écrivent, idem avec pi (plus marrant).

Donc que racine de 2 est forcément tronqué ou alors c'est
l'algorithme qui est stocké et avec la patience nécessaire (et un algo
sophistiqué) tu vas pouvoir le recalculer jusqu'à, mettons, la
milliardième décimale :-)



Parce que tu penses en représentation décimale ou binaire.
Le jeune programmeur pense objet, et racine de deux n'est qu'un
constructeur de Number comme un autre ;-)

Non, très franchement, ton exemple vient de me faire changer
de point de vue sur la prog "moderne".

Marc Boyer
--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0
Avatar
Marc Boyer
Le 03-12-2009, Antoine Leca a écrit :
Normalement si le code marche, personne ne postera ici pour s'en
plaindre.



Pourtant un grnad nombre de fils commencent par « mon code ci-dessous
marche sur XYZ, et bogue quand duchmol essaye sur ABC ». Marchent ou
marchent pas ?



Quand ils n'accusent pas le compilo ABC d'être bugué ;-)
Mes étudiants trouvaient que Sparc était un bien mauvais
processeur, vu qu'il faisait des "bus error" sur des accès
(non alignés) que leur Intel Win/Linux avalait sans broncher.

En fait, même, pour être précis, ils accusaient gcc d'être
bugé, vu que ça marchait sous VC++.

Marc Boyer
--
En prenant aux 10% des francais les plus riches 12% de leurs revenus,
on pourrait doubler les revenus des 10% les plus pauvres.
http://www.inegalites.fr/spip.php?article1&id_mot0
Avatar
Senhon
"Samuel Devulder" a écrit dans le message
de groupe de discussion : 4b16cde8$0$19517$
Marc Boyer a écrit :

Là, on parle d'attitudes, c'est pas vraiment du C.



C'est juste.

Est-ce que dire
qu'on programme ne respecte pas la norme c'est décourager les gens ?



En tout cas, sortir la norme quand c'est hors de propos est plutôt une
mauvaise idée vis a vis du problème de l'OP.



Je suis entièrement, foncièrement, idéologiquement d'accord avec toi.
Mais une chose me gêne, c'est de penser que ce "reproche" s'adresserait à
Candide, alors que j'ai relu une bonne partie ( pas toute ... le temps m'a
manqué) de la conversation hier, et les réponses données par Candide sont
remarquables de pertinence et de considérations envers les dires de l'OP.

Mais peut-être dans la partie que je n'ai pas lue, Candide aurait perdu la
tête :-)


Ainsi quand quelqu'un énonce avoir des problèmes avec son implémentation
d'un truc équivalent à strstr() et qu'on commence à lui dire sorti la
norme parce que ceci ou cela au niveau des I/O alors que cela n'a
strictement, mais strictement rien à voir avec le soucis d'origine, je
trouve cela affligeant et propre à décourager ceux qui viennent chercher
des infos sur le NG.

L'OP vient chercher une explication à un défaut dans son code/snippet et
on lui sort des trucs qui n'ont rien a voir avec son pb, c'est pas génial
comme attitude. Sortir la norme à ce moment là est particulièrement
hors-sujet à mon avis.



Je suis de nouveau d'accord avec toi, pour avoir à maintes reprises assister
à ce désastreux scénario, où des "gourous" de la norme s'en prennent à de
néophytes.
Et une nouvelle fois je réitère : ce n'a pas été la cas, la norme a été
cité, certes, mais pas de ce cas.

Bon d'accord , c'était par Candide ... et (plus ou moins, suivant ses
penchants) à bon escient sur un exemple de Lucas Levrel, mais cela faisait
un bout, déjà, que la question du PO était oubliée. On avait passée la
récursion, pour attaquer l'initialisation des variables par GCC.
Avatar
-ed-
On 1 déc, 17:27, candide wrote:
Lucas Levrel a crit :

> Le 1 d cembre 2009, candide a crit :

>>> #include <stdio.h>

>>> int main(void){
>>>   int i;
>>>   printf(" %i n", i ) ;
>>>   return 0;
>>> }

>> M me si tu donnes a pour l'exemple, ce code est interdit :

> Quelqu'un a-t-il pr tendu le contraire ?

Non mais un code qui contient un UB ne peut rien prouver.



OK. Ceci est correct :

int main(void)
{
char i;
printf(" %i n", i ) ;
return 0;
}
Avatar
-ed-
On 1 déc, 20:14, candide wrote:

Et si tu m'/nous expliquais plut t pourquoi il est tellement scandaleux
d'initialiser par d faut z ro les variables automatiques ?



Parce que ça masque les défauts d'initialisations qui apparaitrons
dans d'autres circonstances. Personnellement, j'aime bien initialiser
la zone de données avec des 0x55. Le motif est facilement identifiable
quand on débogue... (même dans les traces...). On voit tout de suite
qu'on a affaire à une variable qui n'a pas été affectée correctemen t.

Tu as raison, la programmation en C au sens du travail d'un programmeur
ne m'int resse pas plus que a, pour l'instant en tous cas. Ce qui



Mais bon, ce sont des problèmes de programmeurs, donc ça n'intéresse
pas candide...