Pas grave tu ne sera pas pour cette fois.
Pas grave tu ne sera pas pour cette fois.
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
"error: 'Attrib_Liste_Sous_MENU' declared as function returning an array"
c'est exactement la meme erreur que j'ai eu en faisant
Code : Sélectionner tout - Visualiser dans une fenêtre à part char * Attrib_Liste_Sous_MENU (int cnt_pos_ss_menu, unsigned int direction)[4][21] )
Au temps pour moi, j avais pas vu la fin de la ligne
sans vouloir te vexer, tu sembles vouloir faire des choses d un certain niveau sans pour autant avoir une parfaite maitrise des bases. Pour avancer plus vite apres je te conseille de perdre un peu de tant maintenant a betonner les fondations ce ne sera pas une perte de temps loin de la.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 char ** Attrib_Liste_Sous_MENU (int cnt_pos_ss_menu, unsigned int direction)
bon courage
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
mais où est-ce je specifierai la taille et les dimensions du tableau? à l'intérieur de la fonction, en faisant par exp:
et à la fin un
Code : Sélectionner tout - Visualiser dans une fenêtre à part char *Tab[4][21];?
Code : Sélectionner tout - Visualiser dans une fenêtre à part return Tab;
ps: ça ne me vexe pas du tt, je voudrais juste te dire que la syntaxe avec les dimensions et la taille du tableau que j'ai écrite à la création de la fonction ben je l'ai lu sur un bouquin!! et puis des cours j'en ai eu et lus, mais la pratique c'est autre chose, c'est pr ça que je fais ce que je suis en train de faire en ce moment, et ça ne m'empêche pas de vouloir réaliser des choses compliquées..
un niveau de trop ca, char Tab[4][21]; [edit grosse connerie](donc sans l etoile) c'est pareil qu un char**[/edit]
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 char *Tab[4][21];
et pis si tu veux le retourner dans ta fonction, tu ne peux pas le declarer dans celle-ci, sa portee s arrete a la fonction, il sera detruit a la sortie de la methode. Si tu veux retourner ton tableau tu dois passer par l allocation dynamique.
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
oki merci
Pas de Wi-Fi à la maison : CPL
Certes,
mais pour commencer on va faire comme si, les subtilites memoires on verra plus tard
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
Pas de Wi-Fi à la maison : CPL
C est ma foi vrai.
Au temps pour moi, pourtant j etais sur que dans le K&R 1ere edition ils expliquaient que par exemple lors du passage en argument d un tableau on passait l adresse du premier element...
Va falloir que je regarde ca de plus pres
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
Oui. Quel rapport ?
http://emmanuel-delahaye.developpez.....htm#param_tab
Pas de Wi-Fi à la maison : CPL
Ben dans ce cas pourquoi un warning ?
Bon je sais que c est dredi, que la semaine a ete longue, mais y a un truc qui m echappe.
Globalement a 2/3 differences pres (si a est soit mon char*, soit mon tableau sizeof a, &a ... ne donne pas les meme chose et pour cause) leur utilisation est globalement identique (acces par index...).
Bon derriere l impementation bas niveau n a rien a voir, mais si on considere qu'a chaque passage d arguement mon tableau devient un pointeur sur le premier element je comprends pas d ou peux venir le comportement indefini, car pour moi ca ressemble a un truc prevu par les createurs du C...
Faudra que je regarde ca a tete reposee.
"vaste programme"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 . . .
Ok, ça peut se comprendre.sert à créer des noms (synonymes) pour les data types.
Code : Sélectionner tout - Visualiser dans une fenêtre à part typedef
par exemple. Tu donnes un autre nom aux types. Ca rend le code très lisible quand c'est bien implémenté.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 typedef char *String; typedef int Size; Size plouf = 0; String bonjour="hello";
Bon, alors maintenant une autre question, quelle est la différence entre:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #define Size int et typedef int Size;
Une fois que tu as répondu à ça, tu devrais être capable de comprendre ce que tu comprenais pas:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 typedef struct list { [...] } vs struct list{ }
Si tu veux approfondir ton C, je ne peux que te conseiller le Kernighan & Ritchie (K&R), comme quelqu'un l'a mentioné plus haut.
+
à chaque fois que le compilo rencontrera "Size" dans le programme, il l'interpretera comme un "int"
définit un "int" nommé Size. Mais n'est ce pas similaire au fait de créer une variable?
Sinon les réponses que j'ai déjà données précédemment sur les autres cas sont correctes?
Ça ne définit pas un int nommé Size, ça définit le type size comme représentant "int"
Si tu veux voir la différence entre #define et typedef, regarde pour les types pointeurs:
Ici, les deux lignes sont différentes. Avec un typedef, c'est le pointeur qui est constant. Avec un define, c'est l'objet pointé...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 typedef int * PTR1; #define PTR2 int * int unEntier; const PTR1 p1 = &unEntier; const PTR2 p2 = &unEntier;
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
ah ok je vois bien la différence là! merci
nikita_sophie, personnellement m'étant remis au C, 2 ans après mes derniers cours, et après avoir fait du C# et du VBS, j'ai également du mal à refaire certaine chose.
En fait le C est vraiment bas niveau, du coup pour moi la difficulté par rapport au C# est de devoir tout gérer.
Donc plusieurs fois je me suis retrouvé à faire de façon incorrecte certaine chose.
Mais ce qui me permet de m'en sortir c'est les cours que j'ai eu sur les pointeurs et l'utilisation de la mémoire en C. Ma compréhension de ce qu'est un pointeur me permet de comprendre pourquoi je fait mal les choses.
Bon j'ai certainement compris les pointeurs aussi parce que l'on m'a fait faire un peu d'assembleur à l'école.
Bref ce que je veux dire c'est que connaitre le fonctionnement des pointeurs au niveau mémoire, savoir comment elle est gérée, te permet de comprendre le C.
Hors il me semble que tu n'as pas ces notions, et je pense qu'il est indispensble que tu les acquierts avant de continuer.
Et peut être que l'exemple est bon pour comprendre dans la plus part des cas, mais dans le cas des pointeurs l'exemple ne t'aidera pas plus que cela.
Reprends tes cours, fait toi expliquer les choses, c'est la meilleur façon pour toi accélérer.
Pour les pointeurs, toujours avoir considérer que la mémoire est un tableau. Et qu'une case mémoire est composé d'une case du tableau, et d'un indice définissant son adresse mémoire, cela m'a aidé à comprendre les pointeurs.
Ainsi on peut dire qu'un int est une adresse mémoire associé à une case contenant la valeur du int.
On peut donc dire qu'un pointeur est une adresse memoire, et une case contenant ce qui fait le lien entre le pointeur et la variable.
Qu'y a t'il de mieux que de stocké l'adresse mémoire de la cible dans la case du pointeur pour faire ce lien ?
Donc en dérivant on peut considérer un tableau en C comme un ensemble de case mémoire liée les unes aux autres (imgine les toi accolés).
Pour pouvoir utiliser ce tableau localisé on ne sait pas où dans la mémoire, il nous faut un pointeur sur celui-ci. C'est le role du nom du tableau en C. Et il pointe spcéfiquement sur la première case du tableau.
Ensuite il suffit d'utiliser les index, le system saura retrouvé la case recherché (facile à imaginer si tu imagines les cases collées).
Donc au final la différence entre :
et :
Code : Sélectionner tout - Visualiser dans une fenêtre à part char *a;
C'est que dans le premier cas on a un pointeur qui n'a pas encore de lien vers une case ou un ensemble de case memoire, et dans le deuxième cas a est un pointeur vers un tableau de 5 éléments.
Code : Sélectionner tout - Visualiser dans une fenêtre à part char a[5];
Alors le :
n'est autre qu'un pointeur vers un pointeur. C'est ainsi que l'on peut définir des tableaux multidimensionnel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part char **a;
peut être considéré comme un pointeur sur un tableau de 5 pointeurs pointant eux même chacun sur un tableaux de 6 char, tu suis toujours
Code : Sélectionner tout - Visualiser dans une fenêtre à part char a[5][6]
Et qu'en est il des struct ? bah c'est globalement semblable à un tableau en un peu plus complexe, et pas forcément localisé dans la même zone mémoire.
Mais imagines les comme un ensemble de case memoires accoléls, elle même repéré grâce à un pointeur qui est le nom de la variable de type structure.
Seulement, à la différence d'un tableau une structure est plus particulière et on ne peut pas faire :
Non parce que une structure est comme un type (int, char, ...) mais n'en est pas un, et pour que le compilateur la connaisse il faut la définir pour qu'il la comprenne. Et l'on ne peut pas utiliser une définition directement. Il faut redéfinir une variable de type structure, et comme dire au compilo que c un type structure avec struct :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 struct mastructure{ int t; }; mastructure.t;
Et typedef qui permet de définir des types ne te permet en que de tout simplement définir pour les structures un nom pour ce type. Ainsi tu n'as plus besoin d'employer le mot struct.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 struct mastructure{ int t; }; struct mastructure var; var.t;
On peut ainsi définir les string en C de façon peut couteuse pour la mémoire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 typedef struct String{ char *valeur; int length; }string; char tab[8] = "bonjour"; string mastring; mastring.valeur = tab; mastring.length = 8; /* Une telle classe à un intéret par exemple si tu as un gros buffer contenant temporairement plein d'info et que tu veux avoir accés facilement à plein d'info sans recopié les données mémoires. Alors cette structure te permet de pointer sur le débuts de l'élément contenu dans le buffer, et la taille te permet de savoir où t'arrêter pour cette élément.*/
Bref pour finir, pour la mémoire regarde aussi cela :
http://fr.wikipedia.org/wiki/Allocation_de_m%C3%A9moire
Et regardes les liste chainées, cela utilise les notions de structure et de pointeurs.
Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.
je te remercie bcp ced600 pour ton initiative de me guider, preuve que ce forum est vraiment intéressant
j'avoue que lorsque j'ai eu des cours de C, je n'ai pas vraiment eu l'occasion de bien pratiquer, étant donné le systeme de mon école qui ne permet pas forcément de tt bien assimiler vu la multitude de disciplines et la rapidité de leurs enseignements..j'ai également fait de l'assembleur, mais crois moi je n'en ai rien retenu!! je ne blame personne, mais un jugement neutre affirmerait que le prof qui me l'a enseigné n'a pas su transmettre les bases nécessaires, et donc tte initiative d'auto travail reste difficile à entammer avec la multitude de cours comme j'ai cité précédemment..et franchement, c'est seulement mtn que je commence à prendre goût à programmer en C, et jme dis que ce que je fais mtn j'aurais très bien pu le faire même si je n'avais jamais entendu parler du C à l'école!!
Admettons. C'est une analogie acceptable.
Euh, un int, c'est un type. Tu veux dire une variable de type int ?Ainsi on peut dire qu'un int est une adresse mémoire associé à une case contenant la valeur du int.
Alors ca donne 'une variable est une adresse". Euh, non. Je ne peux pas laisser dire ça.
Si tu veux garder l'analogie avec le tableau, tu peux dire :
Une variable est un élément du tableau 'mémoire'. Son adresse est l'indice qui permet de le référencer.
Faut pas trop parler de type pour le moment...
Ca, c'est super abstrait... un lien ? Je ne vois pas bien de quoi tu parles. Il n'y a pas de bouts ficelles dans la mémoire. La réalité est beaucoup plus simple et directe :On peut donc dire qu'un pointeur est une adresse memoire, et une case contenant ce qui fait le lien entre le pointeur et la variable.
Un pointeur est une variable comme une autre. Elle est conçue pour contenir l'adresse d'une variable. Lorsqu'un pointeur contient une adresse valide (l'adresse d'une variable), on dit qu'il pointe vers cette variable.
Il est possible d'appliquer l'opérateur de déréférencement * au pointeur pour accéder à la valeur pointée.
Là, on peut donner des exemples concrets...
Je ne sais pas si un débutant peu répondre à cette question...Qu'y a t'il de mieux que de stocké l'adresse mémoire de la cible dans la case du pointeur pour faire ce lien ?
Liées ? Par quoi ? La mémoire est formée d'éléments consécutifs, oui, mais liées ? Je ne vois pas.Donc en dérivant on peut considérer un tableau en C comme un ensemble de case mémoire liée les unes aux autres (imagine les toi accolés).
C'est là que ça devient compliqué, parce que ce fameux pointeur ... n'existe pas ! Et pourtant, il a une adresse. Décrire la réalité d'un tableau en C n'est pas chose aisée.Pour pouvoir utiliser ce tableau localisé on ne sait pas où dans la mémoire, il nous faut un pointeur sur celui-ci. C'est le rôle du nom du tableau en C. Et il pointe spécifiquement sur la première case du tableau.
En fait le nom du tableau désigne bel et bien l'objet mémoire correspondant. C'est un objet modifiable mais pas directement. On ne peut en effet pas modifier la valeur du nom du tableau, car c'est une 'non-modfiable L-value'.
C'est bien un objet (il a une adresse), il fait donc partie des L-values, c'est à dire des entités pouvant être dans la partie gauche (Left) d'une expression d'affectation, mais on ne peut pas l'utiliser dans une telle expression. Par contre, ses éléments sont tout à fait modifiables en utilisant la notation [] et un indice valide.
Euh, non. Je ne peut pas laisser dire qu'un tableau est un pointeur. C'est faux.Donc au final la différence entre :
et :
Code : Sélectionner tout - Visualiser dans une fenêtre à part char *a;
C'est que dans le premier cas on a un pointeur qui n'a pas encore de lien vers une case ou un ensemble de case memoire, et dans le deuxième cas a est un pointeur vers un tableau de 5 éléments.
Code : Sélectionner tout - Visualiser dans une fenêtre à part char a[5];
Un tableau est un objet composé d'une séquence d'objets identiques consécutifs.
Et voila, je sens la gamelle arriver...Alors le :
n'est autre qu'un pointeur vers un pointeur. C'est ainsi que l'on peut définir des tableaux multidimensionnel.
Code : Sélectionner tout - Visualiser dans une fenêtre à part char **a;
Et voilà. Catastrophe. Faut pas raconter des bêtises pareilles, surtout à un débutant qui n'a pas les moyens de te répondre...peut être considéré comme un pointeur sur un tableau de 5 pointeurs pointant eux même chacun sur un tableaux de 6 char, tu suis toujours
Code : Sélectionner tout - Visualiser dans une fenêtre à part char a[5][6]
Un tableau multi-dimentionnel est avant tout un tableau c'est à dire une suite d'objets identiques consécutifs. Il n'y a aucun pointeurs là dedans, et ce n'est certainement pas avec un T**p qu'on va pouvoir gérer un tableau multi-dimentionnel.
Le mécanisme des dimensions multiples est juste une facilité apportée au programmeur pour qu'il considère, par exemple, qu'un tableau de 100 éléments est accessible comme une matrice de 10 x 10. Au lieu d'utiliser 1 indice et de faire des calculs (ce qui est tout à fait possible), on utilise 2 indices et le compilateur fait le calcul lui même.
Je te laisse faire tous les essais qui vérifient tout ça.
Encore une fois, tu te trompes.Et qu'en est il des struct ? bah c'est globalement semblable à un tableau en un peu plus complexe, et pas forcément localisé dans la même zone mémoire.
Dans une structure, les éléments sont consécutifs (donc 'forcément localisé dans la même zone mémoire'). Par contre, comme la taille des éléments peut être différente (contrairement à un tableau), il peut y avoir des bytes de remplissage (padding bytes) pour respecter certaines contraintes d'alignement en fonction de l'architecture.
Le nom de la structure n'est pas plus un pointeur qu'un nom de tableau. C'est un simple identificateur. Par contre, c'est une modifiable L-value. En effet on peut directement affecter une structure dans une autre (du même type) avec =, ce qu'on ne sait pas faire avec un tableau.Mais imagines les comme un ensemble de case memoires accoléls, elle même repéré grâce à un pointeur qui est le nom de la variable de type structure.
(je suppose que le . avant le T est une faute de frappe...)Seulement, à la différence d'un tableau une structure est plus particulière et on ne peut pas faire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 struct mastructure{ int t; }; mastructure.t;
Parce que la syntaxe du C ne l'autorise pas. Par contre, on peut faire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 /* definition d'une structure */ struct mastructure{ int t; }; /* instanciation d'une structure */ struct mastructure t;Eh bien non, ce n'était pas une faute de frappe. Tu utilises l'opérateur de désignation des éléments de structures (.) sans dire ce que c'est ? Pas cool ça...Non parce que une structure est comme un type (int, char, ...) mais n'en est pas un, et pour que le compilateur la connaisse il faut la définir pour qu'il la comprenne. Et l'on ne peut pas utiliser une définition directement. Il faut redéfinir une variable de type structure, et comme dire au compilo que c un type structure avec struct :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 struct mastructure{ int t; }; struct mastructure var; var.t;
(pas de 'classe' en C...) Oui, enfin, il faut être certain de la persistance de tab... Pas si simple tout ça... Et la longueur de "bonjour" c'est 7. 8, c'est sa taille...On peut ainsi définir les string en C de façon peut couteuse pour la mémoire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 typedef struct String{ char *valeur; int length; }string; char tab[8] = "bonjour"; string mastring; mastring.valeur = tab; mastring.length = 8; /* Une telle classe à un intéret par exemple si tu as un gros buffer contenant temporairement plein d'info et que tu veux avoir accés facilement à plein d'info sans recopié les données mémoires. Alors cette structure te permet de pointer sur le débuts de l'élément contenu dans le buffer, et la taille te permet de savoir où t'arrêter pour cette élément.*/
Si tu veux faire un String utile, il faut au minimum
- l'adresse du premier élément d'un tableau de char (ou NULL)
- un entier qui désigne la taille du tableau de char
- un entier qui désigne la longueur des données utiles du tableau (la position du 0 final).
ensuite, on peut appliquer la technique de l'ADT :
http://emmanuel-delahaye.developpez.com/tad.htm
enfin, on peut obtenir l'équivalent d'un String :
http://emmanuel-delahaye.developpez.com/clib.htm
Module FSTR
Et là, le débutant a fini d'être totalement embrouillé...Bref pour finir, pour la mémoire regarde aussi cela :
http://fr.wikipedia.org/wiki/Allocation_de_m%C3%A9moire
Et regardes les liste chainées, cela utilise les notions de structure et de pointeurs.
http://emmanuel-delahaye.developpez.....htm#pointeurs
Pas de Wi-Fi à la maison : CPL
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager