Interrogations sur les structures et liste chainées
Le
jean mike
#define CDESIGN 5
#define CQTE 10
typedef struct art3
{
char Name[CDESIGN];
long qte ;
struct art3 *suiv ;
} listele ;
listele *deb, *bkup, *nouv, *a ; /* A */
if ((deb = malloc(listele) == NULL))
{
printf("Pas de memoire dispo.") ;
exit(EXIT_FAILURE) ;
}
i = 0 ;
nouv = bkup = deb ; /* B */
deb->suiv = NULL ; /* C */
do
{
printf("Enregistrement no. %d", i+1) ;
printf("Designation (5 caract. max., \"0\" pour quitter : ") ;
nbcar = ReadTxt(Bufftxt, CDESIGN, 1) ;
strncpy(nouv->Name, Buffer, nbcar+1) ;
if ((strcmp(nouv->Name, "0"))
{
printf("Quantite :") ;
nbcar = ReadTxt(Buffdigits, CQTE, 2) ;
nouv->qte = ReadDigit(Buffdigits) ;
if (strcmp(nouv->Name, deb->Name) < 0) /* D */
{
nouv->suiv = deb ;
deb = nouv ;
}
else /* si nouv->Name est alphabetiquement plus grand */
{
if (nouv != deb)
{
for (a = deb ; a->suiv != NULL && strcmp(a->suiv->Name, nouv-
>Name) < 0 ; a = a->suiv) /* E */
;
nouv->suiv = a->suiv ;
a->suiv = nouv ;
}
}
bkup = nouv ;
if ((nouv = malloc(sizeof(listele))) == NULL)
{
printf("Plus de memoire") ;
i++ ;
break ;
}
i++ ;
}
else
bkup = nouv ;
} while (strcmp(bkup->Name, "0")) ;
if (i > 0)
{
printf("Nbr d'enregistrements : %d", i) ;
printf("Afficher la liste ? (o/n)") ;
rep = getc(stdin) ;
if (rep == 'o')
{
HEADER(s)
for (a = deb, ; a != NULL ; a = a->suiv)
printf(" %-22s\t%ld", a->Name, a->qte) ;
}
for (a = deb ; a != NULL ; a = nouv)
{
nouv = a->suiv ;
free(a) ;
}
}
/* A */
listele *deb, *bkup, *nouv, *a ; /* A */
*deb, *bkup, *nouv, *a sont des pointeurs pour accueillir des données
de type listelepour linstant, ils ne pointent pas vers une adresse
ne mémoire, ils sont simplement déclarés pour recevoir des données =
de
type prédéfinies.
/* B */
nouv = bkup = deb ;
Ici nouv et bkup recoivent ladresse en mémoire de deb
/* C */
deb->suiv = NULL ;
deb->suiv recoit ladresse nulle
/* D */ si nouv est alphabetiquement plus petit que deb. Comment est-
ce que la comparaison peut se faire lors de la première saisie? Ce que
jai compris jusquà présent sur les pointeurs et variable non
initialisés cest quils peuvent contenir nimporte quoi. Et ici nu=
l
part deb a été initialisé, il a seulement reçu un espace mémoire =
à la
ligne A mais malloc ninitialise pas, ça serait plutôt calloc et
encore ce nest pas pour des caractèresalors, je me pose la
question avec quoi nouv est comparé?
/* E */ strcmp(a->suiv, nouv->name) < 0
Lauteur :
« Il faut effectuer la comparaison avec lelement suivant et non avec
lelement actuel, afin de vérifier avant quel element de la liste il
faut insérer le nouveau. Cela serait impossible si on comparaît nouv-
>name et a->name. En effet, on ne disposerait plus alors de ladresse
nécessaire du prédécesseur dans la liste. En procédant ainsi on ins=
ère
le nouvel élément avant le premier qui lui est alphabétiquement
supérieur ou égal. Pour cela on actualise de manière adéquate les
pointeurs nouv->suiv et a->suiv.»
Je ne suis pas sûre de comprendre : «on ne disposerait plus alors de
ladresse nécessaire du prédécesseur dans la liste»
#define CQTE 10
typedef struct art3
{
char Name[CDESIGN];
long qte ;
struct art3 *suiv ;
} listele ;
listele *deb, *bkup, *nouv, *a ; /* A */
if ((deb = malloc(listele) == NULL))
{
printf("Pas de memoire dispo.") ;
exit(EXIT_FAILURE) ;
}
i = 0 ;
nouv = bkup = deb ; /* B */
deb->suiv = NULL ; /* C */
do
{
printf("Enregistrement no. %d", i+1) ;
printf("Designation (5 caract. max., \"0\" pour quitter : ") ;
nbcar = ReadTxt(Bufftxt, CDESIGN, 1) ;
strncpy(nouv->Name, Buffer, nbcar+1) ;
if ((strcmp(nouv->Name, "0"))
{
printf("Quantite :") ;
nbcar = ReadTxt(Buffdigits, CQTE, 2) ;
nouv->qte = ReadDigit(Buffdigits) ;
if (strcmp(nouv->Name, deb->Name) < 0) /* D */
{
nouv->suiv = deb ;
deb = nouv ;
}
else /* si nouv->Name est alphabetiquement plus grand */
{
if (nouv != deb)
{
for (a = deb ; a->suiv != NULL && strcmp(a->suiv->Name, nouv-
>Name) < 0 ; a = a->suiv) /* E */
;
nouv->suiv = a->suiv ;
a->suiv = nouv ;
}
}
bkup = nouv ;
if ((nouv = malloc(sizeof(listele))) == NULL)
{
printf("Plus de memoire") ;
i++ ;
break ;
}
i++ ;
}
else
bkup = nouv ;
} while (strcmp(bkup->Name, "0")) ;
if (i > 0)
{
printf("Nbr d'enregistrements : %d", i) ;
printf("Afficher la liste ? (o/n)") ;
rep = getc(stdin) ;
if (rep == 'o')
{
HEADER(s)
for (a = deb, ; a != NULL ; a = a->suiv)
printf(" %-22s\t%ld", a->Name, a->qte) ;
}
for (a = deb ; a != NULL ; a = nouv)
{
nouv = a->suiv ;
free(a) ;
}
}
/* A */
listele *deb, *bkup, *nouv, *a ; /* A */
*deb, *bkup, *nouv, *a sont des pointeurs pour accueillir des données
de type listelepour linstant, ils ne pointent pas vers une adresse
ne mémoire, ils sont simplement déclarés pour recevoir des données =
de
type prédéfinies.
/* B */
nouv = bkup = deb ;
Ici nouv et bkup recoivent ladresse en mémoire de deb
/* C */
deb->suiv = NULL ;
deb->suiv recoit ladresse nulle
/* D */ si nouv est alphabetiquement plus petit que deb. Comment est-
ce que la comparaison peut se faire lors de la première saisie? Ce que
jai compris jusquà présent sur les pointeurs et variable non
initialisés cest quils peuvent contenir nimporte quoi. Et ici nu=
l
part deb a été initialisé, il a seulement reçu un espace mémoire =
à la
ligne A mais malloc ninitialise pas, ça serait plutôt calloc et
encore ce nest pas pour des caractèresalors, je me pose la
question avec quoi nouv est comparé?
/* E */ strcmp(a->suiv, nouv->name) < 0
Lauteur :
« Il faut effectuer la comparaison avec lelement suivant et non avec
lelement actuel, afin de vérifier avant quel element de la liste il
faut insérer le nouveau. Cela serait impossible si on comparaît nouv-
>name et a->name. En effet, on ne disposerait plus alors de ladresse
nécessaire du prédécesseur dans la liste. En procédant ainsi on ins=
ère
le nouvel élément avant le premier qui lui est alphabétiquement
supérieur ou égal. Pour cela on actualise de manière adéquate les
pointeurs nouv->suiv et a->suiv.»
Je ne suis pas sûre de comprendre : «on ne disposerait plus alors de
ladresse nécessaire du prédécesseur dans la liste»

Poser une question


<couic>
Donc quand on écrit dans deb->xxx, on écrit en même temps dans nouv->xxx
et dans bkup->xxx
Et de même pour nouv->suiv et pour bkup->suiv !
Cf. supra: en fait ils sont identiques, deb->Name et nouv->Name sont un
seul et unique objet.
Fait un dessin sur une feuille de papier, et suis les opérations une par
une : une liste chaînée est très facile à visualiser. La symbologie
habituelle, c'est une boîte pour un objet structure (alloué par
malloc()), et une flèche pour un pointeur. Au départ tu as
deb-------
nouv-------
bkup--------
+---------+
->| |
| suiv---------->NULL
| |
+---------+
Au troisième tour, tu auras
deb-------
nouv---
+------+ +------+ +------+ +------+
->| | ->| | /->| | /->| |
| suiv-->??? | suiv--/ | suiv--/ | suiv-->NULL
| | | | | | | |
+------+ +------+ +------+ +------+
Crayon et gomme, il n'y rien de mieux en algorithmique !
Antoine