Fonction retournant un pointeur...

Le
thierryabrard
Bonjour,

Lorsque l'on défini une fonction, peut-elle retourner un pointeur
(tableau) ?

Actuellement, j'ai défini quelques fonctions du type :
void MaFonction (char Data1, char Data2)
{
le calcul
Resultat[0] = ?;
Resultat[1] = ?;
}

Pour réutiliser mon tableau Resultat et ces données dans le main, je
le défini donc en variables globale (char Resultat[2]). Mais je trouve
que cette méthode n'est pas très simple à utiliser par la suite en
effet, dans le main je me retrouve avec des fonctions :
Mafonction (Octet1, Octet2)
et faut ensuite se souvenir de quelle variable globale y est
associé

J'aimerais donc savoir si il est possible en C (j'ai encore beaucoup à
découvir) d'avoir une fonction du style : Resultat =
MaFonction(Octet1, Octet2) avec Resultat comme tableau

Faut-il faire jouer les pointeurs là dedans ?
J'ai essayé :
Char * MaFonction (char Data1, char Data2)
{
char Resultat[2];
mes calculs (Resultat[0] = ?, Resultat[1]=?)
return Resultat;
}
puis dans le main :
Resultat[0]=Mafonction(Octet1, Octet2)
Mais Resultat[1] n'est pas correct

Si vous avez une piste à ce sujet pour obtenir ce que je souhaite
Je vous remercie,
TA

  • Partager ce contenu :
Vos réponses Page 1 / 4
Trier par : date / pertinence
Éric Lévénez
Le #506549
Le 3/12/03 8:10, dans « Thierry Abrard »
Lorsque l'on défini une fonction, peut-elle retourner un pointeur
(tableau) ?


Oui.

Actuellement, j'ai défini quelques fonctions du type :
void MaFonction (char Data1, char Data2)
{
le calcul...
Resultat[0] = ?;
Resultat[1] = ?;
}

Pour réutiliser mon tableau Resultat et ces données dans le main, je
le défini donc en variables globale (char Resultat[2]).


Ce n'est pas bien d'utiliser une globale.

Mais je trouve
que cette méthode n'est pas très simple à utiliser par la suite... en
effet, dans le main je me retrouve avec des fonctions :
Mafonction (Octet1, Octet2)
et faut ensuite se souvenir de quelle variable globale y est
associé...


Il faut passer Resultat en argument à la fonction.

J'aimerais donc savoir si il est possible en C (j'ai encore beaucoup à
découvir) d'avoir une fonction du style : Resultat > MaFonction(Octet1, Octet2) avec Resultat comme tableau...


char *MaFonction(char Data1, char Data2)

Faut-il faire jouer les pointeurs là dedans ?
J'ai essayé :
Char * MaFonction (char Data1, char Data2)
{
char Resultat[2];
mes calculs... (Resultat[0] = ?, Resultat[1]=?)
return Resultat;


Non, ça ne marche pas car "Resultat" est locale à MaFonction, et n'est pas
définie en dehors. Typiquement c'est une variable en pile, et donc le
return, dépilant tout, la variable est écrasée.

Si tu veux ce genre de construction il faut soit allouer Resultat avec
malloc (il faudra normalement faire un free dessus), soit définir le tableau
en static dans la fonction :

char *MaFonction(char Data1, char Data2)
{
static char Resultat[2];

Ainsi Resultat est alloué une fois pour tout, et ne disparaîtra pas au
return.

}
puis dans le main :
Resultat[0]=Mafonction(Octet1, Octet2)


Non. MaFonction retourne un pointeur, pas un char, l'affectation adaptée
serait :

resultat2 = MaFonction(Octet1, Octet2);

Et après tu peux utiliser

resultat2[0] ou resultat2[1]

Mais Resultat[1] n'est pas correct...


Normal. À l'affectation ton compilateur doit crier que tu affecte un
pointeur à un char, non ?

--
Éric Lévénez -- Unix is not only an OS, it's a way of life.

Marc Boyer
Le #506545
Thierry Abrard wrote:
Bonjour,

Lorsque l'on défini une fonction, peut-elle retourner un pointeur
(tableau) ?


Oui, toute la question etant de savoir qui est en charge d'allouer
et de liberer la memoire de ce tableau.

Actuellement, j'ai défini quelques fonctions du type :
[SNIP]

Pour réutiliser mon tableau Resultat et ces données dans le main, je
le défini donc en variables globale (char Resultat[2]). Mais je trouve
que cette méthode n'est pas très simple à utiliser par la suite...


Et c'est entre autre pour cela qu'on la deconseille fortement.

J'aimerais donc savoir si il est possible en C (j'ai encore beaucoup à
découvir) d'avoir une fonction du style : Resultat > MaFonction(Octet1, Octet2) avec Resultat comme tableau...


Une fonction peut retourner un pointeur qui est l'adresse d'un
tableau, mais pas un tableau (dans le sens de copie des elements),
a moins d'encapsuler le tableau dans une structure.

J'ai essayé :
Char * MaFonction (char Data1, char Data2)
{
char Resultat[2];
mes calculs... (Resultat[0] = ?, Resultat[1]=?)
return Resultat;
}
puis dans le main :
Resultat[0]=Mafonction(Octet1, Octet2)
Mais Resultat[1] n'est pas correct...


Parce que ta fonction retourne un pointeur sur une variable
locale a la fonction MaFonction, et que quand cette fonction
est terminee, la variable n'existe plus.

Si vous avez une piste à ce sujet pour obtenir ce que je souhaite...


Le version la plus classique, c'est

void MaFonction(char Data1, char Data2, char[] Resultat){
// Tes calculs
}

int main(){
char Res[2];
...
MaFonction(Octet1, Octet2, Res);
...
}

On peut trouver d'autres solutions, avec des variables
locales statiauesm des enregistrements, de l'allocation
dynamique, mais cette solution la devrait je pense resoudre
ton probleme.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Marc Boyer
Le #506544
Éric Lévénez wrote:
Le 3/12/03 8:10, dans « Thierry Abrard »
Si tu veux ce genre de construction il faut soit allouer Resultat avec
malloc (il faudra normalement faire un free dessus), soit définir le tableau
en static dans la fonction :

char *MaFonction(char Data1, char Data2)
{
static char Resultat[2];

Ainsi Resultat est alloué une fois pour tout, et ne disparaîtra pas au
return.


Je trouve dangeureux de presenter cette solution a quelqu'un
qui semble debuter. S'il s'habitue a ce type de passage de parametre,
il va avoir du mal s'il fait des appels successifs a la fonction,
voire un appel recursif (plus rare).

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

DINH Viêt Hoà
Le #506541

char *MaFonction(char Data1, char Data2)
{
static char Resultat[2];

Ainsi Resultat est alloué une fois pour tout, et ne disparaîtra pas au
return.


Je trouve dangeureux de presenter cette solution a quelqu'un
qui semble debuter. S'il s'habitue a ce type de passage de parametre,
il va avoir du mal s'il fait des appels successifs a la fonction,
voire un appel recursif (plus rare).


Il existe sinon l'alternative :

char * MaFonction(char Data1, char Data2)
{
char * Resultat;

Resultat = malloc(2 * sizeof(* Resultat));

Resultat[0] = truc;
Resultat[1] = autre_truc;

return Resultat;
}

Il faut juste faire attention à bien libérer la mémoire utilisée par le
résultat avec free().

--
DINH V. Hoa,

etPan! - newsreader, mail user agent -- http://libetpan.sf.net/etpan


Marc Boyer
Le #506311
DINH Viêt Hoà wrote:

Il existe sinon l'alternative :

char * MaFonction(char Data1, char Data2)
{
char * Resultat;

Resultat = malloc(2 * sizeof(* Resultat));

Resultat[0] = truc;
Resultat[1] = autre_truc;

return Resultat;
}

Il faut juste faire attention à bien libérer la mémoire utilisée par le
résultat avec free().


Oui, mais Eric avait enonce cette possibilite.
Ceci dit, hors cas des initialiseurs d'ADT, j'evite les fonctions
qui retournent une memoire allouee. J'ai beaucoup lu (et pas mal constate
avec des debutants) que les gens avaient du mal a liberer la memoire
qu'ils n'avaient pas eut meme explicitement alloue.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Erwan David
Le #506310
DINH Viêt Hoà

Il faut juste faire attention à bien libérer la mémoire utilisée par le
résultat avec free().


Et à commenter la fonction en disant qu'elle alloue un buffer et que
l'appelant est responsable de la désallocation.

Yves ROMAN
Le #506307

Bonjour,

Lorsque l'on défini une fonction, peut-elle retourner un pointeur
(tableau) ?

Actuellement, j'ai défini quelques fonctions du type :
void MaFonction (char Data1, char Data2)
{
le calcul...
Resultat[0] = ?;
Resultat[1] = ?;
}

Pour réutiliser mon tableau Resultat et ces données dans le main, je
le défini donc en variables globale (char Resultat[2]). Mais je trouve
que cette méthode n'est pas très simple à utiliser par la suite... en
effet, dans le main je me retrouve avec des fonctions :
Mafonction (Octet1, Octet2)
et faut ensuite se souvenir de quelle variable globale y est
associé...

[...]


Si vous avez une piste à ce sujet pour obtenir ce que je souhaite...
Je vous remercie,


Comme personne n'en a parlé (sans doute parce que ca ne correspond pas au titre)
mais comme c'est aussi une solution, je te rappelle l'utilisation du passage en
paramètre :

void MaFonction (char Data1, char Data2, char Resultat[2])
{
le calcul...
Resultat[0] = ?;
Resultat[1] = ?;
}

et a l'appel :

char MonResultat[2] ;

MaFonction(Octet1,Octet2,MonResultat) ;

Emmanuel Delahaye
Le #506136
In 'fr.comp.lang.c', (Thierry Abrard) wrote:

Lorsque l'on défini une fonction, peut-elle retourner un pointeur
(tableau) ?


Une fonction peut ou non retourner une valeur. Cette valeur peut être une
adresse, dans ce cas, le type retourné est 'pointeur sur le type voulu'.

char const *fa();
int *fb();
struct xx *fc();

Toutefois, pour pouvoir être utilisée (déréférencée), cette adresse doit être
valide, notamment après l'exécution de la fonction.

C'est le cas de l'adresse :

- d'une variable locale de l'appelant.
- d'un paramètre 'adresse valide' de l'appelant.
- d'une variable statique (peu recommandé sauf pour une donnée constante)
- d'une variable allouée avec malloc() ou fopen().

Actuellement, j'ai défini quelques fonctions du type :
void MaFonction (char Data1, char Data2)
{
le calcul...
Resultat[0] = ?;
Resultat[1] = ?;
}

Pour réutiliser mon tableau Resultat et ces données dans le main, je
le défini donc en variables globale (char Resultat[2]). Mais je trouve
que cette méthode n'est pas très simple à utiliser par la suite... en
effet, dans le main je me retrouve avec des fonctions :
Mafonction (Octet1, Octet2)
et faut ensuite se souvenir de quelle variable globale y est
associé...


Oui, cette conception est d'apparence simple, mais trompeuse. Il est
formellement déconseillé de travailler comme ça pour de nombreuses raisons
maintes fois évoquées (lire les archives et la FAQ).

J'aimerais donc savoir si il est possible en C (j'ai encore beaucoup à
découvir) d'avoir une fonction du style : Resultat > MaFonction(Octet1, Octet2) avec Resultat comme tableau...


