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
thierryabrard
Merci beaucoup pour tout ces éléments de réponses... je devrais
maintenant sans problème trouver une solution. Même si l'affectation
dynamique avec les malloc etc n'est pas évident à comprendre (!), je
sais où chercher.

Je me contenterai donc pour le moment du passage du résultat en
paramètre de la fonction...

Good job !
TA
Avatar
Marc Boyer
Thierry Abrard wrote:
Merci beaucoup pour tout ces éléments de réponses... je devrais
maintenant sans problème trouver une solution. Même si l'affectation
dynamique avec les malloc etc n'est pas évident à comprendre (!), je
sais où chercher.


Disons qu'il vaut mieux prendre un problème après l'autre.
La maîtrise de l'allocation dynamique vient après la maîtrise
des structures de controle de base et l'appel de sous programme.

Je me contenterai donc pour le moment du passage du résultat en
paramètre de la fonction...


Un problème après l'autre, en effet.

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

Avatar
espie
In article ,
Thierry Abrard wrote:
Merci beaucoup pour tout ces éléments de réponses... je devrais
maintenant sans problème trouver une solution. Même si l'affectation
dynamique avec les malloc etc n'est pas évident à comprendre (!), je
sais où chercher.

En fait, lorsqu'on peut eviter l'allocation dynamique avec malloc, on

s'en porte assez souvent mieux.

Oui, c'est souvent necessaire, mais dans la plupart des cas ou on peut
s'en passer, s'en passer est souvent plus efficace.

[ inserer ici un couplet standard sur les perfs respectives des tableaux
ajustes avec realloc compares aux listes chainees ]

Avatar
Marc Lasson
Marc Espie wrote:

[ inserer ici un couplet standard sur les perfs respectives des tableaux
ajustes avec realloc compares aux listes chainees ]


Euh, pourrais-je voir ce couplet (ou avoir une référence si vous en avez
déjà parlé) ?

Marci,

--
Marc, fier d'avoir le prénom le plus fréquent de fclc.

Avatar
kilobug

In article ,
Thierry Abrard wrote:
Merci beaucoup pour tout ces éléments de réponses... je devrais
maintenant sans problème trouver une solution. Même si l'affectation
dynamique avec les malloc etc n'est pas évident à comprendre (!), je
sais où chercher.

En fait, lorsqu'on peut eviter l'allocation dynamique avec malloc, on

s'en porte assez souvent mieux.


Je ne suis pas du tout d'accord (sauf pour les débutants qui
commencent juste à apprendre les pointeurs), mais on en a déjà un peu
discuté, et ce n'est pas le sujet du forum.

Oui, c'est souvent necessaire, mais dans la plupart des cas ou on peut
s'en passer, s'en passer est souvent plus efficace.


[ inserer ici un couplet standard sur les perfs respectives des tableaux
ajustes avec realloc compares aux listes chainees ]


Tu m'expliques comment tu fais des listes chaînées sans malloc ?
Perso, je sais pas faire :/

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org


Avatar
DINH Viêt Hoà

Tu m'expliques comment tu fais des listes chaînées sans malloc ?
Perso, je sais pas faire :/


Un tableau indexé dont les cellules contiennent au moins un élément :
"indice_suivant" et tu remplis cet élément avec l'indice dans le
tableau de l'élément suivant à chaîner.

--
DINH V. Hoa,

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

Avatar
espie
In article ,
Gaël Le Mignot wrote:


In article ,
Thierry Abrard wrote:
Merci beaucoup pour tout ces éléments de réponses... je devrais
maintenant sans problème trouver une solution. Même si l'affectation
dynamique avec les malloc etc n'est pas évident à comprendre (!), je
sais où chercher.

En fait, lorsqu'on peut eviter l'allocation dynamique avec malloc, on

s'en porte assez souvent mieux.


Je ne suis pas du tout d'accord (sauf pour les débutants qui
commencent juste à apprendre les pointeurs), mais on en a déjà un peu
discuté, et ce n'est pas le sujet du forum.


Le contraire m'aurait etonne. Je pense que tu as tres fortement tort, et
les perfs mesurees sur un systeme tendent a le prouver, par rapport a la
dialectique qui sous-tend le projet Hurd.

Oui, c'est souvent necessaire, mais dans la plupart des cas ou on peut
s'en passer, s'en passer est souvent plus efficace.

[ inserer ici un couplet standard sur les perfs respectives des tableaux
ajustes avec realloc compares aux listes chainees ]


Tu m'expliques comment tu fais des listes chaînées sans malloc ?
Perso, je sais pas faire :/


Ben justement, c'est le contraire.

Voici donc le couplet standard, vite vu.

Supposons qu'on ait une structure de donnees a stocker en nombre
consequents, disons struct machin.

- on peut faire des listes chainees avec, ce qui implique plein de
pointeurs et de malloc, et des gros problemes de localite des donnees.

- on peut tout stocker dans un tableau de taille limitee, quitte a faire
un coup de realloc() lorsque le tableau deborde.

La 2e approche explose tres regulierement la premiere en termes de
performances.



Avatar
kilobug

En fait, lorsqu'on peut eviter l'allocation dynamique avec malloc, on
s'en porte assez souvent mieux.


Je ne suis pas du tout d'accord (sauf pour les débutants qui
commencent juste à apprendre les pointeurs), mais on en a déjà un peu
discuté, et ce n'est pas le sujet du forum.



Le contraire m'aurait etonne. Je pense que tu as tres fortement
tort, et les perfs mesurees sur un systeme tendent a le prouver,
par rapport a la dialectique qui sous-tend le projet Hurd.


Euh, les perfs du Hurd n'ont rien à voir avec malloc, mais à la
vitesse des IPCs sous Mach (pour info, avec L4 les IPCs sont environ
dix fois plus rapides)

D'autre part, les perfs ne sont pas le plus important dans beaucoup de
cas, la flexibilité, la robustesse et l'absence de contraintes pour
l'utilisateur sont plus importantes dans bcp de cas.

Et pour les perfs, en général seules quelques parties d'un programme
ont un impact réel sur les performances globales du programme.


Voici donc le couplet standard, vite vu.


Supposons qu'on ait une structure de donnees a stocker en nombre
consequents, disons struct machin.


- on peut faire des listes chainees avec, ce qui implique plein de
pointeurs et de malloc, et des gros problemes de localite des donnees.


- on peut tout stocker dans un tableau de taille limitee, quitte a faire
un coup de realloc() lorsque le tableau deborde.


La 2e approche explose tres regulierement la premiere en termes de
performances.


Ah oui, je suis d'accord (sauf si on souvent à retirer des éléments en
plein milieu).

Mais la 2ème approche utilise malloc aussi, et tu semblais donner ça
comme exemple de "sans malloc on fait mieux", j'ai sans doute mal
compris.

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org



Avatar
DINH Viêt Hoà

Euh, les perfs du Hurd n'ont rien à voir avec malloc, mais à la
vitesse des IPCs sous Mach (pour info, avec L4 les IPCs sont environ
dix fois plus rapides)


L'évaluation probable des performances fait partie de la phase de
conception en général. Je crois que le problème des performances de Mach
était assez rapidement connu. Pourquoi ont-ils fait un tel choix ?

D'autre part, les perfs ne sont pas le plus important dans beaucoup de
cas, la flexibilité, la robustesse et l'absence de contraintes pour
l'utilisateur sont plus importantes dans bcp de cas.


Le domaine nommé "système" en informatique (qui comprend ce qui est
systèmes d'exploitation) consiste principalement à améliorer les
performances d'un système. Il y a eu effectivement la phase micronoyau
pendant laquelle les gens ont essayé de faire quelque chose de plus
modulaire mais ils se sont rapidement aperçu que cela était au détriment
des performances et qu'une des solutions pour obtenir des performances
était d'avoir un unique serveur sur le micronoyau (Darwin (aussi connu
sous le nom de Mac OS X)). Je crois que c'était également le cas pour
OSF/1.

Voici donc le couplet standard, vite vu.

Supposons qu'on ait une structure de donnees a stocker en nombre
consequents, disons struct machin.



cas 1 :

- on peut faire des listes chainees avec, ce qui implique plein de
pointeurs et de malloc, et des gros problemes de localite des donnees.



cas 2 :

- on peut tout stocker dans un tableau de taille limitee, quitte a faire
un coup de realloc() lorsque le tableau deborde.

La 2e approche explose tres regulierement la premiere en termes de
performances.


Ah oui, je suis d'accord (sauf si on souvent à retirer des éléments en
plein milieu).


ai-je mal décrit mon système de liste chaînée dans mon post précédent ?

struct cellule {
/* ... */
unsigned int suivant;
};

struct cellule liste_chainee[LISTE_TAILLE_MAX];

Mais la 2ème approche utilise malloc aussi, et tu semblais donner ça
comme exemple de "sans malloc on fait mieux", j'ai sans doute mal
compris.


alors, dans le cas où on fait un malloc par cellule,(cas 1/)
on a un nombre de malloc() en O(n).

dans le cas 2/ décrit par Marc Espié, on obtient un nombre de malloc()
en O(log(n)) dans le pire des cas, c'est-à-dire : si on n'est pas arrivé
à évalué la taille maximum de la liste, ce que l'on peut résoudre par
limiter la taille de la liste, ce qui permet dans le meilleur des cas
d'obtenir un unique malloc(), voire zéro dans le cas d'une déclaration
statique.

--
DINH V. Hoa,

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


Avatar
kilobug

