Go Down

Topic: Problème de pointeurs (Read 504 times) previous topic - next topic

RomainL

Bonjour  :) ,

Je me demandais si quelqu'un ici pourrait me donner conseil et m'aider à résoudre mon code.

J'espère que je suis sur le bon forum  :smiley-confuse:

l'idée est de faire pointer la variable recallVar qui est un byte entre 0 et 9, vers les fonctions respectives p0() à p9()

Voici ce que je tente (partie pertinente de mon code) :
Code: [Select]


byte recallVar;

function f0(){}
function f1(){}
function f2(){}
function f3(){}
function f4(){}
function f5(){}
//etc .....


//array de pointeur vers des fonctions
void (*func_ptr[10]) = {f0, f1, f2, f3, f4, f5, f6, f7, f8, f9};


void setPattern(){
 
 if((recallVar >= 0) && (recallVar<=9))
{
   (*func_ptr[recallVar])();
}


//utilisation dans la loop()

void loop(){
if (recallVar) {
        setPattern();
 }
}



Pour le moment j'obtiens l'erreur "invalid conversion from 'void (*)()' to 'void*'" et j'ai un peu de mal a avancer

S'il y a une personne douée ce serait extra  ;)



fdufnews

Quelque chose comme ça.
Pas vraiment testé. Mais ça compile.
Code: [Select]


byte recallVar=0;

void f0(){}
void f1(){}
void f2(){}
void f3(){}
void f4(){}
void f5(){}
//etc .....


//array de pointeur vers des fonctions
void (*func_ptr[10])() = {f0, f1, f2, f3, f4, f5};


void setPattern(){
 
 if((recallVar >= 0) && (recallVar<=9))
  {
     (*func_ptr[recallVar])();
  }
}

//utilisation dans la loop()
void setup(){}

void loop(){
if (recallVar++) {
        setPattern();
 }
}


RomainL

Alors ok pour passer les "function" en "void" c'était une inattention de ma part.
En revanche je ne vois rien de modifié sauf
Code: [Select]
if(recallVar++)
Qu'est ce que cela change?
La compilation donne toujours: invalid conversion from 'void (*)()' to 'void*' [-fpermissive]


lesept

Ici, j'utilise un tableau de fonctions, indexé par une variable. Ça peut peut-être répondre à ton besoin
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

fdufnews

#4
Apr 17, 2019, 08:30 am Last Edit: Apr 17, 2019, 08:35 am by fdufnews
Non, le programme que j'ai donné compile sans erreur
et la modif importante était là
Code: [Select]
void f0(){}
void f1(){}
void f2(){}
void f3(){}
void f4(){}
void f5(){}

void (*func_ptr[10])() ={f0, f1, f2, f3, f4, f5};


Le truc important c'est ça
void (*func_ptr[10])()

le recallVar++ c'était juste pour que l'optimisation ne supprime pas la ligne puisque recallVar ne change jamais sinon

dbrion06

Une version de votre programme se compile et s'execute comme prévu sur PC
Code: [Select]

sh-4.1$ cat  ptrfun.cpp
#include <stdio.h>
#include <stdint.h>

int8_t recallVar; // r=0;



void f0() {printf("Zero\n");}
void f1() {printf("Yek\n");}
void f2() {printf("Duj\n");}
void f3() {printf("Trin\n");}
void f4() {printf("Shtar\n");}
void f5() {printf("Panjo\n");}

//array de pointeurs vers des fonctions
void (*func_ptr[])() = {f0, f1, f2, f3, f4, f5};
int nFunc = sizeof(func_ptr) /sizeof(func_ptr[0]); // determine la taille sans effort de comptage

void setPattern() {
 
 if((recallVar >= 0) && (recallVar< nFunc))  {
     (*func_ptr[recallVar])();
  }
}

//utilisation dans la loop()
void setup(){}

void loop(){
  if (recallVar++) {
        setPattern();
  }
}
#ifndef ARDUINO // cas du PC
int main() {
  for (recallVar = 0; recallVar < nFunc; recallVar++) setPattern();
}
#endif

ça donne, comme souhaité
h-4.1$ g++  ptrfun.cpp && ./a.exe
Zero
Yek
Duj
Trin
Shtar
Panjo




kamill

Bonjour,

Personnellement je pense que l'utilisation d'un typedef éclairci l'écriture
Code: [Select]
byte recallVar=0;

void f0() {Serial.println("Zero");}
void f1() {Serial.println("Un");}
void f2() {Serial.println("Deux");}
void f3() {Serial.println("Trois");}
void f4() {Serial.println("Quatre");}
void f5() {Serial.println("Cinq");}
//etc .....

//array de pointeur vers des fonctions
typedef void (*voidfunc)();
voidfunc func[] = {f0, f1, f2, f3, f4, f5/*, f6, f7, f8, f9*/};

void setPattern() {
  if ((recallVar >= 0) && (recallVar <= 9))
  {
    func[recallVar]();
  }
}
void setup()
{
  Serial.begin(115200);
}

//utilisation dans la loop()
void loop() {
  setPattern();
  recallVar = (recallVar + 1) % 6;
}

RomainL

@lesept extra, oui c'est ce que je cherche à faire :)

@fdufnews en effet! bien vu :) le problème venait de là

@dbrion06 très intéressant, je ne comprends le principe mais à quoi cela sert-il? Qu'entend-on par  "determine la taille sans effort de comptage" ?

@kamill super la version avec typedef, bien plus clair en effet.

Grand merci à tous :) :) :) :)

dbrion06

Un commentaire du genre // sert à dire ce que fait la ligne:
int nFunc = sizeof(func_ptr) /sizeof(func_ptr[0]); // determine la taille sans effort de comptage

nFunc est le quotient de la taille du tableaux de fonctions,
divisée par
la taille d'un elément de ce tableau:

celà équivaut, tenez vous bien,  au nombre de fonctions.
Naturellement, si vous avez fait le calcul avec un crayon et une feuille de paper, chose recommandée quand on dissèque des codes, vous le savez déjà....

Maintenant, que se passe-t-il si vous rajoutez des fonctions à votre tableau et que vous (oubliez de ) gérer la nombre de  fonctions à la main (une formule, fût elle exotique, est bien pratique pour éviter ce genre d'étourderies...

Go Up