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

5 6 7 8 9
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




Bonjour a tous,
J'ai pris note de toutes vos remarques, aussi je propose ce nouveau
code. Plus de return mais une var local retour;
Encore une fois peu importe l'algo ( bien que la remarque de Charlie
Gordon pose pour moi Pb) :-)


int test_jour( int day, int month, int year ) /* coherence des jours
et mois faite avant l'appel a cette fonction */
{
int retourúux; /* Faux Vrai definis + haut */

/* cas special de l'annee ( 1752 accepte mais Hors Sujet ... ) mois
& jour 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);
}

switch (day)
{
case 29:
if ( month != 2)
{
retour = Vrai;
break;
}
if ( year%4 == 0 && (year%400 == 0 || year%100 != 0)) /* 1500
?? charlie G. */
{
printf("nL'nnee %d est bien Bissextile !!nn",year);
retour = Vrai;
}
else
{
printf("nAnnee non bissextile !!nn");
retour = Faux;
}
break;

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

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]);
retour = Faux;
break;
}
/* les autres cas sont ok */
default:
retour = Vrai;
}
return(retour);
}

Je tiens a preciser que c'est toujours dans le cadre de l'utilisation du
switch case !!
( suis rentre dans la norme ?)
Bonne journee
A+
gil

Avatar
Charlie Gordon
"Albert" wrote in message
news:4395a5a5$0$18308$

Bonjour a tous,
J'ai pris note de toutes vos remarques, aussi je propose ce nouveau
code. Plus de return mais une var local retour;
Encore une fois peu importe l'algo ( bien que la remarque de Charlie
Gordon pose pour moi Pb) :-)


Effectivement, il y a toujours des problemes.

int test_jour( int day, int month, int year ) /* coherence des jours
et mois faite avant l'appel a cette fonction */
{
int retourúux; /* Faux Vrai definis + haut */


Je suppose que Faux est défini à 0 et Vrai à 1, tout autre choix serait mal venu
(certains ont essayé : ils ont eu des problèmes ;-)

Je persiste à dire qu'il FAUT tester les plages de day, month et year ici.
Le fait que tu le fasses ailleurs est anecdotique. Une fonction doit faire un
ensemble cohérent de choses pour que le cheminement du programme soit
compréhensible par le lecteur du code. Si tu appelles cette fonction test_jour,
elle devrait implémenter tous les tests pour valider que day/month/year est un
jour correct. De plus cela se fait trivialement en quelques lignes:

if (day < 1 || day > 31) {
printf("jour incorrect : %dn", day);
return Faux;
}

if (month < 1 || month > 12) {
printf("mois incorrect : %dn", month);
return Faux;
}

if (year < 1) {
printf("annee incorrecte : %dn", year);
return Faux;
}

Ensuite il n'y a plus que les cas particuliers à tester.

/* cas special de l'annee ( 1752 accepte mais Hors Sujet ... ) mois
& jour 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);
}


Pourquoi définir Gregoire ailleurs pour l'année 1752 ? Autant mettre 1752
directement dans ce test, ce sera plus lisible.
Comme expliqué dans d'autres messages, Gregoire XIII a decidé la réforme en
1582, mais elle n'a pas été appliquée tout de suite dans toutes les régions...
le 2 sept 1752 seulement pour certains pays anglo-saxons. Cela n'a aucun sens
de définir l'annee et pas aussi le mois et les jours concernés, le lecteur
pourrait imaginer que la definition de Gregoire permet d'adapter le programme
aux différentes régions quant à la date de prise en compte de la réforme, mais
ce n'est pas le cas en l'état.

Tu peux même facilement mettre le test correct :

if (year == 1752 && month == 9 && day > 2 && day < 14) {
printf("nDate incorrecte dans la plage supprimée par la réforme du
calendrier grégorien anglo-saxon.nn");
return Faux;
}

switch (day)
{
case 29:
if ( month != 2)
{
retour = Vrai;
break;
}
if ( year%4 == 0 && (year%400 == 0 || year%100 != 0)) /* 1500
?? charlie G. */
{
printf("nL'nnee %d est bien Bissextile !!nn",year);
retour = Vrai;
}
else
{
printf("nAnnee non bissextile !!nn");
retour = Faux;
}
break;


Pourquoi mettre une majuscule à bissextile ?
Pourquoi une fois sur deux seulement ?

Voici une explication pour ma remarque concernant 1500 qui te pose problème :
Ton test pour les années bissextiles est faux pour certaines années antérieures
à 1752 : les siècles avant 1752 sont tous bissextiles puisque c'est le
calendrier Julien qui était en vigueur alors (je passe sur les détails sordides
concernant le passage du 1er mars au 1er janvier pour le début de l'année, et
les imprécisions concernant la date de prise en compte effective de la réforme
de Jules César et d'Auguste...)

Il faut un peu compliquer la formule comme ceci :

if (year % 4 == 0 && (year <= 1752 || year % 400 == 0 || year % 100 != 0)) {
// annee bissextile
} else {
// annee non bissextile dans le calendrier anglo-saxon.
}

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


Il manque toujours un break ici. Dans le cas des mois differents de 2, le code
de case 31 sera executé et donc les dates du 30 avril, 30 juin, 30 septembre et
30 novembre seront refusées à tort. Contrairement à d'autres langages, il n'y a
pas de break implicite entre les case d'un swith en C.

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]);
retour = Faux;
break;
}


