× Aidez la recherche contre le COVID-19 avec votre ordi ! Rejoignez l'équipe PC Astuces Folding@home
 > Tous les forums > Forum Autres langages
 Créer un tableau de structure
Ajouter un message à la discussion
Page : [1] 
Page 1 sur 1
don diego
  Posté le 08/12/2006 @ 18:38 
Aller en bas de la page 
Petit astucien

Bonjour,

je souhaite créer un tableau de structure.

Pour commencer, j'ai une structure :

struct trans {
char lettre; // Lettre de transition
int etat_arr; // Etat d arrivee
struct trans* suivant;
};

et j'ai un tableau :

struct trans* matrice = NULL; // Un tableau de structure

et le main :

int main (int argc, char* argv[]) {

matrice = (struct trans*) realloc(matrice, nb_etat*sizeof(struct trans)); // Allocation

// Je teste si la liste est NULL : Je crée donc un premier élément

if (matrice[0] == NULL) {

......

} else {

.......

}

}

Le problème, c'est que le test dans le IF ne marche pas. Le compilateur n'accepte pas.

matrice[0] me renvoie bien le début de la liste chainée?

Publicité
breizhbugs
 Posté le 08/12/2006 à 18:54 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Astucien

struct trans* matrice = NULL ne declare pas un tableau mais juste un lien vers 1 seule structure il me semble.

essai

struct trans matrice[5];

Et je suis pas sur que realloc marche s'il n'y a pas eu un alloc avant...

AlexPrince
 Posté le 09/12/2006 à 06:09 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien

J'appuie Mr. ^ pour ce qui est de realloc. Pour l'erreur, il s'agit simplement du fait que tu essaies de comparer un objet 'trans' et non un pointeur vers un objet 'trans'. Étant donné que tu n'as pas d'opérateur == défini pour comparer un 'trans' avec un ((void*)0), qui est en fait la valeur de la macro 'NULL'. Tu as deux options: soit tu gardes la même syntaxe (comme s'il s'agissait d'un tableau) et que tu spécifies au compilateur l'adresse de la variable. Donc pour le second objet tu ferais &matrice[1] == NULL. Sinon, tu peux utiliser la notation que je préfère, en aditionnant l'index tout simplement au pointeur comme ceci "(matrice + 1) == NULL". Le compilateur convertit le "+ 1" en utilisant la taille de la structure 'trans' et il bouge le pointeur de la distance appropriée. Toutefois, je crois que cette manière peut créer des bugs si le bloc de mémoire alloué pour le tableau n'est pas contigu. Dans ce cas tu aurais donc un accès de violation... Je te suggère donc d'utiliser la première méthode qui te sera probablement plus instinctive =D J'aime faire compliqué ;-)

PS: À ta place, je n'utiliserais pas "nb_etat * sizeof(struct trans)" car si nb_etat vaut 0 (par erreur, ou si nb_etat dépend d'une valeur entrée par l'utilisateur) alors je crois que le comportement du programme devient indéfini. Je te suggère donc quelque chose du genre

int size = nb_etat * sizeof(struct trans);

size = (size <= 0) ? 1 : size;

Dernière astuce: je te conseille d'utiliser la forme suivante pour t'éviter d'avoir à tapper "struct trans" à chaque fois:

typedef struct {

// ...

} trans;

Avec cette astuce bien connue des programmeurs C, tu peux t'éviter l'ennuyant "struct trans" et ne tapper que "trans".



Modifié par AlexPrince le 09/12/2006 06:10
don diego
 Posté le 10/12/2006 à 11:57 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien

Merci pour vos réponses.

Mais je m'aperçois que j'ai un autre problème.

Je n'arrive pas à créer une liste chainée avec la structure que je vous ai donnée dans mon premier message.

Voici mon code (non complet) pour ajouter un élément à la liste :

void ajouter(trans* liste, char etat_arr,char lettre) {
trans nouvelle_transition;

// Allocation et initialisation de la nouvelle transition
nouvelle_transition.lettre = lettre;
nouvelle_transition.etat_arr = etat_arr;
nouvelle_transition.suivant = NULL;

if (liste == NULL) {
printf("matrice vide\n");
*liste = nouvelle_transition;
} else {

....

}

}

int main(int argc, char* argv) {
trans* maListe = NULL;
ajouter(maListe, 1, 'z');

}

