Langage C - problème sur 1 retour de fonction
Fermé
ianick
Messages postés
29
Date d'inscription
mardi 2 octobre 2007
Statut
Membre
Dernière intervention
14 janvier 2008
-
11 janv. 2008 à 16:46
mamiemando Messages postés 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 - 14 janv. 2008 à 22:04
mamiemando Messages postés 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 - 14 janv. 2008 à 22:04
A voir également:
- Langage C - problème sur 1 retour de fonction
- Fonction si et - Guide
- Langage ascii - Guide
- Retour à la ligne excel - Guide
- Langage binaire - Guide
- Fonction moyenne excel - Guide
5 réponses
mamiemando
Messages postés
33435
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 décembre 2024
7 810
11 janv. 2008 à 17:31
11 janv. 2008 à 17:31
De manière générale c'est une mauvaise idée de travailler avec un tableau statique, il vaut mieux travailler avec le pointeur, et ce pour deux raisons :
1) ta fonction sera utilisable pour des tableaux de taille autre
2) tu manipules l'adresses du tableau au lieu de le recopier (cf cours en C sur les fonctions : chaque paramètre est recopié dans la pile)
Conclusion : essaye de travailler avec un char *. Si tu ne t'en sors pas donne nous le code de la fonction en question.
Bonne chance
1) ta fonction sera utilisable pour des tableaux de taille autre
2) tu manipules l'adresses du tableau au lieu de le recopier (cf cours en C sur les fonctions : chaque paramètre est recopié dans la pile)
Conclusion : essaye de travailler avec un char *. Si tu ne t'en sors pas donne nous le code de la fonction en question.
Bonne chance
ianick
Messages postés
29
Date d'inscription
mardi 2 octobre 2007
Statut
Membre
Dernière intervention
14 janvier 2008
5
12 janv. 2008 à 17:26
12 janv. 2008 à 17:26
Merci, je vais me débrouiller avec un char* pour le return de ma fonction
juanpablo
Messages postés
142
Date d'inscription
mercredi 30 mai 2007
Statut
Membre
Dernière intervention
16 juin 2008
10
12 janv. 2008 à 18:51
12 janv. 2008 à 18:51
bonsoir
le nom d'un tableau d'element T est de type T* cad pointeur
si dans une fonction on a
char tc[100];
l'instruction
return tc;
renvoie un char * et il faut declarer la fonction comme char * mafonction(....
(meme chose en argument tc transmet un pointeur et non une copie du tableau , ça étonne pas mal de monde)
le nom d'un tableau d'element T est de type T* cad pointeur
si dans une fonction on a
char tc[100];
l'instruction
return tc;
renvoie un char * et il faut declarer la fonction comme char * mafonction(....
(meme chose en argument tc transmet un pointeur et non une copie du tableau , ça étonne pas mal de monde)
mamiemando
Messages postés
33435
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 décembre 2024
7 810
13 janv. 2008 à 00:11
13 janv. 2008 à 00:11
En résumé ça donne ;
En outre attention à un point très important : un char * comme tout adresse, doit pointer vers un contenu qui existe. En outre toute variable locale est détruite à la fin de l'appel d'une fonction. Ca veut donc dire que ton char * ne doit pas être l'adresse d'une variable locale à la fonction, et pour ça il faut
1) soit avoir alloué cette zone à l'extérieur de la fonction
2) soit faire un malloc
Bonne chance
char *Creation_Nom_FichierLog (struct tm Aujourdhui, time_t Now, char *Nom_Fic);
En outre attention à un point très important : un char * comme tout adresse, doit pointer vers un contenu qui existe. En outre toute variable locale est détruite à la fin de l'appel d'une fonction. Ca veut donc dire que ton char * ne doit pas être l'adresse d'une variable locale à la fonction, et pour ça il faut
1) soit avoir alloué cette zone à l'extérieur de la fonction
2) soit faire un malloc
Bonne chance
ianick
Messages postés
29
Date d'inscription
mardi 2 octobre 2007
Statut
Membre
Dernière intervention
14 janvier 2008
5
14 janv. 2008 à 18:04
14 janv. 2008 à 18:04
Merci pour toutes ses explications
dur dur les pointeurs en c... mais on s'en sort
dur dur les pointeurs en c... mais on s'en sort
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mamiemando
Messages postés
33435
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
18 décembre 2024
7 810
14 janv. 2008 à 22:04
14 janv. 2008 à 22:04
Non c'est souvent mal expliqué mais en fait c'est pas très compliqué. Chaque objet quelque soit sa taille est placé en mémoire, et à donc une adresse mémoire. L'adresse d'un objet x, quel qu'il soit (pointeur, structure, ou type de base) a une adresse notée &x. L'opérateur & ne peut être appliqué plusieurs fois (par exemple && x) n'a pas de sens car &x n'est pas un objet proprement dit en mémoire (et accessoirement, && c'est le et logique en C).
L'opérateur réciproque (examiner ce qu'il y a a une adresse a) c'est * : *a désigne donc l'objet à l'adresse a. Ainsi &*a = a et *&x = x.
Contrairement à l'opérateur &, l'opérateur * peut être appliqué plusieurs fois. En effet *a peut être elle-même une adresse, de même que **a et ainsi de suite. Ainsi un pointeur de type int *** est l'adresse d'un int **, elle même adresse d'un int *, elle même adresse d'un int. Ainsi si a est de type int ***, ***a est de type int. Si tu appliques * sur une adresse non initialisée (ou libérée) tu fera une erreur de segmentation.
Note qu'un tableau d'int est souvent noté int *. En fait c'est juste que l'opérateur [i] sera dans ce cas l'opérateur * décalé de i entiers. De plus une adresse, quel que soit son type, est un cas particulier d'adresse générique (ces adresses sont notées void *). En outre une adresse fait en mémoire toujours la même taille. C'est en particulier pour ça que "caster" une adresse a toujours un sens : le type d'une adresse sert juste à dire le type de l'objet à cette adresse.
Et les malloc ? Un malloc ca cherche juste en mémoire un espace de taille précisée (en paramètre du malloc), ça reserve cette zone, et ça retourne son adresse (sous forme d'une adresse générique, ie un "void *). Un malloc permet donc d'initialiser une adresse. Comme cet espace a été expllcitement alloué, il devra être explicitement libéré avec un free. Exemple : je veux allouer un tableau de n objets adjacents en mémoire de type plop_t :
Note que tu peux remplacer plop_t par n'importe quel type : un int, un char *, ce que tu veux : exemple
Note qu'allouer le char **p1 n'a pas initialisé les char * p1[0],p1[1] etc... qui devront par exemple eux aussi être initialisés avec un malloc (et dès lors libérés avec un free). Ainsi pour allouer/désallouer une matrice m x n d'entier :
Ici tu noteras qu'on libères les m[i] avant m (car sinon m[i] évaluera *m décalé de i entiers, et en évaluant m[i] tu provoquera une erreur de segmentation). L'ordre est donc important !!
En général le free correspondant à un malloc se trouve à la fin du scope (ie paire d'accolade) correspondant. Ou alors si c'est un malloc dans une fonction de création (constructeur...), le free correspondant est fait dans une fonction de destruction (destructeur).
En espérant que c'est plus clair pour toi, et surtout, en espérant ne pas t'avoir noyé, je te souhaite bonne chance avec les pointeurs !
Bonne chance
L'opérateur réciproque (examiner ce qu'il y a a une adresse a) c'est * : *a désigne donc l'objet à l'adresse a. Ainsi &*a = a et *&x = x.
Contrairement à l'opérateur &, l'opérateur * peut être appliqué plusieurs fois. En effet *a peut être elle-même une adresse, de même que **a et ainsi de suite. Ainsi un pointeur de type int *** est l'adresse d'un int **, elle même adresse d'un int *, elle même adresse d'un int. Ainsi si a est de type int ***, ***a est de type int. Si tu appliques * sur une adresse non initialisée (ou libérée) tu fera une erreur de segmentation.
Note qu'un tableau d'int est souvent noté int *. En fait c'est juste que l'opérateur [i] sera dans ce cas l'opérateur * décalé de i entiers. De plus une adresse, quel que soit son type, est un cas particulier d'adresse générique (ces adresses sont notées void *). En outre une adresse fait en mémoire toujours la même taille. C'est en particulier pour ça que "caster" une adresse a toujours un sens : le type d'une adresse sert juste à dire le type de l'objet à cette adresse.
Et les malloc ? Un malloc ca cherche juste en mémoire un espace de taille précisée (en paramètre du malloc), ça reserve cette zone, et ça retourne son adresse (sous forme d'une adresse générique, ie un "void *). Un malloc permet donc d'initialiser une adresse. Comme cet espace a été expllcitement alloué, il devra être explicitement libéré avec un free. Exemple : je veux allouer un tableau de n objets adjacents en mémoire de type plop_t :
plop_t * plop = (plop_t *) malloc(n*sizeof(plop_t)); ... free(plop);
Note que tu peux remplacer plop_t par n'importe quel type : un int, un char *, ce que tu veux : exemple
char ** p1 = (char **)malloc(n*sizeof(char *)); int *p2 = (int *)malloc(n*sizeof(int)); ... free(p2); free(p1);
Note qu'allouer le char **p1 n'a pas initialisé les char * p1[0],p1[1] etc... qui devront par exemple eux aussi être initialisés avec un malloc (et dès lors libérés avec un free). Ainsi pour allouer/désallouer une matrice m x n d'entier :
int **m = (int **)malloc(m*sizeof(int *)); for(unsigned i=0;i<m;++i){ m[i] = (int *) malloc(n*sizeof(int)); } ... for(unsigned i=0;i<m;++i){ free(m[i]); } free(m);
Ici tu noteras qu'on libères les m[i] avant m (car sinon m[i] évaluera *m décalé de i entiers, et en évaluant m[i] tu provoquera une erreur de segmentation). L'ordre est donc important !!
En général le free correspondant à un malloc se trouve à la fin du scope (ie paire d'accolade) correspondant. Ou alors si c'est un malloc dans une fonction de création (constructeur...), le free correspondant est fait dans une fonction de destruction (destructeur).
En espérant que c'est plus clair pour toi, et surtout, en espérant ne pas t'avoir noyé, je te souhaite bonne chance avec les pointeurs !
Bonne chance