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

1 2 3 4 5
Avatar
Antoine Leca
In news:, Pierre Maurette va escriure:
Les switch sont des goto table[i].
case INT_MAX:



Oui, et on a déjà vu des compilateurs générer des tables hallucinantes dans
ce cas-là.


Antoine


Avatar
Jean-Marc Bourguet
"Antoine Leca" writes:

In news:, Pierre Maurette va escriure:
Les switch sont des goto table[i].
case INT_MAX:



Oui, et on a déjà vu des compilateurs générer des tables hallucinantes dans
ce cas-là.


Tant qu'ils arrivaient a generer un executable fonctionnant
correctement sans que la chaine ne plante quelque part, ils n'etaient
pas si mauvais que ca :-)

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org



Avatar
Albert
Albert wrote:


En fait je voulais eviter les if imbriques ou avoir une autre variable
a l'interieur de la fonction ( ce qui faciltait d'un cote mais
alourdissait de l'autre). Mon probleme etait de savoir si le return
dans un switch respectait la norme (vu que je n'ai pas de warning).
C'est une fonction hyper simple de verification des dates entrees pour
le calendrier.



Si la fonction est simple ou courte ( tient sur un écran et sera peu
susceptible d'être allongée ), cela se conçoit.
C'est même un souvent un bon choix pour une fonction de contrôle qui
renvoie 0 ou un code d'erreur, cela peut permettre d'éviter les
cascades de if{}else{} imbriqués qui deviennent illisibles dès qu'ils
dépassent une page d'écran - i.e. 25 lignes 80 colonnes -


C'etait ma demarche.


C'est mon premier prg depuis une 15iene d'annees donc soyez
indulgents. Il fonctionne correctement :-)



Je ne demande qu'à te croire, mais on ne peut dire qu'un programme
fonctionne sinon pour les essais que l'on a effectués dans les
circonstances où on les a effectués dans la mesure où on ne s'est pas
trompé en vérifiant les résultats.

Surtout les problèmes de date, c'est compliqué.



Remarque oh ! combien justifiee.
j'avais juste "oublie" que fevrier n'a pas 30 jours !!

A bientot
gil


Avatar
Albert

Albert wrote:


En fait je voulais eviter les if imbriques ou avoir une autre variable
a l'interieur de la fonction ( ce qui faciltait d'un cote mais
alourdissait de l'autre). Mon probleme etait de savoir si le return
dans un switch respectait la norme (vu que je n'ai pas de warning).
C'est une fonction hyper simple de verification des dates entrees pour
le calendrier.




Si la fonction est simple ou courte ( tient sur un écran et sera peu
susceptible d'être allongée ), cela se conçoit.
C'est même un souvent un bon choix pour une fonction de contrôle qui
renvoie 0 ou un code d'erreur, cela peut permettre d'éviter les
cascades de if{}else{} imbriqués qui deviennent illisibles dès qu'ils
dépassent une page d'écran - i.e. 25 lignes 80 colonnes -



C'etait ma demarche.



C'est mon premier prg depuis une 15iene d'annees donc soyez
indulgents. Il fonctionne correctement :-)




Je ne demande qu'à te croire, mais on ne peut dire qu'un programme
fonctionne sinon pour les essais que l'on a effectués dans les
circonstances où on les a effectués dans la mesure où on ne s'est pas
trompé en vérifiant les résultats.



Surtout les problèmes de date, c'est compliqué.




Remarque oh ! combien justifiee.
j'avais juste "oublie" que fevrier n'a pas 30 jours !!

A bientot
gil


Re,
Pour etre bien sur de ce que vous dites je mets les simples lignes de
code.
Je voulais un code clair. Toutes critiques sont les bienvenues.

int test_saisie( int day, int month, int year )
{
/* cas special de l'annee et mois du changement : on retourne Faux (
+ tard) */
if (year == Gregoire && month == 9 && day > 2)
{
printf("nAttention annee, mois et jour >2 du passage Julien ->
Gregorien !n");
printf("---------> On verra plus tard <--------------nn");
return(Faux);
}

/* c'est un 29 non fevrier donc saisie plausible = Vrai */
if ((day == 29 ) && ( month != 2))
return(Vrai);

switch (day)
{
case 29:
if (( year%4 == 0 && year%100 != 0) || (year%4 ==0 && (year%100
== 0 && year%400 == 0)))
{
printf("nL'annee %d est bien Bissextille !!nn",year);
return(Vrai);
}
else
{
printf("nAnnee non bissextille !!nn");
return(Faux);
}

case 30:
if ( day == 30 && month == 2)
{
printf("n Le mois de %s n'a pas 30 jours !!!nn",t_mois[month-1]);
return(Faux);
}

case 31:
if ((month == 2) || (month == 4) || (month == 6) || (month == 9)
|| (month =))
{
printf("nLe mois de %s n'a pas 31 jours !!!nn",t_mois[month-1]);
return(Faux);
}
}
/* les autres cas sont ok */
return(Vrai);
}



Avatar
Harpo
Albert wrote:

Surtout les problèmes de date, c'est compliqué.



Remarque oh ! combien justifiee.
j'avais juste "oublie" que fevrier n'a pas 30 jours !!


Janvier non plus, et lorsque l'on quitte les mois 'en r' peu propices au
mollusques, ils n'entrent pas dans le même moule.
Il y a bien sûr le problème des années bissextiles, ce qui peut être
assez facilement résolu, mais si tu reçois un email d'avant les
calendriers Grégoriens, Juliens etc. comment faire pour le classer dans
ta mailbox ?
Mettons que le prophête Muhammad (béni soit son nom) t'envoie un email
de la premoère année de l'hégire, déjà on se demande si c'est l'année 0
ou 1, ensuite il faut se demander si son heure est UTC ou non, si le
mois de ramadan fait 27, 28 ou 29 jours...
Laisse tomber ! C'est trop compliqué.
Commence par des programmes simples sur la précession des équinoxes et
les horaires et coefficients des marées à Brest.


Avatar
Pierre Maurette
[...]
Pour etre bien sur de ce que vous dites je mets les simples lignes de code.
Je voulais un code clair. Toutes critiques sont les bienvenues.

int test_saisie( int day, int month, int year )
{
/* cas special de l'annee et mois du changement : on retourne Faux ( +
tard) */
if (year == Gregoire && month == 9 && day > 2)
N'hésitez pas à sur-parenthéser



{
printf("nAttention annee, mois et jour >2 du passage Julien ->
Gregorien !n");
printf("---------> On verra plus tard <--------------nn");
return(Faux);
}

/* c'est un 29 non fevrier donc saisie plausible = Vrai */
if ((day == 29 ) && ( month != 2))
return(Vrai);

switch (day)
{
case 29:
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)
;-)

Le total :
Divisible par 4 ET (pas divisible par 100 OU divisible par 400)
year%4 == 0 && (year%100 != 0 || year%400 == 0)


{
printf("nL'annee %d est bien Bissextille !!nn",year);
return(Vrai);
}
else
{
printf("nAnnee non bissextille !!nn");
return(Faux);
}

case 30:
if ( day == 30 && month == 2)
Pas satisfaisant. Inattention, certainement.



{
printf("n Le mois de %s n'a pas 30 jours !!!nn",t_mois[month-1]);
return(Faux);
}

case 31:
if ((month == 2) || (month == 4) || (month == 6) || (month == 9)
|| (month =))
{
printf("nLe mois de %s n'a pas 31 jours !!!nn",t_mois[month-1]);
return(Faux);
}
}
/* les autres cas sont ok */
return(Vrai);
}


Franchement, je ne suis pas emballé.
Pour l'instant, le problème return or not return est secondaire, mais
je comprends mieux votre question ;-)
L'approche manque d'homogénéité. Pour parler comme à la radio, on ne
perçoit pas immédiatement le projet. Pourquoi aps un seul case sur le
mois ? une enum rendrait les choses plus jolies. Vous auriez en partie:

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 */

Ce n'est pas du tout optimisé, mais pour un contrôle de saisie, on s'en
tape. Il faudrait savoir quelles saisies on attend le plus souvent, et
pifométrer les erreurs les plus fréquentes. Ça dépend aussi de l'énoncé
de l'exo ;-)

Ça c'est une solution 100% cas par cas. On doit pouvoir envisager une
solution 100% logique, mais la gageure est de la rendre non-nouillesque
et lisible. Je verrai peut-être ça après la sangria.

--
Pierre Maurette

Avatar
Albert
Albert wrote:

Surtout les problèmes de date, c'est compliqué.



Remarque oh ! combien justifiee.
j'avais juste "oublie" que fevrier n'a pas 30 jours !!



Janvier non plus, et lorsque l'on quitte les mois 'en r' peu propices au
mollusques, ils n'entrent pas dans le même moule.
Il y a bien sûr le problème des années bissextiles, ce qui peut être
assez facilement résolu, mais si tu reçois un email d'avant les
calendriers Grégoriens, Juliens etc. comment faire pour le classer dans
ta mailbox ?
Mettons que le prophête Muhammad (béni soit son nom) t'envoie un email
de la premoère année de l'hégire, déjà on se demande si c'est l'année 0
ou 1, ensuite il faut se demander si son heure est UTC ou non, si le
mois de ramadan fait 27, 28 ou 29 jours...
Laisse tomber ! C'est trop compliqué.
Commence par des programmes simples sur la précession des équinoxes et
les horaires et coefficients des marées à Brest.

????


Ce programme, meme mal foutu fonctionne tres coreectement sauf pour les
dates du 3 sept 1752 au 31 dec 1752.
Le reste : les mois en r , etant de la rochelle je connais ainsi que les
mollusques qui vont avec...
Brest connasi pas
gil



Avatar
Targeur fou
Albert wrote:

Bonsoir,


[coupé]


Re,
Pour etre bien sur de ce que vous dites je mets les simples lignes de
code.
Je voulais un code clair. Toutes critiques sont les bienvenues.

int test_saisie( int day, int month, int year )


Si aucun des arguments n'est (ne doit être) modifié dans la fonction,
le préciser pour M. le compilateur, il en sera ravi et ralera si
jamais il y a tentative de modif.

int test_saisie( const int day, const int month, const int year )

{

/* cas special de l'annee et mois du changement : on retourne Faux (
+ tard) */
if (year == Gregoire && month == 9 && day > 2)
{
printf("nAttention annee, mois et jour >2 du passage Julien ->
Gregorien !n");
printf("---------> On verra plus tard <--------------nn");


En C de nos jours, un truc de chouette, c'est la "concaténation
automatique" de chaînes constantes. Ainsi, tu peux écrire :

printf("nAttention annee, mois et jour >2 du passage Julien ->
Grégorien ! n"
"---------> On verra plus tard <--------------nn");

Ca économise un appel :-)

return(Faux);



}

/* c'est un 29 non fevrier donc saisie plausible = Vrai */
if ((day == 29 ) && ( month != 2))
return(Vrai);

switch (day)
{
case 29:
if (( year%4 == 0 && year%100 != 0) || (year%4 ==0 && (y ear%100
== 0 && year%400 == 0)))
{
printf("nL'annee %d est bien Bissextille !!nn",year);
return(Vrai);
}
else
{
printf("nAnnee non bissextille !!nn");
return(Faux);
}

case 30:
if ( day == 30 && month == 2)
{
printf("n Le mois de %s n'a pas 30 jours !!!nn",t_mois[month-1]);
return(Faux);
}

case 31:
if ((month == 2) || (month == 4) || (month == 6) || ( month == 9)
|| (month =))
{
printf("nLe mois de %s n'a pas 31 jours !!!nn",t_mois[month-1]);
return(Faux);
}
}
/* les autres cas sont ok */
return(Vrai);
}


Bon, bah perso je ne touve pas terrible les return dans un switch (voir
le thread d'à côté) mais ça passe encore pour une petite fonction
comme celle-ci.

A+
Regis

Avatar
Albert
[...]

Pour etre bien sur de ce que vous dites je mets les simples lignes
de code.
Je voulais un code clair. Toutes critiques sont les bienvenues.

int test_saisie( int day, int month, int year )
{
/* cas special de l'annee et mois du changement : on retourne Faux
( + tard) */
if (year == Gregoire && month == 9 && day > 2)


N'hésitez pas à sur-parenthéser
oui c'est vrai un defaut de ma part.




{
printf("nAttention annee, mois et jour >2 du passage Julien ->
Gregorien !n");
printf("---------> On verra plus tard <--------------nn");
return(Faux);
}

/* c'est un 29 non fevrier donc saisie plausible = Vrai */
if ((day == 29 ) && ( month != 2))
return(Vrai);

switch (day)
{
case 29:
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)
;-)

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



Le total :
Divisible par 4 ET (pas divisible par 100 OU divisible par 400)
year%4 == 0 && (year%100 != 0 || year%400 == 0)



Beaucoup + mathematique correct :-)

{
printf("nL'annee %d est bien Bissextille !!nn",year);
return(Vrai);
}
else
{
printf("nAnnee non bissextille !!nn");
return(Faux);
}

case 30:
if ( day == 30 && month == 2)


Pas satisfaisant. Inattention, certainement.


{
printf("n Le mois de %s n'a pas 30 jours
!!!nn",t_mois[month-1]);
return(Faux);
}

case 31:
if ((month == 2) || (month == 4) || (month == 6) || (month == 9)
|| (month =))
{
printf("nLe mois de %s n'a pas 31 jours !!!nn",t_mois[month-1]);
return(Faux);
}
}
/* les autres cas sont ok */
return(Vrai);
}



Franchement, je ne suis pas emballé.
Pour l'instant, le problème return or not return est secondaire, mais
je comprends mieux votre question ;-)


en fait c'etait le but du fil.

L'approche manque d'homogénéité. Pour parler comme à la radio, on ne
perçoit pas immédiatement le projet.


C'est juste une fonction de test sur le JOUR de saisie c'est tout.

Pourquoi aps un seul case sur le
mois ? une enum rendrait les choses plus jolies. Vous auriez en partie:

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.

Janvier, mars, mai,etc rien a dire. Des case sans reelle utilite ?
seuls les jours 29,30,31 sont a tester.

Ce n'est pas du tout optimisé, mais pour un contrôle de saisie, on s'en
tape. Il faudrait savoir quelles saisies on attend le plus souvent, et
pifométrer les erreurs les plus fréquentes. Ça dépend aussi de l'énoncé
de l'exo ;-)

Ça c'est une solution 100% cas par cas. On doit pouvoir envisager une
solution 100% logique, mais la gageure est de la rendre non-nouillesque
et lisible. Je verrai peut-être ça après la sangria.



et moi apres le souper.
Merci
A+
gil


Avatar
Albert
Albert wrote:

Bonsoir,


[coupé]


Re,
Pour etre bien sur de ce que vous dites je mets les simples lignes de
code.
Je voulais un code clair. Toutes critiques sont les bienvenues.

int test_saisie( int day, int month, int year )



Si aucun des arguments n'est (ne doit être) modifié dans la fonction,
le préciser pour M. le compilateur, il en sera ravi et ralera si
jamais il y a tentative de modif.

int test_saisie( const int day, const int month, const int year )


{



/* cas special de l'annee et mois du changement : on retourne Faux (
+ tard) */
if (year == Gregoire && month == 9 && day > 2)
{
printf("nAttention annee, mois et jour >2 du passage Julien ->
Gregorien !n");
printf("---------> On verra plus tard <--------------nn");



En C de nos jours, un truc de chouette, c'est la "concaténation
automatique" de chaînes constantes. Ainsi, tu peux écrire :

printf("nAttention annee, mois et jour >2 du passage Julien ->
Grégorien ! n"
"---------> On verra plus tard <--------------nn");

Ca économise un appel :-)


suis preneur :-)



return(Faux);




}

/* c'est un 29 non fevrier donc saisie plausible = Vrai */
if ((day == 29 ) && ( month != 2))
return(Vrai);

switch (day)
{
case 29:
if (( year%4 == 0 && year%100 != 0) || (year%4 ==0 && (year%100
== 0 && year%400 == 0)))
{
printf("nL'annee %d est bien Bissextille !!nn",year);
return(Vrai);
}
else
{
printf("nAnnee non bissextille !!nn");
return(Faux);
}

case 30:
if ( day == 30 && month == 2)
{
printf("n Le mois de %s n'a pas 30 jours !!!nn",t_mois[month-1]);
return(Faux);
}

case 31:
if ((month == 2) || (month == 4) || (month == 6) || (month == 9)
|| (month =))
{
printf("nLe mois de %s n'a pas 31 jours !!!nn",t_mois[month-1]);
return(Faux);
}
}
/* les autres cas sont ok */
return(Vrai);
}



Bon, bah perso je ne touve pas terrible les return dans un switch (voir
le thread d'à côté) mais ça passe encore pour une petite fonction
comme celle-ci.
c'etait bien le but de mon post et de mon inquietude !!

Je crois que je vais passer par une variable locale a la fonction ???

style:

int func(day,..)
{
int variable;

switch (day)
{
case 29:
inst...
variable = Vrai
break;
case 30:
inst..
variable = Faux
break;
.....

default:
variable= ..
}
return(variable);
}


A+
Regis




1 2 3 4 5