Le problème c'est que ma liste est vide après l'ajout. Pourtant je pense bien faire un passage par adresse.

NB : *liste = nouvelle_transition plante à l'exécution. Pourtant *liste me permet bien d'accéder au contenu de la liste ?

Cette instruction devrait donc marcher?????

breizhbugs
 Posté le 11/12/2006 à 14:50 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Astucien
don diego a écrit :

void ajouter(trans* liste, char etat_arr,char lettre) {
trans nouvelle_transition; // tu devrais plutot creer ta cellule de facon dynamique: trans * nt= alloc(...)

// Allocation et initialisation de la nouvelle transition
nouvelle_transition.lettre = lettre;
nouvelle_transition.etat_arr = etat_arr;
nouvelle_transition.suivant = NULL;

if (liste == NULL) {
printf("matrice vide\n");
*liste = nouvelle_transition; // liste=nt;
} else {

....

}

}

int main(int argc, char* argv) {
trans* maListe = NULL;
ajouter(maListe, 1, 'z');

}

Le problème c'est que ma liste est vide après l'ajout. Pourtant je pense bien faire un passage par adresse.

NB : *liste = nouvelle_transition plante à l'exécution. Pourtant *liste me permet bien d'accéder au contenu de la liste ?

Cette instruction devrait donc marcher????? ->non car *liste se refere au contenu or tu l'a initialisé a NULL, ce qui aurait ete correct c'est: liste = &nouvelle_transition.

Toutefois tu as declarer nouvelle_transition dans la fonction ajouter et la place memoire de nouvelle_transition est liberable a la fin de cette fonction, c'est pourqoi il est incorrect de faire pointer liste sur nouvelle_transition. Alors que nt est alloué via alloc dans un espace qui ne sera pas liberer a la fin de ajouter. N'oublie pas de faire une fonction qui fait un free() sur chaque cellule lorsque tu as besoin de detruire ta liste.

En fait tu devrais faire en sorte qu'on ne passe pas de liste vide a ajouter et creer une fonction pour la creation d'une liste!!!!

Alex me corrigera si je me trompe.



Modifié par breizhbugs le 11/12/2006 14:57
AlexPrince
 Posté le 11/12/2006 à 16:57 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien

En effet, il s'agit d'un bug d'accès non-autorisé à cause de mémoire non-allouée. Je te suggère le simple pseudo-code suivant:

Si liste == NULL, alloue de la mémoire pour liste, assigne la valeur 0 à liste->suivant et finalement assigne la valeur de nouvelle_transition à *liste. Pour ce faire, tu auras besoin d'avoir codé au préalable l'opérateur = pour deux objets trans.

Si liste != NULL, fais un pointeur vers liste, ensuite une boucle comme celle ci : while((ptr = ptr->suivant) != NULL) pour accéder au dernier élément de la liste, et ensuite assigne la valeur de nouvelle_transition à ce pointeur. La valeur changera automatiquement dans la liste, puisque tu auras utilisé un pointeur vers cette liste.

don diego
 Posté le 11/12/2006 à 17:56 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien

Je n'arrive toujours pas à modifier ma liste. A chaque fois que je sors de cette fonction, ma liste n'a pas changé.

Voici ce que j'ai fait :

void ajouter(trans* liste, int etat_arr,char lettre) {
trans* pCourant; // définition d'un pointeur courant
trans nouvelle_transition;

// Allocation et initialisation de la nouvelle transition
nouvelle_transition.lettre = lettre;
nouvelle_transition.etat_arr = etat_arr;
nouvelle_transition.suivant = NULL;

if (liste == NULL) {
printf("matrice vide\n");
liste = (trans*) malloc(sizeof(trans));
liste->suivant = 0;
*liste = nouvelle_transition;

} else {
pCourant = liste;
// parcours de la liste chaînée jusqu'au dernier noeud
while(pCourant != NULL) {
pCourant = pCourant->suivant;
}
// Attachement a la liste
pCourant->suivant = nouvelle_transition;
}
}

Ensuite dans le else :

pCourant = pCourant->suivant; // Warning : assignment from incompatible pointer type ???

pCourant->suivant = nouvelle_transiton; // incompatible type in assignment

Sinon, je ne comprend pas ce que tu veux dire par :

"tu auras besoin d'avoir codé au préalable l'opérateur = pour deux objets trans."?????

AlexPrince
 Posté le 11/12/2006 à 23:05 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien

[code]