Euh, les perfs du Hurd n'ont rien à voir avec malloc, mais à la
vitesse des IPCs sous Mach (pour info, avec L4 les IPCs sont environ
dix fois plus rapides)



L'évaluation probable des performances fait partie de la phase de
conception en général. Je crois que le problème des performances de Mach
était assez rapidement connu. Pourquoi ont-ils fait un tel choix ?


Je ne sais pas, je n'étais pas là ;)

Enfin, il y a plusieurs facteurs, l'un d'entre eux étant l'évolution
du matériel (les CPUs ont évolué dans un sens qui rend encore plus
coûteuse l'approche de Mach), un autre l'absence d'alternative (à
l'époque où Mach fut choisi, L4 ni aucun de ses prédécesseurs
n'existaient); d'autre part, il est possible d'optimiser le Hurd même
sur Mach, mais ça n'a jamais été fait, parce qu'on cherche d'abord à
avoir un système qui marche avant de l'optimiser (et ça c'est valable
un peu partout).

D'autre part, les perfs ne sont pas le plus important dans beaucoup de
cas, la flexibilité, la robustesse et l'absence de contraintes pour
l'utilisateur sont plus importantes dans bcp de cas.



Le domaine nommé "système" en informatique (qui comprend ce qui est
systèmes d'exploitation) consiste principalement à améliorer les
performances d'un système.


Là, je ne suis pas d'accord. Un OS doit d'abord assurer la sécurité,
être fiable, et flexible. Les perfs sont importantes aussi, mais je ne
dirai pas que c'est le principal.

D'ailleurs si on ne voulait que des perfs, on mettrait tout en espace
noyau (ring 0 sur x86), on aurait aucune sécurité, le moindre bug
pourrait faire planter la machine, mais on gagnerait niveau perf.

Il y a eu effectivement la phase micronoyau pendant laquelle les
gens ont essayé de faire quelque chose de plus modulaire mais ils
se sont rapidement aperçu que cela était au détriment des
performances et qu'une des solutions pour obtenir des performances
était d'avoir un unique serveur sur le micronoyau (Darwin (aussi
connu sous le nom de Mac OS X)). Je crois que c'était également le
cas pour OSF/1.


Et une autre solution est d'avoir de l'IPC rapide, comme L4 le fait =)

Voici donc le couplet standard, vite vu.

Supposons qu'on ait une structure de donnees a stocker en nombre
consequents, disons struct machin.




cas 1 :


- on peut faire des listes chainees avec, ce qui implique plein de
pointeurs et de malloc, et des gros problemes de localite des donnees.




cas 2 :


- on peut tout stocker dans un tableau de taille limitee, quitte a faire
un coup de realloc() lorsque le tableau deborde.

La 2e approche explose tres regulierement la premiere en termes de
performances.


Ah oui, je suis d'accord (sauf si on souvent à retirer des éléments en
plein milieu).



ai-je mal décrit mon système de liste chaînée dans mon post précédent ?


struct cellule {
/* ... */
unsigned int suivant;
};


struct cellule liste_chainee[LISTE_TAILLE_MAX];


En effet, mais là, bonjour le gaspillage de mémoire ou la limitation :/
enfin, ça + realloc, pkoi pas :)

Certaines opérations ne sont pas facilement faisables (concaténation
de listes, découpage d'une liste en deux, ...) mais dans certains cas
pkoi pas

Et comment tu gères les entrées "libres" dans ton tableau ? Faut un
méchanisme à côté pour ça, sinon tu es obligé de parcourir la liste
complètement pour rajouter un élément.

Mais la 2ème approche utilise malloc aussi, et tu semblais donner ça
comme exemple de "sans malloc on fait mieux", j'ai sans doute mal
compris.



alors, dans le cas où on fait un malloc par cellule,(cas 1/)
on a un nombre de malloc() en O(n).
dans le cas 2/ décrit par Marc Espié, on obtient un nombre de malloc()
en O(log(n))


oui oui, je suis d'accord

dans le pire des cas, c'est-à-dire : si on n'est pas arrivé à
évalué la taille maximum de la liste, ce que l'on peut résoudre par
limiter la taille de la liste, ce qui permet dans le meilleur des
cas d'obtenir un unique malloc(), voire zéro dans le cas d'une
déclaration statique.


tu sais ce que je pense de ces limitations là... ça soit limite
vraiment l'utilisateur, soit on est large et on gaspille bcp de
mémoire

--
Gael Le Mignot "Kilobug" - - http://kilobug.free.fr
GSM : 06.71.47.18.22 (in France) ICQ UIN : 7299959
Fingerprint : 1F2C 9804 7505 79DF 95E6 7323 B66B F67B 7103 C5DA

Member of HurdFr: http://hurdfr.org - The GNU Hurd: http://hurd.gnu.org



1 2 3 4