Les listes et les structures
Résolu
safasahnoun
-
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6205 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour,
j'ai constuit une structure et j'aime bien l'afficher mais cela ne marche pas ! lorsque je compile ca donne 0 faute mais rien n'est affiché !!! voila mon code:
typedef struct dresseur dresseur;
struct dresseur { // defini la structure dresseur
char* nom;
//Je sais que ça sert a rein d'affecter un seul element pour une structure mais je veus just savoir ou se trouve la faute
};
dresseur new_dresseur (char* nom,) { // creer nouveau dresseur
dresseur *d;
d=malloc(sizeof(struct dresseur));
d->nom = nom;
return *d;
}
void get_dresseur ( dresseur nom_dresseur ) {
printf ("Voici vos pokémons %s : ", nom_dresseur.nom);
}
dans le main :
dresseur d;
d=new_dresseur("aze");
get_dresseur(d);
j'ai constuit une structure et j'aime bien l'afficher mais cela ne marche pas ! lorsque je compile ca donne 0 faute mais rien n'est affiché !!! voila mon code:
typedef struct dresseur dresseur;
struct dresseur { // defini la structure dresseur
char* nom;
//Je sais que ça sert a rein d'affecter un seul element pour une structure mais je veus just savoir ou se trouve la faute
};
dresseur new_dresseur (char* nom,) { // creer nouveau dresseur
dresseur *d;
d=malloc(sizeof(struct dresseur));
d->nom = nom;
return *d;
}
void get_dresseur ( dresseur nom_dresseur ) {
printf ("Voici vos pokémons %s : ", nom_dresseur.nom);
}
dans le main :
dresseur d;
d=new_dresseur("aze");
get_dresseur(d);
A voir également:
- Les listes et les structures
- Listes déroulantes excel - Guide
- Lister les disques cmd - Guide
- Listes déroulantes en cascade excel - Guide
- CMD - Lister les disques ✓ - Forum Windows
- Sql lister les tables ✓ - Forum Programmation
4 réponses
Salut.
déjà, je mettrais le typedef après la définition de la structure.
Je ne comprend pas l'intéret de la fonction new_dresseur, tu as fait du Java avant ?
d->nom = nom;
cette façon de faire est dangereuse, car tu lies un objet à une variable qui peut changer.
Je ne vois pas d'erreur, mais ta façon de coder est très tordu.
déjà, je mettrais le typedef après la définition de la structure.
Je ne comprend pas l'intéret de la fonction new_dresseur, tu as fait du Java avant ?
d->nom = nom;
cette façon de faire est dangereuse, car tu lies un objet à une variable qui peut changer.
Je ne vois pas d'erreur, mais ta façon de coder est très tordu.
Salut safasahnoun,
Sur la base de ton code posté dans ta question initiale, je pense que le problème vient du fait que tu alloues dans new_dresseur un espace mémoire pour la structure, mais qu'à l'intérieur de la structure tu n'alloues pas un espace pour stocker le "nom" (juste un espace pour le pointeur, et que tu te contentes d'écraser le pointeur de d->nom avec celui de nom, qui est le paramètre passé à ta fonction).
Je pense donc que tu pourrais faire quelque chose comme cela :
Dal
Sur la base de ton code posté dans ta question initiale, je pense que le problème vient du fait que tu alloues dans new_dresseur un espace mémoire pour la structure, mais qu'à l'intérieur de la structure tu n'alloues pas un espace pour stocker le "nom" (juste un espace pour le pointeur, et que tu te contentes d'écraser le pointeur de d->nom avec celui de nom, qui est le paramètre passé à ta fonction).
Je pense donc que tu pourrais faire quelque chose comme cela :
dresseur new_dresseur(char* nom) { /* creer nouveau dresseur */ dresseur *d; d = malloc(sizeof(struct dresseur)); if (d == NULL ) { printf("Erreur : impossible d'allouer nouveau dresseur\n"); exit(EXIT_FAILURE); } /* allouer l'espace nécessaire au stockage du nom */ d->nom = malloc(strlen(nom)); if (d->nom == NULL ) { printf("Erreur : impossible d'allouer dresseur->nom\n"); exit(EXIT_FAILURE); } /* copier nom dans cet espace */ strcpy(d->nom, nom); return *d; }
Dal
Note que je n'ai pas regardé le reste de ton code dans https://forums.commentcamarche.net/forum/affich-26471633-les-listes-et-les-structures#6
C'est plus propre, mais ce n'est pas pour ça. Son code fonctionne bien chez moi.
Le problème de ton code, c'est que tu crée avec malloc un espace mémoire qui ne sera jamais libéré, car inaccessible.
Soit tu fais un vrai new et tu retournes un pointeur, soit tu fais un passage par valeur en retour grace à un objet temporaire.
Pointé sur un "const char*" comme safasahnoun fait ne pose pas de problème car cette chaine est constante, statique. Du coup, pas besoin de malloc pour réserver de l'espace mémoire. Cela dit, ce n'est pas une bonne façon de faire, mais elle ne pose pas de problème.
Le problème de ton code, c'est que tu crée avec malloc un espace mémoire qui ne sera jamais libéré, car inaccessible.
Soit tu fais un vrai new et tu retournes un pointeur, soit tu fais un passage par valeur en retour grace à un objet temporaire.
Pointé sur un "const char*" comme safasahnoun fait ne pose pas de problème car cette chaine est constante, statique. Du coup, pas besoin de malloc pour réserver de l'espace mémoire. Cela dit, ce n'est pas une bonne façon de faire, mais elle ne pose pas de problème.
S'il a le dresseur retourné par la fonction (d), il peut déterminer le pointeur vers le dresseur (&d), et il peut libérer dresseur->nom, et dresseur lui même. C'est peu orthodoxe, mais pourquoi pas.
Cela dit, comme tu le dis justement, s'il fait "dresseur d;" dans son main, il a déjà alloué cet espace, et le malloc d'allocation d'un nouveau dresseur est inutile dans la fonction, et ne fait qu'écraser le pointeur vers l'espace initial. Donc, de toutes façons, il y a un problème.
En revanche le 2ème malloc dans new_dresseur, lui, reste nécessaire me semble-t-il pour allouer l'espace nécessaire à la chaîne nom, car il n'est pas alloué du fait de la définition de la structure.
Il faudra, bien sûr, qu'il gère sa libération.
Dal
Cela dit, comme tu le dis justement, s'il fait "dresseur d;" dans son main, il a déjà alloué cet espace, et le malloc d'allocation d'un nouveau dresseur est inutile dans la fonction, et ne fait qu'écraser le pointeur vers l'espace initial. Donc, de toutes façons, il y a un problème.
En revanche le 2ème malloc dans new_dresseur, lui, reste nécessaire me semble-t-il pour allouer l'espace nécessaire à la chaîne nom, car il n'est pas alloué du fait de la définition de la structure.
Il faudra, bien sûr, qu'il gère sa libération.
Dal
et ne fait qu'écraser le pointeur vers l'espace initial. faux, le = copi les valeurs de l'un à l'autre, le pointeur est bien perdu.
le 2ème malloc dans new_dresseur, lui, reste nécessaire Non plus, car tu le fait pointé sur une chaine const char qui est garantie imuable. Il ne copie pas la chaine, il pointe dessus, donc pas de malloc nécessaire. Mais il ne faut pas faire comme ça.
le 2ème malloc dans new_dresseur, lui, reste nécessaire Non plus, car tu le fait pointé sur une chaine const char qui est garantie imuable. Il ne copie pas la chaine, il pointe dessus, donc pas de malloc nécessaire. Mais il ne faut pas faire comme ça.
C'est n'importe quoi ton truc. Les malloc ne servent à rie tes variable étant déclarées dés le début.
Pour copier les chaines de caractère on utilise strcpy(), pas =, sinon, gare aux erreurs inatendus. Tu écris ton programme comme dans un langage objet type Java ou C++, or c'est du C, il faut raisonner autrement. écrit plutôt :
new_pok(&pokemon1_1,"Dracaufeu", 650, pv1_1, attaques_1_1 );
écrit un code propre, ça évitera les erreurs.
Pour copier les chaines de caractère on utilise strcpy(), pas =, sinon, gare aux erreurs inatendus. Tu écris ton programme comme dans un langage objet type Java ou C++, or c'est du C, il faut raisonner autrement. écrit plutôt :
new_pok(&pokemon1_1,"Dracaufeu", 650, pv1_1, attaques_1_1 );
écrit un code propre, ça évitera les erreurs.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*ATTAQUES:
1_structure de l'attaque :*/
typedef struct Attaque{
char* Nom;
int Force;
float Prob;
}Attaque;
//2_La création:
Attaque new_attack(char* Nom ,int Force ,float Prob){
Attaque* a;
a=malloc(sizeof(Attaque));
a->Nom = Nom;
a->Force = Force;
a->Prob = Prob ;
return (*a);
}
//3_Affichage
void get_attack(Attaque a){
printf("[%s,%d,%f]\n",a.Nom,a.Force,a.Prob);
}
//POKEMONS:
//1_structure :
typedef struct Pokemon {
char* Nom;
int HPMAX;
int HP;
Attaque Attaques[4];
}Pokemon;
//2_creation du pokemon
Pokemon new_pok(char* Nom, int HPMAX, int HP, Attaque Attaques[4]){
Pokemon *p;
p=malloc(sizeof(struct Pokemon));
p->Nom = Nom;
p->HPMAX= HPMAX;
p->HP = HP;
p->Attaques[0] = Attaques[0];
p->Attaques[1] = Attaques[1];
p->Attaques[2] = Attaques[2];
p->Attaques[3] = Attaques[3];
return *p ;
}
//POKEMON_LIST
//structure
typedef Pokemon p;
typedef struct maillon *Pokemon_list;
struct maillon {
p donnee;
Pokemon_list suivant;
};
Pokemon_list add(Pokemon_list liste, Pokemon p)
{Pokemon_list nouvelliste = malloc(sizeof(Pokemon_list));
nouvelliste->donnee = p;
nouvelliste->suivant = liste;
return nouvelliste;
}
//affichage
void get_pokemons_list(Pokemon_list a){
if (a== NULL) {printf ("liste vide");}
printf("[");
while (a->suivant != NULL)
{printf ("%s,",a->donnee.Nom);
a=a->suivant;}
printf("%s]",a->donnee.Nom);}
//DRESSEUR
//la structure dresseur
typedef struct dresseur dresseur;
struct dresseur { // defini la structure dresseur
char* nom;
Pokemon_list pokemon;
};
dresseur new_dresseur (char* nom, Pokemon_list Liste) { // creer nouveau dresseur
dresseur *d;
d=malloc(sizeof(struct dresseur));
d->nom = nom;
d->pokemon = Liste;
return *d;
}
void get_dresseur ( dresseur nom_dresseur ) {
printf ("Voici vos pokémons %s : ", nom_dresseur.nom);
}
int main(){
//création des attaques
//les attaque du pokemon 1 de dresseur 1
Attaque attaque_1_1_1 ,attaque_2_1_1 ,attaque_3_1_1 ,attaque_4_1_1 ;
//les attaque du pokemon 2 de dresseur 1
Attaque attaque_1_2_1 ,attaque_2_2_1 ,attaque_3_2_1 ,attaque_4_2_1 ;
//les attaque du pokemon 3 de dresseur 1
Attaque attaque_1_3_1 ,attaque_2_3_1 ,attaque_3_3_1 ,attaque_4_3_1 ;
//les attaque du pokemon 4 de dresseur 1
Attaque attaque_1_4_1 ,attaque_2_4_1 ,attaque_3_4_1 ,attaque_4_4_1 ;
//les attaque du pokemon 1 de dresseur 2
Attaque attaque_1_1_2 ,attaque_2_1_2 ,attaque_3_1_2 ,attaque_4_1_2 ;
//les attaque du pokemon 2 de dresseur 2
Attaque attaque_1_2_2 ,attaque_2_2_2 ,attaque_3_2_2 ,attaque_4_2_2 ;
//les attaque du pokemon 3 de dresseur 2
Attaque attaque_1_3_2 ,attaque_2_3_2 ,attaque_3_3_2 ,attaque_4_3_2 ;
//les attaque du pokemon 4 de dresseur 2
Attaque attaque_1_4_2 ,attaque_2_4_2 ,attaque_3_4_2 ,attaque_4_4_2 ;
//le dresseur 1
//pokemon 1
attaque_1_1_1 = new_attack ("Abime" , 55, 0.95);
attaque_2_1_1 = new_attack ("Balayage" , 105, 0.8);
attaque_3_1_1 = new_attack ("Cascade" , 150, 0.5);
attaque_4_1_1 = new_attack ("Eclair" , 40, 0.25);
// pokemon 2
attaque_1_2_1 = new_attack ("Poinglace" , 120, 0.7);
attaque_2_2_1 = new_attack ("Vol" , 50, 0.3);
attaque_3_2_1 = new_attack ("Souplesse" , 250, 0.1);
attaque_4_2_1 = new_attack ("Furie" , 15, 1.0);
// pokemon 3
attaque_1_3_1 = new_attack ("Plaquage" , 60, 0.25);
attaque_2_3_1 = new_attack ("Ligotage" , 90, 0.8);
attaque_3_3_1 = new_attack ("Mania", 65, 0.65);
attaque_4_3_1 = new_attack ("Damocles", 40, 0.15);
// pokemon 4 du dresseur
attaque_1_4_1 = new_attack ("Rugissement", 77, 0.65);
attaque_2_4_1 = new_attack ("Hurlement" , 150, 0.84);
attaque_3_4_1 = new_attack ("Ultrason" , 150, 0.5);
attaque_4_4_1 = new_attack ("Sonicboom" , 40, 0.45);
// Le dresseur 2
//pokemon 1
attaque_1_1_2 = new_attack ("Flammèche" , 78, 0.86);
attaque_2_1_2 = new_attack ("Hydrocanon" , 124, 0.28);
attaque_3_1_2 = new_attack ("Surf" , 89, 0.53);
attaque_4_1_2 = new_attack ("Ultralaser" , 28, 0.97);
// pokemon 2
attaque_1_2_2 = new_attack ("Picpic" , 86, 0.38);
attaque_2_2_2 = new_attack ("Sacrifice" , 42, 0.65);
attaque_3_2_2 = new_attack ("Riposte", 83, 0.5);
attaque_4_2_2 = new_attack ("Hypnose" , 17, 1);
// pokemon 3
attaque_1_3_2 = new_attack ("Reflet", 56, 0.95);
attaque_2_3_2 = new_attack ("Toxik" , 43, 0.8);
attaque_3_3_2 = new_attack ("Frustration" , 156, 0.4);
attaque_4_3_2 = new_attack ("Aurore" , 132, 0.25);
// pokemon 4
attaque_1_4_2 = new_attack ("Ouragan" , 115, 0.46);
attaque_2_4_2 = new_attack ("Teleport" , 69, 0.26);
attaque_3_4_2 = new_attack ("Avale" , 76, 0.55);
attaque_4_4_2 = new_attack ("Tranche" , 56, 0.97);
//declarations pour pokemons
//structures d'attaques
Attaque attaques_1_1[]= { attaque_1_1_1, attaque_2_1_1, attaque_3_1_1, attaque_4_1_1 };
Attaque attaques_2_1[]= { attaque_1_2_1, attaque_2_2_1, attaque_3_2_1, attaque_4_2_1 };
Attaque attaques_3_1[]= { attaque_1_3_1, attaque_2_3_1, attaque_3_3_1, attaque_4_3_1 };
Attaque attaques_4_1[]= { attaque_1_4_1, attaque_2_4_1, attaque_3_4_1, attaque_4_4_1 };
Attaque attaques_1_2[]= { attaque_1_1_2, attaque_2_1_2, attaque_3_1_2, attaque_4_1_2 };
Attaque attaques_2_2[]= { attaque_1_2_2, attaque_2_2_2, attaque_3_2_2, attaque_4_2_2 };
Attaque attaques_3_2[]= { attaque_1_3_2, attaque_2_3_2, attaque_3_3_2, attaque_4_3_2 };
Attaque attaques_4_2[]= { attaque_1_4_2, attaque_2_4_2, attaque_3_4_2, attaque_4_4_2 };
// les pokemons du dresseur 1
Pokemon pokemon1_1 ,pokemon1_2 ,pokemon1_3 ,pokemon1_4 ;
// les pokemons du dresseur 2
Pokemon pokemon2_1 ,pokemon2_2 ,pokemon2_3 ,pokemon2_4 ;
// creation des pokemons
int pv1_1=650,pv2_1=450, pv3_1=200, pv4_1=770, pv1_2=320, pv2_2=270,pv3_2=865,pv4_2=500;
pokemon1_1 = new_pok("Dracaufeu", 650, pv1_1, attaques_1_1 );
pokemon1_2 = new_pok("Raichu", 450, pv2_1, attaques_2_1 );
pokemon1_3 = new_pok("Taupiqueur", 200, pv3_1, attaques_3_1 );
pokemon1_4 = new_pok("Otaria", 770, pv4_1, attaques_4_1 );
pokemon2_1 = new_pok("Poissirène", 320, pv1_2, attaques_1_2 );
pokemon2_2 = new_pok("Floravol", 270, pv2_2, attaques_2_2 );
pokemon2_3 = new_pok("pikachu", 865, pv3_2, attaques_3_2 );
pokemon2_4 = new_pok("Bulbizarre", 500, pv4_2, attaques_4_2 );
//les dressurs:
Pokemon_list liste1=NULL;
liste1=add(liste1,pokemon1_1);
liste1=add(liste1,pokemon1_2);
get_pokemons_list(liste1);
dresseur d;
d=new_dresseur("s",liste1);
get_dresseur(d);
return 0;
}