Manque aussi un break ici, mais par chance sans conséquences.

/* les autres cas sont ok */
default:
retour = Vrai;


Il manque aussi un break ici, il est optionnel, mais fortement recommandé!

}
return(retour);
}

Je tiens a preciser que c'est toujours dans le cadre de l'utilisation du
switch case !!
( suis rentre dans la norme ?)


Tu étais déjà dans la norme C, mais pas dans les conventions habituelles, de
plus l'algorithme était incomplet et incorrect.
Le C est un langage piégeux, et tu est tombé dans certaines de ces
chausses-trappes à l'origine de nombreux bugs.
Pour éviter cela, il est important d'être très soigneux et d'appliquer
systématiquement les pratiques recommandées par de plus experts que toi, de
compiler avec tous les avertissements que le compilateur peut emettre et de
corriger le code pour y remédier.

Enfin évite de laisser des tabulations dans ton code, utilise des espaces pour
indenter, cela permet de préserver la présentation quelle que soit
l'environnement, comme ici où les tabs sont carrément ignorés.

--
Chqrlie.

Avatar
Antoine Leca
In news:43969de3$0$29628$,
Charlie Gordon va escriure:
"Albert" wrote in message
news:4395a5a5$0$18308$

J'ai pris note de toutes vos remarques, aussi je propose ce nouveau
code. Plus de return mais une var local retour;



Oui. Et où est la question alors ?
Il y a souvent plusieurs manières d'écrire le même code en C. Si tu veux
savoir ce que l'on pense de mettre des return dans un switch, ce n'est pas
en proposant du code _que ne le fait pas_ que tu vas faire avancer le
schimili, milichi, michili, enfin la question.



if (year < 1) {
printf("annee incorrecte : %dn", year);
return Faux;
}


<PEDANT>
year < 525 /* plus petite date crédible pour l'ère julienne _chrétienne_
*/
</PEDANT>


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


Pourquoi définir Gregoire ailleurs pour l'année 1752 ? Autant mettre
1752 directement dans ce test, ce sera plus lisible.


Tout à fait. Surtout que le fait d'utiliser une majuscule N'est PAS une
convention commune en C pour une constante, et là tu pièges tes lecteurs.


Antoine


Avatar
Pierre Maurette
[...]
Pourquoi définir Gregoire ailleurs pour l'année 1752 ? Autant mettre
1752 directement dans ce test, ce sera plus lisible.


Tout à fait. Surtout que le fait d'utiliser une majuscule N'est PAS une
convention commune en C pour une constante, et là tu pièges tes lecteurs.
Rien à voir avec les constantes en C. C'est une convention sur les noms

de papes.

Pour le code, s'il fonctionne, c'est un miracle (sur le sujet, voir les
"Dialogues de saint Grégoire le Grand sur les miracles des Pères
d'Italie"), vu la position des break.

--
Pierre Maurette


Avatar
Emmanuel Delahaye
Pour le code, s'il fonctionne, c'est un miracle (sur le sujet, voir les
"Dialogues de saint Grégoire le Grand sur les miracles des Pères
d'Italie"), vu la position des break.


Et ça se terminait souvent par un tonitruant :

"Va te faire voir chez lez Breaks..."

--
A+

Emmanuel Delahaye

Avatar
Gil
"Albert" wrote in message
news:4395a5a5$0$18308$


Bonjour a tous,
J'ai pris note de toutes vos remarques, aussi je propose ce nouveau
code. Plus de return mais une var local retour;
Encore une fois peu importe l'algo ( bien que la remarque de Charlie
Gordon pose pour moi Pb) :-)



