for dans une fonction

Bonjour à tous !

Voilà, le problème est simple mais très énervant … :
Je veux faire une moyenne de valeurs d’un capteur de pression.

Je veux utiliser une fonction “Moyenne()” qui stocke les valeurs dans un tableau pour ensuite

int Moyenne(int param1) {//param1 = sonde
    int tab[5] ;                         //création du tableau
    int moyenne ;                     //variable pour la moyenne
    

  for(int i = 0; i <5 ; i++)  {   // index du tableau avec création de la variable et déplacement dans l'index (incrémentation)

      tab[i] = param1;           //stockage de la valeur dans l'index i
      moyenne = ( tab[0]+tab[1]+tab[2]+tab[3]+tab[4]) / 5;   //on calcule la moyenne
      return moyenne;           //en retour, on a le résultat
  }

Jusque là, tout est logique et quand je mets ça dans la loop, sans fonction, tout baigne !
Sauf qu’une fois ma fonction dans une loop, “i” ne veut pas bouger !

Est-ce que c’est normal ? Qu’est-ce que j’ai raté ?

Bonjour,

C'est normal que i reste à zéro puisque tu le mets à 0 chaque fois que tu entre dans Moyenne() et tu sort aussitot de Moyeenne.

Bonjour,

Si tu fais un 'return' au milieu de la boucle... il est difficile de boucler ! :)

Coyotte

coyotte: Si tu fais un 'return' au milieu de la boucle... il est difficile de boucler !

Merci ! Une bêtise en moins :D

kamill: C'est normal que i reste à zéro puisque tu le mets à 0 chaque fois que tu entre dans Moyenne() et tu sort aussitot de Moyeenne.

Tu parles du for(int i = 0 ?

oui tout a fait

Et du coup, comment faire pour ça ? J'ai essayé sans la déclarer, en la déclarant sans valeur int i ;, je n'y arrive point ...

Il ne faut pas de boucle for
Il faut que tes variables tab et l’index persistent entre chaque appel de Moyenne() donc déclarer en static ou en global.
Ca donne quelque chose comme ça:

int Moyenne(int param1) {//param1 = sonde
    static int tab[5] ;                         //création du tableau
    static int index=0;
    int moyenne ;                     //variable pour la moyenne

    tab[index]=param1;
    index++;
    if (index>=5)
      index=0;
   
    moyenne = (tab[0]+tab[1]+tab[2]+tab[3]+tab[4]) / 5;   //on calcule la moyenne

    return moyenne;
}

C’est une version simplifiée car moyenne est fausse tant que le programme n’a pas été appelé 5 fois. Il faudrait tester si la table est pleine.

C'est bien for qui posait problème, donc !

C'est parfait, merci pour votre aide, je me prenais la tête depuis un petit moment ...

Je m’aperçoit que j'ai oublié le return moyenne; à la fin Je corrige mon message précédent

Le même avec gestion correcte des premières mesures, sans occuper plus de RAM (profitant sournoisement d’une optimisation possible :smiling_imp: )

int Moyenne(int param1) {//param1 = sonde
    static int tab[4] = {0, 0, 0, 0}; //création du tableau
    static int index = 0;
    static int nbval = 0;             //taille utile du tableau
    int moyenne ;                     //variable pour la moyenne

    moyenne = (tab[0]+tab[1]+tab[2]+tab[3]+param1) / (1+nbval);   //on calcule la moyenne
    if (nbval < 4) nbval++;

    tab[index]=param1;
    index++;
    if (index>=4)
      index=0;

    return moyenne;
}

pour le gain de 2 octets dans le tableau.

On se moque ??

Puisque c’est ça, 3 octets de plus de gagnés :smiling_imp: :smiling_imp:

int Moyenne(int param1) {//param1 = sonde
    static int tab[4] = {0, 0, 0, 0}; //création du tableau
    static byte nbvalindex = 0;
    int index = nbvalindex & 15;
    int nbval = nbvalindex >> 4;      //taille utile du tableau
    int moyenne ;                     //variable pour la moyenne

    moyenne = (tab[0]+tab[1]+tab[2]+tab[3]+param1) / (1+nbval);   //on calcule la moyenne
    if (nbval < 4) nbval++;

    tab[index]=param1;
    index++;
    if (index>=4)
      index=0;

    nbvalindex = (nbval << 4) | index;

    return moyenne;
}

… Et en permutant deux lignes, on peut écrire du code plus propre :

    if (nbval < 4) nbval++;
    moyenne = (tab[0]+tab[1]+tab[2]+tab[3]+param1) / (nbval);   //on calcule la moyenne

Ben oui… nbval c’est le nombre de valeurs…
Autant diviser par le nombre de valeurs plutôt que le nombre de valeurs + 1…

Ca a l’air de rien… Mais dans 6 mois, quand il faudra (re)comprendre le code… :wink:

Coyotte

D’accord mais dans ce cas le test change

if (nbval < 5) nbval++;

Ca c’est du travail d’équipe !
:smiley:

Après, j'aurais plutôt codé

    tab[index++]=param1;
    index &= 3;

Mais là c'est une histoire de goûts

bricoleau: On se moque ??

Non c'est sincère :)

Donc au final on arrive à :

int Moyenne(int param1) {//param1 = sonde
    static int tab[4] = {0, 0, 0, 0}; //création du tableau
    static byte nbvalindex = 0;
    byte index = nbvalindex & 15;
    byte nbval = nbvalindex >> 4;      //taille utile du tableau

    if (nbval < 5) nbval++;
    int moyenne = (tab[0]+tab[1]+tab[2]+tab[3]+param1) / nbval;   //on calcule la moyenne

    tab[index++]=param1;
    index &= 3;

    nbvalindex = (nbval << 4) | index;

    return moyenne;
}

Tout le monde valide ?

Hello again,

Je trouve

index &= 3;

pas très intuitif...

C'est efficace mais pas très intuitif. Ou alors, il manque une ligne de commentaire....

Il faut toujours penser que l'on risque un jour de retourner dans le code pour le modifier... De plus, si l'on désire faire une moyenne sur 6 ou 7 valeurs, le code ne fonctionne plus et il faudra réécrire le test autrement...

Après, comme Bricoleau l'indique, c'est une question d'habitude et de choix, de préférence et de goût, ... :)

Coyotte

Je pense que bricoleau s'est lancé dans un exercice de style :o

coyotte: Hello again,

Je trouve

index &= 3;

pas très intuitif...

Taratata A chacun sa langue naturelle Moi je trouve ça très clair (mais surtout ne le répétez pas à mon psy).

Faire une moyenne sur 6 ou 7 valeurs? Quelle hérésie !!! Il faudra rester sur une profondeur "simple" pour la moyenne glissante : 5, 9, 17, 33, 65, etc. :stuck_out_tongue_closed_eyes: