OVH Cloud OVH Cloud

return dans un switch case

90 réponses
Avatar
Albert
Bonjour a tous,
Mon probleme est dans le titre.
J'ai un switch case et a l'interieur est il "permis" de sortir d'un
case par un return ( le switch case est bien sur dans une fonction)
A la compile ( gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5))
je n'ai aucun message d'avertissement. Mais je voudrais etre sur que
c'est correcte. Rien vu a ce sujet.
Merci de vos reponses.
gil

10 réponses

Avatar
Pierre Maurette
[...]
tres juste. En fait j'avais repris un prog datant de ... bien longtemps.
L'algèbre de Boole est antérieure à nos petits problèmes de bits ;-)


[...]
case janvier:
case mars:
case mai:
case juillet:
case aout:
case octobre:
case decembre:
retour = !((day > 31) || (day < 0));
break;
case avril:
case juin:
case novembre:
retour = !((day > 30) || (day < 0));
break;
case fevrier:
/* à faire */
break;
case septembre:
/* à faire */
break;
default:
/* mois pas bon */

La je ne vois pas bien. Le test sur le mois c'est pas trop le but.

Le code ne teste pas les mois, mais bien les jours, dans le contexte

des mois. Ça correspond en langage courant à "En janvier, mars, mai,
..., je vérifie que day n'est pas plus grand que 31, en avril, mai,
..., je teste etc."
Pour l'année, elle rentre mal dans la structure, elle fait surtout
chier. Disons que bissextile et gregoire doivent êtr vus comme des
flags qui seront utiliés dans les cas respectivement février et
septembre, et eux seuls.
Le cerveau humain doit avoir une grosse composante parallèle, ou faire
des comparaisons visuelles "câblées". Si on vous montre "35 avril
1935", pour ne passerez pas par une analyse pour conclure à
l'invalidité. L'ordinateur est beaucoup plus con. Il suivra son unique
processus pseudo mental

Janvier, mars, mai,etc rien a dire. Des case sans reelle utilite ?
Non. Les case enchaines signifient que plusieurs "cas" seront traités

par le même bloc de code. Donc là il y a un traitement pour les mois de
31 jours, un autre pour les mois de 30 jours, un autre pour février et
un autre pour septembre.

seuls les jours 29,30,31 sont a tester.
C'est votre point de départ. C'est certainement jouable.


Bon, je vous propose un machin. J'ai jeté un oeil sur Google pour cette
histoire de Gregoire. Je traite l'énoncé suivant : "en 1582, le
lendemain du 4 octobre fut le 15 octobre (10 jours sont passés à la
trappe)". C'est un peu plus compliqué à traiter, mais sans plus.
http://perso.easynet.fr/~cerf/calendar/calendar.htm

J'ai pris des unsigned pour simplifier le code.

enum mois {janvier, fevrier, mars, avril, mai, juin, juillet, aout,
septembre, octobre, novembre, decembre, fevbissext};

const unsigned int MaxJours[] = {31, 28, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31, 29};

#define div4(y) ((y)%4 == 0)
#define div100(y) ((y)%100 == 0)
#define div400(y) ((y)%400 == 0)

#define isBissextile(y) ( div4(y) && ( !div100(y) || div400(y) ) )

#define isBadGreg(y, m, d) ( ( (y) == 1582 ) && ( m == octobre) && ( d >
4 ) && ( d < 15 ) )

int SaisieValide(unsigned int day, unsigned int month, unsigned int
year)
{
unsigned int mois = month -1;
if(isBissextile(year) && (mois == fevrier)) mois = fevbissext;
return (day <= MaxJours[mois]) && !isBadGreg(year, mois, day);
}

J'ai paramétré les macros, mais ce n'étais pas indispensable dans le
cadre de la fonction.

J'ai renommé la fonction pour que son nom indique le sens de la
réponse.

--
Pierre Maurette


Avatar
Harpo
Albert wrote:

Ce programme, meme mal foutu fonctionne tres coreectement sauf pour
les dates du 3 sept 1752 au 31 dec 1752.


Ca fait quand même presque 4 mois. Il faut bien indiquer la clause de
non garantie avant la livraison du programme, sinon tu risques d'avoir
à payer les journées d'incapacité de travail pour les jours que tu n'a
pas trouvé.

Le reste : les mois en r , etant de la rochelle je connais ainsi que
les mollusques qui vont avec...
Brest connasi pas


C'est la base pour les horaires des marées, sinon il faut vraiment être
brestois pour aimer.