Effectivement, il y a toujours des problemes.


int test_jour( int day, int month, int year ) /* coherence des jours
et mois faite avant l'appel a cette fonction */
{
int retourúux; /* Faux Vrai definis + haut */



Je suppose que Faux est défini à 0 et Vrai à 1, tout autre choix serait mal venu
(certains ont essayé : ils ont eu des problèmes ;-)


Esperons

Je persiste à dire qu'il FAUT tester les plages de day, month et year ici.


chacun son opînion. Je pense au contraire qu'il faut le faire au moment
de la saise. Cela evite des appels de fonctions.

Le fait que tu le fasses ailleurs est anecdotique.
Juste pour rire ? :-)


Une fonction doit faire un
ensemble cohérent
justement


de choses pour que le cheminement du programme soit
compréhensible par le lecteur du code.*


Si tu appelles cette fonction test_jour,
elle devrait implémenter tous les tests pour valider que day/month/year est un
jour correct.
Explicite SVP .

( je pense au contraire qu'il faut le faire au moment de la saise. Cela
evite des appels de fonctions.)

De plus cela se fait trivialement

Il faut eviter ce mot car chacun sait qu'il n'est que ce que l'on CROIT
savoir Je dirais par exemple une celebre phrase d'Apelle " sutor ne
supra crepidam"

en quelques lignes:

if (day < 1 || day > 31) {
printf("jour incorrect : %dn", day);
return Faux;
}

if (month < 1 || month > 12) {
printf("mois incorrect : %dn", month);
return Faux;
}

if (year < 1) {
printf("annee incorrecte : %dn", year);
return Faux;
}

Ensuite il n'y a plus que les cas particuliers à tester
?




/* cas special de l'annee ( 1752 accepte mais Hors Sujet ... ) mois
& jour 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);
}



Pourquoi définir Gregoire ailleurs pour l'année 1752 ? Autant mettre 1752
directement dans ce test, ce sera plus lisible.
T'est francais toi


Comme expliqué dans d'autres messages, Gregoire XIII a decidé la
réforme en
1582, mais elle n'a pas été appliquée tout de suite dans toutes les régions...
le 2 sept 1752 seulement pour certains pays anglo-saxons.
ok

Cela n'a aucun sens
de définir l'annee et pas aussi le mois et les jours concernés, le lecteur
pourrait imaginer que la definition de Gregoire permet d'adapter le programme
aux différentes régions quant à la date de prise en compte de la réforme, mais
ce n'est pas le cas en l'état.


La je te renvoies sans hesitations a tes etudes.

Tu peux même facilement mettre le test correct :


donne pe. pour 1500

if (year == 1752 && month
== 9 && day > 2 && day < 14) {


Repique sur le site !!!

http://www.tondering.dk/claus/cal/node3.html#SECTION00310000000000000000

printf("nDate incorrecte dans la plage supprimée par la réforme du
calendrier grégorien anglo-saxon.nn");K&R
return Faux;
}


switch (day)
{
case 29:
if ( month != 2)
{
retour = Vrai;
break;
}
if ( year%4 == 0 && (year%400 == 0 || year%100 != 0)) /* 1500
?? charlie G. */
{
printf("nL'nnee %d est bien Bissextile !!nn",year);
retour = Vrai;
}
else
{
printf("nAnnee non bissextile !!nn");
retour = Faux;
}
break;



Pourquoi mettre une majuscule à bissextile ?
Pourquoi une fois sur deux seulement ?


Oui c'est vrai j'ai pas vu dans K&R

Voici une explication pour ma remarque concernant 1500 qui te pose problème :
Ton test pour les années bissextiles est faux pour certaines années antérieures
à 1752


: les siècles avant 1752 sont tous bissextiles puisque c'est le
calendrier Julien qui était en vigueur alors (je passe sur les détails sordides
concernant le passage du 1er mars au 1er janvier pour le début de l'année, et
les imprécisions concernant la date de prise en compte effective de la réforme
de Jules César et d'Auguste...)

Il faut un peu compliquer la formule comme ceci :

if (year % 4 == 0 && (year <= 1752 || year % 400 == 0 || year % 100 != 0)) {
// annee bissextile
} else {
// annee non bissextile dans le calendrier anglo-saxon.
}


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



Il manque toujours un break ici. Dans le cas des mois differents de 2, le code
de case 31 sera executé et donc les dates du 30 avril, 30 juin, 30 septembre et
30 novembre seront refusées à tort. Contrairement à d'autres langages, il n'y a
pas de break implicite entre les case d'un swith en C.


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]);
retour = Faux;
break;
}



