Langage C

Bonsoir, est-ce que mon programme est correct ? J’ai à calculer une suite : Un = Un-1+Un-2 tel que U0=1 et U1= 2.

int suite( intT,int n )
{
int i;
T[0]=1;
T[1]=2;
for(i=0;i<n;i++)
T[i+2]=T[i+1]+T[i];
return(T[i]);
}

Ce qui me dérange un peu, c’est la dernière ligne du code. Qu’est ce que vous en pensez ? ( Je sais qu’il y a moyen de faire cela avec la récursivité.)

Salut,
oui ce programme fonctionne.
Pense juste à séparer par un espace : int T dans la première ligne.

Comme tu l’as dit, tu peux faire ça en récursif mais rien n’est obligatoire. D’ailleurs la récursivité n’est pas toujours la meilleure solution, surtout ici ou tu risques de faire les mêmes calculs plus d’une fois.

Exemple : si tu veux calculer $$U_n$$ tu vas avoir besoin de $$U_{n-1}$$ et $$U_{n-2}$$.
Pour calculer $$U_{n-1}$$ tu auras également besoin de $$U_{n-2}$$ et donc tu le calculeras deux fois.

Tu n’as rien pour compiler ?
Ca te permettra de tester tes programmes, c’est toujours mieux pour s’améliorer.

PS : tu pourrais créer ton tableau dans ta fonction. Ca t’évitera de devoir le créer ailleurs pour le passer en argument de la fonction. Et tu pourrais éviter l’utilisation du tableau si tu as seulement besoin de la valeur finale (tu utiliseras moins de mémoire).

Phi a écrit:

Bonsoir, est-ce que mon programme est correct ? J’ai à calculer une suite : Un = Un-1+Un-2 tel que U0=1 et U1= 2.

int suite( intT,int n )
{
int i;
T[0]=1;
T[1]=2;
for(i=0;i<n;i++)
T[i+2]=T[i+1]+T[i];
return(T[i]);
}

Ce qui me dérange un peu, c’est la dernière ligne du code. Qu’est ce que vous en pensez ? ( Je sais qu’il y a moyen de faire cela avec la récursivité.)
Comme le dit -L-C-, vérifié déjà que ton programme compile puis qu’il fonctionne (et donc, écris un programme complet et pas seulement une fonction).
Et sinon, il n’est à priori pas correct :

Si tu as réservé n entiers dans ton tableau T, tu ne peux pas accéder à T[n] ni T[n+1].

Ta boucle gagnerait en clarté d’être écrite comme suit :
for (i=2; i<n; i++) T[i]= T[i-1] + T[i-2];

Et la dernière ligne est risquée/fausse … ton i vaut en sortie de boucle n, or c’est T[n-1] que tu veux, soit le nème élément de ta suite. Si c’est vraiment T[n] que tu veux alors calcule T[n] (donc tableau de taille n+1, boucle jusqu’à n inclus).

En testant ton programme, cela t’aurait aidé à voir les risques que j’ai listé. Il y a des compilo + IDE en ligne, tel que IDEONE, si nécessaire.

plusieurs choses :

  1. ce n’est pas un code C complet mais juste une fonction.

  2. int T est une notation un peu étrange pour moi. Je préfère de loin un int T* (ca c’est bien un pointeur qu’on veut).
    3)« Si c’est vraiment T[n] que tu veux alors calcule T[n] (donc tableau de taille n+1, boucle jusqu’à n inclus) ». NON! enfin oui et non :slight_smile: Si tu veux seulement T[n], merci de ne PAS stocker toutes les autres valeurs dans un tableau. Si tu veux seulement T[n] alors tu n’a pas besoin du tout d’un tableau.

  3. mets des {} autour de ta boucle for. Je sais bien que ca fonctionne sans quand on n’a qu’une ligne dans la boucle mais c’est se donner un baton pour se faire battre (car, un jour, tu vas rajouter une ligne et PAF elle ne sera pas dans la boucle et tu vas perdre des heures à comprendre ce qui se passe).

  4. T[0]=1;
    T[1]=2;
    hardcodés dans la fonction c’est moyen. Pourquoi ne pas les passer en arguments? ca rendrait la fonction un peu plus générique.

Merci pour vos réponses. Oui, d’habitude je ne travaille pas beaucoup avec les compilateurs. Néanmoins, j’essaye de faire la trace du programme ( Pas pour celui là, et me voilà pris au piège :grin: )

Vous avez tous évoqué l’histoire de la mémoire, donc en gros, mon prog n’est pas optimal. Qu’est ce que vous proposez à la place du tableau ?

Ca dépend, tu t’intéresses seulement au dernier terme ou tu veux tous les récupérer?

Euh, j’ai besoin de calculer la suite à chaque fois que l’utilisateur demander une valeur de n, je pense. La question au départ est : Ecrire un programme qui permet de calculer Un = Un-1+Un-2 tel que U0=1 et U1= 2

Il faut que je fasse return T[n] seulement alors ?

Phi a écrit:

Euh, j’ai besoin de calculer la suite à chaque fois que l’utilisateur demander une valeur de n, je pense. La question au départ est : Ecrire un programme qui permet de calculer Un = Un-1+Un-2 tel que U0=1 et U1= 2

Il faut que je fasse return T[n] seulement alors ?
L’idéal (selon moi :unamused: ) :


    public int suite(int u0, int u1, int n) {
        int u= 0;

        for (int i= 2; i<=n; i++) {
            u= u0 + u1;
            System.out.printf("%d + %d = %d [%d]\n", u0, u1, u, i); 
            u0= u1;
            u1= u;
        }
        return u;
    }

(le printf c’est juste pour le plaisir :wink: , c’est du java (mettre l’équivalent en C ou le virer))

Les + : c’est simple, ça fait le boulot, rien n’est codé en dur, ça prend un minimum de mémoire et c’est rapide (vu qu’on se limite à des entiers, n ne peut pas dépasser 45 pour des entiers signés)
Les - : pour n>=45, il faut passer par des long (64bits), et il y a sûrement moyen de trouver d’autres points faibles

Mais c’est aussi utile que tu comprennes ton code et l’implication de tes choix (le tableau, les variables en dur, les indices …). Il y a plusieurs solutions au problème, comme tu as vu celle que je donne n’est pas parfaite (ou encore l’énoncé n’est pas assez précis :slight_smile: ).

ou alors on prend son mathematica, maple, crayon préféré et on calcule ce que vaut u[n] pour un n qq positif.

Ce n’est pas parce qu’on fait de l’info qu’il faut oublier les maths… :wink:

Pourquoi mettre un « public »?

Et je suis pas sûr qu’en C on puisse déclarer la variable i de la boucle dans le for…

sisi on peut. C’est même ce qu’il y a de mieux à faire car le variable i n’a pas d’utilité en dehors de la boucle…donc elle n’a pas à exister en dehors de la boucle.

fakbill a écrit:

sisi on peut. C’est même ce qu’il y a de mieux à faire car le variable i n’a pas d’utilité en dehors de la boucle…donc elle n’a pas à exister en dehors de la boucle.
Ca depends de la norme, en mode C99 ca passera, pour d’autres ca passera surement pas. Le mieux est declarer le compteur a l’exterieur. Ce n’est pas ce qu’il y a de plus logique, mais que voulez-vous de plus d’un langage si bas niveau?

C’est bien ce qui me semblait. Les cours que j’ai eu de C précisaient bien qu’il fallait déclarer la variable à l’extérieur.

héhé…C99…ça veut dire que la norme ISO date de 99…donc si on vous apprend encore le C K&R ou déjà un peu mieux le ANSI C…disons qu’il faut changer de compilo et de prof!!!

Attention : il existe encore des 10^6 lignes en ANSI C…mais bon…un cours de C qui ne se base pas sur le C99.
Un bon cours de C (fait pour ceux qui auront à faire du code) devrait au moins parler un peu de ces petites différences.

ps : une version de visual studio et de son compilo compilait for(int i;… de façon à ce que ‹ i › existe encore en dehors de la boucle…bonjour le respect des standards…

Oui mais tu n’es pas sans savoir que l’industrie met souvent énormément de temps avant d’adopter des nouveaux outils, et je peux te garantir qu’il y a des endroits où le C99 n’est pas adopté du tout… Quand on voit que dans le milieu de la banque on se traine encore du COBOL… Ou que les boites gardent une bouse comme IE6 parcequ’ils y a des outils maisons développés dessus…

D’ailleurs il y a pleins de compilateurs qui ne supportent qu’à moitié le C99 : C99 - Wikipedia.

oui oui c’est bien pour cela que je disais qu’il restait des tonnes de lignes de C pas C99, en cobol et autre.
Un « bel » exemple était la cernlib qui ne compilait qu’avec UNE version de gcc…ça a dû être corrigé depuis mais ce genre de problème est assez courant.

LE truc étant « on ne touche pas un système qui marche »…sauf qu’en info il faut convaincre les gens de faire des updates de temps en temps sinon ça leur coutera beaucoup plus cher un jour.

Bon cependant, c’est mal de « leaker » une variable en dehors de la boucle comme ça…donc pour un cours de C, même pour non exeprts, je dirais aux étudiants de faire comme ça (avec un blabla si le public est plus expert).

Les meilleur lib en algèbres linéaire sont parfois en…fortran 77 :slight_smile:

Le C de toute facon n’est pas adapte aux debutants …

Sauf que ca fait partie des quelques langages qui sont vraiment utilisés en ingénierie donc c’est normal qu’il y ait des cours dessus.

Valvino a écrit:

Sauf que ca fait partie des quelques langages qui sont vraiment utilisés en ingénierie donc c’est normal qu’il y ait des cours dessus.
j’ai bien precise « debutant »

maroxe a écrit:

Le C de toute facon n’est pas adapte aux debutants …
je ne suis pas d’accord. Avec un cours un peu pédagogique, cela permet de vraiment bien voir les différents enjeux de la programmation dès le départ, qui sont en général méconnus par les ingé qui chient du maple/caml light/java/python/php , et donc de prendre des bonnes habitudes et de vraiment comprendre ce qu’on fait quand on code…