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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct fiche
{
char nom[10];
char prenom[11];
int jour;
int mois;
int annee;
/* -ed-
int age;
je retire l'age qui est une donnee fluctuante qui peut etre calculee
au jour le jour... */
}
CIT;
/* affichage du tableau */
/* pourquoi size_t n pas int ? */
/* -ed- size_t est un type correct pour les tailles d'objets, donc les nombres
d'élements de tableaux et donc pour les indices (croissants, car c'est
un type non signé).
*/
static void aff (CIT const *a, size_t n)
{
/* pourquoi size_t i pas int i ? */
size_t i;
for (i = 0; i < n; i++)
{
/* pointeur intermediaire pour alleger l'ecriture */
CIT const *p = a + i;
/* -ed- evidemment, "2009" pourrait etre evalué automatiquement avec
time() etc. Et il faudrait aussi tenir compte du mois et du jour ...
*/
int age = 2009 - p->annee;
printf ("%-10s %-10s %d ans\n", p->nom, p->prenom, age);
}
printf ("\n");
}
/* fonction utilisateur de comparaison fournie a qsort() */
/* pourquoi const, alors que moi je veux trier et changer les positions ? */
/* -ed- parce que la fonction de comparaison ne modifie rien.
Elle se contente de tester, donc de lire les données. */
int CompareCitoyenParDate (const void *pcvA, const void *pcvB)
{
/* a quoi ça sert void ? */
/* -ed- void * signifie "pointeur de n'importe quel type" C'est requis par
qsort(). La fonction de comparaison est appelée par qsort(). Elle doit
répondre à des critères d'interface bien précis :
int fonction (void const *, void const *)
ensuite, on doit adapter le codage de la fonction selon les type des données
à traiter. Les 2 paramètres sont les adresses des données en cours de
traitement par qsort().
*/
/* -ed-
const fiche *pcA = tab;
const fiche *pcB = tab;
ça, c'est très faux. Il n'y a jamais eu ça dans mes exemples.
Il faut suivre scrupuleusement les indications. Les pointeurs locaux sont
typés selon les données à traiter ('CIT' ou 'struct fiche', mais pas 'fiche').
Il prennent comme valeur les 2 valeurs reçues en paramètre :
*/
const CIT *pcA = pcvA;
const CIT *pcB = pcvB;
/* -ed- si l'ordre de tri ne convient pas, il suffit d'inverser :
const CIT *pcA = pcvB;
const CIT *pcB = pcvA;
*/
int res;
res = pcA->annee - pcB->annee;
if (res != 0)
return res;
else
res = pcA->mois - pcB->mois;
if (res != 0)
return res;
else
res = pcA->jour - pcB->jour;
if (res != 0)
return res;
return 0;
}
/* -ed- Je recommande un remplissage 'en dur' pour commencer.
Ca permet d'avoir un comportement connu et répétitif ...
De plus, ça accélère considérablement l'exécution et donc ça favorise les tests
intensifs...
J'ai ajoute un paramètre "nombre d'éléments du tableau".
*/
void remplir (CIT * tab, size_t n)
{
size_t i;
/* -ed
for (i = 0; i <= 2; i++)
- on utilise pas de valeur en dur, mais un parametre..
- pour parcourir un tableau de N elements, on utilise :
for (i = 0; i < N; i++)
qui fait varier i de 0 à N-1, comme il se doit.
*/
for (i = 0; i < n; i++)
{
#if 0
printf ("nom :\n");
/* -ed-
scanf("%s",&tab[i].nom);
encore une fois, .nom est un tableau. Il ne faut pas de '&'
*/
scanf ("%s", tab[i].nom);
printf ("prenom :\n");
scanf ("%s", tab[i].prenom);
printf ("date de naissance aaaa/mm/jj:\n");
scanf ("%d%d%d", &tab[i].annee, &tab[i].mois, &tab[i].jour);
#else
/* "simulation de saisie "en dur" */
static const CIT a[] = {
{"Homer", "Simpson", 12, 1, 1960},
{"Marge", "Simpson", 8, 2, 1958},
{"Bart", "Simpson", 22, 8, 1990},
{"Lisa", "Simpson", 15, 3, 1992},
{"Maggie", "Simpson", 30, 4, 1995},
};
tab[i] = a[i];
#endif
}
}
int main (void)
{
/* -ed- déplacé. Aucune raison que ce soit une globale */
CIT tab[4];
/* -ed- sizeof tab / sizeof *tab est un moyen de calculer automatiquement
le nombre d'élements d'un tableau.
Je l'utilise ici pour indiquer à la fonction de remplissage combien
d'éléments elle doit traiter (au maximum).
*/
remplir (tab, sizeof tab / sizeof *tab);
qsort (tab, sizeof tab / sizeof *tab, sizeof *tab, CompareCitoyenParDate);
/* affichage du tableau apres le tri */
aff (tab, sizeof tab / sizeof *tab);
/* -ed- inutile
system ("pause");
*/
return 0;
} |