Manque aussi un break ici, mais par chance sans conséquences.


/* les autres cas sont ok */
default:
retour = Vrai;



Il manque aussi un break ici, il est optionnel, mais fortement recommandé!


}
return(retour);
}



Je tiens a preciser que c'est toujours dans le cadre de l'utilisation du
switch case !!
( suis rentre dans la norme ?)



Tu étais déjà dans la norme C, mais pas dans les conventions habituelles, de
plus l'algorithme était incomplet et incorrect.
Le C est un langage piégeux, et tu est tombé dans certaines de ces
chausses-trappes à l'origine de nombreux bugs.
Pour éviter cela, il est important d'être très soigneux et d'appliquer
systématiquement les pratiques recommandées par de plus experts que toi, de
compiler avec tous les avertissements que le compilateur peut emettre et de
corriger le code pour y remédier.

Enfin évite de laisser des tabulations dans ton code, utilise des espaces pour
indenter, cela permet de préserver la présentation quelle que soit
l'environnement, comme ici où les tabs sont carrément ignorés.



Je reste etonne de la vehemence de ce forum.
J'ai pris parti pour l'accuse je l'avoue mais je pensais etre entre
personnes intellgentes et surtout pas SECTAIRES.
Suis decu
LG


Avatar
Emmanuel Delahaye
Je reste etonne de la vehemence de ce forum.
J'ai pris parti pour l'accuse je l'avoue mais je pensais etre entre
personnes intellgentes et surtout pas SECTAIRES.
Suis decu


??? Pourquoi, c'est mieux ailleurs ?

--
A+

Emmanuel Delahaye

Avatar
Pierre Maurette
[...]
Il faut eviter ce mot car chacun sait qu'il n'est que ce que l'on CROIT
savoir Je dirais par exemple une celebre phrase d'Apelle " sutor ne supra
crepidam"
"Branlare humanum est, sed perseverara diabolicum", sans oublier le

celèbre "Coïto ergo sum".

en quelques lignes:
de quoi ?


[...]
T'est francais toi
Attention. C'est "Tu ais français, toi ?"


[...]
Je reste etonne de la vehemence de ce forum.
Ce forum est étonnnant. On y trouve de tout. La preuve ...


J'ai pris parti pour l'accuse je l'avoue
"Mon vieux complice", comme disait la fille de joie.


mais je pensais etre entre personnes
intellgentes et surtout pas SECTAIRES.
Suis decu
Vous arrêtez de fumer , vous aussi ? Si vous vouler parler, je suis à

votre disposition, ça vous ferait du bien et à oi également. J'ai mon
premier Nicopatch 21mg collé au dargeot depuis ce matin 4h30, et ça
ferait des vacances au chien Garrigou si je pouvais engueuler quelqu'un
d'autre.

--
Pierre Maurette

Avatar
Pierre Maurette
(supersedes )

[...]
Il faut eviter ce mot car chacun sait qu'il n'est que ce que l'on CROIT
savoir Je dirais par exemple une celebre phrase d'Apelle " sutor ne supra
crepidam"
"Branlare humanum est, sed perseverara diabolicum", sans oublier le

celèbre "Coïto ergo sum".

en quelques lignes:
de quoi ?


[...]
T'est francais toi
Attention. C'est "Tu ais français, toi ?"


[...]
Je reste etonne de la vehemence de ce forum.
Ce forum est étonnnant. On y trouve de tout. La preuve ...


J'ai pris parti pour l'accuse je l'avoue
"Mon vieux complice", comme disait la fille de joie.


mais je pensais etre entre personnes intellgentes et surtout pas SECTAIRES.
Suis decu
Vous arrêtez de fumer , vous aussi ? Si vous voulez parler, je suis à

votre disposition, ça vous ferait du bien et à moi également. J'ai mon
premier Nicopatch 21mg collé au dargeot depuis ce matin 4h30, et ça
ferait des vacances au chien Garrigou si je pouvais engueuler quelqu'un
d'autre.


--
Pierre Maurette

Avatar
Harpo
Gil wrote:


Je reste etonne de la vehemence de ce forum.
J'ai pris parti pour l'accuse je l'avoue mais je pensais etre entre
personnes intellgentes et surtout pas SECTAIRES.
Suis decu


Personne ne t'oblige à ne pas fréqunter les salons de thé, mais si tu
tuens à fréquenter ce forum, veilles à ne pas quoter comme un goret.

5 6 7 8 9