OVH Cloud OVH Cloud

[Debutan C++] Retour pointeur

51 réponses
Avatar
PtitMat
Bonjour,

Je voudrais ecrire une fonction qui me retourne un pointeur vers une
variable.
Est-ce possible?
Je vous remercie pour votre aide

Mat.

10 réponses

1 2 3 4 5
Avatar
Fabien LE LEZ
On Thu, 18 Nov 2004 09:26:33 +0100, Pierre Maurette
:

static int * dToRArray[4];


Ben... non. Eviter les "magic values" comme la peste (sauf peut-être
42).

static int const NB_dToRArray= 4;
static int * dToRArray [NB_dToRArray];


--
;-)

Avatar
Pierre Maurette
Fabien LE LEZ a écrit:

On Thu, 18 Nov 2004 09:26:33 +0100, Pierre Maurette
:

static int * dToRArray[4];


Ben... non. Eviter les "magic values" comme la peste (sauf peut-être
42).

static int const NB_dToRArray= 4;
static int * dToRArray [NB_dToRArray];
Merci. Soyez rassuré, c'est une règle que j'applique le plus souvent.

--
Pierre


Avatar
PtitMat
Christophe Lephay wrote:
PtitMat wrote:

Je commence par dejà apprendre a utiliser les exeptions avec les
réponses précédentes.
Chaque chose en son temps.
La factory sera pour plus tard (je vai eviter de faire une usine a gaz
parfaite pour me perdre dans les vapeurs)... ;-)



class instruction
{
...
virtual void extrait_operandes( std::istream& ) = 0;

public:
virtual ~instruction() {}
};


class ajoute : public instruction
{
char valeur;
reg registre;

void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
...
}

public:
// la fonction fabrique
static ajoute * make( std::istream& is )
{
ajoute * instr = new ajoute;
instr->extrait_operandes( is );
return instr;
}

};

classe soustrait : public instruction
{
char valeur;
reg registre;

void extrait_operandes( std::istream& is )
{
// extraire depuis le flux les opérandes requis
...
}

public:
// la fonction fabrique
static soustrait * make( std::istream& is )
{
soustrait * instr = new soustrait;
instr->extrait_operandes( is );
return instr;
}

};

Tu peux faire un fabrique sommaire basée sur un map :

typedef instruction * (* pf ) ( std::istream& ); // typedef pour pointeur
sur fonction
std::map< char, pf > fabrique;

// initialisation de la fabrique :
fabrique[ '1' ] = ajoute::&make;
fabrique[ '2' ] = soustrait::&make;
...

// disons que la rom est mappée dans le fichier "rom" :
std::ifstream ifs( "rom" );

// lecture du premier digit, code de l'instruction
char c;
ifs.get( c );

// recherche du digit
std::map< char, pf >::iterator it;
it = fabrique.find( c );

// erreur si l'instruction n'est pas reconnue par la fabrique
if( it == fabrique.end() )
throw( "instruction invalide" );

// dans le cas contraire, on appelle la fonction make associée via
déréférencement de l'itérateur
instruction * instr = (*it)( ifs ); // appel de la fonction make
...



En gros, ça te donne l'idée. Bonne digestion ;)

Chris


Bonjour a tous

Merci pour votre aide.
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a
l'avenir je decouvre un bug ;-)

int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;

default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to register R"
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}


Avatar
drkm
Fabien LE LEZ writes:

On Thu, 18 Nov 2004 19:20:54 +0100, drkm :

