Loangage c urgent
zargoss
Messages postés
78
Statut
Membre
-
Mahmah Messages postés 497 Statut Membre -
Mahmah Messages postés 497 Statut Membre -
Bonjour,
lors qu'on veut réaliser un tableau de structure dynamique est ce qu'on est obligé de mettre t[i].nom ou t[i]->nom ,ou on a le choix?
et c quoi la différence entre passage par valeur et passage par adresse? et c'est quoi la différence entre un tableau dynamique et un tableau de pointeur?
merci en avance
lors qu'on veut réaliser un tableau de structure dynamique est ce qu'on est obligé de mettre t[i].nom ou t[i]->nom ,ou on a le choix?
et c quoi la différence entre passage par valeur et passage par adresse? et c'est quoi la différence entre un tableau dynamique et un tableau de pointeur?
merci en avance
6 réponses
Salut,
La notation fléchée sert à alléger la notation. Exemple :
Si tu as struct Personne *pers; Au lieu d'écrire (*pers).nom, tu pourras écrire pers->nom.
Donc, ça dépend de la déclaration de ton tableau.
Les valeurs sont stockées dans la mémoire. Lorsque tu passes des valeurs à une fonction, tu as le choix entre le passage par valeurs (tu envoies une copie de la valeur), et le passage par adresse (tu envoies l'adresse de la valeur).
Ainsi dans le cas du passage par valeurs, la modification de la valeur dans la fonction n'entrainera pas la modification dans la fonction appelante, tandis qu'avec le passage par adresse, la valeur sera réellement modifiée.
int tab[] est un tableau dynamique. C'est un tableau dont la dimension n'est pas fixée. Tu peux la changer.
int *tab[] est un exemple de tableau de pointeur. Tous les éléments du tableau sont des pointeurs.
La notation fléchée sert à alléger la notation. Exemple :
Si tu as struct Personne *pers; Au lieu d'écrire (*pers).nom, tu pourras écrire pers->nom.
Donc, ça dépend de la déclaration de ton tableau.
Les valeurs sont stockées dans la mémoire. Lorsque tu passes des valeurs à une fonction, tu as le choix entre le passage par valeurs (tu envoies une copie de la valeur), et le passage par adresse (tu envoies l'adresse de la valeur).
Ainsi dans le cas du passage par valeurs, la modification de la valeur dans la fonction n'entrainera pas la modification dans la fonction appelante, tandis qu'avec le passage par adresse, la valeur sera réellement modifiée.
int tab[] est un tableau dynamique. C'est un tableau dont la dimension n'est pas fixée. Tu peux la changer.
int *tab[] est un exemple de tableau de pointeur. Tous les éléments du tableau sont des pointeurs.
Bonjour zargoss, en fait quand tu utilise les structures, le . entre la variable representant la structure et le nom de la variable que tu veut manipuler c'est quand tu utilise directement une structure sans passer par un pointeur, et vice versa, je te donne un exemple:
int main ()
{
t_struct toto;
toto.var = 25;
return (0);
}
Dans cet exemple je declare une variable representant la structure ce qui explique pourquoi je mets un .
int main()
{
t_struct *toto;
toto->var = 25;
return (0);
}
Ici j'ai déclaré un pointeur vers cette structure ce qui explique que j'aie utilisé -> au lieu du .
Donc non c'est pas au choix c'est selon ce que tu déclares pointeur ou variable.....
Ensuite pour répondre a ta deuxieme question, quand tu déclares une variable, cette variable contiendra des données et sera située a une certaine adresse memoire, si dans une autre fonction tu déclares la meme variable (meme type et meme nom), elle n'aura pas la meme adresse mémoire d'où l'interet de passer une adresse en paramètre. Imagines que tu aies une structure et que tu veuilles faire une fonction pour remplir cette structure ton prog aura en gros cette gueule là:
void fill_struct(t_struct *toto)
{
toto->varx = contenu;
}
void main()
{
t_struct toto;
fill_struct(&toto);
}
En gros tu déclares un pointeur sur une structure dans fill_struct, et tu assignes a ce pointeur l'adresse de la structure qui t'interresse, comme ça tu pourras modifier les données de cette structure.
Donc ici un passage par valeur n'a ici aucun interet car l'adresse te permet de savoir où sont stockés les valeurs qui t'interressent.
Et pour finir, je suppose que par tableau dynamique tu entends liste chainée, bah en fait un tableau de pointeurs est comme son nom l'indique un tableau contenant des variables qui contiennent une adresse memoire, ou encore c'est un tableau a deux dimensions comme celui du main pour récuperer les arguments de la ligne de commande char **argv ici un tableau de pointeurs sur des chaines de caractères donc argv[1][0] désigne le premier caractère de la 2e chaine de caractère de ce tableau.
Un tableau de pointeur ne permet de stocker qu'un type de donnée, et il a une taille finie.
Une liste chainée n'a pas de taille determinée et permet de stocker plus d'un type de donnée, c'est une structure faisant reference a elle meme.
int main ()
{
t_struct toto;
toto.var = 25;
return (0);
}
Dans cet exemple je declare une variable representant la structure ce qui explique pourquoi je mets un .
int main()
{
t_struct *toto;
toto->var = 25;
return (0);
}
Ici j'ai déclaré un pointeur vers cette structure ce qui explique que j'aie utilisé -> au lieu du .
Donc non c'est pas au choix c'est selon ce que tu déclares pointeur ou variable.....
Ensuite pour répondre a ta deuxieme question, quand tu déclares une variable, cette variable contiendra des données et sera située a une certaine adresse memoire, si dans une autre fonction tu déclares la meme variable (meme type et meme nom), elle n'aura pas la meme adresse mémoire d'où l'interet de passer une adresse en paramètre. Imagines que tu aies une structure et que tu veuilles faire une fonction pour remplir cette structure ton prog aura en gros cette gueule là:
void fill_struct(t_struct *toto)
{
toto->varx = contenu;
}
void main()
{
t_struct toto;
fill_struct(&toto);
}
En gros tu déclares un pointeur sur une structure dans fill_struct, et tu assignes a ce pointeur l'adresse de la structure qui t'interresse, comme ça tu pourras modifier les données de cette structure.
Donc ici un passage par valeur n'a ici aucun interet car l'adresse te permet de savoir où sont stockés les valeurs qui t'interressent.
Et pour finir, je suppose que par tableau dynamique tu entends liste chainée, bah en fait un tableau de pointeurs est comme son nom l'indique un tableau contenant des variables qui contiennent une adresse memoire, ou encore c'est un tableau a deux dimensions comme celui du main pour récuperer les arguments de la ligne de commande char **argv ici un tableau de pointeurs sur des chaines de caractères donc argv[1][0] désigne le premier caractère de la 2e chaine de caractère de ce tableau.
Un tableau de pointeur ne permet de stocker qu'un type de donnée, et il a une taille finie.
Une liste chainée n'a pas de taille determinée et permet de stocker plus d'un type de donnée, c'est une structure faisant reference a elle meme.
Bonjour,
Les deux codes suivants sont équivalents:
La flèche est juste un raccourci.
M.
struct myStruct_t
{
int i;
};
struct myStruct_t *pMyVar;
Les deux codes suivants sont équivalents:
(*pMyStruct).i;
pMyStruct->i;
La flèche est juste un raccourci.
M.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
stp ya des perssonnes qui disent que c obligatoire et sa depend de la declaration et il ya des autres qui disent soit en utilisent *t[i].nom ou t[i]->nom et ils sont egaux
est ce qu'il ya un qui peu me dire le vrai de fau
est ce qu'il ya un qui peu me dire le vrai de fau
Le compilo peut te le dire.
Et l'extrait du code asm généré:
idem MAIS Attention, j'ai bien pris ici (*p).i et p->i
(*p).i et *p.i ne veulent pas dire la même chose: *p.i est équivalent à *(p.i) mais ici i n'est pas un pointeur donc c'est invalide.
Autrement dit, le . est prioritaire sur le *
M.
EDIT:
Dans ton exemple
*t[i].nom ou *(t[i].nom)
et
t[i]->nom ou (*t[i]).nom
ne sont pas équivalents.
le premier cas suppose un tableau de structures possédant une chaîne de caractères 'nom' (dont tu prends le premier caractère)
le deuxième cas suppose un tableau de pointeurs sur des structures possédant une chaîne de caractères 'nom' (dont tu récupères le pointeur)
struct A
{
int i;
};
int main(int argc, char* argv[])
{
A a = { 2 };
A *p = &a;
int i;
// p->i
i = p->i;
//(*p).i
i = (*p).i;
return 0;
}
Et l'extrait du code asm généré:
; 17 : // p->i ; 18 : i = p->i; mov eax, DWORD PTR _p$[ebp] mov ecx, DWORD PTR [eax] mov DWORD PTR _i$[ebp], ecx ; 19 : ; 20 : //(*p).i ; 21 : i = (*p).i; mov eax, DWORD PTR _p$[ebp] mov ecx, DWORD PTR [eax] mov DWORD PTR _i$[ebp], ecx
idem MAIS Attention, j'ai bien pris ici (*p).i et p->i
(*p).i et *p.i ne veulent pas dire la même chose: *p.i est équivalent à *(p.i) mais ici i n'est pas un pointeur donc c'est invalide.
Autrement dit, le . est prioritaire sur le *
M.
EDIT:
Dans ton exemple
*t[i].nom ou *(t[i].nom)
et
t[i]->nom ou (*t[i]).nom
ne sont pas équivalents.
le premier cas suppose un tableau de structures possédant une chaîne de caractères 'nom' (dont tu prends le premier caractère)
le deuxième cas suppose un tableau de pointeurs sur des structures possédant une chaîne de caractères 'nom' (dont tu récupères le pointeur)