Bonjour tout le monde,
Voilà je souhaite enoyer une structure de données en paramètres dans une fonction.
Je voudrais savoir si la manipulation à executer est la même que pour une variable banale(exemple : entier, chaîne de caractères).
Merci
Bonjour tout le monde,
Voilà je souhaite enoyer une structure de données en paramètres dans une fonction.
Je voudrais savoir si la manipulation à executer est la même que pour une variable banale(exemple : entier, chaîne de caractères).
Merci
Bonjour,
oui, tu la declares de meme facon que tu la declarerais au sein d'une fonction.
Donc il n'y a pas d'histoires de pointeur comme je l'ai entendu?
j'avais lu qu'avec le C K&R, c'etait obligé de la passer en pointeur, mais j'en sais pas plus.
en ANSI C (je crois que c'est la majorite des compilateurs) tu peux la passer sans pointeur à part si tu veux en modifier la valeur et que ca soit repercute dans la fonction appelante.
Un programme qui passe une structure sans le faire par pointeur n'a rien compris au fonctionnement du C. C'est possible en effet mais déconseillé d'un point de vue performances et en plus cela est dangereux pour un débutant.Envoyé par coca25
La structure sera recopiée lors du passage de paramètre mais d'une facon superficielle. Cela provoque souvent des erreurs de codage parce que le programmeur suppose qu'il a affaire avec une copie compléte.
On passe par pointeur pour éviter cette copie et en même temps cette confusion.
Enfin, si on ne veut pas pouvoir modifier la structure par crainte d'effets de bord, on utilise le mot clé const.
Jc
Ah ok merci
Je vais essayer ça, je vous tient au courant.
Salut,
Les problèmes que tu peux rencontrer en passant une structure à une fonction par valeur sont de deux ordres:
- Si la taille de la structure est importance, le processus de copie peut être lourd du point de vue de la performance.
- Si la structure en question contient elle-même des membres pointeurs, la valeur de ces pointeurs sera dupliquée comme la valeur de tout autre membre de la structure. En revanche, les objets pointés par ces membres pointeurs ne seront eux pas dupliqués.
Exemple cas n°1:
Soit MaStructure une structure contenant deux valiables de type tableau-de-int
La taille d'un objet de type struct MaStructure est de 4*2000 = 8000 octets en supposant un machine où un int est codé sur 4 octets. Ainsi, lorsque tu passe cette structure par valeur à une fonction, ton programme doit copier 8kB sur la pile. Dans le cas d'un passage par pointeur:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 struct MaStructure { int tab1_[1000]; int tab_2[1000]; };
Dans ce cas, seule la valeur d'un pointeur (i.e. 4 octets sur ma machine) sera copiée, ce qui représente un gain en performance important par rapport à la copie de toute la structure.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 void MaStructure_init(struct MaStructure *st) { /* ... */ } int main(void) { struct MaStructure obj1; MaStructure_init(&obj1); return 0; }
Exemple cas n°2:
Soit une structure contenant un pointeurs sur le premier élément d'un tableau.
Ici la taille d'un objet comme obj2 de type MaStructure est de 8 octets sur ma machine où les pointeurs sont codés sur 32 bits. En passant cette structure par valeur à une fonction, seuls 8 octets seront copiés. Les tableaux vers lesquels pointent p_tab_1 et p_tab_2 ne seront eux pas dupliqués. Cela peut causer quelques soucis:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <stdlib.h> #include <stdio.h> struct MaStructure { int *p_tab_1; int *p_tab_2; }; int main(void) { int i; struct MaStructure obj2; const int TAILLE_TAB = 1000; obj2.p_tab_1 = malloc(TAILLE_TAB * sizeof *(obj2.p_tab_1)); obj2.p_tab_2 = malloc(TAILLE_TAB * sizeof *(obj2.p_tab_2)); if (obj2.p_tab_1 == NULL || obj2.p_tab_2 == NULL) { fprintf(stderr, "Allocation of p_tab_1 or p_tab_2 failed!\n"); exit(EXIT_FAILURE); } /* Initialisation des tableaux contenus dans obj2*/ for (i = 0; i < TAILLE_TAB; ++i) { obj2.p_tab_1[i] = 0; obj2.p_tab_2[i] = 0; } /* ...*/ return EXIT_FAILURE }
En passant notre structure par pointeur, on a au moins pas de surprise:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 #include <stdlib.h> #include <stdio.h> struct MaStructure { int *p_tab_1; int *p_tab_2; }; /* MAUVAISE PRATIQUE: ici je passe ma structure par valeur. Une copie de la structure est passée à la fonction, mais les tableaux associés aux membres p_tab_1 et p_tab_2 ne sont eux pas dupliqués*/ void fonction(struct MaStructure st) { /* Je pense que ma structure est passée par valeur, je modifie une valeur dans le tableau p_tab_1*/ st.p_tab_1[0] = 1977; } int main(void) { int i; struct MaStructure obj2; const int TAILLE_TAB = 1000; obj2.p_tab_1 = malloc(TAILLE_TAB * sizeof *(obj2.p_tab_1)); obj2.p_tab_2 = malloc(TAILLE_TAB * sizeof *(obj2.p_tab_2)); if (obj2.p_tab_1 == NULL || obj2.p_tab_2 == NULL) { fprintf(stderr, "Allocation of p_tab_1 or p_tab_2 failed!\n"); exit(EXIT_FAILURE); } /* Initialisation des tableaux contenus dans obj2*/ for (i = 0; i < TAILLE_TAB; ++i) { obj2.p_tab_1[i] = 0; obj2.p_tab_2[i] = 0; } fonction(obj2); printf("La valeur de obj2.p_tab_1[0] est %d!\n", obj2.p_tab_1[0]); /* Aïe, fonction() a modifié les valeurs contenues dans le tableau p_tab_1.*/ return EXIT_SUCCESS; }
Pour conclure, c'est un bonne pratique de toujours passer une structure à une fonction à l'aide de pointeurs.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 /* Ici je sais qu'en passant ma structure par référence, j'ai la possibilité de modifier son contenu. Ni la structure, ni les tableaux associés aux pointeurs p_tab_1 et p_tab_2 ne sont dupliqués*/ void fonction(struct MaStructure *st) { st->p_tab_1[0] = 1977; }
Thierry
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow
FAQ-Python FAQ-C FAQ-C++
+
Contrairement aux tableaux, on peut techniquement passer la valeur de la structure, mais c'est une perte de temps et d'espace mémoire. Il est préférable de passer l'adresse selon le schéma générique bien connu suivant:Envoyé par god_enel
avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 T a; f(&a)
Qui permet un accès à la structure en lecture et en écriture.
Code : Sélectionner tout - Visualiser dans une fenêtre à part void f (T *p);
Nota : dans la fonction, on utilise la notation -> pour atteindre les éléments :
Si on désire un accès en lecture seule, on ajoute le qualificateur const :
Code : Sélectionner tout - Visualiser dans une fenêtre à part p->elem = 123;
Code : Sélectionner tout - Visualiser dans une fenêtre à part void f (T const *p);
Merci pour votre aide je vais essayer ainsi.
Comme je ne suis pas chez moi je vous tiens au courant ce soir ou au plus tard demain.
Merci encore.
Partager