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
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
Oui.
Ce n'est pas bien d'utiliser une globale.
Il faut passer Resultat en argument à la fonction.
char *MaFonction(char Data1, char Data2)
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.
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]
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.
Oui, toute la question etant de savoir qui est en charge d'allouer
et de liberer la memoire de ce tableau.
Et c'est entre autre pour cela qu'on la deconseille fortement.
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.
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.
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 :-(
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 :-(
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
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 :-(
Et à commenter la fonction en disant qu'elle alloue un buffer et que
l'appelant est responsable de la désallocation.
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) ;
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().
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).
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)
'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.
C'est typiquement un cas interdit car l'adresse retournée n'est plus valide
une fois que l'on a quitté la fonction.
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/
if (Resultat)
{
}
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/
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)
--
-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/