La question que je me pose est : pourquoi écrire ce genre de fonction
qui est pleine de pièges ? On doit trouver pas mal de bibliothèques qui
la proposent, si c'est pour le plaisir je veux bien mais moi il
faudrait me payer cher pour que je ne trouve pas soporifique ces
problèmes.

Avatar
Albert
[...]

tres juste. En fait j'avais repris un prog datant de ... bien longtemps.


L'algèbre de Boole est antérieure à nos petits problèmes de bits ;-)


Certainement, mais ce n'etait pas le but.
je ne cherchais pas a ameliorer l'algo ( je n'aurais pas repris tel quel
l'ancien) mais a avoir un code C qui soit correct en utilisant les
operateurs, expressions etc .. du C pour me remettre dans le bain : le
cas des return dans le switch case me posaient probleme.

[...]

Bon, je vous propose un machin. J'ai jeté un oeil sur Google pour cette
histoire de Gregoire. Je traite l'énoncé suivant : "en 1582, le
lendemain du 4 octobre fut le 15 octobre (10 jours sont passés à la
trappe)". C'est un peu plus compliqué à traiter, mais sans plus.
http://perso.easynet.fr/~cerf/calendar/calendar.htm


En fait 1582 c'est pour la france. L'usage international voudrait que le
2 sept 1752 soit suivi du 14 sept 1752. Mais c'est pas trop le Pb....
Faire un cal 1582 / unix ou linux montre la main-mise anglo saxonne.

J'ai pris des unsigned pour simplifier le code.

enum mois {janvier, fevrier, mars, avril, mai, juin, juillet, aout,
septembre, octobre, novembre, decembre, fevbissext};

const unsigned int MaxJours[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31, 29};

#define div4(y) ((y)%4 == 0)
#define div100(y) ((y)%100 == 0)
#define div400(y) ((y)%400 == 0)

#define isBissextile(y) ( div4(y) && ( !div100(y) || div400(y) ) )

#define isBadGreg(y, m, d) ( ( (y) == 1582 ) && ( m == octobre) && ( d
4 ) && ( d < 15 ) )


int SaisieValide(unsigned int day, unsigned int month, unsigned int year)
{
unsigned int mois = month -1;
if(isBissextile(year) && (mois == fevrier)) mois = fevbissext;
return (day <= MaxJours[mois]) && !isBadGreg(year, mois, day);
}

J'ai paramétré les macros, mais ce n'étais pas indispensable dans le
cadre de la fonction.

J'ai renommé la fonction pour que son nom indique le sens de la réponse.



Ca, avec votre permission, je le garde precieusement sous la main :-)
Merci et a bientot,
gil


Avatar
Albert
Albert wrote:


Ce programme, meme mal foutu fonctionne tres coreectement sauf pour
les dates du 3 sept 1752 au 31 dec 1752.



Ca fait quand même presque 4 mois. Il faut bien indiquer la clause de
non garantie avant la livraison du programme, sinon tu risques d'avoir
à payer les journées d'incapacité de travail pour les jours que tu n'a
pas trouvé.


j'aime :-)


Le reste : les mois en r , etant de la rochelle je connais ainsi que
les mollusques qui vont avec...
Brest connasi pas



C'est la base pour les horaires des marées, sinon il faut vraiment être
brestois pour aimer.



Pour avoir naviguer pendant une quinzaine d'annees ( surtout en
atlantique sinon bien plus loin ) j'avoue que je me suis plus interesse
au calcul de position qu'aux horaires de marees ( sinon celles de
granville avec un record de marnage !! ) y avait pas de GPS .. Au
sextant mon petit.
je suis plus accoutume aux HO249 et a ma precieuse calculatrice HP 41
que j'avais programme pour les calculs.

La question que je me pose est : pourquoi écrire ce genre de fonction
qui est pleine de pièges ? On doit trouver pas mal de bibliothèques qui
la proposent, si c'est pour le plaisir je veux bien mais moi il
faudrait me payer cher pour que je ne trouve pas soporifique ces
problèmes.


C'est un programme comme un autre pour reapprendre les bases du C. Ma

question n'a jamais porte sur le programme lui meme mais sur la syntaxe
employee. Tout a fait different :-)

Mettez vous a l'abri ca va "buffer" !!!
A+
gil


Avatar
Emmanuel Delahaye
"Pierre Maurette" a écrit dans le message de news:

retour = qqchose;
break; /* un goto qui fait sa chochote */


Oui, de même que 'switch' est une succession de 'if ... goto ...', relooké.


