je suis débutant en C++ et, dans mon cours, je suis arrivé à un exemple dont beaucoup de points me posent problème. je poserai mes questions au fil du programme dans des comentaires qui seront numérotés ( les numéros ne sont pas dans l´ordre).
j´espère quil n´y aura pas de problèmes d´affichage. si ça fait bizarre, vous pouvez rétressir la taille du texte de votre navigateur.
je vous donne aussi l´introduction de l´exemple du cours:
"L´exemple suivant va vous présenter un programme C classique qui manipule des pointeurs. Ce programme réalise des allocations dynamiques de mémoire et manipule une liste de structures dynamiquement, en fonction des entrées que fait l´utilisateur. Les techniques de saisies de paramètres présentées dans le premier chapitre sont également revues. Ce programme vous présente aussi comment passer des paramètres par variable, soit pour optimiser le programme, soit pour les modifier au sein des fonctions appelées. Enfin, l´utilisation du mot clef const avec les pointeurs est également illustrée."
et maintenant, le programme :
et de scanf. */
et de free. */
strlen et de strcmp. */
/* Type de base d´un élément de liste de personne. */
typedef struct person
{
char *name; /* Nom de la personne. */
char *address; /* Adresse de la personne. */
struct person *next; /* Pointeur sur l´élément suivant. */
} Person;
typedef Person *People; /* Type de liste de personnes. */
/* 7) est-ce que içi person, Person et People sont un seul et même type ? */
/* Fonctions de gestion des listes de personnes : */
/* Fonction d´initialisation d´une liste de personne.
La liste est passée par variable pour permettre son initialisation. */
void init_list(People *lst)
{
*lst = NULL;
}
/* 8) je ne vois pas à quoi ça sert et puis en plus *lst n´est pas une liste mais une structure de type People */
/* Fonction d´ajout d´une personne. Les paramètres de la personne
sont passés par variables, mais ne peuvent être modifiés car
ils sont constants. Ce sont des chaînes de caractères C, qui
sont donc assimilées à des pointeurs de caractères constants. */
int add_person(People *lst, const char *name, const char *address)
{
/* Crée un nouvel élément : */
Person *p = ( Person *) malloc(sizeof(Person)); /* 9) cette ligne alloue de la mémoire mais je ne comprends pas trop la syntaxe */
if ( p ! = NULL) /* 10) comprends pas */
{
/* Alloue la mémoire pour le nom et l´adresse. Attention,
il faut compter le caractère nul terminal des chaînes : */
p->name = ( char *) malloc((strlen(name) + 1) * sizeof(char));
p->address = ( char *) malloc((strlen(address) + 1) * sizeof(char));
/* 11) on a déjà alloué la mémoire pour la structure, alors pourquoi le refaire pour les éléments de cette même structure ? */
if ( p->name ! = NULL && p->address ! = NULL) /* 12) comprends pas */
{
/* Copie le nom et l´adresse : */
strcpy(p->name, name);
strcpy(p->address, address);
p->next = *lst;
*lst = p;
}
else /* 12bis) voir avec le 12 */
{
free(p);
p = NULL;
}
}
return ( p ! = NULL); /* 13) au dessus, y´a écrit p = NULL et là on doit renvoyer p ! = NULL ! ? */
}
/* Fonction de suppression d´une personne.
La structure de la liste est modifiée par la suppression
de l´élément de cette personne. Cela peut impliquer la modification
du chaînage de l´élément précédent, ou la modification de la tête
de liste elle-même. */
/* 14) on verra cette fonction plus tard. si je comprend tout le reste, ce sera déjà pas mal */
int remove_person(People *lst, const char *name)
{
/* Recherche la personne et son antécédant : */
Person *prev = NULL;
Person *p = *lst;
while ( p ! = NULL)
{
/* On sort si l´élément courant est la personne recherchée : */
if ( strcmp(p->name, name) == 0)
break;
/* On passe à l´élément suivant sinon : */
prev = p;
p = p->next;
}
if ( p ! = NULL)
{
/* La personne a été trouvée, on la supprime de la liste : */
if ( prev == NULL)
{
/* La personne est en tête de liste, on met à jour
le pointeur de tête de liste : */
*lst = p->next;
}
else
{
/* On met à jour le lien de l´élément précédent : */
prev->next = p->next;
}
/* et on la détruit : */
free(p->name);
free(p->address);
free(p);
}
return ( p ! = NULL);
}
/* Simple fonction d´affichage. */
void print_list(People const *lst)
{
Person const *p = *lst;
int i = 1;
while ( p ! = NULL)
{
printf("Personne %d : %s ( %s)\n", i, p->name, p->address);
p = p->next;
++i;
}
}
/* Fonction de destruction et de libération de la mémoire. */
void destroy_list(People *lst)
{
while ( *lst ! = NULL)
{
Person *p = *lst;
*lst = p->next;
free(p->name);
free(p->address);
free(p);
}
return ;
}
int main(void)
{
int op = 0;
size_t s; /* 1) je ne connais pas cet opérateur */
char buffer[16];/* 2) je ne vois pas du tout à quoi sert ce tableau de caractères */
char name[256];
/* Crée une liste de personne : */
People p;
init_list(&);/* 3) si je comprends bien, içi, &=NULL */
/* Utilise la liste : */
do
{
printf("Opération ( 0 = quitter, 1 = ajouter, 2 = supprimer) ? ");
fgets(buffer, 16, stdin); /* 4) toujours ce tableau que je ne comprend pas */
buffer[15] = 0;
op = 3; /* 5) à quoi ça sert puisqu´à la ligne suivante, si je comprends bien, l´utilisatuer réinitialise op */
sscanf(buffer, "%d", &);
switch ( op)
{
case 0:
break;
case 1:
printf("Nom : ");
fgets(name, 256, stdin); /* Lit le nom. */
name[255] = 0; /* Assure que le caractère nul
terminal est écrit. */
s = strlen(name); /* Supprime l´éventuel saut de ligne. */
if ( name[s - 1] == ´\n´) name[s - 1] = 0;
/* Même opération pour l´adresse : */
printf("Adresse : ");
fgets(address, 256, stdin);
name[255] = 0;
s = strlen(address);
if ( address[s - 1] == ´\n´) address[s - 1] = 0;
add_person(&, name, address); /* 6) voir la fonction en question */
break;
case 2:
printf("Nom : ");
fgets(name, 256, stdin);
name[255] = 0;
s = strlen(name);
if ( name[s - 1] == ´\n´) name[s - 1] = 0;
if ( remove_person(&, name) == 0)
{
printf("Personne inconnue.\n");
}
break;
default:
printf("Opération invalide\n");
break;
}
if ( op ! = 0) print_list(&);
} while ( op ! = 0);
/* Détruit la liste : */
destroy_list(&);
return 0;
}
____________________________
merci pour votre aide.
Désolé, c´est illisible : )
Mais je peux quand même te dire qu´il va te falloir bosser un peu plus que ca les pointeurs tu m´as l´air un peu perdu avec ca.
7) person et Person représente un même type mais l´utilisation de ´person´ est facultative, sauf dans ce cas là car on a besoin de faire référence à cette structure pour le chainage des cellules de ta liste ( struct person *next)
People est un pointeur sur une cellule de type Person ( ce qui en fait correspond à la tête de liste)
8) lst est bien une liste . .. cf au dessus
9) malloc retourne un pointeur sur la zone allouée ( si pas de pb rencontré) pour laquelle tu fournis la taille de la zone en paramètre ( sizeof(Person)). sizeof indique la taille en octets du type spécifié. Si la zone ne peut être allouée ca retourne NULL.
10) p ! = NULL veut dire "si le pointeur p a été alloué" cad contient quelquechose . .. dans le contexte ca veut dire "est ce que l´allocation de la ligne précédente ( cf malloc) s´est bien passée ? "
11) p->name et p->address ne sont que des pointeurs de chaine de caractères et aucun espace n´a été alloué jusque là pour stocker les données passées en paramètre ( name et address).
12) idem 10 . .. est ce que les allocations se sont bien passées ?
12bis) ya une petite erreur tu pourras le signaler à ton prof/auteur de ton cours : car l´une des allocations pourrait s´être bien passée et free(p) ne libère malheureusement pas name ou address . ..
13) si tu passes dans le if et non dans le else p n´est pas ! = NULL . .. la valeur de retour ( p ! = NULL) est évaluée et ainsi cela te permet de savoir si ton init s´est bien passée ou non . ..
Pour en revenir aux pointeurs :
renseignes toi sur ce qu´est :
- 1 pointeur
- 1 null pointer
- 1 wild pointer
- l´opérateur de cast
- les différentes fonctions liées aux allocations
merci
désolé pour la présentation mais c´est vraiment pas pratique ( la fenêtre est minuscule) et tous les alinéas ont été supprimés.
GamerFou2, je ne crois pas que tout ce que tu me demandes de faire soit encore de mon niveau.
Pourtant, mis à part les wild pointers, tout est dans ton exemple . ..
c´est vrai, mais y´a aussi l´opérateur de cast.
c´est quoi ?
oups je l´ai oublié : )
bin quand tu fais un malloc par ex :
( char *) malloc((strlen(name) + 1) * sizeof(char));
malloc retourne un pointeur sur une zone mémoire de type void ( sans type). L´opérateur de cast permet de forcer le type lors d´une évaluation. Ici la zone mémoire est forcée au type ( char *) ce qui te permet d´effecteur l´affectation sans pb ( sinon ca essaierai d´affecter un void* à un char*)
Tu peux l´utiliser dans d´autres cas ( dans une expression, un passage de paramètres etc..). Mais lis les docs a ce sujet elles sont bien plus claires que moi je pense : )
13) donc la valeur de retour est 1 ou 0, pas la valeur de p.
c´est bien ça ?
yes
up ( pour nutspower )