Pourquoi ? Puisque toutes les fonctions membres utilisent
`dToR()' ... ;-)


Dans ce cas, ces données devraient être dans une classe à part, ne
contenant pas grand-chose d'autre que les pRx et dToR().


Je ne te suis pas ...

--drkm


Avatar
drkm
Fabien LE LEZ writes:

On Thu, 18 Nov 2004 09:26:33 +0100, Pierre Maurette
:

static int * dToRArray[4];


Ben... non. Eviter les "magic values" comme la peste (sauf peut-être
42).

static int const NB_dToRArray= 4;
static int * dToRArray [NB_dToRArray];


Ben dans ce cas, pour éviter une valeur magique, j'aurais dit :

static int * dToRArray[] ;

Non ?

--drkm


Avatar
Christophe Lephay
PtitMat wrote:
Bonjour a tous
Merci pour votre aide.
J'ai écrit ma fonction de la sorte et elle ne changera plus sauf si a
l'avenir je decouvre un bug ;-)

int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;

default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to register R" (*)
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}


Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus
judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...

Chris

Avatar
drkm
PtitMat writes:

Ne cite pas l'entièreté de l'article auquel tu réponds, si cela
n'est pas nécessaire, stp.

int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;

default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to register R"
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}


Ici, je n'ai pas compris l'utilisation d'une exception. As-tu
essayé une des autres réponses qu'il t'a été données ? J'aurais
tendence à utiliser celle de James. Elle ne te convient pas ?

--drkm

Avatar
Jean-Marc Bourguet
PtitMat writes:

J'ai écrit ma fonction de la sorte et elle ne changera
plus sauf si a l'avenir je decouvre un bug ;-)

int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;

default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to
register R" << Rx << " which doesn't exist" << endl;
exit (0);
}
}


* Les exceptions, c'est fait pour sortir de la fonction qui
les lance -- et bien souvent pour dépiler plusieurs
fonctions par la même occasion car sinon il y a des chances
qu'un autre moyen de rapporter l'erreur soit meilleur.

* Pourquoi les pRx ne forment-ils pas un tableau (je
pourrais comprendre s'ils portaient d'autres noms -- et
encore, on peut faire un tableau avec des copies des
pointeurs puisque c'en est --, mais ici c'est vraiment
criant) ?

* exit() dans du C++ est presque toujours une erreur. Ou
bien on veut faire du clean-up et alors c'est une exception
qu'il faut jeter et qui doit arriver jusqu'à main(), ou bien
on n'en veut pas et c'est abort() (ou _exit() pour Unix,
_Exit() avec un lib c99) éventuellement précédé d'un
fflush(0) si on veut vider les tampons.

* je modéliserais les registres d'un processeur par des
unsigned et pas des int.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
PtitMat
Christophe Lephay wrote:
PtitMat wrote:

cout << "Instruction number " << lPc << " Try to acces to register R" (*)
<< Rx << " which doesn't exist" << endl;
exit (0);
}
}



Ben ça me semble correct, si ce n'est qu'il serait potentiellement plus
judicieux de remplacer le cout de la ligne marquée par (*) par un cerr...

Chris


C'est fait.

Je suis débutant, comme indiqué dans l'énoncé du problème.
Je ne conaissait pas cerr, mais c'est vrai que 'est plus logique
d'utiliser la sortie d'érreur que la sortie standard.

Mat


Avatar
Pierre Maurette
Jean-Marc Bourguet a écrit:

PtitMat writes:

J'ai écrit ma fonction de la sorte et elle ne changera
plus sauf si a l'avenir je decouvre un bug ;-)

int * Ccpu::dToR( int dx )
{
try
{
switch( dx )
{
case 0: return pR0; break;
case 1: return pR1; break;
case 2: return pR2; break;
case 3: return pR3; break;

default: throw( dx );
}
}
catch (int Rx)
{
int lPc;
lPc = getPc();//Prend la valeur de Program Counter
cout << "Instruction number " << lPc << " Try to acces to
register R" << Rx << " which doesn't exist" << endl;
exit (0);
}
}


* Les exceptions, c'est fait pour sortir de la fonction qui
les lance -- et bien souvent pour dépiler plusieurs
fonctions par la même occasion car sinon il y a des chances
qu'un autre moyen de rapporter l'erreur soit meilleur.

* Pourquoi les pRx ne forment-ils pas un tableau (je
pourrais comprendre s'ils portaient d'autres noms -- et
encore, on peut faire un tableau avec des copies des
pointeurs puisque c'en est --, mais ici c'est vraiment
criant) ?
Oui, et peut-être une enum pour dx. Ça ne garantit pas que dx reste

entre les bornes, mais ça aide. En fait, ça dépend du genre des
registres. MMX0, ..., MMX7 se prêtent à un dx int (et une arithmétique
en modulo), EAX, EBX, etc. à une enum.

* je modéliserais les registres d'un processeur par des
unsigned et pas des int.
Une union serait pas mal, non ?

--
Pierre


1 2 3 4 5