struct trans {

...

trans(int e, char l) : etat_arr(e), lettre(l), suivant(0) { }

trans& operator = (const trans& t) {

lettre = t.lettre;

etat_arr = t.etat_arr;

return (*this);

}

};

void ajouter(trans* liste, int etat_arr,char lettre) {

trans nouvelle_transition(etat_arr, lettre);

trans* ptr = liste;

if(ptr != NULL)

while((ptr = ptr->suivant) != NULL);

ptr = (trans*) malloc(sizeof(trans));

*ptr = nouvelle_transition;

ptr->suivant = 0;

}

[/code]

Quelque chose du genre, je n'ai pas essayé de compiler le code, mais ça devrait ressembler à quelque chose comme ça.

don diego
 Posté le 24/12/2006 à 18:46 
Aller en bas de la page Revenir au message précédent Revenir en haut de la page
Petit astucien
Je ne comprends pas le code que tu as mis dans la structure.
Page : [1] 
Page 1 sur 1

Vous devez être connecté pour poster des messages. Cliquez ici pour vous identifier.

Vous n'avez pas de compte ? Créez-en un gratuitement !


Les bons plans du moment PC Astuces

Tous les Bons Plans
149,99 €Ecran 24 pouces ViewSonic VX2458-C-MHD (incurvé, FullHD, 144Hz, 1ms) à 149,99 €
Valable jusqu'au 18 Juillet

Darty fait une promotion sur l'écran 24 pouces ViewSonic VX2458-C-MHD qui passe à 149,99 €. On le trouve ailleurs à partir de 170 €. Cet écran dédié aux joueurs dispose d'une dalle incurvée FullHD 1 ms à 144 Hz, un filtre lumière bleue et de la technologie anti scintillement Flicker Free. Il est compatible FreeSync, GSync et a des entrées HDMI, DP et DVI. Il intègre des haut-parleurs. 


> Voir l'offre
27,95 €Casque audio bluetooth JBL Tune 500 BT à 27,95 €
Valable jusqu'au 18 Juillet

Amazon fait une vente flash sur le casque audio sans fil bluetooth JBL Tune 500 BT qui passe à 27,95 € livré gratuitement alors qu'on le trouve ailleurs à partir de 49,99 €. Ce casque sans fil bluetooth 4.1 offre une autonomie de 16h, permet de commander sur le casque les appels et la musique et est repliable à plat. Il est rechargeable avec un câble microUSB fourni. Notez qu'une charge rapide de 5 minutes vous procurera 1 heure de musique.


> Voir l'offre
144,80 €Mini PC Acute Angle AA-B4 (Celeron N3450, 8Go RAM, 64Go+SSD 128Go) à 144,80 € avec le code GBCNSJXPC
Valable jusqu'au 17 Juillet

Gearbest fait une promotion sur l'ordinateur Acute Angle AA - B4 qui passe à 144,80 € au lieu de 180 € grâce au code promo GBCNSJXPC. Ce mini PC au design atypique et au corps en bois, intègre un processeur Intel Celeron N3450 (4 coeurs de 1,1 à 2,2 GHz), 8 Go de RAM, un espace de stockage de 64 Go EMMC ainsi qu'un SSD de 128 Go. Il possède également le WiFi5, le Bluetooth 5.0, une prise Ethernet Gigabit, 3 ports USB 3.0, une sortie HDMI. L'ordinateur est livré avec une prise électrique européenne. Il est accompagné de Windows 10 Familial. Avec ce PC, vous pourrez réaliser sans soucis toutes vos tâches courantes : internet, bureautique, multimédia.

Ce marchand sérieux se trouvant en Chine, la livraison peut prendre une quinzaine de jours. Comptez une dizaine d'euros pour la livraison en France et l'assurance pour le transport. Vous pouvez payer par carte bancaire ou par Paypal (conseillé pour bénéficier de la garantie Paypal).


> Voir l'offre

Sujets relatifs
Rafraichir un tableau en java
Créer un fichier init.lua
commande créer la fonction effacer image en VB10
extraction de valeurs sur un tableau a deux entrees
dev-cpp créer librairie statique
créer une commande dans le menu clic droit
prog C faire choisir le nom du fichier à créer
symétrie d'un tableau 2D
Créer programme ou application pour tablette PC
Créer un labyrinthe en C
Plus de sujets relatifs à Créer un tableau de structure
 > Tous les forums > Forum Autres langages