IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Les listes triées


Sujet :

C

  1. #1
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut Les listes triées
    Bonjour,

    Je trouve un petit problème avec les pointeurs et les listes en C

    je réalise un petit programme tout simple qui insère un nouvel élément dans une liste triée.

    dans mon exemple, une liste d'éléments triées par ordre croissant des numéros de références:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
     
    #include <stdio.h>
    #include <alloc.h>
    #include <conio.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    liste *suiv;
    }
    liste * debut, *courant, *nouveau;
    char reponse;
    void insert (char nom, int num_ref) {
     
    /*création de la liste*/
     
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    do {
    clrscr();
    printf(" /n entrez le nom");
    scanf("%s", courant->nom);
    printf("/n entrez le numéro de référence");
    scanf("%d", courant->num_ref);
     
    printf("avez vous un autre élément à saisir? o/n");
    reponse=getche();
    if (reponse='o' ou 'O')
    {
    nouveau=liste*malloc(sizeof(liste));
    printf("/n entrez le nom");
    printf("/n entrez le numéro de référence");
    scanf("%s%d", nouveau->nom, nouveau->num_ref);
    ref=nouveau->num_ref;
     
    /*parcours de la liste*/
     
    courant=debut
    if (courant->num_ref > ref) /*tester la tête de la liste avec le numéro de référence du nouveau élément*/
    /*insertion en tête de liste*/
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
    else 
     while (courant->suivant!=NULL)
     {
     courant=courant->suivant;
     if (courant->num_ref < ref)
     /*insérer au milieu*/
     {
     nouveau->suivant=courant->suivant;
     courant->suivant=nouveau;
     }
    }
    else
     if (courant->suivant=NULL)
     {
     nouveau->suivant=NULL;
     courant->suivant=nouveau;
    }
     
    }
    qu'en pensez vous?

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Ce que j'en pense ? Ben je pense que je ne comprends pas pourquoi ta procédure d'insertion est placée dans un while() ou alors j'ai pas compris ce que tu cheches à faire. On insère bien un seul élément non ? Si c'est le cas alors mettre l'algo d'insertion dans une boucle n'est pas une bonne idée.

    Autre détail: tu devrais découper ton problème en taches élémentaires et faire faire ces tâches par des fonctions. Cela allègera ton code et tu pourras ensuite utiliser et réutiliser tes fonctions quand ton programme évoluera (par exemple si demain tu décides que les éléments à insérer seront pris dans un fichier tu pourras facilement rajouter cette branche à ton programme)

  3. #3
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ce que j'en pense ? Ben je pense que je ne comprends pas pourquoi ta procédure d'insertion est placée dans un while() ou alors j'ai pas compris ce que tu cheches à faire. On insère bien un seul élément non ? Si c'est le cas alors mettre l'algo d'insertion dans une boucle n'est pas une bonne idée.

    Autre détail: tu devrais découper ton problème en taches élémentaires et faire faire ces tâches par des fonctions. Cela allègera ton code et tu pourras ensuite utiliser et réutiliser tes fonctions quand ton programme évoluera (par exemple si demain tu décides que les éléments à insérer seront pris dans un fichier tu pourras facilement rajouter cette branche à ton programme)
    Bonsoir,

    je cherche à insérer un nouvel élément dans la liste triée, cette insertion pourrait se faire en début, au milieu ou en fin de liste.

    je le fait en boucle pour insérer tout en gardant une liste triée, donc à chaque fois que l'utilisateur veut introduire un nouveau produit, il indique son nom et son num de ref et les le tout est trié selon les num de référence

  4. #4
    Membre habitué Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Points : 180
    Points
    180
    Par défaut
    Salut
    Ce que j’ai compris dans la fonction en question : c’est que tu donnes les paramètres du nouveau élément en argument au même temps tu vas créer la liste tout en la triant pour qu’enfin tu puisse insérer le nouveau élément.

    Si c’est le cas, alors je te suggère de créer le premier élément tout seul, puis utiliser la fonction insert avec quelques rectifications de tel manière à insérer le nouveau élément dans sa place sans boucler puis dans le main faire le test si l’utilisateur veut ajouter un nouveau élément tout en utilisant cette boucle.
    J’espère que ça va te servir.

  5. #5
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut
    Bonsoir,

    alors suivant vos conseils, j'ai refait mon programme différemment en le décomposant en fonctions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <stdio.h>
    #include <conio.h>
    #include <alloc.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    *suivant;
    }
     
    liste * debut, *courant, *nouveau;
    char reponse;
     
    void creer_premier()
    void insert(char nom, int num_ref);
    void insert_debut();
    void insert_milieu();
    void insert_fin();
    void main()
    {
    printf("/n entrez le nom du produit");
    printf("/n entrez la référence");
    creer_premier();
    printf("voulez-vous une autre saisie?");
    reponse=getche();
    while (reponse=='o' || reponse=='O')
    nouveau=liste*malloc(sizeof(liste));
    insert(nom,num_ref);
     
    }
     
    void creer_premier(nom, num_ref)
    {
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    ]
     
    void insert(nom, num_ref) 
    {
    courant=debut;
    if (courant->suivant > num_ref)
    {
    insert_debut();
    }
    else
    {
    while (courant->suivant != NULL)
    {
    courant=courant->suivant;
    if (courant->num_ref < ref)
    insert_milieu();
    }
    }
    else
    insert_fin();
     
    }
     
    void insert_debut()
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
     
    void insert_milieu()
    {
    nouveau->suivant=courant->suivant;
    courant->suivant=nouveau;
    }
     
    void insert_fin()
    {
    nouveau->suivant=NULL;
    courant->suivant=nouveau;
    }
     
    }
    s'il vous plait..

  6. #6
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    déjà corrige les erreurs de syntaxe comme les points virgule, etc.
    puis tu n'as pas déclaré dans le main les variables nom et num_ref.

  7. #7
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut
    Citation Envoyé par coyotte507 Voir le message
    déjà corrige les erreurs de syntaxe comme les points virgule, etc.
    puis tu n'as pas déclaré dans le main les variables nom et num_ref.
    les ";" j'en ai en plus ou en moins? j'ai revu normalement ça ira comme ça sinon, tu seras gentil de m'indiquer les lignes.

    les variable sont locales, et le "nom" et "num_ref" dans une fonction ne sont pas les même dans l'autre.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par acacia Voir le message
    Bonsoir,

    je cherche à insérer un nouvel élément dans la liste triée, cette insertion pourrait se faire en début, au milieu ou en fin de liste.

    je le fait en boucle pour insérer tout en gardant une liste triée
    Je sais comment on se sert d'une liste triée et comment on insère. Ce que je veux te dire c'est que t'as pas besoin de mettre l'insertion dans le while.
    Il te faut
    1) chercher la position où ira s'insérer le nouvel élément (là il faut un while)
    2) une fois qu'on a trouvé la position (donc après le while) il te faut insérer l'élément en cours

    Citation Envoyé par acacia Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <stdio.h>
    #include <conio.h>
    #include <alloc.h>
     
    typedef struct liste
    {
    char nom;
    int num_ref;
    *suivant;
    }
     
    liste * debut, *courant, *nouveau;
    char reponse;
     
    void creer_premier()
    void insert(char nom, int num_ref);
    void insert_debut();
    void insert_milieu();
    void insert_fin();
    void main()
    {
    printf("/n entrez le nom du produit");
    printf("/n entrez la référence");
    creer_premier();
    printf("voulez-vous une autre saisie?");
    reponse=getche();
    while (reponse=='o' || reponse=='O')
    nouveau=liste*malloc(sizeof(liste));
    insert(nom,num_ref);
     
    }
     
    void creer_premier(nom, num_ref)
    {
    debut=liste*malloc(sizeof(liste));
    courant=debut;
    ]
     
    void insert(nom, num_ref) 
    {
    courant=debut;
    if (courant->suivant > num_ref)
    {
    insert_debut();
    }
    else
    {
    while (courant->suivant != NULL)
    {
    courant=courant->suivant;
    if (courant->num_ref < ref)
    insert_milieu();
    }
    }
    else
    insert_fin();
     
    }
     
    void insert_debut()
    {
    nouveau->suivant=debut;
    debut=nouveau;
    }
     
    void insert_milieu()
    {
    nouveau->suivant=courant->suivant;
    courant->suivant=nouveau;
    }
     
    void insert_fin()
    {
    nouveau->suivant=NULL;
    courant->suivant=nouveau;
    }
     
    }
    Bon ben des erreurs courantes
    1) main est de type "int" et non "void"
    2) les variables globales sont inutiles et sources de bug potentiel. Essaye de prendre l'habitude de déclarer dans tes fonctions les variables nécessaires au travail de la fonction et que les fonctions ayant besoin des valeurs d'autres fonctions les reçoivent en paramètre...
    3) tu crées un typedef sur une structure mais tu dis pas comment se nommera le type que tu crées => corollaire => le type "liste" n'existe pas
    4) euh... pourquoi cette accolade supplémentaire après la dernière fonction ???

    Autre détail => tu as créé une fonction qui te crée le premier élément puis ensuite, quand il faut en rajouter, tu les alloues dans le main. Tu aurais écrit une fonction qui crée un élément quel qu'il soit, tu aurais pu l'appeler pour le premier et aussi pour tous les autres...

  9. #9
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je sais comment on se sert d'une liste triée et comment on insère. Ce que je veux te dire c'est que t'as pas besoin de mettre l'insertion dans le while.
    Il te faut
    1) chercher la position où ira s'insérer le nouvel élément (là il faut un while)
    2) une fois qu'on a trouvé la position (donc après le while) il te faut insérer l'élément en cours



    Bon ben des erreurs courantes
    1) main est de type "int" et non "void"
    2) les variables globales sont inutiles et sources de bug potentiel. Essaye de prendre l'habitude de déclarer dans tes fonctions les variables nécessaires au travail de la fonction et que les fonctions ayant besoin des valeurs d'autres fonctions les reçoivent en paramètre...
    3) tu crées un typedef sur une structure mais tu dis pas comment se nommera le type que tu crées => corollaire => le type "liste" n'existe pas
    4) euh... pourquoi cette accolade supplémentaire après la dernière fonction ???

    Autre détail => tu as créé une fonction qui te crée le premier élément puis ensuite, quand il faut en rajouter, tu les alloues dans le main. Tu aurais écrit une fonction qui crée un élément quel qu'il soit, tu aurais pu l'appeler pour le premier et aussi pour tous les autres...
    Bonjour Sve@r merci pour la réponse, je vais corriger tout de suite ces erreurs.

    j'ai une petite question, y a t-il plusieurs manière de déclarer les listes chainées?

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par acacia Voir le message
    j'ai une petite question, y a t-il plusieurs manière de déclarer les listes chainées?
    Personnellement je préconise de déclarer 2 structures
    1) la structure permettant de manipuler un élément qui contient donc les infos de l'élément et le pointeur sur le suivant et éventuellement d'autres pointeurs sur d'autres suivants (si par exemple on veut faire une liste triée sur plusieurs critères)
    2) une structure qui permet de manipuler la liste. Ca peut paraître trivial vu qu'il suffit d'avoir le premier élément et que déclarer une structure juste pour ça c'est idiot mais une fois qu'on a la structure, on peut ensuite évoluer plus facilement. Par exemple si on a envie d'avoir aussi le nombre d'éléments on peut mettre cette info dans cette structure. Si on fait une liste triée sur plusieurs critères alors il y aura plusieurs "premiers" éléments et donc on peut rajouter tous ces pointeurs plus facilement dans une structure déjà toute faite que si on décide de la créer après coup parce qu'on voit qu'on se met à en avoir besoin

    Par exemple voici une bonne base pour démarrer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    // Les structures
    typedef struct s_elem {
        <...>
        struct s_elem *next;
    } t_elem;
     
    typedef struct s_liste {
        t_elem *debut;
        unsigned long nb
    } t_liste;
     
    // Fonction qui nettoie une liste de tous ses éléments résiduels
    void freeListe(t_liste *liste)
    {
        t_elem *cur;
     
        // Traitement de toute la liste
        while (liste->debut != NULL)
        {
            cur=liste->debut;
            liste->debut=liste->debut->next;
            free(cur);
        }
     
        liste->nb=0;
    }
     
    // Fonction qui initialise une liste
    void initListe(t_liste *liste)
    {
        liste->debut=NULL;
        liste->nb=0;
    }
     
    // Fonction qui crée un élément et le remplit
    t_elem *ajoutElem(<... infos à remplir ...>)
    {
        t_elem *elem;
     
        // Création de l'élément - Vérification création
        elem=malloc(sizeof t_elem);
        if (elem == NULL)
           return NULL;
     
        // Remplissage de l'élément
        elem->...=...;
        elem->...=...;
        elem->next=NULL;
     
        // Renvoi de l'élément créé
        return elem;
    }
     
    // Fonction qui insère un élément après un autre ou au début 
    void insereElem(t_liste liste, t_elem *pos, t_elem *elem)
    {
        // S'il faut insérer au début (pos conventionnelement égal à NULL)
        if (pos == NULL)
        {
             // L'élément récupère le début
             elem->next=liste->debut;
     
             // Le début change
             liste->debut=elem;
        }
        else
        {
             // L'élément récupère le suivant de celui après lequel il s'ajoute
             elem->next=pos->next;
     
             // L'élément s'insère
             pos->next=elem;
        }
     
        // On a un élément en plus
        liste->nb++;
    }
    Voilà une ébauche de ce que je ferais si je devais manipuler des listes...

  11. #11
    Membre habitué Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Points : 180
    Points
    180
    Par défaut
    salut
    Désolé pour le retard, en fait essayez ce code, il n’est pas bien commenté mais au cas où vous auriez besoin de quelques explications je serai là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <stdio.h>
    #include <string.h>
    #include<stdlib.h>
    #include <malloc.h>
     
    typedef struct liste
    {
    	char nom[30];
    	int num_ref;
    	struct liste *suiv;
    }element;
    typedef element *nv_type;  
     
    nv_type creer_premier(char *nom, int num_ref);//fct pour créer le premier élément
    nv_type inserer(char *nom,int num_ref,nv_type premier);
    void vider(nv_type premier);//pour liberer la memoire allouée
     
    void main()
    {
    	nv_type premier;//pointeur vers le premier élément
    	char nom[30],reponse='n';
    	int num_ref;
    	printf("entrez le nom du produit\n");
    	scanf("%s",nom);
    	fflush(stdin);//vider le tampon
    	printf("entrez la référence\n");
    	scanf("%d",&num_ref);
    	fflush(stdin);
    	premier=creer_premier(nom,num_ref);
    	printf("voulez-vous une autre saisie?   ");
    	scanf("%c",&reponse);
    	while ((reponse=='o') || (reponse=='O'))
    	{
    		printf("entrez le nom du produit\n");
    		scanf("%s",nom);
    		fflush(stdin);
    		printf("entrez la référence\n");
    		scanf("%d",&num_ref);
    		fflush(stdin);
    		premier=inserer(nom,num_ref,premier);
    		printf("voulez-vous une autre saisie?  ");
    		scanf("%c",&reponse);
    		fflush(stdin);
    	}
    	vider(premier);
     
    }
    nv_type creer_premier(char *nom, int num_ref)
    {
    	nv_type debut;
    	debut=(nv_type)malloc(sizeof(element));
    	strcpy(debut->nom,nom);
    	debut->num_ref=num_ref;
    	debut->suiv=NULL;
    	return debut;//retourner un pointeur vers le premier élément
    }
     
    nv_type inserer(char *nom,int num_ref,nv_type premier) 
    {
    	nv_type courant,suivant,precedent;
    	int dernier=1;//pour indiquer si le nv élément doit être inseré à la fin de la liste
    	courant=(nv_type)malloc(sizeof(element));
    	strcpy(courant->nom,nom);
    	courant->num_ref=num_ref;//remplir les champs du nv élément
    	if(num_ref<(premier->num_ref))//s'il doit être inseré au debut de la liste
    	{
    		courant->suiv=premier;
    		premier=courant;
    	}
    	else
    	{
    		precedent=premier;
    		suivant=precedent->suiv;
    		while(suivant!=NULL)
    		{
    			if(num_ref< suivant->num_ref )
    			{
    				precedent->suiv=courant;// pointer vers le vn élément
    				courant->suiv=suivant;
    				dernier=0;//mettre dernier à zéro pour indiquer l'insertion du nv
    				break;
    			}
    			precedent=suivant;
    			suivant=suivant->suiv;
    		}
    		if(dernier==1)//cas où on doit l'inserer à la fin
    		{
    			precedent->suiv=courant;
    			courant->suiv=NULL;
    		}
    	}
    	return premier;
    }
    void vider(nv_type premier)
    {
    	nv_type courant,suivant;
    	courant=premier;
    	suivant=courant->suiv;
    	while(suivant!=NULL)
    	{
    		free(courant);
    		courant=suivant;
    		suivant=suivant->suiv;
    	}
    	free(courant);//dernier élément
    }

  12. #12
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Citation Envoyé par archer Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ....
    	fflush(stdin);//vider le tampon
    ....
    Le comportement de fflush est indéfini pour un flot d'entrée et cette fonction ne doit être utilisée que pour un flot de sortie.

  13. #13
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par archer Voir le message
    salut
    Désolé pour le retard, en fait essayez ce code, il n’est pas bien commenté mais au cas où vous auriez besoin de quelques explications je serai là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <stdio.h>
    #include <string.h>
    #include<stdlib.h>
    #include <malloc.h>
     
    typedef struct liste
    {
    	char nom[30];
    	int num_ref;
    	struct liste *suiv;
    }element;
    typedef element *nv_type;  
     
    nv_type creer_premier(char *nom, int num_ref);//fct pour créer le premier élément
    nv_type inserer(char *nom,int num_ref,nv_type premier);
    void vider(nv_type premier);//pour liberer la memoire allouée
     
    void main()
    {
    	nv_type premier;//pointeur vers le premier élément
    	char nom[30],reponse='n';
    	int num_ref;
    	printf("entrez le nom du produit\n");
    	scanf("%s",nom);
    	fflush(stdin);//vider le tampon
    	printf("entrez la référence\n");
    	scanf("%d",&num_ref);
    	fflush(stdin);
    	premier=creer_premier(nom,num_ref);
    	printf("voulez-vous une autre saisie?   ");
    	scanf("%c",&reponse);
    	while ((reponse=='o') || (reponse=='O'))
    	{
    		printf("entrez le nom du produit\n");
    		scanf("%s",nom);
    		fflush(stdin);
    		printf("entrez la référence\n");
    		scanf("%d",&num_ref);
    		fflush(stdin);
    		premier=inserer(nom,num_ref,premier);
    		printf("voulez-vous une autre saisie?  ");
    		scanf("%c",&reponse);
    		fflush(stdin);
    	}
    	vider(premier);
     
    }
    nv_type creer_premier(char *nom, int num_ref)
    {
    	nv_type debut;
    	debut=(nv_type)malloc(sizeof(element));
    	strcpy(debut->nom,nom);
    	debut->num_ref=num_ref;
    	debut->suiv=NULL;
    	return debut;//retourner un pointeur vers le premier élément
    }
     
    nv_type inserer(char *nom,int num_ref,nv_type premier) 
    {
    	nv_type courant,suivant,precedent;
    	int dernier=1;//pour indiquer si le nv élément doit être inseré à la fin de la liste
    	courant=(nv_type)malloc(sizeof(element));
    	strcpy(courant->nom,nom);
    	courant->num_ref=num_ref;//remplir les champs du nv élément
    	if(num_ref<(premier->num_ref))//s'il doit être inseré au debut de la liste
    	{
    		courant->suiv=premier;
    		premier=courant;
    	}
    	else
    	{
    		precedent=premier;
    		suivant=precedent->suiv;
    		while(suivant!=NULL)
    		{
    			if(num_ref< suivant->num_ref )
    			{
    				precedent->suiv=courant;// pointer vers le vn élément
    				courant->suiv=suivant;
    				dernier=0;//mettre dernier à zéro pour indiquer l'insertion du nv
    				break;
    			}
    			precedent=suivant;
    			suivant=suivant->suiv;
    		}
    		if(dernier==1)//cas où on doit l'inserer à la fin
    		{
    			precedent->suiv=courant;
    			courant->suiv=NULL;
    		}
    	}
    	return premier;
    }
    void vider(nv_type premier)
    {
    	nv_type courant,suivant;
    	courant=premier;
    	suivant=courant->suiv;
    	while(suivant!=NULL)
    	{
    		free(courant);
    		courant=suivant;
    		suivant=suivant->suiv;
    	}
    	free(courant);//dernier élément
    }
    - main n'est pas de type void
    - c'est une source de confusion que de masquer les étoiles derrière des noms de type
    - le malloc ne se caste pas
    - les conventions demandent à ce que les noms de type soient nommés "t_qqchose"

  14. #14
    Membre habitué Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Points : 180
    Points
    180
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    - main n'est pas de type void
    - c'est une source de confusion que de masquer les étoiles derrière des noms de type
    - le malloc ne se caste pas
    - les conventions demandent à ce que les noms de type soient nommés "t_qqchose"
    salut
    Pouvez vous m’expliquer les 3 dernières remarques

  15. #15
    En attente de confirmation mail
    Étudiant
    Inscrit en
    Août 2007
    Messages
    419
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 419
    Points : 263
    Points
    263
    Par défaut
    Bonsoir,

    je vous remercie pour votre aide et votre patience

    j'ai commencé à refaire mon programme suivant ce que vous me proposez

    en plus je n'ai pas fait attention au début pour la libération de la mémoire déjà allouée

    au fait, que fait fflush?

    Merci encore

  16. #16
    Membre habitué Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Points : 180
    Points
    180
    Par défaut
    Salut
    En fait ffush(stdout) est utilisée pour forcer le vidage de la mémoire tampon par laquelle passent tous ce qu’on veut faire sortir( afficher sur l’écran, écrire dans un fichier … ) –ici stdout réfère à l’écran tand qu’on n’a pas fait la redirection des entrées/sorties-, je l’ai utilisé dans ce code parce que la saisie de la repense ne se faisait pas correctement et je ne voulais pas utiliser getchar() car j’ai lu qu’elle retourne un caractère à partir du tampon, donc il fallait procéder autrement.
    Remarque
    Ce que diogene a dit est vrai car fflush est utilisée pour les sorties son comportement vis-à-vis de l’entrée est imprévisible, donc il faut rectifier un peu le code en mettant fflush(stdout) après chaque affichage sur l’écran, en ce qui concerne le main() il faut qu’il retourne un int est plus précisément 0 pour indiquer que tout marche bien et pour que le code soit portable, en ce qui concerne les 3 dernières remarques qu’a fait Sve@r j’attends moi aussi plus d’explications de sa part.

  17. #17
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par archer Voir le message
    en ce qui concerne les 3 dernières remarques qu’a fait Sve@r j’attends moi aussi plus d’explications de sa part.
    Ce sont des remarques classiques sur ce forum. Une petite recherche de temps en temps ne fait pas mal.
    - c'est une source de confusion que de masquer les étoiles derrière des noms de type
    Il faut eviter de creer des typedefs qui sont "pointeurs vers type T", car le fait qu'une variable est un pointeur est alors "cache" a l'utilisateur du typedef, ce qui n'est pas une bonne chose (au pire, indiquer dans le nom du type qu'on defini un pointeur).

    - le malloc ne se caste pas
    malloc() retourne un void *, qui est implicitement converti en le type qui va bien. Le cast est inutile est peut cacher (dans un compilateur mal regle) l'oubli de stdlib.h

    - les conventions demandent à ce que les noms de type soient nommés "t_qqchose"
    C'est une convention, donc ca se discute, mais c'est une bonne convention, a mon avis. Evidemment, il faut comprendre "noms de type" par "les types definis par l'utilisateur". Le langage et POSIX ont d'autres regles.

  18. #18
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par archer Voir le message
    Ce que diogene a dit est vrai car fflush est utilisée pour les sorties son comportement vis-à-vis de l’entrée est imprévisible, donc il faut rectifier un peu le code en mettant fflush(stdout) après chaque affichage sur l’écran,
    certes, mais ça ne règle absolument pas les problèmes d'instabilité dûs aux saisies avec scanf() ou getchar(). Pour ça, il faut apprendre à faire des saisies correctes.

    http://emmanuel-delahaye.developpez.com/inputs.htm

  19. #19
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par archer Voir le message
    ...en ce qui concerne les 3 dernières remarques qu’a fait Sve@r j’attends moi aussi plus d’explications de sa part.
    Désolé de ne pas être H24 sur ce fofo. DaZumba a parfaitement résumé le pourquoi de mes remarques.
    Pour les conventions de nommage j'ajouterai juste que si les implémenteurs ont créé des types "size_t", "off_t", "ptr_t" etc ce n'est peut-être pas pour rien et qu'on peut au-moins s'inspirer de leur savoir faire. Mais comme le suffixe "_t" est réservé aux implémenteurs ben on le remplace par le préfixe "t_".

    Citation Envoyé par archer Voir le message
    donc il faut rectifier un peu le code en mettant fflush(stdout) après chaque affichage sur l’écran
    Faux. Arrête d'inventer des règles absurdes que rien ne justifie. fflush(stdout) ne se justifie que
    1) si la chaîne que t'affiches ne contient pas de '\n'
    2) au moment où tu décides que ladite chaîne devra être réellement affichée à l'écran

  20. #20
    Membre habitué Avatar de archer
    Ingénieur développement logiciels
    Inscrit en
    Mai 2007
    Messages
    338
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 338
    Points : 180
    Points
    180
    Par défaut
    Il s’est avéré que tu as raison Sve@r , à ton avis, comment on doit procéder pour résoudre le problème de la saisie de la réponse ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Optimiser les performances try/catch ?
    Par KiLVaiDeN dans le forum Langage
    Réponses: 4
    Dernier message: 14/01/2014, 14h47
  2. Tri sur les listes
    Par frizou11 dans le forum Général Python
    Réponses: 4
    Dernier message: 14/05/2006, 12h33
  3. [Liste]Tri
    Par GreenJay dans le forum Collection et Stream
    Réponses: 6
    Dernier message: 02/09/2004, 14h39
  4. [langage] probleme avec les listes dans des listes
    Par pqmoltonel dans le forum Langage
    Réponses: 7
    Dernier message: 27/04/2004, 13h32
  5. [LG]Les listes
    Par franck H dans le forum Langage
    Réponses: 2
    Dernier message: 16/01/2004, 16h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo