Bonjour !
Je vous propose un programme qui calcule la date de Pâques pour une année donnée du calendrier grégorien.
Un code similaire a déjà été proposé ici mais l'algorithme utilisé n'est pas le même.
NDLM : Supprimé à la demande de l'auteur
Version imprimable
Bonjour !
Je vous propose un programme qui calcule la date de Pâques pour une année donnée du calendrier grégorien.
Un code similaire a déjà été proposé ici mais l'algorithme utilisé n'est pas le même.
NDLM : Supprimé à la demande de l'auteur
Pour améliorer mon programme, j'ai pensé y inclure une table qui permettrait une vérification automatique du résultat fourni par l'algorithme. Voici ce que j'ai fait à partir de ce document. Ce sont les dates de Pâques de 1900 à 2199.
NDLM : Supprimé à la demande de l'auteur
Vos observations ou vos suggestions sont les bienvenues. :)
Bonjour !
J'ai remanié mon programme, qui calcule la date de Pâques pour une année donnée du calendrier grégorien. Qu'en pensez-vous ?
Code:
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 /* table.c */ /* Date de Pâques 1900-2199 */ const int table[300] = { 46,38,30,43,34,54,46,31,50,42, 27,47,38,23,43,35,54,39,31,51, 35,27,47,32,51,43,35,48,39,31, 51,36,27,47,32,52,43,28,48,40, 24,44,36,56,40,32,52,37,28,48, 40,25,44,36,49,41,32,52,37,29, 48,33,53,45,29,49,41,26,45,37, 29,42,33,53,45,30,49,41,26,46, 37,50,42,34,53,38,30,50,34,26, 46,31,50,42,34,47,38,30,43,35, 54,46,31,51,42,27,47,39,23,43, 35,55,39,31,51,36,27,47,32,52, 43,35,48,40,31,51,36,28,47,32, 52,44,28,48,40,25,44,36,56,41, 32,52,37,29,48,40,25,45,36,49, 41,33,52,37,29,49,33,53,45,30, 49,41,26,46,37,29,42,34,53,45, 30,50,41,26,46,38,50,42,34,54, 38,30,50,35,26,46,31,51,42,34, 47,39,30,43,35,55,46,31,51,43, 28,48,40,25,44,36,49,41,32,52, 37,29,48,33,53,45,29,49,41,26, 45,37,29,42,33,53,45,30,49,41, 26,46,37,50,42,34,53,38,30,50, 34,26,46,31,50,42,34,47,38,30, 43,35,54,46,31,51,42,27,47,39, 23,43,35,55,39,31,51,36,27,47, 32,52,43,35,48,40,31,51,36,28, 47,32,52,44,28,48,40,25,44,36, 56,41,32,52,37,29,48,40,25,45};
Code:
1
2
3 /* paques.h */ extern const int table[300];
Au modérateur : Auriez-vous l'amabilité de supprimer mes deux premiers messages (si toutefois vous n'y voyez pas d'inconvénient) ? :)Code:
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 /* paques.c */ /* Date du dimanche de Pâques Algorithme d'Oudin : http://www.fil.univ-lille1.fr/~wegrzyno/portail/InitProg/Doc/TP/TP6/tp6.pdf Table des dates de Pâques de 1900 à 2199 : http://www.merlyn.demon.co.uk/estr-tbl.txt */ #include <stdio.h> #include "table.c" #include "paques.h" #define GREGORIEN 1583 const char *nom[] = {"mars", "avril"}; int resultat(int annee){ /* Algorithme d'Oudin */ int G, C, C4, E, H, K, P, Q, I, B, J1, J2, R; G = annee % 19; C = annee / 100; C4 = C / 4; E = (8 * C + 13) / 25; H = (19 * G + C - C4 - E + 15) % 30; K = H / 28; P = 29 /(H + 1); Q = (21 - G) / 11; I = (K * P * Q - 1) * K + H; B = (annee / 4) + annee; J1 = B + I + 2 + C4 - C; J2 = J1 % 7; R = 28 + I - J2; return R; } int main(void){ int annee, mois, jour; int paques; printf("Date du dimanche de Pques dans le calendrier grgorien\n"); annee = 0; while(annee < GREGORIEN){ printf("Veuillez entrer une anne postrieure 1582 : "); scanf("%d", &annee); } paques = resultat(annee); if(paques > 31){ mois = 4; jour = paques - 31; }else{ mois = 3; jour = paques; } if ((annee > 1899) && (annee < 2200)){ if (paques != table[annee - 1900]){ printf("Le rsultat ne concorde pas avec le contenu de la table.\n"); } } printf("En %d, le dimanche de Pques est le %d %s.\n", annee, jour, nom[mois - 3]); return 0; }
Au risque d’être (trop) critique, j'ai pas mal de remarques a faire sur le code...
Je prends le code "au fur et a mesure" :
#include "table.c" Pas fan de l'include du .c... Surtout que ce "code" qui n'en est pas pourrait tout a fait être dans un fichier d'include. Mais bon, comme c'est juste pour la vérification, on peut passer :)
int Resultat(int a){ Pourquoi mettre une majuscule au nom de la fonction ? Je sais que ce n'est pas faux, mais en général on ne le fait pas (la norme définit d'ailleurs que E suivi d'une lettre majuscule ou d'un chiffre peut être utilise comme macro par l’implémentation pour les erreurs (norme C99, 7.5 et 7.26.3)
int G, C, C4, E, H, K, P, Q, I, B, J1, J2, R; Je vais être méchant, mais tu n'as pas trouvé plus illisible ? Je pense que A1, A2, ... serait mieux... Ou pas. Par contre, de vrais noms de variable, en minuscules, ça serait vraiment bien.
Un petit commentaire sur ces magnifiques nombres magiques sortis de null part ? S'il faut le PDF décrivant l'algorithme pour pouvoir comprendre le code, je crains que ce ne soit pas très pratique.Code:
1
2
3
4
5
6
7 G = a % 19; C = a / 100; C4 = C / 4; E = (8 * C + 13) / 25; H = (19 * G + C - C4 - E + 15) % 30; [...]
a, m, j --> annee, mois, jour, comme tu le mets dans le commentaire, et comme paques. Il ne faut pas avoir peur d'user les touches de son clavier, elles sont la pour ca ! :)Code:
1
2
3 int a, m, j; /* annee, mois, jour */ int paques;
Il est plus que fortement déconseillé de lire les entrées clavier avec scanf, qui devrait être réservé aux entrées formatées. Un exemple d’entrées/sorties solides en C.Code:
1
2
3
4 while(a < GREGORIEN){ printf("Veuillez entrer une annee postrieure 1582 : "); scanf("%d", &a); }
Je pense qu'on aurait apprécié d'avoir les deux dates dans ce cas d'erreur :)Code:
1
2
3
4 if ((a > 1899) && (a < 2200)){ if (paques != table[a - 1900]){ printf("Le resultat ne concorde pas avec le contenu de la table.\n");
Désolé, c'est peut-être un peu violent comme commentaire, mais trouve que ce code est vraiment "limite".
Merci pour ces observations, dont je prends bonne note. :)
Pour le fichier inclus, je n'ai pas compris quelle est la solution que tu préconises.
Autrement, pour remplacer ces noms de variables
par des noms plus explicites, il faudrait des connaissances que je n'ai pas. J'avoue que j'ai utilisé la formule sans la comprendre. C'est pourquoi j'ai préféré me tenir aux noms de variables qui sont dans le document auquel je me suis référé.Code:int G, C, C4, E, H, K, P, Q, I, B, J1, J2, R;
En fait, on n'inclue pas de fichier .c (meme si techniquement il est possible de le faire).
Un fichier .c est un fichier qui contient du code, qui doit etre compilable tout seul, obtenant en sortie (au moins) un fichier objet (.o), qui pourra etre linke plus tard si besoin.
Dans ton cas, le seul code que tu mets est un tableau, pas de code. Donc tu peux tout a fait faire de ce fichier un fichier d'en-tete (.h), et dans ce cas tu pourras l'inclure. C'est ce que je ferai (ou ce que je recommande, mais qui suis-je pour recommander :) ? )
Il y a le problème du extern.
En fait, c'est bien un .c, parce que le tableau ne saurait être défini plusieurs fois.
Par contre, il manque un en-tête contenant un extern const int table[300];
Je ne suis pas d'accord : si tu inclues plusieurs fois ton fichier d'en-tête dans des unités de compilation différentes, tu auras une erreur d'édition des liens car le symbole sera défini plusieurs fois ! Une déclaration avec initialisation de tableau, c'est déjà du code.Citation:
Dans ton cas, le seul code que tu mets est un tableau, pas de code
EDIT : j'ai mis très longtemps à poster donc leternel m'a grillé ^^
Merci pour vos conseils. J'ai édité mon message et fait une partie des modifications suggérées.