Un if else aussi... La question n'est pas là.

--
A+

Emmanuel Delahaye


Avatar
Emmanuel Delahaye
"TERENCE" writes:


"Pierre Maurette" a écrit dans le message de news:

retour = qqchose;
break; /* un goto qui fait sa chochote */


Oui, de même que 'switch' est une succession de 'if ... goto ...', relooké.



Les switch sont des goto table[i].


Ca dépend des valeurs. Si elles sont classées et qu'il y a une relation
évidente, oui (un enum aide bien..), sinon, c'est plutôt du if else if
..., voire un lookup dans une table (C51)

Ces histoires d'implémentation ne nous interesse pas.

--
A+

Emmanuel Delahaye



Avatar
Emmanuel Delahaye
if (year == Gregoire && month == 9 && day > 2)


N'hésitez pas à sur-parenthéser


Totalement inutile ici.

if (( year%4 == 0 && year%100 != 0) || (year%4 ==0 && (year%100
== 0 && year%400 == 0)))


Ça se simplifie. Déjà :
(year%100 == 0 && year%400 == 0)
c'est
(year%400 == 0)
puisque (year%400 == 0) => (year%100 == 0)
;-)


La formule reconnue est celle-ci :

http://docs.mandragor.org/files/Programming_languages/C/clc_faq_en/C-faq/q20.32.html

--
A+

Emmanuel Delahaye


Avatar
Pierre Maurette
[...]
Ces histoires d'implémentation ne nous interesse pas.
C'est ce qu'en géopolitique on appelle un "accord de proximité" ?


--
Pierre Maurette

Avatar
Pierre Maurette
if (year == Gregoire && month == 9 && day > 2)


N'hésitez pas à sur-parenthéser


Totalement inutile ici.
Totalement inutile ici.



if (( year%4 == 0 && year%100 != 0) || (year%4 ==0 && (year%100 ==
0 && year%400 == 0)))


Ça se simplifie. Déjà :
(year%100 == 0 && year%400 == 0)
c'est
(year%400 == 0)
puisque (year%400 == 0) => (year%100 == 0)
;-)


La formule reconnue est celle-ci :

http://docs.mandragor.org/files/Programming_languages/C/clc_faq_en/C-faq/q20.32.html
Elle était deux lignes en dessous dans le message auquel tu réponds.

Encore abusé de substances ce soir ?

Si on a des raisons de penser que "de nombreuses" requêtes concerneront
une date en 2000 :
(year % 400 == 0 || year % 100 != 0) && year % 4 == 0
sera plus performant.
S'il on a des raisons de penser qu'il s'agira d'une date "autour de
2000", il faudra faire:
year % 4 == 0 && (year % 400 == 0 || year % 100 != 0)

--
Pierre Maurette



Avatar
Harpo
Albert wrote:


Pour avoir naviguer pendant une quinzaine d'annees ( surtout en
atlantique sinon bien plus loin ) j'avoue que je me suis plus
interesse au calcul de position qu'aux horaires de marees ( sinon
celles de granville avec un record de marnage !! ) y avait pas de GPS
.. Au sextant mon petit.


C'est vrai que lorsqu'on ne voit plus la côte, l'horaire des marées et
l'emploi du temps des bigornaux...

Granville, je connais aussi, un joli petit port, j'y ai passé un certain
temps sur la pointe.

C'est un programme comme un autre pour reapprendre les bases du C. Ma
question n'a jamais porte sur le programme lui meme mais sur la
syntaxe employee. Tout a fait different :-)


Je me permets de récidiver.
La nature ou je ne sais qui ou quoi m'a affublé d'un esprit analytique
et je pense qu'il faut séparer les problèmes.
Les problèmes de dates sont très compliqués voire excessivement chiants
pour le commun des mortels, prendre en même temps 2 niveaux de
complexité n'additionne pas mais multiplie la complexité.

En gros, si on veut essayer un langage, on implémente un algorithme ou
un quelconque truc que l'on connait bien, si on veut tester un
algorithme on prend un langage que l'on connait bien.

Séparer les problèmes permet de mieux les appréhender et de limiter la
confusion.

De plus, ta question ne portait pas vraiment sur la syntaxe (bien que
return soit une instruction) mais plus sur la sémantique. Le fait que
le compilateur ne donne même pas un warning montre que ta construction
est syntaxiquement correcte ou que ton compilateur est à foutre à la
poubelle.
Le problème vient du fait que programmer ne consiste pas à écrire des
programmes syntaxiquement corrects.