On ne peut pas retourner un tableau en C. La méthode la plus courante est:

MaFonction (Resultat, Octet1, Octet2)

ou mieux

MaFonction (Resultat, Taille_de_resultat, Octet1, Octet2)

Faut-il faire jouer les pointeurs là dedans ?
J'ai essayé :
Char * MaFonction (char Data1, char Data2)


'char'

On évitera 'char' pour des calculs, car ils sont traités en int, ce qui
oblige le compilateur à coder des conversions qui ne font que ralentir
l'exécution. de plus, la plage est limitée, et on ne sait pas si le 'char'
est signé ou non. Bref, la plage portable garantie est de 0 à 127.

{
char Resultat[2];
mes calculs... (Resultat[0] = ?, Resultat[1]=?)
return Resultat;
}


C'est typiquement un cas interdit car l'adresse retournée n'est plus valide
une fois que l'on a quitté la fonction.

puis dans le main :
Resultat[0]=Mafonction(Octet1, Octet2)
Mais Resultat[1] n'est pas correct...


C'est possible, car le comportement est indéfini (Undefined Behaviour ou UB).
Le plus grave serait qu'il ai l'air correct. (C'est possible avec un UB).

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Emmanuel Delahaye
Le #506135
In 'fr.comp.lang.c', Marc Boyer
char * MaFonction(char Data1, char Data2)
{
char * Resultat;

Resultat = malloc(2 * sizeof(* Resultat));



if (Resultat)
{

Resultat[0] = truc;
Resultat[1] = autre_truc;



}


return Resultat;
}

Il faut juste faire attention à bien libérer la mémoire utilisée par le
résultat avec free().


Ceci dit, hors cas des initialiseurs d'ADT, j'evite les fonctions
qui retournent une memoire allouee. J'ai beaucoup lu (et pas mal constate
avec des debutants) que les gens avaient du mal a liberer la memoire
qu'ils n'avaient pas eut meme explicitement alloue.


C'est vrai. Il m'arrive d'utiliser de telles fonctions, et dans ce cas, j'y
accolle le suffixe '_dyn'

char *MaFonction_dyn (char Data1, char Data2)

C'est suffisant pour moi, mais peut être pas pour un autre...

--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/


Emmanuel Delahaye
Le #506133
In 'fr.comp.lang.c', Yves ROMAN
void MaFonction (char Data1, char Data2, char Resultat[2])


Rappelons que le '2" ici n'a qu'une valeur documentaire. La taille du tableau
n'est pas transmise, et sizeof ne donnera pas le bon résultat.

Pour éviter les tentations:

void MaFonction (char Data1, char Data2, char Resultat[])
ou
void MaFonction (char Data1, char Data2, char *Resultat)

{
le calcul...
Resultat[0] = ?;
Resultat[1] = ?;
}

et a l'appel :

char MonResultat[2] ;

MaFonction(Octet1,Octet2,MonResultat) ;


--
-ed- [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=cpp
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/

Poster une réponse
Anonyme