Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Fonction retournant un pointeur...

36 réponses
Avatar
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

10 réponses

1 2 3 4
Avatar
Éric Lévénez
Le 3/12/03 8:10, dans ,
« Thierry Abrard » a écrit :

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 -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
Marc Boyer
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 :-(

Avatar
Marc Boyer
Éric Lévénez wrote:
Le 3/12/03 8:10, dans ,
« Thierry Abrard » a écrit :

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 :-(

Avatar
DINH Viêt Hoà

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


Avatar
Marc Boyer
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 :-(

Avatar
Erwan David
DINH Viêt Hoà écrivait :


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.

Avatar
Yves ROMAN

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) ;

Avatar
Emmanuel Delahaye
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/

Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Marc Boyer wrote:

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/


Avatar
Emmanuel Delahaye
In 'fr.comp.lang.c', Yves ROMAN wrote:

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/

1 2 3 4